From 9e8f4d794c9c41a61d79798980324586ace24250 Mon Sep 17 00:00:00 2001 From: pelya Date: Thu, 3 Feb 2011 13:37:24 +0000 Subject: [PATCH] Updated GemRB project (courtesy of Beholder) --- .../application/gemrb/AndroidAppSettings.cfg | 11 +- .../gemrb/AndroidData/{data.zip => data1.zip} | Bin 1141120 -> 1146309 bytes .../application/gemrb/gemrb/CMakeLists.txt | 35 + .../gemrb/gemrb/GemRB.cfg.noinstall.sample | 254 ++++++ .../gemrb/gemrb/GemRB.cfg.sample.in | 259 ++++++ .../gemrb/{src => gemrb}/GemRB.cpp | 8 +- .../jni/application/gemrb/gemrb/Makefile.am | 13 + .../gemrb/{src => gemrb}/core/ActorMgr.cpp | 0 .../gemrb/{src => gemrb}/core/ActorMgr.h | 0 .../gemrb/{src => gemrb}/core/Ambient.cpp | 0 .../gemrb/{src => gemrb}/core/Ambient.h | 0 .../gemrb/{src => gemrb}/core/AmbientMgr.cpp | 0 .../gemrb/{src => gemrb}/core/AmbientMgr.h | 0 .../{src => gemrb}/core/AnimStructures.h | 0 .../gemrb/{src => gemrb}/core/Animation.cpp | 0 .../gemrb/{src => gemrb}/core/Animation.h | 0 .../{src => gemrb}/core/AnimationFactory.cpp | 0 .../{src => gemrb}/core/AnimationFactory.h | 0 .../{src => gemrb}/core/AnimationMgr.cpp | 0 .../gemrb/{src => gemrb}/core/AnimationMgr.h | 0 .../{src => gemrb}/core/ArchiveImporter.cpp | 0 .../{src => gemrb}/core/ArchiveImporter.h | 0 .../gemrb/{src => gemrb}/core/Audio.cpp | 0 .../gemrb/{src => gemrb}/core/Audio.h | 4 +- .../gemrb/{src => gemrb}/core/Bitmap.cpp | 0 .../gemrb/{src => gemrb}/core/Bitmap.h | 0 .../gemrb/{src => gemrb}/core/CMakeLists.txt | 0 .../gemrb/{src => gemrb}/core/Cache.cpp | 0 .../gemrb/{src => gemrb}/core/Cache.h | 0 .../gemrb/{src => gemrb}/core/Calendar.cpp | 0 .../gemrb/{src => gemrb}/core/Calendar.h | 0 .../gemrb/{src => gemrb}/core/Callback.cpp | 0 .../gemrb/{src => gemrb}/core/Callback.h | 0 .../{src => gemrb}/core/CharAnimations.cpp | 9 + .../{src => gemrb}/core/CharAnimations.h | 0 .../gemrb/{src => gemrb}/core/Compressor.cpp | 0 .../gemrb/{src => gemrb}/core/Compressor.h | 0 .../{src => gemrb}/core/ControlAnimation.cpp | 0 .../{src => gemrb}/core/ControlAnimation.h | 0 .../gemrb/{src => gemrb}/core/Core.cpp | 0 .../gemrb/{src => gemrb}/core/DataFileMgr.cpp | 0 .../gemrb/{src => gemrb}/core/DataFileMgr.h | 0 .../gemrb/{src => gemrb}/core/Dialog.cpp | 0 .../gemrb/{src => gemrb}/core/Dialog.h | 0 .../{src => gemrb}/core/DialogHandler.cpp | 0 .../gemrb/{src => gemrb}/core/DialogHandler.h | 0 .../gemrb/{src => gemrb}/core/DialogMgr.cpp | 0 .../gemrb/{src => gemrb}/core/DialogMgr.h | 0 .../{src => gemrb}/core/DisplayMessage.cpp | 29 +- .../{src => gemrb}/core/DisplayMessage.h | 0 .../gemrb/{src => gemrb}/core/Effect.h | 0 .../gemrb/{src => gemrb}/core/EffectMgr.cpp | 0 .../gemrb/{src => gemrb}/core/EffectMgr.h | 0 .../gemrb/{src => gemrb}/core/EffectQueue.cpp | 3 +- .../gemrb/{src => gemrb}/core/EffectQueue.h | 0 .../gemrb/{src => gemrb}/core/Factory.cpp | 0 .../gemrb/{src => gemrb}/core/Factory.h | 0 .../{src => gemrb}/core/FactoryObject.cpp | 0 .../gemrb/{src => gemrb}/core/FactoryObject.h | 0 .../gemrb/{src => gemrb}/core/Font.cpp | 0 .../gemrb/{src => gemrb}/core/Font.h | 0 .../gemrb/{src => gemrb}/core/GUI/Button.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/Button.h | 0 .../gemrb/{src => gemrb}/core/GUI/Console.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/Console.h | 0 .../gemrb/{src => gemrb}/core/GUI/Control.cpp | 12 +- .../gemrb/{src => gemrb}/core/GUI/Control.h | 0 .../{src => gemrb}/core/GUI/EventMgr.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/EventMgr.h | 0 .../{src => gemrb}/core/GUI/GameControl.cpp | 276 ++++-- .../{src => gemrb}/core/GUI/GameControl.h | 8 +- .../gemrb/{src => gemrb}/core/GUI/Label.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/Label.h | 0 .../{src => gemrb}/core/GUI/MapControl.cpp | 0 .../{src => gemrb}/core/GUI/MapControl.h | 0 .../{src => gemrb}/core/GUI/Progressbar.cpp | 0 .../{src => gemrb}/core/GUI/Progressbar.h | 0 .../{src => gemrb}/core/GUI/ScrollBar.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/ScrollBar.h | 0 .../gemrb/{src => gemrb}/core/GUI/Slider.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/Slider.h | 0 .../{src => gemrb}/core/GUI/TextArea.cpp | 21 + .../gemrb/{src => gemrb}/core/GUI/TextArea.h | 2 + .../{src => gemrb}/core/GUI/TextEdit.cpp | 2 + .../gemrb/{src => gemrb}/core/GUI/TextEdit.h | 0 .../gemrb/{src => gemrb}/core/GUI/Window.cpp | 0 .../gemrb/{src => gemrb}/core/GUI/Window.h | 0 .../core/GUI/WorldMapControl.cpp | 0 .../{src => gemrb}/core/GUI/WorldMapControl.h | 0 .../gemrb/{src => gemrb}/core/Game.cpp | 24 +- .../gemrb/{src => gemrb}/core/Game.h | 65 +- .../gemrb/{src => gemrb}/core/GameData.cpp | 0 .../gemrb/{src => gemrb}/core/GameData.h | 0 .../core/GameScript/Actions.cpp | 110 ++- .../core/GameScript/GSUtils.cpp | 43 +- .../{src => gemrb}/core/GameScript/GSUtils.h | 2 - .../core/GameScript/GameScript.cpp | 11 +- .../core/GameScript/GameScript.h | 3 + .../core/GameScript/Matching.cpp | 66 +- .../{src => gemrb}/core/GameScript/Matching.h | 2 +- .../core/GameScript/Objects.cpp | 0 .../core/GameScript/Triggers.cpp | 27 +- .../gemrb/{src => gemrb}/core/GlobalTimer.cpp | 0 .../gemrb/{src => gemrb}/core/GlobalTimer.h | 0 .../gemrb/{src => gemrb}/core/Holder.h | 0 .../gemrb/{src => gemrb}/core/Image.cpp | 0 .../gemrb/{src => gemrb}/core/Image.h | 0 .../{src => gemrb}/core/ImageFactory.cpp | 0 .../gemrb/{src => gemrb}/core/ImageFactory.h | 0 .../gemrb/{src => gemrb}/core/ImageMgr.cpp | 0 .../gemrb/{src => gemrb}/core/ImageMgr.h | 0 .../gemrb/{src => gemrb}/core/ImageWriter.cpp | 0 .../gemrb/{src => gemrb}/core/ImageWriter.h | 0 .../gemrb/{src => gemrb}/core/IniSpawn.cpp | 0 .../gemrb/{src => gemrb}/core/IniSpawn.h | 0 .../gemrb/{src => gemrb}/core/Interface.cpp | 104 ++- .../gemrb/{src => gemrb}/core/Interface.h | 21 + .../gemrb/{src => gemrb}/core/Inventory.cpp | 3 + .../gemrb/{src => gemrb}/core/Inventory.h | 0 .../gemrb/{src => gemrb}/core/Item.cpp | 0 .../gemrb/{src => gemrb}/core/Item.h | 0 .../gemrb/{src => gemrb}/core/ItemMgr.cpp | 0 .../gemrb/{src => gemrb}/core/ItemMgr.h | 0 .../gemrb/{src => gemrb}/core/LRUCache.cpp | 0 .../gemrb/{src => gemrb}/core/LRUCache.h | 0 .../gemrb/{src => gemrb}/core/Makefile.am | 0 .../gemrb/{src => gemrb}/core/Map.cpp | 108 ++- .../gemrb/{src => gemrb}/core/Map.h | 3 +- .../gemrb/{src => gemrb}/core/MapMgr.cpp | 0 .../gemrb/{src => gemrb}/core/MapMgr.h | 0 .../gemrb/{src => gemrb}/core/MoviePlayer.cpp | 0 .../gemrb/{src => gemrb}/core/MoviePlayer.h | 0 .../gemrb/{src => gemrb}/core/MusicMgr.cpp | 0 .../gemrb/{src => gemrb}/core/MusicMgr.h | 0 .../gemrb/{src => gemrb}/core/Palette.cpp | 0 .../gemrb/{src => gemrb}/core/Palette.h | 1 + .../{src => gemrb}/core/PalettedImageMgr.cpp | 0 .../{src => gemrb}/core/PalettedImageMgr.h | 0 .../gemrb/{src => gemrb}/core/Particles.cpp | 0 .../gemrb/{src => gemrb}/core/Particles.h | 0 .../gemrb/{src => gemrb}/core/PathFinder.h | 0 .../gemrb/{src => gemrb}/core/Plugin.cpp | 0 .../gemrb/{src => gemrb}/core/Plugin.h | 0 .../gemrb/{src => gemrb}/core/PluginMgr.cpp | 0 .../gemrb/{src => gemrb}/core/PluginMgr.h | 0 .../gemrb/{src => gemrb}/core/Polygon.cpp | 0 .../gemrb/{src => gemrb}/core/Polygon.h | 0 .../{src => gemrb}/core/PolymorphCache.h | 0 .../gemrb/{src => gemrb}/core/Projectile.cpp | 0 .../gemrb/{src => gemrb}/core/Projectile.h | 0 .../{src => gemrb}/core/ProjectileMgr.cpp | 0 .../gemrb/{src => gemrb}/core/ProjectileMgr.h | 0 .../{src => gemrb}/core/ProjectileServer.cpp | 0 .../{src => gemrb}/core/ProjectileServer.h | 0 .../gemrb/{src => gemrb}/core/Region.cpp | 0 .../gemrb/{src => gemrb}/core/Region.h | 0 .../gemrb/{src => gemrb}/core/Resource.cpp | 0 .../gemrb/{src => gemrb}/core/Resource.h | 0 .../{src => gemrb}/core/ResourceDesc.cpp | 0 .../gemrb/{src => gemrb}/core/ResourceDesc.h | 0 .../{src => gemrb}/core/ResourceManager.cpp | 0 .../{src => gemrb}/core/ResourceManager.h | 0 .../{src => gemrb}/core/ResourceSource.cpp | 0 .../{src => gemrb}/core/ResourceSource.h | 0 .../gemrb/{src => gemrb}/core/SaveGame.h | 0 .../{src => gemrb}/core/SaveGameIterator.cpp | 0 .../{src => gemrb}/core/SaveGameIterator.h | 0 .../gemrb/{src => gemrb}/core/SaveGameMgr.cpp | 0 .../gemrb/{src => gemrb}/core/SaveGameMgr.h | 0 .../{src => gemrb}/core/ScriptEngine.cpp | 0 .../gemrb/{src => gemrb}/core/ScriptEngine.h | 0 .../{src => gemrb}/core/Scriptable/Actor.cpp | 304 +++++-- .../{src => gemrb}/core/Scriptable/Actor.h | 93 +- .../core/Scriptable/ActorBlock.cpp | 501 ++++++++++- .../core/Scriptable/ActorBlock.h | 19 +- .../core/Scriptable/PCStatStruct.cpp | 16 - .../core/Scriptable/PCStatStruct.h | 1 + .../{src => gemrb}/core/ScriptedAnimation.cpp | 0 .../{src => gemrb}/core/ScriptedAnimation.h | 0 .../gemrb/{src => gemrb}/core/SoundMgr.cpp | 0 .../gemrb/{src => gemrb}/core/SoundMgr.h | 0 .../gemrb/{src => gemrb}/core/Spell.cpp | 30 +- .../gemrb/{src => gemrb}/core/Spell.h | 0 .../gemrb/{src => gemrb}/core/SpellMgr.cpp | 0 .../gemrb/{src => gemrb}/core/SpellMgr.h | 0 .../gemrb/{src => gemrb}/core/Spellbook.cpp | 116 ++- .../gemrb/{src => gemrb}/core/Spellbook.h | 10 +- .../gemrb/{src => gemrb}/core/Sprite2D.cpp | 0 .../gemrb/{src => gemrb}/core/Sprite2D.h | 0 .../gemrb/{src => gemrb}/core/SpriteCover.cpp | 0 .../gemrb/{src => gemrb}/core/SpriteCover.h | 0 .../gemrb/{src => gemrb}/core/Store.cpp | 0 .../gemrb/{src => gemrb}/core/Store.h | 0 .../gemrb/{src => gemrb}/core/StoreMgr.cpp | 0 .../gemrb/{src => gemrb}/core/StoreMgr.h | 0 .../gemrb/{src => gemrb}/core/StringMgr.cpp | 0 .../gemrb/{src => gemrb}/core/StringMgr.h | 0 .../gemrb/{src => gemrb}/core/SymbolMgr.cpp | 0 .../gemrb/{src => gemrb}/core/SymbolMgr.h | 0 .../core/System/CachedFileStream.cpp | 0 .../core/System/CachedFileStream.h | 0 .../{src => gemrb}/core/System/DataStream.cpp | 0 .../{src => gemrb}/core/System/DataStream.h | 0 .../{src => gemrb}/core/System/FileStream.cpp | 0 .../{src => gemrb}/core/System/FileStream.h | 0 .../core/System/MemoryStream.cpp | 0 .../{src => gemrb}/core/System/MemoryStream.h | 0 .../gemrb/{src => gemrb}/core/System/VFS.cpp | 0 .../gemrb/{src => gemrb}/core/System/VFS.h | 0 .../gemrb/{src => gemrb}/core/System/swab.c | 0 .../gemrb/{src => gemrb}/core/System/swab.h | 2 +- .../gemrb/{src => gemrb}/core/TableMgr.cpp | 0 .../gemrb/{src => gemrb}/core/TableMgr.h | 0 .../gemrb/{src => gemrb}/core/Tile.cpp | 0 .../gemrb/{src => gemrb}/core/Tile.h | 0 .../gemrb/{src => gemrb}/core/TileMap.cpp | 0 .../gemrb/{src => gemrb}/core/TileMap.h | 0 .../gemrb/{src => gemrb}/core/TileMapMgr.cpp | 0 .../gemrb/{src => gemrb}/core/TileMapMgr.h | 0 .../gemrb/{src => gemrb}/core/TileOverlay.cpp | 0 .../gemrb/{src => gemrb}/core/TileOverlay.h | 0 .../gemrb/{src => gemrb}/core/TileSetMgr.cpp | 0 .../gemrb/{src => gemrb}/core/TileSetMgr.h | 0 .../gemrb/{src => gemrb}/core/TypeID.h | 0 .../gemrb/{src => gemrb}/core/Variables.cpp | 0 .../gemrb/{src => gemrb}/core/Variables.h | 0 .../gemrb/{src => gemrb}/core/Video.cpp | 0 .../gemrb/{src => gemrb}/core/Video.h | 0 .../gemrb/{src => gemrb}/core/VideoMode.h | 0 .../gemrb/{src => gemrb}/core/WindowMgr.cpp | 0 .../gemrb/{src => gemrb}/core/WindowMgr.h | 0 .../gemrb/{src => gemrb}/core/WorldMap.cpp | 0 .../gemrb/{src => gemrb}/core/WorldMap.h | 0 .../gemrb/{src => gemrb}/core/WorldMapMgr.cpp | 0 .../gemrb/{src => gemrb}/core/WorldMapMgr.h | 0 .../gemrb/{src => gemrb}/core/damages.h | 0 .../gemrb/{src => gemrb}/includes/Makefile.am | 0 .../gemrb/{src => gemrb}/includes/RGBAColor.h | 0 .../gemrb/{src => gemrb}/includes/SClassID.h | 0 .../gemrb/{src => gemrb}/includes/defsounds.h | 0 .../gemrb/{src => gemrb}/includes/errors.h | 0 .../gemrb/{src => gemrb}/includes/exports.h | 0 .../gemrb/{src => gemrb}/includes/globals.h | 4 +- .../gemrb/{src => gemrb}/includes/ie_feats.h | 0 .../gemrb/{src => gemrb}/includes/ie_stats.h | 17 +- .../gemrb/{src => gemrb}/includes/ie_types.h | 0 .../gemrb/{src => gemrb}/includes/iless.h | 0 .../gemrb/{src => gemrb}/includes/logging.h | 0 .../{src => gemrb}/includes/opcode_params.h | 7 + .../{src => gemrb}/includes/operatorbool.h | 0 .../gemrb/{src => gemrb}/includes/overlays.h | 0 .../gemrb/{src => gemrb}/includes/plugindef.h | 0 .../gemrb/{src => gemrb}/includes/strrefs.h | 86 +- .../gemrb/{src => gemrb}/includes/win32def.h | 4 - .../gemrb/gemrb/plugins-prepare.sh | 38 + .../plugins/2DAImporter/2DAImporter.cpp | 0 .../plugins/2DAImporter/2DAImporter.h | 0 .../plugins/2DAImporter/CMakeLists.txt | 0 .../plugins/2DAImporter/Makefile.am | 0 .../plugins/ACMReader/ACMReader.cpp | 0 .../plugins/ACMReader/ACMReader.h | 0 .../plugins/ACMReader/CMakeLists.txt | 0 .../plugins/ACMReader/Makefile.am | 0 .../plugins/ACMReader/decoder.cpp | 0 .../plugins/ACMReader/decoder.h | 0 .../plugins/ACMReader/general.h | 0 .../plugins/ACMReader/unpacker.cpp | 0 .../plugins/ACMReader/unpacker.h | 0 .../plugins/AREImporter/AREImporter.cpp | 14 +- .../plugins/AREImporter/AREImporter.h | 0 .../plugins/AREImporter/CMakeLists.txt | 0 .../plugins/AREImporter/Makefile.am | 0 .../plugins/BAMImporter/BAMImporter.cpp | 0 .../plugins/BAMImporter/BAMImporter.h | 0 .../plugins/BAMImporter/CMakeLists.txt | 0 .../plugins/BAMImporter/Makefile.am | 0 .../plugins/BIFImporter/BIFImporter.cpp | 0 .../plugins/BIFImporter/BIFImporter.h | 0 .../plugins/BIFImporter/CMakeLists.txt | 0 .../plugins/BIFImporter/Makefile.am | 0 .../plugins/BIKPlayer/BIKPlayer.cpp | 116 ++- .../plugins/BIKPlayer/BIKPlayer.h | 28 +- .../plugins/BIKPlayer/CMakeLists.txt | 0 .../plugins/BIKPlayer/GetBitContext.cpp | 16 - .../gemrb/plugins/BIKPlayer/GetBitContext.h | 107 +++ .../plugins/BIKPlayer/Makefile.am | 0 .../plugins/BIKPlayer/binkdata.h | 0 .../{src => gemrb}/plugins/BIKPlayer/common.h | 0 .../{src => gemrb}/plugins/BIKPlayer/dct.cpp | 0 .../plugins/BIKPlayer/dsputil.h | 3 - .../{src => gemrb}/plugins/BIKPlayer/fft.cpp | 0 .../{src => gemrb}/plugins/BIKPlayer/mem.cpp | 0 .../plugins/BIKPlayer/rational.cpp | 0 .../plugins/BIKPlayer/rational.h | 0 .../{src => gemrb}/plugins/BIKPlayer/rdft.cpp | 0 .../plugins/BMPImporter/BMPImporter.cpp | 0 .../plugins/BMPImporter/BMPImporter.h | 0 .../plugins/BMPImporter/CMakeLists.txt | 0 .../plugins/BMPImporter/Makefile.am | 0 .../plugins/BMPWriter/BMPWriter.cpp | 0 .../plugins/BMPWriter/BMPWriter.h | 0 .../plugins/BMPWriter/CMakeLists.txt | 0 .../plugins/BMPWriter/Makefile.am | 0 .../plugins/CHUImporter/CHUImporter.cpp | 43 +- .../plugins/CHUImporter/CHUImporter.h | 0 .../plugins/CHUImporter/CMakeLists.txt | 0 .../plugins/CHUImporter/Makefile.am | 0 .../{src => gemrb}/plugins/CMakeLists.txt | 0 .../plugins/CREImporter/CMakeLists.txt | 0 .../plugins/CREImporter/CREImporter.cpp | 0 .../plugins/CREImporter/CREImporter.h | 0 .../plugins/CREImporter/Makefile.am | 0 .../plugins/DLGImporter/CMakeLists.txt | 0 .../plugins/DLGImporter/DLGImporter.cpp | 0 .../plugins/DLGImporter/DLGImporter.h | 0 .../plugins/DLGImporter/Makefile.am | 0 .../plugins/DirectoryImporter/CMakeLists.txt | 0 .../DirectoryImporter/DirectoryImporter.cpp | 0 .../DirectoryImporter/DirectoryImporter.h | 0 .../plugins/DirectoryImporter/Makefile.am | 0 .../plugins/EFFImporter/CMakeLists.txt | 0 .../plugins/EFFImporter/EFFImporter.cpp | 0 .../plugins/EFFImporter/EFFImporter.h | 0 .../plugins/EFFImporter/Makefile.am | 0 .../plugins/FXOpcodes/CMakeLists.txt | 0 .../plugins/FXOpcodes/FXOpcodes.cpp | 236 ++++- .../plugins/FXOpcodes/Makefile.am | 0 .../plugins/GAMImporter/CMakeLists.txt | 0 .../plugins/GAMImporter/GAMImporter.cpp | 125 ++- .../plugins/GAMImporter/GAMImporter.h | 6 +- .../plugins/GAMImporter/Makefile.am | 0 .../plugins/GUIScript/CMakeLists.txt | 0 .../plugins/GUIScript/GUIScript.cpp | 395 ++++++-- .../plugins/GUIScript/GUIScript.h | 0 .../plugins/GUIScript/Makefile.am | 0 .../plugins/GUIScript/PythonHelpers.cpp | 0 .../plugins/GUIScript/PythonHelpers.h | 0 .../plugins/IDSImporter/CMakeLists.txt | 0 .../plugins/IDSImporter/IDSImporter.cpp | 0 .../plugins/IDSImporter/IDSImporter.h | 0 .../plugins/IDSImporter/IDSImporterDefs.h | 0 .../plugins/IDSImporter/Makefile.am | 0 .../plugins/INIImporter/CMakeLists.txt | 0 .../plugins/INIImporter/INIImporter.cpp | 0 .../plugins/INIImporter/INIImporter.h | 0 .../plugins/INIImporter/Makefile.am | 0 .../plugins/ITMImporter/CMakeLists.txt | 0 .../plugins/ITMImporter/ITMImporter.cpp | 0 .../plugins/ITMImporter/ITMImporter.h | 0 .../plugins/ITMImporter/Makefile.am | 0 .../plugins/IWDOpcodes/CMakeLists.txt | 0 .../plugins/IWDOpcodes/IWDOpcodes.cpp | 90 +- .../plugins/IWDOpcodes/Makefile.am | 0 .../plugins/KEYImporter/CMakeLists.txt | 0 .../plugins/KEYImporter/Dictionary.cpp | 0 .../plugins/KEYImporter/Dictionary.h | 0 .../plugins/KEYImporter/KEYImporter.cpp | 0 .../plugins/KEYImporter/KEYImporter.h | 0 .../plugins/KEYImporter/Makefile.am | 0 .../plugins/MOSImporter/CMakeLists.txt | 0 .../plugins/MOSImporter/MOSImporter.cpp | 0 .../plugins/MOSImporter/MOSImporter.h | 0 .../plugins/MOSImporter/Makefile.am | 0 .../plugins/MUSImporter/CMakeLists.txt | 0 .../plugins/MUSImporter/MUSImporter.cpp | 0 .../plugins/MUSImporter/MUSImporter.h | 0 .../plugins/MUSImporter/Makefile.am | 0 .../plugins/MVEPlayer/CMakeLists.txt | 0 .../plugins/MVEPlayer/MVEPlayer.cpp | 0 .../plugins/MVEPlayer/MVEPlayer.h | 0 .../plugins/MVEPlayer/Makefile.am | 0 .../plugins/MVEPlayer/gstmvedemux.h | 4 +- .../{src => gemrb}/plugins/MVEPlayer/mve.h | 0 .../plugins/MVEPlayer/mve_player.cpp | 10 +- .../plugins/MVEPlayer/mve_player.h | 2 +- .../plugins/MVEPlayer/mveaudiodec.cpp | 0 .../gemrb/plugins/MVEPlayer/mvevideodec16.cpp | 844 +++++++++++++++++ .../gemrb/plugins/MVEPlayer/mvevideodec8.cpp | 797 ++++++++++++++++ .../gemrb/{src => gemrb}/plugins/Makefile.am | 0 .../plugins/NullSound/CMakeLists.txt | 0 .../plugins/NullSound/Makefile.am | 0 .../plugins/NullSound/NullSound.cpp | 0 .../plugins/NullSound/NullSound.h | 0 .../plugins/OGGReader/CMakeLists.txt | 0 .../plugins/OGGReader/Makefile.am | 0 .../plugins/OGGReader/OGGReader.cpp | 0 .../plugins/OGGReader/OGGReader.h | 0 .../plugins/OpenALAudio/AmbientMgrAL.cpp | 0 .../plugins/OpenALAudio/AmbientMgrAL.h | 0 .../plugins/OpenALAudio/CMakeLists.txt | 0 .../plugins/OpenALAudio/Makefile.am | 0 .../plugins/OpenALAudio/OpenALAudio.cpp | 11 +- .../plugins/OpenALAudio/OpenALAudio.h | 0 .../plugins/OpenALAudio/StackLock.cpp | 0 .../plugins/OpenALAudio/StackLock.h | 0 .../plugins/PLTImporter/CMakeLists.txt | 0 .../plugins/PLTImporter/Makefile.am | 0 .../plugins/PLTImporter/PLTImporter.cpp | 0 .../plugins/PLTImporter/PLTImporter.h | 0 .../plugins/PNGImporter/CMakeLists.txt | 0 .../plugins/PNGImporter/Makefile.am | 0 .../plugins/PNGImporter/PNGImporter.cpp | 2 +- .../plugins/PNGImporter/PNGImporter.h | 0 .../plugins/PROImporter/CMakeLists.txt | 0 .../plugins/PROImporter/Makefile.am | 0 .../plugins/PROImporter/PROImporter.cpp | 0 .../plugins/PROImporter/PROImporter.h | 0 .../plugins/PSTOpcodes/CMakeLists.txt | 0 .../plugins/PSTOpcodes/Makefile.am | 0 .../plugins/PSTOpcodes/PSTOpcodes.cpp | 0 .../plugins/SDLAudio/CMakeLists.txt | 0 .../plugins/SDLAudio/Makefile.am | 0 .../plugins/SDLAudio/SDLAudio.cpp | 2 +- .../plugins/SDLAudio/SDLAudio.h | 4 +- .../plugins/SDLVideo/CMakeLists.txt | 0 .../plugins/SDLVideo/Makefile.am | 0 .../plugins/SDLVideo/SDLVideo.cpp | 0 .../plugins/SDLVideo/SDLVideo.h | 0 .../plugins/SDLVideo/SDLVideoDriver.inl | 0 .../plugins/SDLVideo/TileRenderer.inl | 0 .../plugins/SPLImporter/CMakeLists.txt | 0 .../plugins/SPLImporter/Makefile.am | 0 .../plugins/SPLImporter/SPLImporter.cpp | 0 .../plugins/SPLImporter/SPLImporter.h | 0 .../plugins/STOImporter/CMakeLists.txt | 0 .../plugins/STOImporter/Makefile.am | 0 .../plugins/STOImporter/STOImporter.cpp | 13 +- .../plugins/STOImporter/STOImporter.h | 0 .../plugins/TISImporter/CMakeLists.txt | 0 .../plugins/TISImporter/Makefile.am | 0 .../plugins/TISImporter/TISImporter.cpp | 0 .../plugins/TISImporter/TISImporter.h | 0 .../plugins/TLKImporter/CMakeLists.txt | 0 .../plugins/TLKImporter/Makefile.am | 0 .../plugins/TLKImporter/TLKImporter.cpp | 76 -- .../plugins/TLKImporter/TLKImporter.h | 0 .../plugins/TLKImporter/TlkOverride.cpp | 0 .../plugins/TLKImporter/TlkOverride.h | 0 .../plugins/WAVReader/CMakeLists.txt | 0 .../plugins/WAVReader/Makefile.am | 0 .../plugins/WAVReader/WAVReader.cpp | 0 .../plugins/WAVReader/WAVReader.h | 0 .../plugins/WEDImporter/CMakeLists.txt | 0 .../plugins/WEDImporter/Makefile.am | 0 .../plugins/WEDImporter/WEDImporter.cpp | 12 + .../plugins/WEDImporter/WEDImporter.h | 0 .../plugins/WMPImporter/CMakeLists.txt | 0 .../plugins/WMPImporter/Makefile.am | 0 .../plugins/WMPImporter/WMPImporter.cpp | 0 .../plugins/WMPImporter/WMPImporter.h | 0 .../plugins/ZLibManager/CMakeLists.txt | 0 .../plugins/ZLibManager/Makefile.am | 0 .../plugins/ZLibManager/ZLibManager.cpp | 0 .../plugins/ZLibManager/ZLibManager.h | 0 project/jni/application/gemrb/src/AUTHORS | 17 - project/jni/application/gemrb/src/COPYING | 340 ------- project/jni/application/gemrb/src/NEWS | 381 -------- project/jni/application/gemrb/src/README | 77 -- project/jni/application/gemrb/src/TODO | 101 --- .../src/plugins/BIKPlayer/GetBitContext.h | 75 -- .../src/plugins/MVEPlayer/mvevideodec16.cpp | 849 ------------------ .../src/plugins/MVEPlayer/mvevideodec8.cpp | 802 ----------------- 462 files changed, 4774 insertions(+), 3611 deletions(-) rename project/jni/application/gemrb/AndroidData/{data.zip => data1.zip} (66%) create mode 100644 project/jni/application/gemrb/gemrb/CMakeLists.txt create mode 100644 project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample create mode 100644 project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in rename project/jni/application/gemrb/{src => gemrb}/GemRB.cpp (93%) create mode 100644 project/jni/application/gemrb/gemrb/Makefile.am rename project/jni/application/gemrb/{src => gemrb}/core/ActorMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ActorMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Ambient.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Ambient.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AmbientMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AmbientMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AnimStructures.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Animation.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Animation.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AnimationFactory.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AnimationFactory.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AnimationMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/AnimationMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ArchiveImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ArchiveImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Audio.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Audio.h (97%) rename project/jni/application/gemrb/{src => gemrb}/core/Bitmap.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Bitmap.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Cache.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Cache.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Calendar.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Calendar.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Callback.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Callback.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/CharAnimations.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/CharAnimations.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Compressor.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Compressor.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ControlAnimation.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ControlAnimation.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Core.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DataFileMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DataFileMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Dialog.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Dialog.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DialogHandler.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DialogHandler.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DialogMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DialogMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/DisplayMessage.cpp (89%) rename project/jni/application/gemrb/{src => gemrb}/core/DisplayMessage.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Effect.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/EffectMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/EffectMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/EffectQueue.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/EffectQueue.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Factory.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Factory.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/FactoryObject.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/FactoryObject.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Font.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Font.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Button.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Button.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Console.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Console.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Control.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Control.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/EventMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/EventMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/GameControl.cpp (92%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/GameControl.h (96%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Label.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Label.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/MapControl.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/MapControl.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Progressbar.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Progressbar.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/ScrollBar.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/ScrollBar.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Slider.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Slider.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/TextArea.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/TextArea.h (97%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/TextEdit.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/TextEdit.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Window.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/Window.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/WorldMapControl.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GUI/WorldMapControl.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Game.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/Game.h (89%) rename project/jni/application/gemrb/{src => gemrb}/core/GameData.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GameData.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/Actions.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/GSUtils.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/GSUtils.h (99%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/GameScript.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/GameScript.h (99%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/Matching.cpp (94%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/Matching.h (95%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/Objects.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GameScript/Triggers.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/GlobalTimer.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/GlobalTimer.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Holder.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Image.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Image.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageFactory.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageFactory.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageWriter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ImageWriter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/IniSpawn.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/IniSpawn.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Interface.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/Interface.h (97%) rename project/jni/application/gemrb/{src => gemrb}/core/Inventory.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/core/Inventory.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Item.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Item.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ItemMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ItemMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/LRUCache.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/LRUCache.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Map.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/core/Map.h (99%) rename project/jni/application/gemrb/{src => gemrb}/core/MapMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/MapMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/MoviePlayer.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/MoviePlayer.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/MusicMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/MusicMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Palette.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Palette.h (99%) rename project/jni/application/gemrb/{src => gemrb}/core/PalettedImageMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/PalettedImageMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Particles.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Particles.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/PathFinder.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Plugin.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Plugin.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/PluginMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/PluginMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Polygon.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Polygon.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/PolymorphCache.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Projectile.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Projectile.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ProjectileMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ProjectileMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ProjectileServer.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ProjectileServer.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Region.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Region.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Resource.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Resource.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceDesc.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceDesc.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceManager.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceManager.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceSource.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ResourceSource.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SaveGame.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SaveGameIterator.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SaveGameIterator.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SaveGameMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SaveGameMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ScriptEngine.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ScriptEngine.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/Actor.cpp (96%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/Actor.h (91%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/ActorBlock.cpp (78%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/ActorBlock.h (95%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/PCStatStruct.cpp (89%) rename project/jni/application/gemrb/{src => gemrb}/core/Scriptable/PCStatStruct.h (97%) rename project/jni/application/gemrb/{src => gemrb}/core/ScriptedAnimation.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/ScriptedAnimation.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SoundMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SoundMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Spell.cpp (90%) rename project/jni/application/gemrb/{src => gemrb}/core/Spell.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SpellMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SpellMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Spellbook.cpp (92%) rename project/jni/application/gemrb/{src => gemrb}/core/Spellbook.h (96%) rename project/jni/application/gemrb/{src => gemrb}/core/Sprite2D.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Sprite2D.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SpriteCover.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SpriteCover.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Store.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Store.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/StoreMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/StoreMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/StringMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/StringMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SymbolMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/SymbolMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/CachedFileStream.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/CachedFileStream.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/DataStream.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/DataStream.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/FileStream.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/FileStream.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/MemoryStream.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/MemoryStream.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/VFS.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/VFS.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/swab.c (100%) rename project/jni/application/gemrb/{src => gemrb}/core/System/swab.h (99%) rename project/jni/application/gemrb/{src => gemrb}/core/TableMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TableMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Tile.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Tile.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileMap.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileMap.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileMapMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileMapMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileOverlay.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileOverlay.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileSetMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TileSetMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/TypeID.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Variables.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Variables.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Video.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/Video.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/VideoMode.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WindowMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WindowMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WorldMap.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WorldMap.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WorldMapMgr.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/core/WorldMapMgr.h (100%) rename project/jni/application/gemrb/{src => gemrb}/core/damages.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/RGBAColor.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/SClassID.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/defsounds.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/errors.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/exports.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/globals.h (98%) rename project/jni/application/gemrb/{src => gemrb}/includes/ie_feats.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/ie_stats.h (96%) rename project/jni/application/gemrb/{src => gemrb}/includes/ie_types.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/iless.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/logging.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/opcode_params.h (96%) rename project/jni/application/gemrb/{src => gemrb}/includes/operatorbool.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/overlays.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/plugindef.h (100%) rename project/jni/application/gemrb/{src => gemrb}/includes/strrefs.h (75%) rename project/jni/application/gemrb/{src => gemrb}/includes/win32def.h (97%) create mode 100644 project/jni/application/gemrb/gemrb/plugins-prepare.sh rename project/jni/application/gemrb/{src => gemrb}/plugins/2DAImporter/2DAImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/2DAImporter/2DAImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/2DAImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/2DAImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/ACMReader.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/ACMReader.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/decoder.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/decoder.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/general.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/unpacker.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ACMReader/unpacker.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/AREImporter/AREImporter.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/plugins/AREImporter/AREImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/AREImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/AREImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BAMImporter/BAMImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BAMImporter/BAMImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BAMImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BAMImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIFImporter/BIFImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIFImporter/BIFImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIFImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIFImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/BIKPlayer.cpp (94%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/BIKPlayer.h (92%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/GetBitContext.cpp (96%) create mode 100644 project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.h rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/binkdata.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/common.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/dct.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/dsputil.h (99%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/fft.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/mem.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/rational.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/rational.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BIKPlayer/rdft.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPImporter/BMPImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPImporter/BMPImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPWriter/BMPWriter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPWriter/BMPWriter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPWriter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/BMPWriter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CHUImporter/CHUImporter.cpp (93%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CHUImporter/CHUImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CHUImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CHUImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CREImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CREImporter/CREImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CREImporter/CREImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/CREImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DLGImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DLGImporter/DLGImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DLGImporter/DLGImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DLGImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DirectoryImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DirectoryImporter/DirectoryImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DirectoryImporter/DirectoryImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/DirectoryImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/EFFImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/EFFImporter/EFFImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/EFFImporter/EFFImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/EFFImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/FXOpcodes/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/FXOpcodes/FXOpcodes.cpp (97%) rename project/jni/application/gemrb/{src => gemrb}/plugins/FXOpcodes/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GAMImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GAMImporter/GAMImporter.cpp (89%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GAMImporter/GAMImporter.h (91%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GAMImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/GUIScript.cpp (97%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/GUIScript.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/PythonHelpers.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/GUIScript/PythonHelpers.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IDSImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IDSImporter/IDSImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IDSImporter/IDSImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IDSImporter/IDSImporterDefs.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IDSImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/INIImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/INIImporter/INIImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/INIImporter/INIImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/INIImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ITMImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ITMImporter/ITMImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ITMImporter/ITMImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ITMImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IWDOpcodes/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IWDOpcodes/IWDOpcodes.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/plugins/IWDOpcodes/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/Dictionary.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/Dictionary.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/KEYImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/KEYImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/KEYImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MOSImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MOSImporter/MOSImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MOSImporter/MOSImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MOSImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MUSImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MUSImporter/MUSImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MUSImporter/MUSImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MUSImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/MVEPlayer.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/MVEPlayer.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/gstmvedemux.h (98%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/mve.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/mve_player.cpp (97%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/mve_player.h (98%) rename project/jni/application/gemrb/{src => gemrb}/plugins/MVEPlayer/mveaudiodec.cpp (100%) create mode 100644 project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec16.cpp create mode 100644 project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec8.cpp rename project/jni/application/gemrb/{src => gemrb}/plugins/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/NullSound/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/NullSound/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/NullSound/NullSound.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/NullSound/NullSound.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OGGReader/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OGGReader/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OGGReader/OGGReader.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OGGReader/OGGReader.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/AmbientMgrAL.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/AmbientMgrAL.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/OpenALAudio.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/OpenALAudio.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/StackLock.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/OpenALAudio/StackLock.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PLTImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PLTImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PLTImporter/PLTImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PLTImporter/PLTImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PNGImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PNGImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PNGImporter/PNGImporter.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PNGImporter/PNGImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PROImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PROImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PROImporter/PROImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PROImporter/PROImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PSTOpcodes/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PSTOpcodes/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/PSTOpcodes/PSTOpcodes.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLAudio/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLAudio/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLAudio/SDLAudio.cpp (99%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLAudio/SDLAudio.h (95%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/SDLVideo.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/SDLVideo.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/SDLVideoDriver.inl (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SDLVideo/TileRenderer.inl (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SPLImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SPLImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SPLImporter/SPLImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/SPLImporter/SPLImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/STOImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/STOImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/STOImporter/STOImporter.cpp (97%) rename project/jni/application/gemrb/{src => gemrb}/plugins/STOImporter/STOImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TISImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TISImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TISImporter/TISImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TISImporter/TISImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/TLKImporter.cpp (83%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/TLKImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/TlkOverride.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/TLKImporter/TlkOverride.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WAVReader/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WAVReader/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WAVReader/WAVReader.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WAVReader/WAVReader.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WEDImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WEDImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WEDImporter/WEDImporter.cpp (98%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WEDImporter/WEDImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WMPImporter/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WMPImporter/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WMPImporter/WMPImporter.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/WMPImporter/WMPImporter.h (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ZLibManager/CMakeLists.txt (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ZLibManager/Makefile.am (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ZLibManager/ZLibManager.cpp (100%) rename project/jni/application/gemrb/{src => gemrb}/plugins/ZLibManager/ZLibManager.h (100%) delete mode 100644 project/jni/application/gemrb/src/AUTHORS delete mode 100644 project/jni/application/gemrb/src/COPYING delete mode 100644 project/jni/application/gemrb/src/NEWS delete mode 100644 project/jni/application/gemrb/src/README delete mode 100644 project/jni/application/gemrb/src/TODO delete mode 100644 project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.h delete mode 100644 project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec16.cpp delete mode 100644 project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec8.cpp diff --git a/project/jni/application/gemrb/AndroidAppSettings.cfg b/project/jni/application/gemrb/AndroidAppSettings.cfg index f65c94933..efda239cb 100644 --- a/project/jni/application/gemrb/AndroidAppSettings.cfg +++ b/project/jni/application/gemrb/AndroidAppSettings.cfg @@ -1,11 +1,11 @@ # The application settings for Android libSDL port -AppSettingVersion=15 +AppSettingVersion=16 LibSdlVersion=1.2 AppName="GemRB" AppFullName=net.sourceforge.gemrb ScreenOrientation=h InhibitSuspend=n -AppDataDownloadUrl="GemRB data(local)|data.zip" +AppDataDownloadUrl="GemRB data(local)|data1.zip" SdlVideoResize=y SdlVideoResizeKeepAspect=y NeedDepthBuffer=n @@ -20,12 +20,13 @@ NonBlockingSwapBuffers=n RedefinedKeys="LCTRL c p o e" AppTouchscreenKeyboardKeysAmount=0 AppTouchscreenKeyboardKeysAmountAutoFire=0 +RedefinedKeysScreenKb="LCTRL c p o e" MultiABI=y -AppVersionCode=063 -AppVersionName="0.6.3" +AppVersionCode=0631 +AppVersionName="0.6.3.1" CompiledLibraries="sdl_mixer ogg vorbis openal png python" CustomBuildScript=n -AppCflags='-fexceptions -finline-functions -O2 -DSTATIC_LINK=Yes' +AppCflags='-fexceptions -finline-functions -O3 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF -DTOUCHSCREEN' AppLdflags='' AppSubdirsBuild='' AppUseCrystaXToolchain=y diff --git a/project/jni/application/gemrb/AndroidData/data.zip b/project/jni/application/gemrb/AndroidData/data1.zip similarity index 66% rename from project/jni/application/gemrb/AndroidData/data.zip rename to project/jni/application/gemrb/AndroidData/data1.zip index 8b60a6777465c9a0075457334a9c99ee6531d4e4..cb1398243faf25b233f553e8d81860aaf8412259 100644 GIT binary patch delta 220585 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
1WhS8}F=tlEEd1i4& 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�O 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 z
AB9@j+F%R((k6S-oQQ}$F@7}i;8V#3Uh*}$_CAHnn>?No2yvIL}iq(tWc^-Y| z(8rQrV%uu7RMuW$-0r)!##)EbB;_${nAKwG2U^@(QvduH|Bnm0e&pc3iOi23RM`E0 z7<^28*!(EDt3SQw%!kCskM(P6j<+-S+iO>Uc%IO=pSh;xN5rGYtn&RoDh?mFw)=Oi zy@g*={_7Mc=KA@M9`nfi)@=Du*w^1(-^_llVvWGd<2mOS1slZ#lwW1bK9rjJ{^rMd z2ez*L(vfnN$7PezZ_c2DaW0d#Pw`6SuSwjrrQfbTGiUR$AzzdcAPRAw|Mb_tQ z&)nMcVT>C87 zlfxI*Y4smC^!TgG_4a1>ALS-(bHaTt_dkB38^*QiQNpK9F*(l`U(`x}@Qp+xqv;3a)}GO`lUrFSA~owC-Z=kGrsRjk z;&Y3HHnSOTc4~fF5O7{hcui~mVV00$tCpr&+Jz4t%~#vU&dC3j#=h_@SK5*Pm)E8} z{&dJEiL345?TWM&rmr#@o(8OYabu3*&iesY4O^uH%s5A~{%2fE9s~5Ct?qy-(xRn$zG>p>vH}riHbFtdn)dJ#iDakvHMO6{ces_ zZ1%48ITsM|_7sn+ki}Pv-dk&0e{~(-Q`qxd;ry3``X4LqZOs?`v_EBQ@{+PICnFgB zt*Wkw)V2n#{P8#Oxo~hem-!~&h~O;>{%=BO_)Jom^eUl)t^WGjqK`cF?|ueWZEogz z{oG*9#K>(+wb$70lkT(ryKPzFi^Dt>zfYFE`SABv@$?wi*r(kduO7KIF(^-X^n_J0 zuYA@aum0zj3wgKIt8ahunN7TC8$iS)SC|;&Z&*d>_OV?w&1P^)k7Ud0%dO$i5ek%^GGK#-^RfnXm3HV8g!r zC;P;L@VS3??V5D{BCktMX#GaNx{0sCrv3>!tY+x+v$bK7QJgYUx>fz5@+pP~5=6J= zCP{s1y=7!sp?O%V`|`onvTvL|#9fte37?!wIum`YVQ_YINE+#+_LUw zt;OaPiwKU_ZOwXiGW$+^JpJx)Wa_CoYfVL8bWO4B_F;|xQSiHP?Rg>HyL>mzO4D|8 zD9w?rfnX>%Q~|;sy$JcD(jh(-S_sM zWh}k(PNT`;2-n22(4v!7E@pzZ_s;rnZ?EuPdumm0!&9k=K5NvK+5XRcI437@@7?fx z_Hr(ZWTk{z+l0Rtb-qe|SME4{`*cyMXBy$*F2@3{vlAGp&5wjVJUC|bPl*RiC7eE%P|Keu|{lFSyty!*>dj<@1o zaTn_MG3)IylUT#WJJ-5{_l?p6`EZw0A9#FM=DOxqWF6W5ao4w!uIIl`Gc226I9=xN zCZ>KJ@grY!PHkF0^Ld2hEp`(fhvjzGj)$E~vu12Q;hL6anBA3R_2#O%XG^_YfJ4~H zHRU223tX8e@9c`^O^`|cmm;YmaPZ7Jv1d=&o<5NKQvdaMz>eBG+rl^aoY!2mPE5y8 zWJ3h^2DQ#>>T>#aDi52p^$*-H`urtEY5(S|7yaJrq(4>1|6KFs|AD%vygJ9-{>DwZ zKUH5jb&XbY-=SY@JHjN{zVIrn?7MKoV%}l1go4}mfBPN0R!}uTTuA?QKl{cfPaNGR z8R+)BUFESUu`Bp)eGto$tMNR$h1Nzq&e~(uee6aX)8gK};c?53bL`OHq%>bjC0aG% zbC2qrx4TtE94sBKg*E&!x}|h)y5KS4wC4eFoBu>6U)7nt@ZFBJd@V0zrfkoyif$KL zq&*>?v;Mu-TfNm$7i#)0HXiu3`r*GHm4BV49A*B@@TU8XFpJKCkH&iSW=z72LQ)zF zpLjRaFJ-q=EzU9BnecMm-T4n=m&uwxo*{6i#{A^zBSL2EX>7swSyw39gq%{@pK8?t@BSuj|-DUg}E2C+Uae%Wi`1c zcvDKw#4D_B`P)Uees^4)o;>ApI#>O=u02tYC;vWMXW>(0^v8lJc*W9V)sr+PWbgGb zF7-BisJ~dGTlt|_g43k4E{S#Aua0m|XPHx|J?o?FgmY2LdpC=4^33b>xv?m?V5!Q+ z4K7oTbT_G-oTeJ!9)9`8;YJ9dQMi;MIrS9EfJ>T8u`-W(Xa zS?l%fu&4jmE8p}tp4RYS?Ma5F=&Ig{?J4Jv|DI|3tHvkq%I$gUdgKeO!#qBmUHbm< z%}I%yN_vwc<#=ycp18x|{OW&m{O1$xQg5$%l! zU%J9sm;Bs+r*fLq*Y+FYZ(nqkebTseIB?f3$**%|BaVnZs*$`}-nn_VO`i^f*_%+!?my%#Hm=roMIe`7~Mf z+gpV*vzN@7@uZ8rzFF{wV^jCGgdE28>vm|jS}A@| z5PdA(>&&mO6kOj|epT@MNsc7`=9g#6t$Da!Jv+67?L_}t-FYWfo=sQX5X7`$anYH{ z74P;Zu6Sglwm>N}_n7YaT|yu3PS|X;Zh=_Nj|PW#=khntZtLGI_9mddvF&4T&J3pN zeRJHuzLneU^6CB3x4|~T>66(uH(dXxd)}7A_~Voh{aiho_m-GHIvi-2_(*bRb?Wrf zniU%kG|#^`CI0AtqojL&=T1*w^P}kMv!49)a1Hgctlfbo(YqGDU8Bb6GP}opgM>)0 z_QlW7ubi(45Sv`LUx}0X%$%TEsrTwRVpi5n^c52_*74R}vi78%Gy8L?54RaqzxHgq zG&#g1`Vp7E^NEL92kxHaf5Lp<&v;XIj#kD}hJ#H0+id=J z@J_hc?dg z`3HCEhVr!=X)`Q+WLMsoMIlRB z&wMFz@6|_1r9Jbn6n=c@nCNSFKCf5&q1RJOaZV>D<2loXCU6^WKHKG8XA#yi<@cjg ztFQYXjhM4>(aKqTUmI@;K61Q~E3oHnIm5;Vy=jRhj6(MgZ+~&6V$K%znUec&OnEEd zccai{;&U|@H^1Ea<^@Ota+!@qfBl(OpftXrfl8~gUV`YbD%9LICnuEAeI zkA{4!+VDu%Cei!s-s{(<>RG!ax6N}{!1>)QujKp(Z<~fSi=-JuPSmev&^vhYnWsXy zlf|b{!9(`zP6(bqwt3H2FB@TZ0nf#ECeDwYlfM4m5z8{GoK>w%d9mx}t8+h-3g3Hg z-@9!aSL~bprL^=)_|%OD?7B4L3mq2B6u6-N_+Uyy_1uqQj+UqH7a?X1{oW!RsJ7cSSVM0xomh#g3^;h=yeaJh(pwo0WV|~_Qzx{frLmTH_=2%+2 zN1;kvaPR$pRx)31HLtt2Puh>IDy;0EZG7ta4L_qjZ63cp5HfSp>mY75&0}$!g(f*T z*MG>nz`nE=xW8>wQCv8>UJxzJSGqXA*dY;eR9*u}kUt}wa?meHkKjLtJ zt#hWyoBFfDSrfA5k1|Rdi@kV#y2HfCW!>@Aq`5-%X%?yrXMaumFw=ACi`UCI=j2Sj zV?6J~u_p|Sh9T=q-8CeF9Li0O`I}CA!xSR1d*Tw_{rgV5-*bGf&7seqpBp@Hcyr?W zhRG{0<*l6I`04P^7gKoq?dqrAQ;9HOZ;w6`p4XUkOZJf8>#kP`f1OxvP7?T}YM~}u zFL~y`qt6da*`}_kzg)K5cwUBW$L8|GdhtsP*QRMND@|u_?A>17y=2x}o|V?2m#^## zT2dkyEOqmW`SpUUdrnM{YMlReN>QoY1oCDE&l>QpDxJ!n!)UKDt|E3r*(_lA8N!eh#3oX+f=bYe!m@XKg5`zKRo zA2E7%tT@ri^64|PQ=h6%={{oAOsbs6|H0qm>&b@jT#;H+uW+vhGaOT-qXkD^=qp ztCxWLii7+7Zg_dcDXNNkT=h)1P^jN4SgxsFyDvAyZRNZGCLX`ciA%32{8-77lC{hI zm(KByO;g_-U1ZJm@YFx)y(;~Z6Tj;&lllJY|CZyi(~3L}$p>Z5YFw-qvyypk@z>Lg zCpTR6DhbsK(^fPHa}(aXcJ;=RrBknTRa@9T%~DpDZwfxa%2yZi=wd{uNp16yoFhLv z>SyFjEIGJJb;|p$4UA#iDkYvRlnH(H`}~f|j_PebLTXGYQ@u@A?6uuCvHGj=C5xK< zu3i3t6P4~47%Wcsv-wE5?K+mXb2*i!zvZ}@aQ{@k)tB4qy;ZSRtlV4+PB}c*`}Kdb zv6=esB{x@{KC2=$u}s3rE56~pt4dtQ@xadL^%Ex4XRA6EDevr-*=dpR?BrbanFrL0 zX7)5p?%v#Fv$Oli{M@84L-|m(i?r5c?NGDuH8E2#%VC?$&#Bt`KJ%WBNy?^(*m~Cx&VW#pg)^<(RGu8LiCF|?^H;VlMI_|z;{*;fCI6GPXCuezk9{OLfcygxTk;ZtZtuEd9D~_5com()^ z^kdI+&i(Iu*X91(Fp=rv_O-$p4=&g^u2Y@=_Vy1;hU0(sKkM7NvRCG(WZlst>tyB~ zon3KE!Xt05=5Y&7>1IoX-z)BlJUvh^ut(7>eYU{5cgN@N`kG~%=H{G`zddMc+LFAj zQ9<@9rQE#VW0->67?|VMyZ&sckowEe`zgu7K-xI??UghPzv~cr5jGzHiy} z_10&O`pKS2+se7#`YLw)HsUF4-8biMcDxPm7LJeqI0Nm(bDuppDR%VatAyq(F0-Fg z>u;}rd_LT#Gse)D{d=(3cy)M{oq=f7`WT6j(DVNGt2(hG9u=T5U- z9pGiZDCWhiHe+#(k83~7;$4}Sc>UjuYxDkCCjVM#$o|~pp8YcG*Pq{TS#mCm`!|pM ze$x7nYoj?oC2Oq<`E0*iQ#mT{b@boO-wjlFBnmIo7dsj>$E`O#vM6B6+Q)&@&zyUF zI%je6_PIfI4==MSH6K2;)+NZMy>D);SL%hr;&%r)EaH28%y(L@nbTvsUgE-~QxS_F z?XS(?D(Y>JjO@6lS`~hTWA(l1Eg!3lm2$R6z1@-I#?pOvPM2&-pdzER9n+-r=&76^ z(#}}SGvsWP)UJQ9LR?(!v*-F5D-7+EYQPzD>r_rI80J?4Z=ZXNm_=&V>R^|0-Wq>N&jGSerK%(&Qx zIj=Tpt~o829C_x|mgu#i=0Rz1OY`$LT>kww!#78X@t4K7kQ(Evat-Z7@4_2anGX-L zZsuNpeERemh11T?Oxe8kVqe{j%JPoiMfRTzZR>Z>D{k(%8W1e)!spB&;1l7T6~1kT zUVf$6W$8U{%B<2Baq>->QTuu3bBnn?H-GpEO3zqn)3|1{mVl<;&(9yluc@DC&@wZ3 zuG;q0i@|QkdKI%f@1m;nO%?s0I^DYQt#JL;jbC+sJ)G|NK4HuL^K1bh`X9IMQL^J} zI+1qn=+YH!^*`Mg9XosUiO4z5r;)}ohVh5DZuRJ^J(GAeYHp%lyk2U;_5Z>-2KUz7 zXV|tp{_A;G<5v4m_b)V79=lt9K~ewIj${5Dthc8vIJIbf_`{3)&RCd;epD{p-lY+< z!}-J`9q`s`lCA;H=|w`>YC(iKUF?R#vF6~zy3b!A@a2bQ{Jc^}bCY{~3r%&=h!2Rj= zZwp_%H*?Nh=aO7?sVR-6?#OD-vdU{cZ>HQ{lgZp!?sEIuj{uH#XT9H(uWdeSB2w?# zy{Lg{XXDNXw|(Z#dAM_jgW-*@cNc!XdSLcV*OiZc6*yEz`Z00DM@?5de#dLO&C+`< z`G4=#)f*hylBay8YDwFc6(4=&4>LVm!Dcxl-KOuJk`V_Z`y>sKqk4Z5(!WbAc*xj( zote|lVzy4D(}~SD<}6J;eI$dc?NgNT7W-TFcJ(s6{&Bs(-uD@NmW>SwJ74JOdybc{ z`Hoq~#hKe*b9d-lv|R_2J`3uPY^n9yN=NY02+6eRA3Qo1fRe&Z#@S zJlRL;YN_JaeR+E>Nd>Y68mu{YH{-PB?}Ln5uhtlSja{bwM4!z>`B$BT@g;qBmgjtb z+hP_lPc52KKfhzf8o~RC+6Po_RX^nlR)bQ zvz58eLhhYXKGUQTu4o|V_+`n)z}rjGjr--e7tOJ^nAyaUb-X^U)ahc_qzCVMHx)Js zBt6R!K4fe1@!KWl&|ASt?IMC#KSmpSS|44x-hnrH3CF{*H?2j!lje9G4Z3XT)#Y)s z@BdGOHqU#XcnrFI1Ew0^jtXb&5O6ve{aQhV+sfg^x3!&eP7F;NJo7B0j(Rh+uB(1L zUrO}{&kAd)Qm*#I>z1eL7j^MJo^&+S+V1lst-p8vysTT&a_+aoYxZ;IE@5Al^d&K-Kzvd(Iv3U_JTXq0+Rj>!+-!97jSa zgDm5!RlAj*RD5_{_`cwRwWSmfd#%Z|LwjrdYHq%*JHb9zBBa~5^InpnHETVy=Yw@0 zqcU9y|&Xo_F<{_Q5Y=^;gB_N0dj%iqC60=K1jbe8o7|j;Bx9?gbq& zj+>}a#3^U;=Blor{-*Ocvt+H(_$ABM=(TRhiGEl6^85KC`9C|PbAGjc*<4r5$XCnk zG$HE@8PeW1a2#>b6t0?g!SjI zWbvSSP7|IMn`aC1Y+q~(dhVjRj%D(dL-iH&?|t09l~H6>+?)1EYtAQa53H**p2sn{ zr}xzIlOg}^N&mMDX04vQ^3P!gmsb{Zesm^$GIx0RzTkY^;VBwZ_TK$_@ge8uNsd?6 zyhuBJpvqp*z_nuLx2oN{*EfV5_iniNrOea2vCDShwCWZ049n|kI(x*b#r}WYpL8*# zKXk{7J$n5$Tbhbhr`+3?P@D0W*YeOp23gC=PK;*Suit*jU$Ff)|B~%rBiL5>hB>e0 zNRBz2a8=0UxCKvyes%Ey=7m$&?Cf5fxNF(>)NBs+7YQ{}&z7f6nD(IV4ZnLoi}d$p zxf7L}R&LO5z9ckbRd>CRhHhi$F3rY^OgkhmYDy(>yma63A|PbL?FDO>_(<~h-8`Tv zn|AL0^u4w>xaD|ncD%c?Wa5IGfBLUo|6E*t@kxWGowq^p++Pbt7OM*UyQq2g&{gX? z;|r_!8_m2MJ`^fCADt$++$}`t`KmR|4-I|4D!$)5NpP=K@9d&xvxRp|b?YUQ9u$am z{LeRADS745JngwoAr`ZuMP8MrJp1Y6XP=sWDZuESZ(5kD=FuDjCTW`x^)t?E49l14 zi>@orwBC3->_*cqwP|-`rTpI>>oknCHx%cy)p!jPWj{I@(34dD_ZIe7hVZV1~)W^t*S8daK zIW9M@JXg=GgBoa(}x0P^+qxGYHL8nj*5dNMVvy;oo}IMc$8?mI?@l+`IS7{28wX zTN!TV^fyQiAM?kEIG*&KFbFS z-rntXXiqT%S4DHjA~p9XGTj!h7OvWJCf71N)_q`(J^>5l#+?JoU zP+(Sv$=!^X*-=dg4`lDIx_bL62xNKit+ofWjl9Q8qV8)ZrP_pt(Aff|If~;Xp6|QD!Lc*#54bLbEdHK z^(@WrIky;gzZNW2Ilsd6USioko`tHNwFZpV>2(V>ar?4(#C`dq{Ap9;yOv$ktN0Zk zW_!%Pe1kh=;bpOqg!O`_-fe4r#rOAFw(63{b8qm6)-QZ+7IC6AmBsL+)&Y(63T0+i zTc)=uMqM~w_NIB|g~MLUxL7y2Z#yCK?K-DPr|5GZ=PeDI(i`PhojMS{d7h8KY}2D` zg>h>Q4)5rD*|zQiSHy<<6~f{{J5RJUuW2+We)?d`54rb^b^Nkg-ka{e+Qgy|^^r@+ za;D$3$sbi!`X}+%mkTl-U9Y}-jhM+1PQ^WpbqS@0muJ;QNnX;QEXm@TRh4--YSq2+)4yw+o3=|GJz}9{YQ2WLJws&X z{fsR$j`I|~;onk!IXQ+wa=-Gv1^HR2Af{4Cyc-<&sip4nHIswsCWT6rHY$^0{Ol~+;ljL-@8!LC&u ziGOs;R#hLm(6#1L*qnZaCrkEnm}yKpvHV8&gkMfi_IaM1t+D4|u`7>{jF#4`zex`! z?42yLd%eWQt)^iS=2zqbx+MEO+v*=%+7u_QX%U##bbUb>o8fi=##dF6a=BF%du(3J z;qWx(EcDlr@2m2oZ)T?N{F%e>WY?*t$(s#2QeU26(@sfeES8#IX}sBN z!qeXM)vHW@&$(x_GkKQd-m0$494Dt_Z>rmVx;SUTxvSsYC)g$BFAsb9X||2N>WRCW zzdcOEYnoT@FuyR9iF?22ucWh8{SQvgmVSBnxm%QbW!{o!cRaMu^ZEsHNrK+LH*?bOCoYlW`{lnbFZ@3{>TYN-SsYfa+ednz;n(B$+MDtdPZq1}k+dJ((C7?lXg&BsP8j z8h-ZeKD(I1m^eX>?^QfKpKtp8Gt5fc&+cKCfm;4{AM*w%bKybeOUz)Ud?p{ZL6y!s z3Rk-CIP(Q2UXW4tu8%DFnHU)ArZ*gAmfODb6tgVUj9X`zU6{ZDBq2O!$z2Wx1_rt5 zjYpYfw|kyvehqc9#SP~9JP^O%e!`r{3Sm0DVoqZNuXnsD?=(Atfq|hAtlM!uvv56Z zTNdqhWhpPnMBA3-W3h1UcV-5LTuz4VTR$+%L&N^Y7iJl#lYjhVPUMHUK9-Xu2P%4& zk3|w1;jctk4nVc7lVs6?ir$fD5fTLl(kYg!x!PO|4Ed^{MWiCr1x#6Z>ZNWM-SYT$ zv&L0?-K|E>Z%z6)Jdg1korth*&`_D=yEJHuj_Czq&$Uxsgu>4rKX18KdKbf{bhA2x zMZfR-y5rv+T=ebr%8Qc6Cn_!W=1KXYI zZ#S!iCtX|MtGDa!Y2zQ|u3vb2FQ(ho|8Jg^_*i7YS6=Rp=byLcTd>H5+bvaju=>O9 zhnK%UnVH|2x#P%kF>a^%wz>5U&6gfcd=JZWT(RZh86>#xyVJHKXe z9Yg*7ldJ+AGmnT^xBOm`+M=<|e@A;p?u4&18;Xq1d_FZfoqY>OG3!m&PO2Brg(`n&$E&?`~$wV&93sYcKDtN(jOF(07~3#tyZ>FWx#WndL`q`b=u8GBW6v$nPeAi`g2Z( zNUGD@x8b^xjGFDupe3DW_!cSGGi9?W%*dVC`?0qv)c4fB#t1gUgW0cUo_Y2zN=6{T zn0KFgj%$ou*@^P`jr}cqa(oV)J9Cp!-t4^flU?i%ZNIOw&COP9VD4n!#`KBb?0H@L zozDs`A39xj)r;?q`@W|9=G)Q}PLn?b@LoCW6u3H*pI-Ah~h1^=hSda`sM z6yDe-(lnb*h3&WLt%MTE7PpA4IiF9Z_TTz;u1fi-_({iiC#LMK-(uLDdp{wuE>!fQ zu!vZ0Hvg8~P$d(cT}rFm?<&0y`yKl@CHJ%XhmD8g+Mjroddy4h3KLr9+?8Y^rT$>r z%75qC&G=VzMXCrcb~2mdvtVK1`Kbvnq_aIXWvedXJK_88od>_8pN(*zq+>5ndtb(i zKxrZEt!d1>0y$g{I4Zd0>fc<}5LB3Gu{Wjfr%O18z)y8GWntE>0_KbCzwA_hvLH;Q zExqi-%~Y4WO}_j;1UBs}mrYsty}bN^&T$M+qKMyr6)L6cGdd@o7$rN zU7oeDHEvv%{J8TL%Y~II@}@*dOkUpjk#{jKqh(3dnbwpiN2hfs?+DC1t6X={!m_XN z=PHI)vlRy466a^mnexE<)SGuw<;TOf-D}x(J0np*^d^IGre0>bb!er$Mj9Ve>HUR) zSLUhJS8^NqG`P;W{cZ9?b3c=h75vkD-qi6`nmzN1`de4c&enPAME@3%O3p?4TMx#_ z_P<~HGia{f#_LiiWsR0!c*-_=QicMXq-&9eQ=eGS@vyE$rmuzu9(@hQ(wd@_6KD)Yen_AQ0oGffX)v)u0dY+~5^ zMYm7q%T8M~zgd@aI|%QHNp zZtjNZ4_+UP6E4Z`yScvpr?IMAtK7sNVJ@$ZC1f-{&~{1V-FyF^&tChc9Cp6K%Hq54 z<#=b$Us=Yxr6S_N>+OMcUwHa|i7mN(_)>g%@e~t@n2f+V8?AoC%E{H+KMjf163$e4 z-+iXY!k;m2db?7JY2^B)GatrC9keeEyVm#0>-L1x|8E=VhdISG^hbPn_57uRwbrTh zAAKI)ZUQELi`13{9eURvC;ne=V+`kxnhkfqT;QJg=$P`eYu_DpzjExm>-|AX^@W7} zD?#IL0=xHg1~C?g&$+>IK`}c=v)+ceYwlG=6O-445l<~H$VWuEBwkk7%D+IQ_2v@x zX)UgQZ!#wzy7FPC=C|4Li~JbVKh8~4JSy(%+!f);6L|m2qlM~`|L%meoz+izVfiGx z@U;63&Y*lM| zy`$BN3`cEqm;U)Z3Cq>WZDu7tWNGb}77Ou`=)dQAdN) z>Wbif)jyS-%=YQ<#0h@N$=@UXSiwl>kc(Baby&Tt^1G>j=5J7%cdzwrmE^}oa|DA^ z&*VIw`779P&qKpqZ>N7}W6rr*wOgxiMbgxs6;1|zDX~)e?5`q9%$c4(lISuDeO@`` zbh5^!`Yw%d_kb<;r)J7M{>8zj;_)|7Z^KJ@$4Sp7FG?|Y50Fz;J!)|)lxLBafV!2g zbfJ;W$<)3b_3PPxi(i)ZP?-6k(|F5ofj50YTke~%^IcJ*}|;DRn)OTQdJt zO4i36oqzpfy8XXBouA)mOK*@gR=kpNa^mFIA`1^6nZ7bRZ?1Yr*5r5h3KD;wE^}#U z2)k_EZ&9`GflEc1)D^}gqSs5#OuQoBqm zc(2~~?bSQ-_mu6sdAs66p^4Q0-$DP5#r->=ch*Ku=pF(!Ycc1+E{@gbW zL$BF)x{nn{E!Es4p76$Z(dW61y!YoO-m5RqNYIKsrm{XFE1^U4nP|nW#h(HWtq!RF z%Duk#)T!#9nqDThuhO>f=j!?Pa(46exl@khmw!-~xZ=3RhWq5fI@{c31sND#hQV8)tlPJTvRoDfOLubxE*6ksU|=prNY@9s zI_niw9MbmyW!k3W7oI^Wu?Mnh(j^)88f6Ou1&Oh1$M zk2~{r|Cwb=_C`eRdcT9=Qpq%Zz3Mr?mt4`AT)%43mA;4Ttt8K{oMTro_x{R<;(Ux% zHtBMayUs0MtkME!AN$EAmVe)5Erkg#D#y4AV}dT#rrcINC$xNO<8^VS zQ<3LwJg3y?F7TXj_Tss@svgGdEeiL|(;`#6PM%u4d1@#l4}-T|$+7Q$PtM5L+yA85 zOeSmZ$K&%E#HR7gyQHpVu<_`nqy~wUqEhK=XJ;}twSU`C$#1-+ezxCs<9{7@?w1|g z`z^yI@3-@!iH&A5<+CQQGgE0kS#Uvqt3QWiU<%jO>Fc76m}9uvMKXfo)2FGY{Np(N zk}-Xn=d)kJt*NFO)lBD z&J#6Adc4F*N{iv;w{Y$$cAx4QWdiPOl3cKVtIYAW6QqxS7X0I=>=hb1HF@i@6{1Fx znHnLCUkzUJ+&(KT@L)zo+v#ch+Q0A~{}y{(=~zs8DKjs_lhT+7*0kB@%uUMD71bZ# z2r}QtwCnGGZIOgp+3Vu}MC)dj%sQ9!@W#Q0A7onWPG9t$;Ms6|#)AhNC;EQaAt7UDCo(hOhJtLy z&j$^+f1T|3wf}`cNw?s^F43YjN^7^iDgV{vb;qK)l1FF5mxY(JzuMRQTx$I4PRZ@3 z0xyruGoE~?KIh=4W&LwOpn>z+80!3MKhUA2)M!MVE%m9Uyt{S z@lgWxUKXsbMJx9gUX6>A?_f+BHH(MC~UAR17;t6}tU%n}dXV|Vso+_=M(71iV4m0bpodp}J z*?wJS6Uj13e7Q+?LBR&r{Yzz3cZE!x8m}wAVy_Uh@5Bb1FJB^N1ZdqB9Z*|@4oLV`F-~L z+c2JY*DlHL_1zKo-}|}a?(F)>|0n%uc3f^bkLR|+!3U>T*gn%SI>Gs_X?bbTEay{- z#%!MJ=A2zC^_Z!cw`b+_ubXdFNM~u(Pqu!N%uzb&g0k99ht30MrzE;=nzKJ;a(;~3 zMfUKOZ@vGkDM%zX**)HsS{z{Q{b)hi%^T6oxqiA%_aYoGZb_)WAZryc$s*v~tNPwr z3yGi`W)+`zSWZ4%xc}<@M{i7-^A4S<_@VLY^jZ$#vkL^0LZ+yBH*MzSlsW$C=As`*0x1Y zM7I3v=gc~&c3o-p)4qW6c>)>du71AWYaII|bra9xGj>ZOXEk^}-m``y%i>PHiR|gZ z=o~ZUr3%N(ziMvPI@02(^LpXCWBu<%)@=W|*@3@CPekOw%wD!DYz?!bg#P4e?P%aV zU^|Ob{Lj>5^`)iaw|8&+FKYL$^!>4o;rB8;4eh2(W1A!<@Fa|VjbhB@OSbRDnvQdc zsW#Y{B(Tn8oLx7A;p*}m6(9F7nOSW3BK|7LkmZ5snzRLVFMX@lZoBqsTYYBv&vo8G z(z~@iX14#E)2LaQ!qsY$vtxPinoQr?h4zM!U60Q#xSh!_ zyh5kc+g!5czvb1nGBxE}`~TkCdo8yiq1)A;w}42G|Qnjif|7tP%7 zY`LkyLpgMVT*Y;Vnb+<&E@WdDEIxTVg8#XSi@wv`tx-38bDACcv?eEC>R8wReD~5X zC-=X&#^v?Z>W92~iAZAC6wk`FmjfJ?@3T(U41K+|O0?<0;^cF($5~Q+O2z*f)Zbm# z@N<{i8nf?wA2Q32K6uSD`|y>u0uP>Mw|XeA5fDGD$g}(0#@Ke>SiBM&`Qx+uJ7d+5B58z_Ui)_Dl8q>-X8B z#4m-iybpMNcWe9W_ggil1=iol;r~7H_|@}=>fc12iEdJ5z3U@saHuv`XI1;nGu+!x zIx@d;iFT?oRD54&WH2xG`~!Q}pD{Yio1Nw^ib=82Z|ZzAt3O)g;H9jIPh}O#Hm~k= zbCRCSey6j0%MXv*N4hHyI#f+u#kf1KadTq#jcDK4yA1~x&ffp|S)$eU@Ff*3ZZaF1 z!)7jA7QC)recb}*95xQ|t%cFuEzc8Lt~CFh_(xz{@SmeW22BAx)*tWaB_^NP>)A13 zA!p{&`8U$=8XD}=Duz9=nk?Vr+RW%so!bz|U{N^{RyT9tgmyiB0)K63@{jsY5!R)os();LM#_Gmj54VODon33Qn(KdlnBI|WqZMV0iIF8M zEO%yaNSYFPfp4#|$LFMq#nT?>G5HJlGo8OAY`!yW)1hObX)aT?Y}n2u*?UW3hmp)< zbL;vIVdtlIpPs|0E4!+!EOM^^+rK?`1lQNgz6oIYzU_Hx+8owx`b(d;dDn~RS22~Z zO%S-@Dp+{p+r-yNFBK1Q?bz~Xg3jbMN4S-4-BRU@IoD;W`FirYTdOXuNMl=(&}t|7 zYtqkMrLm$CmhGAg*_I_HW(J*quwh0CkB?Oli`=Z%wCfp4V!U&v^nChwbLNKECGUC` zD`~#-5p8Vjp0mffG|21eXSuL-SB$kM)yKH?Eo`1GV{nSuRBYw?=N(?Q>*Y_iMlPR} z@j+FfcJm$o*Jbaj_;YW#OjM9PTByqM%w*Y*H4dr|xdp`IpYMySSvB|l%IRn3&i&^7 zdz-yX`LW4i(dR7gC3n4;c}mG`XVYC?^-jU=+Z#M&4iEHWF{@u%G=_c4uVu zR*|Ns>9*lqg07`~qBq{Ch&G-2r=@*nb?DZ*u#>xU9nMa!d9&o(yiXrP*T%=hy*YY4 z@S=_Ovy{Bm)l;J*uYRtb+M3T;Is4>e-J=KgD8(MTZl+fsy7KCG1HChIH@$3S<@j8a zwkK|zgLnR)r!M?TS9e%Wa1PMjD*yLqSV-5mFJ3mMdfKN>xg*WC=%c~zN``LFK94Kk z4nHz;(|=L(rFtf->)LtBCPz6YIUnB0xqX4oUlS>%1iSU^F-n;BK^Nx(= znl`03-qctz$>2hIVUkQ#(&z2c)r+bwzo)m5uHuY2HRO^C6jt&b}{Ir|5PtqzufWN|O zTHyCmsjlf?k5$SopT>BsKrHyqtsjBbIiC(rvk*BIy0jqjL^I!Rxf)5aGCt<)OO66L z2VOWCWcn{v-db3-L~FUbL`KtJrG1L^6GH4okDs&s+&%xYrP<1(VrP~=6Q94IZ_QQh zB^9AZ()M#lt2J)!(fPD>&&9oKVg)Bk>lAUEZavQTvvSIvE7@6V1G_J^KRw2CfB*ZQ z)7fe*z0VVr?H^`6_E8Kxb!yg~1Epza4#XWloqahZ*dyy5Q_~TLlFs<4FP^qmO;gGU zI#5~vxbbZz-^G*v4_wju_F-TDv!1B519!{wb{%Ro6q99{IAOlev-Vwy^5=DhndRTB z%vP}|VfdE`8$_dT%KVqx7CuTiDCBvwLi8`^LM=8GRY@p&lZ8lGoK!b zir#rOH2cc=#kYh)u5lmbf1KJn?Qb}TN1VzJ1xvNS`~&sL*P5mmh1qa%$zGa&HYMX= zc&3tA>7Hv|+wC4?J<8TOAu;pmjj$CRyR)h)f=?$ZaG7jhJyR~?@ukvbzpg~NJMiC+ zli1}iFY8lVQR_J0%74p*dAwDtkBUrMYCO48F?pw%OG`$*Aiw*c1eg3z1()T%V-lZ~oRx5tlJSI%X9HA&L7n!G$M&hn1QrA-3$$)|g+tA+cDez?hAHRHpF02coD zYrn0(8GYn$@~&0KSmT7FHh+3>BmN}&vzh0bJ}mmuwP$OkL}h#F>T4qPIz{3f_vbuM zGqK6DEZdhr)o_0}NoTBV=FGBl+%<+5AjI$Qiv(JC-r8GZq)6=3a zd>8&bZC!Xf#N^?jvcqm)4lz3)GCaKSfyMb_24!BG9^bJ$o3OQPX6=K-WNY3>CaI5~ znAJ~ES-);#L`}E)5h>nVci*kO_R_B{S1*XzWx{ocOFY|rlf>klOVoAMyo zM()Ii8=8e-b%nK>Zxbf-A9U{c8Z5}(c18M@8 zm0IR`s*8+W`VMAYllhWhuC{)y%;9I=kfaMixObYAkqrRjz9#NP@` z4OlfRJyQFd`YqXd-mgk)EBJrEWb6;z&A&@<-#^i^nU3#ctr$d{H^}!+S$U(i;;Yft zdpGogCtiqZS+{RfJFdO&W_j$N{>%2?-na9q3mG>#lSD&+oujAP1kDq4ED3&g0I@NEi zl$E4-sZ&q&o{h_S`C{j|{hUuken{L}BjK#}Gr)4$D&g~mwR?m_w7h%LT~pgGe_T@U zyesqJLyqbH*r$sz2J?2`U)p^mw4?O$8a}?KTdn`3pZZa_&p&d#M*i(v6-%aV_75st zkR`Vu%JOmQg?a0DWT$W4e8ymN;+2?BvSz&oXKIcq-&np?OU$3oFYx|8-Hq~Dp_K`W z0r%87|NXqraLiYbeaXLI-i!Q>LVKPCRrzj_Evzrt5D{s2`mu9UbBXcs<^v$kM) z($XzoiuoF1+F$HwUTiigarML})1{ZMIKo;yQQN^H{zZ0g@!yQ#3XfXPL%$d7=RNs- z`qcSK3@%UY>rcLX_-m5mlUMa7JM9e4-9{uIf{r(;DwN;W`0nhGvo;a?D}QJ#(VuM`kx_U1V^(!?aGQPo)eU(i3zhPim;C9t zI{SR2{<3WoO{b)!B(Py%eQShpqX=H z%H#Dj8k;w(^~G14WnI#*erBXxIkH74YteQ2!^@)gEs|A^ta-_M zl>Nd+-}O#)9}yO z-LK+hED}dj4y>5Wx;fmgA@p?$-|45Ffx-1FKg@T3{e73br?XRMyBYhR>-z;x+TMHE z;Thmm+gkJ5n8#49`jC8kuym@?b=8lbR~@?fk;U|nEXRb^jQ_)5zy7Qt<9USpqj-I3 z0grKr$CIe6pY@3gShFfV&)k3inBv>n|C$W$ES)Z)vF}Hc*OUW>nyn}NIPELgbrPQn z%q%(;sVBps8|$nPVgI|)UYps6*MTegea5{znf!03eJlLpmS-SnYjs`hL2bPePlLtM z3z<0*(UNwR(hsWKEhgW0e0cxl_w5#+=SCc^fB)!~xj5r0`MUq<&J&ey8V63@e7f7C z>rB((&E9{0UMwv-C7LjO(KEdwwI$mY#mJ~GvJb!FYj%lY>Kfzz+xiKInFTvSR&ADz za}YA$Q*ij7-TKMw9m?+~ZolmJ;8CJ|Lj9MoB43O=J-KQ!q7^=b%#--3b>!2NT|!=u ze!GVT`X$$YnEf^QnCxX1MWuZ2Lic02kJ}eLsdb2DjxV+S#40eUpzNQ>?;!nb&L0Qj zllRX%SGVPf@6X=Owef4XJ;aQHudL;aK5%Q8kG`rA@FcwNqaTOV+>yVs&Yb}46BplrQ7a|2d zIhLrNeG#>>=bYDfiz5zi9XH5xB}722`1y>IC; z)k4dcJQuFVY6x_?O#FP3q4riQ(?pLcrQBUyNA*NHTo&a-1%#X^UFe`9v@|1oUf=K=dq_b^;1sbhBDbR?494& zuTfRHzOMeK!pC=0x3WCBRjR*m=Z)QSRxal$*Sc$F+>n{^Qgv(IrpvdwoHKHZHXh(V z`Fi?UrmNc*Is6I!xN7Gk^=Uh5n^(HpY(BD9_lVfbVDDRNI+Lccg^2~6OUQjz8XY** zKG8d2Nqt&=z1;`VHv6)yKbkpdH@es?KAxN`%lCXi&SZHjjav#m%&nzox83^TVtC}y z8LdrguD52-%Y47k*LN+Kr0kU}z2M5)`@Xfu9yBxiY;JqE`>2j{gWV_JplMa-Cn=~J z=_P!vHe0!CzwCFWf2FtjH?Q<%*ZjC?xsS-hy^(pLTt2JoZ$}t?y~zDh=xJ&19NF+S z1?_g*PAwLGaxUPSM*o=&F876uzAjnk5t-XDF>y=k6BVf{$Jt&RmmJw!VRT~smbA>^ z|54T9eTtb<$wzA{twZhXm;cZ?@%WxYd`+D|?FQk%!&X=1=kJfV7x#$0zWV2vSGV6j z6>0qW^7NN-)u-3)B`>KLVQGnwRlPFvTUC>Y>Xwd0PwGz0%{jBq;oZvmGKXm|s#`v8 zz1-irz3Ob!y=|^Xc2`xOzhZRW`+ld6l=q+h+jq}SRN3YI5 z!TW{c&XbNDPgqgn*0`=i<4~x~E6oee7tQ_#7CJ78KCyoG^W_ES6DRVrxX*3!h{-Q) zJECRrPUeu*zJ=`@l-EA;Fh8ns(R2&j;`(h7cJp1@tIe(*@9=7#`g~XBed}+p4JVzf zzh6G(i^jr<#%rr&%~o(Veww#<)l3C@kvR?zrdMXoH9F8N#(q(?cm9JImYrV>Z0f!q zy06#4|9>{?s--vAAO3n?((&r)O25OwpC{U0-+Gm6zrqEHHFL{Xty@=8aLP(?Q`3#u z#)9D9qxH)^g`F;|SzJD4PO7M+x6%7KewI1!|0i3i{*iIMv*grU(cj^sQn5+PZQXW&<+si~7iOPo9JJ2rbh+p;_MK$hY~fA+~A+c!`4VC}tkxVW|>{e10vDfxg_ z#si}3b5~XQ3M~*3JRxAbVYyA|BjvTX7MYfn`F*zgzVt*#y*=~eQ&SZWzyI#z&$i(F zl4VBgZoZmX+Ie2<@H+;1{-@G0zHUEu8(W|wWm-6<-+%#wtR+Wvo`#Am8hh(Fx@41Z{4c;*X zrta`hx;*>ei2$qK_rdehlD=@WHg|QIZixDK!0N}YHFY00cWpaVF|)4W<^Gp#@$vFy z|0f;i*Nx7)XybYL)-va$3p__Rx{90cS`st*Z=dQuEU%$ zOKpn<2Ll6>9Apt=&t`tE?dN+~oH+PED-T~D5N}lFVqj3#Ma)M|x0uQzQGb4C<%=f` zlOwzt5;rf-5K&~G^`N^@`L@dB-(SM-zTMtycyeCa`-vxAF05O(YTfbmtGHhke0hEG z*VXtS_IQud9crsTs>(Dz)6qHpDc-SEPPe^b*R31N{9{#KUi!K^+g7hOqhxl0&S`b` zAJ0X4R5`cx$Nb_q`n=RCNZR{!^Hy*9`q*ODA4Ly^nB-!A=r8lOJFI>8z?qT*s>P>2 z$G%Q{EWDw{VD8WOom)ibMt6sA+fw-K2&??kA4g&<9mM~f{hH8}B>QNVS&te2Hq+*P zrpkTp1=~9}-JG>urMRNvsr0%TY*h;wV*;OK{}L;;W8U~-C-?ayUq9H&C^tKJ9N5Tu zrM0d8rSaC-1=-uycJA88B&B}urk+h@%>l~@zVzKovTe=^Nj~}+r*pfFok_Z1$E=Lo zQbD)oa?k9CM;KBI*zZsI7$GT9K7XQEY@7c{W5GFVuHM=YBB7b={Mzr=DG9g9AL}z#tj=YaYp`_2&uzEG#7<

IPX@TOb;-6vhxe&wrco@>5Z)bw>>S5E5I2tQgHP}85FCd|*Y zEB+{Rx6fJ0%|ScXmGowYU*z>PdJ%Ov$z#Hw3; z@3_I%%Wr;kcWzdaaK2{mS@oSmw8;0g|9ZZ+Kc}(V@b8r=eYnd+om*mE=VaT+#Xmh) z+1~oXm~8ZU4Xb9DuE%S^+|!vin$}3^a-7xnH0615BKPe&Ut6OT1`(~01*(@P=APEs zd^IXebd<8Z&sh}czGl;s<>%)>!q7K8P6A~ zK9|3<)pQk?L>jZ!>zIS<4Bl|cKcA@6QTOYRvGby z59((hDb$wom3B$v-udNXc2ix;j21h=7j5r;Xq?uyn4X$4|9kourPHiZ$9-4cIe+uQ zm8uW5@FS>#rZCvAju=S3XllBvd-7>3h*LQW;?78zJ;*?VU*7cq81#QRf z&zQ}^czbEm>jvF9%lrbjzkGVcpsiW+U*EACaw;)qMJJ8_ecv?R^$vAE1pn_k zeul|RUxI(mboHwd>k~K5JDD2UG|7Tz+RLIcHu(ctZXu!~Qo=dDdsCN)>qlksg>U=$ zBGs~I>O3=%^%q0y7r!hx!}sa!e=B&S>mwvKD>7;SaW`k%GtjvU7=E;q@{*kq$H zWquX&7j|aPZ}R?4{BFK=y2%mdS((du?cSLj?3}aRaV1;oy2o>!UKrNbwlTf&K63pL zgOzLC%4fRVryd?=&b!nR>sH{yYP4ReT4dcxsp|Ym?5huz_U%aQOwPS&wyNpa8?&A$ z!5bA@53TFj{&2tLm!qC*)PAjObVzZke`ZMxu>%~dtBvpUYW z$I7mrbCz+}v;B`+-)ko*Y!G4h@0<-%iX1a%^Bzgda5?nh zTZ?;UNuRa4_*wpn*|`PJ3~&m`8Wgg?J5-X|?O7+)44-E^Wp!acx?yxJT0L+=JpAOFqk0Kg|tSQs1X~L#45; zneCqU!i}Hy$$#3O{3tQkde8X@VuxNNSX|AUn%%gVIrYNoO`83C-=z51soU>)uD&|1 zGx)FHL)VF?6}Gv5dn)s}H}cccGnU&wN@ia-KUP+6`?%ZS`SEVgOY8tXkc-_2EDA2D62rh7*Y`>y5n>=#1WC*7XUro5XkPSWktSw9xV-9PeM z1>UH-sHhx#$gBDD{)~xRt<>5rKS!2TZYXS$+;rAMFz&3n(z1K~df&8)S6(xf-Je}m zw{K(8bgp@ZEAss>Pd&Zwmavt1eP+qN8cy|HzIGWsKNdV-auX=3zr=eqV0qMf&ixG) zcY~+OeNM4&DeZti>J?Yrpy`l?i|IZ+`G;%pZ5GdbT8KiaBgXtknd zvi9LELT{56Ete|6lrzHqpB`V^@@DPx%SR48Zmbmxwd?V^yW|M(n&Prsmi}vtL(UyY4VNsrTBptO zvE1bENv)1`{L7?f3iyi2F_wf~C{7SeIw!VOyK?n8^RxGV&igH~|I_SCszEso%Jph3 zXIZy}W*lr^8DI5w>f`MEXV;=bcAmDKF84|8){+SEbGvplXLl_>%JrqgT$t;Maq6%BK2gGsqrbi~J9Csm1 z4VicNs=ex0-PcH5>g6!?z$)Fna}KQRYMy(k{-*EEE6bx&x&xf0)9q}ZL>omtpPg~f ze)Enx?TY@uL&i5b@88U>auqmV%M-))H1ZLX!}&>54*c5Yzu`!~OMtt7JJ!|Z|d8XLyw7BR0@{-T3wKV}g z$#?JbS03e@*M084`p^GWlgh2+`~B{W*4R&0eXVz0S0e9&KL01-z4nh5|MiJE(OvsWuFz{{ zvG#PX&oj(x&TiscWt<)#5F3$k`-SxUOX$nv%KeiMtYl?ia1xl_IG;ta{%H8^yhk1a zwSD^+xyXsRwH)1fCPi%)J3Eh~Qln|wVjIQdc?-&O%x~u%`tZH_mYMnElu1{;q@Om1 zgkOI;C)oA*lyi1-b+2XVCDj=Ctvs#teA>Ac;{KIquFiT>aV*)bYzvRAs!B{$(#B~u zX5k^ZS6}S8xksV=+^5;jn*Wma8Tr*ed~vSQiCZ)6Qa6YE@=1nXM?%)xoXpG6o%W>K z&{OP#i|4;RAw4^k^!e)igE{!E zUwLlVE!=int|&X&D4o%E{bg?1*n=AD8?2ZLZI8OvIQKk`xx_u0^WU;!mJ^eo2)K9XVPxzv;S7J)1CexkUey{n=*W8ZV z|J?57D{I^D2jzNK7#EyawD9SUz1Mc+TbjsNA3k`ZKJP-u%ULE>>z%!WTe?_2aL@Qu zF(XCSzVR$eYb)c~z2a+|oDqk0lcWM1E!#}hqy;@$1h>+UXlf8|bO?CF=c>h%QIEKA(dz|}up zXE)F7=8l;U4PK~9RRyi(=Vwby_^HX`{;hhN%DpuLCpd0QiCX9pp%}RJ+gXc7C%&^A z=FSOHcywRn=dZ9;lIO#{HT0RKXGLXN?G-=BJjQ8zN7Sb*!|vUDM*_mXKYqH(^Q8d5eq^et+Xb+FPTp9b^8za#QofL*GtB&1iij zxm9)><64mdBd=LY-%EPz$~<``=-7u@#Y?#MN-~_u+SSaMq8uH`Q~UkGC5ht;KQO(G ze^aUa^vuShnAFABkF728oU_MmuU=O0*X_C&9#`xOujsnZ;BuqTQC*(pD0?z4VZi%f2R|3G1io@6Fo0?c-(57!S$R_!>k0GqMV^1Gc97Gn{== z_GVXeyXWn95s&wATeVGYEPjyx__mMe-;dTMAL@HU^=JQ{vo!u?s`B*5wp-RuUwrvH z$CDS6);%=+eR5)H{hmJm?b+`;&NbGp%-LyUoV|Y4rlu^}-K^_hr)~C|KYP|LrHs@S zZ*wR1zuvoMs<}vgUFDuQzG#~%+7Ehj0{cwe{PC+EG@%&30prJ}!n$X6TK$JhP!uWE4KmilRFZ~YHv{`{I3&f;J5 z+g|rN8tq@wHT8_QLg-&F|AoeWzwQ}xpWb@=&&@e$_8q1TW%-yObr06}*jbmhfKgL(B{evK$NyveQA^ z2&b>#!p}SX$0`=ydWTm5lef&>Hq%BTsbe{d#BG(y>TU^=S0p+oJ`MP{Py6walV?+x znfp84+I;J7@sl~1pB{bsF2T$z>EWEq9r=sxVuLh{66s|iJacxUI*K?_X=gPYU zN2`)o*uJ`pIBr+ zSN)0qyq72YmFg$i+-K;{dpKqPC*{dE-W4$>Rb28}l&Zyi&{=@@UEss-hYM%eM1MVO zFq5Uw=WwQr-Pu1Hoa~=B%3sWpJG-p#f@;@J(bUJ*b9GZ6+|pv1QFPcPPR7=L@m$s^ z^-nc(Z)m$mhsW%35??H;_U!*xo$#VqOO|b&AKF~pf+VMZi%Rh5`E|=T#QblG;r`X@ zy!U@)NcyDe{$eAejEM8Z#=05WOJiTHJ{0kz+5cYX`scCV*6p3={rSfBWd|(7bb7;A zOo^@7v1RU^r*8t@a%bqSGFGVnbH4C`<>s%Ij04um0s_gobk}T(f*@6lY=hnJGNa) zn_jq2o1U;mC2zBJK;_PrtF!n-wQ7h6A6-CU=5AiIw@(%RUk z{^PcDSA~?XF`Qn%5=U2<_P5+%Mxz*lz zO~@HxpM#f6rwl=4_*+1;{TY+Qur-l7}`EWz?M!`!r9va-fdpyrQ%l?4&;pPAT zuDMw6Ezo0oy{)Xjisj>6&y5_LCbay|es%NrgY{B!nOm6dUS*&1HTn9Lbt~7lKa-u4 z@Z;*DUq18QB2*c!6#jHw7`EJ~`Y`K{PfqRW1sHr(`SURDiKR>cCK{tB;|G|>QD*R<_qpkV1uJ~95 z28Jcs3=E@{4Vs^pB-qs@~z9PyUTvtzm0?4oz4kCQ>?uKlwWQV~ewQrwFpx zb~LJ|a=kfqZl#ILgda=2R{#6xwa1`s?dFK03G1X;ehP;>FG$GTZKoHka9_9k#H)^H z{auTes5xqj{#ebpJ!{{rGeSE8gl2Uv+dAv*bWRUlQ`I$^2fpN%7Z(S&UkLiQB4^o! z`sb`)AF9iHzBj3Q{(0^VcA4~qwUJvNUn$mqTmNRS{jZXWl6z)dTb6|~Es?qY@L)=M zrnsn!`Qamah80UCHpWOE_+oO)@B34!25${>9R)RM-{+3^ejSwIx*lA7n)`Co-Cq*y z!d;S&c~5^yb@ThS>8-?XF0Ga)^9|+RA4_Hp5z?){CjZEB?~*e&UwZfid-E+Q{m*>P z^2D^lNV_-Zh34_@T(4rBai-CJUVVQ{!ltCp8B*Q~f=|mgNB?7u5`SuuVOg`qH|Ub4 zYo}tKV|P_qmhg=Hv&?D=QKC0O6TG7n7W>|>pXayfpumqMCm!8OSpDvZMC@iqtMCH8 z?JAR}%%9(PrrurR*{S?whcnQ)*_5@F`s@MK>`|zZ-Jf#7;d(;5lQW z$dbMCVwBUXTW5Cd3*2%TE8w(WzpBdXBj=|8Yw^C z8k9NiZO(A{Y4bA5X2uNZ&?kKxjNf*AIxZEP(~|XW?`v7Py}v)d{daSx;nMTJjxT3l zW_vzVIO|bj#;wOEC)CY2w))O%@nq4Q_fpmQ`Zu3(^xBm7o0msLsrIB-b3Hf^Ra*Zk zwD!+4-%WS@{#|}{&$eONvHC;x(I0)~9J9Y3ySsnyTpO9b<5TXWS1i4q$N#M6K*Fys z&yaTkFJBfGzg#=xw_tkT0U@_LCsQ7zeP6Id-iJAf*+yOA!UL_fhU(eRG(e_I@z^J zUPf(h%4~C|3wsruzHf=08o+BmXIaW(Q|(Bz$7w1*U$K2RU-O?aWpUQ@s+Z!QwyuvZ zm5O+yc$p>Mxl{baap|*B=M$)Rs(nj|{)f02huXca^*482 zD9SI2I1~L;u%4eST+#DuHyg`~UF`WCvMWQPn<{Uq8a9NBSuHY6Iiu8A|H7fh@<8pC z?WXf&la2LWuG=kd^CWjc%d)r~2X4r0E4rzBP`G>l;^4K)#e2WWJzje|p)1)sLu}54 z%{x$={FP@cQsh0v~sE81_xBX1>kMLt>nzEz>{G=bLcFVWixz6Ldy4B#q zDdPl@kNzipOuL<>&*W<;I=OFXwF|d6@nZ68hn22nQr15w#RynEKOrmGq{7$T`@_s+ z+tJfk>Ums01eiZ@y>w$b!_CIK(SGM|zDP4!A~H+xX2F!;TuqTDhJ_lpgijw|c&J`u zitg;16q#4cAudnvc=nsgcMihv~SH; zifX&!b4&4XVXk?8W1)DKzT>w<$HZuz|E#E0@$wU@>4yXu7_7Dz>aczkfYgO)wycl% zgh92|vfD4*GesB}dK?)TU^61B(UpJ?(3VPY(TvQe3w|+~mOKjQO*W1f;-*#U+eeIWKtefJWhi|%#cS_Cg zm?qIyZ2#r5x*>;noyO6Gt(P#mh_Q*LRf4=q8n`J~&^gv(#fz<*ygVKAC?M$!&SwrZmmi-ZS}s-ej+b%MbCU z@4t|@I^)^-`5!K-%{dvdWP`WX<4~nVmbDhUceLd?OYUymaqAB2K6ST!>W5tp<%oYf zmVPqm+>yJ&zCRj7d_-6uIkUXpwNk!yKj+KC-#7lyddy5AkQ-Ox@CUStrra;{IZJmPdYFzDmz$FW}TZ5b-h7 z;%`Nzt?1tF^N)h_ZQjND*#Bosc1-!O_K#MjYW-Henh1$=BD)n&=*~LK^t`$7zw((E zb9vkkzf529?{Gnt;S8T6?WgNEzUW+iufpn0e1BDPVX5uDU2}N&j<_iKp4j_#jc9R1 zmMG)@G^5hL3J;a**)r7}A`FDRzprLlS#{|@SIW*q%xiD@rZ|e|y=X8nd;B2((EM%# zui1|bzd5>JTA|}JV{YeWPOCSvCPxd|*>*m3X0VyR#6V`+j|b-yfATwu9Q7>}s#n$I zvwz=Nw*7MEcB}Tce!(&RRTUcS7ScyGv$q-dFP>_#TW+400sl;nuTQ=I9h$z~^VKrZ z{^XfU{Igf?m*7|1uD-W;^S7@XAR?ee(-J_iI_dAAP^yeYoMO zMT7f)Nw@xoBHOpB**tKb$M%T9l;7bkQ=org%wfx3r^-#9jqNt=>SrIk)L-~#+9I*# zZL>6OULL)qd(n7ur}*!bKqi-$t3C=Veb)MP*hKPVCD-SDTk_-ft+nxDnsQLUc~R8i zGaJp1Y|N{dxfIAPyzF8X$G&H?eHV+nXUxsxS;igz@xWvaC&8MX7qu6Ev~66~o*=xC zKkLmQm5^YyDa)F!HN3m@Y|p8V9hn=?-9ECBC-`XE21&IU?*2jMes3>w+8x;YXXZBj zd%Sz%P8Az{>%C*WRs1aP3*`wjd@E#Br|R90l=6+hzM zpz7GK>#$?v>ZL+1nmapHx@uov@3m`ohSQ3B65i}|Dp%clV9x*VBTwSJz-DKDk`yM^GyXbV5Q&e)>1(}cC1?HJs*#25D^fB9uJC?8q z9-fvQoFcbEbJg9px_eiw7Rrg}EZ(rMEUc>Rne0{Jx0+Ynzp%eLFQ|R_R`C3jIcGne zsx@~_3oY1Idvd;k+@I;e%=4~kzLIHh_!n37_?MhbxNw7W=BDcozH6T9Y;Jzt!P2bn zG-d1aD;hNux-7Qpv`vUT5FjM2@rlhz{X6)`QGol^>$nEWJjg@ozou#vYx8{wY4`}EWy2S(Te?<2FoX$K6dY=#7)NE zj#Ex}PuVyxRlmAGR%z!BKfc;0#~Swhdcdvd(7DTXMyta%zW4hKAD`Y>{9En5Rqmhl z#mo63&ihP0I%W1PcBLT8g&b8(2Nv~hp8aS;^&Oj6O-_6B%KCS!{OSMa6W8wjBh#(< zTqc*P(u?{g3CBLIZ!14^28Qj(_TaO*RP=VPcuK-l$CA@OU)|l_drEV~HV0>|*M|@4 z%6$Fyq{?dVo*l9=U;NyfFTb74masfCQRvTZrV^WrdefiBG!}bp({E8)Th4bsB1yaV zr@)SG7m>2p-}Qbq2L{K)-Hq#$?wd60qNmucx@AiqEU@rNtatG;>U_p<#_XT$B%x_( zZw~A`Wx2b6KV9Np=sKr0);6!oCRh|**&Xp={qE?v@7LuG_f~!Xx<9pY|E8yZr#vjZ zzisy1Sl#v8?%TG#IB{!1j&E~phj-zo)bOJls=jlW*|eB^{_sM=CSCl$eq_n)X3HNh zOe>%1sGeau7GKe@S4N7lzWz?$iU)d{f|o^hISL(Y=3UpgRWSU9XC(__Eek9D7Ven`^x{!tmTh0V&RHg7tu zle*rv{7iUHM|R|`nM>6=r)Wr2=CkRpEK<}*VJvhZt_ewU)`KE0Fi&^6Im#pf# z;w$z^X6D|DAKpBwDKKQ^b+ApaN}GLkmj_3ru%u#WPr{v}X{B7p9b^2(Jk=`mXQnWy zT<2X|Kj++)UvnP45;|j>F?VZ#Uh+ZPgZuY-990sE;Ac&{a7p#U-;2H(^2O^;UQICB zHMee`)SWu1f93f#T*oi>ab^5W3NHM-wDz(6?gGF7{8 zb8+kHZ)d$HG^w(*SB7&fR1=zbqV#V2zLQQbjSZ!mbDG6}8T@(v^MPy_gNuu3IR}@( zeH)z>ZJu1|xtpdKmKl&pEidCEoYZ{dGo7W>fH(3JEmfdSFU zUoB4hXFT5TxB0eBeGb#NJd34~B6oQzS~90EzUZ0XBgpsqbvp9}83Dfedz1dHoU?nj z!d3x*tPg>{Mw2V3T^cX3}48|vAZ%}~*6{QcuD#VVEhikvgv*BJ#I&dyZ+ zZyzEjJoUJxmg$^-jdxALw?FVp{k9;hg*{YLnlGkH+-!$DLyDTCw|^Hx9yYrZRb=J zRvO-zRGBlk*z8@cTilCBtYYQd9KlyYCw{Z}mG!QR<8{*2tb?ibp)93YhbzN;oeG|{ zy_wdPd{Mjc!O6F;9*CcEUz_`&e(tRHR_!W9@ftY z{>NXqUTmFe#8Q)Ue#;z>FaEjb((f>pOGhtFp6Xfu{M3dw_M5D9a@Xf@&R-PYw&cpm zHBW=h*7e;x9kb!+)uYedPF^fBotmkCrB3gGN=${mRnWe5Tl4FDVmFHTY!g4YdDqwP zUJvfCY)I#>-T!axsr#)QN!$~g+3k{Y{#~8kFT&0v6Vcb=ShWiynk@^?XU;di~yXv&*U;mhxE@SKi1?R`Cjc z@K|8Vz@rgt0JiDyQeFI+B zbMiIcY_^-*^uIfTNwLN$=aOgWYP6Ie8-pf>TuV@{JM8Z zVNS$q>sS1&PG2>hO|MNoY*NKAVbAeer|KA`drWtVGduUSUBB)S`Sic<_Z_iwFGl`5 z+43}VOT+_Kx07C*tu$oUtV&I(PVVqz>G0IJa;Sc)x8jxSHMf5kUz+&+6i3+mvssZW z2iwkzM{Hnsx-OmLTUw_vC*|C_S@W~5iMQ=vZuIe6$gXL-{Wb`;e$0rLVVL!Q+M1y2 zH6Oi1&aA(x^jmG^1=%Cpc5U0b@1V|kKBg!0y>IN;b@w0Vp4>M#)r#%4)r@PnfBLNY zzxG>9-7M>FP2u|ayEpC=UH4nz)eE`cbl#@%n_<<%vxj&a*z5wxmx> zA!~0E_lJYGE4&>}-Gl^%1~X5|>WDqDhkqTO`^VaJedx-{x$`e}%GR4)W$}KzW^2A# zW76#IZGY1nH|}xM+c;4qD*eW%87uZHIOzU8YINXRU5aw>DODrq)~sLIw-hAjMGEuJ zxz!mIEx+GuLye!suTVYJ|Hr4PoVvbS@$!noUwcm&XBtWH{ySg~P&(SWBl1GHXuJHWm7lmurlj5IJ>AKt z`m$(phh^B+uJ3K<)6Oa!s{ZjyasJgscg+Hrc1oQ1Cs%0YqWk+>i`3RYr}76oiefW%5^sWIK1fWUT%lF9TD%@4*G>UcD&m*Vds&ME%o+m-tngK9=xS@b!LJ3 zCc)FsQ!6zuJJ02g;@=+sDyej4%0rvkcap-KTsPE*=)FC4TS=&VUAlII(aKMv?BN$z zbc98o4pLoty@C7t^dGw>y!L!*e3gTwQ;oluImrso=8qGcTO;C%frh^IXc2G5_hiFV^DGdz3?_H{9B>bM4)g zv5Vqf{Clsv_fdGgQQWTAN3z7uZ4Eayyt00A%esa0_9tsbI$nFX>es3uKfaGK(Yu?! ze^LAvFtsby##q!=*J5YgmV?}nkCneO)iPwNmN{preO>m9U z^E27#r6o7F&-JR=IpzM_*|%SboUZ?W_lFMmRXvZNzrB{dxL9?^?ZoUG?~gc0wd;R= z*`1p0`k^qn+Je>l{sV=}f7%4iPnOttf4{{9(}2`Sr7z{gg@ z2NwJ8_HKK0rO&7MT=v;YhmX9cEGi}Q!j0ZqaW#Lew^DI_;HK1f%GYj%;0-R(NWCi%OEGy;~%08LJz#{L7X{L2*|;D&LY{_kp=r)J5QY=t}$5CS0qo8p_YV z;=Z~q;k$22G2iavH<{;@UfHU@V^ibZ?Qj1aI48Jo`sD0@9bFAKv%G?D-U>ea(;jvF zZ~FBF)(wzRzwSg<50-k+sNYex4@bfo7#Io|7#L)cMk-5+^$Uti^qqYZvr~OCi)nF! zulS^-zfF&X79^sdes(>TwTcfsz4!CT){GEg28P$u<4Ra{>lg2sH2-bPI3jR4fsz|MA~xh&W5m&f1d(0ZmwzYC+P5v!zme3&c!jL`X0dt&jQO$dEC)pSLC+dZHohsCi zHz=qHCFcm+EBG2aZDW44z953TqE=C1dQQsnl4mzravxRjygd|uFh{IG;Mw;#JM?xg zPm#U!^Hwf1TZ8KSkjG_3=>nO5T5BdP3(m}``N^B$7=6KezQ*wI}-gGUpAil zW2qpa8T?bs&Exv30MmU6-MuAeAW@vV$zZ-l#??jVgg2xLaq~PY)he!i-{>olV9fc? zZI0!~KP!CaF|+5Wd@`TPx!AaL+rgT(ezWI%WjOIgE_T9BIYx^G5*Eb{_64=}8I!Z^ z>w5%hR3^SFTz}p6)!dTm+@j^)7Mdc5=W6{vz4U!;k^?bDuRd?w?{e>#NSG$C=bfL^ z$}LL7+|oiW@|r>fIOIZxj&eee6)&?oF@%i7fw%DK<{skM^hTCeO`vr{nc%18Hy zxr-zZ%{CK_Thg0d#H z+%hL^evYV}aqbD<9;(`ub=sIM>r%OY$h*Jc$1ye=*~61AJb2IfXK&zxhf_SX{#YvS zQk1l^nJc_(GINpRmX)hsSiG`jY+OCr(56ly_};bGLXS5uyz<(tey;J|=huWYx9Pp! z8lg0^;kJsf?wWHUD?ZHW+8nq3smY-*xAYgY%kErxv+dQ^IbCLsRSc6Z-&8wc*wo>5 zhs83J(KxfdjX&yO?5ulzL2wBhgr)ug;qh)+z zr|(Ppq&0N>TP$p~!Jetb>YcycS-VxcxNM%RDX@-l%VUqp>c9Q)#-how_Dim=)~nyX z=)lFUZRfW0G^}M+=sm#f%Gk2wO;AU($dU$DckVy;D)rXLJZNZ4T_NBjkS?b)S-y$$ z(wXMeN69Y6iD?O~ThElcOu3|2`dGx6fBRvF;;{4|`=l+kBi#0W&dZl?e)4Zk^X@b+ z%dK`X#?Shu7R8)A@$u%oo*tEB>=Vuue{k4dzqugj?4g(YbnYC{vANK~p1?T0e#hMQ z&0KPNyTq$EF$6L{PV~~X-{2f5Qs2Jkfbre8bLND5KTh!vyYSa2F6oexe$;~t2Di?g za$Oo=_vU1$S!zweA|>g<1)Jvff4{0^d4IBChnm2R$AVpq5QaBs$;gP&ho9$fK(b8g)7%Zx|t4@!A)7AY8?DznjB{%r1bsbANW zD~nzjGy1JirA!+5Yr=4KKF)IALY~fy?niMje0Vmb3ml zSA8ee=-ZpVQ47i-~>nXdpV?B@CsULka%^uVO}>Xt{a`j` zW4W_w#oCirKKz?Gr!>E9;m>CO=A39|@nEs!0jKFEz7v;Sib(60W%|JLr%NV&5_7ez zo40UJr)MkY(u?!WvOdJ`b-R10L$2qCe0}Bn3wIjoeWW;KHrc3@{Pjq2`}zD<_wl!no1@sM(8r;kIQ{l`kJ~EN*%{;Q||z%$+00*7Me|Jhxl= z`Pg=`X3=A*8kPlGm5)#P%e5~#)7dhC>YKzi+~Qb$zTR&3JLP>1)gNo#Yg8`1H(B_{J)v)D&lWgK8SW}pZ^+f`nXY>= zWz9ma<_`=mWq$s6RFeZ27cv`_f|g$ngE*G}xb?8O){@hs00gD<+5Y*G?S!?NsigrCRi z^Y2xj>)G~+QCQzEE3Vmbe<-_~s9f#CGmC8}d|iHt_mA<#TSpJiK6m6b`#&z*xev2H zy}p=h)T%Cg``Gl>2d*;8^|C=nn={JImn~GP4cV3~74*4tQ7y-cb$=Q7XU>*Rcgnq# zT)#j08*^}*gYM7UxB8mo6}Fz_{5^M*y!2e>iH~+%)mr8DL{{+3$FSRZ6ShZPRQcJl zx93xs_gSF}Q`UT3f6lxtDr|jWeniaWwV&o1b|z0Yo!h!Xn&Zpvc_=zb#b z-?3`$J5|pE)jZs6l@T|yo6albEAD$)a#FB8Q}I3j&$@eob0#o;v|3V{pQFGNsanar zW=pbIlxuzCflcop?OndWSMElX{0xJcN(#3H_}E_+ROtHhAI(+dUv4S(=5I)uV(M{` zB{K~GxM^|sX&cU~+S|s*ro}~ApRlD~oFR}G@x+N=JRA=wk5_PBd|E#kX>Jhe|!Y93c z_GG5p&&aLj+XTw=1dJ9$Jl^E3SlG2be^KNY7AE!x<%6dWy~#O#$a>j zjW=q3_F1|!|LLj2TNa2eH;MKN?peDw)gUo&pPu&0|IsW5)p|Gu@4FX$Pn!Hydtd3J z>hQRfrbo>8c4W(+eI;Xk=kNcEp<>F-`%}&Lb}>4H7yOh+eIO~ZyZ&!~$Naw!3}qMF z&(`+k^G;$@d)Xzus_Au@GaGZ&vn8J`f0_AqZA_c0H95&={Z`j+Ym7pk9zOMG>Dz-R z{-5vZdYF8lQ*hpL%PV@jzfRxHc|q^a?sI-gk20VC$T_mG_G4aAS@)h|;ppnXx}A!> zVwt%UPB|Z$(j`7G-ci$h$&?_udZlGka&2dEUSo(1vo;i8*BmtSolv;r`8B^bCg0on z{gR;TzvB0gI12kZLGDm?TepB%3*Y@JdVz^8vH(MdpMkM1?$pxLp? zMXf$PCfusOV_9=AhQ*r}th#q+S-bY^Z}ZZBhN_!HCT)=ydYHmy%Q5fh5{^w3nctl( zUWG~;&k9*N%fDaW@5a;}vl;fUNO~5kZ+>zvYfj+v-`W#uw{6(}Xj0v^7-b#rxvb=~3W z2haN|@3VV)FISdXn6+W*#)YBt*6Rs*AKKY+Y3_D`pFYluH7YdcbN$V`C>mF|Vy(}& zSg(&B;y)SBeGICRS6(mkR(3vP?%cgEjAB2}d#cbR!aZH?=28vrdf`WBe*^?57gZck z2v6H`gKHHdLsR#K_WAbla*K8ptnIu$V^Kq>pMTZz_lZ;YDf9mLFPkW*`cOMtPqM7+ zpW^HD8cwI{E0;R^*?&3LCwwyHw7leFuN4M-K24I-pLAqQC~^M7Sh?P{b6LDpj}c?s z`1o&jWT05>IN&9@t#m@s>&Z;e4h)6;mGSmVIAvJ7N1* zh02eAiWF4r`+nl%FSfm1!>M|H-`DGn5A84gI2T`YP`KWH zlV;rW!)7Xb8Uz*P0y;M2pEz1LT{d)1$?lx+M+y5U-!t6Jxh>{lP=<%{!+CL+RwO3( ze1E~^b|u^Ucy#iQt&Y!Hf-T=)Yh{)8e-I$&_ryMZ`($gIgoJ13CTxqExJ&4FUwl=;Q`MQdp+#ZdLRwE-m1JM*Jw9k~_qYsyYU{T* z91SK%KkZkn=l!2^-$Nqx(Zmn@|5o%&y*T~H&#<@7w=N24dI`Gyu=fo%;_=j5xJvu5 zqv=JvxxwfEWiF~sUC{IUEw7jLvMe2$Uo3hLmcMlR@I8HY&g^Ve_D@Yw{m#E!?(Pl*?BYv$HXzBkcV|6QtiQ}kD)RfMbzpb^9EAKF>hLhsL7IGr^edM6mq z5>|8Q>VEfCtSan~fyVreti{m#!=CMA%@c!&MqFTRgo@t1!J4ni2Qv3J*Z$`zoD2+m z;9z5!Ui^<$to}fm+3Y#*z1SQ>S{q#j=I6ienv`fTnWJ-3OYW+7$K${E z+!N~Gd)GQ#t2OP{UE9Aib~c|Xd++i2*9=$ucyFD3ChBut=ZH-8yYg)uQ@B~?tlP;SeZKbF8r}!z>!%)< z`0-AwVyn$J)^G3l#HKOJMHktB_;Fb;;Q;f7IZxRSW<1vWndR?ooqp1WV}kdAJ-z(z zylTF*8>hTBIKL@zPxYpsOl&m=W#%hxYu%H1Hh#0J&0AKdeiZ{}&IQkvVznQv`^+kF zyp}(1#`DMKTP8Z3P+1beex3O$mq!l&9o>cXR|BruE{GL6{?4|Cod?gQubvz0&c(saf9%Wa3^Uf;9~}I*QWo(p?~fM{+uOSPO{=F@&E~C^ zLT+QBeJFM&qYoY}8i7e|YQgrelzF?(@vI zR_C3ZTYPRnZF<)_b^>ITFrtL3$kNEwGJpLor*YlOHlNb20m+frX>Z^NlVojq@`v@;Ak_^Srd;SXA1B6~ zM{!IM`&X>v~8e8Wa3aEG1lV3l( zbjQCdE;o9feC)Sj4d66;|48MKRPD|cZ8QEFz0DFhUFPt6O6k&95e7Qx2XnkKE3QrH z`m;wke&c~7>mFM%9%Ei{T|PU~AjvE>KcaA5^!_QiuV(NRUcc~s#f3k4W^?=6ivO6; zOE|Q;U8u+Q*>BYowzsRkeLf+Zd*dSei~6%4YfLn?e6yrZn}_W1^a}ENGUb-xZ5v~e z$$gGbXY{SjuHfGz=B%o<&AxWezLR-#0{UAP3X5vaIAp@S#;@{>9^1vc4)4<(0}ao9 zzw7E|t+(j=3Z?mdnwS2>c9qOL+w^~}Rz!+TT4HLV{+zwPmQT@s6(*&7_~M-%*MI%m zzxi}>{bJ*}z9oXL%j|erCCVF$Hm84V_!0c3#{cL!cR_3SqgmTM*OkkE{QrI{%MX76 z{kf00d#+v!)nyg3HhGj*rndOt1Hai5yjT8y@p`3<{7w@sjlx--hpsO_VqUtPt*knq zW5dRK2ANk6ruAuk%Z_Mzd1FgfK_h3BnPQ6FE4I3#8>{PAoVC|%y(}fT_S)k3O4}g8 z$qdUamOpG&+N3abNol0m<^zkgj#-*}PMjh;eco5DMLeCyltd+y&6AhS(c0=9=^o7@ zH2L3g15dt!*Ly;)*p*(`xU9|RU)AhQfm%7y9~;lQF0$+C*WO%P#^+UZWb>NOb9`^} z${0Odo14$_cf1`E;m1+gt2T56Pn#(`HcI`wGUH5S5KT-|F7pvt;?&= zNBBOs{)*+8=TYbJ#lU`PG~3Os@;Qqan@#;NiK|y@?T+o9=6{?lR3{(4d{cY&o|L{W z$NTAui#N%Z$4x3!Da&9ta`Nrr6P&x>bn?Z6XNr3_|4-%KI8A5DkL|jXECcw@>9Vg9 zQ8w{1%1seFROx*7%bO{G>y~19fd_&gu%znvbjmJN3c#B#Xy%RTS`Oy{r^X1+2 z&j^c`p1K%Rp&OhQ`BHnf%KGd@zJbQgHa)j$37)3_<hA*WUrW;{(eni* z4+~>{&*ph~=IODUkEYG-xGW@oPIngPY+V7_B~Nu4Z>?)yr&)5dRc!Z#M0bHNqFZlF zeE(@}_P*j!tzVPa*{$}^x}*Er?s4xL&adkXefgKqHI4qGAk26E;H$p2s>}%*>05VA z*~VYCQ}iLn+2pW_decIinpu+e>TeTEtPW3-E#2bv@Rs8J-It0FJicS{Z{_?wySipy zpUl+qM#*u7>r$(UW>v4Y8PEQ=$Y@hp{QJAA%gVpjUAf9u{CTz8(Ixg5<%0PZuS}cX zQk8Bp$Iq>~GXKiVnHJXrv^qFDuTR^$^=?r$e?(b?LY%Y|Z{frHPxrOfyJ}BAb?CNt zRmXzUZ1d%q{%Dl#Ui zhj>nIw*LJ347=6B5gDO*oQFpFJ=7X zt9ARN%Y@o;6`f0Pk+0aypWcg_M!B9r(9q_b>T&~>usN8178T;a&Yr) z49Sf4s(R}5@VYGj7SXB}h1Ht6nTzF@?p|Ukz3BDDtQzS6nTax2-yEJ$QIsX{{>*7! z&F}K4lf}v6$rB=_7#KcIXJBEFVqlnFxQ}0?KEyxBRj;7(jqTrJsqNeBXYY5~x}5jQ z4c25C_1?J$8*-mnJ>cH4b7s%+&1{X|S<5PSdk3BW(qI4F<5p~D`0v)Y+w}Kl3X82R zQIVaSFWV`*>HFty-5GaZ{|x6&BlRmqnp?~kCUC5{#DH8P`3Wx$Ud= zLbW~RC&FLt_%K(7f#G6jLxk!!=TmL%hs!$l9!e9Hc&*I1r$zVsR%3p33)N*u57^z% zo^h6$q2*_-u{d{;|H)fRH-BBkC9pv6=MCw2zPw{guKsti+tzkCtp3l-@D<#vS@U0p zpHiH8`syK;0|x5HHzb^VBU#VzUVMnjdFT`uOHYmecD3+tm*HC)fYg z%DlF4Qetf+!zFjQ5O#s*&v*{Z*U!1Va+2}wuN!`~i>;Ks@_Osus>NaJC(RDzRu6Tu zx%0*C@xcwd`GapLzdK?WF2~0(?Yz>38w>Z(nD({XJyBGH=kBaq_hT|5{`jwC(ayA% zd%onsY2Wp^`qQ_GYX8vqHOumwkhir+#I#*5SL%Py+;8x5?rX_;>najYA6+Ww*T$@> zz9c_-OUN&W*y}Ugy`qJWY>X=7b&xsy=|WXLU7W?CPVs+*WB9XsAT2+^{D9F%Jgi04~-RFO@X>vUyt48 zFTbA4RPX0e-&>z*!W#ej!!0JiHbL7{cfUG3`pd^!U1}HgUzYvtq3h?XzpncKKlkL9 z#*S25#iw2;H`^u`ZZB%sA94QA?o8h|s`?DS)-i@|mV2<1?|kxu*yBz5>^|HNf|*Zn!Vw7az-vny3BAT}n7@q2xvz0wuU=t#z*S2M1O zSJ*YBvqw$$>bd@|S9SJnvq${@^TKaF{;@qV-san{f0ut8{yMe7COg){UzG2RaX8P7 zhYx38->P-6-|D|bLx0-dx-)isum0SY{$6TclQt7qliy&)jqJNk2LEx%CUVS~^`iK2lThMinWDQtnkY0`lz z#clB-A6!;$X-$%QBAK|U_;Objw`8o*;OELdbzeF3YGGpPR+n|_F4`qY zg^Rcdi8nRwz3n|?$@ns09|99hcIh*|Zy4Sr`>EU;|ZY~rnVQ4wIW}4*| z#_kiJWU3p#u`CrkloGsmqntw+Q_TzgOJ~x)t;~hsV>gtPi25T($vUpcH z&NVu$wsM6_=j5J?OMF_+drkT$?Ww?)%DAerpgdt(LgJ#*zNs7ZH*NCe*2&r4rKaHM ze5-zz^K01;vT>COkE`#5u^6f{EP5QoTKegObEfyy15XpK2_}Z!;=1Re5_Q8#C@ZKm zauaK7SIJ~8Z6!S&-lOiS3HMGn2zXU;@@1GSShnlEU7x9PyrQYRRB*bm2T$~-#325Y z_G#;nJmFOrQp{lyW}g4KFxfr`dnn| zzp^FaV|ddCmemZOOv7T^cr%0K-7DiCuf%jfyVeLpQO z6e+1qNdBcUt7G|w{TI1n?E}IaWq-_U{Qak^wukY>>f5)o&i?N&t;pZ;puvg%!Hjhg z$3qXPp4q!$@yzG8iH|Oci{;cfZPvcvrs##hh&Okp(3 z@?@ypb|+(wPx8?N*R~a&HJ8bJYap32>x#e7m*b+YGv?pqW7~Cl>#9HTe;@3KvQP5Q z`pUEL(A~z(Uz7KR9lm$;>5cr`o72pU;#TZ6POA^9-+M5mW`A(t<|pmKmmJi4rGMni zG9Lpyh6;n^*g*Ne~Xys@I-+~=ChwtpsTWGgPt zWS6+l(E8_Uy}2&)W7C7X*1DdFp1W^nynco2j?@49aXRmK+0Uqct6;O+ zUG_C#5qsz(8^bJq_VDoZwThcq-B$KKXP0w!RMbmzb<}g* zUcsbv?25mDz^8MecUrIIaI{^^iitAV>^F^b;`bY7(J3otXKH?W^mSQX&}aWeiJ5AZ zHS-ROONMO|Khzd^f&b#nQ)iVHO)p)wgYD@PTC*(japai;`?rc# z{BYs+dAfqv=fJVedq6g!nAxiuHnnlX zbMHl{m32zgKm9tLQNil^IwDpyrL`)tegJ_*Sk+B{P_-!4es zc;Boj#waX4YN5C1qx_VDSho_faz5MSee(~1y&(WegPUh(?w)5qb3V&X``TSm@#Q(4HSCpJ5mmO7Y zOW0ai9Q*M3>GVtYz0wkT=0DwD*mv&e)`?dRi|ngCoZ)+lk*OfX^{#$@=fifj$4Q1i z`8YiKk8$qanXQzviHZ3YI{Rn*d4DV7!AGIu%!Fr0&qcmwcDQ}a z=3f2%n7TCtzI^e0y4+3mbcCgchg@Txfw<$Z{S$6}WZKBlDe&~G z?}Lea%Uu79`Uok$TfV__##^!UNe^UaeNf`ID_k7!x!d<)Tk^w-8{Z~9Wnld3ULW*k z`-i#ne;oF4nfB}Mit9hzo9h>FT+6oq?VYl)jp2jTR<;Xk=4_h0K*9WKi6YmLWz+vY zjWxNg9{Xh8tz6n;22m;RALV_0H*N>5QamPgB-cPwUZ}XEb5Z;+hQC*H zQ|tFeC337+5^CNM9JBGNiq8t49^<9YCn#w6e)BL`^}6+=$6Pz_$1%PErW;Ehh;$Uc zo8rc>YhG}Dm|In@#XV)K4Hj!twxlmjXOvvs-sAO8i@jY-i8Cgl@yyEOn?DDn`0*Gx zzmc5BAtE{b81uAeANU z|ABSuDM1U-#GY{>Wngn($EHF@NsenqSSfJ-fp1 ze%le0(zo%;;^*_S*{(O&$IQH~vEOk2)7cMwVvGFMkKHRf|29};WFonC`tp;j7~5}`%2*qGp1oD-eDc@of6vz`d7Yb4Kkv~3 zAF;OEx03EJ(fXrn_U8}R{Prudmu_m$n^~vJ_w-Ts`Smxphi`xKoFTeo+)pYdnapAe5dQ%!zrtR`29NX6k zZ*i2{DRHrI{^7RmOrZ{Z;r>EXKZ{S86d3DUpL9y<#_3I+uA0_PCfgfVerV%5b+bLN z_=Mx6ZKuy#3m#EC5`ED3`rED}c2Crm7U~D9yn4vy9XREK*ngKdt2Oi&O)%ORucc>L zRw(K4StM$gi5&M|p>>xk%=BzhELBc1EQ(8$*gJjR>`TVSL_P<41hOlxZw$Y}c1~ZZ zSTmYHXDYT`xg_(Co4rpwlJ9-?_n)(9J>LtBg8%`HK68 zM3rajbY|SwOq>-mamkj|Cj^TwcEzVpe6ABQ&veKA-Z$bdO<_eJPRL(fC*PE&{Hu|_ zlh<(ijexWj9`6t3$ni7*=OF_Yvw=p`W7w!L8>jHV$SLCKjAFLwLdxR zs<7td4UY4)HF}`_MfKBCU#qikwu<>!EV5CW^!&k&ixskx58ZynE&mW|x@dl7wSiRr zOz#fb@bxc^_d{CegYA%huikA5qK7&_fw>3DsSTMO5l`m*Gc zr_L{XCb0JFVUdfgo}AKFu3l7dcE+}(g|+gVzO}xwVVwK!j>EP4J?P0q@@yY{8P+{W`)1j2n|qLkX}w=PM)!hG_hs^yj`0jd@Ai$gC@Uw-{# zYp1}^MGvm#mI*0sinigLD7e*Ls5V5kfZh4+zr0{>HI|J#KNd~7u3IxXY4?vQKa9k> zP0qf*5OFcfYnhV-_Z$z8yGQg>LZl)rf8@9C67JdlOFvZTSiP%v=Y-d@r3B9}`@Z?h z;s>$u&d=&id4dGjy3WnvPf_03p;VWqt;(IeRVRkC_?fk#*{1VSPi?Cce^s9=SrsQV zIn_UV(Nv?G$MWZ%JhGfkDLyRnp}U^xgDgAOpN8t{h5O&mwNH`Bny_=?(hY(t-*0AT z9ZtXagi(Bc*PoK5-AvY#PTi|nAAB>xzUcgM|7(J^shvsX^}-#Yzl`53FnJ@o#iPl? zi}7kt@%QIFqN{u!WC@7GNlfdKN%c2YUH7j2a(vQ?OA~)x*|_TVlK(5NUJ2p4YxA^S zF<=kJJ%_@hRie*J59BdD+mZ@JXRD81cM)V%c2`5yf#^Ak=j z=gFG-!_lUWFW>8@f8~RE-qqia8O45Ik@@B2c5$1BNvldWe{Yz7)aBO+nSzP0#o}@f zY&~OpG^(OCZI}7;_f}j=mveNMu|Iyqmayq$gy)?-J(Bw@6_Rx$w!QJ5Ub@__J8svR zN#@pXv?6WHo61jaKH|A6rn3Lx-jZL=b#KlrsLy(Q@ZYzC^O)vOx9721yLxy1#Z>P8 zycnM7`I8nqtu(*<#KQK$N%wj2zuq`}e7w%GkL``=KeozW(sx!&)aHyAe>iFT?8qsr z15O>B_HR~Sh1~p-&pzv1_U+*ewG7Wncb&`mKw^q$;rf40$nr^FCKIkx~p=*^;^4pu|EJAf9vSHEm#Y+_sx;%iZ_B6rIgg8G1RuEi`v2L&%EHd=o?S(ZkzeB% zPM%craW03nt7+H$50yW4KB(NctFv5~rQ^O%{YlduVuL! zN`HOu!uM|g%jqKuA0AB?ywU%m?DmX`@~y|pR5*m9uN1sD+1jk~qhvS3MU~k4sp5<0 zpT6@^$X80LcA|+%Z3JV!R8OmDL}H{_`TsdHoRYG{q$lKL^xv?Z^JzzMEC-(mNto=Rv$_dN^&xf(3hin%y!HzbllI+fXlRFnQ7LtDNO8-M+7!{QmD5AyrMM!~Bk7 zi5Gac?Ki*k@!E#~zRz1He9_oYIgjs+!tbh!X|B_6X#0O!f45wBU#phh>$B4XrZn>u z@3dcY$$C-2%5O{yn2+A^Fq$oJXWpq#JGZk}@NS3~>u*XlNLg|<>*Sl+2^){-KMl>D zc4F(E%0KmC&R?V77fWmZ(k{O_b=^kMr%O|>YG@R+t~hq!!&@%CC^H?dl_}R`wy@TT z1fET|Sz9#TIZ;2&b0*K0*(yT8mM6r! z7M=*^4AlNC^)ofDWzABaPM$eomO|yM3<>&KXZNzR9e!N-_F#*}LzX?_*LcnD9e)#* z8`t01v6l0YPYL()W1rT2vw9?Y>|KrDq>aC%=RW10qg*3kawFo=sqO6U-#0d&&N9}S z{MgHGcGjVj>J8dW8(+TpUB7J6S-!*4-8W^g%x5mx?jy49O3M2ms+SV~R-{Rtx*jUQ zq%Wt`_cy{(&Vo}(fSoI2#>{h*E<4}bs@2le?bA3(;-TZV*iN2;I8Gg&IOd~zGqzmP zJ-+*E!Plc}eq?Q4?Y^k>xA`@uH)Su`Qe@Aj2cPSEne^9zKo1) zNKk(Fz0*bfhy1R@Pd>Te&Xexti{WTT+DlT2sw*FLIb>boECF}QoOMj{SFW*gV#a(|TKi&3Sev=<0rRjV(Udk|; zy)IlTsd(u^)syL~r{^fKNu+O;KJdXrWqowlB%KCRpTI1sd5xk$ZpJ*E-#=}vW_!g| zut)IC&1CP`l6N-`Z*}fsO*rSwsTT0eSB1ZJBg0Gd>)rxm!uY#=m&T+vxqP-F>rtvJc-TC+@-<5z@W*%z#xITMG~w! zxFoTtM6aOo^cmd~`dWbn{%3iM9(j5C27fsJ`J}(k#S2>=J!0X0#X2o*T1Ezj7g%dv z%k5!fU@#K|nZEtE8=Dbi?bLKbKepRoM@|>;XN!WcF6wYfPTx?##xmXS5I@iKx7^%@ z5Qz)CJO~N4>F@p7%pnqbd?*sW0WgVp2M)>Y3j^4s7$FMx2eRFVuoBHUC8w=qXPLe~ zh|LBf^goEL8p5gzX3K)G61_N}R@NWk=b64wg4+=yaUNNMeR^F8n;S&J)*DF&`}8*< zY(5Z)jc|$mL2Rtk<3ic2z!KZ%gtEDEbAXnI^><1ioz8cgU3^+1n|wXDOX}o>Q>z|H z+sLPD>WT*P$>|#>Yd0TVy~k@ugTSt%nN2@!qZC7yE;u|(d8d}as={U0JKT zp1aM!{N665mh7WbttZ_)*r6+Rzu2@lb(*S?d~oMSeaW5vY5c6t{`pP9hxYx8viTCa z`}vx=6Mmb#dDHpE#W4TR?thb5wN-tXGrbjij=yUACzx~RlI@S`C(1{rbC{u~oUh^j zw}Yp@yUi{(Es>2Qtw_%(B~i9(CvSs+$kA8dmoHf6V42XcK1SiGgJAoL8}-~yR<}28 zvWY1YG7$>6X<;?*E~A%s)cGTl0#6pP&no`%{`@2-y_K=W`Guz$XT3SQwRY9^Al?lZ z*ikK=&Y!>`IX&|jKlgNYU2ZLKI8IMY;DAKw`eXc@)2;kC&A{T@lG%Eo(LW)DEdVSw z-9ME>a(a9!8|(DC^&=3+1>Si&BnPB#RW7Wb#J`9s8n(%7DGf}-oqss)io z(=Yn7NlX_{XY&BdZck2UyTJrzPPfluD+epQc;d--o9P>OvP(?Ap2ZdfmffzK%_akJ z*LL3=wsjEZ^#8dqYhnvHC8zrpu(3@q4&b%`>zU5j3`tz9(+l$0Sf^jeW3vaZE6kp@ z#bO!*1H(1O>GlO|qSKA?*;YVw+{S$x69dC`uIUR4*o3z` z^sz}oZHS$~b`oN^) z{G8LHXR)b+wM;+A%OO2IU=|zO^yRbI)F5IPXR)P1SXQ&yA|NcrV3>>NT;b=LzJE3w zq>$RqGKWnEYG*!NjpkK;p6Ri3+3X;i=g(zp2eY_ZAlfk7oOR2}_>4EFn<);VS;b)t+fjt(Y zJ#hnj8H5$s1hI=_`kxK#VGuFFzZ{a&6*jYTO|RU@4y}pwn|YyPcQ&&7LDU_%!vz&P z-pp$Y5%c{A(aSyE<1Uvk*b%8V*QQPn{Kp{*GBX0AjPD*y>-^2^z7Vkwo7oG%tf}&x zP;=Y2z$E?JVD|ss!VbyPQ~$%1rEi4_P2aGUJrQii^b3rf;DF_rZt#GgW4hfon5!pj zV=sp&Y3zXceIH0k-6L*j@B}c!^lsY@i>Qr{xS-}a?0|{Mcfkxe1s8kA0@M5KF;@u0 zBD*Iry=Ql_L&YAj!qmC#f;o+^2WH;-NBkVqYuGrUHF#qWFDSvWPS@PcZUQkgaW{Jc zgw?F;*4LyP7Gy%6KrrhD#zg`+?pOpNCVKiBj+4o;|_?{mORao)=g ztyTg#VPf|C*jcB~f5Oi?eg9rqB2w4~OV|n%V1}OD#~u!G)qO6Q-u$QhT+{nrb3;>& z;VVdBuub2$pFJI-c>Y9~0e?Y?d3j*2%Hx5VlJc4hnmqTth8f^}kR4ii&OZo?_l8d} zS(C}Uo)F_3C&P^IKg13ddpj8#q`wZq(!KsSaJFWhUUZn<5?qvASk9Yyf`x(M7x(s^ zhuNR72weP+R_k9p!47HjPVfKE1#OpAon%i1pQGVct)B|214E}TC}0zrc8Yxs#625M zu|vv^>2jypXF|jrtU(!vm4jtE_bYzx=^54>>md@L2IF)G84i~1o6oR|K?<7fXV0>4 zVgx(!t);(8AU6YpP|0*bRu19q3(m8rp*G#j2D;g%MqIOP`petU1T`(0O?rFZ9ri+q z7fa+BJ{d7GFkEJacv0aVyE`--vhTC&Lwg?r#h@aQor7ij?nmsLQ27&&+2xqPrBKh0 zg$t%%EaMQJ&i$5OX!`mTPLb)F&)6a7F;Abb#3MQV13L%H^r&a-8Q``=?7{u@p3@aw zIYg%4f5r}}w~-n(hB6$&(-WSvuY$x9-wXB^5Z133>{;NLF`e6Rz?_SL;fEC1+0$EJ zvJ2N2*B@Q;{?w#DL1krkURJ2_*B9oc_XeCyQ{s$QS!(_Ly1yttYtHwSR6j+HSCtC4 z&;IK_xt=rn?!Omidmge^{Ixl_SSwZ4aj{0?>V3~2?Y-St7w8<#wrR>;KB>HKrUy9N zC2xP<(>~ku1>YBIrC{ra+%tA+Zg*cNtsywm_?PbPwt9AM{TpjnP2G3XdH-Y6FSZIh z{xHSwTQ7J*c7yaQKAj_iS-a!DIqQc?uZf88E%Pc{b#!CGw=F+5r$|5eD_Gw+cT1z! z>UHi5oGz}H+w#WVd9u$P&3Bd8XFIEK)~;Om_I>%oBU5ZY#cz_FC2{V?wzmt{J!Om% zl&pRgc5j>frpd0pzv@+uzbz;+$vr2>_EAoW``ZeWSz1S?`i!+Z zji1F`d*W)8w(CP9y*z_C&sUyUnaKe;gPSq3-eChoc*W$^`)GK;$IoU^4l89 z)-HJjK(GEU`(wjT80JHfSu>w}e1sM?LiZ&;qK@7xs- z^k~;34qpic$qlk{dta}w(p-IP%~})n$5QIP>i6ym&ibJh$^Ye}N$UDp+hyHYsub>& zbX~MEsqf9&Ys)cv)BaoUn7*cd_1r4`;^Tw7^*gUVkU3`18voEQsRVp?fI7*JL~M9Dfh$n zNrpAeDtEsrx9;@D*)JddKQTS0egBdCrPce?e`)jU~=I4rJY)CK0oo zLu|+Fiu(_9Iu=!gZL&Ud>9D|B-YcuF=!aK1dAb&A-wS-rFxUSEbB%+n)5(a{=bAI- zSxw)^Q08=DhkLbxjPiV;`ds4|pL3sIzA)R7?@ao_2R~IpG9OfO%nt2sQi(E%HlJ6K zyiD)r_IUN2Z|T03^ESVK@mt{Gy4ykfIc|U0lVH8H`fRHGv?V(a@KsCw>Yn@~tG2(} ze&t$&otEr#?q1&bZc7%&ihr&3x8}H$;uJFP{1t3^S0nXYSd#A=!+9^w7o^)Y z@cnSw#-*Vu#IvYvL2lsIiQB%ovSucm*5A0a+2xe>Mdi0|FYuVI%2~79=jN=aU##;c z)}Ofjw>85{spS3h)|51kJFIUkk5=xF*OLgG=Jrz9aQ@RtcQth%9KUgV`p*?dXT`rd zx4&w`%>f#c2aVn)ZcCk(>^Q+q@*+bpZy!WvJUmCMeyFA&bMlz*77D|WYeV@X`ki^Vxp z-IPVy#N)eVRIfbM&~QH}Ey8kuqvra$oliq&_&MGv@~^+Zbacn-s(IIo%lQ{OIUVk~ zo7pfm|9g$k=k-p024X&aivLf2WjxVWlNWvWs@h@keVj+9^y>fp`|$K0n{+#)9lZYM zd^sf44BeC-wtjxT%48O|xlFc{{>;5=V#2w4y!vRvs+dO0I;*Sm zlXbO%PP^5Y9CYleKeKVZgll!uyuVi&U9A~63lyx`I-}kC$IR~H3+LlD^=AF9=Rd2t zXUnsLjXk&S%y|*I^Hz+=8}_()Cr_RD^l?&$O2c)zMVw7*H+0^+)*xb>ch&XfXPI2S z#A@vWcYo@$O#T04&&lr2le?_%oro%GPB8yetEw_zDfKqYmji-Xcu zCbcju-h1Ru$vF|FsH{H=dLDf4e~?t~wAv%y#fvBFX51dlDV%Dj{4eBtO)qIz()inS zM|8s%f0NtKmT0b(5!R^fv}o@9^RGVnp2xFepO1LTEm?W?>7gg{-tr_%P4zzg-^`=Y zX;bjCM!k1CS1i$Pak}+S&R_RT@|Bya8${kEna|p+V_TGVQbipWtM+F~UczIQ!@K9vQvggybwEx_iYvT+to0idj(umG6tJbkB~v5nQtU^; z!z{-*))gI!>yV!suTb9m;LXjoT6aW~eDy6(O_zLa-C#o;YGn;-LxU;o<0EtsBe@l*@`_I&NJ-LK}SxrFRr zywzPSIh7y%($Bns~3VI?lzQOmD5sPD%S78z{U7YerUV6K)@s>^h zO%eoCr!8N2(&a+w8oTPBa~3$VZkk}IP3m!G|LZ7b)S2&>N%1rNVdeDkMlj>?hP+a0Fros0kdc0B&h zv*^szU3-pLZuVEa@}gQ?{L6{oshuBRnhTy$arXH*X~~uizKtGC^F-q&hQ9H<>!q6| z@!hvmt>o{`Uztf4POAoeX?XM4{jJI8?`-w%i+CmWa{Vwcog`VkZq>P#Gg;EQCdYpi z%_(AjW+lKO{`l<^i!JZjy7YD^cKcrHu-?OWYf(f=d!7CQQ}Nd-rbnGhzf}pmRl9Nd zU0Lsw^F0%0Wa>OU@#GvYtBc9R^mVuVk84a8Vcz?%GgR58v`wY4{4V!&*?GOQdrk;# zVhLOQDLv<^POAQ=0-Nt%(|*cj+^h5{J)va%`@6jI%$;lO(-&~={hV}p(eBR@>^GZg zxAWV5P}{w@aav;LsiLy~8;thLc;9&Jm$@WfFug)W_}|q&t~rjUKGd7Nl>g6+*3od7 z2J0XE`OH2a($t*)g}n*f)KpV34{v2)U|7IB{UJMt@br%N{5;eBzOwg2)II#leh19j ze()Rnb?89ToS*DzV9f{BBflW$rUDFsL(4 z2e*86KJs%-z02_uV(ckKj(-p>)6Xz-6oLh(JF;*b0=J|epFg$GXu4r0hsbmVRu1SO zM?NdZA&9#A$!yZw1K2p4p(b2s=ZFT|`9@&I(kYA#44b7vz7n4v^O>JxdprjRba-nz zBNxXOh!H!vI3QzM(-(4cC`~Wt=75e(E#!s{%Rwagd5|QOrhVmSou0tMp$IWVo|i*; z`UoKLp6wp|9I!#J3IUED zPS8lLRk7qm>*)*CIV7g53PKHBUM0u@4TL%&j!zJyC(dD)-rg_F(FK)}73Ej~4xaXc z8KpwZ3=E3mkSKX3${|zlvEkZ95s&QP>`U>N=EooQsye2uw8e6-K~2Z@{MKtvSKhpT z<$Kci-0jEXm*?*ao}ik-8hQRx*1uP=AKwRv9Q{-O``-3bJm%`&C%87H-F!Rq$bKG}Km`GXS^ z(%1Q`ep|W3PWy@Fq59_%Z=<80L@J&av^$=0|I(rKRvY&{ZzbMFS5@8KVDJ9syy30w zTW-u3{dDI|aY4!n02 zDA^-(gTd56_P{(x$5_c8nd=c36I`AB6LeW?Lyfy98_QovmZ`UV%xD{Cnr^kgz2EXM zqwTgiPV1jFEetpAo;<^iL*b%Q-w^|*fXka!Np3!|X;o(+i?&o1Q?{l=mFaqmMK{|W z5573OAVDc1z(Bwt!u#Nb)iaNF`bM!#V3-tpL{NGQLsrAAX`x^D{;Jp|q_%r z6W+V)TjiRdy}S6@;?8ROy|rF0U-#*0iA-@JU&bdp?c>ZvZ<5zb{WUFMkN+chVgF0- zhxb%8B|{iPc0A3tY^+oMzU$)jJP8ho`W%}K`}}`5Jx?Y)4f~U-_5V%FoTztCb=TaO zxW3Hm+=6cpZnhbzs5X1CO^PqvQ}g4s=1s#FVQx?D7Rzx6C{<6W;kElnMwt3Uku-M?Q|RXrfN z+~lCJlULd9|ELA!b{R>I3TP2GLz<%-oQbxp%W$Yb^3QgESq^1J@bFCajHlNN85kHo zPk+G9Au@fkZQ85kJUrV9#kh)ho^=M|m4O@Si=ENPQhFnc-!1H*yo3#B#a* zWz}<*zXDIBh)s{xq@q;x?ziGn3UEe$1JO8$uNb7f| zFY=pwq^Br6KN}igqL-kM$9z0v`jHN)NUan@h1BKt`<*l2&3WkBa7z2uKa2k2cioRJ zuYdn9YgN_WUzK~S+UKv2e`iA&pe1c7__8J-Qex1Dk`|{@(eD5Fncw=t+ zx&DLYiQBpVR_@(Y!#?|7Sn0ikg~tRhr!0Hwx>-WaYp|jcyc@1|IDoZ%? zt&o*CDN*F$ZO~=-q#-Q9B>4m*?{ulnDKYm}TlA;Co^bA1Q(=$d++OC()6VP_+fqOM z>r6qPbVsY`Igt+OflsZ^`CO{xIv!g-!>WEx+q*Z%pBM1m{vmfcZo)Udk4iJX{p{h} z#g(DIde5^nOAhxOmRWnBzqZ4`*l_~qxdg|wLtnqoY&@{YQR4vjc_EIDA zhd0;%u;#{3rBm}wj6F}iy)d`!^S^?sK7-8;&zcqMR5vSJmyVaYclW@7re&uNni#)q zx_|89{D_Bq$1lWkKPX#Q`?pRe?$6H)<%f54n$DQHL_@(wDb&>5Ku237wY7bU*S!M< z-Xb@zDPNdczpt@T`2YOauIbCBtP4`m7SYkH3QE!FaI3$?r*G*d`lfQv?_VtQrbr#m z=xU(WpT&+yV2zPT!s*eut~l%18AdqKfu zv$J+mK#u9=$L-Yz`NE&RKIgMa{PuN2wx$k!QVdFc15OC9&&fm1qYk znEju@Q2BM*+Ih3K>dfkB)b@@2JE_VmWyPsEZF!&a7go#vFR%Qix$nqsbIxl{A&1Wx zHc32bY_!~TO3mfi^7@!Z<>q_(?*0_WPOfQ=OucmOma;a_8m(hJGd-{SIo8aaqO?yV z{rjY2a&I55Nwkyn=CNu_td~9dr1Zhk#J+&^OLCS8KYzHq&M9!+ZJ;o3X37nP>2EjH zOBfW~Kh(hQ@nEKB`T3u>UC&<1x%oSDp2kk$pEGu>d&+BTe6)1>r{|vT`39kpYWBX$ zyWE#=@Tv2z{+iJ`?PPv*Qov)`{1@&t31C_QdnX#xECm z{5&^*_uCJZ= zfN#3{X?ABe$nuowd{!LLk^fm%9Hprc(Qi){yt8CrU|7Szz#z`Rz>r^-T2z#ol8Sz! zcS&IzM^ur`y_aK-YNm+Hk}{ z6u-BDwnsq=TO_9&6mhUj@3-S%n_g|p0bR8MUgv_4xCxg4uXBM(uur$JgO%OjbuKUo z=p5h$JC10GmHPG^`QXv_W7AJYOka3~Lvs3ldk)AVlj(o$p)T7V@4#UUt@Ab-a7s>Z zXy#y<&gaa*HhrffhY#3;n{)bB*-pQBhC^cdIyM2G>3#y-(582-69;74aQa6lSdCq8 z1T&@4nFBKOJpCbD?6EVfQ=sp{Q4DeEL1UPX!!8`qiB}m{jy#BLpDRZRgr#T-Q>X04 z5e)X*gR|9_rw1P3keoi*3Sy&g?e5A*6C`#9QI&;T$nUX84^ce@orxZQ-}sWYfh*` z!4h`70&LUY_;Tn&Waa%h!om9QNd1UG(m%(K!xUUeKgjm1Tfoo2u&rD+t* z+}r>9ajfD8yRkAOP;c$@4RIXWDaY5Jn91xF{E^|ZMXrna%%%rd^1u8{$zCWL$Tw3m z{mn)*jrm6-4|29h%v@7_@Qa)$M{L%Hb$Mz@idTX(SbJ*!x+-tWh|y0y7V7;*>t(9J zp8_=-t2LTeve*0fDr-0In<5uC@$7W_cn%43&lBrdXZz0j+h2O_yL8z(>A(W{9ZG!X zXKa=J6@8-2)A4WV3v*F_qaSDs-=;hG!h&K|JglF`pTGf~+DuG<#lXP?j-%i}NpQa( z2?>;U`~qy#*Cuk9fW^DCCF0@Y+|zlJV8Q8-#8C zbPhkTuhIlora*l4Mo55rx|J!nK3M!;!U6$^_@#7M_7}+DfKC<5g+T(9b^3l`0j}w8 zVVn?MX;+!hLvDozLNKQ#`dVkcs<>P7w28P*;p!6;>ojHeNKiIxW2Hm~W6HZ=P zw&_+y94TOl34g=`ET)62ko`r_5@)+WF^3u?HEp*l;fRAUr_U+nxCHjm;TQHlAR*OX z28-9TWgO7u0}AEPlEJZEbvs1ajB=Q=-c(M>=@+Uw*rwl+65yQvuN+ok`BlKuMM4@( z$%zUM3$P=tCU{FlfC@CJ=^H9JSf;C2a->20JFya`?M)@L*EhYoiUYcUb3z6uxHM&* z{=JGL5$yIaFP?mWII6N5=BT_(h>egg(w_AaYz~kR@u-1?@WL97II#W`lP?=gcf0@^ zm8*r-CponoWnjsBb(=J&JJxZ?OlPa(Fow9$whmfhykEuS4U&|dzO|0S2&_KALZ}}i z#8b~<1orC3np#nHNJPcgb3m)s1@+J%jrWjFg}B~RL4bR@w;wd8RaT$;2odiGiPts2 z%9V``FdrPugQW~2WFooYSq^IP@U8a@shaLRf;O5bv=}f2ktCJ-xOa z9s-~&tgR}*GyPfwXEH>wO$W@4ab+-V`#WH^{q5jrf~d1EhuOQZ6IOpOgo`nE!Nvjo zx?r_&T?Nd%`&}^e8VX^hv{g5U5M*&fqJmPxZcYYuPuaX z!|Gk@r#n<}N;BGTkE!BpVPrf!{b4m{B4fyO=NisN#{B6=YdEtR7fv^<WYcqA(fBb&I@u?oyHQ|-Evkba-o$_^f)NuR%w=S!Vsa=^Htarp^ zor?Lu|8mlSo1VHJoO2d4$j{JPzwV<2lNcjM*D{Xir1cAXE(L_U^d{7tXcN{kmFpao*BP%N8z6-xY)~l8Dd6 zH-B#YbBmd6f6UWuA@$S#a38+Bn&r2(PUnsVzkD0Mh;32^qSD{(@zMP2y zHy_RTn6Y!o0qva)8ontnR%;klb!|G`W1HyQc;YJG<*e()ud^iOAKaGu%=mVCM?I%} z{p+Z(BM(J(>hkZ6RFU}3s=wvSo&JO=&KZ`euIwfo-ezz14N$>sY#N-kdE-?KSh zcfxjIgMP;Q8=iIlXgRRchL!nyS8mDOzgNS3ZPuq{zmk9+9e~i z9~SaSf1jr|bU1FvUNhfZHKE*c-KCv8g?(1-J2pLiaQv^alc1gD+V@FGi{JHyuL`-N z6w&Jx+xgpX;->m`+he>rBKlwN?NT`SV#~ke9Dx&6NoETDCb2hspXc-*6Enzrctq)d z^GWg3485oJM$A1dy+A?e=2N+Y!9PFDwaCcbeu|yr!fn-K%gmPvEMD8j|AfQtFUPra z>fPN*Dh5hId!w$VzvnbM=<$>HnXk0xXJN;ef}bAG=Q(f8ADXPOuD(WF!MV?(aplLq z$M^N?ta-Uo^XJN(qG{gJHS0`x3RS|_eZQUXTiD#ns5|AOzw4x9?7h0bf6p-8&L61G zyg;OGh4dHAR0qEh&5iAc7RHC`2RJQ$yF{bAc(%pmrt=%zH*)$oT^7Ej>#=|9y!+`^ zWrF?Z^r|}5&$*XZt@5mjh}l&?ZMp7E?lSuorkCVfj&HEm`+HeD;Z^PJIa9MAd^?*~ z@wUlk-Nz^C4Wa)V@;)!BPK-bJ#9+P5{!Om)=Q-u@`*-B}y$npQ2-eQo>aM6)67Aab za#hxpK&3gsOBPC8N_zEMgLT>z?@L={#nxx# z+Q(O}yW8mf_x5KYMd#04S6i(@K4k1IbAPUra@Wbg`og1g{%u+niu)_Iw%&Q5{pjP@ zg$E8D@qV&SRpQj~`U}4ww)|aHWbnQA=fA_Okw%_3_Lol8KJ(a(ujgfC+J+A=Pdj8? zl-&LAfvkBL+dB(=AJ;z1jKbC0^P*eiVqc$oQU6K&RF>#OpF5AI3Vm_gU0#&-X4#cL ze^>5cei!Hb^JtXy)-5()IJTWE)ACnqx?6WJ_+wFn`*)TJK2I3l)-7h!VRJWo=dUmG zg=?$q#7QYdfBN>U-kk8r;mwqnnm58)RXk-gKKHRMi`ypKR^7Yh+M>-9d38w<^={vV{59^rnW5tSeE-wU(@i2bikF;RtS3CHZNuejONDl`r5hh_>)enp zHD}GO-)mV5a@_xx>3?|1CqAQ{^;GZ7gI{{T-%^ph_p8RuSBRtX^tq?+j22(nuC}B2 zn&06sn>X_&ObSZAxs_>7-lgK>o4@%4rc1rwySiXc$;7!!4r_CjC1>Rsuen-qK!EA- zr^pjaJa;90zhe@g9~1fCXZjocDP7a^SM&>Tz3hrq|Fy`j>dIx6%wzASE@3>}R{Ceg zge7wl<)6h(eCX`@_L0eE<4g0et44je(ejTUb*y{3!!(XP;0kKmbdCgYrFngM=~_r< zv~fB|5Ll=pK8mst>0hS9I>YZOxRWGz3qcdx50z%%{dY>r^C1av|FISz^GMRTCDWYfWG z`5(;TfUXDq09x8_;K{)#o#Y2v(Enf#2gmfCb76hvyC5-#c^q}%P&t~$xfkN@ z`}1J#mYvUW8Qg>qsZM>ek%@tUk$w8bIUFL><8=kNx63Zz*bSXnxU-0(1nj<~HEMGV zK~tL&(_iWea8IvU%wY|Vkm-dJIVGnb*vi2=-9S%(d-_`w9<}KQCUS~{EjK%rFco6C z(-N5F4NEw3!CJR}T*C2@6YP!|tX`%?tPBk6xuz?6atLo{UeD3ZQva=_>$|c$=LVJf zAl+p@9)04g&3|YW^!wZ^D+!i^D}tGVoHQQ$ae7KR?tC#tP%~L$`dlNmr%b0pm&Z&f z;(WR*SkH5(6wAX6!RtJBwq5!hv)fRDZy}5A!wD+#K{veZJQwg)XW1)o-bn0!+pf}R z{buK1K~Dz$>VkS7p%aJa&0(vzl3=oZbMdeDqyu)ZZvNGt#9&{gt#Ntc4rWjuwx2^T~f}oV&qn(k+x&GRL zrJ%X!!0CpUIYg#!*uwD{92vY%jrAfRDeJtx0MGObTVahm@a_w64>x!lM+{i;cfZUZ zUZ9?Y#Pkc>IO4#;&3EgF;~Pc>24Sx08@FVB1%1xIR^R zdP5b5#PmOg0-V#M_i*TfBY(R60#4{)%gQ|*?qJ0mH?0+nnO<1RDKedRFGmqr%)^m6 z+7aUX1$#L{!D8yyCD@!G-9kQN0nX|2`(S;l{C&_lm_<(|!`vW2^kE-tup(eTM=Lm4 zYRuU94dR7w`=QPIX-iu znto~$8)PCX%}B~!2V%X*Ar2>qkNGFFNlq6y#KASa_7Dejj=gpnq`l2DozF~wYx?WC z+=gHmPOr252eHigFwC<4!yFU9(YJm|=BzLV1_lqt>5PX!%XZBKxTpIZ;ef1@-@f4p z$3IAH@}-@9R?fu0@XQ#jaQlVh96ivSop6d{0eH5nXLnMZCL;sG+v$N>93tBlPjlEY zf}L>o_1o(ZCp4UaIRU)g1w2O5aE60*`a8Hp!UmW>PFVf`82^p5%zVR%FIJ7qn z-UkEL{PG-!7bHx~&qJ39EN^>t2-*jIavs)$v%SEP3Xbv5>71IDkm4uTN`QO%xeFZ5 zU`N&))v$sJ7^&&T7db2;W)@t8cJDqHFTOY3(VSBhG6rmKEx7sw6V~}l(8QMJpCk_*h2pmn;F|7#8P*kRyvzaJ<)OcY3p$uvaFv5~ z`v1$&kw%vd`;0-Zlb^n06F0QC_#UM8!FdkW=?PajSf?Mj0v(L;t4S{gsg;|aZwnfn zy2_ys_MwNx1s{m`@vU5@U>{D~23q zgAH>EZb#8>yqyc8{ZP>cuuam_1?&Ylr_bFA?P^OtI(hq71k ztaTClm_up$%16)=uH^0_FJs6^OPz}V_jH-Zu!=nPF>I8Q_b_OC(*q9H>D;aYoYPBL zc=)G1;cy1K=Q!6jO*@Et{9OgOrsq9@hWS#>j@^(jzy1Uo<{U-+e;pud<=q6>ray2M zV3}_7l*0=gNektl3qdr zXdd=I#w7_F+Gm-r`JCe_*i9Rzr;umxloN^nWj510060V5KJyI+ zWQ&ZxZ_o-e1_p*-4ATSObBI7>8@vQqr~iAy;Q$U(K?B9A>4u*{q$ThZHX{YzBM4Sf8z8_jef3Y+Mpy7| zL9m4AFPM3Czc`><5buNb2!drbe{-aQ!x^?mP!!~Sj_I3!!*nHXfVu2Jpa92oncG~@ zX(;fXL9ij)|G+Z8;9m~tY$vwzUR=jq^0f&u?w!T(`1#64Wo&;5rgnJUi-o%;jt4+PmTbsHyqdmwbe zYr|HU#y&<)=pNGxjGWMp&4g_bS&r#BOq|dz1$bv5*oV)VI3bJprUx){LIV-J6%Z`@ zn;9kx-Uzx{#>n&d!x`@rHIT%6FU$@^Te zumkPo154I&!^{S4@fckUxZ9@?w)6Xt|Y7=icr1^nk=oBlpVfD5$X2s$wY-slIGFcE?IzflC{j{ToO zIrJk3>vT3zPG|yj6y=0&z`G~P30W*QJy#57(fqHlV*RNYEVe+q1R*ga9WTH+y-u7H z(lmWtCcF$%UM0i}a8180&Z!Tsm>;fvs4U0Iz@WhkDIj$uIC<*5XU(<}Xgwaj`U6{$ zy}C->kCvTl*o>rB( z_DazQll7-pCB8pybILX2cjpG(n+E5r=KNlt;I$#izc767)g;gP+f8Su{S`@G#3H>- zTJ^@JIG@Wo?>{q^oeMhs{7?NSbH*~s!~eHzd|B0GX}oyK>6d5vj6d#K_pGpq_4V_U z^X9(y`tfs)`cKQKur={pJ1=rI*;0e?nH5-+ZsgT%RpTVf8O| zZ|Ml-IG|s@TlBHG(SsVMUBOkyoNZ>UdYCikET^#UiErmMk1trd**0mB=uIu{`RY;D zx0Tgy#hi$kFLd|nT64RkMZ7n=R!fDhh;>C4t-t4+(D8>YN&F^}PagDw|WB&|=lFzJQ!&E%ZVdz607yPoOc%lqn_>=FsTZM=bd zu1|GZq#J0-JByF=;i*5lMU&27G1#->)0`J8x7S-fS#+2CKAYS^<|S^q&;Bd@)7Sdv zn(Dx@qfV}ROZ}R_$<3EO{qT-6%Y7ylfBvz=*^fJGR)( zi@qAu_wQNFW#1mKx%<`re~(?`%Jq)hdj#yMtBY&xz2ufM%W$3Bbi*FzUn$ZCEHzmd z`8(UZJGXi4XxJ~U))3geVN$)EM@`80_PGxpeN>I2F<*F6{Vzioj?L5VL}j!^zBigBlv=-F@?u?gJH9D$PTM$6 zH||nXxFx5#EBzXud5-Cqb+bjxR9ToSA_J5KnI7K#p>gbjtDun7iru#^uPN=^UC;IT z!?9TQrCui@nSOfKZdz3?vi6igTJM&1cTR5gOqk2rI;kP@cbpL8g3R@)Q&v5&auE}% z`yRRYmq+}8^pM}*JD*DG3rMK^`7RZ%c5f;xx59px5Vs@3tCX~aRw-)9kG5q@4EXfjj|3q*65{Q+q9)yW!lgB#%X5q25VxwH{Q( zLeK4~eX|5jg+*F3-klE(`p$kz_U+fIO<(Qq7zFA4&fQZI(kCSK=&nN4Phq~-0vB%u zUR*7lTQ768Nio^Z_?FYY@SXaeOME}69{;+<FTK}sxoEQCGov~>}tKk9OpjHbG+R0e##T&#+V$m&c8m0^O5Z8Z zH5xs(ua0-lSgld^>Tgk0?g#agX8S%|TKV6R?dEaW13910n;2zx`#s4BTQN`KXoF#i z@Qp7U_!bG6yiKc8xBSX{b*Iro>kzTu+-ReneX_86XWk!3JCJp{x*R8DPCROQ&s{G_ z1GPzxGY;Igl$-d+O$XAp+?yc4Ih|Xc(+u3&$mCJ_11YPML;(dO&(&I>`c@)Af`&gTRV;E$7dGx?m9_?4XrF5cp!b_Nr{UuLBuyP!6tVf*s9h&%ND|A+Ry9Otu>+8NUQW)yT>@)$c=`xzIQ1)jBxe7F%o2|*21=f$~ zH+|EDHFX?78|FWxaI#FV(Bj+$b`xY3oFHhS*Y0!yuIX{woNi$KXC-&JO`ixF^FFE# zYc#zFjfgAjKnG+XYvLAIaI#KM$P{3mJ|RPZZF(R4oTrOAoY0j7;FWMNb!^k+L5gkd zIH2c2ftSOciX(J`Z49mH^-OHU|zKXnbun;DmG{A?xHmc5q5e|DPqmHr+#j z8`^5G1r1Gt!wW32+mI6~@ex%*-v|~Y^+ue~rGpQRU`bow1+>c^6zb{5uy))*V@}AR zq~%$5IlJi_7jjBW*U1&&oE~e!37uBx1Fd=iTYk(0*0@qM-X20kWhfd$NY8$pL-EwJF^oGxq0X~pt&ZKLgUK_8g!D=axZ zIYDBOC3cQyxg@4PvgFKwsPnVpOymH`g4fg?)Z>(zexXo+W%@B`Zc~T~K5Nc!2ut1% zX66MePS)w&)|{qbt>EQ!2(8boIU!oN%iC~T3xMs0FP#&Cgj}@`r|{rjLmK@obuCm`*WH=Bps4CB&RR1;AELD5WpD$5z7hS3tk`Cr{g>W~5xZu>-WX$aY z5xW=+vsO2RGY29z7tZ1hg}NQQI!-W@Q+j%PD5nKPnLq|4Rj^Kf7|Ll05t9ppYJe?_ zlbAj=jMEJwc^@VTUjHT-$|*HHBAn9_>{rxo|vM0oIAr^&nklsP3xOn^+0cmX;0;xgDqeJc^nQR(v3xGY=dDnzCWfw5EU1<&>E2pTTJh(K{i7 zvmWd+@TxeF%cf;iLvngy7N;xN zAn@|I#Lb+N)AO1HxTb5>a@c|O-@bSKzbnK^4%wWM5Uq2wIfKEv_HHpKp1v@fQ)aqD zvjF>a=^RcSusC?h99TR%htn7=1a1?6g%0I#8iUP-ESUpGJ5P%M&-Cni4nv3q3+g!} zrx)aMLV_Q>cup{nQ+oRB76DH1;yH*i-aJ^U-q^q)IlVED(*`1OFpm=&$_0%alG7dX zp(cS>%7KDw`ht8|RNc+ztbyo?Er1yZJ|z#7x~89K6X2P?Mwtherwcg`K@@|R#(@hO z#v)j%0Uwa}w~&)#dQ1^4svfpLqM2p-opu54>Ds~EK@bDtTR9}B_ZD+ag?0u-pSaZx8G!*AmVX5JLn@VNTu{!6`evzEgk$yj%_(zPD4# z_83kt4B(WQE?NdF_~Oc7I{tQWNKW_c65yNupo}vbVxE0DXB>pJu$(g$!t(3lken{j zEx23;0q*T4 zRh&H>^_4G#a%R7sGS7!)_ur=FkDfC0zf)D1d4loQUpLtZp1zzr^W!XDh-O)=HEcoOZ7Hbh>`#rX>9rQ}$o@bZ4)~Wt*10+w`W^-!Qe9YiZ`wT6_6H&eePQ zx(%1DUu~~$^e^9Wz(*$_?+ov<{5|*8PJVduyf|x;!-<$OoAT+Bs{2h3&fQ!t^=$s! zT*k>$qE4?9eNZxa-tKu@)4QxLSGi3QGIpiZFAA~TQ{!CQlHd`3#_FPY>7~W%)I5#L)~obNm~D7$-m3DH$J+4w z3?6x{EQ$Y&i0%|9OhJoBBta!D%XHxu&iUYIm^K}jwyJsrxToK1;j{p!BiO1EXba7} zl@prgdRt-9`@WU45Nrl$35n$N+BQyTC3v=ta{@#nv7NINY@8ox%?LPIes6~*%lcU` zt5^03a8Hlz;M9lcn$Q8OMBj99&IYGL$a0a79h|b$*LHG7fyE#zMZh(UMi*xwL~m^u zXFi1Wp^GyL!t(3p?1r%Jc5_Y#y9c}$1ni!vJuvsk&gTF(*jc83=;7Q3*06n5FXs~` zux&G6FpIiCTDt2eKuc!GS`fiFPKoK3lVEE>z#&~Ykuwc!5qRAP*rFd3VHP!j&X5G> zd!ESx9MhvGaeDBAbmco7KApnKz|b>&!z9j7=9jCgrgKc@G_2RT9`#qZ==I$P3EQT( znMS=eSuY{CJ&Ggk$~C#2V&-p_@aa4^y}W3`v8sr5~6~SOED;C$#g&PjH_e+O{F~{TuygD^-ShRce^xiKPBz_n zcQxD1HxC7V%BDtc>P=u*-qv2kz;AJS-lI2lUuSH5@o=WCtEZ4{%6W5(?C)IhN4qm@ zPp;Bbl~Gndn;kRr)}ez%(|q11PLJ8Zpw~Cb z#rOk9Bm4S()|ZE^s&bcn^ro6Kf5x3nQ8yW_vpUr_zS_T?^Y!=NG7IWIe`b{aZE@sv zylU6HD4F)|op%oX-4o))f5S!cb)UYn8Bb09kE{Ic{~BzUP4qt1e0lDQFVAE)H!QsI zk?Wv;Z~c!fsfnj`Z}e^myJqd|n(6Lv;Yh_jeqEj_Rqo4$Czr!)5_*k!h+Uw*xbw08tlNugg@^k~ds;6&t?6IZ^}6Id zcWI8Zd(?;bmlA}!-pA~}y6m>)_C1fR4FkU}1?=Qn7JpJOhpQKYyFRu_Dn z%V`EK$ziL#pf#e$JkDUS3%1Xn$LY!lwiB|(3*69VT>xv**)QNs0n5S{bxBO`pC-UD z{mcT+G_V9@Wf$0~!3$wcwKWSli@@ej&))~@)Y>oNbO!5yEb0P>$>K$vF%WeD`#B`1 z%Pi*10XrAAvJ2{5g~gm~)7LNN^aZP(wggs79suoPe7A&?bNc=n0<6>T%;q)+YX`6K zN(43LCoJJ)o&J3Zr!!dRbnrs2@THvoV27lEmv@03(m7LrXS&2(ZfN%hyv7UEsGF{} z4Ax($UB(#!HXXdE3v7DKECH@*%Q@{JhW8(aH3{OEa~4CyHXMP9ZU4NS^C1&haQlr_ zoU0(r=?SNx^3xZu-5#@Vg3Lw-~zjke*-jBrYCHG zS-SBo$j}X(|G?%=2QS!yDBi>gU9c6qiL(tH29O0?;QkTIW?1yaZie|(hIeo!)LDp)4lSXA3$_EajBEOag`ASp6*qH1MnOQUxIm*I zlGCSe=7J7AG+ySAoc?Armp#O{`dhdlV_D!;TVN+{+QbbV5PQFc3o`x!UZw?>OyA07 z1-1^nLJKT(Xe$>){j_aR<=`b*V7ZEIQ03qySzw{AMWD9lHZEubP;fg`6L=vOSViY{ zs3!0lEU-|_Vgc^y@3+G=UAWF6IeqR9F3#yLJGgAX?g1~!0!P064ldT|%XV-<6Y<*} zT##V{$Z{-j|0Z=O)c@O8?BtpO$b!r_01B3Q-!xB!B z>4N*YrhrF8pv$qqBO)x*BbNzqPhalGEi(PYeGX}`#;I|u8j~0p80JqGoXaUPef}~5 z&gohQxS)egwGTKXr*A&MWeZL&kX2jYEnejw!4&@jDRz6r0Wle}ehZxF1s`)jM^tzZb5(+kf~?L0+k1M20N3=T zSGi=TpF7M29Z36o7#jSLm04hQrAJ^^o;|_^87SSZag<9LS~U9~X^HGuQSsR|VK_kR?~(K)rUF%O31h@KP$UNoHqY8s@$QIphr2YKTK@&T=(_ z)q)pLfz>`Z3sWn1j%zYR*}eC$I_=Uqu2`^z+Dn$iYJ-MmB&P?S=Ykf(dq69*z~h=5 z&U2lD=&ifJ^&7&fy$H4J%cZ|Brh_e8wLyS;y3Qr27q`b>;`#)QwYsk`-xghgIcUQb zE@-#W?;D5Ybi1ou&=Hrqt1t=BN~&o$xHzTQ=YkGG2>j##2|))ELCdM8-QePyUULIx7HA7C z*TF(%H(^5eZ*sMPLmRw|D)Bm(?DX?n1URPe{>=fk8?=lHtV!fH7t}V;0xGaj-)&en z6#NTz4##xPJFt+~Z-zQL=MGl@#2*Lla3w%kpmWy2M!4SP3IIC*wt`9&EPP;_0LS## z|6qBM?;aO)j1;tr3ar9!y8y@ZnETxBU<0ShbAp0{W4ic#F6ek3Xh{`V<(=&U98>pj zLh1w1sq0|T@AtVNT0w`dL-Zy;faM18>FWm`a6!j@z-z1yJmBJ*?)ngxvB7Js93F9T zO+WCED;ewv&>Abr=?;&$av|J}kGR?(EYR{Qu&ptVVIdDXXdNsBK4%?N^-Z^X!c_`U z4?bP}!V_5Nf>&5wc*4as-S;UMbX)?w!YaT7G&}H&i*@?`r(6aQz2FsA;1nE*}4q3)1qO4mxoiY}kjr0$kJYzvS|R_{Z=S zEEK_Ov*0@Ky@HttI%OTK6YQOg*IdxioqeylAj2oy4c~ChWQ7=a?jy`XKVi_8AW+qD zcfSDlbl*?VJU_kR6Bl$MtPym|I>^SH1E7UkBG5!My-@_Fwe&L=bOvMpXITDl6otv! z92DT5?(hXx6x;(zocqF61Wxg8C+(L&%ACZnu<~U7SFRq2JN3Uo3uN%ZEO61Z{2P}Q zxWd->|Fr)p3j>1y4`e*?_8|f8`qXKsXD!wdXuED7e$m|E|Kf@`Ayv-HY&i!~s-FJ6 zf3)W4!3_VfE3<{VtPZJv{HXI^|Hk@BwR7svMQg7=(|f2o^QlPY&1=5LrZM)z3_3nFX{bAc9);n+Cd)?nt_{iGo;r7V2VxKF-e~HONgq=MQ zx1#-};W;m1&Q}PyIwB2EqJunS?kRfb*--{nUkNaQ<|r?wdM`$ z;nmA@I_G8m4tF?sdvQmqfS{H`)RVNI`j7rEdKDj{&eDGS_(r$a^$mucVlriK)| zNzE>bez)?(uclk?+V-@kPg-4ZanaF3?>+|a?H0Uu>V;NFN4%v;=p5%0H(h(@|Npou zr(NK&yh`bwi#B?Po?mlwk?vV->B954!S1FSPoqTCmBW6Q7rIol#2mQCD|}$3YsJj^ zq;+}a>k}V*YK#DaJEdlIN3{W@zO!=p?i4jls`M*=ZZRYJ`^x9Wq)|B^JlOMd#6z zi4Xbr^oTv*{-Iv|%<|G3FE*4tT-3B~$I9c(%as4#cW{ut2yYemKVrQZzJ2KM}H?W|wgWb4S$=_aYT zze(=nl?8_?mgb$h-?2_U;;2EuU)vp9QpHWQzjU5i{DIZk^Zr1a<&c$C;CASm!vfsXd*nDn!0koI@+!x(T$0nL z|AjVC!7Ho4h3)shurhf8=suSKP)%EV1hm)fAD1_{{01$wg0#Dj|ATct!Aq>beQSmP zT-lJ4y#GH}6NJ^E$SFBhk2?`;J!DB0$X!!6aEF40ASZi?r1s%T941k4Q)WnaB;^&0;Zme8!~5MTfce3^upU* z64Q^L7T^WVH*!sv;pTP$n{>p+Ww-kD!n@p((*@25@PJoLfhGF0i`GLW9C*0drpKKT zU<2Qq2bNuE_wFS^7CHyr$ioetGm=`xbnFSfMGm)bu!BZno(+c)6kD zBLaNf@!+2D#8s7V*cllZB&H`iaEorA$j2=WjhPMn+>p6z$l@r*o7|Gq&+&6Z7Ds{I zGndKA!)`h_K)@1vL93>~QOzgFT?AI*QPv%4i=JUOHNnd;+CE+F2wBs zRx2Wurff1@k&9budX*5jJ6KtM_oG3SB?ZwT<(~dep z6t5KJhKz8WIVU4;53wWn66g?4F>c5*CeRuzsQ0Fe!Df`-igAa5?d9N0E6@Z@{EAQC zAi>Q(JxiS194t}vv{k?pV#fqYZr151#JMBE681B`eKm(9j0uw5?9;s@xZS`KoO_)o zBTMXrNu++)j6;^tkmQCeRbhKwoHG63J#MM#6C}AI%LFc7HUBkz;d6)(>vS$DZY!|i zOQCes5gxh1EkNkM%ES)c{Z3e{HyxTe3cgiTr6N^>WH;|9D+3!J$8t_iSBKQ0YR zT>qt^rNgZ_|K#al6_qmFkQ@qLp9L1Wb4`GI`U4qmeQ?{dxMk(@7(NCDtLf7db-2a0 z8_RO%^MO-nMzN(}6$1mq`soQe+|ttvt_!eEKd;T*0?BaUI^6AGPnakQo>Q3a*uo|< z-JhL@b($`>Az1wMCRR6{>EJlFz9GOlJw}%sG8UZxI%5p%l7<@s+|&2#a_fV=1zr;c z78lTi4cPhVahHK5y+{s`!UphB`V>bf> z!*S5~lJNAy`rPxu+QG}Gz}j03xFG|F+YcCU_d>H=pb<0?-q5(!s0&GOzitU|O+RM@ zO*z}w3$&;}qRQd60QdB*DQu$C-Ho{=!A{w={rh8cNV;k==Jo-L<;e;DPzU8I$>|@A zxve3grfUvjk1KBOtQ5rqKAiKh5(tDE?%ozcl5B%xOQXk+}vElAi8j#tmJK z(P+k<4EElZ*)G)($pvQItkZeSxlO?0;Kfyirrgrg!QvU_u#~dE9I6w%unMeVzd1MS zbZrZ$PVjOngm}9JOy_;uo{&A6YoXrcdzXW}nXK#tj*l{{D!;9pZ>}PXxH8>!!h0 z1MG9-jsOP(WF6E*Z*J-7woe5(!0VvE!KlH0Z9hcoad&RW`Zv%rsOg2@xTU5md2l1I zf+`H)6raAqgWDc#`16wE>@52pgZGo0RL1oXs5a67C-v>6N$?pqQ0$KkAj;E-X(DhH?Fgfs7(+?6R zPko_b0$u|J_SmbJ0$fOIpz8dfd4|1Q-~^udVC11 z6*e)1`x#j0rkN|iAuBa~W+==v`z^TTrayQmz%l)AD0ed0<&c$Aid@{1)0@J$AuHt4 zW_;NO3NxwcS?>k7r=RNJfQ-CvZ7Q-41SJE>>8|12(BaB;;jo68U<5a0qVT%xL}6%M z&KJqeHhq2sH)K9<`iBVa2yk80kniofjhlhty3F*ABHSX=1wIOJZ!eAHUdd6vWr@C+ z&&u4R@;*U@zg_)*zMd!dRzYD#3iFn~yqpp}eYcnFw%vX~f0fT-5thl1%X2cSG^E&iXwVDf%K{%^1O-#&>j zTC(2f5Zz^M!Oho{_~^M)wm^XV37_&jdE>6u>pa`TZYSPn&h=H5Xo*SO=Ia$^_HgGz z$=bFFk-g>l-X=4zoo+6ev2;Po=61!*%W{1#x7c>rZDD)pbH}^(N7dw0H_|P{>zlPB z_c+$e?bUAKPV9Nn&HXB{P`JgraJ|txlb-J1%B>1hm{@1dRlVH)>D94{q(xWaznfMx zE;)NZqwTot{S%q*zA^h8{a|@z*|}!lXWb9;wR^*Oe!11}XBX&}k2&V?XHM5`t?kab zehWXQq@~^6rh1?#@BhgUYNqSOnxdU1OKfzCdGu_;tNL}7mu+tM{j}#frXTM5u{HI< zwC$o(_wZG#^KR^DncsbOe{NFp{uQ@GXB4K19d1}37+~tLJL1fa<*Iy{`7v(JLOFXn zRL(t0p7Czu+y~0jUu+c=m>tp>sBLqjzf$ak!QAMymmjX~pLzVl3g6Rj=P`%LxGitm zw&_vwqs<$n8Rzyn*9*osJ(^Y4Wk0h!TE*~lzTBl_xycbd58L*~axLGjUb0V$_xpB> zSslq=IixpAugOz>Ht);3(_$=zM{*nUCf+}>QQlRJ{e$HR|0O$h6@&lupL1-R9l|Gf_u_LucJs9-Ge#@Kt}Y2S<%qqM>zF<3xi1%M$m;sD7h4{4zBWjV zU*Xf!`S?N7onFVzU)SFDG+T(R4>7H1ooW00!ld06ZXwO#lfO32*!_ad>&?nEk@?ql zRXv!-!|;Aj*`I1{=5kzST+I1`Yu-!M4Tr?sta*{cW3wZEDMfM`!CJs%9r%qTG3g?>C`bk{YRQVrm#=V{a*U}Ez$wdpr-$J%T(?e zkZEI$^vT@Q7Y1=lO`rD>wBtSvTK0gJ#X%d*5$Ui-^SX3+PR-!X2j~9kpzytR;EHA1 zX93pfdp`-VgO6MSOWtd0o&~8BrhOLRn%>>U30Wu`vpj2GELhX@rc7?g^!N6kncP~C z$w-St_I?*=DUl7URu{rqf3unMdk#dgU@3PkSTSVX9k>U$p%mKat7+m4v4J%H zH96K-Kpj?I!F>hnuk{WvWIqP1wec%{ZoJk)VbxEeqb@D;PixAZfLi3VJ&w$*mCgV zJ#Zzl`X^|(dkM6>UYffiQ5jMzwbXG#E1vyz+<9OJO*gEE#?JQMdhW?w;Bt9m)jaJR zEDQ{+oYMovxka`+b#dQg5uEZO9(7b^yG1{@AhbQ@JAoTIuzhy|cNIA3A&XkTJ)6pj z+>oi3?YAd#3p0T&StqsZ&OrtS1{p@MCDR3_a9;uIV+kj zf6AS5A<%7`F4G^Daf@!hJeAu6>IC`e&~}E1#j7YIP%}VsI^RFgSx3{kp|f@mro&uW zFoU}oY#ZcMB5*X^|0lpXoo^;=dqmt!Xypu9zyfZ!sKIoZ0b2d zuIcu3xS_L~jdQp&A==-~;Z6Xn-SV~9(h`y;3g&V{7Pc&IOMU?DdKfSXvQB@`D9Ab; zbSM!-ufjZNm0aVt-#-r0%2+WEnrElW&*$y}tJ}VIKKFmfI+g7k7ICkHFsH{Z<%aBL z+0MI++n5FH2+%?mh=Zpmt%5Za*R6uJxMf#!mw?s9EXtc;0?BEcS93#~n~ZC?Tfiw6 zv=#-@AYHzO8#4DeZ7tNPkd-Kbo4KW?%dh2To!+;W+XJkr-l&EZ(kzi%%gr`DflZKg zy6r`1T7R+B{*5bW-K+TYpmp5P)%)w$LCYG@5*26{UWZ)}a;Ol*=T+;uIUwa0WX%dV z(Jt8l%^A}+auFQfx z4e^96P-DRhRlwR0a0zlx@43bS(HWq@y9r6B^;W2Lhd}2Cfz|tQ3vz?c4+00u^b1>| z{-3V14OVCLZ-WlIflmtp>k{7%9o>K|PXRX~*YgN+O|RX~Z3@n^$%nSdhBGoSm`@M% z;uhV0Wjl8cB(NbXR=_%Jcm=VqSW(=^Ejs<^PFO=zZx?qj*m>Lc@8bT!1P+s|w4?K< z2Oj2@o_=dDtg9@(kNYcF-E@Kd+~MH9+>d34r%!a{5Sy-Wh?{M?F25k>bm@a!kWsQb zo6a>sj9@wdGs6A=bZqU+UZp}~NVd6r0G8V24?;ttKc2a1`a@9N&@Uj!1wZ%)>@v{O z63~fdq98jVE0MrQ{sbQ8mYpsqD9ACr>@c_Zbekhw65#v-Sz-cCeP0i8Lszx<9)`xl z_LYaZlc2eh{}^{L#DDz0+;Y>agao;!_Z@?Ex%M4{YMCx|9G1@~9*6cOwuS91n4Wl& zTY5Uz320{synqBObVpc_YkI*6XlE$=kKa`dNG(3`By8ye<4Ks|u_vKv4!nXS@g%px z^t&gyXM(-nwN_&3bjI)8($i<2;J>wftwfS*OoA%WVQS zccSmY#fgx}`*fDO45BON9CtNX7P6)!@jtiJbguKTQrG7^_Y1Hr!xMS^!0EOZxYg^U ziw+s^xc=YVm9t>(C0UN!0{rKaH#B~lS}4mXC)3WUDO+}*#i0L}|D}oVrvC9%jO)8+ zzi4})$p8AF#wr(sXHBb1S)#?-{l9J}dVWmd{dRKS{t4v^59TFl*F@Spobu5}&EfOZ9?jofJKpEyYTtdhxPSSa zrXu9h}25w_Ci@;knOh^H>KiHI|u& zU072Jj~HEz&OY=pXhxCK%}K&#(N(Fjt!s}z-e`XJ(bHWAv;T+1xS_RXqa`~p22U?M z$1OGe;YIFLa0&vi*#XC>w4@*xc+Czt8R1%JmM#ul$;D)SHn4W(V zI)vIbZFVBmjD0eK9MkJ=LYFwn$LunPN-VzxGhE;{R2#EV{0e7?)q8Jqhl1THA-y)o z1tNA&R*+-5!yRrvutZ#~r@9WP>Xo0q?GCpMSnR+~hWU07u>v_kw&@CYVWnBlUG79k z*0^{VTIzuo>_8P~--9(x_uk_!1V_#TM!EN(QE!FmVfVRx!9tp=EsG&S3JQX3(|fnD zLl@x4JmAg*+i&>z)ihIx{To0^a<{TWhPJrkS&Q``5>gLg*)ZlIcLmtsE$ucv(-R(Y zD@_0M5Zc81em>I)8c^pHK_U1EHfVDH5j3$n7S;nVj|e_U{?Nz&6BUUIWc=Y0)zB$Fload2{yp01z{s#0FVeDvToRPPCExvfy+H-MDz z@^Hq2qsj5)5lu+Q)xG3qn=bVh*5xdC%UuA@xhi{7rh)bhZIPJ%@H4mAc9wVC<(8{a-d$9Hvnjl96gMtb^zFWfBCEhh6qx`)#je1Wx(dB1X}fc3|o zxa9>I6Px@M)_FMpm3tN>HgdngIskva!D_L{@7&P&+xy?4^%;0g4!G!v`oV1pZp54o ze}9&nm4U%_`+^_b>a5~?f&Z9MyF+$y%Wd31WsdZ8<$o~4>;FMZB*-*1xPJTj57wND z`484l}7;?wUL3UW@5X6J#-?Ly|U!EL33>^zWh%$Jr&euhH4>c+tXDRf?fPXYm}TW=)D zHT^aREQIVhc_4%JkV$W_5*uSduIWA+u%U4QE~xXs6W(Ayb#d`P=A)*RZvGe!2^W47 zLC)!Kxp<&uD7Z;hz|CVK2f23Z=|f&N4+aK?a0Uhj5u|IkrhiOel{M@6Q`CCqlZb#> zkcNg{pvE~59WUR9MZFxHMLp#odH5K$%D(xY@%wsGM^E#b_DYSw3zytQA23Z<)Z)~T zDJU+{M@@wt?>F{yF)}cCa!fzy%_F@16E}|>w1X_*&n7wDL70bi`UGAc*6H%5g3vQW z!2J^N|qaY8oKL$A%qlcGedc1`o>+}Y=1o(6e2VoxQ=@?*FfltQ(i{%UPKv&{{ zPsad@-Gz&RPseZ&=7B7Hm<~Q2!$FvbbNXIkXj0q$TbM@=I^m=%!2=zS=$GILhWZA4 z+QWZI9>_Ts)4^vv%opHcogOB|1L==%pCQF_2C6zkhG!ilXuwA>7|ZfNhgQG`FI@2E zVVT}7%i{=90=~isEcRBG2RbzfzPQLin1^M$ryLJ-P3s&vo>Xv2`PP+DOP-N|L6c?r z!yaDY?Mm`ICQys*v)Cl37c20@fiw5T6HmU|OgEI{k(mC=Mv!OvKLuzgE%#95fea6B zZ`u1Cvfn>di3hsjWxf(mE5vEw`%%D7TcFItHr-p92fA_ryeAy&z6HuW(DL@BGS6{{ zHt=@vvno8$Y+Mi8^$j*f$6k;NX@(BN@sv-O>PB-cFxjz%vD6uZAJd zO0d&HQo>SpFflNMv4fqq{gWZjIY{qw_kps^=?i|ci-NKi%k)YoL7wSvO?aTgbKvc> z?xsADzTEctraY<;UvEEQ&C|&WHv4A#ODSgt28J*OaL`Qea~9;DUhBvMoh~`&$OGA^ zpdUGHiS_i0%p4-qQ=E99i(q#-@k|Gs!WI1AC7z9eK}H0U@r#^!irK(vkpu8 z$L7TYZJ7mn@l--Qdd`anGV%VkfM0a_Mt&a2>8aj4e&BNZVdfTz=?VfolGA^=g1TYe zJdm~4pzT!|VC~y`eR$?T(&u(vKc0IK=5+o5o_!Gcivc{EP{DtJJk!9&f(DVMJ6_-r zoeoYoTZ4F@GmebGJkUwp{9vARumRI=1@k~gsitRy@Vo|#Z4VFS(fbQwb_VhCNJE%2 zb9q^yRxQlqjRn_qzK?mTvKSc{_D+A$!z;2~KA*Q9vU7jkquT<|tuf#fx4(cFGCe(A zvyk^W#6XcE-WAaP#eouD$YL1BdEQ^urVH$57nvSh%4-Xb09Mm1K2b&nhH6%D5~(lB zODQQzO)Sy7+xc+C z%3Pjzr!(en_nR(*TeYeFV9u=auuifP#CtgOAQ#TEUwIj_WmX zEy3#m7-pNfa=xz(} z0kjMQjz{l5uGgyFwvhVc97G8zvIxR5Q*0#WOfsd~RJ4Lva7h3;-c3(j3X@`k{ zc3wb)e#3;O`?c{x@;zv`1w^tSSde2ns6PjB68KD8u;K3QywEL3;7u1`v40@NcH7vY z^Bv&r7hnnX4qix0cY0$7EKmZNL96XSzSHT11sV8=TdH{lvL2IQ z;k@rPB<-+GKRAgOI;#ObzZUGb1yO>~^J_u*b9&=sXuMB(gfnP7d62v7Y;!aptYZPo1VGwJf)2 zi;XlYdBn*nr~jPga2rc@N&W<OiVn#ylD_tv0F=ulnm!`8jc$4~4jua~Y` zxX<9m8{S3MOC58sAC{1R?IgMVu#5DjzbAz~x1`>d5w@MQ_KU&0jN{uZ)vDB@x#g{6 zZkQeS*gYxdXsDKC*JQ7cE)zCyYwhc}XgJNqAfA8a`+F82<4(#ON9%_C7x;B9(R%9i zbrp##`4`VnT9$k}NvJqZv;Em6vslB|w#R+zWAmRrG2bKAl{xe4nwNX(% zOHReR6Knarb&P{9Ojl$PRGYc<=b`m|EbG!lBQ^*u6BT;vvGcFeS0S@!PrrOtx+|1g zbk#jqY)xU00|%$wgka}ick55y?e2b|wuFl>Q2F4kIVu0Y`q$qLsnB`)zL~}J_1Owh zyX)q;8}4iPac5cUMzV!`x!PXrcDU0e`^+kbbn%c9b@hjeDq;8J;})0S|-pm%S&}-+MPv%|+|l zvnhH9ww%-yH@j%H{D(|WeQJ#8=Ec%?6MCh$oy$B_)ls}hQ)+!&$lZ;4%8~uAPZ_Jf z(7L0%a~8wx7WVC%JrttWoW0oC|Mm5j1O2@LteiV`zE`}$x;2eEu&8OZ#x#v1OAc;f z`8+>N=2h|avZLSm#-^Q0mx+3MB(*VlRiYF7Q-a?k(f?ZiF$ zlP79O6drptK`rDo*P|<%XSi)o?FedmySXy|`Q7*CSFT&IvHrNVZEf{08II(Or%jG+ z<1*WF=e^{Q=!SdZHjZa6FI;OF7-Sz9BD%kxM@TMf>+%oZ+AF(4TWsC$T~?Vkx%qvH zNJ+c2%1gh!io2{fZ#yvUg?viAE90T(^|m3Uq4O`7?Bo(_znr#ls(F@0f^@~A?YsUf zFn?Ld9I^et`II&B+_^$tJS*mzFRT#vzRy=SyJ@l1M7FEV=f?U(T`m+g6XVKx4gBY!*!v`IU zTBE}UtqR$6`F?}j@k{U52)csKG!>aHr^g3vB-HEiC4$|t@A#V6p^OX+uUMxW=d z`b!K941SE$?_2PRO;0xDdj@f!uMy1Rbw+%UMcXD#8F!7QJ2>%4PrsWe$TOXdpF?uG zpD~{@*eHX8vlT!s>?Vfkg3f$m)2ABqLEAn5jQOCwyKg3ZkcQ6oLQ_6A$lPGQG)ZvQKAr;DZh% z*g8NpGF*$y#RmZ&yCZ z82(e9dxt#mGbMZ7a?xMQ4b1p?nT<&S9`OJEs zULEKj(f2G*g;5msnBngNe&}Za!5GQc;hwY=3U@pT*wyaQ~zjL&+s3Cp6ug&vGuf z!y;*_6ZGJJdx_k=QmcB|OJZkEL<*!%*&K7!zTxHM8I4`bST|oY;(a_vB4_Rg-o@*9 z_D#6WzFa}geN#tr{nxkgx|cFvv$KRQcbpMkAR2vaS?OO_0oS7YMqYckCCojZZ{az7 z+XO(1>dGwOYs_%xcKblm(lO>4Z*F1#;i(r*0Y%NSbe%^laq`sx3arK5K zw-ay5;+o5(MBZ$YUBu0vx%6O*mTuLD*PMQv?mEQPCunn@?PmkI(J(8Fdf7)y`j8r~kq|{S0I4#2q4~YmY2Ao+uaC zB6w2b;jhUyo>$8b3iricQ*b#T-QB?VUCZy{q)Y3XN?z%|RN+}<@HjDk$4)&x5A8%A zIV0cJ`kh^$0#@!5ntxD$O@-4W`me^E-qjY{N|-g}4tW%{ z{;XgBcJF4%xYJ%&d4;itC zCrn&*@oq6EJ6#N!SNJSL`074l=dwaiBG|FX=W#Q}Y`^}nxgy#Bn<&O1nGl7U*LzLd+n_5f9>9Pmk-?CcKGnki>sv`maww~ z_q|Ifca_OuIpjEP`LjMLdB59lz0%iyiT__M;d-i4e?jqY<*6~{3%dW^u+v>-nVG%w zv!_qQuQh&JQQ?Q{y{0$Fv2pK;n{$)RIwvebY+*$ygAH3KbN_7bqKzGm%a1rqty&p+ zq|Qq57`L;Pv0Tk5zrNZS`7?$dk8FGw?V5Ww&vwd`bJdP6PR~WO?#qe(vXojN$DpOS zlEwSXx}zM%%lpzh^`_2u{%@n6CK+z(deXMd{O}yXwjL{^fMagi^}gEK@3dzoicDbc zt92+4H{Y&M9xuN?`Qdh6hLbNIA4oM=9`N(vgERIwZ4#uiqczUUH9OXvICgAt_mjT5 zp2@#wJf3d+_C(p;^^f(Hf4@$DE?>)Uq>%B$^iO>MEYqEJId^Oh|JS{=`r)TpSI&R< zDaIo=Sz(z3 zqoG%_E^a)ry-am(6U*=C+vnf3mpf}?_4{XeNpljX=%3H;jfD8L9`zmEni`SAGBZHo zO>nC?{@VDpJ*o>1Kbar(j|MB`7 zp3hRU8a?_F3l_+>us0jZN~HHa@87@coBD0jHBF@x#Z8~=FS^)OT>8LY^P8ulS@*H1-t8UV zn3iU}Nwr>j@cY(KgN*#}i3g(AujygUs#;rFFXZ-gt#a1#1-lZf-L!39h|XGhX~~i8 z9RZI|a_+u2;ihKn#b>wX1}|P1WViUhozS?ih2ml5wbiou%ugr$ms^+6G{bh2Sdny( z{GC80_gKqKqKRMD?3sDL?F*l=69eO{C)-U_ZEkp3mV}oG+1kv1m%QlTn{Rqd?_8(U zzsvvB&{m0d{vQ(+vLqUIGc><%9xYaF<(+uNOnT~H_$8Fl~UYm92 z7{BJrO^fe^UAQkR`}Lc6jc)U!=@U1E#qatj`gFoyo%EAh9A_pPozH1F&{SUf?DMqj zf{WkJyl0=kN$C_(Q|wi*xV|}5zcp@quDtx-%FW5q3HsB{i29oe z8+kP^Qjn1I+Tz2M`uNhKQsei6jioncv!yWkG#i{-;1p0~{C--$+b5Nc27S}Ldk+6G zI~cSxY_Dp%*kRqGE7o>ab)UDD|7klgW%9X2Pv+e zqX*LcBF7#)6FB|ggXY}MZlS*(ulQD8wrh}T-d4ueXDd_l^TPMzGs^AbE0;I? znmK#5(&CWIk7qu){H;Un>4dfi$p>@_rVGljaJM=}6fBxmu-2r)pkUq`7N(Y6g&UI7 zRMQH3n3W7V_T;m4Fm$}0AIIi7Wr?YMJ>!X_C*l>-tbZ20uZU+4e>e5```lL#9BxY6 zi9X--fBR~6<6R|fsVZwbnfvG1y?5qF;?jGg9J{%7XT-%c-s8p^pN*8B9QR-NYpTuS zUp;HK#F>cd?_F(>Y}hA#=I^#COo1g_|7W#bFg;bd`^USQQ)2TAetuY+Rq5NA%ub*rwJN6I|SN=qgG!L?Dh3rwByLF@?YU?s)2Rf_4=#iu6z=X-PWy; ztnuq~Q}5=|(^Gz^zL)#vKKo7gnp4xRzq?g(VQadqw5Rv}lUL2N?>x18t`&Z3`v2v- zE>21~pXGJhv+DoS`WLt5OEtC5eR0=!^)C5WukU*Q>Wqm}XRqn>9DWlfa`|71)AS!p z<@aBFq<-tD^1=4VgDUN56s5xed8wNEk7o#T3urMu7B?8g|0;=9^6%-9v^<@8Z_2#*cBU8^bjx7C|1C{eg?xm9q*DPNNfr&k9*KeN$xv2Rwy>p!Pj zU(MNn!};?qS!?C+0No;H=}XKK(|@+JPCDZ;;rYQQ)!)RO(v7W78W;6X&pTM6#S`H3 zx&Mh;XSnH~{EFJ22irP#*~@)rm#;0$WP78Yvucg`)SHj@X)oW@{;qx2!F3%+i)x^Qmc-ho)8HOWtMk+HOeuZu;jTd}DfCSy%?yof}`W;{Qi}RMM#VMtk zm(E(XwC`z=wcDbR&AUitarlq54~;{nJh>;MW+=M3MdkZx&i`3U_n)?#qp&LS%dDs2 zB@Xxd@;@G9{#$9(#IJ;(EKI;47uETRJgSQd}=Wa%4iyFD$o+h-Q@xwG(n+tXruwYZgiF$)939`4B#rwC7%pToz#ouh(p6AKID z-WJ>K`)c@t+4%%p+HCDoSbi^JV_-0ofGeywG}bGq+#3;{|H?w3t}Whhk^V!C)P>Vy zb9dXcM9;Pr2w+;iDolF{8?zm6;nW%5KD;l_agr&{yxhL-2=lh*()IIgllzO=%2S?h zdm!^B!%z8?`GsCF6Qv8WYn|tB-ciGr`)yO_%cPSBGr}J(ire4vanh0#foJL_HB3K$ zpCAK3qShJeS7Is1Pa?ri0ac7EV4Fj>;K!e{=qISfx9xNpAy#6{a| z@#o$bQSQb<%*P`wI>R|P?991iDLltaX`}q1jK3n67=D>31Ud=4eSBw;e&i%cn_QIz z>Jk;2%r6YTye>YqC|W_}cyfhmVN>o72lkgLE8T@7c-qd_v%ZzM(cKU_@ikjPtjMOa zkexyn%u=4)y}vbOO?x5mb?-%k7ImiAEoZJT?3BA8Cimv!-vT4H)0Hjkr%QFy|5S8u zt2tRPWzVFw>bt5qHLcuyH_AVpw$ai`qU7#3TctJA?ruNc-&A{E&N}vd^SukK+-}pX zx80t+@9Ck8M}2K^+u7X)$&)AVax%^hjzS^*FJN z6~2g8{uD?!B65541Xu2r0=ZX(?lH}EKC*)|-|(oy!#4%yf@{BBKJtS%OD)Fy!ioNQ z&M_tZi!FD(xM;cSeQVEAwJi~cT7Mp3S`lv|_4V_y)V+y^j%;4C>Qm%~FUj@x0@iyb ztl9pKS*)vI$Lt$#cOOgL+EaZXY2Vq#Pc~`V2Nv=jlu_bb(tLj#^AsQ9cb{X*e=YAd zet2rj&8(w~&M2Q-P`c&arLvv67CnELPjC=^b^94}Z`vE*t?nijZm$;IO%%*rYk4a4 zu-UV#`ZuSv8Q;{r{oSs&_}V?=-lDUO|0mZ!ZD%*Rbc<vl`nG+#A#YniQLih?-s>9OLEUH}04w{GBCM{-Mx?flC z@9HB<^q%}LS{XBGVSw|5%TD|Z(vU1+zpAl{$vt4b{7AlrJ;mMYJ zC?_|Yg=e?*(K|D?sXhL9Vdl5?x9{(sTUe<7Mf~Kvw%I%b?pgg)&Z(h3W>24Q<(3|U$&;94PD@El{kEb0dDPr4&eET!nVd8(@I4de zI^w6fdl6U3k>6Y`Z~YqktXC;;`!96Z@9pQYV_jC8tLYoZd*X_{1T;}X9cYUJj#tRn@b-z0NL_~2ZPwR8TpGSL-eXS3DTrP7d zt5?|W)vUQi7k_;2Ki#}Ax%WV3Q-rX{5drCgD*=OfugEtX>SC;3Ow($q2zbLtAq*fvB zeml!kr&(pH{tUa&eJ8Aq!|l7WHLm;Ad-E;UdNt>fOtETO@Kmi=%K}7KuGH#~ugeLs z5qdOx(iyF*s}`y0&OZD1bd2w$Z{qg8-timTcdxzq{O*p6?=yS9KR)xApB2KeBbx+pph(kJ*S% zol>zWxc=iy#`weBNilJqonF5L=c<*z>sWU6jK=EyepBO@`rplnP+P)M`0evC&8FtF z?^1tUY*bvCv?8rTEo5J4OMj9U_a*ix?<4v|Vz@3a_FjAPS-aBafmtL&x4QQ~$9s2p zy&RX9RcWhi-|*$|+t*fMtM~7(e{s!ANKEF3UX^E>`Gj5dikDP1>$+22KRWs?v7YDu zVsAEw>V=lB@K?=mIsR|^eE3^V$gbTXSKIq1{d=l>I$&bJ?j=`drXGDa-6;Ew@#(&a zm(PT-{$6@T@7v0ili$ncMTY)bdPk3c$J2eMWFD)XOuf3`N!!l0(71orY-ubBW-UH- zdjsOr_FP%$p=+?sLfF7b_nq$Txk*j@cke9ZKf2*w`R$vDSC?;2y3zRcyTR;;-3PlG za@ExZf44vz&|J}KKes{(68P=z|0{5NC{Cay@N@q=#`-1yz z3nN{Ab%o9BjVNEA_!sGtxXBDK|JD=reC^wVYquV9E^#y8Gh^RUvEC59DFy6OE2aj_VLR$) zw468SS5>t^($=yoFU(io&Wqpn;d5JBcHC6|o`18`^{kw~<>>0<_Qpwu3CI;6wv4Qw zyW7_IPZwX6yJT?6kD!S3BT3IKINg18>-n~eR%w1}=6`!-l629IqlLi{mntiEN}exV z`>4%x)*G>)lqnrO+NT507HsdoX&Qg&kpNfQJjW=*1q<2qik((#KVo{`HgCtqisgC? ztGu<2%-FJ!t$5xx#l2rseG6;_j#!4q{Yielyq;~kN=QTOYu#Ou%mRPkwocjdV9REk z`zIwhPAvU>@y*}6HEw%9GT;5a?DD;eZw0L}Jv__*bWZnJbi<1=;Y-SlLw8E}8g3ul z@?TDL@AkzhCep4mbDYI|SiT$!)FSJU^|<&&{iI~2Tjsy}`DyF6Eu zJ#3-kgGttEOX_v2>ke4x&N!*M_NMUh2xGl@2f72CU{w2R>g4ZL;>4U5B4JgPa5RC*82M7Z!NX^yUqP=-txasJch>^OgH^i#mOo7ivU(n)5DX z(alX4|Jbgo70?U0Pv zHZhxPRsSu`lJ9mAKK9kR`#)G+)?RP%9aU8qSnq~UN^0vb{ zS)Q%WmzM8I<>7g9qH@ZLwx8iO>sEf2j&hlKRqb)xY%+dKOn_5Jb6-_Xu*zv>rkLBC%&)j~y8eCa(xtC-m=&+N#3LpWz|iD;BWs^Xw|SEzEFp@yQKSvsQk$JN=CZR53%BzgdgrorV*TE`p6dH9Z0Tyf*i@Igns17) z&4u#2(|PRpCKd6CUWtF}U(d2}58t8soQ?l)Tw_zQUux1k=U&MD&03~?p^t=lq=R>R z+8=O!{*~cleMMQlkna7cwc8BlB#Noa2E8l0z2OSu`LL<_>v$Djrc6-j-`sxk!NG{9b1-)9m{@_tr(>4jGZ+1OB`&_+G8HWDvi(`nhNipcyzKl_I@uKsHb--u#w%C3! zfAw6Cg@NG}=k$#m_@uVG?d7w9lq>Jw@RswjFfjZBmn+*>9psZ?0Z%uuwA@ubEylp$ z7Co8qGq^v%HvL_xApiD1NBL}p>g{f}eV)lOFY(doK<)|34aVVhYjyV+{t4@TzHzIug%WPo_$3!X}!=f*0Oc}*m1gYutdd`VpQ@tco8Xo`BUY17R5 z{KkYg987asB4F=s9-}OtfL2bnxJ1g`MALa@i`poI6G3wCr3% zpPdo$Ykso%obNU;y=Es8rt~&D)mxT-?a_marY{L_Gj(3DTiGT-^8GfK!=+(H)r=e| zQ@9vod~CWtg|FQHd|CNszT#pxXO44j!kULptJjM$taU1>Z|<~u)^SGd){gaMTMj*% zpJUaeyZ%C@#jR;_H}>7{TrQPwB`@XjlQV$#HLsNB?9&WY5`S*{F!ud56WWlyd{gAS zH)%%|l#U0VtDAP^r+?w@1e@m{j}$D*pZM^}o)eSyKS)TB)AJNhOl#oxQ)eyqo12ik z%l7E=xj)a_)|)NTaowd|boce%NbhfbCf`!$>&n%vG-myW2#yVU zy|>{kb57d(w1&0$oOfq$Ey|xH_1zHpd)u(3Zubdbsc~{kp_4=Bh!Bd!S720&I+V8;k^!4G0)6ecj zC32}ec-~xImXr14&>e%{u{P~|AKe^1FV~6p3;g)E=!w>rtqaY5OwqhJEiL5m1%r6| zOY6#(^X~S_TPEv$HC*g(QtByn{+Z=>Zih0*doilj_t`gz z+}l}qo$E}~_H~oe>Z&F`cj=N_W4X8f%~A8l%o&THe0+0pW32O!%9+K6hlK9@;CA|R z^nP+tncCgFUPqN10d=o_bT7N;9(sh^>5`GsUBTFRYwelmew=Cl=lwD0Mfl{Zilx<0 z9$H&nT(;!p!*ch%dcpTT-HCqpf@_OY)z_x_XxlTNZyXaY-k_rQ%x;HK`@Wf*HFw;Y zZZ7FC-WQV%q*a+E? z#m4OO|20|Ce^HC~!PQsJc849Asq(wM<)g2La9{GF4wdC8JXQQW3)7|5R3E?GdQMHv z;g#@L%LnyGpN5JFJmzG(^Y=n;!#!q!7q@oi*DhT2HkSF8-LD@LW7|w`-)+f@U1hG% za_D6HqVp;Df7c$;?@CC`VyT+8jL)2J&fOj2hK6AeOZ29l`M8PY&y@Z{`yNXQT;=nB ze{OTTLT%8bWQ9%zu60M_?3K3m?@cWKQuuA5`P;kSw(feeq(k2&=&Uh!jk4sTDyC0O z30|H`r&>B5BRA^Sv9#LyRy;avz{9}Mr3EVXB&PG+<#T18SLZuD`Zt>#ZL}{} zEuP~XGe0!~dQ^ zq>roYrMMQy&eaEs8}&3qqU>ZOW_$NmmtNY<%<|MtI_nv`NbQ1|%2y3eILsGl?U~xS z^6N6^RHtK?PezzuF-{7Y!ojos{)+k(zA0fmKF=@QDB9bx`ZuGWA=65mcAd5QB7T>b zy%V2sQpwE1d+Fv+Gxk3?#rWb_#rqCxb-V7=Po^aYO_RcGTvu+ibd&sZ&2I8ZSLpXwVYjRpQq z(Q_$#!B*IECimHK#m^4}4*n6~^;g*Re#80~H*#EA#MZG+`zv{3&!2vkgN>UE#1>AE zzRxFJ-(uA3!SrqNje?gtU2Avb+)TcGI>_yN<7=;VCp&(INF6TA*!l6@s&mZBr*x~% z$z`0^be$k$rC#OmSLVH(#o6?tJ2l!@AB8epxZ{<+-J~wxvE zUEyeZ!t1e|C0oqQ84snJZUwYwouA`-zA0&q5@z(4v1HBZu76wl!C! z1gaH9&771xz3$w2T|e=hpu-Ga;T642Rvp?ezB`K*Sgue$!jUs`P8mxnyBYHXcZFVk zr!%}WTo;^iP*Q9%EjY77(NFa2ywuuzQ(C4L9eX@u=hn?D-y5D5JXY|0_wmz$WnrHl z>~25vuzdP9fhA0zO%4T>_L!7xyR(3gYwN_@$AUjN2*2uh=%$x4?=gGs^e+$i#Okk} z=Q_FI!S2+E%M6oj&OR(+tN!fGIkje=<`E9{@L5y6R!FX#%v_S6`IEbfeQ!7W-vfq= z78GPY^2jOPo;tJZTkEVzQ5H*$TA0N?By$@l#ZHm4*m*k7TkY;@u?hNewck|zTV>{_ z?=0%~ezG^>wYcFs#lKP9R$Js&vTJavq%_6V2U+w--@m2%=kiSRMy7);(ObTKZdbd? z^?@}v>h`s}R%=QN{Qs5)`Ly^5rtO`}a(mKgBb$I6muuoaIy2Tvd^xa=ztY^pM&C2s zbmbLU{v!<`);*0zPxtP>dM1*2YRk2B)gs-FIcW|jLIt-Oo%t-cHei+HpVz!Hw@YtY z#>Sa#PpF@;s_UA<@mW^PC)3>W7xA~7pGsNQpLQer-YTP+0WaP!PCZzlaBQsrbMUf| z!+MvFs>mcAnedo9E;;X-;g^)Bk9Md}4?oMZOyk^MJJTyOt&Faoe3OzBv5@6PGp zd46SIZBL8kD4uaIAoSkq^OvQAUR0cZ;pm_dcqFICcVF+S?)uygo^tUU92@qs`md2b za7yA;T5R6I^E>ZMwcfpexh?6M`{m!#r9t=a?oL#^H>oeW=+|Yt{g3{i)7N`)T2F6E z@|MP_KVE*=&v9OJO7r}59sz^YpkoOSBD*z=R~tO_k<8k@_@>M5y~Zc!FUdK7<#_Ad zjn|Bq3l|vI+FVw@vpVeB`}zl7_LHW*KCE8CSy0*VW6MnT?Z?w)UkQD_%V-$f#<_p* zxk(Mm$5_@ysLpFj`gE_Pz3b!*@!gCO@_HBY0~V&MzWXy(Xt5)|N6pcG1>gGf-1Qf4 zElfUew)xpo$ya;hul`F^b^qnFJ3Q}dy6lmFvtGZxtDn;Sv%J6C>_Tm-tnt_W`mNFh zzAN+Bhxbp|l#{_)(RusDEpE*W6|v1y*WaF4!pr!FEs0-gsp|4T?d#F`uZ>O^U2so( z^wGIA;or{PERGk}oLH$nS$pU0wTC*|Vw2^sUj*GSFN5D12qZ?t34X)n0wb zGM#bb^+b-cwQldH@BOk%bMMrzYo&Cv`PZJSmwvc&oqhTdXNH+N8R7%{{Ot!5q zobkS3!F>b6>l3#z&RoInX@76uqDPBT}+Qye-Cp!^Pw{FjDUBi z;ww+Xwk?mN3a{bs@M`Xy%bEYCf7Fm30PyY*`uCv09p__bfCuNRpUBWUx^3z^lF0fY275nM3b67D2V*?fj-24&7*VQ9WlO{X1GtCEUk;<)S}ZzOVXm z-y+Xo^7+3Tyj*Sc!;YNENu+U*D1z*~TRGP4SPwe$CGtjuao9;GC>Jf9{jbvuom1 z=1)KQT-q)pb0L4kzTLBSo>M&PcH!G>sVh8oRa`s6uSegn%P6g1Jy~8zDM+{Izi*}6 zO&cXkX={ai6*-ZL?1BRV?6#%Ozo(y)-d2B%c`MU1W}}wJJ^o9JKkk$KmUjA2mO#Ms z`PtY1%{f*moE|k{tC3Sp%{*m|j#LHtN^awYf-IXd4mTVyyl)xgp!+X}Tlm~X^-tTg zi%PE4?2hh#xTNnj|6?ml#hBm1L47q&uadle$f{p^_RVOT-q$%^-(I~jci!NI4Cv z_x70T-`IE2*+?_yl za#8(zx9!|P&S#akCWPd#t2Zc~Ag`#y*8KL`6Stl1dGZQ*>R$WxtU6WXw9f`=dv1Km z6|e59oO$oEyMc9i&x&8RT5rF0zqd}gKKI#on~&GFl;Eg$Bd zc)ou6vZPfNrcExY`@V-RJzsdycU8}ppy{{xxjWx6^WV-1_}CSGM@nnOp=T-Yn4Z4z zwSH-j7$pF$Fx>9{l5Z&+3z+%iJ)Z^}pVYn<+jkq+`}VRkFf3P?{^2j5Eb3w{yQ~LZ{pX=W(Fr8!n_txB!_tkHUc&xa?&MaLa z8>ch3(R^mh2^Ws7erkSv30CPw4^0bx&TQp5o&Q5**S`(VA5XY{zbjSwONHNyjVqLe z_VIn*qNu?b-TeBNT$WPmOFk{(V*T`dzPAuM}@LKqXwf=j^198Be;l>H^ef?dpow(2aDb${$aemXYWwyVpGhl|`2C*pHNs=IhMeH0sqU|S-iT=Jsd=`m{%Z20?;0<@mR(+c z(9EWzYA%cQRi+8IYnMjt)coRR6xF)jv`t!S$&#MSCoj467j8a$U`CW~vVas;kxJN68~!+cjFIbyt!{e zqMGh6gFKs8+DmWWwY+HVX#MzMLY3gNxKFvA9Wt`h*Y@1Ze02KbhVNG-&C-P*--$Pf z{AzP$W%&!K|9?V!etfo*K7a05(5!o(O_QJ8_q+T3;cvT||F0h2R)4g6-rkFMyw2UR zueVq`S@y~Q#58sGbd$~en}e$-{h4)d!zHwhb6<#-P~P>VlJEL&v~BqBkd)pdVx~w+r^su=ijJ&cuxLa7#Hu-1zRp8 zhre34N&oNTd!Z{MTYD2EZYR~$gqQG5XkGGigWdtN`s6ozmM`r8`D*2R{$R(r74bUD z4SxS=_50bdukF4<-?}+2r3zm)`8xx$Cto>PoV(F=>7i*Wiq%@Knjhq46#W;SW4O{| z!-Avt-@Vf^-K*yEq@-E=k+Halp!cc`FBkpz$Y6BZ_u0SS$7HW6#HHt+(%4d3u;j;V z;amBOXD_Txe?MVCeRqJ0t6#Belj^0zwMWguCvKiT*(=61ecW3K6=94$1-S?4G6}$51{pD5@!}fadmqzw}M`Ki5B=KfkZ-`+VlzjKn{^y{|U4>XmbPzF~Md z;nwyv)*nmveP8$OWaESi_AV~%3(hB#EcGRewzb|~v*6n@!3|q8l{}8`xu0e8gdxqm z=V!s4Y*l+{m1PH2CH^Y*-CzDK;a0ue@e039`B`P+E1X#uG{## zl*awFvV7Jt^92~cmv8+gJl)2`%HY7H{QFGn;yGG)KAsF( zc6D~I7lu64AuUX3va#?m}Bf- zYLRK=c(E@3>{T&~=)_8~s`#(_tY7fFUw(i0<9DV0t6P24&s~}&9HaYT+1Yv5?3FbO z`Xt&8Y?hYXenP7I^Xc;WGHp8+8gAU!wD8BbOC|G8$X-*Py(4s6Q|iAf7h)JGYuchwNKFc9d2N$ zsnusIS;QgZeX^@S+k5Kk-u_l)6X(a%ejJQjaB7k3na!c~QqwZuOxblyMAd)2dYhq) z&&U5B$Affy42w>3pP&2VL8WP?`R{8B->^S9>%U=o>WUN6&u=bV&$ms+<4}7Ur>*_^ zqZt)b5>6^)9^9MwJAAFO$J35$4lFCCU&~BO_| zp3bTh^1oAZdhh#tmssm-*j9_F>oj_(-#A+3y)1m)cWc57vbcuH-C-n&C8?K+!*e;*r{i){muAI`DjhAyi-rCB2X5|4P_9EZd zYwNN}>qwtVsGzl$?mCz*tAUYvJ(#*3&GSH0>Z#e1)O z^mzF>&Ued{y|Xf6(?Tb9R~pPI`~B)|yTf$-h=93kHp;4X%FL2Wda0v+mGvptCfB_) zp1H~M^+Z`ce)ml5O3=k)PZPY&ivF&>&vpHn@l=n3{hM6G`aBl}q;+1*vajnp`Gm`G z<6Y^xZUc|0Uv<{xtyywE@2c;!#oule&8yD|6#7$cb1s%~R`1Wk{4ATEEiY@o+poGe zQLF5Ng!{*JOKK^6bY%fk*5YBK^;=+-o*3$3T5;dTBz@D<#%XPFIZOEnmyj zhuoXR^?Q!mFUDrO$2&Jx-MPFkd+%eb2M0w~F+E7nxR%9uy5d&eyf~)f$&9P(4d*D| zu2I*MuYY=DN|dF|^GL-WPT{~cy$2>7-StCxC->|O?tP95bIUJiua|IftBKv<`NXs= z>`<{%Ncg?}
+a?|=B&vy!LU)tGd^jnIIZrj_$e3Br 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%0Ae&{p({g@Iuy54vS~U#DMK4=YxF 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 diff --git a/project/jni/application/gemrb/gemrb/CMakeLists.txt b/project/jni/application/gemrb/gemrb/CMakeLists.txt new file mode 100644 index 000000000..199dd2108 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/CMakeLists.txt @@ -0,0 +1,35 @@ +ADD_SUBDIRECTORY( core ) +ADD_SUBDIRECTORY( plugins ) +ADD_SUBDIRECTORY( override ) +ADD_SUBDIRECTORY( GUIScripts ) +ADD_SUBDIRECTORY( docs ) +ADD_SUBDIRECTORY( tests ) + +ADD_EXECUTABLE(gemrb GemRB.cpp ) +SET_TARGET_PROPERTIES(gemrb PROPERTIES INSTALL_RPATH ${LIB_DIR}) +INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} ) +IF(WIN32) + TARGET_LINK_LIBRARIES(gemrb gemrb_core) +ELSE(WIN32) + IF(APPLE) + TARGET_LINK_LIBRARIES(gemrb gemrb_core ${SDL_LIBRARY} + ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + ELSE(APPLE) + if (STATIC_LINK) + TARGET_LINK_LIBRARIES(gemrb ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} + -Wl,--whole-archive gemrb_core ${plugins} -Wl,--no-whole-archive) + else (STATIC_LINK) + TARGET_LINK_LIBRARIES(gemrb gemrb_core ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + endif (STATIC_LINK) + ENDIF(APPLE) +ENDIF(WIN32) + +# preconfigure the sample config with the selected paths +CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/GemRB.cfg.sample.in" + "${CMAKE_CURRENT_BINARY_DIR}/GemRB.cfg.sample" + IMMEDIATE @ONLY +) + +INSTALL( TARGETS gemrb DESTINATION ${BIN_DIR} ) +INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/GemRB.cfg.sample" GemRB.cfg.noinstall.sample DESTINATION ${SYSCONF_DIR} ) diff --git a/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample b/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample new file mode 100644 index 000000000..1f2261507 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample @@ -0,0 +1,254 @@ +##################################################### +# # +# This is the GemRB Configuration file. # +# Here are defined some default parameters for # +# basic configuration and paths definition. # +# # +# Parameters are defined as a Name=Value pair # +# The Value can be of three types: # +# - String # +# - Integer # +# - Boolean # +# # +# The String value is represented as follows # +# i.e. H:\GemRB\plugins # +# Integers are defined as follows # +# i.e. 12723 # +# Booleans are represented as 1 or 0 in this file # +# # +# Lines starting with # are ignored # +# # +##################################################### + +##################################################### +# # +# Game Type [String] Use one of the following # +# values: # +# # +# bg1 Baldur's Gate # +# bg2 Baldur's Gate 2 : SoA or ToB # +# tob Baldur's Gate 2 : ToB (obsolete) # +# iwd IceWind Dale # +# how IceWind Dale : HoW or ToTL # +# iwd2 IceWind Dale 2 # +# pst Planescape Torment # +# (More will come) # +# # +##################################################### + +GameType=test + +##################################################### +# Game Name [String] Title for GemRB window, use # +# anything you wish, e.g. Baldur's Gate 3: RotFL # +##################################################### + +GameName=Baldur's Gate 2 + +##################################################### +# Video Parameters # +##################################################### + +#Screen width +Width=640 + +#Screen height +Height=480 + +#Bits per pixel [Integer:16,32] +Bpp=32 + +#Fullscreen [Boolean] +Fullscreen=0 + +# Delay before tooltips appear [milliseconds] +TooltipDelay=500 + +##################################################### +# Audio Parameters # +##################################################### +# # +# All volume options are in percents, with 100 # +# being the normal and default volume # +# # +##################################################### + +# Choices: openal (default), sdlaudio (faster, but limited featureset), none +#AudioDriver = openal + +# Volume of ambient sounds +#VolumeAmbients = 100 + +# Volume during movie playback +#VolumeMovie = 100 + +# Volume of background music +#VolumeMusic = 100 + +# Volume of sound effects +#VolumeSFX = 100 + +# Volume of PC or NPC voices +#VolumeVoices = 100 + +##################################################### +# Case Sensitive Filesystem [Boolean] # +# # +# If your installed game files are residing on a # +# case sensitive filesystem (ext2 on Linux) then # +# you need to set this value to 1, it has no # +# effect on Windows # +##################################################### + +#CaseSensitive=1 + +#GameOnCD=0 + +##################################################### +# GUI Parameters # +##################################################### +# # +# GemRB may enhance the GUI of the Infinity Engine # +# games (so far only in bg2) creating functionally # +# new buttons or scrollbars where they weren't # +# present in original games. It may improve its # +# usability, but is not quite compatible with # +# mods changing graphics and alignment in the *.chu # +# files (e.g. the buttons will appear in old # +# coordinates and may stop being clickable). # +##################################################### + +# Enable all gui enhancements ? [Boolean] +GUIEnhancements = 1 + + +##################################################### +# Debug # +##################################################### + +# Do not play intro videos [Boolean], useful for development +#SkipIntroVideos=1 + +# Draw Frames per Second info [Boolean] +#DrawFPS=1 + +# Hide unexplored parts of a map +#FogOfWar=1 + +# Enable debug and cheat keystrokes, see docs/en/CheatKeys.txt +# full listing +#EnableCheatKeys=1 + +##################################################### +# Paths # +##################################################### + +##################################################### +# Game Paths [String] # +# # +# These are the paths where the Game you want to # +# play is installed. # +# Enter the full path to the directory. # +##################################################### + +GamePath=../gemrb/tests/minimal +CD1=/mnt/windows/Programmi/Black Isle/BGII - SoA/ +CD2=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD2/ +CD3=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD3/ +CD4=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD4/ +CD5=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD5/ + +##################################################### +# GemRB Cache Path [String] # +# # +# This is the path where GemRB will store the # +# cached files, enter the full path to the GemRB # +# Cache directory. # +##################################################### + +CachePath=./gemrb/Cache/ + +##################################################### +# GemRB Save Path [String] # +# # +# This is the path where GemRB looks for saved # +# games. # +# Enter the full path to the directory containing # +# e.g. the 'save' subdirectory. # +# # +# You do not have to specify this if you use save # +# subdir in the GamePath directory. # +##################################################### + +#SavePath=/mnt/windows/Programmi/Black Isle/BGII - SoA/ + +##################################################### +# GemRB Path [String] # +# # +# This is the path where GemRB is stored, just # +# enter the full path to the GemRB executable # +##################################################### + +GemRBPath=../gemrb + +##################################################### +# GemRB GUI Scripts Path [String] # +# # +# This is the path where GemRB GUI scripts are # +# stored, usually these are in the GemRB directory # +# Enter the full path to the directory containing # +# the 'GUIScript' subdirectory. # +##################################################### + +#GUIScriptsPath=./ + +##################################################### +# GemRB Plugins Path [String] # +# # +# This is the path containing GemRB plugins # +# - shared libraries (.so) on Unixes, or # +# DLLs (.dll) on windows. # +# Enter the full path to the directory. # +# # +# You may need to specify this path if running # +# GemRB from source directory on Linux. # +##################################################### + +PluginsPath=./gemrb/plugins/ + +##################################################### +# Game Data Path [String] # +# # +# This is the subdirectory under GamePath where # +# game data files are stored. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GameDataPath=data + +##################################################### +# Game Data Override Path [String] # +# # +# This is the subdirectory under GamePath where # +# game data override files are stored. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GameOverridePath=override + +##################################################### +# GemRB Data Override Path [String] # +# # +# This is the path where GemRB looks for the GemRB # +# data override directory. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GemRBOverridePath=/usr/share/games/gemrb + +##################################################### +# END # +##################################################### diff --git a/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in b/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in new file mode 100644 index 000000000..4b4dfbdac --- /dev/null +++ b/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in @@ -0,0 +1,259 @@ +##################################################### +# # +# This is the GemRB Configuration file. # +# Here are defined some default parameters for # +# basic configuration and paths definition. # +# # +# Parameters are defined as a Name=Value pair # +# The Value can be of three types: # +# - String # +# - Integer # +# - Boolean # +# # +# The String value is represented as follows # +# i.e. H:\GemRB\plugins # +# Integers are defined as follows # +# i.e. 12723 # +# Booleans are represented as 1 or 0 in this file # +# # +# Lines starting with # are ignored # +# # +##################################################### + +##################################################### +# # +# Game Type [String] Use one of the following # +# values: # +# # +# bg1 Baldur's Gate # +# bg2 Baldur's Gate 2 : SoA or ToB # +# tob Baldur's Gate 2 : ToB (obsolete) # +# iwd IceWind Dale # +# how IceWind Dale : HoW or ToTL # +# iwd2 IceWind Dale 2 # +# pst Planescape Torment # +# (More will come) # +# # +##################################################### + +GameType=bg2 + +##################################################### +# Game Name [String] Title for GemRB window, use # +# anything you wish, e.g. Baldur's Gate 3: RotFL # +##################################################### + +GameName=Baldur's Gate 2 + +##################################################### +# Video Parameters # +##################################################### + +#Screen width +Width=640 + +#Screen height +Height=480 + +#Bits per pixel [Integer:16,32] +Bpp=32 + +#Fullscreen [Boolean] +Fullscreen=0 + +# Delay before tooltips appear [milliseconds] +TooltipDelay=500 + +##################################################### +# Audio Parameters # +##################################################### +# # +# All volume options are in percents, with 100 # +# being the normal and default volume # +# # +##################################################### + +# Choices: openal (default), sdlaudio (faster, but limited featureset), none +#AudioDriver = openal + +# Volume of ambient sounds +#VolumeAmbients = 100 + +# Volume during movie playback +#VolumeMovie = 100 + +# Volume of background music +#VolumeMusic = 100 + +# Volume of sound effects +#VolumeSFX = 100 + +# Volume of PC or NPC voices +#VolumeVoices = 100 + +##################################################### +# Case Sensitive Filesystem [Boolean] # +# # +# If your installed game files are residing on a # +# case sensitive filesystem (ext2 on Linux) then # +# you need to set this value to 1, it has no # +# effect on Windows # +##################################################### + +#CaseSensitive=1 + +#GameOnCD=0 + +##################################################### +# GUI Parameters # +##################################################### +# # +# GemRB may enhance the GUI of the Infinity Engine # +# games (so far only in bg2) creating functionally # +# new buttons or scrollbars where they weren't # +# present in original games. It may improve its # +# usability, but is not quite compatible with # +# mods changing graphics and alignment in the *.chu # +# files (e.g. the buttons will appear in old # +# coordinates and may stop being clickable). # +##################################################### + +# Enable all gui enhancements ? [Boolean] +GUIEnhancements = 1 + + +##################################################### +# Debug # +##################################################### + +# Do not play intro videos [Boolean], useful for development +#SkipIntroVideos=1 + +# Draw Frames per Second info [Boolean] +#DrawFPS=1 + +# Hide unexplored parts of a map +#FogOfWar=1 + +# Enable debug and cheat keystrokes, see docs/en/CheatKeys.txt +# full listing +#EnableCheatKeys=1 + +##################################################### +# Paths # +##################################################### + +##################################################### +# Game Paths [String] # +# # +# These are the paths where the Game you want to # +# play is installed. # +# Enter the full path to the directory. # +##################################################### + +GamePath=/mnt/windows/Programmi/Black Isle/BGII - SoA/ +CD1=/mnt/windows/Programmi/Black Isle/BGII - SoA/ +CD2=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD2/ +CD3=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD3/ +CD4=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD4/ +CD5=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD5/ + +##################################################### +# GemRB Cache Path [String] # +# # +# This is the path where GemRB will store the # +# cached files, enter the full path to the GemRB # +# Cache directory. # +##################################################### + +CachePath=./Cache/ + +##################################################### +# GemRB Save Path [String] # +# # +# This is the path where GemRB looks for saved # +# games. # +# Enter the full path to the directory containing # +# e.g. the 'save' subdirectory. # +# # +# You do not have to specify this if you use save # +# subdir in the GamePath directory. # +##################################################### + +#SavePath=/mnt/windows/Programmi/Black Isle/BGII - SoA/ + +###### HERE BE DRAGONS ############################# +###### HERE BE DRAGONS ############################# +###### HERE BE DRAGONS ############################# +# You shouldn't need to change anything below this point. + +##################################################### +# GemRB Path [String] # +# # +# This is the path where GemRB is stored, just # +# enter the full path to the GemRB executable # +##################################################### + +#GemRBPath=@DATA_DIR@ + +##################################################### +# GemRB GUI Scripts Path [String] # +# # +# This is the path where GemRB GUI scripts are # +# stored, usually these are in the GemRB directory # +# Enter the full path to the directory containing # +# the 'GUIScript' subdirectory. # +##################################################### + +#GUIScriptsPath=@DATA_DIR@ + +##################################################### +# GemRB Plugins Path [String] # +# # +# This is the path containing GemRB plugins # +# - shared libraries (.so) on Unixes, or # +# DLLs (.dll) on windows. # +# Enter the full path to the directory. # +# # +# You may need to specify this path if running # +# GemRB from source directory on Linux. # +##################################################### + +#PluginsPath=@PLUGIN_DIR@ + +##################################################### +# Game Data Path [String] # +# # +# This is the subdirectory under GamePath where # +# game data files are stored. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GameDataPath=data + +##################################################### +# Game Data Override Path [String] # +# # +# This is the subdirectory under GamePath where # +# game data override files are stored. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GameOverridePath=override + +##################################################### +# GemRB Data Override Path [String] # +# # +# This is the path where GemRB looks for the GemRB # +# data override directory. # +# # +# You probably do NOT want to specify this! # +##################################################### + +#GemRBOverridePath=@DATA_DIR@ + +##################################################### +# END # +##################################################### diff --git a/project/jni/application/gemrb/src/GemRB.cpp b/project/jni/application/gemrb/gemrb/GemRB.cpp similarity index 93% rename from project/jni/application/gemrb/src/GemRB.cpp rename to project/jni/application/gemrb/gemrb/GemRB.cpp index fecabd6e2..9f8b08b75 100644 --- a/project/jni/application/gemrb/src/GemRB.cpp +++ b/project/jni/application/gemrb/gemrb/GemRB.cpp @@ -34,7 +34,7 @@ #endif #ifdef ANDROID -#include +#include #include "audio.h" // pause audio playing if app goes in background @@ -52,9 +52,6 @@ static void appPutToForeground() int main(int argc, char* argv[]) { -#ifdef ANDROID - SDL_ANDROID_SetApplicationPutToBackgroundCallback(&appPutToBackground, &appPutToForeground); -#endif Interface::SanityCheck(VERSION_GEMRB); core = new Interface( argc, argv ); if (core->Init() == GEM_ERROR) { @@ -64,6 +61,9 @@ int main(int argc, char* argv[]) getc(stdin); return -1; } +#ifdef ANDROID + SDL_ANDROID_SetApplicationPutToBackgroundCallback(&appPutToBackground, &appPutToForeground); +#endif core->Main(); delete( core ); textcolor(DEFAULT); diff --git a/project/jni/application/gemrb/gemrb/Makefile.am b/project/jni/application/gemrb/gemrb/Makefile.am new file mode 100644 index 000000000..4feac3dab --- /dev/null +++ b/project/jni/application/gemrb/gemrb/Makefile.am @@ -0,0 +1,13 @@ +bin_PROGRAMS = gemrb +sysconf_DATA = GemRB.cfg.sample.in +gemrb_SOURCES = GemRB.cpp + +gemrb_LDADD = ./core/libgemrb_core.la + +SUBDIRS = core plugins includes GUIScripts override docs +EXTRA_DIST = GemRB.cfg* plugins-prepare.sh CMakeLists.txt + +gemrb_LDFLAGS = $(all_libraries) @LIBPTHREAD@ + +#install-data-local: +# $(INSTALL_DATA) GemRB.cfg* $(sysconfdir) diff --git a/project/jni/application/gemrb/src/core/ActorMgr.cpp b/project/jni/application/gemrb/gemrb/core/ActorMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ActorMgr.cpp rename to project/jni/application/gemrb/gemrb/core/ActorMgr.cpp diff --git a/project/jni/application/gemrb/src/core/ActorMgr.h b/project/jni/application/gemrb/gemrb/core/ActorMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/ActorMgr.h rename to project/jni/application/gemrb/gemrb/core/ActorMgr.h diff --git a/project/jni/application/gemrb/src/core/Ambient.cpp b/project/jni/application/gemrb/gemrb/core/Ambient.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Ambient.cpp rename to project/jni/application/gemrb/gemrb/core/Ambient.cpp diff --git a/project/jni/application/gemrb/src/core/Ambient.h b/project/jni/application/gemrb/gemrb/core/Ambient.h similarity index 100% rename from project/jni/application/gemrb/src/core/Ambient.h rename to project/jni/application/gemrb/gemrb/core/Ambient.h diff --git a/project/jni/application/gemrb/src/core/AmbientMgr.cpp b/project/jni/application/gemrb/gemrb/core/AmbientMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/AmbientMgr.cpp rename to project/jni/application/gemrb/gemrb/core/AmbientMgr.cpp diff --git a/project/jni/application/gemrb/src/core/AmbientMgr.h b/project/jni/application/gemrb/gemrb/core/AmbientMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/AmbientMgr.h rename to project/jni/application/gemrb/gemrb/core/AmbientMgr.h diff --git a/project/jni/application/gemrb/src/core/AnimStructures.h b/project/jni/application/gemrb/gemrb/core/AnimStructures.h similarity index 100% rename from project/jni/application/gemrb/src/core/AnimStructures.h rename to project/jni/application/gemrb/gemrb/core/AnimStructures.h diff --git a/project/jni/application/gemrb/src/core/Animation.cpp b/project/jni/application/gemrb/gemrb/core/Animation.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Animation.cpp rename to project/jni/application/gemrb/gemrb/core/Animation.cpp diff --git a/project/jni/application/gemrb/src/core/Animation.h b/project/jni/application/gemrb/gemrb/core/Animation.h similarity index 100% rename from project/jni/application/gemrb/src/core/Animation.h rename to project/jni/application/gemrb/gemrb/core/Animation.h diff --git a/project/jni/application/gemrb/src/core/AnimationFactory.cpp b/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/AnimationFactory.cpp rename to project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp diff --git a/project/jni/application/gemrb/src/core/AnimationFactory.h b/project/jni/application/gemrb/gemrb/core/AnimationFactory.h similarity index 100% rename from project/jni/application/gemrb/src/core/AnimationFactory.h rename to project/jni/application/gemrb/gemrb/core/AnimationFactory.h diff --git a/project/jni/application/gemrb/src/core/AnimationMgr.cpp b/project/jni/application/gemrb/gemrb/core/AnimationMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/AnimationMgr.cpp rename to project/jni/application/gemrb/gemrb/core/AnimationMgr.cpp diff --git a/project/jni/application/gemrb/src/core/AnimationMgr.h b/project/jni/application/gemrb/gemrb/core/AnimationMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/AnimationMgr.h rename to project/jni/application/gemrb/gemrb/core/AnimationMgr.h diff --git a/project/jni/application/gemrb/src/core/ArchiveImporter.cpp b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ArchiveImporter.cpp rename to project/jni/application/gemrb/gemrb/core/ArchiveImporter.cpp diff --git a/project/jni/application/gemrb/src/core/ArchiveImporter.h b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h similarity index 100% rename from project/jni/application/gemrb/src/core/ArchiveImporter.h rename to project/jni/application/gemrb/gemrb/core/ArchiveImporter.h diff --git a/project/jni/application/gemrb/src/core/Audio.cpp b/project/jni/application/gemrb/gemrb/core/Audio.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Audio.cpp rename to project/jni/application/gemrb/gemrb/core/Audio.cpp diff --git a/project/jni/application/gemrb/src/core/Audio.h b/project/jni/application/gemrb/gemrb/core/Audio.h similarity index 97% rename from project/jni/application/gemrb/src/core/Audio.h rename to project/jni/application/gemrb/gemrb/core/Audio.h index 640083160..af7e57766 100644 --- a/project/jni/application/gemrb/src/core/Audio.h +++ b/project/jni/application/gemrb/gemrb/core/Audio.h @@ -61,8 +61,8 @@ public: virtual void ResetMusics() = 0; virtual bool Play() = 0; virtual bool Stop() = 0; - virtual bool Pause() = 0; - virtual bool Resume() = 0; + virtual bool Pause() = 0; + virtual bool Resume() = 0; virtual int CreateStream(Holder) = 0; virtual void UpdateListenerPos(int XPos, int YPos ) = 0; virtual void GetListenerPos(int &XPos, int &YPos ) = 0; diff --git a/project/jni/application/gemrb/src/core/Bitmap.cpp b/project/jni/application/gemrb/gemrb/core/Bitmap.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Bitmap.cpp rename to project/jni/application/gemrb/gemrb/core/Bitmap.cpp diff --git a/project/jni/application/gemrb/src/core/Bitmap.h b/project/jni/application/gemrb/gemrb/core/Bitmap.h similarity index 100% rename from project/jni/application/gemrb/src/core/Bitmap.h rename to project/jni/application/gemrb/gemrb/core/Bitmap.h diff --git a/project/jni/application/gemrb/src/core/CMakeLists.txt b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/core/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/core/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/core/Cache.cpp b/project/jni/application/gemrb/gemrb/core/Cache.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Cache.cpp rename to project/jni/application/gemrb/gemrb/core/Cache.cpp diff --git a/project/jni/application/gemrb/src/core/Cache.h b/project/jni/application/gemrb/gemrb/core/Cache.h similarity index 100% rename from project/jni/application/gemrb/src/core/Cache.h rename to project/jni/application/gemrb/gemrb/core/Cache.h diff --git a/project/jni/application/gemrb/src/core/Calendar.cpp b/project/jni/application/gemrb/gemrb/core/Calendar.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Calendar.cpp rename to project/jni/application/gemrb/gemrb/core/Calendar.cpp diff --git a/project/jni/application/gemrb/src/core/Calendar.h b/project/jni/application/gemrb/gemrb/core/Calendar.h similarity index 100% rename from project/jni/application/gemrb/src/core/Calendar.h rename to project/jni/application/gemrb/gemrb/core/Calendar.h diff --git a/project/jni/application/gemrb/src/core/Callback.cpp b/project/jni/application/gemrb/gemrb/core/Callback.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Callback.cpp rename to project/jni/application/gemrb/gemrb/core/Callback.cpp diff --git a/project/jni/application/gemrb/src/core/Callback.h b/project/jni/application/gemrb/gemrb/core/Callback.h similarity index 100% rename from project/jni/application/gemrb/src/core/Callback.h rename to project/jni/application/gemrb/gemrb/core/Callback.h diff --git a/project/jni/application/gemrb/src/core/CharAnimations.cpp b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/CharAnimations.cpp rename to project/jni/application/gemrb/gemrb/core/CharAnimations.cpp index 979094834..7104db16f 100644 --- a/project/jni/application/gemrb/src/core/CharAnimations.cpp +++ b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp @@ -558,10 +558,12 @@ CharAnimations::CharAnimations(unsigned int AnimID, ieDword ArmourLevel) // make initial phase depend on location to make the pulse appear // less even ColorMods[i].phase = 5*i; + ColorMods[i].locked = false; } GlobalColorMod.type = RGBModifier::NONE; GlobalColorMod.speed = 0; GlobalColorMod.phase = 0; + GlobalColorMod.locked = false; lastModUpdate = 0; AvatarsRowNum=AvatarsCount; @@ -2338,6 +2340,7 @@ void CharAnimations::PulseRGBModifiers() GlobalColorMod.type = RGBModifier::NONE; GlobalColorMod.phase = 0; GlobalColorMod.speed = 0; + GlobalColorMod.locked = false; } } @@ -2347,6 +2350,12 @@ void CharAnimations::PulseRGBModifiers() { ColorMods[i].phase += inc; change[i>>3] = true; + if (ColorMods[i].phase > 2*ColorMods[i].speed) { + ColorMods[i].type = RGBModifier::NONE; + ColorMods[i].phase = 0; + ColorMods[i].speed = 0; + ColorMods[i].locked = false; + } } } diff --git a/project/jni/application/gemrb/src/core/CharAnimations.h b/project/jni/application/gemrb/gemrb/core/CharAnimations.h similarity index 100% rename from project/jni/application/gemrb/src/core/CharAnimations.h rename to project/jni/application/gemrb/gemrb/core/CharAnimations.h diff --git a/project/jni/application/gemrb/src/core/Compressor.cpp b/project/jni/application/gemrb/gemrb/core/Compressor.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Compressor.cpp rename to project/jni/application/gemrb/gemrb/core/Compressor.cpp diff --git a/project/jni/application/gemrb/src/core/Compressor.h b/project/jni/application/gemrb/gemrb/core/Compressor.h similarity index 100% rename from project/jni/application/gemrb/src/core/Compressor.h rename to project/jni/application/gemrb/gemrb/core/Compressor.h diff --git a/project/jni/application/gemrb/src/core/ControlAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ControlAnimation.cpp rename to project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp diff --git a/project/jni/application/gemrb/src/core/ControlAnimation.h b/project/jni/application/gemrb/gemrb/core/ControlAnimation.h similarity index 100% rename from project/jni/application/gemrb/src/core/ControlAnimation.h rename to project/jni/application/gemrb/gemrb/core/ControlAnimation.h diff --git a/project/jni/application/gemrb/src/core/Core.cpp b/project/jni/application/gemrb/gemrb/core/Core.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Core.cpp rename to project/jni/application/gemrb/gemrb/core/Core.cpp diff --git a/project/jni/application/gemrb/src/core/DataFileMgr.cpp b/project/jni/application/gemrb/gemrb/core/DataFileMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/DataFileMgr.cpp rename to project/jni/application/gemrb/gemrb/core/DataFileMgr.cpp diff --git a/project/jni/application/gemrb/src/core/DataFileMgr.h b/project/jni/application/gemrb/gemrb/core/DataFileMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/DataFileMgr.h rename to project/jni/application/gemrb/gemrb/core/DataFileMgr.h diff --git a/project/jni/application/gemrb/src/core/Dialog.cpp b/project/jni/application/gemrb/gemrb/core/Dialog.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Dialog.cpp rename to project/jni/application/gemrb/gemrb/core/Dialog.cpp diff --git a/project/jni/application/gemrb/src/core/Dialog.h b/project/jni/application/gemrb/gemrb/core/Dialog.h similarity index 100% rename from project/jni/application/gemrb/src/core/Dialog.h rename to project/jni/application/gemrb/gemrb/core/Dialog.h diff --git a/project/jni/application/gemrb/src/core/DialogHandler.cpp b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/DialogHandler.cpp rename to project/jni/application/gemrb/gemrb/core/DialogHandler.cpp diff --git a/project/jni/application/gemrb/src/core/DialogHandler.h b/project/jni/application/gemrb/gemrb/core/DialogHandler.h similarity index 100% rename from project/jni/application/gemrb/src/core/DialogHandler.h rename to project/jni/application/gemrb/gemrb/core/DialogHandler.h diff --git a/project/jni/application/gemrb/src/core/DialogMgr.cpp b/project/jni/application/gemrb/gemrb/core/DialogMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/DialogMgr.cpp rename to project/jni/application/gemrb/gemrb/core/DialogMgr.cpp diff --git a/project/jni/application/gemrb/src/core/DialogMgr.h b/project/jni/application/gemrb/gemrb/core/DialogMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/DialogMgr.h rename to project/jni/application/gemrb/gemrb/core/DialogMgr.h diff --git a/project/jni/application/gemrb/src/core/DisplayMessage.cpp b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp similarity index 89% rename from project/jni/application/gemrb/src/core/DisplayMessage.cpp rename to project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp index 1954acc3f..941391d52 100644 --- a/project/jni/application/gemrb/src/core/DisplayMessage.cpp +++ b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp @@ -113,15 +113,17 @@ unsigned int DisplayMessage::GetSpeakerColor(const char *&name, const Scriptable void DisplayMessage::DisplayConstantString(int stridx, unsigned int color, Scriptable *target) const { if (stridx<0) return; - const char* text = core->GetString( strref_table[stridx], IE_STR_SOUND ); + char* text = core->GetString( strref_table[stridx], IE_STR_SOUND ); DisplayString(text, color, target); + core->FreeString(text); } void DisplayMessage::DisplayString(int stridx, unsigned int color, ieDword flags) const { if (stridx<0) return; - const char* text = core->GetString( stridx, flags); + char* text = core->GetString( stridx, flags); DisplayString(text, color, NULL); + core->FreeString(text); } void DisplayMessage::DisplayString(const char *text, unsigned int color, Scriptable *target) const @@ -179,10 +181,13 @@ void DisplayMessage::DisplayConstantStringName(int stridx, unsigned int color, c if (stridx<0) return; if(!speaker) return; - const char* text = core->GetString( strref_table[stridx], IE_STR_SOUND|IE_STR_SPEECH ); + char* text = core->GetString( strref_table[stridx], IE_STR_SOUND|IE_STR_SPEECH ); DisplayStringName(text, color, speaker); + core->FreeString(text); } +// String format is +// - blah blah void DisplayMessage::DisplayConstantStringAction(int stridx, unsigned int color, const Scriptable *attacker, const Scriptable *target) const { unsigned int attacker_color; @@ -209,8 +214,9 @@ void DisplayMessage::DisplayStringName(int stridx, unsigned int color, const Scr { if (stridx<0) return; - const char* text = core->GetString( stridx, flags); + char* text = core->GetString( stridx, flags); DisplayStringName(text, color, speaker); + core->FreeString( text ); } void DisplayMessage::DisplayStringName(const char *text, unsigned int color, const Scriptable *speaker) const @@ -221,10 +227,13 @@ void DisplayMessage::DisplayStringName(const char *text, unsigned int color, con if (!text) return; speaker_color = GetSpeakerColor(name, speaker); - int newlen = (int)(strlen( DisplayFormatName ) + strlen( name ) + - + strlen( text ) + 18); - char* newstr = ( char* ) malloc( newlen ); - snprintf( newstr, newlen, DisplayFormatName, speaker_color, name, color, text ); - DisplayString( newstr ); - free( newstr ); + //FIXME: what happens if there is no name? + if (name) { + int newlen = (int)(strlen( DisplayFormatName ) + strlen( name ) + + + strlen( text ) + 18); + char* newstr = ( char* ) malloc( newlen ); + snprintf( newstr, newlen, DisplayFormatName, speaker_color, name, color, text ); + DisplayString( newstr ); + free( newstr ); + } } diff --git a/project/jni/application/gemrb/src/core/DisplayMessage.h b/project/jni/application/gemrb/gemrb/core/DisplayMessage.h similarity index 100% rename from project/jni/application/gemrb/src/core/DisplayMessage.h rename to project/jni/application/gemrb/gemrb/core/DisplayMessage.h diff --git a/project/jni/application/gemrb/src/core/Effect.h b/project/jni/application/gemrb/gemrb/core/Effect.h similarity index 100% rename from project/jni/application/gemrb/src/core/Effect.h rename to project/jni/application/gemrb/gemrb/core/Effect.h diff --git a/project/jni/application/gemrb/src/core/EffectMgr.cpp b/project/jni/application/gemrb/gemrb/core/EffectMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/EffectMgr.cpp rename to project/jni/application/gemrb/gemrb/core/EffectMgr.cpp diff --git a/project/jni/application/gemrb/src/core/EffectMgr.h b/project/jni/application/gemrb/gemrb/core/EffectMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/EffectMgr.h rename to project/jni/application/gemrb/gemrb/core/EffectMgr.h diff --git a/project/jni/application/gemrb/src/core/EffectQueue.cpp b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/EffectQueue.cpp rename to project/jni/application/gemrb/gemrb/core/EffectQueue.cpp index 3828c85ad..b34f6dd52 100644 --- a/project/jni/application/gemrb/src/core/EffectQueue.cpp +++ b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp @@ -857,8 +857,7 @@ static int check_type(Actor* actor, Effect* fx) return 0; } if (actor->fxqueue.HasEffectWithResource(fx_store_spell_sequencer_ref, fx->Source) ) { - //TODO: display strref 0x806C - return 0; + return 0; } } diff --git a/project/jni/application/gemrb/src/core/EffectQueue.h b/project/jni/application/gemrb/gemrb/core/EffectQueue.h similarity index 100% rename from project/jni/application/gemrb/src/core/EffectQueue.h rename to project/jni/application/gemrb/gemrb/core/EffectQueue.h diff --git a/project/jni/application/gemrb/src/core/Factory.cpp b/project/jni/application/gemrb/gemrb/core/Factory.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Factory.cpp rename to project/jni/application/gemrb/gemrb/core/Factory.cpp diff --git a/project/jni/application/gemrb/src/core/Factory.h b/project/jni/application/gemrb/gemrb/core/Factory.h similarity index 100% rename from project/jni/application/gemrb/src/core/Factory.h rename to project/jni/application/gemrb/gemrb/core/Factory.h diff --git a/project/jni/application/gemrb/src/core/FactoryObject.cpp b/project/jni/application/gemrb/gemrb/core/FactoryObject.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/FactoryObject.cpp rename to project/jni/application/gemrb/gemrb/core/FactoryObject.cpp diff --git a/project/jni/application/gemrb/src/core/FactoryObject.h b/project/jni/application/gemrb/gemrb/core/FactoryObject.h similarity index 100% rename from project/jni/application/gemrb/src/core/FactoryObject.h rename to project/jni/application/gemrb/gemrb/core/FactoryObject.h diff --git a/project/jni/application/gemrb/src/core/Font.cpp b/project/jni/application/gemrb/gemrb/core/Font.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Font.cpp rename to project/jni/application/gemrb/gemrb/core/Font.cpp diff --git a/project/jni/application/gemrb/src/core/Font.h b/project/jni/application/gemrb/gemrb/core/Font.h similarity index 100% rename from project/jni/application/gemrb/src/core/Font.h rename to project/jni/application/gemrb/gemrb/core/Font.h diff --git a/project/jni/application/gemrb/src/core/GUI/Button.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Button.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Button.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Button.h b/project/jni/application/gemrb/gemrb/core/GUI/Button.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Button.h rename to project/jni/application/gemrb/gemrb/core/GUI/Button.h diff --git a/project/jni/application/gemrb/src/core/GUI/Console.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Console.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Console.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Console.h b/project/jni/application/gemrb/gemrb/core/GUI/Console.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Console.h rename to project/jni/application/gemrb/gemrb/core/GUI/Console.h diff --git a/project/jni/application/gemrb/src/core/GUI/Control.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Control.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/GUI/Control.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Control.cpp index 74e2488d3..fc02eb9db 100644 --- a/project/jni/application/gemrb/src/core/GUI/Control.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Control.cpp @@ -125,8 +125,7 @@ void Control::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) { //printf("OnKeyPress: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key); #ifdef ANDROID // mapping volume control to volume control keys on device, these keys must be set up in AndroidAppSettings.cfg - switch(Key) - { + switch(Key) { case 'o': // volume down case 'p': // volume up int Ambients, Movie, Music, SFX, Voices; @@ -135,23 +134,20 @@ void Control::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) core->GetDictionary()->Lookup( "Volume Music", (ieDword&)Music ); core->GetDictionary()->Lookup( "Volume SFX", (ieDword&)SFX ); core->GetDictionary()->Lookup( "Volume Voices", (ieDword&)Voices ); - if(Key=='o') - { + if (Key=='o') { if(Ambients>0) Ambients-=10; if(Ambients<0) Ambients=0; if(Movie>0) Movie-=10; if(Movie<0) Movie=0; if(Music>0) Music-=10; if(Music<0) Music=0; if(SFX>0) SFX-=10; if(SFX<0) SFX=0; if(Voices>0) Voices-=10; if(Voices<0) Voices=0; - } - else - { + } else { if(Ambients<100) Ambients+=10; if(Ambients>100) Ambients=100; if(Movie<100) Movie+=10; if(Movie>100) Movie=100; if(Music<100) Music+=10; if(Music>100) Music=100; if(SFX<100) SFX+=10; if(SFX>100) SFX=100; if(Voices<100) Voices+=10; if(Voices>100) Voices=100; } - core->GetDictionary()->SetAt( "Volume Ambients", (ieDword)Ambients ); + core->GetDictionary()->SetAt( "Volume Ambients", Ambients ); core->GetDictionary()->SetAt( "Volume Movie", Movie ); core->GetDictionary()->SetAt( "Volume Music", Music ); core->GetDictionary()->SetAt( "Volume SFX", SFX ); diff --git a/project/jni/application/gemrb/src/core/GUI/Control.h b/project/jni/application/gemrb/gemrb/core/GUI/Control.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Control.h rename to project/jni/application/gemrb/gemrb/core/GUI/Control.h diff --git a/project/jni/application/gemrb/src/core/GUI/EventMgr.cpp b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/EventMgr.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/EventMgr.h b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/EventMgr.h rename to project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h diff --git a/project/jni/application/gemrb/src/core/GUI/GameControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp similarity index 92% rename from project/jni/application/gemrb/src/core/GUI/GameControl.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp index a907b6f49..4382281ed 100644 --- a/project/jni/application/gemrb/src/core/GUI/GameControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp @@ -44,6 +44,12 @@ #define DEBUG_SHOW_DOORS DEBUG_SHOW_CONTAINERS #define DEBUG_SHOW_LIGHTMAP 0x08 +#ifndef TOUCHSCREEN + #define SCROLL_BORDER 5 +#else + #define SCROLL_BORDER 32 +#endif + static const Color cyan = { 0x00, 0xff, 0xff, 0xff }; @@ -68,6 +74,12 @@ static const Color blue = { 0x00, 0x00, 0xff, 0x80 }; +#ifdef TOUCHSCREEN +static const Color gray = { + 0x80, 0x80, 0x80, 0xff +}; +#endif + //Animation* effect; #define FORMATIONSIZE 10 @@ -120,6 +132,9 @@ GameControl::GameControl(void) lastCursor = IE_CURSOR_NORMAL; moveX = moveY = 0; scrolling = false; +#ifdef TOUCHSCREEN + touched=false; +#endif numScrollCursor = 0; DebugFlags = 0; AIUpdateCounter = 1; @@ -131,8 +146,7 @@ GameControl::GameControl(void) core->GetDictionary()->Lookup("Center",tmp); if (tmp) { ScreenFlags=SF_ALWAYSCENTER|SF_CENTERONACTOR; - } - else { + } else { ScreenFlags = SF_CENTERONACTOR; } LeftCount = 0; @@ -572,6 +586,25 @@ void GameControl::Draw(unsigned short x, unsigned short y) } } } + +#ifdef TOUCHSCREEN + if(moveY < 0 && scrolling) + video->DrawLine(screen.x+4, screen.y+SCROLL_BORDER, screen.w+screen.x-4, screen.y+SCROLL_BORDER, red); + else + video->DrawLine(screen.x+4, screen.y+SCROLL_BORDER, screen.w+screen.x-4, screen.y+SCROLL_BORDER, gray); + if(moveY > 0 && scrolling) + video->DrawLine(screen.x+4, screen.h-SCROLL_BORDER, screen.w+screen.x-4, screen.h-SCROLL_BORDER, red); + else + video->DrawLine(screen.x+4, screen.h-SCROLL_BORDER, screen.w+screen.x-4, screen.h-SCROLL_BORDER, gray); + if(moveX < 0 && scrolling) + video->DrawLine(screen.x+SCROLL_BORDER, screen.y+4, screen.x+SCROLL_BORDER, screen.h+screen.y-4, red); + else + video->DrawLine(screen.x+SCROLL_BORDER, screen.y+4, screen.x+SCROLL_BORDER, screen.h+screen.y-4, gray); + if(moveX > 0 && scrolling) + video->DrawLine(screen.w+screen.x-SCROLL_BORDER, screen.y+4, screen.w+screen.x-SCROLL_BORDER, screen.h-4, red); + else + video->DrawLine(screen.w+screen.x-SCROLL_BORDER, screen.y+4, screen.w+screen.x-SCROLL_BORDER, screen.h-4, gray); +#endif } /** inherited from Control, GameControl doesn't need it */ @@ -760,9 +793,9 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) if (target) { src->CastSpell( TestSpell, target, false ); if (src->LastTarget) { - src->CastSpellEnd( TestSpell ); + src->CastSpellEnd(); } else { - src->CastSpellPointEnd( TestSpell ); + src->CastSpellPointEnd(); } } } @@ -971,12 +1004,12 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) printf("Show lightmap %s\n", DebugFlags & DEBUG_SHOW_LIGHTMAP ? "ON" : "OFF"); break; case '7': //toggles fog of war - core->FogOfWar ^= 1; - printf("Show Fog-Of-War: %s\n", core->FogOfWar & 1 ? "ON" : "OFF"); + core->FogOfWar ^= FOG_DRAWFOG; + printf("Show Fog-Of-War: %s\n", core->FogOfWar & FOG_DRAWFOG ? "ON" : "OFF"); break; case '8': //show searchmap over area - core->FogOfWar ^= 2; - printf("Show searchmap %s\n", core->FogOfWar & 2 ? "ON" : "OFF"); + core->FogOfWar ^= FOG_DRAWSEARCHMAP; + printf("Show searchmap %s\n", core->FogOfWar & FOG_DRAWSEARCHMAP ? "ON" : "OFF"); break; default: printf( "KeyRelease:%d - %d\n", Key, Mod ); @@ -1196,7 +1229,72 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y) if (ScreenFlags & SF_DISABLEMOUSE) { return; } + +#ifdef TOUCHSCREEN + int mousescrollspd = core->GetMouseScrollSpeed(); + Region region; + Map* map; + Point mapsize; + Region viewport = core->GetVideoDriver()->GetViewport(); + moveX = 0; + moveY = 0; + // Top scroll area + region=Region(XPos, YPos, Width, YPos+SCROLL_BORDER); + if(region.PointInside(x, y)) + { + // Check for end of map area + if(viewport.y > 0) + moveY = -mousescrollspd; + } + // Bottom scroll area + region=Region(XPos, Height-SCROLL_BORDER, Width, Height); + if(region.PointInside(x, y)) + { + // Check for end of map area + map = core->GetGame()->GetCurrentArea(); + if(map != NULL) + { + mapsize = map->TMap->GetMapSize(); + if((viewport.y + viewport.h) < mapsize.y) + moveY = mousescrollspd; + } + } + // Left scroll area + region=Region(XPos, YPos, XPos+SCROLL_BORDER, Height); + if(region.PointInside(x, y)) + { + // Check for end of map area + if(viewport.x > 0) + moveX = -mousescrollspd; + } + // Right scroll area + region=Region(Width-SCROLL_BORDER, YPos, Width, Height); + if(region.PointInside(x, y)) + { + // Check for end of map area + map = core->GetGame()->GetCurrentArea(); + if(map != NULL) + { + mapsize = map->TMap->GetMapSize(); + if((viewport.x + viewport.w) < mapsize.x) + moveX = mousescrollspd; + } + } + if ((moveX != 0 || moveY != 0) && touched) + { + scrolling = true; + return; + } + else + { + moveX = 0; + moveY = 0; + scrolling = false; + Video* video = core->GetVideoDriver(); + video->SetDragCursor(NULL); + } +#endif lastMouseX = x; lastMouseY = y; Point p( x,y ); @@ -1361,7 +1459,7 @@ end_function: } } -#define SCROLL_BORDER 5 +//#define SCROLL_BORDER 5 /** Global Mouse Move Event */ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) @@ -1373,7 +1471,7 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) if (Owner->Visible!=WINDOW_VISIBLE) { return; } - +#ifndef TOUCHSCREEN int mousescrollspd = core->GetMouseScrollSpeed(); if (x <= SCROLL_BORDER) @@ -1401,6 +1499,7 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) Video* video = core->GetVideoDriver(); video->SetDragCursor(NULL); } +#endif } void GameControl::UpdateScrolling() { @@ -1475,11 +1574,11 @@ void GameControl::TryToPick(Actor *source, Door *tgt) source->ClearActions(); source->SetModal(MS_NONE); if (tgt->Trapped && tgt->TrapDetected) { - snprintf(Tmp, sizeof(Tmp), "RemoveTraps(\"%s\")", tgt->GetScriptName() ); + strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); } else { - snprintf(Tmp, sizeof(Tmp), "PickLock(\"%s\")", tgt->GetScriptName() ); + strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) ); } - source->AddAction( GenerateAction( Tmp ) ); + source->AddAction( GenerateActionDirect( Tmp, tgt ) ); } //generate action code for source actor to try to pick a lock/disable trap on a container @@ -1491,11 +1590,11 @@ void GameControl::TryToPick(Actor *source, Container *tgt) source->ClearActions(); source->SetModal(MS_NONE); if (tgt->Trapped && tgt->TrapDetected) { - snprintf(Tmp, sizeof(Tmp), "RemoveTraps(\"%s\")", tgt->GetScriptName() ); + strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); } else { - snprintf(Tmp, sizeof(Tmp), "PickLock(\"%s\")", tgt->GetScriptName() ); + strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) ); } - source->AddAction( GenerateAction( Tmp ) ); + source->AddAction( GenerateActionDirect( Tmp, tgt ) ); } //generate action code for source actor to try to disable trap (only trap type active regions) @@ -1508,20 +1607,8 @@ void GameControl::TryToDisarm(Actor *source, InfoPoint *tgt) source->ClearPath(); source->ClearActions(); source->SetModal(MS_NONE); - snprintf(Tmp, sizeof(Tmp), "RemoveTraps(\"%s\")", tgt->GetScriptName() ); - source->AddAction( GenerateAction( Tmp ) ); -} - -//generate action code for source actor to try to force open lock on a door/container -void GameControl::TryToBash(Actor *source, Scriptable *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - snprintf(Tmp, sizeof(Tmp), "Attack(\"%s\")", tgt->GetScriptName() ); - source->AddAction( GenerateAction( Tmp ) ); + strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); + source->AddAction( GenerateActionDirect( Tmp, tgt ) ); } //generate action code for source actor to use item/cast spell on a point @@ -1538,29 +1625,33 @@ void GameControl::TryToCast(Actor *source, const Point &tgt) spellCount--; if (spellOrItem>=0) { - sprintf(Tmp, "NIDSpecial8()"); + if (spellIndex<0) { + strncpy(Tmp, "SpellPointNoDec(\"\",[0.0])", sizeof(Tmp) ); + } else { + strncpy(Tmp, "SpellPoint(\"\",[0.0])", sizeof(Tmp) ); + } } else { //using item on target - sprintf(Tmp, "NIDSpecial7()"); + strncpy(Tmp, "UseItemPoint(\"\",[0,0],0)", sizeof(Tmp) ); } Action* action = GenerateAction( Tmp ); action->pointParameter=tgt; - if (spellOrItem>=0) - { - CREMemorizedSpell *si; - //spell casting at target - si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); - if (!si) - { - ResetTargetMode(); - return; + if (spellOrItem>=0) { + if (spellIndex<0) { + sprintf(action->string0Parameter,"%.8s",spellName); + } else { + CREMemorizedSpell *si; + //spell casting at target + si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); + if (!si) { + ResetTargetMode(); + return; + } + sprintf(action->string0Parameter,"%.8s",si->SpellResRef); } - sprintf(action->string0Parameter,"%.8s",si->SpellResRef); - } - else - { - action->int0Parameter=spellSlot; - action->int1Parameter=spellIndex; + } else { + action->int0Parameter = spellSlot; + action->int1Parameter = spellIndex; } source->AddAction( action ); if (!spellCount) { @@ -1582,28 +1673,32 @@ void GameControl::TryToCast(Actor *source, Actor *tgt) spellCount--; if (spellOrItem>=0) { - sprintf(Tmp, "NIDSpecial6()"); + if (spellIndex<0) { + sprintf(Tmp, "NIDSpecial7()"); + } else { + sprintf(Tmp, "NIDSpecial6()"); + } } else { //using item on target sprintf(Tmp, "NIDSpecial5()"); } Action* action = GenerateActionDirect( Tmp, tgt); - if (spellOrItem>=0) - { - CREMemorizedSpell *si; - //spell casting at target - si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); - if (!si) - { - ResetTargetMode(); - return; + if (spellOrItem>=0) { + if (spellIndex<0) { + sprintf(action->string0Parameter,"%.8s",spellName); + } else { + CREMemorizedSpell *si; + //spell casting at target + si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); + if (!si) { + ResetTargetMode(); + return; + } + sprintf(action->string0Parameter,"%.8s",si->SpellResRef); } - sprintf(action->string0Parameter,"%.8s",si->SpellResRef); - } - else - { - action->int0Parameter=spellSlot; - action->int1Parameter=spellIndex; + } else { + action->int0Parameter = spellSlot; + action->int1Parameter = spellIndex; } source->AddAction( action ); if (!spellCount) { @@ -1718,7 +1813,7 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p) switch(trap->Type) { case ST_TRAVEL: - actor->UseExit(true); + actor->UseExit(trap->GetGlobalID()); return false; case ST_TRIGGER: //the importer shouldn't load the script @@ -1788,6 +1883,9 @@ void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short StartY = py; SelectionRect.w = 0; SelectionRect.h = 0; +#ifdef TOUCHSCREEN + touched=true; +#endif } } @@ -1812,6 +1910,37 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B Map* area = game->GetCurrentArea( ); if (!area) return; +#ifdef TOUCHSCREEN + touched=false; + if(scrolling) + { + moveX = 0; + moveY = 0; + scrolling=false; + Video* video = core->GetVideoDriver(); + video->SetDragCursor(NULL); + if (DrawSelectionRect) + { + Actor** ab; + unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); + if (count != 0) + { + for (i = 0; i < highlighted.size(); i++) + highlighted[i]->SetOver( false ); + highlighted.clear(); + game->SelectActor( NULL, false, SELECT_NORMAL ); + for (i = 0; i < count; i++) + { + // FIXME: should call handler only once + game->SelectActor( ab[i], true, SELECT_NORMAL ); + } + } + free( ab ); + DrawSelectionRect = false; + } + return; + } +#endif if (DrawSelectionRect) { Actor** ab; unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); @@ -1876,8 +2005,16 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B return; } if (overInfoPoint) { - if (HandleActiveRegion(overInfoPoint, pc, p)) { - return; + if (overInfoPoint->Type==ST_TRAVEL) { + int i = game->selected.size(); + ieDword exitID = overInfoPoint->GetGlobalID(); + while(i--) { + game->selected[i]->UseExit(exitID); + } + } else { + if (HandleActiveRegion(overInfoPoint, pc, p)) { + return; + } } } @@ -2160,8 +2297,7 @@ void GameControl::OnSpecialKeyPress(unsigned char Key) if (ScreenFlags & SF_LOCKSCROLL) { moveX = 0; moveY = 0; - } - else { + } else { // override any existing viewport moves which may be in progress core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false ); // move it directly ourselves, since we might be paused @@ -2668,6 +2804,7 @@ Actor *GameControl::GetLastActor() //cnt is the number of different targets (usually 1) void GameControl::SetupItemUse(int slot, int header, Actor *u, int targettype, int cnt) { + memset(spellName, 0, sizeof(ieResRef)); spellOrItem = -1; spellUser = u; spellSlot = slot; @@ -2685,8 +2822,9 @@ void GameControl::SetupItemUse(int slot, int header, Actor *u, int targettype, i //u is the caster //target type is a bunch of GetActor flags that alter valid targets //cnt is the number of different targets (usually 1) -void GameControl::SetupCasting(int type, int level, int idx, Actor *u, int targettype, int cnt) +void GameControl::SetupCasting(ieResRef spellname, int type, int level, int idx, Actor *u, int targettype, int cnt) { + memcpy(spellName, spellname, sizeof(ieResRef)); spellOrItem = type; spellUser = u; spellSlot = level; diff --git a/project/jni/application/gemrb/src/core/GUI/GameControl.h b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h similarity index 96% rename from project/jni/application/gemrb/src/core/GUI/GameControl.h rename to project/jni/application/gemrb/gemrb/core/GUI/GameControl.h index 8faa5e5ad..8a4f845f2 100644 --- a/project/jni/application/gemrb/src/core/GUI/GameControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h @@ -112,6 +112,9 @@ private: Region SelectionRect; short StartX, StartY; //int action; +#ifdef TOUCHSCREEN + bool touched; // true, if player touched screen (left button down and hold) +#endif public: Door* overDoor; Container* overContainer; @@ -187,6 +190,8 @@ private: Actor *user; //the user of item or spell public: DialogHandler *dialoghandler; + //the name of the spell to cast + ieResRef spellName; //using spell or item int spellOrItem; // -1 = item, otherwise the spell type //the user of spell or item @@ -201,7 +206,6 @@ public: int HideGUI(); int UnhideGUI(); void TryToAttack(Actor *source, Actor *target); - void TryToBash(Actor *source, Scriptable *tgt); void TryToCast(Actor *source, const Point &p); void TryToCast(Actor *source, Actor *target); void TryToDefend(Actor *source, Actor *target); @@ -245,7 +249,7 @@ public: /** Sets up targeting with spells or items */ void SetupItemUse(int slot, int header, Actor *actor, int targettype, int cnt); /** Page is the spell type + spell level info */ - void SetupCasting(int type, int level, int slot, Actor *actor, int targettype, int cnt); + void SetupCasting(ieResRef spellname, int type, int level, int slot, Actor *actor, int targettype, int cnt); bool SetEvent(int eventType, EventHandler handler); }; diff --git a/project/jni/application/gemrb/src/core/GUI/Label.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Label.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Label.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Label.h b/project/jni/application/gemrb/gemrb/core/GUI/Label.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Label.h rename to project/jni/application/gemrb/gemrb/core/GUI/Label.h diff --git a/project/jni/application/gemrb/src/core/GUI/MapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/MapControl.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/MapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/MapControl.h rename to project/jni/application/gemrb/gemrb/core/GUI/MapControl.h diff --git a/project/jni/application/gemrb/src/core/GUI/Progressbar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Progressbar.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Progressbar.h b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Progressbar.h rename to project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h diff --git a/project/jni/application/gemrb/src/core/GUI/ScrollBar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/ScrollBar.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/ScrollBar.h b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/ScrollBar.h rename to project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h diff --git a/project/jni/application/gemrb/src/core/GUI/Slider.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Slider.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Slider.h b/project/jni/application/gemrb/gemrb/core/GUI/Slider.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Slider.h rename to project/jni/application/gemrb/gemrb/core/GUI/Slider.h diff --git a/project/jni/application/gemrb/src/core/GUI/TextArea.cpp b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/GUI/TextArea.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp index 6f3d05d43..b19ad5770 100644 --- a/project/jni/application/gemrb/src/core/GUI/TextArea.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp @@ -840,6 +840,27 @@ void TextArea::RedrawTextArea(const char* VariableName, unsigned int Sum) Changed = true; } +void TextArea::SelectText(const char *select) +{ + int i = lines.size(); + while(i--) { + if (!stricmp(lines[i], select) ) { + CurLine = i; + if (sb) { + ScrollBar* bar = ( ScrollBar* ) sb; + bar->SetPos( i ); + } else { + SetRow( i ); + } + RedrawTextArea( VarName, i); + CalcRowCount(); + Owner->Invalidate(); + core->RedrawAll(); + break; + } + } +} + const char* TextArea::QueryText() { if ( ValueCreatePalette( white, black ); } diff --git a/project/jni/application/gemrb/src/core/GUI/TextEdit.h b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/TextEdit.h rename to project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h diff --git a/project/jni/application/gemrb/src/core/GUI/Window.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Window.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/Window.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/Window.h b/project/jni/application/gemrb/gemrb/core/GUI/Window.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/Window.h rename to project/jni/application/gemrb/gemrb/core/GUI/Window.h diff --git a/project/jni/application/gemrb/src/core/GUI/WorldMapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/WorldMapControl.cpp rename to project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp diff --git a/project/jni/application/gemrb/src/core/GUI/WorldMapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h similarity index 100% rename from project/jni/application/gemrb/src/core/GUI/WorldMapControl.h rename to project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h diff --git a/project/jni/application/gemrb/src/core/Game.cpp b/project/jni/application/gemrb/gemrb/core/Game.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/Game.cpp rename to project/jni/application/gemrb/gemrb/core/Game.cpp index 59a218593..a5f706c10 100644 --- a/project/jni/application/gemrb/src/core/Game.cpp +++ b/project/jni/application/gemrb/gemrb/core/Game.cpp @@ -96,6 +96,8 @@ Game::Game(void) : Scriptable( ST_GLOBAL ) } interval = 1000/AI_UPDATE_TIME; + hasInfra = false; + familiarBlock = false; //FIXME:i'm not sure in this... NoInterrupt(); } @@ -365,6 +367,11 @@ void Game::InitActorPos(Actor *actor) unsigned int ip = (unsigned int) (actor->InParty-1); AutoTable start("start"); AutoTable strta("startpos"); + + if (!start || !strta) { + printMessage("Game","Game is missing character start data.\n",RED); + abort(); + } // 0 - single player, 1 - tutorial, 2 - expansion ieDword playmode = 0; core->GetDictionary()->Lookup( "PlayMode", playmode ); @@ -384,8 +391,11 @@ void Game::InitActorPos(Actor *actor) actor->Pos.y = actor->Destination.y = (short) atoi( strta->QueryField( strta->GetRowIndex(ypos), ip ) ); actor->SetOrientation( atoi( strta->QueryField( strta->GetRowIndex(rot), ip) ), false ); - strta.load("startare"); - strnlwrcpy(actor->Area, strta->QueryField( strta->GetRowIndex(area), 0 ), 8 ); + if (strta.load("startare")) { + strnlwrcpy(actor->Area, strta->QueryField( strta->GetRowIndex(area), 0 ), 8 ); + } else { + strnlwrcpy(actor->Area, CurrentArea, 8 ); + } } int Game::JoinParty(Actor* actor, int join) @@ -1076,6 +1086,7 @@ bool Game::EveryoneNearPoint(Map *area, const Point &p, int flags) const return false; } if (Distance(p,PCs[i])>MAX_TRAVELING_DISTANCE) { +printf("Actor %s is not near!\n", PCs[i]->LongName); return false; } } @@ -1814,3 +1825,12 @@ Actor *Game::GetActorByGlobalID(ieDword globalID) return GetGlobalActorByGlobalID(globalID); } +ieByte *Game::AllocateMazeData() +{ + if (mazedata) { + free(mazedata); + } + mazedata = (ieByte*)malloc(MAZE_DATA_SIZE); + return mazedata; +} + diff --git a/project/jni/application/gemrb/src/core/Game.h b/project/jni/application/gemrb/gemrb/core/Game.h similarity index 89% rename from project/jni/application/gemrb/src/core/Game.h rename to project/jni/application/gemrb/gemrb/core/Game.h index 1e4f9b9ea..edb356001 100644 --- a/project/jni/application/gemrb/src/core/Game.h +++ b/project/jni/application/gemrb/gemrb/core/Game.h @@ -157,6 +157,64 @@ struct GAMLocationEntry { Point Pos; }; +//pst maze data structures (TODO: create a separate class?) +struct maze_entry { + ieDword unknown00; + ieDword accessible; + ieDword valid; + ieDword trapped; + ieDword traptype; + ieWord walls; + ieDword unknown16; +}; + +struct maze_header { + ieDword maze_sizex, maze_sizey; + ieDword pos1x, pos1y; //nordom's position + ieDword pos2x, pos2y; //main hall position + ieDword pos3x, pos3y; //unknown + ieDword pos4x, pos4y; //unknown + ieDword trapcount; //based on map size + ieDword initialized; //set to 1 + ieDword unknown2c; //unknown + ieDword unknown30; //unknown +}; + +#define MAZE_ENTRY_SIZE sizeof(maze_entry) +#define MAZE_HEADER_SIZE sizeof(maze_header) +#define MAZE_MAX_DIM 8 +#define MAZE_ENTRY_COUNT (MAZE_MAX_DIM*MAZE_MAX_DIM) +#define MAZE_DATA_SIZE (MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE+MAZE_HEADER_SIZE) +#define MAZE_DATA_SIZE_HARDCODED 1720 + +//maze header indices +#define MH_POS1X 0 +#define MH_POS1Y 1 +#define MH_POS2X 2 +#define MH_POS2Y 3 +#define MH_POS3X 4 +#define MH_POS3Y 5 +#define MH_POS4X 6 +#define MH_POS4Y 7 +#define MH_TRAPCOUNT 8 +#define MH_INITED 9 +#define MH_UNKNOWN2C 10 +#define MH_UNKNOWN30 11 + +//maze entry indices +#define ME_0 0 +#define ME_VALID 1 +#define ME_ACCESSIBLE 2 +#define ME_TRAP 3 +#define ME_WALLS 4 +#define ME_16 5 + +//ME_WALL bitfields +#define WALL_EAST 1 +#define WALL_WEST 2 +#define WALL_NORTH 4 +#define WALL_SOUTH 8 + #define MAX_CRLEVEL 32 typedef int CRRow[MAX_CRLEVEL]; @@ -227,6 +285,7 @@ public: int event_timer; EventHandler event_handler; //like in Control bool hasInfra; + bool familiarBlock; private: /** reads the challenge rating table */ void LoadCRTable(); @@ -398,6 +457,8 @@ public: void RestParty(int checks, int dream, int hp); /** timestop effect initiated by actor */ void TimeStop(Actor *actor, ieDword end); + /** updates the infravision info */ + void Infravision(); /** gets the colour which should be applied over the game area, may return NULL */ const Color *GetGlobalTint() const; @@ -413,8 +474,8 @@ public: void DebugDump(); /** Finds an actor by global ID */ Actor *GetActorByGlobalID(ieDword objectID); - /** updates the infravision info */ - void Infravision(); + /** Allocates maze data */ + ieByte *AllocateMazeData(); private: bool DetermineStartPosType(const TableMgr *strta); ieResRef *GetDream(Map *area); diff --git a/project/jni/application/gemrb/src/core/GameData.cpp b/project/jni/application/gemrb/gemrb/core/GameData.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GameData.cpp rename to project/jni/application/gemrb/gemrb/core/GameData.cpp diff --git a/project/jni/application/gemrb/src/core/GameData.h b/project/jni/application/gemrb/gemrb/core/GameData.h similarity index 100% rename from project/jni/application/gemrb/src/core/GameData.h rename to project/jni/application/gemrb/gemrb/core/GameData.h diff --git a/project/jni/application/gemrb/src/core/GameScript/Actions.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/GameScript/Actions.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp index 2a9284883..f6cb55b7e 100644 --- a/project/jni/application/gemrb/src/core/GameScript/Actions.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp @@ -189,7 +189,7 @@ void GameScript::RealSetGlobalTimer(Scriptable* Sender, Action* parameters) ieDword mytime=core->GetGame()->RealTime; SetVariable( Sender, parameters->string0Parameter, - parameters->int0Parameter + mytime); + parameters->int0Parameter*AI_UPDATE_TIME + mytime); } void GameScript::ChangeAllegiance(Scriptable* Sender, Action* parameters) @@ -2038,6 +2038,40 @@ void GameScript::PlaySequence(Scriptable* Sender, Action* parameters) actor->SetStance( parameters->int0Parameter ); } +//same as PlaySequence, but the value comes from a variable +//ToDo: create a PlaySequenceCore in GSUtils +void GameScript::PlaySequenceGlobal(Scriptable* Sender, Action* parameters) +{ + Scriptable* tar; + ieDword value; + + value = (ieDword) CheckVariable( Sender, parameters->string0Parameter ); + + if (parameters->objects[1]) { + tar = GetActorFromObject( Sender, parameters->objects[1] ); + if (!tar) { + //could be an animation + AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName); + if (anim) { + //set animation's cycle to value; + anim->sequence=value; + anim->frame=0; + //what else to be done??? + anim->InitAnimation(); + } + return; + } + + } else { + tar = Sender; + } + if (tar->Type != ST_ACTOR) { + return; + } + Actor* actor = ( Actor* ) tar; + actor->SetStance( value ); +} + void GameScript::SetDialogue(Scriptable* Sender, Action* parameters) { if (Sender->Type != ST_ACTOR) { @@ -2544,14 +2578,14 @@ void GameScript::Spell(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd( spellres ); + Sender->CastSpellEnd(); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2613,7 +2647,7 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2654,18 +2688,22 @@ void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd( spellres ); + Sender->CastSpellEnd(); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2707,11 +2745,15 @@ void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2745,18 +2787,22 @@ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd( spellres ); + Sender->CastSpellEnd(); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2797,11 +2843,15 @@ void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd( spellres ); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); return; } @@ -2835,6 +2885,10 @@ void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); @@ -2851,9 +2905,9 @@ void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) } Sender->CastSpell (spellres, tar, false, true); if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(spellres); + Sender->CastSpellEnd(); } else { - Sender->CastSpellPointEnd(spellres); + Sender->CastSpellPointEnd(); } Sender->ReleaseCurrentAction(); } @@ -2869,6 +2923,10 @@ void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } //Sender->LastTargetPos=parameters->pointParameter; @@ -2882,7 +2940,7 @@ void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) actor->SetStance (IE_ANI_CONJURE); } Sender->CastSpellPoint (spellres, parameters->pointParameter, false, true); - Sender->CastSpellPointEnd(spellres); + Sender->CastSpellPointEnd(); Sender->ReleaseCurrentAction(); } @@ -2895,6 +2953,10 @@ void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); return; + } else { + if (!Sender->SpellResRef[0]) { + Sender->SetSpellResRef(spellres); + } } Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); @@ -2912,9 +2974,9 @@ void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) */ Sender->CastSpell (spellres, tar, false, true); if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(spellres); + Sender->CastSpellEnd(); } else { - Sender->CastSpellPointEnd(spellres); + Sender->CastSpellPointEnd(); } Sender->ReleaseCurrentAction(); } @@ -3161,7 +3223,6 @@ void GameScript::JoinParty(Scriptable* Sender, Action* parameters) } } core->GetGame()->JoinParty( act, JP_JOIN ); - //core->GetGUIScriptEngine()->RunFunction( "GUICommonWindows", "UpdatePortraitWindow" ); } void GameScript::LeaveParty(Scriptable* Sender, Action* /*parameters*/) @@ -3171,7 +3232,6 @@ void GameScript::LeaveParty(Scriptable* Sender, Action* /*parameters*/) } Actor* act = ( Actor* ) Sender; core->GetGame()->LeaveParty( act ); - //core->GetGUIScriptEngine()->RunFunction( "GUICommonWindows", "UpdatePortraitWindow" ); } //HideCreature hides only the visuals of a creature @@ -4752,7 +4812,7 @@ void GameScript::Damage(Scriptable* Sender, Action* parameters) } else { damager=damagee; } - int damage = damagee->LuckyRoll( (parameters->int1Parameter>>12)&15, (parameters->int1Parameter>>4)&255, parameters->int1Parameter&15, 0, 1, damager); + int damage = damagee->LuckyRoll( (parameters->int1Parameter>>12)&15, (parameters->int1Parameter>>4)&255, parameters->int1Parameter&15, LR_DAMAGELUCK, damager); int type=MOD_ADDITIVE; switch(parameters->int0Parameter) { case 2: //raise @@ -5553,6 +5613,20 @@ void GameScript::SetMazeHarder(Scriptable* Sender, Action* /*parameters*/) } } +void GameScript::GenerateMaze(Scriptable* /*Sender*/, Action* /*parameters*/) +{ + core->SetEventFlag(EF_CREATEMAZE); +} + +void GameScript::FixEngineRoom(Scriptable* Sender, Action* /*parameters*/) +{ + int value = CheckVariable( Sender, "EnginInMaze","GLOBAL"); + if (value) { + SetVariable(Sender, "EnginInMaze", "GLOBAL", 0); + core->SetEventFlag(EF_CREATEMAZE); + } +} + void GameScript::StartRainNow(Scriptable* /*Sender*/, Action* /*parameters*/) { core->GetGame()->StartRainOrSnow( false, WB_RAIN|WB_LIGHTNING); diff --git a/project/jni/application/gemrb/src/core/GameScript/GSUtils.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/GameScript/GSUtils.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp index f283c2d62..a6d653cd9 100644 --- a/project/jni/application/gemrb/src/core/GameScript/GSUtils.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp @@ -64,8 +64,6 @@ int ExtraParametersCount = 0; int InDebug = 0; int happiness[3][20]; int RandomNumValue; -int *SkillStats=NULL; -int SkillCount=-1; // reaction modifiers (by reputation and charisma) int rmodrep[20]; int rmodchr[25]; @@ -73,20 +71,6 @@ Gem_Polygon **polygons; void InitScriptTables() { - //initializing the skill->stats conversion table - { - AutoTable tab("skillsta"); - if (tab) { - int rowcount = tab->GetRowCount(); - SkillCount = rowcount; - if (rowcount) { - SkillStats = (int *) malloc(rowcount * sizeof(int) ); - while(rowcount--) { - SkillStats[rowcount]=strtol(tab->QueryField(rowcount,0), NULL, 0); - } - } - } - } //initializing the happiness table { AutoTable tab("happy"); @@ -1182,19 +1166,6 @@ void AttackCore(Scriptable *Sender, Scriptable *target, int flags) //bool leftorright = (bool) ((attacksperround-attackcount)&1); bool leftorright = false; - - //will return false on any errors (eg, unusable weapon) - if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style)) { - Sender->ReleaseCurrentAction(); - return; - } - - if (header) wi.range *= 10; - else wi.range = 0; - - if ( target->Type == ST_DOOR || target->Type == ST_CONTAINER) { - wi.range += 10; - } Actor *tar = NULL; ieDword targetID = 0; if (target->Type==ST_ACTOR) { @@ -1205,6 +1176,20 @@ void AttackCore(Scriptable *Sender, Scriptable *target, int flags) Sender->ReleaseCurrentAction(); return; } + + //will return false on any errors (eg, unusable weapon) + if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, tar)) { + actor->SetStance(IE_ANI_READY); + Sender->ReleaseCurrentAction(); + return; + } + + if (header) wi.range *= 10; + else wi.range = 0; + + if ( target->Type == ST_DOOR || target->Type == ST_CONTAINER) { + wi.range += 10; + } if (!(flags&AC_NO_SOUND) ) { if (actor->LastTarget != targetID) { //play attack sound for party members diff --git a/project/jni/application/gemrb/src/core/GameScript/GSUtils.h b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h similarity index 99% rename from project/jni/application/gemrb/src/core/GameScript/GSUtils.h rename to project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h index afe9b1ae5..9297ba792 100644 --- a/project/jni/application/gemrb/src/core/GameScript/GSUtils.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h @@ -55,8 +55,6 @@ extern ieResRef *ObjectIDSTableNames; extern int ObjectFieldsCount; extern int ExtraParametersCount; extern int InDebug; -extern int *SkillStats; -extern int SkillCount; extern Gem_Polygon **polygons; #define MIC_INVALID -2 diff --git a/project/jni/application/gemrb/src/core/GameScript/GameScript.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/GameScript/GameScript.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp index f7c900069..37fc21835 100644 --- a/project/jni/application/gemrb/src/core/GameScript/GameScript.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp @@ -572,6 +572,7 @@ static const ActionLink actionnames[] = { {"fillslot", GameScript::FillSlot, 0}, {"finalsave", GameScript::SaveGame, 0}, //synonym {"findtraps", GameScript::FindTraps, 0}, + {"fixengineroom", GameScript::FixEngineRoom, 0}, {"floatmessage", GameScript::DisplayStringHead, 0}, {"floatmessagefixed", GameScript::FloatMessageFixed, 0}, {"floatmessagefixedrnd", GameScript::FloatMessageFixedRnd, 0}, @@ -592,6 +593,7 @@ static const ActionLink actionnames[] = { {"formation", GameScript::Formation, AF_BLOCKING}, {"fullheal", GameScript::FullHeal, 0}, {"fullhealex", GameScript::FullHeal, 0}, //pst, not sure what's different + {"generatemodronmaze", GameScript::GenerateMaze, 0}, {"generatepartymember", GameScript::GeneratePartyMember, 0}, {"getitem", GameScript::GetItem, 0}, {"getstat", GameScript::GetStat, 0}, //gemrb specific @@ -698,8 +700,8 @@ static const ActionLink actionnames[] = { {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT|AF_ALIVE}, {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, - {"nidspecial7", GameScript::UseItemPoint, AF_BLOCKING|AF_ALIVE}, - {"nidspecial8", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, + {"nidspecial7", GameScript::SpellNoDec, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, + //{"nidspecial8", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, //not needed {"nidspecial9", GameScript::ToggleDoor, AF_BLOCKING},//another internal hack, maybe we should use UseDoor instead {"noaction", GameScript::NoAction, 0}, {"opendoor", GameScript::OpenDoor,0}, @@ -715,6 +717,7 @@ static const ActionLink actionnames[] = { {"playerdialog", GameScript::PlayerDialogue,AF_BLOCKING}, {"playerdialogue", GameScript::PlayerDialogue,AF_BLOCKING}, {"playsequence", GameScript::PlaySequence, 0}, + {"playsequenceglobal", GameScript::PlaySequenceGlobal, 0}, //pst {"playsequencetimed", GameScript::PlaySequenceTimed, 0},//pst {"playsong", GameScript::StartSong, 0}, {"playsound", GameScript::PlaySound, 0}, @@ -1251,10 +1254,6 @@ void Targets::Clear() /** releasing global memory */ static void CleanupIEScript() { - if (SkillStats) - free(SkillStats); - SkillStats = NULL; - SkillCount = -1; if (ObjectIDSTableNames) free(ObjectIDSTableNames); ObjectIDSTableNames = NULL; diff --git a/project/jni/application/gemrb/src/core/GameScript/GameScript.h b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h similarity index 99% rename from project/jni/application/gemrb/src/core/GameScript/GameScript.h rename to project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h index e0654c2f4..e6dc3c1e5 100644 --- a/project/jni/application/gemrb/src/core/GameScript/GameScript.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h @@ -1095,6 +1095,7 @@ public: static void FakeEffectExpiryCheck(Scriptable* Sender, Action* parameters); static void FillSlot(Scriptable *Sender, Action* parameters); static void FindTraps(Scriptable* Sender, Action* parameters); + static void FixEngineRoom(Scriptable *Sender, Action* parameters); static void FloatMessageFixed(Scriptable* Sender, Action* parameters); static void FloatMessageFixedRnd(Scriptable* Sender, Action* parameters); static void FloatMessageRnd(Scriptable* Sender, Action* parameters); @@ -1113,6 +1114,7 @@ public: static void ForceUseContainer(Scriptable* Sender, Action* parameters); static void Formation(Scriptable* Sender, Action* parameters); static void FullHeal(Scriptable* Sender, Action* parameters); + static void GenerateMaze(Scriptable* Sender, Action* parameters); static void GeneratePartyMember(Scriptable* Sender, Action* parameters); static void GetItem(Scriptable* Sender, Action* parameters); static void GetStat(Scriptable* Sender, Action* parameters); @@ -1217,6 +1219,7 @@ public: static void PlayDeadInterruptable(Scriptable* Sender, Action* parameters); static void PlayerDialogue(Scriptable* Sender, Action* parameters); static void PlaySequence(Scriptable* Sender, Action* parameters); + static void PlaySequenceGlobal(Scriptable* Sender, Action* parameters); static void PlaySequenceTimed(Scriptable* Sender, Action* parameters); static void PlaySound(Scriptable* Sender, Action* parameters); static void PlaySoundNotRanged(Scriptable* Sender, Action* parameters); diff --git a/project/jni/application/gemrb/src/core/GameScript/Matching.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp similarity index 94% rename from project/jni/application/gemrb/src/core/GameScript/Matching.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp index 4665a8a2f..f0ad5d186 100644 --- a/project/jni/application/gemrb/src/core/GameScript/Matching.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp @@ -26,30 +26,15 @@ #include "Game.h" #include "TileMap.h" -/* return a Targets object with a single actor inside */ -inline static Targets* ReturnActorAsTarget(Actor *aC) +/* return a Targets object with a single scriptable inside */ +inline static Targets* ReturnScriptableAsTarget(Scriptable *sc) { - if (!aC) return NULL; + if (!sc) return NULL; Targets *tgts = new Targets(); - tgts->AddTarget(aC, 0, 0); + tgts->AddTarget(sc, 0, 0); return tgts; } -/*Actor *FindActorNearby(const char *name, Map *except, int ga_flags) -{ - Game *game = core->GetGame(); - size_t mc = game->GetLoadedMapCount(); - while(mc--) { - Map *map = game->GetMap(mc); - if (map==except) continue; - Actor * aC = map->GetActor(name, ga_flags); - if (aC) { - return aC; - } - } - return NULL; -}*/ - /* do IDS filtering: [PC], [ENEMY], etc */ inline static bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) { for (int j = 0; j < ObjectIDSCount; j++) { @@ -162,18 +147,34 @@ static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_ }*/ //return here because object name/IDS targeting are mutually exclusive - return ReturnActorAsTarget(aC); + return ReturnScriptableAsTarget(aC); } if (oC->objectFields[0]==-1) { // this is an internal hack, allowing us to pass actor ids around as objects Actor* aC = map->GetActorByGlobalID( (ieDword) oC->objectFields[1] ); - /* TODO: this hack will throw away an invalid target */ - /* Consider putting this in GetActorByGlobalID */ - if (aC && !aC->ValidTarget(ga_flags)) { - aC = NULL; + if (aC) { + if (!aC->ValidTarget(ga_flags)) { + return NULL; + } + return ReturnScriptableAsTarget(aC); } - return ReturnActorAsTarget(aC); + Door *door = map->GetDoorByGlobalID( (ieDword) oC->objectFields[1]); + if (door) { + return ReturnScriptableAsTarget(door); + } + + Container* cont = map->GetContainerByGlobalID((ieDword) oC->objectFields[1]); + if (cont) { + return ReturnScriptableAsTarget(cont); + } + + InfoPoint* trap = map->GetInfoPointByGlobalID((ieDword) oC->objectFields[1]); + if (trap) { + return ReturnScriptableAsTarget(trap); + } + + return NULL; } Targets *tgts = NULL; @@ -225,21 +226,6 @@ Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags) return tgts; } -/*Targets *GetAllObjectsNearby(Scriptable* Sender, Object* oC, int ga_flags) -{ - Game *game = core->GetGame(); - size_t mc = game->GetLoadedMapCount(); - while(mc--) { - Map *map = game->GetMap(mc); - if (map==Sender->GetCurrentArea()) continue; - Targets *tgts = GetAllObjects(map, Sender, oC, ga_flags); - if (tgts) { - return tgts; - } - } - return NULL; -}*/ - Targets *GetAllActors(Scriptable *Sender, int ga_flags) { Map *map = Sender->GetCurrentArea(); diff --git a/project/jni/application/gemrb/src/core/GameScript/Matching.h b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h similarity index 95% rename from project/jni/application/gemrb/src/core/GameScript/Matching.h rename to project/jni/application/gemrb/gemrb/core/GameScript/Matching.h index 6a6562191..a01fa2253 100644 --- a/project/jni/application/gemrb/src/core/GameScript/Matching.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h @@ -24,7 +24,7 @@ #include "exports.h" -Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags); +GEM_EXPORT Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags); Targets* GetAllActors(Scriptable* Sender, int ga_flags); Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags = 0); Scriptable* GetStoredActorFromObject(Scriptable* Sender, Object* oC, int ga_flags = 0); diff --git a/project/jni/application/gemrb/src/core/GameScript/Objects.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GameScript/Objects.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp diff --git a/project/jni/application/gemrb/src/core/GameScript/Triggers.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/GameScript/Triggers.cpp rename to project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp index a780d818f..874845a94 100644 --- a/project/jni/application/gemrb/src/core/GameScript/Triggers.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp @@ -2258,9 +2258,6 @@ int GameScript::XPLT(Scriptable* Sender, Trigger* parameters) int GameScript::CheckSkill(Scriptable* Sender, Trigger* parameters) { - if (parameters->int1Parameter>=SkillCount) { - return 0; - } Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter ); if (!target) { return 0; @@ -2269,7 +2266,9 @@ int GameScript::CheckSkill(Scriptable* Sender, Trigger* parameters) return 0; } Actor* actor = ( Actor* ) target; - if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) == parameters->int0Parameter) { + int sk = actor->GetSkill( parameters->int1Parameter ); + if (sk<0) return 0; + if ( sk == parameters->int0Parameter) { return 1; } return 0; @@ -2284,7 +2283,7 @@ int GameScript::CheckStat(Scriptable* Sender, Trigger* parameters) return 0; } Actor* actor = ( Actor* ) target; - if ((signed) actor->GetStat( parameters->int1Parameter ) == parameters->int0Parameter) { + if ( (signed) actor->GetStat( parameters->int1Parameter ) == parameters->int0Parameter) { return 1; } return 0; @@ -2292,15 +2291,14 @@ int GameScript::CheckStat(Scriptable* Sender, Trigger* parameters) int GameScript::CheckSkillGT(Scriptable* Sender, Trigger* parameters) { - if (parameters->int1Parameter>=SkillCount) { - return 0; - } Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); if (!tar || tar->Type != ST_ACTOR) { return 0; } Actor* actor = ( Actor* ) tar; - if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) > parameters->int0Parameter) { + int sk = actor->GetSkill( parameters->int1Parameter ); + if (sk<0) return 0; + if ( sk > parameters->int0Parameter) { return 1; } return 0; @@ -2313,7 +2311,7 @@ int GameScript::CheckStatGT(Scriptable* Sender, Trigger* parameters) return 0; } Actor* actor = ( Actor* ) tar; - if ((signed) actor->GetStat( parameters->int1Parameter ) > parameters->int0Parameter) { + if ( (signed) actor->GetStat( parameters->int1Parameter ) > parameters->int0Parameter) { return 1; } return 0; @@ -2321,15 +2319,14 @@ int GameScript::CheckStatGT(Scriptable* Sender, Trigger* parameters) int GameScript::CheckSkillLT(Scriptable* Sender, Trigger* parameters) { - if (parameters->int1Parameter>=SkillCount) { - return 0; - } Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); if (!tar || tar->Type != ST_ACTOR) { return 0; } Actor* actor = ( Actor* ) tar; - if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) < parameters->int0Parameter) { + int sk = actor->GetSkill( parameters->int1Parameter ); + if (sk<0) return 0; + if ( sk < parameters->int0Parameter) { return 1; } return 0; @@ -2342,7 +2339,7 @@ int GameScript::CheckStatLT(Scriptable* Sender, Trigger* parameters) return 0; } Actor* actor = ( Actor* ) tar; - if ((signed) actor->GetStat( parameters->int1Parameter ) < parameters->int0Parameter) { + if ( (signed) actor->GetStat( parameters->int1Parameter ) < parameters->int0Parameter) { return 1; } return 0; diff --git a/project/jni/application/gemrb/src/core/GlobalTimer.cpp b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/GlobalTimer.cpp rename to project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp diff --git a/project/jni/application/gemrb/src/core/GlobalTimer.h b/project/jni/application/gemrb/gemrb/core/GlobalTimer.h similarity index 100% rename from project/jni/application/gemrb/src/core/GlobalTimer.h rename to project/jni/application/gemrb/gemrb/core/GlobalTimer.h diff --git a/project/jni/application/gemrb/src/core/Holder.h b/project/jni/application/gemrb/gemrb/core/Holder.h similarity index 100% rename from project/jni/application/gemrb/src/core/Holder.h rename to project/jni/application/gemrb/gemrb/core/Holder.h diff --git a/project/jni/application/gemrb/src/core/Image.cpp b/project/jni/application/gemrb/gemrb/core/Image.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Image.cpp rename to project/jni/application/gemrb/gemrb/core/Image.cpp diff --git a/project/jni/application/gemrb/src/core/Image.h b/project/jni/application/gemrb/gemrb/core/Image.h similarity index 100% rename from project/jni/application/gemrb/src/core/Image.h rename to project/jni/application/gemrb/gemrb/core/Image.h diff --git a/project/jni/application/gemrb/src/core/ImageFactory.cpp b/project/jni/application/gemrb/gemrb/core/ImageFactory.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ImageFactory.cpp rename to project/jni/application/gemrb/gemrb/core/ImageFactory.cpp diff --git a/project/jni/application/gemrb/src/core/ImageFactory.h b/project/jni/application/gemrb/gemrb/core/ImageFactory.h similarity index 100% rename from project/jni/application/gemrb/src/core/ImageFactory.h rename to project/jni/application/gemrb/gemrb/core/ImageFactory.h diff --git a/project/jni/application/gemrb/src/core/ImageMgr.cpp b/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ImageMgr.cpp rename to project/jni/application/gemrb/gemrb/core/ImageMgr.cpp diff --git a/project/jni/application/gemrb/src/core/ImageMgr.h b/project/jni/application/gemrb/gemrb/core/ImageMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/ImageMgr.h rename to project/jni/application/gemrb/gemrb/core/ImageMgr.h diff --git a/project/jni/application/gemrb/src/core/ImageWriter.cpp b/project/jni/application/gemrb/gemrb/core/ImageWriter.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ImageWriter.cpp rename to project/jni/application/gemrb/gemrb/core/ImageWriter.cpp diff --git a/project/jni/application/gemrb/src/core/ImageWriter.h b/project/jni/application/gemrb/gemrb/core/ImageWriter.h similarity index 100% rename from project/jni/application/gemrb/src/core/ImageWriter.h rename to project/jni/application/gemrb/gemrb/core/ImageWriter.h diff --git a/project/jni/application/gemrb/src/core/IniSpawn.cpp b/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/IniSpawn.cpp rename to project/jni/application/gemrb/gemrb/core/IniSpawn.cpp diff --git a/project/jni/application/gemrb/src/core/IniSpawn.h b/project/jni/application/gemrb/gemrb/core/IniSpawn.h similarity index 100% rename from project/jni/application/gemrb/src/core/IniSpawn.h rename to project/jni/application/gemrb/gemrb/core/IniSpawn.h diff --git a/project/jni/application/gemrb/src/core/Interface.cpp b/project/jni/application/gemrb/gemrb/core/Interface.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/Interface.cpp rename to project/jni/application/gemrb/gemrb/core/Interface.cpp index 70f9afa3f..ee7b52cec 100644 --- a/project/jni/application/gemrb/src/core/Interface.cpp +++ b/project/jni/application/gemrb/gemrb/core/Interface.cpp @@ -236,6 +236,8 @@ Interface::Interface(int iargc, char* iargv[]) ItemDial2Table = NULL; ItemTooltipTable = NULL; update_scripts = false; + SpecialSpellsCount = -1; + SpecialSpells = NULL; gamedata = new GameData(); } @@ -341,6 +343,11 @@ Interface::~Interface(void) reputationmod=NULL; } + if (SpecialSpells) { + free(SpecialSpells); + } + SurgeSpells.clear(); + PluginMgr::Get()->RunCleanup(); ReleaseMemoryActor(); @@ -577,6 +584,12 @@ void Interface::HandleEvents() guiscript->RunFunction( "MessageWindow", "GameExpansion", false ); return; } + + if (EventFlag&EF_CREATEMAZE) { + EventFlag&=~EF_CREATEMAZE; + guiscript->RunFunction( "Maze", "CreateMaze", false ); + return; + } } /* handle main loop events that might destroy or create windows @@ -640,7 +653,7 @@ bool GenerateAbilityTables() strmodex = (ieWordSigned *) malloc (101 * 4 * sizeof(ieWordSigned) ); if (!strmodex) return false; - intmod = (ieWordSigned *) malloc (tablesize * 3 * sizeof(ieWordSigned) ); + intmod = (ieWordSigned *) malloc (tablesize * 5 * sizeof(ieWordSigned) ); if (!intmod) return false; dexmod = (ieWordSigned *) malloc (tablesize * 3 * sizeof(ieWordSigned) ); @@ -698,7 +711,7 @@ bool Interface::ReadAbilityTables() //3rd ed doesn't have strmodex, but has a maximum of 40 if (!ret && (MaximumAbility<=25) ) return ret; - ret = ReadAbilityTable("intmod", intmod, 3, MaximumAbility + 1); + ret = ReadAbilityTable("intmod", intmod, 5, MaximumAbility + 1); if (!ret) return ret; ret = ReadAbilityTable("hpconbon", conmod, 5, MaximumAbility + 1); @@ -741,10 +754,73 @@ bool Interface::ReadGameTimeTable() return true; } +bool Interface::ReadSpecialSpells() +{ + int i; + bool result = true; + + AutoTable table("splspec"); + if (table) { + SpecialSpellsCount = table->GetRowCount(); + SpecialSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialSpellsCount); + for (i=0;iGetRowName(i),8 ); + //if there are more flags, compose this value into a bitfield + SpecialSpells[i].value = atoi(table->QueryField(i,0) ); + } + } else { + result = false; + } + + table.load("wildmag"); + if (table) { + SurgeSpell ss; + for (i = 0; (unsigned)i < table->GetRowCount(); i++) { + strncpy(ss.spell, table->QueryField(i, 0), 8); + ss.message = strtol(table->QueryField(i, 1), NULL, 0); + // comment ignored + SurgeSpells.push_back(ss); + } + } else { + result = false; + } + + return result; +} + +int Interface::GetSpecialSpell(ieResRef resref) +{ + for (int i=0;iGetStat(IE_STATE_ID) & STATE_SILENCED ) { + if (!(sp&SP_SILENCE)) { + return 1; + } + } + + return 0; +} + bool Interface::ReadAuxItemTables() { int idx; - int table; bool flag = true; if (ItemExclTable) { @@ -753,7 +829,6 @@ bool Interface::ReadAuxItemTables() ItemExclTable = new Variables(); ItemExclTable->SetType(GEM_VARIABLES_INT); } - table = gamedata->LoadTable( "itemexcl" ); AutoTable aa; @@ -1756,6 +1831,14 @@ int Interface::Init() } printStatus( "OK", LIGHT_GREEN ); + ret = ReadSpecialSpells(); + printMessage( "Core", "Reading special spells table...", WHITE); + if (ret) { + printStatus( "OK", LIGHT_GREEN ); + } else { + printStatus( "NOT FOUND", YELLOW ); + } + ret = ReadAuxItemTables(); printMessage( "Core", "Reading item tables...", WHITE); if (!ret) { @@ -2399,6 +2482,7 @@ static const char *game_flags[GF_COUNT+1]={ "JournalHasSections", //56GF_JOURNAL_HAS_SECTIONS "CastingSounds", //57GF_CASTING_SOUNDS "EnhancedCastingSounds", //58GF_CASTING_SOUNDS2 + "ForceAreaScript", //59GF_FORCE_AREA_SCRIPT NULL //for our own safety, this marks the end of the pole }; @@ -5121,17 +5205,11 @@ int Interface::GetStrengthBonus(int column, int value, int ex) const return strmod[column*(MaximumAbility+1)+value]+strmodex[column*101+ex]; } -// we don't use the stuff maze yet -// IE: bonus skill points are ignored and the plain int mod used! +//The maze columns are used only in the maze spell, no need to restrict them further int Interface::GetIntelligenceBonus(int column, int value) const { - if (HasFeature(GF_3ED_RULES)) { - //learn spell, max spell level, max spell number on level, bonus skill points - if (column<0 || column>2) return -9999; - } else { - //learn spell, max spell level, max spell number on level, maze duration dice, maze duration dice size - if (column<0 || column>4) return -9999; - } + //learn spell, max spell level, max spell number on level, maze duration dice, maze duration dice size + if (column<0 || column>4) return -9999; return intmod[column*(MaximumAbility+1)+value]; } diff --git a/project/jni/application/gemrb/src/core/Interface.h b/project/jni/application/gemrb/gemrb/core/Interface.h similarity index 97% rename from project/jni/application/gemrb/src/core/Interface.h rename to project/jni/application/gemrb/gemrb/core/Interface.h index 3965efc37..06eb11b9b 100644 --- a/project/jni/application/gemrb/src/core/Interface.h +++ b/project/jni/application/gemrb/gemrb/core/Interface.h @@ -133,6 +133,18 @@ struct TimeStruct { unsigned int rounds_per_turn; }; +struct SpellDescType { + ieResRef resref; + ieStrRef value; +}; +#define SP_IDENTIFY 1 //any spell that cannot be cast from the menu +#define SP_SILENCE 2 //any spell that can be cast in silence + +struct SurgeSpell { + ieResRef spell; + ieStrRef message; +}; + class ItemList { public: ieResRef *ResRefs; @@ -188,6 +200,7 @@ public: #define EF_SELECTION 128 //selection changed #define EF_OPENSTORE 256 //open store window #define EF_EXPANSION 512 //upgrade game request +#define EF_CREATEMAZE 1024 //call the maze generator //autopause #define AP_UNUSABLE 0 @@ -332,6 +345,8 @@ private: char NextScript[64]; /** Function to call every main loop iteration */ EventHandler TickHook; + int SpecialSpellsCount; + SpellDescType *SpecialSpells; public: Holder strings; GlobalTimer * timer; @@ -359,6 +374,7 @@ public: std::multimap DamageInfoMap; std::vector ModalStates; TimeStruct Time; + std::vector SurgeSpells; public: Interface(int iargc, char *iargv[]); ~Interface(void); @@ -668,6 +684,10 @@ public: void StripLine(char * string, size_t size); /** Returns the DeathVarFormat of the day */ static const char *GetDeathVarFormat(); + int CheckSpecialSpell(ieResRef resref, Actor *actor); + int GetSpecialSpell(ieResRef resref); + int GetSpecialSpellsCount() { return SpecialSpellsCount; }; + SpellDescType *GetSpecialSpells() { return SpecialSpells; }; private: int LoadSprites(); bool LoadConfig(void); @@ -683,6 +703,7 @@ private: bool ReadDamageTypeTable(); bool ReadReputationModTable(); bool ReadGameTimeTable(); + bool ReadSpecialSpells(); bool ReadModalStates(); /** Reads table of area name mappings for WorldMap (PST only) */ bool ReadAreaAliasTable(const ieResRef name); diff --git a/project/jni/application/gemrb/src/core/Inventory.cpp b/project/jni/application/gemrb/gemrb/core/Inventory.cpp similarity index 99% rename from project/jni/application/gemrb/src/core/Inventory.cpp rename to project/jni/application/gemrb/gemrb/core/Inventory.cpp index b1bf807ec..1dcc638c6 100644 --- a/project/jni/application/gemrb/src/core/Inventory.cpp +++ b/project/jni/application/gemrb/gemrb/core/Inventory.cpp @@ -1020,6 +1020,9 @@ bool Inventory::EquipItem(unsigned int slot) if (item->Flags & IE_INV_ITEM_CURSED) { item->Flags|=IE_INV_ITEM_UNDROPPABLE; } + if (effect == SLOT_EFFECT_MISSILE) { + slot = FindRangedWeapon(); + } AddSlotEffects( slot ); } return true; diff --git a/project/jni/application/gemrb/src/core/Inventory.h b/project/jni/application/gemrb/gemrb/core/Inventory.h similarity index 100% rename from project/jni/application/gemrb/src/core/Inventory.h rename to project/jni/application/gemrb/gemrb/core/Inventory.h diff --git a/project/jni/application/gemrb/src/core/Item.cpp b/project/jni/application/gemrb/gemrb/core/Item.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Item.cpp rename to project/jni/application/gemrb/gemrb/core/Item.cpp diff --git a/project/jni/application/gemrb/src/core/Item.h b/project/jni/application/gemrb/gemrb/core/Item.h similarity index 100% rename from project/jni/application/gemrb/src/core/Item.h rename to project/jni/application/gemrb/gemrb/core/Item.h diff --git a/project/jni/application/gemrb/src/core/ItemMgr.cpp b/project/jni/application/gemrb/gemrb/core/ItemMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ItemMgr.cpp rename to project/jni/application/gemrb/gemrb/core/ItemMgr.cpp diff --git a/project/jni/application/gemrb/src/core/ItemMgr.h b/project/jni/application/gemrb/gemrb/core/ItemMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/ItemMgr.h rename to project/jni/application/gemrb/gemrb/core/ItemMgr.h diff --git a/project/jni/application/gemrb/src/core/LRUCache.cpp b/project/jni/application/gemrb/gemrb/core/LRUCache.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/LRUCache.cpp rename to project/jni/application/gemrb/gemrb/core/LRUCache.cpp diff --git a/project/jni/application/gemrb/src/core/LRUCache.h b/project/jni/application/gemrb/gemrb/core/LRUCache.h similarity index 100% rename from project/jni/application/gemrb/src/core/LRUCache.h rename to project/jni/application/gemrb/gemrb/core/LRUCache.h diff --git a/project/jni/application/gemrb/src/core/Makefile.am b/project/jni/application/gemrb/gemrb/core/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/core/Makefile.am rename to project/jni/application/gemrb/gemrb/core/Makefile.am diff --git a/project/jni/application/gemrb/src/core/Map.cpp b/project/jni/application/gemrb/gemrb/core/Map.cpp similarity index 98% rename from project/jni/application/gemrb/src/core/Map.cpp rename to project/jni/application/gemrb/gemrb/core/Map.cpp index c18fd49df..45e1dc9e8 100644 --- a/project/jni/application/gemrb/src/core/Map.cpp +++ b/project/jni/application/gemrb/gemrb/core/Map.cpp @@ -66,7 +66,7 @@ static Point **VisibilityMasks=NULL; static bool PathFinderInited = false; static Variables Spawns; static int LargeFog; -static TerrainSounds *terrainsounds; +static TerrainSounds *terrainsounds=NULL; static int tsndcount = -1; void ReleaseSpawnGroup(void *poi) @@ -81,11 +81,14 @@ void Map::ReleaseMemory() free(VisibilityMasks[i]); } free(VisibilityMasks); - VisibilityMasks=NULL; + VisibilityMasks = NULL; } - Spawns.RemoveAll(ReleaseSpawnGroup); PathFinderInited = false; + if (terrainsounds) { + delete [] terrainsounds; + terrainsounds = NULL; + } } inline static AnimationObjectType SelectObject(Actor *actor, int q, AreaAnimation *a, ScriptedAnimation *sca, Particles *spark, Projectile *pro) @@ -188,22 +191,26 @@ void InitSpawnGroups() void InitPathFinder() { PathFinderInited = true; + tsndcount = 0; AutoTable tm("pathfind"); - if (tm) { - const char* poi; - for (int i = 0; i < 16; i++) { - poi = tm->QueryField( 0, i ); - if (*poi != '*') - Passable[i] = atoi( poi ); - } - poi = tm->QueryField( 1, 0 ); - if (*poi != '*') - NormalCost = atoi( poi ); - poi = tm->QueryField( 1, 1 ); - if (*poi != '*') - AdditionalCost = atoi( poi ); + if (!tm) { + return; } + + const char* poi; + + for (int i = 0; i < 16; i++) { + poi = tm->QueryField( 0, i ); + if (*poi != '*') + Passable[i] = atoi( poi ); + } + poi = tm->QueryField( 1, 0 ); + if (*poi != '*') + NormalCost = atoi( poi ); + poi = tm->QueryField( 1, 1 ); + if (*poi != '*') + AdditionalCost = atoi( poi ); int rc = tm->GetRowCount()-2; if (rc>0) { terrainsounds = new TerrainSounds[rc]; @@ -292,7 +299,6 @@ Map::Map(void) area=this; TMap = NULL; LightMap = NULL; - SearchMap = NULL; HeightMap = NULL; SmallMap = NULL; MapSet = NULL; @@ -351,7 +357,6 @@ Map::~Map(void) delete spawns[i]; } delete LightMap; - delete SearchMap; delete HeightMap; core->GetVideoDriver()->FreeSprite( SmallMap ); for (i = 0; i < QUEUE_COUNT; i++) { @@ -412,7 +417,6 @@ void Map::AddTileMap(TileMap* tm, Image* lm, Bitmap* sr, Sprite2D* sm, Bitmap* h // CHECKME: leaks? Should the old TMap, LightMap, etc... be freed? TMap = tm; LightMap = lm; - SearchMap = sr; HeightMap = hm; SmallMap = sm; Width = (unsigned int) (TMap->XCellCount * 4); @@ -420,13 +424,12 @@ void Map::AddTileMap(TileMap* tm, Image* lm, Bitmap* sr, Sprite2D* sm, Bitmap* h //Filling Matrices MapSet = (unsigned short *) malloc(sizeof(unsigned short) * Width * Height); //Internal Searchmap - int y = SearchMap->GetHeight(); - //smWidth = SearchMap->GetWidth(); - SrchMap = (unsigned short *) malloc(sizeof(unsigned short) * Width * y); + int y = sr->GetHeight(); + SrchMap = (unsigned short *) calloc(Width * Height, sizeof(unsigned short)); while(y--) { - int x=SearchMap->GetWidth(); + int x=sr->GetWidth(); while(x--) { - SrchMap[y*Width+x] = Passable[SearchMap->GetAt(x,y)&PATH_MAP_AREAMASK]; + SrchMap[y*Width+x] = Passable[sr->GetAt(x,y)&PATH_MAP_AREAMASK]; } } } @@ -499,6 +502,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir while (i--) { Actor *pc = game->GetPC(i,false); if (pc->GetCurrentArea()==this) { + pc->UseExit(0); pc->ClearPath(); pc->ClearActions(); pc->AddAction( GenerateAction( command ) ); @@ -516,6 +520,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir continue; } if (pc->GetCurrentArea()==this) { + pc->UseExit(0); pc->ClearPath(); pc->ClearActions(); pc->AddAction( GenerateAction( command ) ); @@ -550,9 +555,9 @@ void Map::UseExit(Actor *actor, InfoPoint *ip) break; } - actor->UseExit(false); if (ip->Destination[0] != 0) { - // 0 here is direction, can infopoints specify that or is an entrance always provided? + // the 0 here is default orientation, can infopoints specify that or + // is an entrance always provided? MoveToNewArea(ip->Destination, ip->EntranceName, 0, EveryOne, actor); return; } @@ -656,7 +661,7 @@ void Map::UpdateScripts() //if the actor is immobile, don't run the scripts if (!game->StateOverrideFlag && !game->StateOverrideTime) { - if (actor->Immobile()) { + if (actor->Immobile() || actor->GetStat(IE_STATE_ID) & STATE_SLEEP) { actor->no_more_steps = true; continue; } @@ -802,6 +807,7 @@ void Map::UpdateScripts() if (wasActive) { q=Qcount[PR_SCRIPT]; + ieDword exitID = ip->GetGlobalID(); while (q--) { Actor* actor = queue[PR_SCRIPT][q]; if (ip->Type == ST_PROXIMITY) { @@ -813,7 +819,7 @@ void Map::UpdateScripts() //ST_TRAVEL //don't move if doing something else // added CurrentAction as part of blocking action fixes - if (actor->CannotPassEntrance() ) { + if (actor->CannotPassEntrance(exitID) ) { continue; } //this is needed, otherwise the travel @@ -837,7 +843,7 @@ void Map::UpdateScripts() void Map::ResolveTerrainSound(ieResRef &sound, Point &Pos) { for(int i=0;iGetAt( Pos.x/16, Pos.y/12 )&PATH_MAP_AREAMASK; + int type = GetInternalSearchMap( Pos.x/16, Pos.y/12 )&PATH_MAP_AREAMASK; memcpy(sound, terrainsounds[i].Sounds[type], sizeof(ieResRef) ); return; } @@ -1138,7 +1144,7 @@ void Map::DrawMap(Region screen) } } - if ((core->FogOfWar&FOG_DRAWSEARCHMAP) && SearchMap) { + if ((core->FogOfWar&FOG_DRAWSEARCHMAP) && SrchMap) { DrawSearchMap(screen); } else { if ((core->FogOfWar&FOG_DRAWFOG) && TMap) { @@ -1719,7 +1725,7 @@ void Map::PlayAreaSong(int SongType, bool restart, bool hard) unsigned int Map::GetBlocked(unsigned int x, unsigned int y) { - if (y>Height || x>Width) { + if (y>=Height || x>=Width) { return 0; } unsigned int ret = SrchMap[y*Width+x]; @@ -2049,7 +2055,6 @@ void Map::RemoveActor(Actor* actor) size_t i=actors.size(); while (i--) { if (actors[i] == actor) { - //BlockSearchMap(actor->Pos, actor->size, PATH_MAP_FREE); ClearSearchMapFor(actor); actors.erase( actors.begin()+i ); return; @@ -3039,18 +3044,21 @@ void Map::UpdateFog() { if (!(core->FogOfWar&FOG_DRAWFOG) ) { SetMapVisibility( -1 ); - return; + Explore(-1); + } else { + SetMapVisibility( 0 ); } - SetMapVisibility( 0 ); for (unsigned int e = 0; eModified[ IE_EXPLORE ] ) continue; - int state = actor->Modified[IE_STATE_ID]; - if (state & STATE_CANTSEE) continue; - int vis2 = actor->Modified[IE_VISUALRANGE]; - if ((state&STATE_BLIND) || (vis2<2)) vis2=2; //can see only themselves - ExploreMapChunk (actor->Pos, vis2+actor->GetAnims()->GetCircleSize(), 1); + if (core->FogOfWar&FOG_DRAWFOG) { + int state = actor->Modified[IE_STATE_ID]; + if (state & STATE_CANTSEE) continue; + int vis2 = actor->Modified[IE_VISUALRANGE]; + if ((state&STATE_BLIND) || (vis2<2)) vis2=2; //can see only themselves + ExploreMapChunk (actor->Pos, vis2+actor->GetAnims()->GetCircleSize(), 1); + } Spawn *sp = GetSpawnRadius(actor->Pos, SPAWN_RANGE); //30 * 12 if (sp) { TriggerSpawn(sp); @@ -3085,29 +3093,21 @@ void Map::BlockSearchMap(const Point &Pos, unsigned int size, unsigned int value if ((ppxpiGetAt(ppx+i,ppy+j)&PATH_MAP_NOTACTOR; - //SearchMap->SetAt(ppx+i,ppy+j,tmp|value); } if ((ppxpiGetAt(ppx+i,ppy-j)&PATH_MAP_NOTACTOR; - //SearchMap->SetAt(ppx+i,ppy-j,tmp|value); } if ((ppxmiGetAt(ppx-i,ppy+j)&PATH_MAP_NOTACTOR; - //SearchMap->SetAt(ppx-i,ppy+j,tmp|value); } if ((ppxmiGetAt(ppx-i,ppy-j)&PATH_MAP_NOTACTOR; - //SearchMap->SetAt(ppx-i,ppy-j,tmp|value); } } } @@ -3615,3 +3615,17 @@ void Map::SeeSpellCast(Scriptable *caster, ieDword spell) } } } + +short unsigned int Map::GetInternalSearchMap(int x, int y) { + if ((unsigned)x >= Width || (unsigned)y >= Height) { + return 0; + } + return SrchMap[x+y*Width]; +} + +void Map::SetInternalSearchMap(int x, int y, int value) { + if ((unsigned)x >= Width || (unsigned)y >= Height) { + return; + } + SrchMap[x+y*Width] = value; +} diff --git a/project/jni/application/gemrb/src/core/Map.h b/project/jni/application/gemrb/gemrb/core/Map.h similarity index 99% rename from project/jni/application/gemrb/src/core/Map.h rename to project/jni/application/gemrb/gemrb/core/Map.h index d6df6c787..bf9cce508 100644 --- a/project/jni/application/gemrb/src/core/Map.h +++ b/project/jni/application/gemrb/gemrb/core/Map.h @@ -229,7 +229,6 @@ class GEM_EXPORT Map : public Scriptable { public: TileMap* TMap; Image* LightMap; - Bitmap* SearchMap; Bitmap* HeightMap; Sprite2D* SmallMap; IniSpawn *INISpawn; @@ -469,6 +468,8 @@ public: //returns true if tracking failed bool DisplayTrackString(Actor *actor); unsigned int GetLightLevel(const Point &Pos); + unsigned short GetInternalSearchMap(int x, int y); + void SetInternalSearchMap(int x, int y, int value); private: AreaAnimation *GetNextAreaAnimation(aniIterator &iter, ieDword gametime); Particles *GetNextSpark(spaIterator &iter); diff --git a/project/jni/application/gemrb/src/core/MapMgr.cpp b/project/jni/application/gemrb/gemrb/core/MapMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/MapMgr.cpp rename to project/jni/application/gemrb/gemrb/core/MapMgr.cpp diff --git a/project/jni/application/gemrb/src/core/MapMgr.h b/project/jni/application/gemrb/gemrb/core/MapMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/MapMgr.h rename to project/jni/application/gemrb/gemrb/core/MapMgr.h diff --git a/project/jni/application/gemrb/src/core/MoviePlayer.cpp b/project/jni/application/gemrb/gemrb/core/MoviePlayer.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/MoviePlayer.cpp rename to project/jni/application/gemrb/gemrb/core/MoviePlayer.cpp diff --git a/project/jni/application/gemrb/src/core/MoviePlayer.h b/project/jni/application/gemrb/gemrb/core/MoviePlayer.h similarity index 100% rename from project/jni/application/gemrb/src/core/MoviePlayer.h rename to project/jni/application/gemrb/gemrb/core/MoviePlayer.h diff --git a/project/jni/application/gemrb/src/core/MusicMgr.cpp b/project/jni/application/gemrb/gemrb/core/MusicMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/MusicMgr.cpp rename to project/jni/application/gemrb/gemrb/core/MusicMgr.cpp diff --git a/project/jni/application/gemrb/src/core/MusicMgr.h b/project/jni/application/gemrb/gemrb/core/MusicMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/MusicMgr.h rename to project/jni/application/gemrb/gemrb/core/MusicMgr.h diff --git a/project/jni/application/gemrb/src/core/Palette.cpp b/project/jni/application/gemrb/gemrb/core/Palette.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Palette.cpp rename to project/jni/application/gemrb/gemrb/core/Palette.cpp diff --git a/project/jni/application/gemrb/src/core/Palette.h b/project/jni/application/gemrb/gemrb/core/Palette.h similarity index 99% rename from project/jni/application/gemrb/src/core/Palette.h rename to project/jni/application/gemrb/gemrb/core/Palette.h index ed3df4d7e..14d53bb2c 100644 --- a/project/jni/application/gemrb/src/core/Palette.h +++ b/project/jni/application/gemrb/gemrb/core/Palette.h @@ -43,6 +43,7 @@ struct RGBModifier { TINT, BRIGHTEN } type; + bool locked; }; diff --git a/project/jni/application/gemrb/src/core/PalettedImageMgr.cpp b/project/jni/application/gemrb/gemrb/core/PalettedImageMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/PalettedImageMgr.cpp rename to project/jni/application/gemrb/gemrb/core/PalettedImageMgr.cpp diff --git a/project/jni/application/gemrb/src/core/PalettedImageMgr.h b/project/jni/application/gemrb/gemrb/core/PalettedImageMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/PalettedImageMgr.h rename to project/jni/application/gemrb/gemrb/core/PalettedImageMgr.h diff --git a/project/jni/application/gemrb/src/core/Particles.cpp b/project/jni/application/gemrb/gemrb/core/Particles.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Particles.cpp rename to project/jni/application/gemrb/gemrb/core/Particles.cpp diff --git a/project/jni/application/gemrb/src/core/Particles.h b/project/jni/application/gemrb/gemrb/core/Particles.h similarity index 100% rename from project/jni/application/gemrb/src/core/Particles.h rename to project/jni/application/gemrb/gemrb/core/Particles.h diff --git a/project/jni/application/gemrb/src/core/PathFinder.h b/project/jni/application/gemrb/gemrb/core/PathFinder.h similarity index 100% rename from project/jni/application/gemrb/src/core/PathFinder.h rename to project/jni/application/gemrb/gemrb/core/PathFinder.h diff --git a/project/jni/application/gemrb/src/core/Plugin.cpp b/project/jni/application/gemrb/gemrb/core/Plugin.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Plugin.cpp rename to project/jni/application/gemrb/gemrb/core/Plugin.cpp diff --git a/project/jni/application/gemrb/src/core/Plugin.h b/project/jni/application/gemrb/gemrb/core/Plugin.h similarity index 100% rename from project/jni/application/gemrb/src/core/Plugin.h rename to project/jni/application/gemrb/gemrb/core/Plugin.h diff --git a/project/jni/application/gemrb/src/core/PluginMgr.cpp b/project/jni/application/gemrb/gemrb/core/PluginMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/PluginMgr.cpp rename to project/jni/application/gemrb/gemrb/core/PluginMgr.cpp diff --git a/project/jni/application/gemrb/src/core/PluginMgr.h b/project/jni/application/gemrb/gemrb/core/PluginMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/PluginMgr.h rename to project/jni/application/gemrb/gemrb/core/PluginMgr.h diff --git a/project/jni/application/gemrb/src/core/Polygon.cpp b/project/jni/application/gemrb/gemrb/core/Polygon.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Polygon.cpp rename to project/jni/application/gemrb/gemrb/core/Polygon.cpp diff --git a/project/jni/application/gemrb/src/core/Polygon.h b/project/jni/application/gemrb/gemrb/core/Polygon.h similarity index 100% rename from project/jni/application/gemrb/src/core/Polygon.h rename to project/jni/application/gemrb/gemrb/core/Polygon.h diff --git a/project/jni/application/gemrb/src/core/PolymorphCache.h b/project/jni/application/gemrb/gemrb/core/PolymorphCache.h similarity index 100% rename from project/jni/application/gemrb/src/core/PolymorphCache.h rename to project/jni/application/gemrb/gemrb/core/PolymorphCache.h diff --git a/project/jni/application/gemrb/src/core/Projectile.cpp b/project/jni/application/gemrb/gemrb/core/Projectile.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Projectile.cpp rename to project/jni/application/gemrb/gemrb/core/Projectile.cpp diff --git a/project/jni/application/gemrb/src/core/Projectile.h b/project/jni/application/gemrb/gemrb/core/Projectile.h similarity index 100% rename from project/jni/application/gemrb/src/core/Projectile.h rename to project/jni/application/gemrb/gemrb/core/Projectile.h diff --git a/project/jni/application/gemrb/src/core/ProjectileMgr.cpp b/project/jni/application/gemrb/gemrb/core/ProjectileMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ProjectileMgr.cpp rename to project/jni/application/gemrb/gemrb/core/ProjectileMgr.cpp diff --git a/project/jni/application/gemrb/src/core/ProjectileMgr.h b/project/jni/application/gemrb/gemrb/core/ProjectileMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/ProjectileMgr.h rename to project/jni/application/gemrb/gemrb/core/ProjectileMgr.h diff --git a/project/jni/application/gemrb/src/core/ProjectileServer.cpp b/project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ProjectileServer.cpp rename to project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp diff --git a/project/jni/application/gemrb/src/core/ProjectileServer.h b/project/jni/application/gemrb/gemrb/core/ProjectileServer.h similarity index 100% rename from project/jni/application/gemrb/src/core/ProjectileServer.h rename to project/jni/application/gemrb/gemrb/core/ProjectileServer.h diff --git a/project/jni/application/gemrb/src/core/Region.cpp b/project/jni/application/gemrb/gemrb/core/Region.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Region.cpp rename to project/jni/application/gemrb/gemrb/core/Region.cpp diff --git a/project/jni/application/gemrb/src/core/Region.h b/project/jni/application/gemrb/gemrb/core/Region.h similarity index 100% rename from project/jni/application/gemrb/src/core/Region.h rename to project/jni/application/gemrb/gemrb/core/Region.h diff --git a/project/jni/application/gemrb/src/core/Resource.cpp b/project/jni/application/gemrb/gemrb/core/Resource.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Resource.cpp rename to project/jni/application/gemrb/gemrb/core/Resource.cpp diff --git a/project/jni/application/gemrb/src/core/Resource.h b/project/jni/application/gemrb/gemrb/core/Resource.h similarity index 100% rename from project/jni/application/gemrb/src/core/Resource.h rename to project/jni/application/gemrb/gemrb/core/Resource.h diff --git a/project/jni/application/gemrb/src/core/ResourceDesc.cpp b/project/jni/application/gemrb/gemrb/core/ResourceDesc.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceDesc.cpp rename to project/jni/application/gemrb/gemrb/core/ResourceDesc.cpp diff --git a/project/jni/application/gemrb/src/core/ResourceDesc.h b/project/jni/application/gemrb/gemrb/core/ResourceDesc.h similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceDesc.h rename to project/jni/application/gemrb/gemrb/core/ResourceDesc.h diff --git a/project/jni/application/gemrb/src/core/ResourceManager.cpp b/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceManager.cpp rename to project/jni/application/gemrb/gemrb/core/ResourceManager.cpp diff --git a/project/jni/application/gemrb/src/core/ResourceManager.h b/project/jni/application/gemrb/gemrb/core/ResourceManager.h similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceManager.h rename to project/jni/application/gemrb/gemrb/core/ResourceManager.h diff --git a/project/jni/application/gemrb/src/core/ResourceSource.cpp b/project/jni/application/gemrb/gemrb/core/ResourceSource.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceSource.cpp rename to project/jni/application/gemrb/gemrb/core/ResourceSource.cpp diff --git a/project/jni/application/gemrb/src/core/ResourceSource.h b/project/jni/application/gemrb/gemrb/core/ResourceSource.h similarity index 100% rename from project/jni/application/gemrb/src/core/ResourceSource.h rename to project/jni/application/gemrb/gemrb/core/ResourceSource.h diff --git a/project/jni/application/gemrb/src/core/SaveGame.h b/project/jni/application/gemrb/gemrb/core/SaveGame.h similarity index 100% rename from project/jni/application/gemrb/src/core/SaveGame.h rename to project/jni/application/gemrb/gemrb/core/SaveGame.h diff --git a/project/jni/application/gemrb/src/core/SaveGameIterator.cpp b/project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SaveGameIterator.cpp rename to project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp diff --git a/project/jni/application/gemrb/src/core/SaveGameIterator.h b/project/jni/application/gemrb/gemrb/core/SaveGameIterator.h similarity index 100% rename from project/jni/application/gemrb/src/core/SaveGameIterator.h rename to project/jni/application/gemrb/gemrb/core/SaveGameIterator.h diff --git a/project/jni/application/gemrb/src/core/SaveGameMgr.cpp b/project/jni/application/gemrb/gemrb/core/SaveGameMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SaveGameMgr.cpp rename to project/jni/application/gemrb/gemrb/core/SaveGameMgr.cpp diff --git a/project/jni/application/gemrb/src/core/SaveGameMgr.h b/project/jni/application/gemrb/gemrb/core/SaveGameMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/SaveGameMgr.h rename to project/jni/application/gemrb/gemrb/core/SaveGameMgr.h diff --git a/project/jni/application/gemrb/src/core/ScriptEngine.cpp b/project/jni/application/gemrb/gemrb/core/ScriptEngine.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ScriptEngine.cpp rename to project/jni/application/gemrb/gemrb/core/ScriptEngine.cpp diff --git a/project/jni/application/gemrb/src/core/ScriptEngine.h b/project/jni/application/gemrb/gemrb/core/ScriptEngine.h similarity index 100% rename from project/jni/application/gemrb/src/core/ScriptEngine.h rename to project/jni/application/gemrb/gemrb/core/ScriptEngine.h diff --git a/project/jni/application/gemrb/src/core/Scriptable/Actor.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp similarity index 96% rename from project/jni/application/gemrb/src/core/Scriptable/Actor.cpp rename to project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp index f83a0ff2e..bf07faf3e 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/Actor.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp @@ -88,10 +88,13 @@ static int xpbonuslevels = -1; static int **levelslots = NULL; static int *dualswap = NULL; static int *maxhpconbon = NULL; +static int *skillstats = NULL; +static int *skillabils = NULL; +static int skillcount = -1; static ieVariable CounterNames[4]={"GOOD","LAW","LADY","MURDER"}; static int FistRows = -1; -int *wmlevels[20]; +static int *wmlevels[20]; typedef ieResRef FistResType[MAX_LEVEL+1]; static FistResType *fistres = NULL; @@ -343,6 +346,7 @@ Actor::Actor() LastDamage = 0; LastDamageType = 0; LastTurner = 0; + LastExit = 0; HotKey = 0; attackcount = 0; secondround = 0; @@ -404,8 +408,10 @@ Actor::Actor() //this one is not saved GotLUFeedback = false; RollSaves(); + WMLevelMod = 0; polymorphCache = NULL; + memset(&wildSurgeMods, 0, sizeof(wildSurgeMods)); } Actor::~Actor(void) @@ -475,10 +481,12 @@ void Actor::SetName(int strref, unsigned char type) if (type!=2) { if (LongName) free(LongName); LongName = core->GetString( strref, IE_STR_REMOVE_NEWLINE ); + LongStrRef = strref; } if (type!=1) { if (ShortName) free(ShortName); ShortName = core->GetString( strref, IE_STR_REMOVE_NEWLINE ); + ShortStrRef = strref; } } @@ -549,7 +557,7 @@ void Actor::SetAnimationID(unsigned int AnimID) } -CharAnimations* Actor::GetAnims() +CharAnimations* Actor::GetAnims() const { return anims; } @@ -719,7 +727,7 @@ bool Actor::ApplyKit(bool remove) //multi class if (multiclass) { ieDword msk = 1; - for(unsigned int i=1;(i<32) && (msk<=multiclass);i++) { + for(unsigned int i=1;(i<(unsigned int) classcount) && (msk<=multiclass);i++) { if (multiclass & msk) { max = GetClassLevel(levelslotsbg[i]); // don't apply/remove the old kit clab if the kit is disabled @@ -735,11 +743,13 @@ bool Actor::ApplyKit(bool remove) } //single class ieDword cls = GetStat(IE_CLASS); + if (cls<(ieDword) classcount) { + return false; + } max = GetClassLevel(levelslotsbg[cls]); if (kitclass==cls) { ApplyClab(clab, max, remove); - } - else { + } else { ApplyClab(classabilities[cls], max, remove); } return true; @@ -1247,6 +1257,15 @@ void Actor::ReleaseMemory() free(maxhpconbon); maxhpconbon=NULL; } + if (skillstats) { + free(skillstats); + skillstats=NULL; + } + if (skillabils) { + free(skillabils); + skillabils=NULL; + } + if (wspecial) { for (i=0; i<=wspecial_max; i++) { if (wspecial[i]) { @@ -1899,6 +1918,21 @@ static void InitActorTables() VCMap[row]=value; } } + + //initializing the skill->stats conversion table (used in iwd2) + tm.load("skillsta"); + if (tm) { + int rowcount = tm->GetRowCount(); + skillcount = rowcount; + if (rowcount) { + skillstats = (int *) malloc(rowcount * sizeof(int) ); + skillabils = (int *) malloc(rowcount * sizeof(int) ); + while(rowcount--) { + skillstats[rowcount]=core->TranslateStat(tm->QueryField(rowcount,0)); + skillabils[rowcount]=core->TranslateStat(tm->QueryField(rowcount,1)); + } + } + } } void Actor::SetLockedPalette(const ieDword *gradients) @@ -2018,7 +2052,7 @@ int Actor::GetMod(unsigned int StatIndex) return (signed) Modified[StatIndex] - (signed) BaseStats[StatIndex]; } /** Returns a Stat Base Value */ -ieDword Actor::GetBase(unsigned int StatIndex) +ieDword Actor::GetBase(unsigned int StatIndex) const { if (StatIndex >= MAX_STATS) { return 0xffff; @@ -2092,7 +2126,7 @@ bool Actor::SetBaseBit(unsigned int StatIndex, ieDword Value, bool setreset) return true; } -const unsigned char *Actor::GetStateString() +const unsigned char *Actor::GetStateString() const { if (!PCStats) { return NULL; @@ -2151,12 +2185,16 @@ void Actor::RefreshEffects(EffectQueue *fx) //put all special cleanup calls here CharAnimations* anims = GetAnims(); if (anims) { - anims->GlobalColorMod.type = RGBModifier::NONE; - anims->GlobalColorMod.speed = 0; + if (!anims->GlobalColorMod.locked) { + anims->GlobalColorMod.type = RGBModifier::NONE; + anims->GlobalColorMod.speed = 0; + } unsigned int location; for (location = 0; location < 32; ++location) { - anims->ColorMods[location].type = RGBModifier::NONE; - anims->ColorMods[location].speed = 0; + if (!anims->ColorMods[location].phase) { + anims->ColorMods[location].type = RGBModifier::NONE; + anims->ColorMods[location].speed = 0; + } } } spellbook.ClearBonus(); @@ -2317,10 +2355,15 @@ void Actor::RefreshPCStats() { } else { //wspattack appears to only effect warriors int defaultattacks = 2 + 2*dualwielding; - if (tmplevel) { - SetBase(IE_NUMBEROFATTACKS, defaultattacks+wspattack[stars][tmplevel]); + if (stars) { + if (tmplevel) { + SetBase(IE_NUMBEROFATTACKS, defaultattacks+wspattack[stars][tmplevel]); + } else { + SetBase(IE_NUMBEROFATTACKS, defaultattacks); + } } else { - SetBase(IE_NUMBEROFATTACKS, defaultattacks); + // unproficient user - force defaultattacks + SetStat(IE_NUMBEROFATTACKS, defaultattacks, 0); } } } @@ -2681,9 +2724,6 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) int resisted = 0; ModifyDamage (this, hitter, damage, resisted, damagetype, NULL, false); - if (damage) { - GetHit(); - } DisplayCombatFeedback(damage, resisted, damagetype, hitter); @@ -2691,14 +2731,26 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) // common fists do normal damage, but cause sleeping for a round instead of death if ((damagetype & DAMAGE_STUNNING) && Modified[IE_MINHITPOINTS] <= 0) { NewBase(IE_HITPOINTS, 1, MOD_ABSOLUTE); - Effect *fx = EffectQueue::CreateEffect(fx_sleep_ref, 0, 0, FX_DURATION_INSTANT_LIMITED); - fx->Duration = core->Time.round_sec; // 1 round - core->ApplyEffect(fx, this, this); - delete fx; + // stack unconsciousness carefully to avoid replaying the stance changing + Effect *sleep = fxqueue.HasEffectWithParamPair(fx_sleep_ref, 0, 0); + if (sleep) { + sleep->Duration += core->Time.round_sec; + } else { + Effect *fx = EffectQueue::CreateEffect(fx_sleep_ref, 0, 0, FX_DURATION_INSTANT_LIMITED); + fx->Duration = core->Time.round_sec; // 1 round + core->ApplyEffect(fx, this, this); + delete fx; + } } else { + if (damage) { + GetHit(); + } NewBase(IE_HITPOINTS, (ieDword) -damage, MOD_ADDITIVE); } } else { + if (damage) { + GetHit(); + } NewBase(IE_HITPOINTS, (ieDword) -damage, MOD_ADDITIVE); // also apply reputation damage if we hurt (but not killed) an innocent @@ -3081,17 +3133,55 @@ ieDword Actor::GetXPLevel(int modified) const return ieDword(average); } -int Actor::GetWildMod(int level) const +// returns the guessed caster level by passed spell type +// FIXME: add iwd2 support (should be more precise, as there are more class types) +// FIXME: add more logic for cross-type kits (like avengers)? +ieDword Actor::GetBaseCasterLevel(int spelltype) const { - if(GetStat(IE_KIT)&0x8000) { - if (level>=MAX_LEVEL) level=MAX_LEVEL; - if(level<1) level=1; - return wmlevels[core->Roll(1,20,-1)][level-1]; + int level = 0; + + switch(spelltype) + { + case IE_SPL_PRIEST: + level = GetClericLevel(); + if (!level) level = GetDruidLevel(); + if (!level) level = GetPaladinLevel(); + if (!level) level = GetRangerLevel(); + break; + case IE_SPL_WIZARD: + level = GetMageLevel(); + if (!level) level = GetSorcererLevel(); + if (!level) level = GetBardLevel(); + break; + } + // if nothing was found, use the average level + if (!level) level = GetXPLevel(true); + + return level; +} + +int Actor::GetWildMod(int level) +{ + if(GetStat(IE_KIT)&0x1e) { + // avoid rerolling the mod, since we get called multiple times per each cast + if (!WMLevelMod) { + if (level>=MAX_LEVEL) level=MAX_LEVEL; + if(level<1) level=1; + WMLevelMod = wmlevels[core->Roll(1,20,-1)][level-1]; + + core->GetTokenDictionary()->SetAtCopy("LEVELDIF", abs(WMLevelMod)); + if (WMLevelMod > 0) { + displaymsg->DisplayConstantStringName(STR_CASTER_LVL_INC, 0xffffff, this); + } else if (WMLevelMod < 0) { + displaymsg->DisplayConstantStringName(STR_CASTER_LVL_DEC, 0xffffff, this); + } + } + return WMLevelMod; } return 0; } -int Actor::CastingLevelBonus(int level, int type) const +int Actor::CastingLevelBonus(int level, int type) { int bonus = 0; switch(type) @@ -3103,21 +3193,15 @@ int Actor::CastingLevelBonus(int level, int type) const bonus = GetWildMod(level) + GetStat(IE_CASTINGLEVELBONUSMAGE); } - if (!bonus) { - return 0; - } - - core->GetTokenDictionary()->SetAtCopy("LEVELDIF", bonus); - - if (bonus > 0) { - displaymsg->DisplayConstantStringName(STR_CASTER_LVL_INC, 0xffffff, this); - } else { - displaymsg->DisplayConstantStringName(STR_CASTER_LVL_DEC, 0xffffff, this); - } - return bonus; } +ieDword Actor::GetCasterLevel(int spelltype) +{ + int level = GetBaseCasterLevel(spelltype); + return level + CastingLevelBonus(level, spelltype); +} + /** maybe this would be more useful if we calculate with the strength too */ int Actor::GetEncumbrance() @@ -3864,7 +3948,7 @@ int Actor::IsDualWielding() const //returns weapon header currently used (bow in case of bow+arrow) //if range is nonzero, then the returned header is valid -ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) +ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) const { //only use the shield slot if we are dual wielding leftorright = leftorright && IsDualWielding(); @@ -3940,7 +4024,18 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags) if (flags & LS_STATS) { // chance to learn roll - if (LuckyRoll(1,100,0) > core->GetIntelligenceBonus(0, GetStat(IE_INT))) { + int roll = LuckyRoll(1, 100, 0); + // adjust the roll for specialist mages + // doesn't work in bg1, since its spells don't have PrimaryType set + if (GetKitIndex(BaseStats[IE_KIT])) { + if ((signed)BaseStats[IE_KIT] == 1<<(spell->PrimaryType+5)) { // +5 since the kit values start at 0x40 + roll += 15; + } else { + roll -= 15; + } + } + + if (roll > core->GetIntelligenceBonus(0, GetStat(IE_INT))) { return LSR_FAILED; } } @@ -4069,7 +4164,7 @@ void Actor::SetModalSpell(ieDword state, const char *spell) //this is just a stub function for now, attackstyle could be melee/ranged //even spells got this attack style -int Actor::GetAttackStyle() +int Actor::GetAttackStyle() const { WeaponInfo wi; //Non NULL if the equipped slot is a projectile or a throwing weapon @@ -4202,7 +4297,7 @@ void Actor::InitRound(ieDword gameTime) } bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader, \ - ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style) + ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target) const { tohit = GetStat(IE_TOHIT); speed = -GetStat(IE_PHYSICALSPEED); @@ -4229,7 +4324,7 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx if (!rangedheader) { //display out of ammo verbal constant if there is any??? //DisplayStringCore(this, VB_OUTOFAMMO, DS_CONSOLE|DS_CONST ); - SetStance(IE_ANI_READY); + //SetStance(IE_ANI_READY); //set some trigger? return false; } @@ -4241,7 +4336,7 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx break; default: //item is unsuitable for fight - SetStance(IE_ANI_READY); + //SetStance(IE_ANI_READY); return false; }//melee or ranged //this flag is set by the bow in case of projectile launcher. @@ -4315,7 +4410,7 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx // TODO: Elves get a racial THAC0 bonus with all swords and bows in BG2 (but not daggers) //second parameter is left or right hand flag - tohit = GetToHit(THAC0Bonus, Flags); + tohit = GetToHit(THAC0Bonus, Flags, target); //pst increased critical hits if (pstflags && (Modified[IE_STATE_ID]&STATE_CRIT_ENH)) { @@ -4324,7 +4419,14 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx return true; } -int Actor::GetToHit(int bonus, ieDword Flags) +int Actor::MeleePenalty() const +{ + if (GetMonkLevel()) return 0; + if (inventory.GetEquippedSlot()!=IW_NO_EQUIPPED) return 4; + return 0; +} + +int Actor::GetToHit(int bonus, ieDword Flags, Actor *target) const { int tohit = bonus; @@ -4357,19 +4459,22 @@ int Actor::GetToHit(int bonus, ieDword Flags) tohit += core->GetStrengthBonus(0,GetStat(IE_STR), GetStat(IE_STREXTRA) ); } - // if the target is using a ranged weapon while we're meleeing, we get a +4 bonus - if ((Flags&WEAPON_STYLEMASK) != WEAPON_RANGED) { - Actor *target = area->GetActorByGlobalID(LastTarget); - if (target && target->GetAttackStyle() == WEAPON_RANGED) { - tohit += 4; + if (target) { + // if the target is using a ranged weapon while we're meleeing, we get a +4 bonus + if ((Flags&WEAPON_STYLEMASK) != WEAPON_RANGED) { + if (target->GetAttackStyle() == WEAPON_RANGED) { + tohit += 4; + } } - } - // add +4 attack bonus vs racial enemies - if (GetRangerLevel()) { - Actor *target = area->GetActorByGlobalID(LastTarget); - if (target && IsRacialEnemy(target)) { - tohit += 4; + // melee vs. unarmed + tohit += target->MeleePenalty() - MeleePenalty(); + + // add +4 attack bonus vs racial enemies + if (GetRangerLevel()) { + if (IsRacialEnemy(target)) { + tohit += 4; + } } } @@ -4384,7 +4489,7 @@ int Actor::GetToHit(int bonus, ieDword Flags) static const int weapon_damagetype[] = {DAMAGE_CRUSHING, DAMAGE_PIERCING, DAMAGE_CRUSHING, DAMAGE_SLASHING, DAMAGE_MISSILE, DAMAGE_STUNNING}; -int Actor::GetDefense(int DamageType) +int Actor::GetDefense(int DamageType) const { //specific damage type bonus. int defense = 0; @@ -4507,7 +4612,7 @@ void Actor::PerformAttack(ieDword gameTime) int speed, style; //will return false on any errors (eg, unusable weapon) - if (!GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style)) { + if (!GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, target)) { return; } @@ -4517,9 +4622,8 @@ void Actor::PerformAttack(ieDword gameTime) // speed contains the bonus from the physical speed stat and the proficiency level int spdfactor = hittingheader->Speed + speed; if (spdfactor<0) spdfactor = 0; - // FIXME: make LuckyRoll also be able to use luck as a malus // -3: k/2 in the original, hardcoded to 6; -1 for the difference in rolls - the original rolled 0-5 - spdfactor += core->Roll(1, 6, -Modified[IE_LUCK]) - 4; + spdfactor += LuckyRoll(1, 6, -4, LR_NEGATIVE); if (spdfactor<0) spdfactor = 0; if (spdfactor>10) spdfactor = 10; @@ -4585,7 +4689,7 @@ void Actor::PerformAttack(ieDword gameTime) int resisted = 0; if (hittingheader->DiceThrown<256) { - damage += LuckyRoll(hittingheader->DiceThrown, hittingheader->DiceSides, 0, 1, 0); + damage += LuckyRoll(hittingheader->DiceThrown, hittingheader->DiceSides, 0, LR_CRITICAL); damage += DamageBonus; printf("| Damage %dd%d%+d = %d ",hittingheader->DiceThrown, hittingheader->DiceSides, DamageBonus, damage); } else { @@ -4720,7 +4824,7 @@ void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &re // damage type without a resistance stat } else { damage += (signed)target->GetStat(IE_DAMAGEBONUS); - resisted = (int) (damage * (signed)target->GetStat(it->second.resist_stat)/100.0); + resisted = (int) (damage * (signed)target->GetSafeStat(it->second.resist_stat)/100.0); // check for bonuses for specific damage types if (core->HasFeature(GF_SPECIFIC_DMG_BONUS) && hitter && hitter->Type == ST_ACTOR) { int bonus = ((Actor *)hitter)->fxqueue.SpecificDamageBonus(it->second.iwd_mod_type); @@ -4730,7 +4834,7 @@ void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &re } } damage -= resisted; - printf("Resisted %d of %d at %d%% resistance to %d\n", resisted, damage+resisted, target->GetStat(it->second.resist_stat), damagetype); + printf("Resisted %d of %d at %d%% resistance to %d\n", resisted, damage+resisted, target->GetSafeStat(it->second.resist_stat), damagetype); if (damage <= 0) resisted = DR_IMMUNE; } } @@ -4878,6 +4982,8 @@ void Actor::SetColorMod( ieDword location, RGBModifier::Type type, int speed, if (!ca) return; if (location == 0xff) { + if (phase && ca->GlobalColorMod.locked) return; + ca->GlobalColorMod.locked = !phase; ca->GlobalColorMod.type = type; ca->GlobalColorMod.speed = speed; ca->GlobalColorMod.rgb.r = r; @@ -4894,6 +5000,7 @@ void Actor::SetColorMod( ieDword location, RGBModifier::Type type, int speed, } //00xx0yyy-->000xxyyy if (location&0xffffffc8) return; //invalid location + if (phase && ca->ColorMods[location].locked) return; location = (location &7) | ((location>>1)&0x18); ca->ColorMods[location].type = type; ca->ColorMods[location].speed = speed; @@ -5517,7 +5624,7 @@ bool Actor::HandleActorStance() return false; } -void Actor::GetSoundFrom2DA(ieResRef Sound, unsigned int index) +void Actor::GetSoundFrom2DA(ieResRef Sound, unsigned int index) const { if (!anims) return; @@ -5552,7 +5659,7 @@ void Actor::GetSoundFrom2DA(ieResRef Sound, unsigned int index) strnlwrcpy(Sound, tab->QueryField (index, col), 8); } -void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) +void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) const { const char *resource = ""; char section[12]; @@ -5587,7 +5694,7 @@ void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) Sound[count]=0; } -void Actor::ResolveStringConstant(ieResRef Sound, unsigned int index) +void Actor::ResolveStringConstant(ieResRef Sound, unsigned int index) const { if (PCStats && PCStats->SoundSet[0]) { //resolving soundset (bg1/bg2 style) @@ -5709,15 +5816,15 @@ void Actor::GetSoundFolder(char *soundset, int full) const } } -bool Actor::HasVVCCell(const ieResRef resource) +bool Actor::HasVVCCell(const ieResRef resource) const { return GetVVCCell(resource) != NULL; } -ScriptedAnimation *Actor::GetVVCCell(const ieResRef resource) +ScriptedAnimation *Actor::GetVVCCell(const ieResRef resource) const { int j = true; - vvcVector *vvcCells=&vvcShields; + const vvcVector *vvcCells=&vvcShields; retry: size_t i=vvcCells->size(); while (i--) { @@ -5761,9 +5868,9 @@ retry: //this is a faster version of hasvvccell, because it knows where to look //for the overlay, it also returns the vvc for further manipulation //use this for the seven eyes overlay -ScriptedAnimation *Actor::FindOverlay(int index) +ScriptedAnimation *Actor::FindOverlay(int index) const { - vvcVector *vvcCells; + const vvcVector *vvcCells; if (index>31) return NULL; @@ -5863,7 +5970,7 @@ void Actor::Rest(int hours) } //returns the actual slot from the quickslot -int Actor::GetQuickSlot(int slot) +int Actor::GetQuickSlot(int slot) const { assert(slot<8); if (inventory.HasItemInSlot("",inventory.GetMagicSlot())) { @@ -6348,7 +6455,7 @@ bool Actor::SetSpellState(unsigned int spellstate) } //returns true if spell state is already set -bool Actor::HasSpellState(unsigned int spellstate) +bool Actor::HasSpellState(unsigned int spellstate) const { if (spellstate>=192) return false; unsigned int pos = IE_SPLSTATE_ID1+(spellstate>>5); @@ -6357,6 +6464,20 @@ bool Actor::HasSpellState(unsigned int spellstate) return false; } +//this is a very specific rule that might need an external table later +int Actor::GetAbilityBonus(unsigned int ability) const +{ + return GetStat(ability)/2-5; +} + +int Actor::GetSkill(unsigned int skill) const +{ + if (skill>=(unsigned int) skillcount) return -1; + int ret = GetStat(skillstats[skill])+GetAbilityBonus(skillabils[skill]); + if (ret<0) ret = 0; + return ret; +} + //returns the numeric value of a feat, different from HasFeat //for multiple feats int Actor::GetFeat(unsigned int feat) const @@ -6683,43 +6804,54 @@ bool Actor::BlocksSearchMap() const } //return true if the actor doesn't want to use an entrance -bool Actor::CannotPassEntrance() const +bool Actor::CannotPassEntrance(ieDword exitID) const { + if (LastExit!=exitID) { + return true; + } + if (InternalFlags&IF_USEEXIT) { return false; } + return true; } -void Actor::UseExit(int flag) { - if (flag) { +void Actor::UseExit(ieDword exitID) { + if (exitID) { InternalFlags|=IF_USEEXIT; } else { InternalFlags&=~IF_USEEXIT; } + LastExit = exitID; } // luck increases the minimum roll per dice, but only up to the number of dice sides; // luck does not affect critical hit chances: // if critical is set, it will return 1/sides on a critical, otherwise it can never // return a critical miss when luck is positive and can return a false critical hit -int Actor::LuckyRoll(int dice, int size, int add, bool critical, bool only_damage, Actor* opponent) const +int Actor::LuckyRoll(int dice, int size, int add, ieDword flags, Actor* opponent) const { assert(this != opponent); ieDword stat; - if (only_damage) { + if (flags&LR_DAMAGELUCK) { stat = IE_DAMAGELUCK; } else { stat = IE_LUCK; } - int luck = (signed) GetStat(stat); + int luck = (signed) GetSafeStat(stat); + if (flags&LR_NEGATIVE) { + luck = -luck; + } if (opponent) luck -= (signed) opponent->GetStat(stat); if (dice < 1 || size < 1) { return add + luck; } + ieDword critical = flags&LR_CRITICAL; + if (dice > 100) { int bonus; if (abs(luck) > size) { @@ -6801,7 +6933,7 @@ void Actor::ResetState() // doesn't check the range, but only that the azimuth and the target // orientation match with a +/-2 allowed difference -bool Actor::IsBehind(Actor* target) +bool Actor::IsBehind(Actor* target) const { unsigned char tar_orient = target->GetOrientation(); // computed, since we don't care where we face @@ -6818,7 +6950,7 @@ bool Actor::IsBehind(Actor* target) } // checks all the actor's stats to see if the target is her racial enemy -bool Actor::IsRacialEnemy(Actor* target) +bool Actor::IsRacialEnemy(Actor* target) const { if (Modified[IE_HATEDRACE] == target->Modified[IE_RACE]) { return true; @@ -6900,14 +7032,14 @@ bool Actor::TryToHide() { return true; } -bool Actor::InvalidSpellTarget() +bool Actor::InvalidSpellTarget() const { if (GetStat(IE_STATE_ID) & (STATE_DEAD)) return true; if (HasSpellState(SS_SANCTUARY)) return true; return false; } -bool Actor::InvalidSpellTarget(int spellnum, Actor *caster, int range) +bool Actor::InvalidSpellTarget(int spellnum, Actor *caster, int range) const { ieResRef spellres; @@ -6931,7 +7063,7 @@ bool Actor::PCInDark() const return false; } -int Actor::GetClassMask() +int Actor::GetClassMask() const { int classmask = 0; for (int i=0; i < ISCLASSES; i++) { diff --git a/project/jni/application/gemrb/src/core/Scriptable/Actor.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h similarity index 91% rename from project/jni/application/gemrb/src/core/Scriptable/Actor.h rename to project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h index cc847308f..358fdd357 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/Actor.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h @@ -49,7 +49,12 @@ struct PolymorphCache; #define MAX_STATS 256 #define MAX_LEVEL 128 -#define MAX_FEATS 96 //3*sizeof(ieDword) +#define MAX_FEATS 96 //3*sizeof(ieDword) + +//lucky roll +#define LR_CRITICAL 1 +#define LR_DAMAGELUCK 2 +#define LR_NEGATIVE 4 //modal states #define MS_NONE 0 @@ -179,6 +184,20 @@ struct PolymorphCache; // used for distinguishing damage immunity from high damage resistance #define DR_IMMUNE 999999 +// wild surge target change type +#define WSTC_SETTYPE 1 // change to this target type +#define WSTC_ADDTYPE 2 // affect also this target type +#define WSTC_RANDOMIZE 3 // choose a random target +struct WildSurgeSpellMods { + unsigned int num_castings; // number of times to cast + unsigned int num_wildrolls; // number of times to roll + unsigned int projectile_id; // new projectile id + unsigned int target_change_type; // settype, addtype, randomize + unsigned int target_type; // type to use when target_change_type is not WSTC_RANDOMIZE + unsigned int projectile_speed_mod; // factor in percents + int saving_throw_mod; +}; + typedef ieByte ActionButtonRow[GUIBT_COUNT]; struct ActionButtonRow2 { ActionButtonRow buttons; @@ -268,16 +287,18 @@ public: ieDword LastCommander; ieDword LastHelp; ieDword LastSeen; - ieDword LastMarked; // no idea if non-actors could mark objects + ieDword LastMarked; //no idea if non-actors could mark objects int LastMarkedSpell; //a spell number to cast ieDword LastHeard; ieDword HotKey; + ieDword LastExit; //the global ID of the exit to be used char ShieldRef[2]; char HelmetRef[2]; char WeaponRef[2]; int WeaponType; ieDword multiclass; bool GotLUFeedback; + int WMLevelMod; int LastCommand; //lastcommander int LastShout; //lastheard @@ -303,6 +324,7 @@ public: int speed; PolymorphCache *polymorphCache; // fx_polymorph etc + WildSurgeSpellMods wildSurgeMods; private: //this stuff doesn't get saved CharAnimations* anims; @@ -371,7 +393,7 @@ public: /** you better use SetStat, this stuff is only for special cases*/ void SetAnimationID(unsigned int AnimID); /** returns the animations */ - CharAnimations* GetAnims(); + CharAnimations* GetAnims() const; /** Re/Inits the Modified vector */ void RefreshEffects(EffectQueue *eqfx); /** gets saving throws */ @@ -389,7 +411,7 @@ public: /** Returns the difference */ int GetMod(unsigned int StatIndex); /** Returns a Stat Base Value */ - ieDword GetBase(unsigned int StatIndex); + ieDword GetBase(unsigned int StatIndex) const; /** Sets a Base Stat Value */ bool SetBase(unsigned int StatIndex, ieDword Value); bool SetBaseNoPCF(unsigned int StatIndex, ieDword Value); @@ -423,10 +445,13 @@ public: const char* GetScript(int ScriptIndex) const; /** Gets the Character's level for XP calculations */ ieDword GetXPLevel(int modified) const; + /** Guesses the (base) casting level */ + ieDword GetCasterLevel(int spelltype); + ieDword GetBaseCasterLevel(int spelltype) const; /** Returns the wild mage casting level modifier */ - int GetWildMod(int level) const; + int GetWildMod(int level); /** Returns any casting level modifier */ - int CastingLevelBonus(int level, int type) const; + int CastingLevelBonus(int level, int type); /** Gets the Dialog ResRef */ const char* GetDialog(int flags=GD_NORMAL) const; @@ -520,7 +545,7 @@ public: ITMExtHeader *GetRangedWeapon(WeaponInfo &wi) const; /* Returns current weapon range and extended header if range is nonzero, then which is valid */ - ITMExtHeader* GetWeapon(WeaponInfo &wi, bool leftorright=false); + ITMExtHeader* GetWeapon(WeaponInfo &wi, bool leftorright=false) const; /* Creates player statistics */ void CreateStats(); /* Heals actor by days */ @@ -534,20 +559,22 @@ public: /* Sets the modal spell after checks */ void SetModalSpell(ieDword state, const char *spell); /* returns current attack style */ - int GetAttackStyle(); + int GetAttackStyle() const; /* adds the combatants to the attackers list */ void AttackedBy(Actor *actor); /* sets target for immediate attack */ void SetTarget( Scriptable *actor); /* starts combat round*/ void InitRound(ieDword gameTime); + /* returns melee penalty */ + int MeleePenalty() const; /* gets the to hit value */ - int GetToHit(int bonus, ieDword Flags); + int GetToHit(int bonus, ieDword Flags, Actor *target) const; /* gets the defense against an attack */ - int GetDefense(int DamageType) ; + int GetDefense(int DamageType) const; /* get the current hit bonus */ bool GetCombatDetails(int &tohit, bool leftorright, WeaponInfo &wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader,\ - ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style); + ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target) const; /* performs attack against target */ void PerformAttack(ieDword gameTime); /* ensures we can deal damage to a target */ @@ -570,9 +597,9 @@ public: /* overridden method, won't walk if dead */ void WalkTo(const Point &Des, ieDword flags, int MinDistance = 0); /* resolve string constant (sound will be altered) */ - void ResolveStringConstant(ieResRef sound, unsigned int index); - void GetSoundFromINI(ieResRef Sound, unsigned int index); - void GetSoundFrom2DA(ieResRef Sound, unsigned int index); + void ResolveStringConstant(ieResRef sound, unsigned int index) const; + void GetSoundFromINI(ieResRef Sound, unsigned int index) const; + void GetSoundFrom2DA(ieResRef Sound, unsigned int index) const; /* sets the quick slots */ void SetActionButtonRow(ActionButtonRow &ar); /* updates the quick slots */ @@ -591,12 +618,12 @@ public: /* remove a vvc from the list, graceful means animated removal */ void RemoveVVCell(const ieResRef vvcname, bool graceful); /* returns true if actor already has the overlay (slow) */ - bool HasVVCCell(const ieResRef resource); + bool HasVVCCell(const ieResRef resource) const; /* returns overlay if actor already has it (slow) */ - ScriptedAnimation *GetVVCCell(const ieResRef resource); + ScriptedAnimation *GetVVCCell(const ieResRef resource) const; /* returns the vvc pointer to a hardcoded overlay */ /* if it exists (faster than hasvvccell) */ - ScriptedAnimation *FindOverlay(int index); + ScriptedAnimation *FindOverlay(int index) const; /* draw videocells */ void DrawVideocells(const Region &screen, vvcVector &vvcCells, const Color &tint); @@ -610,13 +637,13 @@ public: /* rememorizes spells, cures fatigue, etc */ void Rest(int hours); /* returns the portrait icons list */ - const unsigned char *GetStateString(); + const unsigned char *GetStateString() const; /* adds a state icon to the list */ void AddPortraitIcon(ieByte icon); /* disables a state icon in the list, doesn't remove it! */ void DisablePortraitIcon(ieByte icon); /* returns which slot belongs to the quickweapon slot */ - int GetQuickSlot(int slot); + int GetQuickSlot(int slot) const; /* Sets equipped Quick slot, if header is -1, then use the current one */ int SetEquippedQuickSlot(int slot, int header); /* Uses an item on the target or point */ @@ -625,12 +652,14 @@ public: /* Deducts a charge from an item */ void ChargeItem(ieDword slot, ieDword header, CREItem *item, Item *itm, bool silent); /* If it returns true, then default AC=10 and the lesser the better */ - int IsReverseToHit(); + static int IsReverseToHit(); /* initialize the action buttons based on class. If forced, it will override previously customized or set buttons. */ void InitButtons(ieDword cls, bool forced); - void SetFeat(unsigned int feat, int mode); + int GetAbilityBonus(unsigned int ability) const; + int GetSkill(unsigned int skill) const; int GetFeat(unsigned int feat) const; + void SetFeat(unsigned int feat, int mode); void SetUsedWeapon(const char *AnimationType, ieWord *MeleeAnimation, int WeaponType=-1); void SetUsedShield(const char *AnimationType, int WeaponType=-1); @@ -649,7 +678,7 @@ public: /* Checks and sets a spellstate if it wasn't set yet */ bool SetSpellState(unsigned int spellstate); /* Checks a spellstate */ - bool HasSpellState(unsigned int spellstate); + bool HasSpellState(unsigned int spellstate) const; /* Checks a feat */ bool HasFeat(unsigned int featindex) const; /* Reports projectile immunity, nonzero if immune */ @@ -684,11 +713,11 @@ public: /* true if we are dual-wielding */ int IsDualWielding() const; bool BlocksSearchMap() const; - bool CannotPassEntrance() const; - void UseExit(int flag); - int GetReaction(); + bool CannotPassEntrance(ieDword exitID) const; + void UseExit(ieDword exitID); + //int GetReaction() const; /* Similar to Roll, but takes luck into account */ - int LuckyRoll(int dice, int size, int add, bool critical=1, bool only_damage=0, Actor* opponent=NULL) const; + int LuckyRoll(int dice, int size, int add, ieDword flags=1, Actor* opponent=NULL) const; /* removes normal invisibility (type 0) */ void CureInvisibility(); /* removes sanctuary */ @@ -696,23 +725,23 @@ public: /* resets the invisibility, sanctuary and modal states */ void ResetState(); /* checks whether the actor is behind the target */ - bool IsBehind(Actor* target); + bool IsBehind(Actor* target) const; /* checks whether the target is the actor's racial enemy */ - bool IsRacialEnemy(Actor* target); + bool IsRacialEnemy(Actor* target) const; /* checks whether the actor can stay in the current modal state */ bool ModalSpellSkillCheck(); /* does all the game logic checks to see if the actor can hide */ bool TryToHide(); /* checks if the alignment matches one of the masking constants */ - bool MatchesAlignmentMask(ieDword mask); + //bool MatchesAlignmentMask(ieDword mask); /* returns true if this actor is untargetable */ - bool InvalidSpellTarget(); + bool InvalidSpellTarget() const; /* returns true if the spell is useless to cast on target or the spell's range is smaller than range */ - bool InvalidSpellTarget(int spellnum, Actor *caster, int range); + bool InvalidSpellTarget(int spellnum, Actor *caster, int range) const; /* returns true if the lightmap under the actor is dark */ bool PCInDark() const; /* computes the actor's classmask (iwd2) */ - int GetClassMask(); + int GetClassMask() const; }; #endif diff --git a/project/jni/application/gemrb/src/core/Scriptable/ActorBlock.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.cpp similarity index 78% rename from project/jni/application/gemrb/src/core/Scriptable/ActorBlock.cpp rename to project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.cpp index ff1b5da3e..f16688788 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/ActorBlock.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.cpp @@ -96,6 +96,7 @@ Scriptable::Scriptable(ScriptableType type) LastCasterSeen = 0; LastSpellSeen = 0xffffffff; SpellHeader = -1; + SpellResRef[0] = 0; LastTargetPos.empty(); locals = new Variables(); locals->SetType( GEM_VARIABLES_INT ); @@ -188,6 +189,10 @@ void Scriptable::SetScript(int index, GameScript* script) Scripts[index] = script; } +void Scriptable::SetSpellResRef(ieResRef resref) { + strnuprcpy(SpellResRef, resref, 8); +} + void Scriptable::DisplayHeadText(const char* text) { if (overHeadText) { @@ -593,22 +598,40 @@ static EffectRef fx_set_invisible_state_ref={"State:Invisible",NULL,-1}; void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool fake) { Spell* spl = gamedata->GetSpell( SpellResRef ); + Actor *caster = NULL; //PST has a weird effect, called Enoll Eva's duplication //it creates every projectile of the affected actor twice int duplicate = 1; + if (Type == ST_ACTOR) { + caster = (Actor *) this; + duplicate = caster->wildSurgeMods.num_castings; + if (!duplicate) { + duplicate = 1; + } + } if (core->HasFeature(GF_PST_STATE_FLAGS) && (Type == ST_ACTOR)) { - if ( ((Actor *)this)->GetStat(IE_STATE_ID)&STATE_EE_DUPL) { - duplicate = 2; + if (caster->GetStat(IE_STATE_ID)&STATE_EE_DUPL) { + duplicate *= 2; } } while(duplicate --) { - Projectile *pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); - if (!pro) { - return; + Projectile *pro = NULL; + // jump through hoops to skip applying selftargetting spells to the caster + // if we'll be changing the target + int tct = 0; + if (caster) { + tct = caster->wildSurgeMods.target_change_type; } - pro->SetCaster(GetGlobalID()); + if (!caster || !tct || tct == WSTC_ADDTYPE || !caster->wildSurgeMods.projectile_id) { + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + if (!pro) { + return; + } + pro->SetCaster(GetGlobalID()); + } + Point origin = Pos; if (Type == ST_TRIGGER || Type == ST_PROXIMITY) { // try and make projectiles start from the right trap position @@ -617,6 +640,106 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool origin = ((InfoPoint *)this)->TrapLaunch; } + if (caster) { + // check for the speed mod + if (caster->wildSurgeMods.projectile_speed_mod) { + pro->Speed = (pro->Speed * caster->wildSurgeMods.projectile_speed_mod) / 100; + if (!pro->Speed) { + pro->Speed = 1; + } + } + + // check for target (type) change + int count, i; + Actor *newact = NULL; + SPLExtHeader *seh = NULL; + Effect *fx = NULL; + switch (caster->wildSurgeMods.target_change_type) { + case WSTC_SETTYPE: + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + seh->features[i].Target = caster->wildSurgeMods.target_type; + } + // we need to fetch the projectile, so the effect queue is created + // (skipped above) + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID()); + break; + case WSTC_ADDTYPE: + // TODO: unhardcode to allow for mixing all the target types + // caster gets selftargetting fx when the projectile is fetched above + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = caster->wildSurgeMods.target_type; + } else { + // also apply to the caster + fx = seh->features+i; + core->ApplyEffect(fx, caster, caster); + } + } + // we need to refetch the projectile, so the effect queue is created + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID()); + break; + case WSTC_RANDOMIZE: + count = area->GetActorCount(false); + newact = area->GetActor(core->Roll(1,count,-1), false); + if (count > 1 && newact == caster) { + while (newact == caster) { + newact = area->GetActor(core->Roll(1,count,-1), false); + } + } + if (tgt) { + LastTarget = newact->GetGlobalID(); + LastTargetPos = newact->Pos; + } else { + // no better idea; I wonder if the original randomized point targets at all + LastTargetPos = newact->Pos; + } + + // make it also work for self-targetting spells: + // change the payload or this was all in vain + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = FX_TARGET_PRESET; + } + } + // we need to fetch the projectile, so the effect queue is created + // (skipped above) + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID()); + break; + default: //0 - do nothing + break; + } + + // apply the saving throw mod + if (caster->wildSurgeMods.saving_throw_mod) { + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + seh->features[i].SavingThrowBonus += caster->wildSurgeMods.saving_throw_mod; + } + } + + // change the projectile + if (caster->wildSurgeMods.projectile_id) { + spl->ext_headers[SpellHeader].ProjectileAnimation = caster->wildSurgeMods.projectile_id; + // make it also work for self-targetting spells: + // change the payload or this was all in vain + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = FX_TARGET_PRESET; + } + } + // we need to refetch the projectile, so the new one is used + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID()); + } + } + if (tgt) { area->AddProjectile(pro, origin, LastTarget, fake); } else { @@ -651,9 +774,8 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool if(LastTarget) { if (target && (Type==ST_ACTOR) ) { - Actor *me = (Actor *) this; target->LastSpellOnMe = spellnum; - target->LastCasterOnMe = me->GetGlobalID(); + target->LastCasterOnMe = caster->GetGlobalID(); // don't cure invisibility if this is a self targetting invisibility spell // like shadow door //can't check GetEffectBlock, since it doesn't construct the queue for selftargetting spells @@ -668,11 +790,11 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool if (invis && spl->GetExtHeader(SpellHeader)->Target == TARGET_SELF) { //pass } else { - me->CureInvisibility(); + caster->CureInvisibility(); } // sanctuary ends with all hostile actions or when the caster targets someone else if (target != this || spl->Flags & SF_HOSTILE) { - me->CureSanctuary(); + caster->CureSanctuary(); } } } @@ -684,10 +806,12 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool } -void Scriptable::CastSpellPointEnd( const ieResRef SpellResRef ) +void Scriptable::CastSpellPointEnd() { + Actor *caster = NULL; if (Type == ST_ACTOR) { - ((Actor *) this)->SetStance(IE_ANI_CONJURE); + caster = ((Actor *) this); + caster->SetStance(IE_ANI_CONJURE); } if (SpellHeader == -1) { @@ -700,17 +824,27 @@ void Scriptable::CastSpellPointEnd( const ieResRef SpellResRef ) return; } + if (!SpellResRef) { + return; + } + CreateProjectile(SpellResRef, 0, false); SpellHeader = -1; + SpellResRef[0] = 0; LastTarget = 0; LastTargetPos.empty(); + if (caster) { + memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods)); + } } -void Scriptable::CastSpellEnd( const ieResRef SpellResRef ) +void Scriptable::CastSpellEnd() { + Actor *caster = NULL; if (Type == ST_ACTOR) { - ((Actor *) this)->SetStance(IE_ANI_CONJURE); + caster = ((Actor *) this); + caster->SetStance(IE_ANI_CONJURE); } if (SpellHeader == -1) { @@ -721,68 +855,181 @@ void Scriptable::CastSpellEnd( const ieResRef SpellResRef ) SpellHeader = -1; return; } + if (!SpellResRef) { + return; + } + //if the projectile doesn't need to follow the target, then use the target position CreateProjectile(SpellResRef, LastTarget, GetSpellDistance(SpellResRef, this)==0xffffffff); SpellHeader = -1; + SpellResRef[0] = 0; LastTarget = 0; LastTargetPos.empty(); + if (caster) { + memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods)); + } +} + +// check for input sanity and good casting conditions +int Scriptable::CanCast(const ieResRef SpellResRef) { + Spell* spl = gamedata->GetSpell(SpellResRef); + if (!spl) { + SpellHeader = -1; + printMessage("Scriptable", "Spell not found, aborting cast!\n", LIGHT_RED); + return 0; + } + + // check for area dead magic + // tob AR3004 is a dead magic area, but using a script with personal dead magic + if (area->GetInternalFlag()&AF_DEADMAGIC) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this); + return 0; + } + + // various individual checks + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + + // check for silence + // only a handful of spells don't have a verbal component - + // the original hardcoded vocalize and a few more + // we (also) ignore nonmagic spells + if (actor->Modified[IE_STATE_ID] & STATE_SILENCED) { + if (!(core->GetSpecialSpell(spl->Name)&SP_SILENCE) && !(spl->Flags&SF_HLA)) { + printMessage("Scriptable", "Tried to cast while silenced!\n", YELLOW); + return 0; + } + } + + // check for personal dead magic + if (actor->Modified[IE_DEADMAGIC]) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this); + return 0; + } + + // check for miscast magic and similar + ieDword roll = actor->LuckyRoll(1, 100, 0, 0); + bool failed = false; + switch(spl->SpellType) + { + case IE_SPL_PRIEST: + if (actor->Modified[IE_SPELLFAILUREPRIEST] >= roll) { + failed = true; + } + break; + case IE_SPL_WIZARD: + if (actor->Modified[IE_SPELLFAILUREMAGE] >= roll) { + failed = true; + } + break; + case IE_SPL_INNATE: + if (actor->Modified[IE_SPELLFAILUREINNATE] >= roll) { + failed = true; + } + break; + } + if (failed) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_MISCASTMAGIC, 0xffffff, this); + return 0; + } + } + + return 1; } //set target as point //if spell needs to be depleted, do it //if spell is illegal stop casting -int Scriptable::CastSpellPoint( const ieResRef SpellResRef, const Point &target, bool deplete, bool instant ) +int Scriptable::CastSpellPoint( ieResRef &SpellRef, const Point &target, bool deplete, bool instant ) { LastTarget = 0; LastTargetPos.empty(); if (Type == ST_ACTOR) { Actor *actor = (Actor *) this; - if (actor->HandleCastingStance(SpellResRef,deplete) ) { + if (actor->HandleCastingStance(SpellRef,deplete) ) { + printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED); return -1; } } + if(!CanCast(SpellRef)) { + SpellResRef[0] = 0; + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + actor->SetStance(IE_ANI_READY); + } + return -1; + } + + if (!SpellResRef[0]) { + SetSpellResRef(SpellRef); + } + LastTargetPos = target; - return SpellCast(SpellResRef, instant); + + if(!CheckWildSurge()) { + return -1; + } + return SpellCast(instant); } //set target as actor (if target isn't actor, use its position) //if spell needs to be depleted, do it //if spell is illegal stop casting -int Scriptable::CastSpell( const ieResRef SpellResRef, Scriptable* target, bool deplete, bool instant ) +int Scriptable::CastSpell( ieResRef &SpellRef, Scriptable* target, bool deplete, bool instant ) { LastTarget = 0; LastTargetPos.empty(); if (Type == ST_ACTOR) { Actor *actor = (Actor *) this; - if (actor->HandleCastingStance(SpellResRef,deplete) ) { + if (actor->HandleCastingStance(SpellRef,deplete) ) { + printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED); return -1; } } + // FIXME: fishy if (!target) target = this; + if(!CanCast(SpellRef)) { + SpellResRef[0] = 0; + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + actor->SetStance(IE_ANI_READY); + } + return -1; + } + + if (!SpellResRef[0]) { + SetSpellResRef(SpellRef); + } + LastTargetPos = target->Pos; if (target->Type==ST_ACTOR) { LastTarget = target->GetGlobalID(); } - return SpellCast(SpellResRef, instant); -} -//start spellcasting (common part) -int Scriptable::SpellCast(const ieResRef SpellResRef, bool instant) -{ - Spell* spl = gamedata->GetSpell( SpellResRef ); - if (!spl) { - SpellHeader = -1; + if(!CheckWildSurge()) { return -1; } + return SpellCast(instant); +} + +static EffectRef fx_force_surge_modifier_ref={"ForceSurgeModifier",NULL,-1}; + +//start spellcasting (common part) +int Scriptable::SpellCast(bool instant) +{ + Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here + Actor *actor = NULL; if (Type == ST_ACTOR) { - Actor *actor = (Actor *) this; + actor = (Actor *) this; + //The ext. index is here to calculate the casting time - int level = actor->GetXPLevel(true); - //Add casting level bonus/penalty - from stats and LVLMODWM.2da - level += actor->CastingLevelBonus(level, spl->SpellType); + int level = actor->GetCasterLevel(spl->SpellType); SpellHeader = spl->GetHeaderIndexFromLevel(level); } else { SpellHeader = 0; @@ -791,9 +1038,9 @@ int Scriptable::SpellCast(const ieResRef SpellResRef, bool instant) SPLExtHeader *header = spl->GetExtHeader(SpellHeader); int casting_time = (int)header->CastingTime; // how does this work for non-actors exactly? - if (Type == ST_ACTOR) { + if (actor) { // The mental speed effect can shorten or lengthen the casting time. - casting_time -= (int)((Actor *) this)->Modified[IE_MENTALSPEED]; + casting_time -= (int)actor->Modified[IE_MENTALSPEED]; if (casting_time < 0) casting_time = 0; } // this is a guess which seems approximately right so far @@ -801,10 +1048,8 @@ int Scriptable::SpellCast(const ieResRef SpellResRef, bool instant) if (instant) { duration = 0; } - - //cfb - if (Type == ST_ACTOR) { - Actor *actor = (Actor *) this; + if (actor) { + //cfb EffectQueue *fxqueue = spl->GetEffectBlock(this, this->Pos, -1); fxqueue->SetOwner(actor); if (!actor->Modified[IE_AVATARREMOVAL]) { @@ -812,12 +1057,177 @@ int Scriptable::SpellCast(const ieResRef SpellResRef, bool instant) } fxqueue->AddAllEffects(actor, actor->Pos); delete fxqueue; + actor->WMLevelMod = 0; + if (actor->Modified[IE_FORCESURGE] == 1) { + // affects only the next spell cast, but since the timing is permanent, + // we have to remove it manually + actor->fxqueue.RemoveAllEffectsWithParam(fx_force_surge_modifier_ref, 1); + } } gamedata->FreeSpell(spl, SpellResRef, false); return duration; } +// Anyone with some wildness has 5% chance of getting a wild surge when casting, +// but most innates are excluded, due to being nonmagic. +// A d100 roll is made, some stat boni are added, then either: +// 1. the spell is cast normally (score of 100 or more) +// 2. one or more wild surges happen and something else is cast +// 2.1. this can loop, since some surges cause rerolls +int Scriptable::CheckWildSurge() +{ + if (Type != ST_ACTOR || core->HasFeature(GF_3ED_RULES)) { + return 1; + } + Actor *caster = (Actor *) this; + + int roll = core->Roll(1, 100, 0); + if ((roll <= 5 && caster->Modified[IE_SURGEMOD]) || caster->Modified[IE_FORCESURGE]) { + Spell *spl = gamedata->GetSpell( SpellResRef ); // this was checked before we got here + // ignore non-magic "spells" + if (!(spl->Flags&SF_HLA)) { + int check = roll + caster->GetCasterLevel(spl->SpellType) + caster->Modified[IE_SURGEMOD]; + // hundred or more means a normal cast + if (check < 100) { + // display feedback: Wild Surge: bla bla + char text[200]; + snprintf(text, 200, "%s %s", core->GetString(displaymsg->GetStringReference(STR_WILDSURGE), 0), core->GetString(core->SurgeSpells[check-1].message, 0)); + displaymsg->DisplayStringName(text, 0xffffff, this); + + // lookup the spell in the "check" row of wildmag.2da + ieResRef surgeSpellRef; + memset(surgeSpellRef, 0, sizeof(surgeSpellRef)); + strncpy(surgeSpellRef, core->SurgeSpells[check-1].spell, 8); + + Spell *surgeSpell = gamedata->GetSpell(surgeSpellRef); + if (!surgeSpell) { + // handle the hardcoded cases - they'll also fail here + if (!HandleHardcodedSurge(surgeSpellRef, spl, caster)) { + return 0; + } + } else { + // finally change the spell + // the hardcoded bunch does it on its own when needed + strncpy(SpellResRef, surgeSpellRef, 8); + } + } + } + } + + return 1; +} + +bool Scriptable::HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor *caster) +{ + // format: ID or ID.param1 or +SPELLREF + int types = caster->spellbook.GetTypes(); + int lvl = spl->SpellLevel-1; + int count, i, tmp, tmp2, tmp3; + Scriptable *target = NULL; + Point targetpos(-1, -1); + ieResRef newspl; + switch (surgeSpellRef[0]) { + case '+': // cast normally, but also cast SPELLREF first + core->ApplySpell(surgeSpellRef+1, caster, caster, caster->GetCasterLevel(spl->SpellType)); + break; + case '0': // cast spell param1 times + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.num_castings = count; + break; + case '1': // change projectile (id) to param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.projectile_id = count; + break; + case '2': // also target target type param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.target_type = count; + caster->wildSurgeMods.target_change_type = WSTC_ADDTYPE; + break; + case '3': // (wild surge) roll param1 more times + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + // force surge and then cast + // force the surge roll to be < 100, so we cast a spell from the surge table + tmp = caster->Modified[IE_FORCESURGE]; + tmp2 = caster->Modified[IE_SURGEMOD]; + tmp3 = caster->WMLevelMod; // also save caster level; the original didn't reroll the bonus + caster->Modified[IE_FORCESURGE] = 7; + caster->Modified[IE_SURGEMOD] = - caster->GetCasterLevel(spl->SpellType); // nulify the bonus + if (LastTarget) { + target = area->GetActorByGlobalID(LastTarget); + if (!target) { + target = core->GetGame()->GetActorByGlobalID(LastTarget); + } + } + if (!LastTargetPos.isempty()) { + targetpos = LastTargetPos; + } else if (target) { + targetpos = target->Pos; + } + for (i=0; iCastSpell(SpellResRef, target, false, true); + strncpy(newspl, SpellResRef, 8); + caster->WMLevelMod = tmp3; + caster->CastSpellEnd(); + } else { + caster->CastSpellPoint(SpellResRef, targetpos, false, true); + strncpy(newspl, SpellResRef, 8); + caster->WMLevelMod = tmp3; + caster->CastSpellPointEnd(); + } + // reset the ref, since CastSpell*End destroyed it + strncpy(SpellResRef, newspl, 8); + } + caster->Modified[IE_FORCESURGE] = tmp; + caster->Modified[IE_SURGEMOD] = tmp2; + break; + case '4': // change the target type to param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.target_type = count; + caster->wildSurgeMods.target_change_type = WSTC_SETTYPE; + break; + case '5': // change the target to a random actor + caster->wildSurgeMods.target_change_type = WSTC_RANDOMIZE; + break; + case '6': // change saving throw (+param1) + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.saving_throw_mod = count; + break; + case '7': // random spell of the same level (FIXME: make an effect out of this?) + // change this if we ever want the surges to respect the original type + for (i=0; ispellbook.GetKnownSpellsCount(i, lvl); + if (!spellCount) continue; + int id = core->Roll(1, spellCount, -1); + CREKnownSpell *ck = caster->spellbook.GetKnownSpell(i, lvl, id); + if (ck) { + strncpy(SpellResRef, ck->SpellResRef, 8); + break; + } + } + break; + case '8': // set projectile speed to param1 % + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.projectile_speed_mod = count; + break; + default: + SpellHeader = -1; + SpellResRef[0] = 0; + printMessage("Scriptable", "New spell not found, aborting cast mid-surge!\n", LIGHT_RED); + caster->SetStance(IE_ANI_READY); + return false; + } + return true; +} + bool Scriptable::TimerActive(ieDword ID) { if (ID>=MAX_TIMER) { @@ -989,7 +1399,7 @@ void Selectable::SetCircle(int circlesize, const Color &color, Sprite2D* normal_ int Selectable::WantDither() { //if dithering is disabled globally, don't do it - if (core->FogOfWar&4) { + if (core->FogOfWar&FOG_DITHERSPRITES) { return 0; } //if actor is dead, dither it if polygon wants @@ -1583,8 +1993,8 @@ Door::~Door(void) void Door::ImpedeBlocks(int count, Point *points, unsigned char value) { for(int i = 0;iSearchMap->GetAt( points[i].x, points[i].y ) & PATH_MAP_NOTDOOR; - area->SearchMap->SetAt( points[i].x, points[i].y, (tmp|value) ); + unsigned char tmp = area->GetInternalSearchMap(points[i].x, points[i].y) & PATH_MAP_NOTDOOR; + area->SetInternalSearchMap(points[i].x, points[i].y, tmp|value); } } @@ -1708,7 +2118,7 @@ bool Door::BlockedOpen(int Open, int ForceOpen) Actor** ab; rgn.x = points[i].x*16; rgn.y = points[i].y*12; - unsigned char tmp = area->SearchMap->GetAt( points[i].x, points[i].y ) & PATH_MAP_ACTOR; + unsigned char tmp = area->GetInternalSearchMap(points[i].x, points[i].y) & PATH_MAP_ACTOR; if (tmp) { int ac = area->GetActorInRect(ab, rgn, false); while(ac--) { @@ -2040,10 +2450,7 @@ bool InfoPoint::TriggerTrap(int skill, ieDword ID) bool InfoPoint::Entered(Actor *actor) { if (outline->PointIn( actor->Pos ) ) { - //don't trigger again for this actor - if (!(actor->GetInternalFlag()&IF_INTRAP)) { - goto check; - } + goto check; } // why is this here? actors which aren't *in* a trap get IF_INTRAP // repeatedly unset, so this triggers again and again and again. @@ -2071,6 +2478,10 @@ check: return true; } + if (actor->GetInternalFlag()&IF_INTRAP) { + return false; + } + if (actor->InParty || (Flags&TRAP_NPC) ) { //no need to avoid a travel trigger diff --git a/project/jni/application/gemrb/src/core/Scriptable/ActorBlock.h b/project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.h similarity index 95% rename from project/jni/application/gemrb/src/core/Scriptable/ActorBlock.h rename to project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.h index b93713b95..72945e8db 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/ActorBlock.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/ActorBlock.h @@ -26,6 +26,7 @@ #include "CharAnimations.h" #include "Inventory.h" #include "PathFinder.h" +#include "Spell.h" // for HandleHardcodedSurge (repeat the spell lookup if this header is unwanted) #include "Sprite2D.h" #include "TileOverlay.h" #include "Variables.h" @@ -209,6 +210,7 @@ public: ieDword LastCasterSeen; //Last spellcaster seen Point LastTargetPos; int SpellHeader; + ieResRef SpellResRef; public: /** Gets the Dialog ResRef */ const char* GetDialog(void) const @@ -219,6 +221,7 @@ public: strnuprcpy(Dialog, resref, 8); } void SetScript(const ieResRef aScript, int idx, bool ai=false); + void SetSpellResRef(ieResRef resref); void SetWait(unsigned long time); unsigned long GetWait() const; void LeaveDialog(); @@ -260,12 +263,16 @@ public: void AddTrigger(ieDword *actorref); /* re/draws overhead text on the map screen */ void DrawOverheadText(const Region &screen); + /* check if casting is allowed at all */ + int CanCast(const ieResRef SpellResRef); + /* check for and trigger a wild surge */ + int CheckWildSurge(); /* actor/scriptable casts spell */ - int CastSpellPoint( const ieResRef SpellResRef, const Point &Target, bool deplete, bool instant = false ); - int CastSpell( const ieResRef SpellResRef, Scriptable* Target, bool deplete, bool instant = false ); + int CastSpellPoint( ieResRef &SpellRef, const Point &Target, bool deplete, bool instant = false ); + int CastSpell( ieResRef &SpellRef, Scriptable* Target, bool deplete, bool instant = false ); /* spellcasting finished */ - void CastSpellPointEnd( const ieResRef SpellResRef); - void CastSpellEnd( const ieResRef SpellResRef); + void CastSpellPointEnd(); + void CastSpellEnd(); ieDword GetGlobalID() const { return globalID; } /** timer functions (numeric ID, not saved) */ bool TimerActive(ieDword ID); @@ -274,9 +281,11 @@ public: virtual char* GetName(int /*which*/) const { return NULL; } private: /* used internally to handle start of spellcasting */ - int SpellCast(const ieResRef SpellResRef, bool instant); + int SpellCast(bool instant); /* also part of the spellcasting process, creating the projectile */ void CreateProjectile(const ieResRef SpellResRef, ieDword tgt, bool fake); + /* do some magic for the wierd/awesome wild surges */ + bool HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor *caster); }; class GEM_EXPORT Selectable : public Scriptable { diff --git a/project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.cpp similarity index 89% rename from project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.cpp rename to project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.cpp index a17359b6a..32338e52d 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.cpp @@ -151,22 +151,6 @@ void PCStatsStruct::InitQuickSlot(unsigned int which, int slot, int headerindex) } } -/* this function is obsolete, use initquickslot with slot=-1 -void PCStatsStruct::SetSlotIndex(unsigned int which, ieWord headerindex) -{ - //this is not correct, not the slot, but a separate headerindex should be here - switch(which) { - case ACT_QSLOT1: QuickItemHeaders[0]=headerindex; return; - case ACT_QSLOT2: QuickItemHeaders[1]=headerindex; return; - case ACT_QSLOT3: QuickItemHeaders[2]=headerindex; return; - case ACT_QSLOT4: QuickItemHeaders[3]=headerindex; return; - case ACT_QSLOT5: QuickItemHeaders[4]=headerindex; return; - } - ///it shouldn't reach this point - abort(); -} -*/ - //returns both the inventory slot and the header index associated to a quickslot void PCStatsStruct::GetSlotAndIndex(unsigned int which, ieWord &slot, ieWord &headerindex) { diff --git a/project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.h b/project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.h similarity index 97% rename from project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.h rename to project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.h index 2ebd877df..f081f585e 100644 --- a/project/jni/application/gemrb/src/core/Scriptable/PCStatStruct.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/PCStatStruct.h @@ -88,6 +88,7 @@ public: ieWord FavouriteWeaponsCount[MAX_FAVOURITES]; ieResRef SoundSet; char SoundFolder[SOUNDFOLDERSIZE]; + ieDword ExtraSettings[16]; //iwd2 - expertise, hamstring, arterial strike, etc ieResRef QuickSpells[MAX_QSLOTS]; //iwd2 uses 9, others use only 3 ieWord QuickWeaponSlots[MAX_QUICKWEAPONSLOT]; //iwd2 uses 8, others use only 4 ieWord QuickWeaponHeaders[MAX_QUICKWEAPONSLOT]; diff --git a/project/jni/application/gemrb/src/core/ScriptedAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/ScriptedAnimation.cpp rename to project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp diff --git a/project/jni/application/gemrb/src/core/ScriptedAnimation.h b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h similarity index 100% rename from project/jni/application/gemrb/src/core/ScriptedAnimation.h rename to project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h diff --git a/project/jni/application/gemrb/src/core/SoundMgr.cpp b/project/jni/application/gemrb/gemrb/core/SoundMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SoundMgr.cpp rename to project/jni/application/gemrb/gemrb/core/SoundMgr.cpp diff --git a/project/jni/application/gemrb/src/core/SoundMgr.h b/project/jni/application/gemrb/gemrb/core/SoundMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/SoundMgr.h rename to project/jni/application/gemrb/gemrb/core/SoundMgr.h diff --git a/project/jni/application/gemrb/src/core/Spell.cpp b/project/jni/application/gemrb/gemrb/core/Spell.cpp similarity index 90% rename from project/jni/application/gemrb/src/core/Spell.cpp rename to project/jni/application/gemrb/gemrb/core/Spell.cpp index e35820e8f..c7eec2698 100644 --- a/project/jni/application/gemrb/src/core/Spell.cpp +++ b/project/jni/application/gemrb/gemrb/core/Spell.cpp @@ -155,6 +155,17 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block fx->InventorySlot = 0xffff; //the hostile flag is used to determine if this was an attack fx->SourceFlags = Flags; + + // apply the stat-based spell duration modifier + if (self->Type == ST_ACTOR) { + Actor *caster = (Actor *) self; + if (caster->Modified[IE_SPELLDURATIONMODMAGE] && SpellType == IE_SPL_WIZARD) { + fx->Duration = (fx->Duration * caster->Modified[IE_SPELLDURATIONMODMAGE]) / 100; + } else if (caster->Modified[IE_SPELLDURATIONMODPRIEST] && SpellType == IE_SPL_PRIEST) { + fx->Duration = (fx->Duration * caster->Modified[IE_SPELLDURATIONMODPRIEST]) / 100; + } + } + if (fx->Target != FX_TARGET_SELF) { fx->Projectile = pro; fxqueue->AddEffect( fx ); @@ -203,24 +214,7 @@ unsigned int Spell::GetCastingDistance(Scriptable *Sender) const Actor *actor = NULL; if (Sender && Sender->Type==ST_ACTOR) { actor = (Actor *) Sender; - } - - if (actor) { - if (SpellType==IE_SPL_WIZARD) { - level = actor->GetMageLevel(); - if (!level) level = actor->GetSorcererLevel(); - if (!level) level = actor->GetBardLevel(); - if (!level) level = actor->GetStat(IE_LEVEL); - level+=actor->GetStat(IE_CASTINGLEVELBONUSMAGE); - } - else if (SpellType==IE_SPL_PRIEST) { - level = actor->GetClericLevel(); - if (!level) level = actor->GetDruidLevel(); - if (!level) level = actor->GetPaladinLevel(); - if (!level) level = actor->GetRangerLevel(); - if (!level) level = actor->GetStat(IE_LEVEL); - level += actor->GetStat(IE_CASTINGLEVELBONUSCLERIC); - } + level = actor->GetCasterLevel(SpellType); } if (level<1) { diff --git a/project/jni/application/gemrb/src/core/Spell.h b/project/jni/application/gemrb/gemrb/core/Spell.h similarity index 100% rename from project/jni/application/gemrb/src/core/Spell.h rename to project/jni/application/gemrb/gemrb/core/Spell.h diff --git a/project/jni/application/gemrb/src/core/SpellMgr.cpp b/project/jni/application/gemrb/gemrb/core/SpellMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SpellMgr.cpp rename to project/jni/application/gemrb/gemrb/core/SpellMgr.cpp diff --git a/project/jni/application/gemrb/src/core/SpellMgr.h b/project/jni/application/gemrb/gemrb/core/SpellMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/SpellMgr.h rename to project/jni/application/gemrb/gemrb/core/SpellMgr.h diff --git a/project/jni/application/gemrb/src/core/Spellbook.cpp b/project/jni/application/gemrb/gemrb/core/Spellbook.cpp similarity index 92% rename from project/jni/application/gemrb/src/core/Spellbook.cpp rename to project/jni/application/gemrb/gemrb/core/Spellbook.cpp index 1a1c64b93..b910faf67 100644 --- a/project/jni/application/gemrb/src/core/Spellbook.cpp +++ b/project/jni/application/gemrb/gemrb/core/Spellbook.cpp @@ -891,6 +891,80 @@ SpellExtHeader *Spellbook::FindSpellInfo(unsigned int level, unsigned int type, return NULL; } +void Spellbook::AddSpellInfo(unsigned int sm_level, unsigned int sm_type, const ieResRef spellname, unsigned int idx) +{ + Spell *spl = gamedata->GetSpell(spellname); + if (!spl) + return; + if (spl->ExtHeaderCount<1) + return; + + ieDword level = 0; + SpellExtHeader *seh = FindSpellInfo(sm_level, sm_type, spellname); + if (seh) { + seh->count++; + return; + } + + seh = new SpellExtHeader; + spellinfo.push_back( seh ); + + memcpy(seh->spellname, spellname, sizeof(ieResRef) ); + int ehc; + + for (ehc = 0; ehc < spl->ExtHeaderCount-1; ehc++) { + if (levelext_headers[ehc+1].RequiredLevel) { + break; + } + } + + SPLExtHeader *ext_header = spl->ext_headers+ehc; + seh->headerindex = ehc; + seh->level = sm_level; + seh->type = sm_type; + seh->slot = idx; + seh->count = 1; + seh->SpellForm = ext_header->SpellForm; + memcpy(seh->MemorisedIcon, ext_header->MemorisedIcon,sizeof(ieResRef) ); + seh->Target = ext_header->Target; + seh->TargetNumber = ext_header->TargetNumber; + seh->Range = ext_header->Range; + seh->Projectile = ext_header->ProjectileAnimation; + seh->CastingTime = (ieWord) ext_header->CastingTime; + seh->strref = spl->SpellName; + gamedata->FreeSpell(spl, spellname, false); +} + +void Spellbook::SetCustomSpellInfo(ieResRef *data, ieResRef spell, int type) +{ + ClearSpellInfo(); + if (data) { + for(int i = 0; iknown_spells.size(); k++) { + CREKnownSpell* slot = sm->known_spells[k]; + if (!slot) + continue; + //skip the spell itself + if (!strnicmp(slot->SpellResRef, spell, sizeof(ieResRef))) + continue; + AddSpellInfo(sm->Level, sm->Type, slot->SpellResRef, -1); + } + } + } + } +} + // grouping the castable spells void Spellbook::GenerateSpellInfo() { @@ -905,41 +979,7 @@ void Spellbook::GenerateSpellInfo() continue; if (!slot->Flags) continue; - Spell *spl = gamedata->GetSpell(slot->SpellResRef); - if (!spl) - continue; - ieDword level = 0; - SpellExtHeader *seh = FindSpellInfo(sm->Level, sm->Type, slot->SpellResRef); - if (seh) { - seh->count++; - continue; - } - seh = new SpellExtHeader; - spellinfo.push_back( seh ); - - memcpy(seh->spellname, slot->SpellResRef, sizeof(ieResRef) ); - int ehc; - - for (ehc = 0; ehc < spl->ExtHeaderCount-1; ehc++) { - if (levelext_headers[ehc+1].RequiredLevel) { - break; - } - } - SPLExtHeader *ext_header = spl->ext_headers+ehc; - seh->headerindex = ehc; - seh->level = sm->Level; - seh->type = sm->Type; - seh->slot = k; - seh->count = 1; - seh->SpellForm = ext_header->SpellForm; - memcpy(seh->MemorisedIcon, ext_header->MemorisedIcon,sizeof(ieResRef) ); - seh->Target = ext_header->Target; - seh->TargetNumber = ext_header->TargetNumber; - seh->Range = ext_header->Range; - seh->Projectile = ext_header->ProjectileAnimation; - seh->CastingTime = (ieWord) ext_header->CastingTime; - seh->strref = spl->SpellName; - gamedata->FreeSpell(spl, slot->SpellResRef, false); + AddSpellInfo(sm->Level, sm->Type, slot->SpellResRef, k); } } } @@ -953,12 +993,6 @@ void Spellbook::dump() for (int i = 0; i < NUM_BOOK_TYPES; i++) { for (unsigned int j = 0; j < spells[i].size(); j++) { CRESpellMemorization* sm = spells[i][j]; - //if (!sm || !sm->Number) continue; - //if (!sm) continue; - - //Never ever use field length qualifiers it is not portable, if you need to convert, convert to compatible values, anyway we don't need this! - //printf ( "type: %d: L: %d; N1: %d; N2: %d; T: %d; KC: %d; MC: %d\n", i, - // sm->Level, sm->Number, sm->Number2, sm->Type, (int) sm->known_spells.size(), (int) sm->memorized_spells.size() ); if (sm->known_spells.size()) printf( " Known spells:\n" ); diff --git a/project/jni/application/gemrb/src/core/Spellbook.h b/project/jni/application/gemrb/gemrb/core/Spellbook.h similarity index 96% rename from project/jni/application/gemrb/src/core/Spellbook.h rename to project/jni/application/gemrb/gemrb/core/Spellbook.h index 3a65b775f..fb24516d7 100644 --- a/project/jni/application/gemrb/src/core/Spellbook.h +++ b/project/jni/application/gemrb/gemrb/core/Spellbook.h @@ -138,10 +138,10 @@ private: bool DepleteSpell(CREMemorizedSpell* spl); /** Depletes a sorcerer type spellpage by one */ void DepleteLevel(CRESpellMemorization* sm); + /** Adds a single spell to the spell info list */ + void AddSpellInfo(unsigned int level, unsigned int type, const ieResRef name, unsigned int idx); /** regenerates the spellinfo list */ void GenerateSpellInfo(); - /** invalidates the spellinfo list */ - void ClearSpellInfo(); /** looks up the spellinfo list for an element */ SpellExtHeader *FindSpellInfo(unsigned int level, unsigned int type, const ieResRef name); /** removes all instances of a spell from a given page */ @@ -232,6 +232,12 @@ public: /** returns the number of distinct spells (generates spellinfo) */ unsigned int GetSpellInfoSize(int type); + /** generates a custom spellinfo list for fx_select_spell */ + void SetCustomSpellInfo(ieResRef *data, ieResRef spell, int type); + + /** invalidates the spellinfo list */ + void ClearSpellInfo(); + /** lists spells of a type */ bool GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count); /** Dumps spellbook to stdout for debugging */ diff --git a/project/jni/application/gemrb/src/core/Sprite2D.cpp b/project/jni/application/gemrb/gemrb/core/Sprite2D.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Sprite2D.cpp rename to project/jni/application/gemrb/gemrb/core/Sprite2D.cpp diff --git a/project/jni/application/gemrb/src/core/Sprite2D.h b/project/jni/application/gemrb/gemrb/core/Sprite2D.h similarity index 100% rename from project/jni/application/gemrb/src/core/Sprite2D.h rename to project/jni/application/gemrb/gemrb/core/Sprite2D.h diff --git a/project/jni/application/gemrb/src/core/SpriteCover.cpp b/project/jni/application/gemrb/gemrb/core/SpriteCover.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SpriteCover.cpp rename to project/jni/application/gemrb/gemrb/core/SpriteCover.cpp diff --git a/project/jni/application/gemrb/src/core/SpriteCover.h b/project/jni/application/gemrb/gemrb/core/SpriteCover.h similarity index 100% rename from project/jni/application/gemrb/src/core/SpriteCover.h rename to project/jni/application/gemrb/gemrb/core/SpriteCover.h diff --git a/project/jni/application/gemrb/src/core/Store.cpp b/project/jni/application/gemrb/gemrb/core/Store.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Store.cpp rename to project/jni/application/gemrb/gemrb/core/Store.cpp diff --git a/project/jni/application/gemrb/src/core/Store.h b/project/jni/application/gemrb/gemrb/core/Store.h similarity index 100% rename from project/jni/application/gemrb/src/core/Store.h rename to project/jni/application/gemrb/gemrb/core/Store.h diff --git a/project/jni/application/gemrb/src/core/StoreMgr.cpp b/project/jni/application/gemrb/gemrb/core/StoreMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/StoreMgr.cpp rename to project/jni/application/gemrb/gemrb/core/StoreMgr.cpp diff --git a/project/jni/application/gemrb/src/core/StoreMgr.h b/project/jni/application/gemrb/gemrb/core/StoreMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/StoreMgr.h rename to project/jni/application/gemrb/gemrb/core/StoreMgr.h diff --git a/project/jni/application/gemrb/src/core/StringMgr.cpp b/project/jni/application/gemrb/gemrb/core/StringMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/StringMgr.cpp rename to project/jni/application/gemrb/gemrb/core/StringMgr.cpp diff --git a/project/jni/application/gemrb/src/core/StringMgr.h b/project/jni/application/gemrb/gemrb/core/StringMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/StringMgr.h rename to project/jni/application/gemrb/gemrb/core/StringMgr.h diff --git a/project/jni/application/gemrb/src/core/SymbolMgr.cpp b/project/jni/application/gemrb/gemrb/core/SymbolMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/SymbolMgr.cpp rename to project/jni/application/gemrb/gemrb/core/SymbolMgr.cpp diff --git a/project/jni/application/gemrb/src/core/SymbolMgr.h b/project/jni/application/gemrb/gemrb/core/SymbolMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/SymbolMgr.h rename to project/jni/application/gemrb/gemrb/core/SymbolMgr.h diff --git a/project/jni/application/gemrb/src/core/System/CachedFileStream.cpp b/project/jni/application/gemrb/gemrb/core/System/CachedFileStream.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/System/CachedFileStream.cpp rename to project/jni/application/gemrb/gemrb/core/System/CachedFileStream.cpp diff --git a/project/jni/application/gemrb/src/core/System/CachedFileStream.h b/project/jni/application/gemrb/gemrb/core/System/CachedFileStream.h similarity index 100% rename from project/jni/application/gemrb/src/core/System/CachedFileStream.h rename to project/jni/application/gemrb/gemrb/core/System/CachedFileStream.h diff --git a/project/jni/application/gemrb/src/core/System/DataStream.cpp b/project/jni/application/gemrb/gemrb/core/System/DataStream.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/System/DataStream.cpp rename to project/jni/application/gemrb/gemrb/core/System/DataStream.cpp diff --git a/project/jni/application/gemrb/src/core/System/DataStream.h b/project/jni/application/gemrb/gemrb/core/System/DataStream.h similarity index 100% rename from project/jni/application/gemrb/src/core/System/DataStream.h rename to project/jni/application/gemrb/gemrb/core/System/DataStream.h diff --git a/project/jni/application/gemrb/src/core/System/FileStream.cpp b/project/jni/application/gemrb/gemrb/core/System/FileStream.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/System/FileStream.cpp rename to project/jni/application/gemrb/gemrb/core/System/FileStream.cpp diff --git a/project/jni/application/gemrb/src/core/System/FileStream.h b/project/jni/application/gemrb/gemrb/core/System/FileStream.h similarity index 100% rename from project/jni/application/gemrb/src/core/System/FileStream.h rename to project/jni/application/gemrb/gemrb/core/System/FileStream.h diff --git a/project/jni/application/gemrb/src/core/System/MemoryStream.cpp b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/System/MemoryStream.cpp rename to project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp diff --git a/project/jni/application/gemrb/src/core/System/MemoryStream.h b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.h similarity index 100% rename from project/jni/application/gemrb/src/core/System/MemoryStream.h rename to project/jni/application/gemrb/gemrb/core/System/MemoryStream.h diff --git a/project/jni/application/gemrb/src/core/System/VFS.cpp b/project/jni/application/gemrb/gemrb/core/System/VFS.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/System/VFS.cpp rename to project/jni/application/gemrb/gemrb/core/System/VFS.cpp diff --git a/project/jni/application/gemrb/src/core/System/VFS.h b/project/jni/application/gemrb/gemrb/core/System/VFS.h similarity index 100% rename from project/jni/application/gemrb/src/core/System/VFS.h rename to project/jni/application/gemrb/gemrb/core/System/VFS.h diff --git a/project/jni/application/gemrb/src/core/System/swab.c b/project/jni/application/gemrb/gemrb/core/System/swab.c similarity index 100% rename from project/jni/application/gemrb/src/core/System/swab.c rename to project/jni/application/gemrb/gemrb/core/System/swab.c diff --git a/project/jni/application/gemrb/src/core/System/swab.h b/project/jni/application/gemrb/gemrb/core/System/swab.h similarity index 99% rename from project/jni/application/gemrb/src/core/System/swab.h rename to project/jni/application/gemrb/gemrb/core/System/swab.h index 39dfdb55a..8788ad7b9 100644 --- a/project/jni/application/gemrb/src/core/System/swab.h +++ b/project/jni/application/gemrb/gemrb/core/System/swab.h @@ -25,7 +25,7 @@ extern "C" { #ifndef _SSIZE_T_DEFINED_ # define _SSIZE_T_DEFINED_ typedef long int ssize_t; -#endif +#endif void swab(const void *bfrom, void *bto, ssize_t n); diff --git a/project/jni/application/gemrb/src/core/TableMgr.cpp b/project/jni/application/gemrb/gemrb/core/TableMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/TableMgr.cpp rename to project/jni/application/gemrb/gemrb/core/TableMgr.cpp diff --git a/project/jni/application/gemrb/src/core/TableMgr.h b/project/jni/application/gemrb/gemrb/core/TableMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/TableMgr.h rename to project/jni/application/gemrb/gemrb/core/TableMgr.h diff --git a/project/jni/application/gemrb/src/core/Tile.cpp b/project/jni/application/gemrb/gemrb/core/Tile.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Tile.cpp rename to project/jni/application/gemrb/gemrb/core/Tile.cpp diff --git a/project/jni/application/gemrb/src/core/Tile.h b/project/jni/application/gemrb/gemrb/core/Tile.h similarity index 100% rename from project/jni/application/gemrb/src/core/Tile.h rename to project/jni/application/gemrb/gemrb/core/Tile.h diff --git a/project/jni/application/gemrb/src/core/TileMap.cpp b/project/jni/application/gemrb/gemrb/core/TileMap.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/TileMap.cpp rename to project/jni/application/gemrb/gemrb/core/TileMap.cpp diff --git a/project/jni/application/gemrb/src/core/TileMap.h b/project/jni/application/gemrb/gemrb/core/TileMap.h similarity index 100% rename from project/jni/application/gemrb/src/core/TileMap.h rename to project/jni/application/gemrb/gemrb/core/TileMap.h diff --git a/project/jni/application/gemrb/src/core/TileMapMgr.cpp b/project/jni/application/gemrb/gemrb/core/TileMapMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/TileMapMgr.cpp rename to project/jni/application/gemrb/gemrb/core/TileMapMgr.cpp diff --git a/project/jni/application/gemrb/src/core/TileMapMgr.h b/project/jni/application/gemrb/gemrb/core/TileMapMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/TileMapMgr.h rename to project/jni/application/gemrb/gemrb/core/TileMapMgr.h diff --git a/project/jni/application/gemrb/src/core/TileOverlay.cpp b/project/jni/application/gemrb/gemrb/core/TileOverlay.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/TileOverlay.cpp rename to project/jni/application/gemrb/gemrb/core/TileOverlay.cpp diff --git a/project/jni/application/gemrb/src/core/TileOverlay.h b/project/jni/application/gemrb/gemrb/core/TileOverlay.h similarity index 100% rename from project/jni/application/gemrb/src/core/TileOverlay.h rename to project/jni/application/gemrb/gemrb/core/TileOverlay.h diff --git a/project/jni/application/gemrb/src/core/TileSetMgr.cpp b/project/jni/application/gemrb/gemrb/core/TileSetMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/TileSetMgr.cpp rename to project/jni/application/gemrb/gemrb/core/TileSetMgr.cpp diff --git a/project/jni/application/gemrb/src/core/TileSetMgr.h b/project/jni/application/gemrb/gemrb/core/TileSetMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/TileSetMgr.h rename to project/jni/application/gemrb/gemrb/core/TileSetMgr.h diff --git a/project/jni/application/gemrb/src/core/TypeID.h b/project/jni/application/gemrb/gemrb/core/TypeID.h similarity index 100% rename from project/jni/application/gemrb/src/core/TypeID.h rename to project/jni/application/gemrb/gemrb/core/TypeID.h diff --git a/project/jni/application/gemrb/src/core/Variables.cpp b/project/jni/application/gemrb/gemrb/core/Variables.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Variables.cpp rename to project/jni/application/gemrb/gemrb/core/Variables.cpp diff --git a/project/jni/application/gemrb/src/core/Variables.h b/project/jni/application/gemrb/gemrb/core/Variables.h similarity index 100% rename from project/jni/application/gemrb/src/core/Variables.h rename to project/jni/application/gemrb/gemrb/core/Variables.h diff --git a/project/jni/application/gemrb/src/core/Video.cpp b/project/jni/application/gemrb/gemrb/core/Video.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/Video.cpp rename to project/jni/application/gemrb/gemrb/core/Video.cpp diff --git a/project/jni/application/gemrb/src/core/Video.h b/project/jni/application/gemrb/gemrb/core/Video.h similarity index 100% rename from project/jni/application/gemrb/src/core/Video.h rename to project/jni/application/gemrb/gemrb/core/Video.h diff --git a/project/jni/application/gemrb/src/core/VideoMode.h b/project/jni/application/gemrb/gemrb/core/VideoMode.h similarity index 100% rename from project/jni/application/gemrb/src/core/VideoMode.h rename to project/jni/application/gemrb/gemrb/core/VideoMode.h diff --git a/project/jni/application/gemrb/src/core/WindowMgr.cpp b/project/jni/application/gemrb/gemrb/core/WindowMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/WindowMgr.cpp rename to project/jni/application/gemrb/gemrb/core/WindowMgr.cpp diff --git a/project/jni/application/gemrb/src/core/WindowMgr.h b/project/jni/application/gemrb/gemrb/core/WindowMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/WindowMgr.h rename to project/jni/application/gemrb/gemrb/core/WindowMgr.h diff --git a/project/jni/application/gemrb/src/core/WorldMap.cpp b/project/jni/application/gemrb/gemrb/core/WorldMap.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/WorldMap.cpp rename to project/jni/application/gemrb/gemrb/core/WorldMap.cpp diff --git a/project/jni/application/gemrb/src/core/WorldMap.h b/project/jni/application/gemrb/gemrb/core/WorldMap.h similarity index 100% rename from project/jni/application/gemrb/src/core/WorldMap.h rename to project/jni/application/gemrb/gemrb/core/WorldMap.h diff --git a/project/jni/application/gemrb/src/core/WorldMapMgr.cpp b/project/jni/application/gemrb/gemrb/core/WorldMapMgr.cpp similarity index 100% rename from project/jni/application/gemrb/src/core/WorldMapMgr.cpp rename to project/jni/application/gemrb/gemrb/core/WorldMapMgr.cpp diff --git a/project/jni/application/gemrb/src/core/WorldMapMgr.h b/project/jni/application/gemrb/gemrb/core/WorldMapMgr.h similarity index 100% rename from project/jni/application/gemrb/src/core/WorldMapMgr.h rename to project/jni/application/gemrb/gemrb/core/WorldMapMgr.h diff --git a/project/jni/application/gemrb/src/core/damages.h b/project/jni/application/gemrb/gemrb/core/damages.h similarity index 100% rename from project/jni/application/gemrb/src/core/damages.h rename to project/jni/application/gemrb/gemrb/core/damages.h diff --git a/project/jni/application/gemrb/src/includes/Makefile.am b/project/jni/application/gemrb/gemrb/includes/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/includes/Makefile.am rename to project/jni/application/gemrb/gemrb/includes/Makefile.am diff --git a/project/jni/application/gemrb/src/includes/RGBAColor.h b/project/jni/application/gemrb/gemrb/includes/RGBAColor.h similarity index 100% rename from project/jni/application/gemrb/src/includes/RGBAColor.h rename to project/jni/application/gemrb/gemrb/includes/RGBAColor.h diff --git a/project/jni/application/gemrb/src/includes/SClassID.h b/project/jni/application/gemrb/gemrb/includes/SClassID.h similarity index 100% rename from project/jni/application/gemrb/src/includes/SClassID.h rename to project/jni/application/gemrb/gemrb/includes/SClassID.h diff --git a/project/jni/application/gemrb/src/includes/defsounds.h b/project/jni/application/gemrb/gemrb/includes/defsounds.h similarity index 100% rename from project/jni/application/gemrb/src/includes/defsounds.h rename to project/jni/application/gemrb/gemrb/includes/defsounds.h diff --git a/project/jni/application/gemrb/src/includes/errors.h b/project/jni/application/gemrb/gemrb/includes/errors.h similarity index 100% rename from project/jni/application/gemrb/src/includes/errors.h rename to project/jni/application/gemrb/gemrb/includes/errors.h diff --git a/project/jni/application/gemrb/src/includes/exports.h b/project/jni/application/gemrb/gemrb/includes/exports.h similarity index 100% rename from project/jni/application/gemrb/src/includes/exports.h rename to project/jni/application/gemrb/gemrb/includes/exports.h diff --git a/project/jni/application/gemrb/src/includes/globals.h b/project/jni/application/gemrb/gemrb/includes/globals.h similarity index 98% rename from project/jni/application/gemrb/src/includes/globals.h rename to project/jni/application/gemrb/gemrb/includes/globals.h index 91ade29fd..e4ff5cfef 100644 --- a/project/jni/application/gemrb/src/includes/globals.h +++ b/project/jni/application/gemrb/gemrb/includes/globals.h @@ -146,9 +146,9 @@ #define GF_JOURNAL_HAS_SECTIONS 56 //bg2 #define GF_CASTING_SOUNDS 57 //all except pst and bg1 #define GF_CASTING_SOUNDS2 58 //bg2 - +#define GF_FORCE_AREA_SCRIPT 59 //how and iwd2 (maybe iwd1) //update this or bad things can happen -#define GF_COUNT 59 +#define GF_COUNT 60 //the number of item usage fields (used in CREItem and STOItem) #define CHARGE_COUNTERS 3 diff --git a/project/jni/application/gemrb/src/includes/ie_feats.h b/project/jni/application/gemrb/gemrb/includes/ie_feats.h similarity index 100% rename from project/jni/application/gemrb/src/includes/ie_feats.h rename to project/jni/application/gemrb/gemrb/includes/ie_feats.h diff --git a/project/jni/application/gemrb/src/includes/ie_stats.h b/project/jni/application/gemrb/gemrb/includes/ie_stats.h similarity index 96% rename from project/jni/application/gemrb/src/includes/ie_stats.h rename to project/jni/application/gemrb/gemrb/includes/ie_stats.h index 2404ec356..99e784bd7 100644 --- a/project/jni/application/gemrb/src/includes/ie_stats.h +++ b/project/jni/application/gemrb/gemrb/includes/ie_stats.h @@ -102,10 +102,10 @@ #define STATE_HELPLESS 0x00000020 #define STATE_FROZEN 0x00000040 #define STATE_PETRIFIED 0x00000080 -#define STATE_D3 0x00000100 +#define STATE_EXPLODING 0x00000100 #define STATE_PST_MIRROR 0x00000100 -#define STATE_D4 0x00000200 -#define STATE_D5 0x00000400 +#define STATE_FLAME 0x00000200 +#define STATE_ACID 0x00000400 #define STATE_DEAD 0x00000800 #define STATE_SILENCED 0x00001000 #define STATE_CHARMED 0x00002000 @@ -157,10 +157,21 @@ #define EXTSTATE_EYE_SPIRIT 0x00000100 #define EXTSTATE_EYE_FORT 0x00000200 #define EXTSTATE_EYE_STONE 0x00000400 +#define EXTSTATE_ANIMAL_RAGE 0x00000800 #define EXTSTATE_NO_HP 0x00001000 //disable hp info in berserk mode +#define EXTSTATE_BERSERK 0x00002000 #define EXTSTATE_NO_BACKSTAB 0x00004000 #define EXTSTATE_FLOATTEXTS 0x00008000 //weapon chatting (IWD) +#define EXTSTATE_UNSTUN 0x00010000 //receiving damage will unstun #define EXTSTATE_DEAF 0x00020000 +#define EXTSTATE_CHAOTICCMD 0x00040000 +#define EXTSTATE_MISCAST 0x00080000 +#define EXTSTATE_PAIN 0x00100000 +#define EXTSTATE_MALISON 0x00200000 +#define EXTSTATE_BLOODRAGE 0x00400000 +#define EXTSTATE_CATSGRACE 0x00800000 +#define EXTSTATE_MOLD 0x01000000 +#define EXTSTATE_SHROUD 0x02000000 #define EXTSTATE_NO_WAKEUP 0x80000000 //original HoW engine put this on top of eye_mind #define EXTSTATE_SEVEN_EYES 0x000007f0 diff --git a/project/jni/application/gemrb/src/includes/ie_types.h b/project/jni/application/gemrb/gemrb/includes/ie_types.h similarity index 100% rename from project/jni/application/gemrb/src/includes/ie_types.h rename to project/jni/application/gemrb/gemrb/includes/ie_types.h diff --git a/project/jni/application/gemrb/src/includes/iless.h b/project/jni/application/gemrb/gemrb/includes/iless.h similarity index 100% rename from project/jni/application/gemrb/src/includes/iless.h rename to project/jni/application/gemrb/gemrb/includes/iless.h diff --git a/project/jni/application/gemrb/src/includes/logging.h b/project/jni/application/gemrb/gemrb/includes/logging.h similarity index 100% rename from project/jni/application/gemrb/src/includes/logging.h rename to project/jni/application/gemrb/gemrb/includes/logging.h diff --git a/project/jni/application/gemrb/src/includes/opcode_params.h b/project/jni/application/gemrb/gemrb/includes/opcode_params.h similarity index 96% rename from project/jni/application/gemrb/src/includes/opcode_params.h rename to project/jni/application/gemrb/gemrb/includes/opcode_params.h index f20d72cf7..081dba684 100644 --- a/project/jni/application/gemrb/src/includes/opcode_params.h +++ b/project/jni/application/gemrb/gemrb/includes/opcode_params.h @@ -42,6 +42,13 @@ #define RPD_WIS 8 #define RPD_CHA 9 #define RPD_SLOW 10 +//HoW specific disease types +#define RPD_MOLD 11 +#define RPD_MOLD2 12 +//iwd2 specific disease types +#define RPD_CONTAGION 13 +#define RPD_PEST 14 +#define RPD_DOLOR 15 //appply spell on condition #define COND_GOTHIT 0 diff --git a/project/jni/application/gemrb/src/includes/operatorbool.h b/project/jni/application/gemrb/gemrb/includes/operatorbool.h similarity index 100% rename from project/jni/application/gemrb/src/includes/operatorbool.h rename to project/jni/application/gemrb/gemrb/includes/operatorbool.h diff --git a/project/jni/application/gemrb/src/includes/overlays.h b/project/jni/application/gemrb/gemrb/includes/overlays.h similarity index 100% rename from project/jni/application/gemrb/src/includes/overlays.h rename to project/jni/application/gemrb/gemrb/includes/overlays.h diff --git a/project/jni/application/gemrb/src/includes/plugindef.h b/project/jni/application/gemrb/gemrb/includes/plugindef.h similarity index 100% rename from project/jni/application/gemrb/src/includes/plugindef.h rename to project/jni/application/gemrb/gemrb/includes/plugindef.h diff --git a/project/jni/application/gemrb/src/includes/strrefs.h b/project/jni/application/gemrb/gemrb/includes/strrefs.h similarity index 75% rename from project/jni/application/gemrb/src/includes/strrefs.h rename to project/jni/application/gemrb/gemrb/includes/strrefs.h index 3764294bc..e960f71c7 100644 --- a/project/jni/application/gemrb/src/includes/strrefs.h +++ b/project/jni/application/gemrb/gemrb/includes/strrefs.h @@ -119,19 +119,19 @@ #define STR_LOCKPICK_FAILED 86 #define STR_STATIC_DISS 87 #define STR_LIGHTNING_DISS 88 -#define STR_UNUSABLEITEM 89 //item has no usable ability -#define STR_ITEMID 90 //item needs identify +#define STR_UNUSABLEITEM 89 //item has no usable ability +#define STR_ITEMID 90 //item needs identify #define STR_WRONGITEMTYPE 91 #define STR_ITEMEXCL 92 -#define STR_PICKPOCKET_DONE 93 //done -#define STR_PICKPOCKET_NONE 94 //no items to steal -#define STR_PICKPOCKET_FAIL 95 //failed, noticed -#define STR_PICKPOCKET_EVIL 96 //can't pick hostiles -#define STR_PICKPOCKET_ARMOR 97 //armor restriction -#define STR_USING_FEAT 98 -#define STR_STOPPED_FEAT 99 -#define STR_DISARM_DONE 100 //trap disarmed -#define STR_DISARM_FAIL 101 //trap not disarmed +#define STR_PICKPOCKET_DONE 93 //done +#define STR_PICKPOCKET_NONE 94 //no items to steal +#define STR_PICKPOCKET_FAIL 95 //failed, noticed +#define STR_PICKPOCKET_EVIL 96 //can't pick hostiles +#define STR_PICKPOCKET_ARMOR 97 //armor restriction +#define STR_USING_FEAT 98 +#define STR_STOPPED_FEAT 99 +#define STR_DISARM_DONE 100 //trap disarmed +#define STR_DISARM_FAIL 101 //trap not disarmed #define STR_DOORBASH_DONE 102 #define STR_DOORBASH_FAIL 103 #define STR_CONTBASH_DONE 104 @@ -158,40 +158,44 @@ #define STR_PST_HOUR 125 #define STR_PST_HOURS 126 #define STR_DAMAGE_IMMUNITY 127 -#define STR_DAMAGE1 128 -#define STR_DAMAGE2 129 -#define STR_DAMAGE3 130 -#define STR_DMG_POISON 131 -#define STR_DMG_MAGIC 132 -#define STR_DMG_MISSILE 133 -#define STR_DMG_SLASHING 134 -#define STR_DMG_PIERCING 135 -#define STR_DMG_CRUSHING 136 -#define STR_DMG_FIRE 137 -#define STR_DMG_ELECTRIC 138 -#define STR_DMG_COLD 139 -#define STR_DMG_ACID 140 -#define STR_DMG_OTHER 141 -#define STR_GOTQUESTXP 142 -#define STR_LEVELUP 143 +#define STR_DAMAGE1 128 +#define STR_DAMAGE2 129 +#define STR_DAMAGE3 130 +#define STR_DMG_POISON 131 +#define STR_DMG_MAGIC 132 +#define STR_DMG_MISSILE 133 +#define STR_DMG_SLASHING 134 +#define STR_DMG_PIERCING 135 +#define STR_DMG_CRUSHING 136 +#define STR_DMG_FIRE 137 +#define STR_DMG_ELECTRIC 138 +#define STR_DMG_COLD 139 +#define STR_DMG_ACID 140 +#define STR_DMG_OTHER 141 +#define STR_GOTQUESTXP 142 +#define STR_LEVELUP 143 #define STR_INVFULL_ITEMDROP 144 -#define STR_CONTDUP 145 -#define STR_CONTTRIG 146 -#define STR_CONTFAIL 147 -#define STR_SEQDUP 148 -#define STR_CRITICAL_HIT 149 +#define STR_CONTDUP 145 +#define STR_CONTTRIG 146 +#define STR_CONTFAIL 147 +#define STR_SEQDUP 148 +#define STR_CRITICAL_HIT 149 #define STR_CRITICAL_MISS 150 -#define STR_DEATH 151 -#define STR_BACKSTAB 152 -#define STR_BACKSTAB_BAD 153 +#define STR_DEATH 151 +#define STR_BACKSTAB 152 +#define STR_BACKSTAB_BAD 153 #define STR_BACKSTAB_FAIL 154 #define STR_CASTER_LVL_INC 155 // caster level bonus (wild mages) #define STR_CASTER_LVL_DEC 156 -#define STR_EXPORTED 157 // characters exported (iwd) -#define STR_PALADIN_FALL 158 -#define STR_RANGER_FALL 159 -#define STR_RES_RESISTED 160 - -#define STRREF_COUNT 161 +#define STR_EXPORTED 157 // characters exported (iwd) +#define STR_PALADIN_FALL 158 +#define STR_RANGER_FALL 159 +#define STR_RES_RESISTED 160 +#define STR_DEADMAGIC_FAIL 161 +#define STR_MISCASTMAGIC 162 +#define STR_WILDSURGE 163 +#define STR_FAMBLOCK 164 +#define STR_FAMPROTAGONIST 165 +#define STRREF_COUNT 166 #endif //! IE_STRINGS_H diff --git a/project/jni/application/gemrb/src/includes/win32def.h b/project/jni/application/gemrb/gemrb/includes/win32def.h similarity index 97% rename from project/jni/application/gemrb/src/includes/win32def.h rename to project/jni/application/gemrb/gemrb/includes/win32def.h index 715d09d75..5b676e090 100644 --- a/project/jni/application/gemrb/src/includes/win32def.h +++ b/project/jni/application/gemrb/gemrb/includes/win32def.h @@ -60,10 +60,6 @@ # define strnicmp strncasecmp #endif //WIN32 -#ifdef ANDROID -# define HAVE_SNPRINTF 1 -#endif - #ifndef HAVE_SNPRINTF # ifdef WIN32 # define snprintf _snprintf diff --git a/project/jni/application/gemrb/gemrb/plugins-prepare.sh b/project/jni/application/gemrb/gemrb/plugins-prepare.sh new file mode 100644 index 000000000..ea3c18ed4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins-prepare.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# GemRB - Infinity Engine Emulator +# Copyright (C) 2003 The GemRB Project +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# +# link all plugins to the plugin dir, so gemrb can run from the build dir +dir=$1 +if test -z "$dir"; then + cd `dirname $0`/plugins +else + cd "$dir" +fi || return 1 + +if test -d 2DAImporter/.libs; then + ln -sf */.libs/*.so . +else + # cmake; expect to be in the build dir since it is arbitrary + if test -z "$dir"; then + echo missing dir parameter - pass the path to the build dir + exit 1 + fi && + cd gemrb/plugins && + ln -sf */*.so . +fi || return 2 diff --git a/project/jni/application/gemrb/src/plugins/2DAImporter/2DAImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/2DAImporter/2DAImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/2DAImporter/2DAImporter.h b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/2DAImporter/2DAImporter.h rename to project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h diff --git a/project/jni/application/gemrb/src/plugins/2DAImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/2DAImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/2DAImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/2DAImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/2DAImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/2DAImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/ACMReader.cpp b/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/ACMReader.cpp rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/ACMReader.h b/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/ACMReader.h rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.h diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/ACMReader/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/ACMReader/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/decoder.cpp b/project/jni/application/gemrb/gemrb/plugins/ACMReader/decoder.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/decoder.cpp rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/decoder.cpp diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/decoder.h b/project/jni/application/gemrb/gemrb/plugins/ACMReader/decoder.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/decoder.h rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/decoder.h diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/general.h b/project/jni/application/gemrb/gemrb/plugins/ACMReader/general.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/general.h rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/general.h diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/unpacker.cpp b/project/jni/application/gemrb/gemrb/plugins/ACMReader/unpacker.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/unpacker.cpp rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/unpacker.cpp diff --git a/project/jni/application/gemrb/src/plugins/ACMReader/unpacker.h b/project/jni/application/gemrb/gemrb/plugins/ACMReader/unpacker.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ACMReader/unpacker.h rename to project/jni/application/gemrb/gemrb/plugins/ACMReader/unpacker.h diff --git a/project/jni/application/gemrb/src/plugins/AREImporter/AREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp similarity index 99% rename from project/jni/application/gemrb/src/plugins/AREImporter/AREImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp index 987864657..8d79968f0 100644 --- a/project/jni/application/gemrb/src/plugins/AREImporter/AREImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp @@ -340,13 +340,14 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) } // Small map for MapControl - ResourceHolder sm(TmpResRef); // small map is *optional*! + ResourceHolder sm(TmpResRef); if (Script[0]) { - map->Scripts[0] = new GameScript( Script, map ); - } else { - map->Scripts[0] = NULL; + //for some reason the area's script is run from the last slot + //at least one area script depends on this, if you need something + //more customisable, add a game flag + map->Scripts[MAX_SCRIPTS-1] = new GameScript( Script, map ); } if (day_or_night) { @@ -450,6 +451,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) str->ReadWord( &LaunchY ); str->ReadResRef( KeyResRef ); str->ReadResRef( Script ); + //if the Script field is empty, the area name will be copied into it on first load + //this works only in the iwd branch of the games + if (!Script[0] && core->HasFeature(GF_FORCE_AREA_SCRIPT) ) { + memcpy(Script, ResRef, sizeof(ieResRef) ); + } str->ReadWord( &PosX); str->ReadWord( &PosY); //maybe we have to store this diff --git a/project/jni/application/gemrb/src/plugins/AREImporter/AREImporter.h b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/AREImporter/AREImporter.h rename to project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h diff --git a/project/jni/application/gemrb/src/plugins/AREImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/AREImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/AREImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/AREImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/AREImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/AREImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/AREImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/AREImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/BAMImporter/BAMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BAMImporter/BAMImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/BAMImporter/BAMImporter.h b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BAMImporter/BAMImporter.h rename to project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h diff --git a/project/jni/application/gemrb/src/plugins/BAMImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/BAMImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/BAMImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/BAMImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/BAMImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/BAMImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/BIFImporter/BIFImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIFImporter/BIFImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/BIFImporter/BIFImporter.h b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIFImporter/BIFImporter.h rename to project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h diff --git a/project/jni/application/gemrb/src/plugins/BIFImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIFImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/BIFImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/BIFImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIFImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/BIFImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp similarity index 94% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp index 65092ab87..aa5228e02 100644 --- a/project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp @@ -59,12 +59,8 @@ static const int ff_wma_critical_freqs[25] = { 24500, }; -static uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; - BIKPlayer::BIKPlayer(void) { - int i; - video = core->GetVideoDriver(); inbuff = NULL; maxRow = 0; @@ -73,12 +69,6 @@ BIKPlayer::BIKPlayer(void) //force initialisation of static tables memset(bink_trees, 0, sizeof(bink_trees)); memset(table, 0, sizeof(table)); - - for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i; - for(i=0;iSeek(frame.pos, GEM_STREAM_START); ieDword audframesize; str->ReadDword(&audframesize); @@ -482,7 +470,7 @@ int BIKPlayer::sound_init(bool need_init) return ret; } -void BIKPlayer::ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ +void BIKPlayer::ff_init_scantable(ScanTable *st, const uint8_t *src_scantable){ int i,j; int end; @@ -490,7 +478,7 @@ void BIKPlayer::ff_init_scantable(uint8_t *permutation, ScanTable *st, const uin for(i=0; i<64; i++){ j = src_scantable[i]; - st->permutated[i] = permutation[j]; + st->permutated[i] = j; } end=-1; @@ -524,14 +512,7 @@ int BIKPlayer::video_init(int w, int h) return 1; } - //pixel format is PIX_FMT_YUV420P - //idct permutation is used in various optimisations, - //we go with the simplest (no permutation) - for(i=0;i<64;i++) { - c_idct_permutation[i]=i; - } - - ff_init_scantable(c_idct_permutation, &c_scantable, bink_scan); + ff_init_scantable(&c_scantable, bink_scan); bw = (header.width + 7) >> 3; bh = (header.height + 7) >> 3; @@ -1156,7 +1137,8 @@ int BIKPlayer::read_colors(Bundle *b) int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) { int i, j, len, len2, bsize, v, v2; - int16_t *dst = (int16_t*)b->cur_dec; + SET_INT_TYPE *dst = (SET_INT_TYPE*)b->cur_dec; + //int16_t *dst = (int16_t*)b->cur_dec; CHECK_READ_VAL(v_gb, b, len); if (has_sign) { @@ -1166,7 +1148,8 @@ int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) } else { v = v_gb.get_bits(start_bits); } - *dst++ = v; + SET_INT_VALUE(dst, v); + //*dst++ = v; len--; for (i = 0; i < len; i += 8) { len2 = FFMIN(len - i, 8); @@ -1178,14 +1161,16 @@ int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) v2 = -v2; } v += v2; - *dst++ = v; + SET_INT_VALUE(dst, v); + //*dst++ = v; if (v < -32768 || v > 32767) { return -1; } } } else { for (j = 0; j < len2; j++) { - *dst++ = v; + SET_INT_VALUE(dst, v); + //*dst++ = v; } } } @@ -1204,8 +1189,9 @@ inline int BIKPlayer::get_value(int bundle) if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) { return (int8_t)*c_bundle[bundle].cur_ptr++; } - ret = *(int16_t*)c_bundle[bundle].cur_ptr; - c_bundle[bundle].cur_ptr += 2; + GET_INT_VALUE(ret, c_bundle[bundle].cur_ptr); + //ret = *(int16_t*)c_bundle[bundle].cur_ptr; + //c_bundle[bundle].cur_ptr += 2; return ret; } @@ -1234,50 +1220,47 @@ static void get_pixels(DCTELEM *block, const uint8_t *pixels, int line_size) } } -static void put_pixels_clamped(const DCTELEM *block, uint8_t *pixels, int line_size) +static void put_pixels_nonclamped(const DCTELEM *block, uint8_t *pixels, int line_size) { - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - /* read the pixels */ - for(i=0;i<8;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; - pixels[2] = cm[block[2]]; - pixels[3] = cm[block[3]]; - pixels[4] = cm[block[4]]; - pixels[5] = cm[block[5]]; - pixels[6] = cm[block[6]]; - pixels[7] = cm[block[7]]; - pixels += line_size; - block += 8; - } + int i; + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = block[0]; + pixels[1] = block[1]; + pixels[2] = block[2]; + pixels[3] = block[3]; + pixels[4] = block[4]; + pixels[5] = block[5]; + pixels[6] = block[6]; + pixels[7] = block[7]; + pixels += line_size; + block += 8; + } } -static void add_pixels_clamped(const DCTELEM *block, uint8_t *pixels, int line_size) +static void add_pixels_nonclamped(const DCTELEM *block, uint8_t *pixels, int line_size) { - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + int i; - /* read the pixels */ - for(i=0;i<8;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; - pixels[2] = cm[pixels[2] + block[2]]; - pixels[3] = cm[pixels[3] + block[3]]; - pixels[4] = cm[pixels[4] + block[4]]; - pixels[5] = cm[pixels[5] + block[5]]; - pixels[6] = cm[pixels[6] + block[6]]; - pixels[7] = cm[pixels[7] + block[7]]; - pixels += line_size; - block += 8; - } + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels[4] += block[4]; + pixels[5] += block[5]; + pixels[6] += block[6]; + pixels[7] += block[7]; + pixels += line_size; + block += 8; + } } static inline void copy_block(DCTELEM block[64], const uint8_t *src, uint8_t *dst, int stride) { get_pixels(block, src, stride); - put_pixels_clamped(block, dst, stride); + put_pixels_nonclamped(block, dst, stride); } #define clear_block(block) memset( (block), 0, sizeof(DCTELEM)*64); @@ -1362,12 +1345,13 @@ void bink_idct(DCTELEM *block) static void idct_put(uint8_t *dest, int line_size, DCTELEM *block) { bink_idct(block); - put_pixels_clamped(block, dest, line_size); + put_pixels_nonclamped(block, dest, line_size); } + static void idct_add(uint8_t *dest, int line_size, DCTELEM *block) { bink_idct(block); - add_pixels_clamped(block, dest, line_size); + add_pixels_nonclamped(block, dest, line_size); } int BIKPlayer::DecodeVideoFrame(void *data, int data_size) @@ -1433,7 +1417,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) prev = c_last.data[plane] + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(BINK_SRC_BLOCK_TYPES); - if ((by & 1) && blk == 1) { + if ((by & 1) && (blk == SCALED_BLOCK) ) { bx++; dst += 8; prev += 8; @@ -1552,7 +1536,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) clear_block(block); v = v_gb.get_bits(7); read_residue(block, v); - add_pixels_clamped(block, dst, stride); + add_pixels_nonclamped(block, dst, stride); break; case INTRA_BLOCK: clear_block(block); diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h similarity index 92% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.h rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h index a59e32397..628d282e8 100644 --- a/project/jni/application/gemrb/src/plugins/BIKPlayer/BIKPlayer.h +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h @@ -41,6 +41,31 @@ #define MAX_CHANNELS 2 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) +#if defined(__arm__) +#define SET_INT_TYPE uint8_t +#define SET_INT_VALUE(ptr, value)\ + *(ptr) = (value) && 0xff; \ + (ptr)++; \ + *(ptr) = ((value) >> 8) && 0xff; \ + (ptr)++; +#else +#define SET_INT_TYPE int16_t +#define SET_INT_VALUE(ptr, value)\ + *(ptr)++ = (value); +#endif + +#if defined(__arm__) +#define GET_INT_VALUE(value, ptr)\ + (value) = *(ptr); \ + (ptr)++; \ + (value) |= (*(ptr)) << 8; \ + (ptr)++; +#else +#define GET_INT_VALUE(value, ptr)\ + (value) = *(int16_t*)(ptr); \ + (ptr) += 2; +#endif + enum BinkAudFlags { BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output BINK_AUD_STEREO = 0x2000, @@ -175,7 +200,6 @@ private: int outputwidth, outputheight; unsigned int video_skippedframes; //bink specific - uint8_t c_idct_permutation[64]; ScanTable c_scantable; Bundle c_bundle[BINK_NB_SRC]; ///< bundles for decoding all data types Tree c_col_high[16]; ///< trees for decoding high nibble in "colours" data type @@ -203,7 +227,7 @@ private: void queueBuffer(int stream, unsigned short bits, int channels, short* memory, int size, int samplerate); int sound_init(bool need_init); - void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable); + void ff_init_scantable(ScanTable *st, const uint8_t *src_scantable); int video_init(int w, int h); void av_set_pts_info(AVRational &time_base, unsigned int pts_num, unsigned int pts_den); int ReadHeader(); diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp similarity index 96% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp index eaaca2def..5ef416a47 100644 --- a/project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp @@ -175,22 +175,6 @@ int VLC::alloc_table(int size) return index; } -#define GET_DATA(v, table, i, wrap, size) \ -{\ - const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ - switch(size) {\ - case 1:\ - v = *(const uint8_t *)ptr;\ - break;\ - case 2:\ - v = *(const uint16_t *)ptr;\ - break;\ - default:\ - v = *(const uint32_t *)ptr;\ - break;\ - }\ -} - int VLC::build_table(int table_nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, diff --git a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.h new file mode 100644 index 000000000..d056f37f3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.h @@ -0,0 +1,107 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2009 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + */ + +//code derived from FFMPEG +//using code from get_bits.h, bitstream.c + +#include "common.h" + +#define INIT_VLC_LE 2 +#define INIT_VLC_USE_NEW_STATIC 4 + +class VLC +{ +public: + int bits; + int16_t (*table)[2]; ///< code, bits + int table_size, table_allocated; +public: + int init_vlc(int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + int flags); +private: + int alloc_table(int size); + int build_table(int table_nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix, int flags); + +}; + +#if defined(__arm__) +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + v = 0;\ + switch(size) {\ + default:\ + v |= *((const uint8_t *)ptr+3) << 24;\ + v |= *((const uint8_t *)ptr+2) << 16;\ + case 2:\ + v |= *((const uint8_t *)ptr+1) << 8;\ + case 1:\ + v |= *(const uint8_t *)ptr;\ + }\ +} +#else +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} +#endif + +#define AV_RL32(x) \ + ((((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) + +class GetBitContext +{ +public: + const uint8_t *buffer, *buffer_end; + int index; + int size_in_bits; +public: + void debug(const char *prefix); + float get_float(); + void skip_bits(int x) { index+=x; } + int get_bits_count() { return index; } + void get_bits_align32(); + unsigned int get_bits(int x); + unsigned int peek_bits(int x); + unsigned int get_bits_long(int n); + void init_get_bits(const uint8_t *b, int bit_size); + void read_tree(Tree *tree); +private: + void merge( uint8_t *dst, uint8_t *src, int size); +}; diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/binkdata.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/binkdata.h rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/common.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/common.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/common.h rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/common.h diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/dct.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/dct.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/dct.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/dct.cpp diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/dsputil.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/dsputil.h similarity index 99% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/dsputil.h rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/dsputil.h index 7e21dc6cb..84161fad9 100644 --- a/project/jni/application/gemrb/src/plugins/BIKPlayer/dsputil.h +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/dsputil.h @@ -37,9 +37,6 @@ typedef short DCTELEM; typedef int DWTELEM; typedef short IDWTELEM; -/* pixel operations */ -#define MAX_NEG_CROP 1024 - /** * Scantable. */ diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/fft.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/fft.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/fft.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/fft.cpp diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/mem.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/mem.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/mem.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/mem.cpp diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/rational.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rational.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/rational.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rational.cpp diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/rational.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rational.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/rational.h rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rational.h diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/rdft.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rdft.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BIKPlayer/rdft.cpp rename to project/jni/application/gemrb/gemrb/plugins/BIKPlayer/rdft.cpp diff --git a/project/jni/application/gemrb/src/plugins/BMPImporter/BMPImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPImporter/BMPImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/BMPImporter/BMPImporter.h b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPImporter/BMPImporter.h rename to project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h diff --git a/project/jni/application/gemrb/src/plugins/BMPImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/BMPImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/BMPImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/BMPImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/BMPWriter/BMPWriter.cpp b/project/jni/application/gemrb/gemrb/plugins/BMPWriter/BMPWriter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPWriter/BMPWriter.cpp rename to project/jni/application/gemrb/gemrb/plugins/BMPWriter/BMPWriter.cpp diff --git a/project/jni/application/gemrb/src/plugins/BMPWriter/BMPWriter.h b/project/jni/application/gemrb/gemrb/plugins/BMPWriter/BMPWriter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPWriter/BMPWriter.h rename to project/jni/application/gemrb/gemrb/plugins/BMPWriter/BMPWriter.h diff --git a/project/jni/application/gemrb/src/plugins/BMPWriter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/BMPWriter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPWriter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/BMPWriter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/BMPWriter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/BMPWriter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/BMPWriter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/BMPWriter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/CHUImporter/CHUImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp similarity index 93% rename from project/jni/application/gemrb/src/plugins/CHUImporter/CHUImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp index 5f965b7cf..4d9609d04 100644 --- a/project/jni/application/gemrb/src/plugins/CHUImporter/CHUImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp @@ -185,7 +185,7 @@ Window* CHUImporter::GetWindow(unsigned int wid) if (!bam ) { printMessage( "CHUImporter","Cannot Load Button Images, skipping control\n",LIGHT_RED ); /* IceWind Dale 2 has fake BAM ResRefs for some Buttons, - this will handle bad ResRefs */ + this will handle bad ResRefs */ win->AddControl( btn ); break; } @@ -230,7 +230,7 @@ Window* CHUImporter::GetWindow(unsigned int wid) str->ReadWord( &KnobYPos ); str->ReadWord( &CapXPos ); str->ReadWord( &CapYPos ); - Progressbar* pbar = new Progressbar(KnobStepsCount, true ); + Progressbar* pbar = new Progressbar(KnobStepsCount, true ); pbar->ControlID = ControlID; pbar->XPos = XPos; pbar->YPos = YPos; @@ -249,7 +249,7 @@ Window* CHUImporter::GetWindow(unsigned int wid) ResourceHolder mos(MOSFile2); img2 = mos->GetSprite2D(); } - + pbar->SetImage( img, img2 ); if( KnobStepsCount ) { /* getting the bam */ @@ -302,7 +302,7 @@ Window* CHUImporter::GetWindow(unsigned int wid) sldr->SetImage( IE_GUI_SLIDER_GRABBEDKNOB, img ); } else { - sldr->SetState(IE_GUI_SLIDER_BACKGROUND); + sldr->SetState(IE_GUI_SLIDER_BACKGROUND); } win->AddControl( sldr ); } @@ -314,30 +314,41 @@ Window* CHUImporter::GetWindow(unsigned int wid) ieResRef BGMos; ieResRef FontResRef, CursorResRef; ieWord maxInput; - ieWord CurCycle, CurFrame; - ieWord PosX, PosY; + ieWord CurCycle, CurFrame; + ieWord PosX, PosY; + ieWord Pos2X, Pos2Y; + ieVariable Initial; str->ReadResRef( BGMos ); + //These are two more MOS resrefs, probably unused str->Seek( 16, GEM_CURRENT_POS ); str->ReadResRef( CursorResRef ); - str->ReadWord( &CurCycle ); - str->ReadWord( &CurFrame ); - str->ReadWord( &PosX ); - str->ReadWord( &PosY ); - str->Seek( 4, GEM_CURRENT_POS ); + str->ReadWord( &CurCycle ); + str->ReadWord( &CurFrame ); + str->ReadWord( &PosX ); + str->ReadWord( &PosY ); + //FIXME: I still don't know what to do with this point + //Contrary to forum posts, it is definitely not a scrollbar ID + str->ReadWord( &Pos2X ); + str->ReadWord( &Pos2Y ); str->ReadResRef( FontResRef ); - str->Seek( 34, GEM_CURRENT_POS ); + //this field is still unknown or unused + str->Seek( 2, GEM_CURRENT_POS ); + //This is really a text field, but apparently the original engine + //always writes it over, and never uses it + str->Read( Initial, 32 ); + Initial[32]=0; str->ReadWord( &maxInput ); Font* fnt = core->GetFont( FontResRef ); - + AnimationFactory* bam = ( AnimationFactory* ) gamedata->GetFactoryResource( CursorResRef, IE_BAM_CLASS_ID, IE_NORMAL ); Sprite2D *cursor = NULL; - if (bam) { + if (bam) { cursor = bam->GetFrame( CurCycle, CurFrame ); - } + } ResourceHolder mos(BGMos); Sprite2D *img = NULL; @@ -355,6 +366,8 @@ Window* CHUImporter::GetWindow(unsigned int wid) te->SetFont( fnt ); te->SetCursor( cursor ); te->SetBackGround( img ); + //The original engine always seems to ignore this textfield + //te->SetText (Initial ); win->AddControl( te ); } break; diff --git a/project/jni/application/gemrb/src/plugins/CHUImporter/CHUImporter.h b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/CHUImporter/CHUImporter.h rename to project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h diff --git a/project/jni/application/gemrb/src/plugins/CHUImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/CHUImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/CHUImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/CHUImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/CHUImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/CHUImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/CREImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/CREImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/CREImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/CREImporter/CREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/CREImporter/CREImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/CREImporter/CREImporter.h b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/CREImporter/CREImporter.h rename to project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h diff --git a/project/jni/application/gemrb/src/plugins/CREImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/CREImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/CREImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/CREImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/DLGImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/DLGImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/DLGImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/DLGImporter/DLGImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/DLGImporter/DLGImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/DLGImporter/DLGImporter.h b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/DLGImporter/DLGImporter.h rename to project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h diff --git a/project/jni/application/gemrb/src/plugins/DLGImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/DLGImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/DLGImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/DirectoryImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/DirectoryImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/DirectoryImporter/DirectoryImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/DirectoryImporter/DirectoryImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/DirectoryImporter/DirectoryImporter.h b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/DirectoryImporter/DirectoryImporter.h rename to project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h diff --git a/project/jni/application/gemrb/src/plugins/DirectoryImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/DirectoryImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/EFFImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/EFFImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/EFFImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/EFFImporter/EFFImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/EFFImporter/EFFImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/EFFImporter/EFFImporter.h b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/EFFImporter/EFFImporter.h rename to project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h diff --git a/project/jni/application/gemrb/src/plugins/EFFImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/EFFImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/EFFImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/FXOpcodes/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/FXOpcodes/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/FXOpcodes/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/FXOpcodes/FXOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp similarity index 97% rename from project/jni/application/gemrb/src/plugins/FXOpcodes/FXOpcodes.cpp rename to project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp index 20376774d..867cde181 100644 --- a/project/jni/application/gemrb/src/plugins/FXOpcodes/FXOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp @@ -35,12 +35,14 @@ #include "TileMap.h" //needs for knock! #include "damages.h" #include "GameScript/GSUtils.h" //needs for MoveBetweenAreasCore +#include "GameScript/Matching.h" //needs for GetAllObjects #include "GUI/GameControl.h" #include "Scriptable/Actor.h" #include "PolymorphCache.h" // fx_polymorph #include "Scriptable/PCStatStruct.h" //fx_polymorph (action definitions) //FIXME: find a way to handle portrait icons better +#define PI_RIGID 2 #define PI_CONFUSED 3 #define PI_BERSERK 4 #define PI_POISONED 6 @@ -411,6 +413,7 @@ int fx_golem_stoneskin_modifier (Scriptable* Owner, Actor* target, Effect* fx);/ int fx_avatar_removal_modifier (Scriptable* Owner, Actor* target, Effect* fx);//13b int fx_magical_rest (Scriptable* Owner, Actor* target, Effect* fx);//13c //int fx_improved_haste_state (Scriptable* Owner, Actor* target, Effect* fx);//13d same as haste +int fx_change_weather (Scriptable* Owner, Actor* target, Effect* fx);//13e ChangeWeather int fx_unknown (Scriptable* Owner, Actor* target, Effect* fx);//??? @@ -465,6 +468,7 @@ static EffectRef effectnames[] = { { "CastSpellOnCondition", fx_cast_spell_on_condition, -1 }, { "ChangeBardSong", fx_change_bardsong, -1 }, { "ChangeName", fx_change_name, -1 }, + { "ChangeWeather", fx_change_weather, -1 }, { "ChantBadNonCumulative", fx_set_chantbad_state, -1 }, { "ChantNonCumulative", fx_set_chant_state, -1 }, { "ChaosShieldModifier", fx_chaos_shield_modifier, -1 }, @@ -1233,7 +1237,7 @@ int fx_death (Scriptable* Owner, Actor* target, Effect* fx) ieDword damagetype = 0; switch (fx->Parameter2) { case 1: - BASE_STATE_SET(STATE_D4); //not sure, should be charred + BASE_STATE_SET(STATE_FLAME); //not sure, should be charred damagetype = DAMAGE_FIRE; break; case 2: @@ -1269,6 +1273,9 @@ int fx_death (Scriptable* Owner, Actor* target, Effect* fx) default: damagetype = DAMAGE_ACID; } + //these two bits are turned off on death + BASE_STATE_CURE(STATE_FROZEN|STATE_PETRIFIED); + target->Damage(0, damagetype, Owner); //death has damage type too target->Die(Owner); @@ -1414,7 +1421,12 @@ int fx_maximum_hp_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_maximum_hp_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - if (STATE_GET( STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { + //state_exploding is different in PST, probably not needed anyway + if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN|STATE_ACID|STATE_FLAME) ) { + return FX_NOT_APPLIED; + } + + if (BASE_GET(IE_HITPOINTS)<=0 ) { return FX_NOT_APPLIED; } @@ -1548,6 +1560,7 @@ int fx_morale_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_morale_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); + //FIXME: in bg2 this is hacked to set param1=10, param2=1, we might need some flag for this STAT_MOD( IE_MORALE ); return FX_APPLIED; } @@ -1576,10 +1589,8 @@ int fx_set_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) int fx_set_poisoned_state (Scriptable* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_set_poisoned_state (%2d): Damage: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - //apparently this bit isn't set, but then why is it here - //this requires a little research STATE_SET( STATE_POISONED ); - //also this effect is executed every update + ieDword damage; int tmp = fx->Parameter1; @@ -1716,8 +1727,11 @@ int fx_magic_damage_resistance_modifier (Scriptable* /*Owner*/, Actor* target, E int fx_cure_dead_state (Scriptable* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_cure_dead_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - Point p(fx->PosX, fx->PosY); - Resurrect(Owner, target, fx, p); + //call this only if the target is dead, otherwise some variables can get wrong + if (STATE_GET(STATE_DEAD) ) { + Point p(fx->PosX, fx->PosY); + Resurrect(Owner, target, fx, p); + } return FX_NOT_APPLIED; } @@ -2557,6 +2571,12 @@ int fx_set_diseased_state (Scriptable* Owner, Actor* target, Effect* fx) break; case RPD_SLOW: //slow break; + case RPD_MOLD: //mold touch (how) + EXTSTATE_SET(EXTSTATE_MOLD); + damage = 1; + break; + case RPD_MOLD2: + break; default: damage = 1; break; @@ -2885,6 +2905,7 @@ int fx_protection_spelllevel (Scriptable* /*Owner*/, Actor* target, Effect* fx) int fx_change_name (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_change_name_modifier (%2d): StrRef: %d\n", fx->Opcode, fx->Parameter1 ); + //this also changes the base stat target->SetName(fx->Parameter1, 0); return FX_NOT_APPLIED; } @@ -2893,8 +2914,9 @@ int fx_change_name (Scriptable* /*Owner*/, Actor* target, Effect* fx) int fx_experience_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_experience_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - //i believe this has mode too - target->AddExperience (fx->Parameter1); + //FIXME: this has mode too + //target->AddExperience (fx->Parameter1); + STAT_MOD( IE_XP ); return FX_NOT_APPLIED; } @@ -3116,10 +3138,7 @@ int fx_mirror_image (Scriptable* Owner, Actor* target, Effect* fx) else { // the original uses only IE_LEVEL, but that can be awefully bad in // the case of dual- and multiclasses - unsigned int level = target->GetMageLevel(); - if (!level) level = target->GetSorcererLevel(); - if (!level) level = target->GetBardLevel(); - if (!level) level = target->GetStat(IE_LEVEL); + unsigned int level = target->GetCasterLevel(IE_SPL_WIZARD); // 2-8 mirror images images = level/3 + 2; if (images > 8) images = 8; @@ -3365,10 +3384,10 @@ int fx_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx) core->GetResRefFrom2DA(monster_summoning_2da[fx->Parameter2], monster, hit, areahit); if (!hit[0]) { - strnuprcpy(hit,fx->Resource2,8); + strnuprcpy(hit, fx->Resource2, 8); } if (!areahit[0]) { - strnuprcpy(areahit,fx->Resource3,8); + strnuprcpy(areahit, fx->Resource3, 8); } //the monster should appear near the effect position @@ -3412,6 +3431,8 @@ int fx_set_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //NOTE: iwd2 is also unable to display the portrait icon //for permanent confusion + //the portrait icon cannot be made common because rigid thinking uses a different icon + //in bg2/how if (enhanced_effects) { target->AddPortraitIcon(PI_CONFUSED); } @@ -3874,7 +3895,7 @@ int fx_cast_spell (Scriptable* Owner, Actor* target, Effect* fx) //cast spell on target Owner->CastSpell(fx->Resource, target, false); //actually finish casting (if this is not good enough, use an action???) - Owner->CastSpellEnd(fx->Resource); + Owner->CastSpellEnd(); } return FX_NOT_APPLIED; } @@ -3886,7 +3907,8 @@ int fx_learn_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) //parameter1 is unused, gemrb lets you to make it not give XP //probably we should also let this via a game flag if we want //full compatibility with bg1 - target->LearnSpell(fx->Resource, fx->Parameter2^LS_ADDXP); + //parameter2 is used in bg1 and pst to specify the spell type; bg2 and iwd2 figure it out from the resource + target->LearnSpell(fx->Resource, fx->Parameter1^LS_ADDXP); return FX_NOT_APPLIED; } // 0x94 Spell:CastSpellPoint @@ -3895,7 +3917,7 @@ int fx_cast_spell_point (Scriptable* Owner, Actor* target, Effect* fx) if (0) printf( "fx_cast_spell_point (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 ); Owner->CastSpellPoint(fx->Resource, target->Pos, false); //actually finish casting (if this is not good enough, use an action???) - Owner->CastSpellPointEnd(fx->Resource); + Owner->CastSpellPointEnd(); return FX_NOT_APPLIED; } @@ -3931,7 +3953,7 @@ int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx) break; //find traps case 3: //detect secret doors - skill = target->LuckyRoll(1,100,0); + skill = target->LuckyRoll(1, 100, 0, 0); detecttraps = false; break; case 2: @@ -4498,15 +4520,24 @@ int fx_attackspeed_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xbf CastingLevelModifier +// gemrb extension: if the resource key is set, apply param1 as a percentual modifier int fx_castinglevel_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_castinglevel_modifier (%2d) Value:%d Type:%d", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: - STAT_SET( IE_CASTINGLEVELBONUSMAGE, fx->Parameter1 ); + if (fx->Resource[0]) { + STAT_MUL( IE_CASTINGLEVELBONUSMAGE, fx->Parameter1 ); + } else { + STAT_SET( IE_CASTINGLEVELBONUSMAGE, fx->Parameter1 ); + } break; case 1: - STAT_SET( IE_CASTINGLEVELBONUSCLERIC, fx->Parameter1 ); + if (fx->Resource[0]) { + STAT_MUL( IE_CASTINGLEVELBONUSCLERIC, fx->Parameter1 ); + } else { + STAT_SET( IE_CASTINGLEVELBONUSCLERIC, fx->Parameter1 ); + } break; default: return FX_NOT_APPLIED; @@ -4534,9 +4565,25 @@ int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx) } if (!target->GetCurrentArea()) { + //this will delay casting until we get an area return FX_APPLIED; } + Game *game = core->GetGame(); + //FIXME: the familiar block field is not saved in the game and not set when the + //familiar is itemized, so a game reload will clear it (see how this is done in original) + if (game->familiarBlock) { + displaymsg->DisplayConstantStringName(STR_FAMBLOCK, 0xff0000, target); + return FX_NOT_APPLIED; + } + + //The protagonist is ALWAYS in the first slot + if (game->GetPC(0, false)!=target) { + displaymsg->DisplayConstantStringName(STR_FAMPROTAGONIST, 0xff0000, target); + return FX_NOT_APPLIED; + } + + if (fx->Parameter2!=FAMILIAR_RESOURCE) { ieDword alignment; @@ -4655,12 +4702,10 @@ int fx_familiar_marker (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_familiar_marker (%2d)\n", fx->Opcode ); if (! (STAT_GET(IE_STATE_ID)&STATE_NOSAVE)) { - //TODO: where to disable familiar? - //core->GetGame()->WeatherBits|=1; + core->GetGame()->familiarBlock=true; return FX_APPLIED; } - //TODO: enable familiar? - //core->GetGame()->WeatherBits&=~1; + core->GetGame()->familiarBlock=false; return FX_NOT_APPLIED; } @@ -4843,7 +4888,7 @@ int fx_power_word_stun (Scriptable* Owner, Actor* target, Effect* fx) //0xd3 State:Imprisonment (avatar removal plus portrait icon) int fx_imprisonment (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_inprisonment (%2d)\n", fx->Opcode ); + if (0) printf( "fx_imprisonment (%2d)\n", fx->Opcode ); target->SetMCFlag(MC_HIDDEN, BM_OR); target->AddPortraitIcon(PI_PRISON); return FX_APPLIED; @@ -4865,17 +4910,42 @@ int fx_freedom (Scriptable* /*Owner*/, Actor* target, Effect* fx) int fx_maze (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_maze (%2d)\n", fx->Opcode ); + if (!fx->Parameter2 && fx->FirstApply) { + //get the maze dice number (column 3) + int stat = target->GetSafeStat(IE_INT); + int size = core->GetIntelligenceBonus(3, stat); + int dice = core->GetIntelligenceBonus(4, stat); + fx->Duration = core->GetGame()->GameTime+target->LuckyRoll(dice, size, 0, 0)*100; + } target->SetMCFlag(MC_HIDDEN, BM_OR); target->AddPortraitIcon(PI_MAZE); return FX_APPLIED; } //0xd6 CastFromList -int fx_select_spell (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) +//GemRB extension: if fx->Parameter1 is set, it is the bitfield of spell types (could be priest spells) +int fx_select_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_select_spell (%2d) %d\n", fx->Opcode, fx->Parameter2 ); - //if parameter2==0 -> cast spells from 2da (all spells listed in 2da) - //if parameter2==1 -> cast spells from book (all known spells, no need of memorize) + Spellbook *sb = &target->spellbook; + if(fx->Parameter2) { + //all known spells, no need to memorize + if (!fx->Parameter1) { + fx->Parameter1=1<SetCustomSpellInfo(NULL, fx->Source, fx->Parameter1); + } else { + //all spells listed in 2da + ieResRef *data = NULL; + + int count = core->ReadResRefTable(fx->Resource, data); + sb->SetCustomSpellInfo(data, fx->Source, count); + core->FreeResRefTable(data, count); + } + core->GetDictionary()->SetAt("Type",-1); + //this is required, because not all of these opcodes are firing right at casting + core->GetDictionary()->SetAt("ActionLevel", 2); + core->SetEventFlag(EF_ACTION); return FX_NOT_APPLIED; } @@ -5478,6 +5548,15 @@ int fx_cure_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) if (0) printf( "fx_cure_confused_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_CURE( STATE_CONFUSED ); target->fxqueue.RemoveAllEffects(fx_confused_state_ref); + //FIXME:oddly enough, HoW removes the confused icon + //no one removes the rigid thinking icon + //there are also several mods floating around, which change these things inconsistently + //probably the best is to remove them all by default + //New mods can still disable the icon removal by setting param2 + if (!fx->Parameter2) { + target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref,PI_CONFUSED ); + target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref,PI_RIGID ); + } return FX_NOT_APPLIED; } @@ -5588,7 +5667,7 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx) if (Owner->Type==ST_ACTOR) { skill = ((Actor *)Owner)->GetStat(IE_SETTRAPS); - roll = core->Roll(1,100,0); + roll = target->LuckyRoll(1,100,0,LR_NEGATIVE); } else { roll=0; skill=0; @@ -5596,8 +5675,18 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx) if (roll>skill) { //failure - displaymsg->DisplayConstantStringName(STR_SNAREFAILED, 0xf0f0f0, target); - //TODO check luck and do some damage effect on target + displaymsg->DisplayConstantStringName(STR_SNAREFAILED, 0xf0f0f0, target); + if (target->LuckyRoll(1,100,0)<25) { + ieResRef spl; + + strnuprcpy(spl, fx->Resource, 8); + if (strlen(spl)<8) { + strcat(spl,"F"); + } else { + spl[7]='F'; + } + core->ApplySpell(spl, target, Owner, fx->Power); + } return FX_NOT_APPLIED; } //success @@ -5852,16 +5941,17 @@ int fx_unpause_caster (Scriptable* /*Owner*/, Actor* target, Effect* fx) target->fxqueue.RemoveAllEffects(fx_pause_caster_modifier_ref); return FX_NOT_APPLIED; } -// 0x10f AvatarRemoval -// 0x104 AvatarRemoval (iwd) + +// 0x10f SummonDisable (bg2) int fx_avatar_removal (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_avatar_removal (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - //FIXME: this is a permanent irreversible effect in IWD - //if it is different in bg2, then create another effect - //bg2 calls this SummonDisable - BASE_SET(IE_AVATARREMOVAL, 1); - return FX_NOT_APPLIED; + STAT_SET(IE_SUMMONDISABLE, 1); + STAT_SET(IE_CASTERHOLD, 1); + if (fx->Parameter2==1) { + STAT_SET(IE_AVATARREMOVAL, 1); + } + return FX_APPLIED; } /* note/TODO from Taimon: @@ -5984,13 +6074,20 @@ int fx_teleport_to_target (Scriptable* /*Owner*/, Actor* target, Effect* fx) Map *map = target->GetCurrentArea(); if (map) { - Actor *victim = map->GetActorByGlobalID(target->LastAttacker); - if (victim) { + Object oC; + oC.objectFields[0]=EA_ENEMY; + Targets *tgts = GetAllObjects(map, target, &oC, GA_NO_DEAD); + int rnd = core->Roll(1,tgts->Count(),-1); + Actor *victim = (Actor *) tgts->GetTarget(rnd, ST_ACTOR); + delete tgts; + if (victim && PersonalDistance(victim, target)>20) { target->SetPosition( victim->Pos, true, 0 ); + target->SetColorMod(0xff, RGBModifier::ADD, 0x50, 0xff, 0xff, 0xff, 0); } } return FX_NOT_APPLIED; } + // 0x113 HideInShadowsModifier int fx_hide_in_shadows_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5998,6 +6095,7 @@ int fx_hide_in_shadows_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f STAT_MOD( IE_HIDEINSHADOWS ); return FX_APPLIED; } + // 0x114 DetectIllusionsModifier int fx_detect_illusion_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -6005,6 +6103,7 @@ int fx_detect_illusion_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f STAT_MOD( IE_DETECTILLUSIONS ); return FX_APPLIED; } + // 0x115 SetTrapsModifier int fx_set_traps_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -6030,11 +6129,12 @@ int fx_renable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx) target->fxqueue.RemoveAllEffectsWithParam( fx_disable_button_ref, fx->Parameter2 ); return FX_NOT_APPLIED; } + // 0x118 ForceSurgeModifier int fx_force_surge_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_force_surge_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); - STAT_MOD( IE_FORCESURGE ); + STAT_MOD_VAR( IE_FORCESURGE, MOD_ABSOLUTE ); return FX_APPLIED; } @@ -6397,20 +6497,42 @@ int fx_timeless_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //0x137 GenerateWish -#define WISHCOUNT 25 -static int wishlevels[WISHCOUNT]={10,10,10,10,0,10,0,15,0,0,0,0,0,0,15,0,0, -17,9,17,17,9,9,9,0}; - +//GemRB extension: you can use different tables and not only wisdom stat int fx_generate_wish (Scriptable* Owner, Actor* target, Effect* fx) { ieResRef spl; if (0) printf( "fx_generate_wish (%2d): Mod: %d\n", fx->Opcode, fx->Parameter2 ); - int tmp = core->Roll(1,WISHCOUNT,0); - sprintf(spl,"SPWISH%02d",tmp); - core->ApplySpell(spl, target, Owner, wishlevels[tmp-1]); + if (!fx->Parameter2) { + fx->Parameter2=IE_WIS; + } + int stat = target->GetSafeStat(fx->Parameter2); + if (!fx->Resource[0]) { + memcpy(fx->Resource,"wishcode",8); + } + AutoTable tm(fx->Resource); + if (!tm) { + return FX_NOT_APPLIED; + } + + int max = tm->GetRowCount(); + int tmp = core->Roll(1,max,0); + int i = tmp; + bool pass = true; + while(--i!=tmp && pass) { + if (i<0) { + pass=false; + i=max-1; + } + int min = atoi(tm->QueryField(i, 1)); + int max = atoi(tm->QueryField(i, 2)); + if (stat>=min && stat<=max) break; + } + strnuprcpy(spl, tm->QueryField(i,0), 8); + core->ApplySpell(spl, target, Owner, fx->Power); return FX_NOT_APPLIED; } + //0x138 //see fx_crash, this effect is not fully enabled in original bg2/tob int fx_immunity_sequester (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -6457,6 +6579,22 @@ int fx_magical_rest (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x13d ImprovedHaste (See 0x10 Haste) + +// 0x13e ChangeWeather +// sets the weather to param1, set it to: +// 0 normal weather +// 1 rain +// 2 snow +// 3 fog +int fx_change_weather (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) +{ + printf( "fx_change_weather (%2d): P1: %d\n", fx->Opcode, fx->Parameter1 ); + + core->GetGame()->StartRainOrSnow(false, fx->Parameter1 & WB_MASK); + + return FX_NOT_APPLIED; +} + // unknown int fx_unknown (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) { diff --git a/project/jni/application/gemrb/src/plugins/FXOpcodes/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/FXOpcodes/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/FXOpcodes/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/GAMImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/GAMImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/GAMImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp similarity index 89% rename from project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp index b0ea042d1..f757f7fe8 100644 --- a/project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp @@ -31,7 +31,6 @@ #include -#define MAZE_DATA_SIZE 1720 #define FAMILIAR_FILL_SIZE 324 // if your compiler chokes on this, use -1 or 0xff whichever works for you #define UNINITIALIZED_CHAR '\xff' @@ -257,9 +256,13 @@ Game* GAMImporter::LoadGame(Game *newGame, int ver_override) if (version == GAM_VER_PST) { //loading maze if (MazeOffset) { - newGame->mazedata = (ieByte*)malloc(MAZE_DATA_SIZE); + //Don't allocate memory in plugins (MSVC chokes on this) + newGame->AllocateMazeData(); str->Seek(MazeOffset, GEM_STREAM_START ); - str->Read(newGame->mazedata, MAZE_DATA_SIZE); + for (i = 0; imazedata+i*MAZE_ENTRY_SIZE); + } + GetMazeHeader(newGame->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); } str->Seek( FamiliarsOffset, GEM_STREAM_START ); } else { @@ -353,7 +356,8 @@ Actor* GAMImporter::GetActor(Holder aM, bool is_in_party ) str->ReadDword( &pcInfo.Interact[i] ); //interact counters } - if (version==GAM_VER_GEMRB || version==GAM_VER_IWD2) { + bool extended = version==GAM_VER_GEMRB || version==GAM_VER_IWD2; + if (extended) { ieResRef tmp; for (i = 0; i < 4; i++) { @@ -499,7 +503,7 @@ Actor* GAMImporter::GetActor(Holder aM, bool is_in_party ) // actor->CreateStats(); PCStatsStruct *ps = actor->PCStats; - GetPCStats(ps); + GetPCStats(ps, extended); memcpy(ps->QSlots, pcInfo.QSlots, sizeof(pcInfo.QSlots) ); memcpy(ps->QuickSpells, pcInfo.QuickSpellResRef, MAX_QSLOTS*sizeof(ieResRef) ); memcpy(ps->QuickSpellClass, pcInfo.QuickSpellClass, MAX_QSLOTS ); @@ -523,7 +527,7 @@ Actor* GAMImporter::GetActor(Holder aM, bool is_in_party ) return actor; } -void GAMImporter::GetPCStats (PCStatsStruct *ps) +void GAMImporter::GetPCStats (PCStatsStruct *ps, bool extended) { int i; @@ -553,6 +557,18 @@ void GAMImporter::GetPCStats (PCStatsStruct *ps) if (core->HasFeature(GF_SOUNDFOLDERS) ) { str->Read( ps->SoundFolder, 32); } + + //iwd2 has some PC only stats that the player can set (this can be done via a guiscript interface) + if (extended) { + //3 - expertise + //4 - power attack + //5 - arterial strike + //6 - hamstring + //7 - rapid shot + for (i=0;i<16;i++) { + str->ReadDword( &ps->ExtraSettings[i] ); + } + } } GAMJournalEntry* GAMImporter::GetJournalEntry() @@ -629,7 +645,8 @@ int GAMImporter::GetStoredFileSize(Game *game) if (game->mazedata) { MazeOffset = headersize; - headersize += MAZE_DATA_SIZE; + //due to alignment the internal size is not the same as the external size + headersize += MAZE_DATA_SIZE_HARDCODED; } else { MazeOffset = 0; } @@ -662,7 +679,11 @@ int GAMImporter::GetStoredFileSize(Game *game) SavedLocOffset = headersize; SavedLocCount = game->GetSavedLocationCount(); - headersize +=SavedLocCount*12; + //there is an unknown dword at the end of iwd2 savegames + if (game->version==GAM_VER_IWD2) { + headersize += 4; + } + headersize += SavedLocCount*12; PPLocOffset = headersize; PPLocCount = game->GetPlaneLocationCount(); @@ -687,10 +708,19 @@ int GAMImporter::PutJournals(DataStream *stream, Game *game) return 0; } -//only in ToB +//only in ToB (and iwd2) int GAMImporter::PutSavedLocations(DataStream *stream, Game *game) { ieWord tmpWord; + ieDword filling = 0; + + //iwd2 has a single 0 dword here (at the end of the file) + //it could be a hacked out saved location list (inherited from SoA) + //if the field is missing, original engine cannot load this saved game + if (game->version==GAM_VER_IWD2) { + stream->WriteDword(&filling); + return 0; + } for (unsigned int i=0;iGetSavedLocationEntry(i); @@ -858,7 +888,7 @@ int GAMImporter::PutActor(DataStream *stream, Actor *ac, ieDword CRESize, ieDwor int i; ieDword tmpDword; ieWord tmpWord; - char filling[194]; + char filling[130]; memset(filling,0,sizeof(filling) ); if (ac->Selected) { @@ -1022,7 +1052,12 @@ int GAMImporter::PutActor(DataStream *stream, Actor *ac, ieDword CRESize, ieDwor stream->Write(ac->PCStats->SoundFolder, 32); } if (version==GAM_VER_IWD2 || version==GAM_VER_GEMRB) { - stream->Write(filling, 194); + //I don't know how many fields are actually used in IWD2 saved game + //but we got at least 8 (and only 5 of those are actually used) + for(i=0;i<16;i++) { + stream->WriteDword( &ac->PCStats->ExtraSettings[i]); + } + stream->Write(filling, 130); } return 0; @@ -1083,9 +1118,75 @@ int GAMImporter::PutNPCs(DataStream *stream, Game *game) return 0; } +void GAMImporter::GetMazeHeader(void *memory) +{ + maze_header *m = (maze_header *) memory; + str->ReadDword( &m->maze_sizex ); + str->ReadDword( &m->maze_sizey ); + str->ReadDword( &m->pos1x ); + str->ReadDword( &m->pos1y ); + str->ReadDword( &m->pos2x ); + str->ReadDword( &m->pos2y ); + str->ReadDword( &m->pos3x ); + str->ReadDword( &m->pos3y ); + str->ReadDword( &m->pos4x ); + str->ReadDword( &m->pos4y ); + str->ReadDword( &m->trapcount ); + str->ReadDword( &m->initialized ); + str->ReadDword( &m->unknown2c ); + str->ReadDword( &m->unknown30 ); +} + +void GAMImporter::GetMazeEntry(void *memory) +{ + maze_entry *h = (maze_entry *) memory; + + str->ReadDword( &h->unknown00 ); + str->ReadDword( &h->valid ); + str->ReadDword( &h->accessible ); + str->ReadDword( &h->traptype ); + str->ReadDword( &h->trapped ); + str->ReadWord( &h->walls ); + str->ReadDword( &h->unknown16 ); +} + +void GAMImporter::PutMazeHeader(DataStream *stream, void *memory) +{ + maze_header *m = (maze_header *) memory; + stream->WriteDword( &m->maze_sizex ); + stream->WriteDword( &m->maze_sizey ); + stream->WriteDword( &m->pos1x ); + stream->WriteDword( &m->pos1y ); + stream->WriteDword( &m->pos2x ); + stream->WriteDword( &m->pos2y ); + stream->WriteDword( &m->pos3x ); + stream->WriteDword( &m->pos3y ); + stream->WriteDword( &m->pos4x ); + stream->WriteDword( &m->pos4y ); + stream->WriteDword( &m->trapcount ); + stream->WriteDword( &m->initialized ); + stream->WriteDword( &m->unknown2c ); + stream->WriteDword( &m->unknown30 ); +} + +void GAMImporter::PutMazeEntry(DataStream *stream, void *memory) +{ + maze_entry *h = (maze_entry *) memory; + stream->WriteDword( &h->unknown00 ); + stream->WriteDword( &h->valid ); + stream->WriteDword( &h->accessible ); + stream->WriteDword( &h->trapped ); + stream->WriteDword( &h->traptype ); + stream->WriteWord( &h->walls ); + stream->WriteDword( &h->unknown16 ); +} + int GAMImporter::PutMaze(DataStream *stream, Game *game) { - stream->Write( game->mazedata, MAZE_DATA_SIZE); + for(int i=0;i<64;i++) { + PutMazeEntry(stream, game->mazedata+i*MAZE_ENTRY_SIZE); + } + PutMazeHeader(stream, game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); return 0; } diff --git a/project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.h b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h similarity index 91% rename from project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.h rename to project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h index a59ee2337..fba05f0fe 100644 --- a/project/jni/application/gemrb/src/plugins/GAMImporter/GAMImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h @@ -59,7 +59,7 @@ public: int PutGame(DataStream *stream, Game *game); private: Actor* GetActor(Holder aM, bool is_in_party ); - void GetPCStats(PCStatsStruct* ps); + void GetPCStats(PCStatsStruct* ps, bool extended); GAMJournalEntry* GetJournalEntry(); int PutHeader(DataStream *stream, Game *game); @@ -69,6 +69,10 @@ private: int PutJournals(DataStream *stream, Game *game); int PutVariables( DataStream *stream, Game *game); int PutKillVars(DataStream *stream, Game *game); + void GetMazeHeader(void *memory); + void GetMazeEntry(void *memory); + void PutMazeHeader(DataStream *stream, void *memory); + void PutMazeEntry(DataStream *stream, void *memory); int PutMaze(DataStream *stream, Game *game); int PutFamiliars(DataStream *stream, Game *game); int PutSavedLocations(DataStream *stream, Game *game); diff --git a/project/jni/application/gemrb/src/plugins/GAMImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/GAMImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/GAMImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/GUIScript/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/GUIScript/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/GUIScript.cpp b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp similarity index 97% rename from project/jni/application/gemrb/src/plugins/GUIScript/GUIScript.cpp rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp index 609df9a1b..18ccf9ff1 100644 --- a/project/jni/application/gemrb/src/plugins/GUIScript/GUIScript.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp @@ -77,7 +77,6 @@ GUIScript *gs = NULL; #define METHOD(name, args) {#name, GemRB_ ## name, args, GemRB_ ## name ## __doc} static int SpecialItemsCount = -1; -static int SpecialSpellsCount = -1; static int StoreSpellsCount = -1; static int UsedItemsCount = -1; static int ItemSoundsCount = -1; @@ -87,6 +86,9 @@ static int ItemSoundsCount = -1; #define CRI_EQUIP 1 #define CRI_SWAP 2 +//bit used in SetCreatureStat to access some fields +#define EXTRASETTINGS 0x1000 + struct UsedItemType { ieResRef itemname; ieVariable username; //death variable @@ -94,24 +96,15 @@ struct UsedItemType { int flags; }; -struct SpellDescType { - ieResRef resref; - ieStrRef value; -}; - typedef char EventNameType[17]; -#define IS_DROP 0 -#define IS_GET 1 +#define IS_DROP 0 +#define IS_GET 1 typedef ieResRef ResRefPairs[2]; #define UNINIT_IEDWORD 0xcccccccc static SpellDescType *SpecialItems = NULL; -static SpellDescType *SpecialSpells = NULL; - -#define SP_IDENTIFY 1 //any spell that cannot be cast from the menu -#define SP_SILENCE 2 //any spell that can be cast in silence static SpellDescType *StoreSpells = NULL; static ItemExtHeader *ItemArray = NULL; @@ -276,6 +269,16 @@ static inline bool CheckStat(Actor * actor, ieDword stat, ieDword value, int op) static int GetCreatureStat(Actor *actor, unsigned int StatID, int Mod) { + //this is a hack, if more PCStats fields are needed, improve it + if (StatID&EXTRASETTINGS) { + PCStatsStruct *ps = actor->PCStats; + if (!ps) { + //the official invalid value in GetStat + return 0xdadadada; + } + StatID&=15; + return ps->ExtraSettings[StatID]; + } if (Mod) { return actor->GetStat( StatID ); } @@ -284,6 +287,17 @@ static int GetCreatureStat(Actor *actor, unsigned int StatID, int Mod) static int SetCreatureStat(Actor *actor, unsigned int StatID, int StatValue, bool pcf) { + //this is a hack, if more PCStats fields are needed, improve it + if (StatID&EXTRASETTINGS) { + PCStatsStruct *ps = actor->PCStats; + if (!ps) { + return 0; + } + StatID&=15; + ps->ExtraSettings[StatID] = StatValue; + return 1; + } + if (pcf) { actor->SetBase( StatID, StatValue ); } else { @@ -1310,6 +1324,43 @@ static PyObject* GemRB_TextEdit_SetBufferLength(PyObject * /*self*/, PyObject* a return Py_None; } +PyDoc_STRVAR( GemRB_TextArea_SelectText__doc, +"SelectText(WindowIndex, ControlIndex, String|Strref) => void\n\n" +"Tries to set the Variable of the TextArea control to the linenumber of the referenced string."); + +static PyObject* GemRB_TextArea_SelectText(PyObject * /*self*/, PyObject* args) +{ + PyObject* wi, * ci, * str; + long WindowIndex, ControlIndex; + char* string; + + if (!PyArg_UnpackTuple( args, "ref", 3, 3, &wi, &ci, &str )) { + return AttributeError( GemRB_TextArea_SelectText__doc ); + } + + if (!PyObject_TypeCheck( wi, &PyInt_Type ) || + !PyObject_TypeCheck( ci, &PyInt_Type ) || + ( !PyObject_TypeCheck( str, &PyString_Type ) && + !PyObject_TypeCheck( str, &PyInt_Type ) )) { + return AttributeError( GemRB_TextArea_SelectText__doc ); + } + + WindowIndex = PyInt_AsLong( wi ); + ControlIndex = PyInt_AsLong( ci ); + if (PyObject_TypeCheck( str, &PyString_Type )) { + string = PyString_AsString( str ); + if (string == NULL) { + return RuntimeError("Null string received"); + } + TextArea* ta = (TextArea *) GetControl( WindowIndex, ControlIndex, IE_GUI_TEXTAREA ); + if (!ta) + return NULL; + ta->SelectText( string ); + } + Py_INCREF( Py_None ); + return Py_None; +} + PyDoc_STRVAR( GemRB_Control_SetText__doc, "SetText(WindowIndex, ControlIndex, String|Strref) => int\n\n" "Sets the Text of a control in a Window." ); @@ -2444,7 +2495,7 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args) links[WMP_WEST] = atoi(newarea->QueryField(i,12)); //this is the number of links in the 2da, we don't need it int linksto = atoi(newarea->QueryField(i,13)); - + unsigned int local = 0; int linkcnt = wmap->GetLinkCount(); for (k=0;k<4;k++) { @@ -2472,7 +2523,7 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args) memset(entry->LoadScreenResRef, 0, 8); memcpy(entry->AreaLinksIndex, indices, sizeof(entry->AreaLinksIndex) ); memcpy(entry->AreaLinksCount, links, sizeof(entry->AreaLinksCount) ); - + int thisarea = wmap->GetEntryCount(); wmap->AddAreaEntry(entry); wmap->AreaEntriesCount++; @@ -2918,7 +2969,7 @@ static PyObject* GemRB_GameGetExpansion(PyObject * /*self*/, PyObject* /*args*/) Game *game = core->GetGame(); if (!game) { return RuntimeError( "No game loaded!" ); - } + } return PyInt_FromLong( game->Expansion ); } @@ -3250,8 +3301,6 @@ static PyObject* GemRB_Button_SetSprite2D(PyObject * /*self*/, PyObject* args) CObject spr(obj); - if (spr) - spr->acquire(); btn->SetPicture( spr.get() ); Py_INCREF( Py_None ); @@ -4393,11 +4442,11 @@ PyDoc_STRVAR( GemRB_SetJournalEntry__doc, static PyObject* GemRB_SetJournalEntry(PyObject * /*self*/, PyObject * args) { - int section=-1, chapter = -1, strref; + int section=-1, chapter = -1, strref; - if (!PyArg_ParseTuple( args, "i|ii", &strref, §ion, &chapter )) { - return AttributeError( GemRB_SetJournalEntry__doc ); - } + if (!PyArg_ParseTuple( args, "i|ii", &strref, §ion, &chapter )) { + return AttributeError( GemRB_SetJournalEntry__doc ); + } Game *game = core->GetGame(); if (!game) { @@ -4421,8 +4470,8 @@ static PyObject* GemRB_SetJournalEntry(PyObject * /*self*/, PyObject * args) game->AddJournalEntry( chapter, section, strref); } - Py_INCREF( Py_None ); - return Py_None; + Py_INCREF( Py_None ); + return Py_None; } PyDoc_STRVAR( GemRB_GameIsBeastKnown__doc, @@ -6201,60 +6250,6 @@ static PyObject* GemRB_GetStoreDrink(PyObject * /*self*/, PyObject* args) return dict; } -static void ReadSpecialSpells() -{ - int i; - - SpecialSpellsCount = 0; - int table = gamedata->LoadTable("splspec"); - if (table>=0) { - Holder tab = gamedata->GetTable(table); - if (!tab) goto table_loaded; - SpecialSpellsCount = tab->GetRowCount(); - SpecialSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialSpellsCount); - for (i=0;iGetRowName(i),8 ); - //if there are more flags, compose this value into a bitfield - SpecialSpells[i].value = atoi(tab->QueryField(i,0) ); - } -table_loaded: - gamedata->DelTable(table); - } -} - -int GetSpecialSpell(ieResRef resref) -{ - if (SpecialSpellsCount==-1) { - ReadSpecialSpells(); - } - for (int i=0;iGetStat(IE_STATE_ID) & STATE_SILENCED ) { - if (!(sp&SP_SILENCE)) { - return 1; - } - } - - return 0; -} - static void ReadUsedItems() { int i; @@ -8348,7 +8343,7 @@ static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* arg // Identify is misclassified and has Target 3 (Dead char) ieDword spelltype = ResolveSpellNumber(spell->spellname)/1000; - if (CheckSpecialSpell(spell->spellname, actor) || (disabled_spellcasting&(1<CheckSpecialSpell(spell->spellname, actor) || (disabled_spellcasting&(1<SetState(IE_GUI_BUTTON_DISABLED); btn->EnableBorder(1, IE_GUI_BUTTON_DISABLED); PyObject *Function = PyDict_GetItemString(dict, "UpdateActionsWindow"); @@ -8923,13 +8918,14 @@ static PyObject* GemRB_SetModalState(PyObject * /*self*/, PyObject* args) PyDoc_STRVAR( GemRB_SpellCast__doc, "SpellCast(slot, type, spell[, global])\n\n" "Makes the actor try to cast a spell. Type is the spell type like 3 for normal spells and 4 for innates.\n" +"If type is -1, then the castable spell list will be deleted and no spell will be cast.\n" "Spell is the index of the spell in the memorised spell list.\n" -"If global is set, the actor will be looked up by its global ID instead of party slot."); +"If global is set, the actor will be looked up by its global ID instead of party slot.\n"); static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) { unsigned int slot; - unsigned int type; + int type; unsigned int spell; int global = 0; @@ -8950,6 +8946,13 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) return RuntimeError( "Actor not found" ); } + //don't cast anything, just reinit the spell list + if (type==-1) { + actor->spellbook.ClearSpellInfo(); + Py_INCREF( Py_None ); + return Py_None; + } + SpellExtHeader spelldata; // = SpellArray[spell]; actor->spellbook.GetSpellInfo(&spelldata, type, spell, 1); @@ -8970,23 +8973,23 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) switch (spelldata.Target) { case TARGET_SELF: // FIXME: GA_NO_DEAD and such are not actually used by SetupCasting - gc->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, GA_NO_DEAD, spelldata.TargetNumber); + gc->SetupCasting(spelldata.spellname, spelldata.type, spelldata.level, spelldata.slot, actor, GA_NO_DEAD, spelldata.TargetNumber); gc->TryToCast(actor, actor); break; case TARGET_NONE: //reset the cursor gc->ResetTargetMode(); - //this is always instant casting + //this is always instant casting without spending the spell core->ApplySpell(spelldata.spellname, actor, actor, 0); break; case TARGET_AREA: - gc->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, GA_POINT, spelldata.TargetNumber); + gc->SetupCasting(spelldata.spellname, spelldata.type, spelldata.level, spelldata.slot, actor, GA_POINT, spelldata.TargetNumber); break; case TARGET_CREA: - gc->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, GA_NO_DEAD, spelldata.TargetNumber); + gc->SetupCasting(spelldata.spellname, spelldata.type, spelldata.level, spelldata.slot, actor, GA_NO_DEAD, spelldata.TargetNumber); break; case TARGET_DEAD: - gc->SetupCasting(spelldata.type, spelldata.level, spelldata.slot, actor, 0, spelldata.TargetNumber); + gc->SetupCasting(spelldata.spellname, spelldata.type, spelldata.level, spelldata.slot, actor, 0, spelldata.TargetNumber); break; case TARGET_INV: //bring up inventory in the end??? @@ -9286,9 +9289,6 @@ static PyObject* GemRB_HasSpecialSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &PartyID, &itemtype, &useup)) { return AttributeError( GemRB_HasSpecialSpell__doc ); } - if (SpecialSpellsCount==-1) { - ReadSpecialSpells(); - } Game *game = core->GetGame(); if (!game) { @@ -9298,10 +9298,14 @@ static PyObject* GemRB_HasSpecialSpell(PyObject * /*self*/, PyObject* args) if (!actor) { return RuntimeError( "Actor not found" ); } - int i = SpecialSpellsCount; + int i = core->GetSpecialSpellsCount(); + if (i == -1) { + return RuntimeError( "Game has no splspec.2da table!" ); + } + SpellDescType *special_spells = core->GetSpecialSpells(); while(i--) { - if (itemtype&SpecialSpells[i].value) { - if (actor->spellbook.HaveSpell(SpecialSpells[i].resref,useup)) { + if (itemtype&special_spells[i].value) { + if (actor->spellbook.HaveSpell(special_spells[i].resref,useup)) { if (useup) { //actor->SpellCast(SpecialSpells[i].resref, actor); } @@ -9584,7 +9588,7 @@ static PyObject* GemRB_GetCombatDetails(PyObject * /*self*/, PyObject* args) int speed, style=0; PyObject* dict = PyDict_New(); - if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style)) { + if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, NULL)) { //TODO: handle error, so tohit will still be set correctly? } PyDict_SetItemString(dict, "ToHit", PyInt_FromLong (tohit)); @@ -9706,6 +9710,204 @@ static PyObject* GemRB_SetTickHook(PyObject* /*self*/, PyObject* args) return Py_None; } +PyDoc_STRVAR( GemRB_SetupMaze__doc, +"SetupMaze(x,y)\n\n" +"Initializes a maze of XxY size. " +"The dimensions shouldn't exceed the maximum possible maze size (8x8)."); + +static PyObject* GemRB_SetupMaze(PyObject* /*self*/, PyObject* args) +{ + int xsize, ysize; + + if (!PyArg_ParseTuple( args, "ii", &xsize, &ysize )) { + return AttributeError( GemRB_SetupMaze__doc ); + } + + if ((unsigned) xsize>MAZE_MAX_DIM || (unsigned) ysize>MAZE_MAX_DIM) { + return AttributeError( GemRB_SetupMaze__doc ); + } + + Game *game = core->GetGame(); + if (!game) { + return RuntimeError( "No game loaded!" ); + } + + maze_header *h = (maze_header *) (game->AllocateMazeData()+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); + memset(h, 0, MAZE_HEADER_SIZE); + h->maze_sizex = xsize; + h->maze_sizey = ysize; + for(int i=0;imazedata+i*MAZE_ENTRY_SIZE); + memset(m, 0, MAZE_ENTRY_SIZE); + bool used = (i/MAZE_MAX_DIMvalid = used; + m->accessible = used; + } + Py_INCREF(Py_None); + return Py_None; +} + +PyDoc_STRVAR( GemRB_SetMazeEntry__doc, +"SetMazeEntry(entry, type, value)\n\n" +"Sets a field in a maze entry. " +"The entry index shouldn't exceed the maximum possible maze size (64). " +"The type could be: ME_0, ME_WALLS, ME_TRAP or ME_16."); + +static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args) +{ + int entry; + int index; + int value; + + if (!PyArg_ParseTuple( args, "iii", &entry, &index, &value )) { + return AttributeError( GemRB_SetMazeEntry__doc ); + } + + if (entry<0 || entry>63) { + return AttributeError( GemRB_SetMazeEntry__doc ); + } + + Game *game = core->GetGame(); + if (!game) { + return RuntimeError( "No game loaded!" ); + } + + if (!game->mazedata) { + return RuntimeError( "No maze set up!" ); + } + + maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); + int dims = h->maze_sizex; + maze_entry *m = (maze_entry *) (game->mazedata+entry*MAZE_ENTRY_SIZE); + maze_entry *m2; + switch(index) { + case ME_0: //unknown00 + m->unknown00 = value; + break; + default: + case ME_VALID: + case ME_ACCESSIBLE: + return AttributeError( GemRB_SetMazeEntry__doc ); + break; + case ME_TRAP: //trapped/traptype + if (value==-1) { + m->trapped = 0; + m->traptype = 0; + } else { + m->trapped = 1; + m->traptype = value; + } + break; + case ME_WALLS: + m->walls |= value; + if (value & WALL_EAST) { + if (entry%dims!=dims-1) { + m2 = (maze_entry *) (game->mazedata+(entry+1)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_WEST; + } + } + + if (value & WALL_WEST) { + if (entry%dims) { + m2 = (maze_entry *) (game->mazedata+(entry-1)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_EAST; + } + } + + if (value & WALL_NORTH) { + if (entry>=dims) { + m2 = (maze_entry *) (game->mazedata+(entry-dims)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_SOUTH; + } + } + + if (value & WALL_SOUTH) { + if (entry+dimsmazedata+(entry+dims)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_SOUTH; + } + } + + break; + case ME_16: + m->unknown16 = value; + break; + } + + Py_INCREF(Py_None); + return Py_None; +} + +PyDoc_STRVAR( GemRB_SetMazeData__doc, +"SetMazeData(type, value)\n\n" +"Sets a field in the maze header. " +"The type could be: ME_0, ME_WALLS, ME_TRAP or ME_16."); + +static PyObject* GemRB_SetMazeData(PyObject* /*self*/, PyObject* args) +{ + int entry; + int value; + + if (!PyArg_ParseTuple( args, "ii", &entry, &value )) { + return AttributeError( GemRB_SetMazeData__doc ); + } + + Game *game = core->GetGame(); + if (!game) { + return RuntimeError( "No game loaded!" ); + } + + if (!game->mazedata) { + return RuntimeError( "No maze set up!" ); + } + + + maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); + switch(entry) { + case MH_POS1X: + h->pos1x = value; + break; + case MH_POS1Y: + h->pos1y = value; + break; + case MH_POS2X: + h->pos2x = value; + break; + case MH_POS2Y: + h->pos2y = value; + break; + case MH_POS3X: + h->pos3x = value; + break; + case MH_POS3Y: + h->pos3y = value; + break; + case MH_POS4X: + h->pos4x = value; + break; + case MH_POS4Y: + h->pos4y = value; + break; + case MH_TRAPCOUNT: + h->trapcount = value; + break; + case MH_INITED: + h->initialized = value; + break; + case MH_UNKNOWN2C: + h->unknown2c = value; + break; + case MH_UNKNOWN30: + h->unknown30 = value; + break; + default: + return AttributeError( GemRB_SetMazeData__doc ); + } + + Py_INCREF(Py_None); + return Py_None; +} + static PyMethodDef GemRBMethods[] = { METHOD(ActOnPC, METH_VARARGS), METHOD(AddNewArea, METH_VARARGS), @@ -9858,6 +10060,8 @@ static PyMethodDef GemRBMethods[] = { METHOD(SetJournalEntry, METH_VARARGS), METHOD(SetMapnote, METH_VARARGS), METHOD(SetMasterScript, METH_VARARGS), + METHOD(SetMazeEntry, METH_VARARGS), + METHOD(SetMazeData, METH_VARARGS), METHOD(SetMemorizableSpellsCount, METH_VARARGS), METHOD(SetModalState, METH_VARARGS), METHOD(SetMouseScrollSpeed, METH_VARARGS), @@ -9873,6 +10077,7 @@ static PyMethodDef GemRBMethods[] = { METHOD(SetTimedEvent, METH_VARARGS), METHOD(SetToken, METH_VARARGS), METHOD(SetTooltipDelay, METH_VARARGS), + METHOD(SetupMaze, METH_VARARGS), METHOD(SetupQuickSlot, METH_VARARGS), METHOD(SetVar, METH_VARARGS), METHOD(SoftEndPL, METH_NOARGS), @@ -9950,6 +10155,7 @@ static PyMethodDef GemRBInternalMethods[] = { METHOD(TextArea_MoveText, METH_VARARGS), METHOD(TextArea_Rewind, METH_VARARGS), METHOD(TextArea_Scroll, METH_VARARGS), + METHOD(TextArea_SelectText, METH_VARARGS), METHOD(TextArea_SetHistory, METH_VARARGS), METHOD(TextEdit_ConvertEdit, METH_VARARGS), METHOD(TextEdit_SetBufferLength, METH_VARARGS), @@ -10008,10 +10214,6 @@ GUIScript::~GUIScript(void) free(StoreSpells); StoreSpells=NULL; } - if (SpecialSpells) { - free(SpecialSpells); - SpecialSpells=NULL; - } if (SpecialItems) { free(SpecialItems); SpecialItems=NULL; @@ -10026,7 +10228,6 @@ GUIScript::~GUIScript(void) } StoreSpellsCount = -1; - SpecialSpellsCount = -1; SpecialItemsCount = -1; UsedItemsCount = -1; ItemSoundsCount = -1; diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/GUIScript.h b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/GUIScript/GUIScript.h rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/GUIScript/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/GUIScript/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/PythonHelpers.cpp b/project/jni/application/gemrb/gemrb/plugins/GUIScript/PythonHelpers.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/GUIScript/PythonHelpers.cpp rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/PythonHelpers.cpp diff --git a/project/jni/application/gemrb/src/plugins/GUIScript/PythonHelpers.h b/project/jni/application/gemrb/gemrb/plugins/GUIScript/PythonHelpers.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/GUIScript/PythonHelpers.h rename to project/jni/application/gemrb/gemrb/plugins/GUIScript/PythonHelpers.h diff --git a/project/jni/application/gemrb/src/plugins/IDSImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/IDSImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/IDSImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporter.h b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporter.h rename to project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h diff --git a/project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporterDefs.h b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/IDSImporter/IDSImporterDefs.h rename to project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h diff --git a/project/jni/application/gemrb/src/plugins/IDSImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/IDSImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/IDSImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/INIImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/INIImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/INIImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/INIImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/INIImporter/INIImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/INIImporter/INIImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/INIImporter/INIImporter.h b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/INIImporter/INIImporter.h rename to project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h diff --git a/project/jni/application/gemrb/src/plugins/INIImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/INIImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/INIImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/INIImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/ITMImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/ITMImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/ITMImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/ITMImporter/ITMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/ITMImporter/ITMImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/ITMImporter/ITMImporter.h b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ITMImporter/ITMImporter.h rename to project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h diff --git a/project/jni/application/gemrb/src/plugins/ITMImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/ITMImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/ITMImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/IWDOpcodes/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/IWDOpcodes/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/IWDOpcodes/IWDOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp similarity index 98% rename from project/jni/application/gemrb/src/plugins/IWDOpcodes/IWDOpcodes.cpp rename to project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp index b46d22152..5efe18cf7 100644 --- a/project/jni/application/gemrb/src/plugins/IWDOpcodes/IWDOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp @@ -41,7 +41,6 @@ static bool enhanced_effects = false; //a scripting object for enemy (used for enemy in line of sight check) static Trigger *Enemy = NULL; -#define PI_CONFUSION 3 #define PI_PROTFROMEVIL 9 #define PI_FREEACTION 19 #define PI_BARKSKIN 20 @@ -116,14 +115,14 @@ static int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx); //1 static int fx_zombielord_aura (Scriptable* Owner, Actor* target, Effect* fx); //101, duff in iwd2 static int fx_resist_spell (Scriptable* Owner, Actor* target, Effect* fx); //102 static int fx_summon_creature2 (Scriptable* Owner, Actor* target, Effect* fx); //103 -//int fx_avatar_removal (Scriptable* Owner, Actor* target, Effect* fx); //104 +static int fx_avatar_removal (Scriptable* Owner, Actor* target, Effect* fx); //104 //int fx_immunity_effect2 (Scriptable* Owner, Actor* target, Effect* fx); //105 static int fx_summon_pomab (Scriptable* Owner, Actor* target, Effect* fx); //106 static int fx_control_undead (Scriptable* Owner, Actor* target, Effect* fx); //107 static int fx_static_charge (Scriptable* Owner, Actor* target, Effect* fx); //108 static int fx_cloak_of_fear (Scriptable* Owner, Actor* target, Effect* fx); //109 //int fx_movement_modifier (Scriptable* Owner, Actor* target, Effect* fx); //10a -static int fx_remove_confusion (Scriptable* Owner, Actor* target, Effect* fx);//10b +//int fx_remove_confusion (Scriptable* Owner, Actor* target, Effect* fx);//10b static int fx_eye_of_the_mind (Scriptable* Owner, Actor* target, Effect* fx);//10c static int fx_eye_of_the_sword (Scriptable* Owner, Actor* target, Effect* fx);//10d static int fx_eye_of_the_mage (Scriptable* Owner, Actor* target, Effect* fx);//10e @@ -255,11 +254,11 @@ static EffectRef effectnames[] = { { "UmberHulkGaze", fx_umberhulk_gaze, -1}, //100 { "ZombieLordAura", fx_zombielord_aura, -1},//101, duff in iwd2 { "SummonCreature2", fx_summon_creature2, -1}, //103 + { "AvatarRemoval", fx_avatar_removal, -1}, //104 { "SummonPomab", fx_summon_pomab, -1}, //106 { "ControlUndead", fx_control_undead, -1}, //107 { "StaticCharge", fx_static_charge, -1}, //108 { "CloakOfFear", fx_cloak_of_fear, -1}, //109 how/iwd2 - { "RemoveConfusion", fx_remove_confusion, -1},//10b { "EyeOfTheMind", fx_eye_of_the_mind, -1}, //10c { "EyeOfTheSword", fx_eye_of_the_sword, -1}, //10d { "EyeOfTheMage", fx_eye_of_the_mage, -1}, //10e @@ -1204,6 +1203,13 @@ int fx_salamander_aura (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } + //timing + ieDword time = core->GetGame()->GameTime; + if ((fx->Parameter4==time) || (time%6) ) { + return FX_APPLIED; + } + fx->Parameter4=time; + ieDword damage = DAMAGE_FIRE; if (fx->Parameter2==1) { @@ -1218,7 +1224,6 @@ int fx_salamander_aura (Scriptable* Owner, Actor* target, Effect* fx) //it is a specially hacked effect to ignore certain races //from the confusion effect static EffectRef fx_confusion_ref={"State:Confused",NULL,-1}; -static EffectRef fx_display_portrait_icon_ref={"Icon:Display",NULL,-1}; static EffectRef fx_immunity_resource_ref={"Protection:Spell",NULL,-1}; int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx) @@ -1366,7 +1371,13 @@ int fx_summon_creature2 (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } -//0x104 AvatarRemovalModifier (same as bg2) +//0x104 AvatarRemoval +int fx_avatar_removal (Scriptable* /*Owner*/, Actor* target, Effect* /*fx*/) +{ + BASE_SET(IE_AVATARREMOVAL, 1); + return FX_NOT_APPLIED; +} + //0x105 immunity to effect (same as bg2?) //0x106 SummonPomab @@ -1542,16 +1553,8 @@ int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx) } //0x10a MovementRateModifier3 (Like bg2) -//0x10b RemoveConfusion -int fx_remove_confusion (Scriptable* /*Owner*/, Actor* target, Effect* fx) -{ - if (0) printf( "fx_remove_confusion (%2d)\n", fx->Opcode ); - BASE_STATE_CURE(STATE_CONFUSED); - target->fxqueue.RemoveAllEffects(fx_confusion_ref); - target->fxqueue.RemoveAllEffects(fx_umberhulk_gaze_ref); - target->fxqueue.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref,PI_CONFUSION); - return FX_APPLIED; -} +//0x10b Cure:Confusion (Like bg2) + //0x10c EyeOfTheMind int fx_eye_of_the_mind (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1730,10 +1733,26 @@ int fx_shroud_of_flame (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } - //timing - if (core->GetGame()->GameTime%6) { + //don't apply it twice in a round + if (EXTSTATE_GET(EXTSTATE_SHROUD)) { return FX_APPLIED; } + EXTSTATE_SET(EXTSTATE_SHROUD); + //directly modifying the color of the target + if (fx->Parameter2==1) { + target->SetColorMod(0xff, RGBModifier::ADD, -1, 0, 0, 0x96); + } + else { + target->SetColorMod(0xff, RGBModifier::ADD, -1, 0x96, 0, 0); + } + + //timing + ieDword time = core->GetGame()->GameTime; + if ((fx->Parameter4==time) || (time%6) ) { + return FX_APPLIED; + } + fx->Parameter4=time; + //inflicts damage calculated by dice values+parameter1 //creates damage opcode on everyone around. fx->Parameter2 - 0 fire, 1 - ice ieDword damage = DAMAGE_FIRE; @@ -1742,13 +1761,16 @@ int fx_shroud_of_flame (Scriptable* Owner, Actor* target, Effect* fx) damage = DAMAGE_COLD; } - target->Damage(fx->Parameter1, DAMAGE_FIRE, Owner); - ApplyDamageNearby(Owner, target, fx, DAMAGE_FIRE); + target->Damage(fx->Parameter1, damage, Owner); + ApplyDamageNearby(Owner, target, fx, damage); return FX_APPLIED; } +static ieResRef resref_sof1={"effsof1"}; +static ieResRef resref_sof2={"effsof2"}; + //0x116 ShroudOfFlame (iwd2) -int fx_shroud_of_flame2 (Scriptable* /*Owner*/, Actor* target, Effect* fx) +int fx_shroud_of_flame2 (Scriptable* Owner, Actor* target, Effect* fx) { if (0) printf( "fx_shroud_of_flame2 (%2d)\n", fx->Opcode ); @@ -1758,18 +1780,32 @@ int fx_shroud_of_flame2 (Scriptable* /*Owner*/, Actor* target, Effect* fx) } if (target->SetSpellState( SS_FLAMESHROUD)) return FX_APPLIED; + EXTSTATE_SET(EXTSTATE_SHROUD); //just for compatibility if(enhanced_effects) { target->SetColorMod(0xff, RGBModifier::ADD, 1, 0xa0, 0, 0); } - //timing - //if (core->GetGame()->GameTime%6) { - // return FX_APPLIED; - //} - //apply resource on hitter - memcpy(target->applyWhenBeingHit,fx->Resource,sizeof(ieResRef)); + //actually, this should be a list of triggers + if (fx->Resource[0]) { + memcpy(target->applyWhenBeingHit,fx->Resource,sizeof(ieResRef)); + } else { + memcpy(target->applyWhenBeingHit,resref_sof1,sizeof(ieResRef)); + } + + //timing + ieDword time = core->GetGame()->GameTime; + if ((fx->Parameter4==time) || (time%6) ) { + return FX_APPLIED; + } + fx->Parameter4=time; + + if (fx->Resource2[0]) { + core->ApplySpell(fx->Resource2, target, Owner, fx->Power); + } else { + core->ApplySpell(resref_sof2, target, Owner, fx->Power); + } return FX_APPLIED; } diff --git a/project/jni/application/gemrb/src/plugins/IWDOpcodes/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/IWDOpcodes/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/Dictionary.cpp b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/Dictionary.cpp rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/Dictionary.h b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/Dictionary.h rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.h diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/KEYImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/KEYImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/KEYImporter.h b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/KEYImporter.h rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h diff --git a/project/jni/application/gemrb/src/plugins/KEYImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/KEYImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/KEYImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/MOSImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/MOSImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/MOSImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/MOSImporter/MOSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/MOSImporter/MOSImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/MOSImporter/MOSImporter.h b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/MOSImporter/MOSImporter.h rename to project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.h diff --git a/project/jni/application/gemrb/src/plugins/MOSImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/MOSImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/MOSImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/MUSImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/MUSImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/MUSImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/MUSImporter/MUSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/MUSImporter/MUSImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/MUSImporter/MUSImporter.h b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/MUSImporter/MUSImporter.h rename to project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.h diff --git a/project/jni/application/gemrb/src/plugins/MUSImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/MUSImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/MUSImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/MVEPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/MVEPlayer.cpp rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/MVEPlayer.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/MVEPlayer.h rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/gstmvedemux.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h similarity index 98% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/gstmvedemux.h rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h index c8ed20bb8..c8908c297 100644 --- a/project/jni/application/gemrb/src/plugins/MVEPlayer/gstmvedemux.h +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h @@ -121,8 +121,8 @@ struct _GstMveDemuxStream { /*guint8 bpp;*/ /* bytes per pixel */ guint8 *code_map; /*gboolean code_map_avail;*/ - guint8 *back_buf1; - guint8 *back_buf2; + guint16 *back_buf1; + guint16 *back_buf2; guint32 max_block_offset; /*GstBuffer *palette; GstBuffer *buffer;*/ diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mve.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/mve.h rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve.h diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp similarity index 97% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.cpp rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp index 8c4085362..b8edf7d11 100644 --- a/project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp @@ -311,15 +311,15 @@ void MVEPlayer::segment_video_init(unsigned char version) { if (video_back_buf) free(video_back_buf); unsigned int size = width * height * (truecolour ? 2 : 1); - video_back_buf = (char *)malloc(size * 2); + video_back_buf = (guint16 *)malloc(size * 2); memset(video_back_buf, 0, size * 2); video_data = (GstMveDemuxStream *)malloc(sizeof(GstMveDemuxStream)); video_data->code_map = NULL; video_data->width = width; video_data->height = height; - video_data->back_buf1 = (guint8 *)video_back_buf; - video_data->back_buf2 = (guint8 *)video_back_buf + size; + video_data->back_buf1 = video_back_buf; + video_data->back_buf2 = video_back_buf + size/2; video_data->max_block_offset = (height - 7) * width - 8; } @@ -387,7 +387,7 @@ void MVEPlayer::segment_video_data(unsigned short size) { char *data = buffer + 14; if (flags & MVE_VIDEO_DELTA_FRAME) { - guint8 *temp = video_data->back_buf1; + guint16 *temp = video_data->back_buf1; video_data->back_buf1 = video_data->back_buf2; video_data->back_buf2 = temp; } @@ -404,7 +404,7 @@ void MVEPlayer::segment_video_play() { } else { unsigned int dest_x = (outputwidth - video_data->width) >> 1; unsigned int dest_y = (outputheight - video_data->height) >> 1; - host->showFrame(video_data->back_buf1, video_data->width, video_data->height, 0, 0, video_data->width, video_data->height, dest_x, dest_y); + host->showFrame( (guint8 *) video_data->back_buf1, video_data->width, video_data->height, 0, 0, video_data->width, video_data->height, dest_x, dest_y); } video_rendered_frame = true; diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.h similarity index 98% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.h rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.h index d8831a300..77e1fb7b0 100644 --- a/project/jni/application/gemrb/src/plugins/MVEPlayer/mve_player.h +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.h @@ -39,7 +39,7 @@ protected: struct _GstMveDemuxStream *video_data; unsigned short video_width; unsigned short video_height; - char *video_back_buf; + unsigned short *video_back_buf; bool truecolour; bool video_rendered_frame; unsigned int video_frameskip; diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mveaudiodec.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mveaudiodec.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/MVEPlayer/mveaudiodec.cpp rename to project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mveaudiodec.cpp diff --git a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec16.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec16.cpp new file mode 100644 index 000000000..66d158cfc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec16.cpp @@ -0,0 +1,844 @@ +/* + * Interplay MVE Video Decoder (16 bit) + * Copyright (C) 2003 the ffmpeg project, Mike Melanson + * (C) 2006 Jens Granseuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * For more information about the Interplay MVE format, visit: + * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt + */ + +#include "gstmvedemux.h" +#include + +#define PIXEL(s) GST_READ_UINT16_LE (s) + +#define CHECK_STREAM(l, n) \ + do { \ + if (G_UNLIKELY (*(l) < (n))) { \ + GST_ERROR ("wanted to read %d bytes from stream, %d available", (n), *(l)); \ + return -1; \ + } \ + *(l) -= (n); \ + } while (0) + +/* copy an 8x8 block from the stream to the frame buffer */ +static int +ipvideo_copy_block (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned short *src, int offset) +{ + int i; + int frame_offset; + + frame_offset = frame - s->back_buf1 + offset; + + if (G_UNLIKELY (frame_offset < 0)) { + GST_ERROR ("frame offset < 0 (%d)", frame_offset); + return -1; + } else if (G_UNLIKELY ((guint32)frame_offset > s->max_block_offset)) { + GST_ERROR ("frame offset above limit (%d > %u)", + frame_offset, s->max_block_offset); + return -1; + } + + for (i = 0; i < 8; ++i) { + memcpy (frame, src, 16); + frame += s->width; + src += s->width; + } + + return 0; +} + +static int +ipvideo_decode_0x2 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + unsigned char B; + int x, y; + int offset; + + /* copy block from 2 frames ago using a motion vector */ + CHECK_STREAM (len, 1); + B = *(*data)++; + + if (B < 56) { + x = 8 + (B % 7); + y = B / 7; + } else { + x = -14 + ((B - 56) % 29); + y = 8 + ((B - 56) / 29); + } + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + offset, offset); +} + +static int +ipvideo_decode_0x3 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + unsigned char B; + int x, y; + int offset; + + /* copy 8x8 block from current frame from an up/left block */ + CHECK_STREAM (len, 1); + B = *(*data)++; + + if (B < 56) { + x = -(8 + (B % 7)); + y = -(B / 7); + } else { + x = -(-14 + ((B - 56) % 29)); + y = -(8 + ((B - 56) / 29)); + } + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + offset, offset); +} + +static int +ipvideo_decode_0x4 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char B; + int offset; + + /* copy a block from the previous frame */ + CHECK_STREAM (len, 1); + B = *(*data)++; + x = -8 + (B & 0x0F); + y = -8 + (B >> 4); + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + + (s->back_buf2 - s->back_buf1) + offset, offset); +} + +static int +ipvideo_decode_0x5 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + signed char x, y; + int offset; + + /* copy a block from the previous frame using an expanded range */ + CHECK_STREAM (len, 2); + x = (signed char) *(*data)++; + y = (signed char) *(*data)++; + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + + ((unsigned short *) s->back_buf2 - (unsigned short *) s->back_buf1) + + offset, offset); +} + +static int +ipvideo_decode_0x7 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P0, P1; + unsigned int flags; + int bitmask; + + /* 2-color encoding */ + CHECK_STREAM (len, 4 + 2); + P0 = PIXEL (*data); + (*data) += 2; + P1 = PIXEL (*data); + (*data) += 2; + + if (!(P0 & 0x8000)) { + + /* need 8 more bytes from the stream */ + CHECK_STREAM (len, 8 - 2); + + for (y = 0; y < 8; ++y) { + flags = *(*data)++; + for (x = 0x01; x <= 0x80; x <<= 1) { + if (flags & x) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + P0 &= ~0x8000; + + /* need 2 more bytes from the stream */ + + flags = ((*data)[1] << 8) | (*data)[0]; + (*data) += 2; + bitmask = 0x0001; + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, bitmask <<= 1) { + if (flags & bitmask) { + *(frame + x) = P1; + *(frame + x + 1) = P1; + *(frame + s->width + x) = P1; + *(frame + s->width + x + 1) = P1; + } else { + *(frame + x) = P0; + *(frame + x + 1) = P0; + *(frame + s->width + x) = P0; + *(frame + s->width + x + 1) = P0; + } + } + frame += s->width * 2; + } + } + + return 0; +} + +static int +ipvideo_decode_0x8 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P[8]; + unsigned char B[8]; + unsigned int flags = 0; + unsigned int bitmask = 0; + unsigned short P0 = 0, P1 = 0; + int lower_half = 0; + + /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM (len, 6 + 10); + + P[0] = PIXEL (*data); + (*data) += 2; + P[1] = PIXEL (*data); + (*data) += 2; + B[0] = *(*data)++; + B[1] = *(*data)++; + + if (!(P[0] & 0x8000)) { + + /* need 18 more bytes */ + CHECK_STREAM (len, 18 - 10); + + P[2] = PIXEL (*data); + (*data) += 2; + P[3] = PIXEL (*data); + (*data) += 2; + B[2] = *(*data)++; + B[3] = *(*data)++; + P[4] = PIXEL (*data); + (*data) += 2; + P[5] = PIXEL (*data); + (*data) += 2; + B[4] = *(*data)++; + B[5] = *(*data)++; + P[6] = PIXEL (*data); + (*data) += 2; + P[7] = PIXEL (*data); + (*data) += 2; + B[6] = *(*data)++; + B[7] = *(*data)++; + + flags = ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 0; /* still on top half */ + + for (y = 0; y < 8; ++y) { + + /* time to reload flags? */ + if (y == 4) { + flags = ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 2; + } + + /* get the pixel values ready for this quadrant */ + P0 = P[lower_half + 0]; + P1 = P[lower_half + 1]; + + for (x = 0; x < 8; ++x, bitmask <<= 1) { + if (x == 4) { + P0 = P[lower_half + 4]; + P1 = P[lower_half + 5]; + } + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + P[0] &= ~0x8000; + + /* need 10 more bytes */ + B[2] = *(*data)++; + B[3] = *(*data)++; + P[2] = PIXEL (*data); + (*data) += 2; + P[3] = PIXEL (*data); + (*data) += 2; + B[4] = *(*data)++; + B[5] = *(*data)++; + B[6] = *(*data)++; + B[7] = *(*data)++; + + if (!(P[2] & 0x8000)) { + /* vertical split; left & right halves are 2-color encoded */ + + flags = + ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + + for (y = 0; y < 8; ++y) { + + /* time to reload flags? */ + if (y == 4) { + flags = ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + } + + /* get the pixel values ready for this half */ + P0 = P[0]; + P1 = P[1]; + + for (x = 0; x < 8; ++x, bitmask <<= 1) { + if (x == 4) { + P0 = P[2]; + P1 = P[3]; + } + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + /* horizontal split; top & bottom halves are 2-color encoded */ + + P0 = P[0]; + P1 = P[1]; + + for (y = 0; y < 8; ++y) { + + flags = B[y]; + if (y == 4) { + P0 = P[2] & ~0x8000; + P1 = P[3]; + } + + for (bitmask = 0x01; bitmask <= 0x80; bitmask <<= 1) { + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + } + } + + return 0; +} + +static int +ipvideo_decode_0x9 (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P[4]; + unsigned char B[4]; + unsigned int flags = 0; + int shifter = 0; + unsigned short pix; + + /* 4-color encoding */ + CHECK_STREAM (len, 8 + 4); + + P[0] = PIXEL (*data); + (*data) += 2; + P[1] = PIXEL (*data); + (*data) += 2; + P[2] = PIXEL (*data); + (*data) += 2; + P[3] = PIXEL (*data); + (*data) += 2; + + if (!(P[0] & 0x8000) && !(P[2] & 0x8000)) { + + /* 1 of 4 colors for each pixel, need 16 more bytes */ + CHECK_STREAM (len, 16 - 4); + + for (y = 0; y < 8; ++y) { + /* get the next set of 8 2-bit flags */ + flags = ((*data)[1] << 8) | (*data)[0]; + (*data) += 2; + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + *frame++ = P[(flags >> shifter) & 0x03]; + } + frame += s->width - 8; + } + + } else if (!(P[0] & 0x8000) && (P[2] & 0x8000)) { + P[2] &= ~0x8000; + + /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ + + B[0] = *(*data)++; + B[1] = *(*data)++; + B[2] = *(*data)++; + B[3] = *(*data)++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + x + 1) = pix; + *(frame + s->width + x) = pix; + *(frame + s->width + x + 1) = pix; + } + frame += s->width * 2; + } + + } else if ((P[0] & 0x8000) && !(P[2] & 0x8000)) { + P[0] &= ~0x8000; + + /* 1 of 4 colors for each 2x1 block, need 8 more bytes */ + + CHECK_STREAM (len, 8 - 4); + for (y = 0; y < 8; ++y) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = *(*data)++; + B[1] = *(*data)++; + B[2] = *(*data)++; + B[3] = *(*data)++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + x + 1) = pix; + } + frame += s->width; + } + + } else { + P[0] &= ~0x8000; + P[2] &= ~0x8000; + + /* 1 of 4 colors for each 1x2 block, need 8 more bytes */ + CHECK_STREAM (len, 8 - 4); + + for (y = 0; y < 8; y += 2) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = *(*data)++; + B[1] = *(*data)++; + B[2] = *(*data)++; + B[3] = *(*data)++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; ++x, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + s->width + x) = pix; + } + frame += s->width * 2; + } + } + + return 0; +} + +static int +ipvideo_decode_0xa (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P[16]; + unsigned char B[16]; + int flags = 0; + int shifter = 0; + int index; + int split; + int lower_half; + + /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM (len, 8 + 24); + + P[0] = PIXEL (*data); + (*data) += 2; + P[1] = PIXEL (*data); + (*data) += 2; + P[2] = PIXEL (*data); + (*data) += 2; + P[3] = PIXEL (*data); + (*data) += 2; + + if (!(P[0] & 0x8000)) { + + /* 4-color encoding for each quadrant; need 40 more bytes */ + CHECK_STREAM (len, 40 - 24); + + B[0] = *(*data)++; + B[1] = *(*data)++; + B[2] = *(*data)++; + B[3] = *(*data)++; + for (y = 4; y < 16; y += 4) { + for (x = y; x < y + 4; ++x) { + P[x] = PIXEL (*data); + (*data) += 2; + } + for (x = y; x < y + 4; ++x) + B[x] = *(*data)++; + } + + for (y = 0; y < 8; ++y) { + + lower_half = (y >= 4) ? 4 : 0; + flags = (B[y + 8] << 8) | B[y]; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + split = (x >= 4) ? 8 : 0; + index = split + lower_half + ((flags >> shifter) & 0x03); + *frame++ = P[index]; + } + + frame += s->width - 8; + } + + } else { + P[0] &= ~0x8000; + + /* 4-color encoding for either left and right or top and bottom + * halves; need 24 more bytes */ + + memcpy (&B[0], *data, 8); + (*data) += 8; + P[4] = PIXEL (*data); + (*data) += 2; + P[5] = PIXEL (*data); + (*data) += 2; + P[6] = PIXEL (*data); + (*data) += 2; + P[7] = PIXEL (*data); + (*data) += 2; + memcpy (&B[8], *data, 8); + (*data) += 8; + + if (!(P[4] & 0x8000)) { + + /* block is divided into left and right halves */ + for (y = 0; y < 8; ++y) { + + flags = (B[y + 8] << 8) | B[y]; + split = 0; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + if (x == 4) + split = 4; + *frame++ = P[split + ((flags >> shifter) & 0x03)]; + } + + frame += s->width - 8; + } + + } else { + P[4] &= ~0x8000; + + /* block is divided into top and bottom halves */ + split = 0; + for (y = 0; y < 8; ++y) { + + flags = (B[y * 2 + 1] << 8) | B[y * 2]; + if (y == 4) + split = 4; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) + *frame++ = P[split + ((flags >> shifter) & 0x03)]; + + frame += s->width - 8; + } + } + } + + return 0; +} + +static int +ipvideo_decode_0xb (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + + /* 64-color encoding (each pixel in block is a different color) */ + CHECK_STREAM (len, 128); + + for (y = 0; y < 8; ++y) { + for (x = 0; x < 8; ++x) { + *frame++ = PIXEL (*data); + (*data) += 2; + } + frame += s->width - 8; + } + + return 0; +} + +static int +ipvideo_decode_0xc (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short pix; + + /* 16-color block encoding: each 2x2 block is a different color */ + CHECK_STREAM (len, 32); + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2) { + pix = PIXEL (*data); + (*data) += 2; + *(frame + x) = pix; + *(frame + x + 1) = pix; + *(frame + s->width + x) = pix; + *(frame + s->width + x + 1) = pix; + } + frame += s->width * 2; + } + + return 0; +} + +static int +ipvideo_decode_0xd (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P[4]; + unsigned char index = 0; + + /* 4-color block encoding: each 4x4 block is a different color */ + CHECK_STREAM (len, 8); + + P[0] = PIXEL (*data); + (*data) += 2; + P[1] = PIXEL (*data); + (*data) += 2; + P[2] = PIXEL (*data); + (*data) += 2; + P[3] = PIXEL (*data); + (*data) += 2; + + for (y = 0; y < 8; ++y) { + if (y < 4) + index = 0; + else + index = 2; + + for (x = 0; x < 8; ++x) { + if (x == 4) + ++index; + *frame++ = P[index]; + } + frame += s->width - 8; + } + + return 0; +} + +static int +ipvideo_decode_0xe (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short pix; + + /* 1-color encoding: the whole block is 1 solid color */ + CHECK_STREAM (len, 2); + + pix = PIXEL (*data); + (*data) += 2; + + for (y = 0; y < 8; ++y) { + for (x = 0; x < 8; ++x) { + *frame++ = pix; + } + frame += s->width - 8; + } + + return 0; +} + +static int +ipvideo_decode_0xf (const GstMveDemuxStream * s, unsigned short *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned short P[2]; + + /* dithered encoding */ + CHECK_STREAM (len, 4); + + P[0] = PIXEL (*data); + (*data) += 2; + P[1] = PIXEL (*data); + (*data) += 2; + + for (y = 0; y < 8; ++y) { + for (x = 0; x < 4; ++x) { + *frame++ = P[y & 1]; + *frame++ = P[(y & 1) ^ 1]; + } + frame += s->width - 8; + } + + return 0; +} + +int +ipvideo_decode_frame16 (const GstMveDemuxStream * s, const unsigned char *data, + unsigned short len) +{ + int rc = 0; + int x, y, xx, yy; + int index = 0; + unsigned short offset; + unsigned char opcode; + unsigned short *frame; + const unsigned char *data2; + unsigned short len2; + + CHECK_STREAM (&len, 2); + + offset = (data[1] << 8) | data[0]; + data2 = data + offset; + len2 = len - offset + 2; + data += 2; + + frame = s->back_buf1; + + /* decoding is done in 8x8 blocks */ + xx = s->width >> 3; + yy = s->height >> 3; + + for (y = 0; y < yy; ++y) { + for (x = 0; x < xx; ++x) { + /* decoding map contains 4 bits of information per 8x8 block */ + /* bottom nibble first, then top nibble */ + if (index & 1) + opcode = s->code_map[index >> 1] >> 4; + else + opcode = s->code_map[index >> 1] & 0x0F; + ++index; + + /* GST_DEBUG ("block @ (%3d, %3d): encoding 0x%X, data ptr @ %p", + x, y, opcode, data); */ + + switch (opcode) { + case 0x0: + /* copy a block from the previous frame */ + rc = ipvideo_copy_block (s, frame, frame + + (s->back_buf2 - s->back_buf1), 0); + break; + case 0x1: + /* copy block from 2 frames ago; since we switched the back + * buffers we don't actually have to do anything here */ + break; + case 0x2: + rc = ipvideo_decode_0x2 (s, frame, &data2, &len2); + break; + case 0x3: + rc = ipvideo_decode_0x3 (s, frame, &data2, &len2); + break; + case 0x4: + rc = ipvideo_decode_0x4 (s, frame, &data2, &len2); + break; + case 0x5: + rc = ipvideo_decode_0x5 (s, frame, &data, &len); + break; + case 0x6: + /* mystery opcode? skip multiple blocks? */ + GST_WARNING ("encountered unsupported opcode 0x6"); + rc = -1; + break; + case 0x7: + rc = ipvideo_decode_0x7 (s, frame, &data, &len); + break; + case 0x8: + rc = ipvideo_decode_0x8 (s, frame, &data, &len); + break; + case 0x9: + rc = ipvideo_decode_0x9 (s, frame, &data, &len); + break; + case 0xa: + rc = ipvideo_decode_0xa (s, frame, &data, &len); + break; + case 0xb: + rc = ipvideo_decode_0xb (s, frame, &data, &len); + break; + case 0xc: + rc = ipvideo_decode_0xc (s, frame, &data, &len); + break; + case 0xd: + rc = ipvideo_decode_0xd (s, frame, &data, &len); + break; + case 0xe: + rc = ipvideo_decode_0xe (s, frame, &data, &len); + break; + case 0xf: + rc = ipvideo_decode_0xf (s, frame, &data, &len); + break; + } + + if (rc != 0) + return rc; + + frame += 8; + } + frame += 7 * s->width; + } + + return 0; +} diff --git a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec8.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec8.cpp new file mode 100644 index 000000000..5d3820820 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mvevideodec8.cpp @@ -0,0 +1,797 @@ +/* + * Interplay MVE Video Decoder (8 bit) + * Copyright (C) 2003 the ffmpeg project, Mike Melanson + * (C) 2006 Jens Granseuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * For more information about the Interplay MVE format, visit: + * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt + */ + +#include "gstmvedemux.h" +#include + +#define CHECK_STREAM(l, n) \ + do { \ + if (G_UNLIKELY (*(l) < (n))) { \ + GST_ERROR ("wanted to read %d bytes from stream, %d available", (n), *(l)); \ + return -1; \ + } \ + *(l) -= (n); \ + } while (0) + + +/* copy an 8x8 block from the stream to the frame buffer */ +static int +ipvideo_copy_block (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char *src, int offset) +{ + int i; + long frame_offset; + + frame_offset = frame - (guint8 *) s->back_buf1 + offset; + + if (G_UNLIKELY (frame_offset < 0)) { + GST_ERROR ("frame offset < 0 (%ld)", frame_offset); + return -1; + } else if (G_UNLIKELY ((guint32)frame_offset > s->max_block_offset)) { + GST_ERROR ("frame offset above limit (%ld > %u)", + frame_offset, s->max_block_offset); + return -1; + } + + for (i = 0; i < 8; ++i) { + memcpy (frame, src, 8); + frame += s->width; + src += s->width; + } + + return 0; +} + +static int +ipvideo_decode_0x2 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + unsigned char B; + int x, y; + int offset; + + /* copy block from 2 frames ago using a motion vector */ + CHECK_STREAM (len, 1); + B = *(*data)++; + + if (B < 56) { + x = 8 + (B % 7); + y = B / 7; + } else { + x = -14 + ((B - 56) % 29); + y = 8 + ((B - 56) / 29); + } + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + offset, offset); +} + +static int +ipvideo_decode_0x3 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + unsigned char B; + int x, y; + int offset; + + /* copy 8x8 block from current frame from an up/left block */ + CHECK_STREAM (len, 1); + B = *(*data)++; + + if (B < 56) { + x = -(8 + (B % 7)); + y = -(B / 7); + } else { + x = -(-14 + ((B - 56) % 29)); + y = -(8 + ((B - 56) / 29)); + } + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, frame + offset, offset); +} + +static int +ipvideo_decode_0x4 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + unsigned char B; + int x, y; + int offset; + + /* copy a block from the previous frame */ + CHECK_STREAM (len, 1); + B = *(*data)++; + x = -8 + (B & 0x0F); + y = -8 + (B >> 4); + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, + frame + ((guint8 *) s->back_buf2 - (guint8 *) s->back_buf1) + offset, offset); +} + +static int +ipvideo_decode_0x5 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + signed char x, y; + int offset; + + /* copy a block from the previous frame using an expanded range */ + CHECK_STREAM (len, 2); + + x = (signed char) *(*data)++; + y = (signed char) *(*data)++; + offset = y * s->width + x; + + return ipvideo_copy_block (s, frame, + frame + ((guint8 *) s->back_buf2 - (guint8 *) s->back_buf1) + offset, offset); +} + +static int +ipvideo_decode_0x7 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P0, P1; + unsigned int flags; + int bitmask; + + /* 2-color encoding */ + CHECK_STREAM (len, 2 + 2); + + P0 = *(*data)++; + P1 = *(*data)++; + + if (P0 <= P1) { + + /* need 8 more bytes from the stream */ + CHECK_STREAM (len, 8 - 2); + + for (y = 0; y < 8; ++y) { + flags = *(*data)++; + for (x = 0x01; x <= 0x80; x <<= 1) { + if (flags & x) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + + /* need 2 more bytes from the stream */ + flags = ((*data)[1] << 8) | (*data)[0]; + (*data) += 2; + bitmask = 0x0001; + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, bitmask <<= 1) { + if (flags & bitmask) { + *(frame + x) = P1; + *(frame + x + 1) = P1; + *(frame + s->width + x) = P1; + *(frame + s->width + x + 1) = P1; + } else { + *(frame + x) = P0; + *(frame + x + 1) = P0; + *(frame + s->width + x) = P0; + *(frame + s->width + x + 1) = P0; + } + } + frame += s->width * 2; + } + } + + return 0; +} + +static int +ipvideo_decode_0x8 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P[8]; + unsigned char B[8]; + unsigned int flags = 0; + unsigned int bitmask = 0; + unsigned char P0 = 0, P1 = 0; + int lower_half = 0; + + /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM (len, 4 + 8); + + P[0] = (*data)[0]; + P[1] = (*data)[1]; + B[0] = (*data)[2]; + B[1] = (*data)[3]; + (*data) += 4; + + if (P[0] <= P[1]) { + + /* need 12 more bytes */ + CHECK_STREAM (len, 12 - 8); + + P[2] = (*data)[0]; + P[3] = (*data)[1]; + B[2] = (*data)[2]; + B[3] = (*data)[3]; + P[4] = (*data)[4]; + P[5] = (*data)[5]; + B[4] = (*data)[6]; + B[5] = (*data)[7]; + P[6] = (*data)[8]; + P[7] = (*data)[9]; + B[6] = (*data)[10]; + B[7] = (*data)[11]; + (*data) += 12; + + flags = + ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 0; /* still on top half */ + + for (y = 0; y < 8; ++y) { + + /* time to reload flags? */ + if (y == 4) { + flags = + ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 2; + } + + /* get the pixel values ready for this quadrant */ + P0 = P[lower_half + 0]; + P1 = P[lower_half + 1]; + + for (x = 0; x < 8; ++x, bitmask <<= 1) { + if (x == 4) { + P0 = P[lower_half + 4]; + P1 = P[lower_half + 5]; + } + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + + /* need 8 more bytes */ + B[2] = (*data)[0]; + B[3] = (*data)[1]; + P[2] = (*data)[2]; + P[3] = (*data)[3]; + B[4] = (*data)[4]; + B[5] = (*data)[5]; + B[6] = (*data)[6]; + B[7] = (*data)[7]; + (*data) += 8; + + if (P[2] <= P[3]) { + + /* vertical split; left & right halves are 2-color encoded */ + + flags = ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + + for (y = 0; y < 8; ++y) { + + /* time to reload flags? */ + if (y == 4) { + flags = ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + } + + /* get the pixel values ready for this half */ + P0 = P[0]; + P1 = P[1]; + + for (x = 0; x < 8; ++x, bitmask <<= 1) { + if (x == 4) { + P0 = P[2]; + P1 = P[3]; + } + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + + } else { + + /* horizontal split; top & bottom halves are 2-color encoded */ + + P0 = P[0]; + P1 = P[1]; + + for (y = 0; y < 8; ++y) { + + flags = B[y]; + if (y == 4) { + P0 = P[2]; + P1 = P[3]; + } + + for (bitmask = 0x01; bitmask <= 0x80; bitmask <<= 1) { + + if (flags & bitmask) + *frame++ = P1; + else + *frame++ = P0; + } + frame += s->width - 8; + } + } + } + + return 0; +} + +static int +ipvideo_decode_0x9 (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P[4]; + unsigned char B[4]; + unsigned long flags = 0; + int shifter = 0; + unsigned char pix; + + /* 4-color encoding */ + CHECK_STREAM (len, 4 + 4); + + P[0] = (*data)[0]; + P[1] = (*data)[1]; + P[2] = (*data)[2]; + P[3] = (*data)[3]; + (*data) += 4; + + if ((P[0] <= P[1]) && (P[2] <= P[3])) { + + /* 1 of 4 colors for each pixel, need 16 more bytes */ + CHECK_STREAM (len, 16 - 4); + + for (y = 0; y < 8; ++y) { + /* get the next set of 8 2-bit flags */ + flags = ((*data)[1] << 8) | (*data)[0]; + (*data) += 2; + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + *frame++ = P[(flags >> shifter) & 0x03]; + } + frame += s->width - 8; + } + + } else if ((P[0] <= P[1]) && (P[2] > P[3])) { + + /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ + B[0] = (*data)[0]; + B[1] = (*data)[1]; + B[2] = (*data)[2]; + B[3] = (*data)[3]; + (*data) += 4; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + x + 1) = pix; + *(frame + s->width + x) = pix; + *(frame + s->width + x + 1) = pix; + } + frame += s->width * 2; + } + + } else if ((P[0] > P[1]) && (P[2] <= P[3])) { + + /* 1 of 4 colors for each 2x1 block, need 8 more bytes */ + CHECK_STREAM (len, 8 - 4); + + for (y = 0; y < 8; ++y) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = (*data)[0]; + B[1] = (*data)[1]; + B[2] = (*data)[2]; + B[3] = (*data)[3]; + (*data) += 4; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + x + 1) = pix; + } + frame += s->width; + } + + } else { + + /* 1 of 4 colors for each 1x2 block, need 8 more bytes */ + CHECK_STREAM (len, 8 - 4); + + for (y = 0; y < 8; y += 2) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = (*data)[0]; + B[1] = (*data)[1]; + B[2] = (*data)[2]; + B[3] = (*data)[3]; + (*data) += 4; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; ++x, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(frame + x) = pix; + *(frame + s->width + x) = pix; + } + frame += s->width * 2; + } + } + + return 0; +} + +static int +ipvideo_decode_0xa (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P[16]; + unsigned char B[16]; + int flags = 0; + int shifter = 0; + int index; + int split; + int lower_half; + + /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM (len, 8 + 16); + + P[0] = (*data)[0]; + P[1] = (*data)[1]; + P[2] = (*data)[2]; + P[3] = (*data)[3]; + B[0] = (*data)[4]; + B[1] = (*data)[5]; + B[2] = (*data)[6]; + B[3] = (*data)[7]; + (*data) += 8; + + if (P[0] <= P[1]) { + + /* 4-color encoding for each quadrant; need 24 more bytes */ + CHECK_STREAM (len, 24 - 16); + + for (y = 4; y < 16; y += 4) { + for (x = y; x < y + 4; ++x) + P[x] = *(*data)++; + for (x = y; x < y + 4; ++x) + B[x] = *(*data)++; + } + + for (y = 0; y < 8; ++y) { + + lower_half = (y >= 4) ? 4 : 0; + flags = (B[y + 8] << 8) | B[y]; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + split = (x >= 4) ? 8 : 0; + index = split + lower_half + ((flags >> shifter) & 0x03); + *frame++ = P[index]; + } + + frame += s->width - 8; + } + + } else { + + /* 4-color encoding for either left and right or top and bottom + * halves; need 16 more bytes */ + + B[4] = (*data)[0]; + B[5] = (*data)[1]; + B[6] = (*data)[2]; + B[7] = (*data)[3]; + P[4] = (*data)[4]; + P[5] = (*data)[5]; + P[6] = (*data)[6]; + P[7] = (*data)[7]; + (*data) += 8; + memcpy (&B[8], *data, 8); + (*data) += 8; + + if (P[4] <= P[5]) { + + /* block is divided into left and right halves */ + for (y = 0; y < 8; ++y) { + + flags = (B[y + 8] << 8) | B[y]; + split = 0; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { + if (x == 4) + split = 4; + *frame++ = P[split + ((flags >> shifter) & 0x03)]; + } + + frame += s->width - 8; + } + + } else { + + /* block is divided into top and bottom halves */ + split = 0; + for (y = 0; y < 8; ++y) { + + flags = (B[y * 2 + 1] << 8) | B[y * 2]; + if (y == 4) + split = 4; + + for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) + *frame++ = P[split + ((flags >> shifter) & 0x03)]; + + frame += s->width - 8; + } + } + } + + return 0; +} + +static int +ipvideo_decode_0xb (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int y; + + /* 64-color encoding (each pixel in block is a different color) */ + CHECK_STREAM (len, 64); + + for (y = 0; y < 8; ++y) { + memcpy (frame, *data, 8); + frame += s->width; + (*data) += 8; + } + + return 0; +} + +static int +ipvideo_decode_0xc (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char pix; + + /* 16-color block encoding: each 2x2 block is a different color */ + CHECK_STREAM (len, 16); + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2) { + pix = *(*data)++; + *(frame + x) = pix; + *(frame + x + 1) = pix; + *(frame + s->width + x) = pix; + *(frame + s->width + x + 1) = pix; + } + frame += s->width * 2; + } + + return 0; +} + +static int +ipvideo_decode_0xd (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P[4]; + unsigned char index = 0; + + /* 4-color block encoding: each 4x4 block is a different color */ + CHECK_STREAM (len, 4); + + P[0] = (*data)[0]; + P[1] = (*data)[1]; + P[2] = (*data)[2]; + P[3] = (*data)[3]; + (*data) += 4; + + for (y = 0; y < 8; ++y) { + if (y < 4) + index = 0; + else + index = 2; + + for (x = 0; x < 8; ++x) { + if (x == 4) + ++index; + *frame++ = P[index]; + } + frame += s->width - 8; + } + + return 0; +} + +static int +ipvideo_decode_0xe (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int y; + unsigned char pix; + + /* 1-color encoding: the whole block is 1 solid color */ + CHECK_STREAM (len, 1); + pix = *(*data)++; + + for (y = 0; y < 8; ++y) { + memset (frame, pix, 8); + frame += s->width; + } + + return 0; +} + +static int +ipvideo_decode_0xf (const GstMveDemuxStream * s, unsigned char *frame, + const unsigned char **data, unsigned short *len) +{ + int x, y; + unsigned char P[2]; + + /* dithered encoding */ + CHECK_STREAM (len, 2); + + P[0] = *(*data)++; + P[1] = *(*data)++; + + for (y = 0; y < 8; ++y) { + for (x = 0; x < 4; ++x) { + *frame++ = P[y & 1]; + *frame++ = P[(y & 1) ^ 1]; + } + frame += s->width - 8; + } + + return 0; +} + +int +ipvideo_decode_frame8 (const GstMveDemuxStream * s, const unsigned char *data, + unsigned short len) +{ + int rc = 0; + int x, y, xx, yy; + int index = 0; + unsigned char opcode; + unsigned char *frame; + + frame = (guint8 *) s->back_buf1; + + /* decoding is done in 8x8 blocks */ + xx = s->width >> 3; + yy = s->height >> 3; + + for (y = 0; y < yy; ++y) { + for (x = 0; x < xx; ++x) { + /* decoding map contains 4 bits of information per 8x8 block */ + /* bottom nibble first, then top nibble */ + if (index & 1) + opcode = s->code_map[index >> 1] >> 4; + else + opcode = s->code_map[index >> 1] & 0x0F; + ++index; + + switch (opcode) { + case 0x00: + /* copy a block from the previous frame */ + rc = ipvideo_copy_block (s, frame, + frame + ((guint8 *) s->back_buf2 - (guint8 *) s->back_buf1), 0); + break; + case 0x01: + /* copy block from 2 frames ago; since we switched the back + * buffers we don't actually have to do anything here */ + break; + case 0x02: + rc = ipvideo_decode_0x2 (s, frame, &data, &len); + break; + case 0x03: + rc = ipvideo_decode_0x3 (s, frame, &data, &len); + break; + case 0x04: + rc = ipvideo_decode_0x4 (s, frame, &data, &len); + break; + case 0x05: + rc = ipvideo_decode_0x5 (s, frame, &data, &len); + break; + case 0x06: + /* mystery opcode? skip multiple blocks? */ + GST_WARNING ("encountered unsupported opcode 0x6"); + rc = -1; + break; + case 0x07: + rc = ipvideo_decode_0x7 (s, frame, &data, &len); + break; + case 0x08: + rc = ipvideo_decode_0x8 (s, frame, &data, &len); + break; + case 0x09: + rc = ipvideo_decode_0x9 (s, frame, &data, &len); + break; + case 0x0a: + rc = ipvideo_decode_0xa (s, frame, &data, &len); + break; + case 0x0b: + rc = ipvideo_decode_0xb (s, frame, &data, &len); + break; + case 0x0c: + rc = ipvideo_decode_0xc (s, frame, &data, &len); + break; + case 0x0d: + rc = ipvideo_decode_0xd (s, frame, &data, &len); + break; + case 0x0e: + rc = ipvideo_decode_0xe (s, frame, &data, &len); + break; + case 0x0f: + rc = ipvideo_decode_0xf (s, frame, &data, &len); + break; + } + + if (rc != 0) + return rc; + + frame += 8; + } + frame += 7 * s->width; + } + + return 0; +} diff --git a/project/jni/application/gemrb/src/plugins/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/NullSound/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/NullSound/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/NullSound/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/NullSound/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/NullSound/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/NullSound/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/NullSound/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/NullSound/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/NullSound/NullSound.cpp b/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/NullSound/NullSound.cpp rename to project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.cpp diff --git a/project/jni/application/gemrb/src/plugins/NullSound/NullSound.h b/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/NullSound/NullSound.h rename to project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h diff --git a/project/jni/application/gemrb/src/plugins/OGGReader/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/OGGReader/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/OGGReader/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/OGGReader/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/OGGReader/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/OGGReader/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/OGGReader/OGGReader.cpp b/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/OGGReader/OGGReader.cpp rename to project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp diff --git a/project/jni/application/gemrb/src/plugins/OGGReader/OGGReader.h b/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/OGGReader/OGGReader.h rename to project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.h diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/AmbientMgrAL.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/AmbientMgrAL.cpp rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/AmbientMgrAL.h b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/AmbientMgrAL.h rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.h diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/OpenALAudio.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp similarity index 99% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/OpenALAudio.cpp rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp index d85e13635..9a4440ebb 100644 --- a/project/jni/application/gemrb/src/plugins/OpenALAudio/OpenALAudio.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp @@ -505,6 +505,7 @@ bool OpenALAudioDriver::Stop() SDL_mutexV( musicMutex ); return true; } + bool OpenALAudioDriver::Pause() { SDL_mutexP( musicMutex ); @@ -512,21 +513,20 @@ bool OpenALAudioDriver::Pause() SDL_mutexV( musicMutex ); return false; } - // pause Music alSourcePause(MusicSource); checkALError("Unable to pause music source", "WARNING"); MusicPlaying = false; SDL_mutexV( musicMutex ); ((AmbientMgrAL*) ambim)->deactivate(); -#ifdef ANDROID +#ifdef ANDROID al_android_pause_playback(); //call AudioTrack.pause() from JNI -#endif +#endif return true; } bool OpenALAudioDriver::Resume() { -#ifdef ANDROID +#ifdef ANDROID al_android_resume_playback(); //call AudioTrack.play() from JNI #endif SDL_mutexP( musicMutex ); @@ -534,12 +534,11 @@ bool OpenALAudioDriver::Resume() SDL_mutexV( musicMutex ); return false; } - // resume Music alSourcePlay(MusicSource); checkALError("Unable to resume music source", "WARNING"); MusicPlaying = true; SDL_mutexV( musicMutex ); - ((AmbientMgrAL*) ambim)->activate(); + ((AmbientMgrAL*) ambim)->activate(); return true; } diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/OpenALAudio.h b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/OpenALAudio.h rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/StackLock.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/StackLock.cpp rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp diff --git a/project/jni/application/gemrb/src/plugins/OpenALAudio/StackLock.h b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/OpenALAudio/StackLock.h rename to project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.h diff --git a/project/jni/application/gemrb/src/plugins/PLTImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/PLTImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/PLTImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/PLTImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/PLTImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/PLTImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/PLTImporter/PLTImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/PLTImporter/PLTImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/PLTImporter/PLTImporter.h b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/PLTImporter/PLTImporter.h rename to project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.h diff --git a/project/jni/application/gemrb/src/plugins/PNGImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/PNGImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/PNGImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/PNGImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/PNGImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/PNGImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/PNGImporter/PNGImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp similarity index 99% rename from project/jni/application/gemrb/src/plugins/PNGImporter/PNGImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp index c4dba11fe..30afe7481 100644 --- a/project/jni/application/gemrb/src/plugins/PNGImporter/PNGImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp @@ -33,7 +33,7 @@ static void DataStream_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { - voidp read_io_ptr = png_get_io_ptr(png_ptr); + void *read_io_ptr = png_get_io_ptr(png_ptr); DataStream* str = reinterpret_cast(read_io_ptr); str->Read(data, length); } diff --git a/project/jni/application/gemrb/src/plugins/PNGImporter/PNGImporter.h b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/PNGImporter/PNGImporter.h rename to project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.h diff --git a/project/jni/application/gemrb/src/plugins/PROImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/PROImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/PROImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/PROImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/PROImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/PROImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/PROImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/PROImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/PROImporter/PROImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/PROImporter/PROImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/PROImporter/PROImporter.h b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/PROImporter/PROImporter.h rename to project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h diff --git a/project/jni/application/gemrb/src/plugins/PSTOpcodes/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/PSTOpcodes/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/PSTOpcodes/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/PSTOpcodes/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/PSTOpcodes/PSTOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/PSTOpcodes/PSTOpcodes.cpp rename to project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp diff --git a/project/jni/application/gemrb/src/plugins/SDLAudio/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLAudio/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/SDLAudio/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLAudio/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/SDLAudio/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.cpp b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp similarity index 99% rename from project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.cpp rename to project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp index b5ae6216b..d3075529b 100644 --- a/project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp @@ -94,7 +94,7 @@ void SDLAudio::music_callback(void *udata, unsigned short *stream, int len) { printMessage("SDLAudio", "Playing Next Music\n", WHITE ); core->GetMusicMgr()->PlayNext(); - stream = stream + (cnt * 2); + stream = stream + cnt; len = len - (cnt * 2); if (!driver->MusicPlaying) { diff --git a/project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.h b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h similarity index 95% rename from project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.h rename to project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h index 0e3398bd2..b31f45ec7 100644 --- a/project/jni/application/gemrb/src/plugins/SDLAudio/SDLAudio.h +++ b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h @@ -39,8 +39,8 @@ public: int CreateStream(Holder); bool Play(); bool Stop(); - bool Pause(){/*not implemented*/ return true; } - bool Resume(){/*not implemented*/ return true; } + bool Pause() { return true; } /*not implemented*/ + bool Resume() { return true; } /*not implemented*/ bool CanPlay(); bool IsSpeaking(); void ResetMusics(); diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideo.cpp b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideo.cpp rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideo.h b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideo.h rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideoDriver.inl b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideoDriver.inl similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/SDLVideoDriver.inl rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideoDriver.inl diff --git a/project/jni/application/gemrb/src/plugins/SDLVideo/TileRenderer.inl b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl similarity index 100% rename from project/jni/application/gemrb/src/plugins/SDLVideo/TileRenderer.inl rename to project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl diff --git a/project/jni/application/gemrb/src/plugins/SPLImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/SPLImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/SPLImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/SPLImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/SPLImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/SPLImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/SPLImporter/SPLImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/SPLImporter/SPLImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/SPLImporter/SPLImporter.h b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/SPLImporter/SPLImporter.h rename to project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h diff --git a/project/jni/application/gemrb/src/plugins/STOImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/STOImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/STOImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/STOImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/STOImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/STOImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/STOImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/STOImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/STOImporter/STOImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp similarity index 97% rename from project/jni/application/gemrb/src/plugins/STOImporter/STOImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp index b4543a086..b6f086b06 100644 --- a/project/jni/application/gemrb/src/plugins/STOImporter/STOImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp @@ -129,7 +129,7 @@ Store* STOImporter::GetStore(Store *s) str->Seek( s->ItemsOffset, GEM_STREAM_START ); for (i = 0; i < s->ItemsCount; i++) { - STOItem *item = s->items[i]; + STOItem *item = s->items[i]; GetItem(item); //it is important to handle this field as signed if (item->InfiniteSupply>0) { @@ -160,14 +160,9 @@ void STOImporter::GetItem(STOItem *it) { CREItem *itm = core->ReadItem(str); memcpy(it, itm, sizeof(CREItem) ); -/* - str->ReadResRef( it->ItemResRef ); - str->ReadWord( &it->PurchasedAmount ); - for (int i=0;iReadWord( it->Usages+i ); - } - str->ReadDword( &it->Flags ); -*/ + //core allocates CREItem!!! + delete itm; + str->ReadDword( &it->AmountInStock ); //if there was no item on stock, how this could be 0 //we hack-fix this here so it won't cause trouble diff --git a/project/jni/application/gemrb/src/plugins/STOImporter/STOImporter.h b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/STOImporter/STOImporter.h rename to project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h diff --git a/project/jni/application/gemrb/src/plugins/TISImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/TISImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/TISImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/TISImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/TISImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/TISImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/TISImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/TISImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/TISImporter/TISImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/TISImporter/TISImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/TISImporter/TISImporter.h b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/TISImporter/TISImporter.h rename to project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/TLKImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/TLKImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/TLKImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp similarity index 83% rename from project/jni/application/gemrb/src/plugins/TLKImporter/TLKImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp index fdaee2b56..ed5732fee 100644 --- a/project/jni/application/gemrb/src/plugins/TLKImporter/TLKImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp @@ -249,44 +249,6 @@ int TLKImporter::BuiltinToken(char* Token, char* dest) Decoded = GetString( RaceStrRef(-1), 0); goto exit_function; } -/* - if (!strcmp( Token, "SIRMAAM" )) { - Decoded = GetString( GenderStrRef(-1,27473,27475), 0); - goto exit_function; - } - if (!strcmp( Token, "GIRLBOY" )) { - Decoded = GetString( GenderStrRef(-1,27477,27476), 0); - goto exit_function; - } - if (!strcmp( Token, "BROTHERSISTER" )) { - Decoded = GetString( GenderStrRef(-1,27478,27479), 0); - goto exit_function; - } - if (!strcmp( Token, "LADYLORD" )) { - Decoded = GetString( GenderStrRef(-1,27481,27480), 0); - goto exit_function; - } - if (!strcmp( Token, "MALEFEMALE" )) { - Decoded = GetString( GenderStrRef(-1,27482,27483), 0); - goto exit_function; - } - if (!strcmp( Token, "HESHE" )) { - Decoded = GetString( GenderStrRef(-1,27484,27485), 0); - goto exit_function; - } - if (!strcmp( Token, "HISHER" )) { - Decoded = GetString( GenderStrRef(-1,27486,27487), 0); - goto exit_function; - } - if (!strcmp( Token, "HIMHER" )) { - Decoded = GetString( GenderStrRef(-1,27488,27487), 0); - goto exit_function; - } - if (!strcmp( Token, "MANWOMAN" )) { - Decoded = GetString( GenderStrRef(-1,27489,27490), 0); - goto exit_function; - } -*/ if (!strncmp( Token, "PLAYER",6 )) { Decoded = CharName(Token[6]-'1'); goto exit_function; @@ -304,44 +266,6 @@ int TLKImporter::BuiltinToken(char* Token, char* dest) Decoded = GetString( RaceStrRef(0), 0); goto exit_function; } -/* - if (!strcmp( Token, "PRO_SIRMAAM" )) { - Decoded = GetString( GenderStrRef(0,27473,27475), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_GIRLBOY" )) { - Decoded = GetString( GenderStrRef(0,27477,27476), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_BROTHERSISTER" )) { - Decoded = GetString( GenderStrRef(0,27478,27479), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_LADYLORD" )) { - Decoded = GetString( GenderStrRef(0,27481,27480), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_MALEFEMALE" )) { - Decoded = GetString( GenderStrRef(0,27482,27483), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_HESHE" )) { - Decoded = GetString( GenderStrRef(0,27484,27485), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_HISHER" )) { - Decoded = GetString( GenderStrRef(0,27486,27487), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_HIMHER" )) { - Decoded = GetString( GenderStrRef(0,27488,27487), 0); - goto exit_function; - } - if (!strcmp( Token, "PRO_MANWOMAN" )) { - Decoded = GetString( GenderStrRef(0,27489,27490), 0); - goto exit_function; - } -*/ if (!strcmp( Token, "MAGESCHOOL" )) { ieDword row = 0; //default value is 0 (generalist) //this is subject to change, the row number in magesch.2da diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/TLKImporter.h b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/TLKImporter/TLKImporter.h rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/TlkOverride.cpp b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/TLKImporter/TlkOverride.cpp rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp diff --git a/project/jni/application/gemrb/src/plugins/TLKImporter/TlkOverride.h b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/TLKImporter/TlkOverride.h rename to project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.h diff --git a/project/jni/application/gemrb/src/plugins/WAVReader/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/WAVReader/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/WAVReader/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/WAVReader/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/WAVReader/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/WAVReader/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/WAVReader/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/WAVReader/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/WAVReader/WAVReader.cpp b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/WAVReader/WAVReader.cpp rename to project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp diff --git a/project/jni/application/gemrb/src/plugins/WAVReader/WAVReader.h b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/WAVReader/WAVReader.h rename to project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.h diff --git a/project/jni/application/gemrb/src/plugins/WEDImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/WEDImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/WEDImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/WEDImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/WEDImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/WEDImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/WEDImporter/WEDImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp similarity index 98% rename from project/jni/application/gemrb/src/plugins/WEDImporter/WEDImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp index 1526d51d5..802937dcc 100644 --- a/project/jni/application/gemrb/src/plugins/WEDImporter/WEDImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp @@ -117,6 +117,10 @@ int WEDImporter::AddOverlay(TileMap *tm, Overlay *overlays, bool rain) } TileOverlay *over = new TileOverlay( overlays->Width, overlays->Height ); DataStream* tisfile = gamedata->GetResource(res, IE_TIS_CLASS_ID); + if (!tisfile) { + delete over; + return -1; + } PluginHolder tis(IE_TIS_CLASS_ID); tis->Open( tisfile ); for (int y = 0; y < overlays->Height; y++) { @@ -164,6 +168,7 @@ int WEDImporter::AddOverlay(TileMap *tm, Overlay *overlays, bool rain) TileMap* WEDImporter::GetTileMap(TileMap *tm) { int usedoverlays; + bool freenew = false; if (!overlays.size()) { return NULL; @@ -171,9 +176,16 @@ TileMap* WEDImporter::GetTileMap(TileMap *tm) if (!tm) { tm = new TileMap(); + freenew = true; } usedoverlays = AddOverlay(tm, &overlays.at(0), false); + if (usedoverlays == -1) { + if (freenew) { + delete tm; + } + return NULL; + } // rain_overlays[0] is never used // XXX: should fix AddOverlay not to load an overlay twice if there's no rain version!! //AddOverlay(tm, &overlays.at(0), true); diff --git a/project/jni/application/gemrb/src/plugins/WEDImporter/WEDImporter.h b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/WEDImporter/WEDImporter.h rename to project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h diff --git a/project/jni/application/gemrb/src/plugins/WMPImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/WMPImporter/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/WMPImporter/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/WMPImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/WMPImporter/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/WMPImporter/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/WMPImporter/WMPImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/WMPImporter/WMPImporter.cpp rename to project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp diff --git a/project/jni/application/gemrb/src/plugins/WMPImporter/WMPImporter.h b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/WMPImporter/WMPImporter.h rename to project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h diff --git a/project/jni/application/gemrb/src/plugins/ZLibManager/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/CMakeLists.txt similarity index 100% rename from project/jni/application/gemrb/src/plugins/ZLibManager/CMakeLists.txt rename to project/jni/application/gemrb/gemrb/plugins/ZLibManager/CMakeLists.txt diff --git a/project/jni/application/gemrb/src/plugins/ZLibManager/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/Makefile.am similarity index 100% rename from project/jni/application/gemrb/src/plugins/ZLibManager/Makefile.am rename to project/jni/application/gemrb/gemrb/plugins/ZLibManager/Makefile.am diff --git a/project/jni/application/gemrb/src/plugins/ZLibManager/ZLibManager.cpp b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp similarity index 100% rename from project/jni/application/gemrb/src/plugins/ZLibManager/ZLibManager.cpp rename to project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp diff --git a/project/jni/application/gemrb/src/plugins/ZLibManager/ZLibManager.h b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h similarity index 100% rename from project/jni/application/gemrb/src/plugins/ZLibManager/ZLibManager.h rename to project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h diff --git a/project/jni/application/gemrb/src/AUTHORS b/project/jni/application/gemrb/src/AUTHORS deleted file mode 100644 index 28a7ad991..000000000 --- a/project/jni/application/gemrb/src/AUTHORS +++ /dev/null @@ -1,17 +0,0 @@ -GemRB authors listed in Alphabetical Order - -Alyssa Milburn -Avenger -Balrog994 -Brian Tanedo -Dark-Star -Divide -Edheldil -GuidoJ -Jaka Kranjc -Lotana -Marshall Mattingly III -Thuy Nguyen -Tom Prince -Willem Jan Palenstijn -Zefklop diff --git a/project/jni/application/gemrb/src/COPYING b/project/jni/application/gemrb/src/COPYING deleted file mode 100644 index 5b6e7c66c..000000000 --- a/project/jni/application/gemrb/src/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/project/jni/application/gemrb/src/NEWS b/project/jni/application/gemrb/src/NEWS deleted file mode 100644 index 961e2a864..000000000 --- a/project/jni/application/gemrb/src/NEWS +++ /dev/null @@ -1,381 +0,0 @@ -GemRB git (2bd6d0e): - New features: - - - - Improved features: - - - - bugfixes - - Applied patches: - -GemRB V0.6.3 git (2010-11-21) - New features: - - IWD:HoW is now completable! - - casting sounds and footsteps - - autodetection of secret doors, detect illusions - - basic bardsong support and selective magic resistance (bg2-style) - - proper store economics, ergonomics and dragging - - custom blood color (creature-dependant) - - new actions, iwd effects and triggers - - Importing a SoA game into ToB - - Improved features: - - actor selection and action bar (for summons and illusions too!) - - door bashing and traps - - loading screens, ambushes, worldmap - - sparkles, panic and other effects - - actions, dialogs, object matching - - personal items support (swap/equip/remove) - - bugfixes - - Applied patches: - iwd regression fix from Eggert Jón Magnússon - -GemRB V0.6.2 (2010-08-21): - New features: - - a basic SDL_mixer plugin for faster, but lower-quality audio - - dualclassing for bg1 and iwd - - new triggers, actions, infravision - - feet circle flickering on portrait hover, coloration in dialog - - wisdom xp bonus (pst) - - Improved features: - - actions, triggers, object matching - - item loading and ability selection, inventory - - projectiles, effects, subtitles, verbal constants - - the core and guiscript design was cleaned up in many places - - bugfixes - - Applied patches: - backslash check patch from anthiste - bg1 character generation patch from Maighstir - a crosscompiling fix from F.Fischer - -GemRB V0.6.1 (2010-06-16): - New features: - - a minimal dataset - - reputation penalties on death or injury - - casting level bonus/malus (wild mages, clerics) - - tinting for different times of the day and weather effects - - a BI(n)K player plugin for the IWD2 movies - - new actions, turn undead - - Improved features: - - the internal design was cleaned up in many places - - game saving, modal actions, combat, effects, spawns - - magic missiles are now drawn properly - - various guiscripts (no more flickering!) - - bugfixes - - Applied patches: - two patches from Brendan Molloy - -GemRB V0.6.0 (2009-11-03): - New features: - - BG1 and IWD are roughly completable! - - levelup support for bg1 and iwd, dream cutscenes in ToB - - more hardcoded projectiles and avatar animations - - evasion, backstabbing and basic hide in shadows - - compatibility with the widescreen mod (unreleased) allows for multiple - custom resolutions - - contingency and sequencer spells, beginnings of wild magic support - - Improved features: - - combat, travelling and feedback - - better spellcasting timing - - actions, effects and triggers - - various guiscripts - - bugfixes - - Applied patches: - a few patches from nugrud for how/totl support - -GemRB V0.5.1 (2009-08-27): - New features: - - BG2:SoA is roughly completable! - - almost all missing IE's hardcoded projectiles, spell hit projectiles, - projectile trails, projectile failure (spell), projectile effectlists - - auto-reloading of projectile weapons in case the ammo stack runs out - - damage resistance - - sorcerer style spellbooks, reading of iwd2 spellbooks - - target following to other areas - - the null sound plugin is now always loaded last by default; for old - installs see the provided configuration example (DelayPlugin) - - intelligence and wisdom dictated lore bonus - - a GUIEnhancements config option (on by default) that enables a few - extra controls (for convenience and larger mods) - - PST death counters (don't anger the Lady) - - initial support for targetting by portrait - - Improved features: - - actions, effects and triggers - - pathfinding, feet circles, fog of war and worldmap travel - - combat and spellcasting (especially summoning) - - projectiles - - config and default table value parsing is smarter about spaces - - various guiscripts - - bugfixes - - Applied patches: - various patches from nugrud for bg2 gui enhancements - fix compilation (with cmake) on OS X, by hanicka - -GemRB V0.5.0 (2009-06-25): - New features: - - SoA, ToB and PST are roughly playable beyond their first levels - - combat: dual-wielding, APR, proficiency and style boni, dexterity - bonus, initiatitive and speed factor, individual combat rounds - - many IE's hardcoded projectiles and support for projectile sounds - - IWD2 GUI now works after chargen too - - bg2 chargen now levels to the correct level - - summoned and charmed creatures can be ordered around - - actor tooltips (name and injury status) - - running, initial variable values and portal animations in PST - - hardcoded monk bonuses - - Improved features: - - dialog, actions and triggers - - combat mechanics, animation, feedback, ranged combat - - matters of time and matter - - levelup, dual classing, multiclass handling - - focus: scrolling while paused is now possible - - animations (projectile, creature) - - pathfinding - - area music restarts when there's no music playing - - disarm trap checks skills - - various guiscripts - - bugfixes - - Applied patches: - #2802190 jbmetz (improve the rpm spec handling) - #2802437 danamin (patch bomb sanitizing bg1 chargen + bg2 code share) - -GemRB V0.4.0 (2009-05-25): - New features: - - level up support in bg2 - - basic party reordering - - bashing of containers and doors - - persistent area effects (cloudkill, stinking cloud, web, etc.) - - item amount window for stack splitting (shift+click or doubleclick) - - depletion of item charges - - opcodes: disable spellcasting, cutscene2 (pocketplane travel), knock, - clear air, polymorph, disable button - - dynamic scrollbar creation (display of more than 10 kits, 24 spells) - - portrait effect icons - - item ability selection - - character customization - - Improved features: - - fog of war - - party reformation - - iwd and how guiscripts have been merged - - traps - - pst dialogs - - regeneration, hp bonuses, healing - - animations and projectiles - - rewritten MVE player - - ranged combat - - various guiscripts - - bugfixes - - Applied patches: - #2770564 Whiteclone (pst options window bug) - numerous patches from mattinm finishing the level up support - a few patches from ape fixing and extending iwd - #2579743 jbmetz added RPM spec files - -GemRB V0.3.2 (2009-02-16): - New features: - - default cancel button, bound to the escape key - - tooltip animations and a shortcut (tab) - - wrapper python classes that simplified the GUIScripts - - trap detection, removal, triggering, xp, feedback, autopause - - modal effects - - proper xp award for dual- and multiclass actors - - double click (used in the map window) - - click-and-hold incrementing/decrementing - - accumulate kill statistics - - characters can move while the map is open - - sound on item equip - - arbitrary feat prerequisites in iwd2 - - hard pause for all games (originally a ToB feature); triggered with 'h' - - extended night areas (originally a bg2 feature) - - Improved features: - - walking animation timing - - formations (arbitrary sizes, rotation, cursor) - - ppc support (no more crashes) - - container/door/infopoint cursor and highlight handling - - various guiscripts - - cmake build system (now really works on *nix) - - magic item exclusion - - stores and bags - - fixed attack loop when target dies - - bugfixes - - Applied patches: - #2159734 Zefklop (Mouse activity during movies) - #2243323 Zefklop (correct Openal cleanup) - #2263333 Whiteclone (bg1 guiinv) - #2380891 Amikrop (iwd1 guicommonwindows) - -GemRB V0.3.1 (2008-09-25): - New features: - - mouse scroll support - - starting tob inventory - - character import in iwd and how - - spritecover for area animations - - proper XP bonus for thieving and learning spells - - Improved features: - - gcc 4.3 compatibility - - PST bestiary - - bg2 and tob game modes have been merged - - bg2 and iwd2 character generation was simplified and improved - - stricter dualclassing prerequisites - - the cmake build system is available for other platforms too - - pathfinding - - starting time is now at day 0 - - less memory leaks - - bugfixes - -GemRB V0.3.0 (2008-02-17): - New features: - - TLK override handling (custom biographies and map notes) - - weapon immunities - - party AI - - expansion playmode - - more actions, triggers and effects - - loading of projectile explosion animations - - kit information window - - optional CMake build system (windows only) - - Improved features: - - sound (now perfect!) - - character generation - - opcodes - - character record window - - pathfinding - - tooltip delay - - bugfixes - -GemRB V0.2.9 (2007-07-06): - New features: - - thieving - - tracking - - graphical feedback (color pulse, blur, mirror image, vvc overlays etc) - - projectiles - - spell casting - - item use - - challenge rating calculation - - Improved features: - - more opcodes - - bugfixes - - shop/inventory gui - -GemRB V0.2.8 (2006-12-24): - New features: - - equipment is rendered both on paperdoll and avatar - - weather (snow/rain) is now rendered - - Improved features: - - action menus - - game scripting (actions/triggers) - -GemRB V0.2.7 (2006-08-30): - New features: - - large animations - - worldmap travel - - dialogue portraits - - translucent shadows option - - personal space of actors - - combat - - many new effects - - overlay animation - - Improved features: - - Script fixes - - Action menus - - TextScreen - - doors - - animated overlays - - new actions - -GemRB V0.2.6 (2005-12-06): - New features: - - Effects are in a different plugin - - DoxyGen docs - - Wallgroup covers - - Door triggers - - Action menus (talk/attack) - - party/protagonist death handled - - Improved features: - - Textscreen graphic fixed - - script workflow - - compilation and running on different systems (MacOSX, PPC Linux) - - various leaks/instabilities fixed - - Saving games - - inventory screens in many games - -GemRB V0.2.5 (2005-08-22): - New features: - - Save game - - Effects are now loaded - - Equipping effects in items - - Spawn points in areas - - Textscreen (scrolled text between chapters) - - Improved features: - - GameScript is now much more reliable: Action override works, triggers fire once and then get cleared - - fully working Store screen - - fixed padding of message window rows (in dialogs) - -GemRB V0.2.4 (2005-05-29): - New features: - - Store dialogs (Temple, Inn, Container, Tavern, Store) - - Fog of war with line of sight - - Doors block path and line of sight - - Window frames at higher resolutions - - Animated buttons (PST portraits, Donation window) - - Store opens when appropriate - - Containers - - Improved features: - - Fixed dialogs - - new GUIScript functions with documentation - - Fog of war/door/store related gamescript actions - - fixed object distance and area variable handling in gamescript - - other new gamescript actions/triggers - - Implemented PCs fidget animations - - Documentation: - - Introduction to writing GUIScript scripts - -GemRB v0.2.3 (2005-02-13): - New features: - - GUI for most of the games, especially interactive Inventory and Spellbook - - Map and WorldMap - - Load screen interstitials with progress bar - - Spell and item cache to speed up object management - - Added gamescript actions/triggers - - Selection of spells during character generation - - First attempt on effects code - - First attempt on Fog-Of-War - - Tooltips - - Overhead text - - Ambient sounds - - Volume control - - Manual page gemrb(1) - - Documentation for GemRB Python API and our custom override files - - Improved features: - - Character generation - - GUI - - Build infrastructure on Linux and Un*x systems - - Progress towards portability to 64 bit and big endian machines - - Many bugfixes and new bugs as well ;-) - - Shortened version numbers - - Simplified user configuration, game specific settings are now - in gemrb/override dir diff --git a/project/jni/application/gemrb/src/README b/project/jni/application/gemrb/src/README deleted file mode 100644 index 8d3b71955..000000000 --- a/project/jni/application/gemrb/src/README +++ /dev/null @@ -1,77 +0,0 @@ -Introduction ------------- -GemRB (Game Engine Made with preRendered Background) is a "port" -(actually a new implementation) of the original Infinity Engine (the one -of Baldur's Gate, Icewind Dale, Planescape: Torment, ...) to -Linux/Unix, MacOS X and Windows with some enhancements. Would you like to -create a game like Baldur's Gate? - -It means that you either need some of the original game's data -somewhere on your harddisk, or you can try to use the data from the -Dragonlance Total Conversion project - see the link below. - -The original game data has to be installed on a windows -partition and mounted to your Linux/Unix filesystem, installed on -windows and then copied to your filesystem, installed with WINE or -extracted manually from the CDs using the tool `unshield'. - -What little documentation exists is mostly in gemrb/docs/en/ and -subdirectories, the gemrb.6 man page and this file. - -Supported platforms -------------------- -Supported (i.e. we got reports about successfully running GemRB) systems: -Linux x86, x86-64, ppc -FreeBSD x86 -MS Windows (98, XP or Vista) -various Macintosh systems (even pre x86) also should work ... -some smart phones (Symbian, Android) -some consoles (OpenPandora, Dingoo) -some exotic OSes (ReactOS, SyllableOS, Haiku) - -Requirements ------------- -See the INSTALL file. - -Contacts --------- -Our homepage: -http://gemrb.sourceforge.net - -Our project at sourceforge.net: -http://sourceforge.net/projects/gemrb - -New GemRB forum (users): -http://forums.gibberlings3.net/index.php?showforum=91 - -IRC channel: -The best way to talk with us is by joining the #GemRB channel -on the FreeNode IRC network. There's somebody to talk with most of -the time. - - -Useful links ------------- -IESDP, documentation for the Infinity Engine file formats and more: -http://iesdp.gibberlings3.net/ - -Near Infinity, Java viewer and editor for data files of the original games: -http://www.idi.ntnu.no/~joh/ni/index.html - -DLTCEP, MS Windows viewer and editor for data files of the original games: -http://forums.gibberlings3.net/index.php?showforum=137 - -Unshield, extractor for .CAB files created by InstallShield -http://synce.sourceforge.net/synce/unshield.php - -Valgrind, a powerful developer tool to fix programmer errors (leaks, buffer overflows and all the like that happen) -http://valgrind.org/ - -SDL, Simple Directmedia Layer, the graphical library used for GemRB -http://www.libsdl.org/index.php - -OpenAL, Cross-Platform 3D audio libraries, the sound library used for GemRB -http://openal.org/ - -WINE, Open Source implementation of the Windows API, useful for installing the games -http://www.winehq.org diff --git a/project/jni/application/gemrb/src/TODO b/project/jni/application/gemrb/src/TODO deleted file mode 100644 index 2f1af016a..000000000 --- a/project/jni/application/gemrb/src/TODO +++ /dev/null @@ -1,101 +0,0 @@ -Scripts: -1. (DONE?) ToB specific actions/triggers, like pocketplane (so ToB will work) -2. (PARTLY) Properly detect the play mode (sp/mp, normal/extended) - -Strings: -1. fix (finish implementation of) talk table override -2. implement feature: "" (or even more ambitious stat specific strref tokens) - -Combat: -1. (PARTLY) fix combat round timings -2. implement customisable combat calculation, it should be general enough to -simulate all games, without any hardcoded parts - -Items: -1. (DONE-almost) Break items, count charges -2. (PARTLY) Implement switching weapon abilities -3. (DONE-almost) Implement item usage (similar to spells) - -Effects: -1. (DONE-almost) Implement common effects -2. (PARTLY) Implement IWD2 effects -3. (DONE-almost) Implement TOB effects -4. (PARTLY) Implement PST effects -5. (DONE-almost) Implement area/non-living affecting effects - -Area: -1. (PARTLY) Don't load scripts for pile items? (research when a script is unused) -2. (DONE) Create real streaming ambients (do not preload them, just use them when needed) -3. (DONE) in pathfinder, calculate with the actor's feet circle size (npc blocking still needed) -4. (DONE-almost) fix overlaid tiles - bug #1623839 - -Store: -1. Store caching (especially bags) - -Animation: -1. (PARTLY) fix char animation sequences -2. stanceID is still fuzzy. Fix it. (FIXED?) -3. (PARTLY) Implement projectile animations (area, cone, fragments, hardcoded features) - -Actor: -1. (PARTLY) Use the character sheet (Actor.cpp) itself to store attributes of the character - during character generation. - Benefits: data is already stored in the destination, data constraints and relations - are easily implemented. - How to: replace GemRB.SetVar with GemRB.SetPlayerStat. Don't forget to create - the character first. - see bg1 chargen for a complete solution -2. Move position of actor (and ground circle) to the center of a searchmap cell -3. (PARTLY) Actually handle the iwd2 spelllists. Exporter is still needed. - -Game GUI: -1. (PARTLY) implement class based (but customisable) action button bar. Generally port - the IWD2 system to all engines -2. implement grabbing mouse pointer by a control to fix dragging of PST Float menu window -3. (PARTLY) Fix drop capitals (initials) Calculate text height/width correctly, display - it correctly too. -4. (PARTLY) Fix unwanted screen shake (especially when on bottom of area) -5. (DONE-almost) Level up code, this should be written mostly in GuiScript!!! -6. (PARTLY) Contingency, spell trigger setup windows -7. (PARTLY) Customize windows (part of character record window) - -General: -1. The Cache and Variables classes could be rewritten to incorporate the release - function more smoothly (use templates?) -2. various directories (GemRB override, game override ...) should be resolved - right after loading config files and remain static afterwards. Maybe define - some PATH variable describing all the directories searched for files -3. valgrind reports a big heap of unreleased python objects -4. Implement at least all the options accessible from the GUI options setup, - rewrite baldur|torment|icewind.ini - -Graphics: -1. use scaling in Video::SpriteScaleDown() instead of in Video::GetPreview() - and in BMPImporter -2. move SDLVideoDriver sprite functions to their own file, rename them to - SpriteIsPixelTransparent etc. -3. (PARTLY) Add PNG support? (still image done) -4. Fog of war: fully visible squares with one corner neighbour invisible need alpha of the adjacent corner to the invisible square tuned down (uh, i hope it is clear what to do, look for artifacts in the fog of war edge) - -Sound: -1. valgrind reports invalid memory access due to Unqueueing buffers and using - them in another thread (openal weirdness?) -2. (PARTLY) sounds get sometimes distorted, might be connected to problem #1 -3. (PARTLY) Separate OpenAL interface from ACM loader and MVE player -4. implement sound handles so looping, moving sound, stopping sound is possible -5. fix sound settings (currently the volumes get reset on area change, for example) -6. implement and use as much from EAX (echo, damping, etc) as possible - -Release: -2. Get a sample game with some free license which could be distributed - with GemRB. - - -Documentation: -1. (PARTLY) make tool to scan source files for those with non-standard - copyright notices -2. Add Doxygen doc comments to more objects -3. Write GemRB overview, structure and high-level flow docs - - -Community: -2. Move this todo to bug/task tracker at Sourceforge :-) diff --git a/project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.h b/project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.h deleted file mode 100644 index 42b1091e9..000000000 --- a/project/jni/application/gemrb/src/plugins/BIKPlayer/GetBitContext.h +++ /dev/null @@ -1,75 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2009 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -//code derived from FFMPEG -//using code from get_bits.h, bitstream.c - -#include "common.h" - -#define INIT_VLC_LE 2 -#define INIT_VLC_USE_NEW_STATIC 4 - -class VLC -{ -public: - int bits; - int16_t (*table)[2]; ///< code, bits - int table_size, table_allocated; -public: -int init_vlc(int nb_bits, int nb_codes, - const void *bits, int bits_wrap, int bits_size, - const void *codes, int codes_wrap, int codes_size, - int flags); -private: - int alloc_table(int size); - int build_table(int table_nb_bits, int nb_codes, - const void *bits, int bits_wrap, int bits_size, - const void *codes, int codes_wrap, int codes_size, - uint32_t code_prefix, int n_prefix, int flags); - -}; - - -#define AV_RL32(x) \ - ((((const uint8_t*)(x))[3] << 24) | \ - (((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) - -class GetBitContext -{ -public: - const uint8_t *buffer, *buffer_end; - int index; - int size_in_bits; -public: - void debug(const char *prefix); - float get_float(); - void skip_bits(int x) { index+=x; } - int get_bits_count() { return index; } - void get_bits_align32(); - unsigned int get_bits(int x); - unsigned int peek_bits(int x); - unsigned int get_bits_long(int n); - void init_get_bits(const uint8_t *b, int bit_size); - void read_tree(Tree *tree); -private: - void merge( uint8_t *dst, uint8_t *src, int size); -}; diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec16.cpp b/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec16.cpp deleted file mode 100644 index 0d4713119..000000000 --- a/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec16.cpp +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Interplay MVE Video Decoder (16 bit) - * Copyright (C) 2003 the ffmpeg project, Mike Melanson - * (C) 2006 Jens Granseuer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * For more information about the Interplay MVE format, visit: - * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt - */ - -#include "gstmvedemux.h" -#include - -#define PIXEL(s) GST_READ_UINT16_LE (s) - -#define CHECK_STREAM(l, n) \ - do { \ - if (G_UNLIKELY (*(l) < (n))) { \ - GST_ERROR ("wanted to read %d bytes from stream, %d available", (n), *(l)); \ - return -1; \ - } \ - *(l) -= (n); \ - } while (0) - -/* copy an 8x8 block from the stream to the frame buffer */ -static int -ipvideo_copy_block (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned short *src, int offset) -{ - int i; - int frame_offset; - - frame_offset = frame - (unsigned short *) s->back_buf1 + offset; - - if (G_UNLIKELY (frame_offset < 0)) { - GST_ERROR ("frame offset < 0 (%d)", frame_offset); - return -1; - } else if (G_UNLIKELY ((guint32)frame_offset > s->max_block_offset)) { - GST_ERROR ("frame offset above limit (%d > %u)", - frame_offset, s->max_block_offset); - return -1; - } - - for (i = 0; i < 8; ++i) { - memcpy (frame, src, 16); - frame += s->width; - src += s->width; - } - - return 0; -} - -static int -ipvideo_decode_0x2 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - unsigned char B; - int x, y; - int offset; - - /* copy block from 2 frames ago using a motion vector */ - CHECK_STREAM (len, 1); - B = *(*data)++; - - if (B < 56) { - x = 8 + (B % 7); - y = B / 7; - } else { - x = -14 + ((B - 56) % 29); - y = 8 + ((B - 56) / 29); - } - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + offset, offset); -} - -static int -ipvideo_decode_0x3 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - unsigned char B; - int x, y; - int offset; - - /* copy 8x8 block from current frame from an up/left block */ - CHECK_STREAM (len, 1); - B = *(*data)++; - - if (B < 56) { - x = -(8 + (B % 7)); - y = -(B / 7); - } else { - x = -(-14 + ((B - 56) % 29)); - y = -(8 + ((B - 56) / 29)); - } - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + offset, offset); -} - -static int -ipvideo_decode_0x4 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char B; - int offset; - - /* copy a block from the previous frame */ - CHECK_STREAM (len, 1); - B = *(*data)++; - x = -8 + (B & 0x0F); - y = -8 + (B >> 4); - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + - ((unsigned short *) s->back_buf2 - (unsigned short *) s->back_buf1) + - offset, offset); -} - -static int -ipvideo_decode_0x5 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - signed char x, y; - int offset; - - /* copy a block from the previous frame using an expanded range */ - CHECK_STREAM (len, 2); - x = (signed char) *(*data)++; - y = (signed char) *(*data)++; - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + - ((unsigned short *) s->back_buf2 - (unsigned short *) s->back_buf1) + - offset, offset); -} - -static int -ipvideo_decode_0x7 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P0, P1; - unsigned int flags; - int bitmask; - - /* 2-color encoding */ - CHECK_STREAM (len, 4 + 2); - P0 = PIXEL (*data); - (*data) += 2; - P1 = PIXEL (*data); - (*data) += 2; - - if (!(P0 & 0x8000)) { - - /* need 8 more bytes from the stream */ - CHECK_STREAM (len, 8 - 2); - - for (y = 0; y < 8; ++y) { - flags = *(*data)++; - for (x = 0x01; x <= 0x80; x <<= 1) { - if (flags & x) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - P0 &= ~0x8000; - - /* need 2 more bytes from the stream */ - - flags = ((*data)[1] << 8) | (*data)[0]; - (*data) += 2; - bitmask = 0x0001; - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, bitmask <<= 1) { - if (flags & bitmask) { - *(frame + x) = P1; - *(frame + x + 1) = P1; - *(frame + s->width + x) = P1; - *(frame + s->width + x + 1) = P1; - } else { - *(frame + x) = P0; - *(frame + x + 1) = P0; - *(frame + s->width + x) = P0; - *(frame + s->width + x + 1) = P0; - } - } - frame += s->width * 2; - } - } - - return 0; -} - -static int -ipvideo_decode_0x8 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P[8]; - unsigned char B[8]; - unsigned int flags = 0; - unsigned int bitmask = 0; - unsigned short P0 = 0, P1 = 0; - int lower_half = 0; - - /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM (len, 6 + 10); - - P[0] = PIXEL (*data); - (*data) += 2; - P[1] = PIXEL (*data); - (*data) += 2; - B[0] = *(*data)++; - B[1] = *(*data)++; - - if (!(P[0] & 0x8000)) { - - /* need 18 more bytes */ - CHECK_STREAM (len, 18 - 10); - - P[2] = PIXEL (*data); - (*data) += 2; - P[3] = PIXEL (*data); - (*data) += 2; - B[2] = *(*data)++; - B[3] = *(*data)++; - P[4] = PIXEL (*data); - (*data) += 2; - P[5] = PIXEL (*data); - (*data) += 2; - B[4] = *(*data)++; - B[5] = *(*data)++; - P[6] = PIXEL (*data); - (*data) += 2; - P[7] = PIXEL (*data); - (*data) += 2; - B[6] = *(*data)++; - B[7] = *(*data)++; - - flags = - ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | - ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | - ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | - ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); - bitmask = 0x00000001; - lower_half = 0; /* still on top half */ - - for (y = 0; y < 8; ++y) { - - /* time to reload flags? */ - if (y == 4) { - flags = - ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | - ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | - ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | - ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); - bitmask = 0x00000001; - lower_half = 2; - } - - /* get the pixel values ready for this quadrant */ - P0 = P[lower_half + 0]; - P1 = P[lower_half + 1]; - - for (x = 0; x < 8; ++x, bitmask <<= 1) { - if (x == 4) { - P0 = P[lower_half + 4]; - P1 = P[lower_half + 5]; - } - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - P[0] &= ~0x8000; - - /* need 10 more bytes */ - B[2] = *(*data)++; - B[3] = *(*data)++; - P[2] = PIXEL (*data); - (*data) += 2; - P[3] = PIXEL (*data); - (*data) += 2; - B[4] = *(*data)++; - B[5] = *(*data)++; - B[6] = *(*data)++; - B[7] = *(*data)++; - - if (!(P[2] & 0x8000)) { - /* vertical split; left & right halves are 2-color encoded */ - - flags = - ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | - ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | - ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | - ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); - bitmask = 0x00000001; - - for (y = 0; y < 8; ++y) { - - /* time to reload flags? */ - if (y == 4) { - flags = - ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | - ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | - ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | - ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); - bitmask = 0x00000001; - } - - /* get the pixel values ready for this half */ - P0 = P[0]; - P1 = P[1]; - - for (x = 0; x < 8; ++x, bitmask <<= 1) { - if (x == 4) { - P0 = P[2]; - P1 = P[3]; - } - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - /* horizontal split; top & bottom halves are 2-color encoded */ - - P0 = P[0]; - P1 = P[1]; - - for (y = 0; y < 8; ++y) { - - flags = B[y]; - if (y == 4) { - P0 = P[2] & ~0x8000; - P1 = P[3]; - } - - for (bitmask = 0x01; bitmask <= 0x80; bitmask <<= 1) { - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - } - } - - return 0; -} - -static int -ipvideo_decode_0x9 (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P[4]; - unsigned char B[4]; - unsigned int flags = 0; - int shifter = 0; - unsigned short pix; - - /* 4-color encoding */ - CHECK_STREAM (len, 8 + 4); - - P[0] = PIXEL (*data); - (*data) += 2; - P[1] = PIXEL (*data); - (*data) += 2; - P[2] = PIXEL (*data); - (*data) += 2; - P[3] = PIXEL (*data); - (*data) += 2; - - if (!(P[0] & 0x8000) && !(P[2] & 0x8000)) { - - /* 1 of 4 colors for each pixel, need 16 more bytes */ - CHECK_STREAM (len, 16 - 4); - - for (y = 0; y < 8; ++y) { - /* get the next set of 8 2-bit flags */ - flags = ((*data)[1] << 8) | (*data)[0]; - (*data) += 2; - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - *frame++ = P[(flags >> shifter) & 0x03]; - } - frame += s->width - 8; - } - - } else if (!(P[0] & 0x8000) && (P[2] & 0x8000)) { - P[2] &= ~0x8000; - - /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ - - B[0] = *(*data)++; - B[1] = *(*data)++; - B[2] = *(*data)++; - B[3] = *(*data)++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + x + 1) = pix; - *(frame + s->width + x) = pix; - *(frame + s->width + x + 1) = pix; - } - frame += s->width * 2; - } - - } else if ((P[0] & 0x8000) && !(P[2] & 0x8000)) { - P[0] &= ~0x8000; - - /* 1 of 4 colors for each 2x1 block, need 8 more bytes */ - - CHECK_STREAM (len, 8 - 4); - for (y = 0; y < 8; ++y) { - /* time to reload flags? */ - if ((y == 0) || (y == 4)) { - B[0] = *(*data)++; - B[1] = *(*data)++; - B[2] = *(*data)++; - B[3] = *(*data)++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - } - for (x = 0; x < 8; x += 2, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + x + 1) = pix; - } - frame += s->width; - } - - } else { - P[0] &= ~0x8000; - P[2] &= ~0x8000; - - /* 1 of 4 colors for each 1x2 block, need 8 more bytes */ - CHECK_STREAM (len, 8 - 4); - - for (y = 0; y < 8; y += 2) { - /* time to reload flags? */ - if ((y == 0) || (y == 4)) { - B[0] = *(*data)++; - B[1] = *(*data)++; - B[2] = *(*data)++; - B[3] = *(*data)++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - } - for (x = 0; x < 8; ++x, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + s->width + x) = pix; - } - frame += s->width * 2; - } - } - - return 0; -} - -static int -ipvideo_decode_0xa (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P[16]; - unsigned char B[16]; - int flags = 0; - int shifter = 0; - int index; - int split; - int lower_half; - - /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM (len, 8 + 24); - - P[0] = PIXEL (*data); - (*data) += 2; - P[1] = PIXEL (*data); - (*data) += 2; - P[2] = PIXEL (*data); - (*data) += 2; - P[3] = PIXEL (*data); - (*data) += 2; - - if (!(P[0] & 0x8000)) { - - /* 4-color encoding for each quadrant; need 40 more bytes */ - CHECK_STREAM (len, 40 - 24); - - B[0] = *(*data)++; - B[1] = *(*data)++; - B[2] = *(*data)++; - B[3] = *(*data)++; - for (y = 4; y < 16; y += 4) { - for (x = y; x < y + 4; ++x) { - P[x] = PIXEL (*data); - (*data) += 2; - } - for (x = y; x < y + 4; ++x) - B[x] = *(*data)++; - } - - for (y = 0; y < 8; ++y) { - - lower_half = (y >= 4) ? 4 : 0; - flags = (B[y + 8] << 8) | B[y]; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - split = (x >= 4) ? 8 : 0; - index = split + lower_half + ((flags >> shifter) & 0x03); - *frame++ = P[index]; - } - - frame += s->width - 8; - } - - } else { - P[0] &= ~0x8000; - - /* 4-color encoding for either left and right or top and bottom - * halves; need 24 more bytes */ - - memcpy (&B[0], *data, 8); - (*data) += 8; - P[4] = PIXEL (*data); - (*data) += 2; - P[5] = PIXEL (*data); - (*data) += 2; - P[6] = PIXEL (*data); - (*data) += 2; - P[7] = PIXEL (*data); - (*data) += 2; - memcpy (&B[8], *data, 8); - (*data) += 8; - - if (!(P[4] & 0x8000)) { - - /* block is divided into left and right halves */ - for (y = 0; y < 8; ++y) { - - flags = (B[y + 8] << 8) | B[y]; - split = 0; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - if (x == 4) - split = 4; - *frame++ = P[split + ((flags >> shifter) & 0x03)]; - } - - frame += s->width - 8; - } - - } else { - P[4] &= ~0x8000; - - /* block is divided into top and bottom halves */ - split = 0; - for (y = 0; y < 8; ++y) { - - flags = (B[y * 2 + 1] << 8) | B[y * 2]; - if (y == 4) - split = 4; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) - *frame++ = P[split + ((flags >> shifter) & 0x03)]; - - frame += s->width - 8; - } - } - } - - return 0; -} - -static int -ipvideo_decode_0xb (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - - /* 64-color encoding (each pixel in block is a different color) */ - CHECK_STREAM (len, 128); - - for (y = 0; y < 8; ++y) { - for (x = 0; x < 8; ++x) { - *frame++ = PIXEL (*data); - (*data) += 2; - } - frame += s->width - 8; - } - - return 0; -} - -static int -ipvideo_decode_0xc (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short pix; - - /* 16-color block encoding: each 2x2 block is a different color */ - CHECK_STREAM (len, 32); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2) { - pix = PIXEL (*data); - (*data) += 2; - *(frame + x) = pix; - *(frame + x + 1) = pix; - *(frame + s->width + x) = pix; - *(frame + s->width + x + 1) = pix; - } - frame += s->width * 2; - } - - return 0; -} - -static int -ipvideo_decode_0xd (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P[4]; - unsigned char index = 0; - - /* 4-color block encoding: each 4x4 block is a different color */ - CHECK_STREAM (len, 8); - - P[0] = PIXEL (*data); - (*data) += 2; - P[1] = PIXEL (*data); - (*data) += 2; - P[2] = PIXEL (*data); - (*data) += 2; - P[3] = PIXEL (*data); - (*data) += 2; - - for (y = 0; y < 8; ++y) { - if (y < 4) - index = 0; - else - index = 2; - - for (x = 0; x < 8; ++x) { - if (x == 4) - ++index; - *frame++ = P[index]; - } - frame += s->width - 8; - } - - return 0; -} - -static int -ipvideo_decode_0xe (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short pix; - - /* 1-color encoding: the whole block is 1 solid color */ - CHECK_STREAM (len, 2); - - pix = PIXEL (*data); - (*data) += 2; - - for (y = 0; y < 8; ++y) { - for (x = 0; x < 8; ++x) { - *frame++ = pix; - } - frame += s->width - 8; - } - - return 0; -} - -static int -ipvideo_decode_0xf (const GstMveDemuxStream * s, unsigned short *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned short P[2]; - - /* dithered encoding */ - CHECK_STREAM (len, 4); - - P[0] = PIXEL (*data); - (*data) += 2; - P[1] = PIXEL (*data); - (*data) += 2; - - for (y = 0; y < 8; ++y) { - for (x = 0; x < 4; ++x) { - *frame++ = P[y & 1]; - *frame++ = P[(y & 1) ^ 1]; - } - frame += s->width - 8; - } - - return 0; -} - -int -ipvideo_decode_frame16 (const GstMveDemuxStream * s, const unsigned char *data, - unsigned short len) -{ - int rc = 0; - int x, y, xx, yy; - int index = 0; - unsigned short offset; - unsigned char opcode; - unsigned short *frame; - const unsigned char *data2; - unsigned short len2; - - CHECK_STREAM (&len, 2); - - offset = (data[1] << 8) | data[0]; - data2 = data + offset; - len2 = len - offset + 2; - data += 2; - - frame = (unsigned short *) s->back_buf1; - - /* decoding is done in 8x8 blocks */ - xx = s->width >> 3; - yy = s->height >> 3; - - for (y = 0; y < yy; ++y) { - for (x = 0; x < xx; ++x) { - /* decoding map contains 4 bits of information per 8x8 block */ - /* bottom nibble first, then top nibble */ - if (index & 1) - opcode = s->code_map[index >> 1] >> 4; - else - opcode = s->code_map[index >> 1] & 0x0F; - ++index; - - /* GST_DEBUG ("block @ (%3d, %3d): encoding 0x%X, data ptr @ %p", - x, y, opcode, data); */ - - switch (opcode) { - case 0x0: - /* copy a block from the previous frame */ - rc = ipvideo_copy_block (s, frame, frame + - ((unsigned short *) s->back_buf2 - - (unsigned short *) s->back_buf1), 0); - break; - case 0x1: - /* copy block from 2 frames ago; since we switched the back - * buffers we don't actually have to do anything here */ - break; - case 0x2: - rc = ipvideo_decode_0x2 (s, frame, &data2, &len2); - break; - case 0x3: - rc = ipvideo_decode_0x3 (s, frame, &data2, &len2); - break; - case 0x4: - rc = ipvideo_decode_0x4 (s, frame, &data2, &len2); - break; - case 0x5: - rc = ipvideo_decode_0x5 (s, frame, &data, &len); - break; - case 0x6: - /* mystery opcode? skip multiple blocks? */ - GST_WARNING ("encountered unsupported opcode 0x6"); - rc = -1; - break; - case 0x7: - rc = ipvideo_decode_0x7 (s, frame, &data, &len); - break; - case 0x8: - rc = ipvideo_decode_0x8 (s, frame, &data, &len); - break; - case 0x9: - rc = ipvideo_decode_0x9 (s, frame, &data, &len); - break; - case 0xa: - rc = ipvideo_decode_0xa (s, frame, &data, &len); - break; - case 0xb: - rc = ipvideo_decode_0xb (s, frame, &data, &len); - break; - case 0xc: - rc = ipvideo_decode_0xc (s, frame, &data, &len); - break; - case 0xd: - rc = ipvideo_decode_0xd (s, frame, &data, &len); - break; - case 0xe: - rc = ipvideo_decode_0xe (s, frame, &data, &len); - break; - case 0xf: - rc = ipvideo_decode_0xf (s, frame, &data, &len); - break; - } - - if (rc != 0) - return rc; - - frame += 8; - } - frame += 7 * s->width; - } - - return 0; -} diff --git a/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec8.cpp b/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec8.cpp deleted file mode 100644 index 01992e970..000000000 --- a/project/jni/application/gemrb/src/plugins/MVEPlayer/mvevideodec8.cpp +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Interplay MVE Video Decoder (8 bit) - * Copyright (C) 2003 the ffmpeg project, Mike Melanson - * (C) 2006 Jens Granseuer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * For more information about the Interplay MVE format, visit: - * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt - */ - -#include "gstmvedemux.h" -#include - -#define CHECK_STREAM(l, n) \ - do { \ - if (G_UNLIKELY (*(l) < (n))) { \ - GST_ERROR ("wanted to read %d bytes from stream, %d available", (n), *(l)); \ - return -1; \ - } \ - *(l) -= (n); \ - } while (0) - - -/* copy an 8x8 block from the stream to the frame buffer */ -static int -ipvideo_copy_block (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char *src, int offset) -{ - int i; - long frame_offset; - - frame_offset = frame - s->back_buf1 + offset; - - if (G_UNLIKELY (frame_offset < 0)) { - GST_ERROR ("frame offset < 0 (%ld)", frame_offset); - return -1; - } else if (G_UNLIKELY ((guint32)frame_offset > s->max_block_offset)) { - GST_ERROR ("frame offset above limit (%ld > %u)", - frame_offset, s->max_block_offset); - return -1; - } - - for (i = 0; i < 8; ++i) { - memcpy (frame, src, 8); - frame += s->width; - src += s->width; - } - - return 0; -} - -static int -ipvideo_decode_0x2 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - unsigned char B; - int x, y; - int offset; - - /* copy block from 2 frames ago using a motion vector */ - CHECK_STREAM (len, 1); - B = *(*data)++; - - if (B < 56) { - x = 8 + (B % 7); - y = B / 7; - } else { - x = -14 + ((B - 56) % 29); - y = 8 + ((B - 56) / 29); - } - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + offset, offset); -} - -static int -ipvideo_decode_0x3 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - unsigned char B; - int x, y; - int offset; - - /* copy 8x8 block from current frame from an up/left block */ - CHECK_STREAM (len, 1); - B = *(*data)++; - - if (B < 56) { - x = -(8 + (B % 7)); - y = -(B / 7); - } else { - x = -(-14 + ((B - 56) % 29)); - y = -(8 + ((B - 56) / 29)); - } - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, frame + offset, offset); -} - -static int -ipvideo_decode_0x4 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - unsigned char B; - int x, y; - int offset; - - /* copy a block from the previous frame */ - CHECK_STREAM (len, 1); - B = *(*data)++; - x = -8 + (B & 0x0F); - y = -8 + (B >> 4); - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, - frame + (s->back_buf2 - s->back_buf1) + offset, offset); -} - -static int -ipvideo_decode_0x5 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - signed char x, y; - int offset; - - /* copy a block from the previous frame using an expanded range */ - CHECK_STREAM (len, 2); - - x = (signed char) *(*data)++; - y = (signed char) *(*data)++; - offset = y * s->width + x; - - return ipvideo_copy_block (s, frame, - frame + (s->back_buf2 - s->back_buf1) + offset, offset); -} - -static int -ipvideo_decode_0x7 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P0, P1; - unsigned int flags; - int bitmask; - - /* 2-color encoding */ - CHECK_STREAM (len, 2 + 2); - - P0 = *(*data)++; - P1 = *(*data)++; - - if (P0 <= P1) { - - /* need 8 more bytes from the stream */ - CHECK_STREAM (len, 8 - 2); - - for (y = 0; y < 8; ++y) { - flags = *(*data)++; - for (x = 0x01; x <= 0x80; x <<= 1) { - if (flags & x) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - - /* need 2 more bytes from the stream */ - flags = ((*data)[1] << 8) | (*data)[0]; - (*data) += 2; - bitmask = 0x0001; - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, bitmask <<= 1) { - if (flags & bitmask) { - *(frame + x) = P1; - *(frame + x + 1) = P1; - *(frame + s->width + x) = P1; - *(frame + s->width + x + 1) = P1; - } else { - *(frame + x) = P0; - *(frame + x + 1) = P0; - *(frame + s->width + x) = P0; - *(frame + s->width + x + 1) = P0; - } - } - frame += s->width * 2; - } - } - - return 0; -} - -static int -ipvideo_decode_0x8 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P[8]; - unsigned char B[8]; - unsigned int flags = 0; - unsigned int bitmask = 0; - unsigned char P0 = 0, P1 = 0; - int lower_half = 0; - - /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM (len, 4 + 8); - - P[0] = (*data)[0]; - P[1] = (*data)[1]; - B[0] = (*data)[2]; - B[1] = (*data)[3]; - (*data) += 4; - - if (P[0] <= P[1]) { - - /* need 12 more bytes */ - CHECK_STREAM (len, 12 - 8); - - P[2] = (*data)[0]; - P[3] = (*data)[1]; - B[2] = (*data)[2]; - B[3] = (*data)[3]; - P[4] = (*data)[4]; - P[5] = (*data)[5]; - B[4] = (*data)[6]; - B[5] = (*data)[7]; - P[6] = (*data)[8]; - P[7] = (*data)[9]; - B[6] = (*data)[10]; - B[7] = (*data)[11]; - (*data) += 12; - - flags = - ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | - ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | - ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | - ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); - bitmask = 0x00000001; - lower_half = 0; /* still on top half */ - - for (y = 0; y < 8; ++y) { - - /* time to reload flags? */ - if (y == 4) { - flags = - ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | - ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | - ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | - ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); - bitmask = 0x00000001; - lower_half = 2; - } - - /* get the pixel values ready for this quadrant */ - P0 = P[lower_half + 0]; - P1 = P[lower_half + 1]; - - for (x = 0; x < 8; ++x, bitmask <<= 1) { - if (x == 4) { - P0 = P[lower_half + 4]; - P1 = P[lower_half + 5]; - } - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - - /* need 8 more bytes */ - B[2] = (*data)[0]; - B[3] = (*data)[1]; - P[2] = (*data)[2]; - P[3] = (*data)[3]; - B[4] = (*data)[4]; - B[5] = (*data)[5]; - B[6] = (*data)[6]; - B[7] = (*data)[7]; - (*data) += 8; - - if (P[2] <= P[3]) { - - /* vertical split; left & right halves are 2-color encoded */ - - flags = - ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | - ((B[0] & 0x0F)) | ((B[4] & 0x0F) << 4) | - ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | - ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); - bitmask = 0x00000001; - - for (y = 0; y < 8; ++y) { - - /* time to reload flags? */ - if (y == 4) { - flags = - ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | - ((B[2] & 0x0F)) | ((B[6] & 0x0F) << 4) | - ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | - ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); - bitmask = 0x00000001; - } - - /* get the pixel values ready for this half */ - P0 = P[0]; - P1 = P[1]; - - for (x = 0; x < 8; ++x, bitmask <<= 1) { - if (x == 4) { - P0 = P[2]; - P1 = P[3]; - } - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - - } else { - - /* horizontal split; top & bottom halves are 2-color encoded */ - - P0 = P[0]; - P1 = P[1]; - - for (y = 0; y < 8; ++y) { - - flags = B[y]; - if (y == 4) { - P0 = P[2]; - P1 = P[3]; - } - - for (bitmask = 0x01; bitmask <= 0x80; bitmask <<= 1) { - - if (flags & bitmask) - *frame++ = P1; - else - *frame++ = P0; - } - frame += s->width - 8; - } - } - } - - return 0; -} - -static int -ipvideo_decode_0x9 (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P[4]; - unsigned char B[4]; - unsigned long flags = 0; - int shifter = 0; - unsigned char pix; - - /* 4-color encoding */ - CHECK_STREAM (len, 4 + 4); - - P[0] = (*data)[0]; - P[1] = (*data)[1]; - P[2] = (*data)[2]; - P[3] = (*data)[3]; - (*data) += 4; - - if ((P[0] <= P[1]) && (P[2] <= P[3])) { - - /* 1 of 4 colors for each pixel, need 16 more bytes */ - CHECK_STREAM (len, 16 - 4); - - for (y = 0; y < 8; ++y) { - /* get the next set of 8 2-bit flags */ - flags = ((*data)[1] << 8) | (*data)[0]; - (*data) += 2; - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - *frame++ = P[(flags >> shifter) & 0x03]; - } - frame += s->width - 8; - } - - } else if ((P[0] <= P[1]) && (P[2] > P[3])) { - - /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ - B[0] = (*data)[0]; - B[1] = (*data)[1]; - B[2] = (*data)[2]; - B[3] = (*data)[3]; - (*data) += 4; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + x + 1) = pix; - *(frame + s->width + x) = pix; - *(frame + s->width + x + 1) = pix; - } - frame += s->width * 2; - } - - } else if ((P[0] > P[1]) && (P[2] <= P[3])) { - - /* 1 of 4 colors for each 2x1 block, need 8 more bytes */ - CHECK_STREAM (len, 8 - 4); - - for (y = 0; y < 8; ++y) { - /* time to reload flags? */ - if ((y == 0) || (y == 4)) { - B[0] = (*data)[0]; - B[1] = (*data)[1]; - B[2] = (*data)[2]; - B[3] = (*data)[3]; - (*data) += 4; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - } - for (x = 0; x < 8; x += 2, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + x + 1) = pix; - } - frame += s->width; - } - - } else { - - /* 1 of 4 colors for each 1x2 block, need 8 more bytes */ - CHECK_STREAM (len, 8 - 4); - - for (y = 0; y < 8; y += 2) { - /* time to reload flags? */ - if ((y == 0) || (y == 4)) { - B[0] = (*data)[0]; - B[1] = (*data)[1]; - B[2] = (*data)[2]; - B[3] = (*data)[3]; - (*data) += 4; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; - shifter = 0; - } - for (x = 0; x < 8; ++x, shifter += 2) { - pix = P[(flags >> shifter) & 0x03]; - *(frame + x) = pix; - *(frame + s->width + x) = pix; - } - frame += s->width * 2; - } - } - - return 0; -} - -static int -ipvideo_decode_0xa (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P[16]; - unsigned char B[16]; - int flags = 0; - int shifter = 0; - int index; - int split; - int lower_half; - - /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM (len, 8 + 16); - - P[0] = (*data)[0]; - P[1] = (*data)[1]; - P[2] = (*data)[2]; - P[3] = (*data)[3]; - B[0] = (*data)[4]; - B[1] = (*data)[5]; - B[2] = (*data)[6]; - B[3] = (*data)[7]; - (*data) += 8; - - if (P[0] <= P[1]) { - - /* 4-color encoding for each quadrant; need 24 more bytes */ - CHECK_STREAM (len, 24 - 16); - - for (y = 4; y < 16; y += 4) { - for (x = y; x < y + 4; ++x) - P[x] = *(*data)++; - for (x = y; x < y + 4; ++x) - B[x] = *(*data)++; - } - - for (y = 0; y < 8; ++y) { - - lower_half = (y >= 4) ? 4 : 0; - flags = (B[y + 8] << 8) | B[y]; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - split = (x >= 4) ? 8 : 0; - index = split + lower_half + ((flags >> shifter) & 0x03); - *frame++ = P[index]; - } - - frame += s->width - 8; - } - - } else { - - /* 4-color encoding for either left and right or top and bottom - * halves; need 16 more bytes */ - - B[4] = (*data)[0]; - B[5] = (*data)[1]; - B[6] = (*data)[2]; - B[7] = (*data)[3]; - P[4] = (*data)[4]; - P[5] = (*data)[5]; - P[6] = (*data)[6]; - P[7] = (*data)[7]; - (*data) += 8; - memcpy (&B[8], *data, 8); - (*data) += 8; - - if (P[4] <= P[5]) { - - /* block is divided into left and right halves */ - for (y = 0; y < 8; ++y) { - - flags = (B[y + 8] << 8) | B[y]; - split = 0; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) { - if (x == 4) - split = 4; - *frame++ = P[split + ((flags >> shifter) & 0x03)]; - } - - frame += s->width - 8; - } - - } else { - - /* block is divided into top and bottom halves */ - split = 0; - for (y = 0; y < 8; ++y) { - - flags = (B[y * 2 + 1] << 8) | B[y * 2]; - if (y == 4) - split = 4; - - for (x = 0, shifter = 0; x < 8; ++x, shifter += 2) - *frame++ = P[split + ((flags >> shifter) & 0x03)]; - - frame += s->width - 8; - } - } - } - - return 0; -} - -static int -ipvideo_decode_0xb (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int y; - - /* 64-color encoding (each pixel in block is a different color) */ - CHECK_STREAM (len, 64); - - for (y = 0; y < 8; ++y) { - memcpy (frame, *data, 8); - frame += s->width; - (*data) += 8; - } - - return 0; -} - -static int -ipvideo_decode_0xc (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char pix; - - /* 16-color block encoding: each 2x2 block is a different color */ - CHECK_STREAM (len, 16); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2) { - pix = *(*data)++; - *(frame + x) = pix; - *(frame + x + 1) = pix; - *(frame + s->width + x) = pix; - *(frame + s->width + x + 1) = pix; - } - frame += s->width * 2; - } - - return 0; -} - -static int -ipvideo_decode_0xd (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P[4]; - unsigned char index = 0; - - /* 4-color block encoding: each 4x4 block is a different color */ - CHECK_STREAM (len, 4); - - P[0] = (*data)[0]; - P[1] = (*data)[1]; - P[2] = (*data)[2]; - P[3] = (*data)[3]; - (*data) += 4; - - for (y = 0; y < 8; ++y) { - if (y < 4) - index = 0; - else - index = 2; - - for (x = 0; x < 8; ++x) { - if (x == 4) - ++index; - *frame++ = P[index]; - } - frame += s->width - 8; - } - - return 0; -} - -static int -ipvideo_decode_0xe (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int y; - unsigned char pix; - - /* 1-color encoding: the whole block is 1 solid color */ - CHECK_STREAM (len, 1); - pix = *(*data)++; - - for (y = 0; y < 8; ++y) { - memset (frame, pix, 8); - frame += s->width; - } - - return 0; -} - -static int -ipvideo_decode_0xf (const GstMveDemuxStream * s, unsigned char *frame, - const unsigned char **data, unsigned short *len) -{ - int x, y; - unsigned char P[2]; - - /* dithered encoding */ - CHECK_STREAM (len, 2); - - P[0] = *(*data)++; - P[1] = *(*data)++; - - for (y = 0; y < 8; ++y) { - for (x = 0; x < 4; ++x) { - *frame++ = P[y & 1]; - *frame++ = P[(y & 1) ^ 1]; - } - frame += s->width - 8; - } - - return 0; -} - -int -ipvideo_decode_frame8 (const GstMveDemuxStream * s, const unsigned char *data, - unsigned short len) -{ - int rc = 0; - int x, y, xx, yy; - int index = 0; - unsigned char opcode; - unsigned char *frame; - - frame = s->back_buf1; - - /* decoding is done in 8x8 blocks */ - xx = s->width >> 3; - yy = s->height >> 3; - - for (y = 0; y < yy; ++y) { - for (x = 0; x < xx; ++x) { - /* decoding map contains 4 bits of information per 8x8 block */ - /* bottom nibble first, then top nibble */ - if (index & 1) - opcode = s->code_map[index >> 1] >> 4; - else - opcode = s->code_map[index >> 1] & 0x0F; - ++index; - - /* GST_DEBUG ("block @ (%3d, %3d): encoding 0x%X, data ptr @ %p", - x, y, opcode, data); */ - - switch (opcode) { - case 0x00: - /* copy a block from the previous frame */ - rc = ipvideo_copy_block (s, frame, - frame + (s->back_buf2 - s->back_buf1), 0); - break; - case 0x01: - /* copy block from 2 frames ago; since we switched the back - * buffers we don't actually have to do anything here */ - break; - case 0x02: - rc = ipvideo_decode_0x2 (s, frame, &data, &len); - break; - case 0x03: - rc = ipvideo_decode_0x3 (s, frame, &data, &len); - break; - case 0x04: - rc = ipvideo_decode_0x4 (s, frame, &data, &len); - break; - case 0x05: - rc = ipvideo_decode_0x5 (s, frame, &data, &len); - break; - case 0x06: - /* mystery opcode? skip multiple blocks? */ - GST_WARNING ("encountered unsupported opcode 0x6"); - rc = -1; - break; - case 0x07: - rc = ipvideo_decode_0x7 (s, frame, &data, &len); - break; - case 0x08: - rc = ipvideo_decode_0x8 (s, frame, &data, &len); - break; - case 0x09: - rc = ipvideo_decode_0x9 (s, frame, &data, &len); - break; - case 0x0a: - rc = ipvideo_decode_0xa (s, frame, &data, &len); - break; - case 0x0b: - rc = ipvideo_decode_0xb (s, frame, &data, &len); - break; - case 0x0c: - rc = ipvideo_decode_0xc (s, frame, &data, &len); - break; - case 0x0d: - rc = ipvideo_decode_0xd (s, frame, &data, &len); - break; - case 0x0e: - rc = ipvideo_decode_0xe (s, frame, &data, &len); - break; - case 0x0f: - rc = ipvideo_decode_0xf (s, frame, &data, &len); - break; - } - - if (rc != 0) - return rc; - - frame += 8; - } - frame += 7 * s->width; - } - - return 0; -}