From c2117ee86d4f8b59fd9201d51987714ab1b8d7e1 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 23 Jun 2006 18:07:28 +0000 Subject: [PATCH] Behold, Nenya, Ring of Water and repository for our media and animation related goodies, both Java 2D and LWJGL/JME 3D. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1 ed5b42cb-e716-0410-a449-f6a68f950b19 --- LICENSE | 458 +++++ README | 69 + build.xml | 323 +++ code | 1 + docs/media/design.txt | 44 + docs/media/notes.txt | 14 + docs/miso/design.txt | 139 ++ docs/miso/fringebits.png | Bin 0 -> 43448 bytes docs/miso/render_sort_diagram.dia | Bin 0 -> 1761 bytes docs/miso/render_sort_diagram.png | Bin 0 -> 44536 bytes docs/miso/scene.ps | 51 + docs/miso/scenegroup.xml | 21 + docs/stylesheet.css | 52 + lib/LIBS | 17 + lib/README | 26 + lib/SOURCE_HEADER | 21 + src/java/com/threerings/cast/ActionCache.java | 42 + .../com/threerings/cast/ActionFrames.java | 67 + .../com/threerings/cast/ActionSequence.java | 72 + src/java/com/threerings/cast/CastPrefs.java | 35 + .../threerings/cast/CharacterComponent.java | 100 + .../threerings/cast/CharacterDescriptor.java | 144 ++ .../com/threerings/cast/CharacterManager.java | 430 ++++ .../com/threerings/cast/CharacterSprite.java | 402 ++++ .../com/threerings/cast/ComponentClass.java | 241 +++ .../threerings/cast/ComponentIDBroker.java | 63 + .../threerings/cast/ComponentRepository.java | 71 + .../cast/CompositedActionFrames.java | 186 ++ .../cast/CompositedMaskedImage.java | 131 ++ .../cast/CompositedMultiFrameImage.java | 254 +++ .../cast/CompositedShadowImage.java | 92 + .../com/threerings/cast/FrameProvider.java | 37 + src/java/com/threerings/cast/Log.java | 56 + .../cast/NoSuchComponentException.java | 50 + .../com/threerings/cast/StandardActions.java | 42 + .../cast/TrimmedMultiFrameImage.java | 41 + .../threerings/cast/builder/BuilderModel.java | 151 ++ .../cast/builder/BuilderModelListener.java | 40 + .../threerings/cast/builder/BuilderPanel.java | 60 + .../threerings/cast/builder/ClassEditor.java | 109 ++ .../cast/builder/ComponentPanel.java | 74 + .../threerings/cast/builder/SpritePanel.java | 131 ++ .../threerings/cast/bundle/BundleUtil.java | 110 ++ .../bundle/BundledComponentRepository.java | 528 +++++ .../bundle/tools/ComponentBundlerTask.java | 624 ++++++ .../cast/bundle/tools/DumpBundle.java | 84 + .../bundle/tools/MetadataBundlerTask.java | 267 +++ .../cast/tools/xml/ActionRuleSet.java | 146 ++ .../cast/tools/xml/ClassRuleSet.java | 110 ++ .../com/threerings/cast/util/CastUtil.java | 97 + src/java/com/threerings/geom/GeomUtil.java | 251 +++ src/java/com/threerings/geom/Log.java | 63 + src/java/com/threerings/jme/JmeApp.java | 582 ++++++ src/java/com/threerings/jme/JmeCanvasApp.java | 184 ++ src/java/com/threerings/jme/JmeContext.java | 59 + src/java/com/threerings/jme/Log.java | 56 + src/java/com/threerings/jme/StatsDisplay.java | 83 + .../threerings/jme/camera/CameraHandler.java | 412 ++++ .../com/threerings/jme/camera/CameraPath.java | 69 + .../threerings/jme/camera/GodViewHandler.java | 191 ++ .../com/threerings/jme/camera/PanPath.java | 87 + .../com/threerings/jme/camera/SplinePath.java | 113 ++ .../com/threerings/jme/camera/SwingPath.java | 168 ++ .../com/threerings/jme/camera/rotate_zoom.dia | Bin 0 -> 1672 bytes .../com/threerings/jme/camera/rotate_zoom.png | Bin 0 -> 16237 bytes .../com/threerings/jme/chat/ChatView.java | 181 ++ .../jme/effect/FadeInOutEffect.java | 148 ++ .../threerings/jme/effect/WindowSlider.java | 127 ++ .../jme/model/EmissionController.java | 79 + src/java/com/threerings/jme/model/Model.java | 1036 ++++++++++ .../threerings/jme/model/ModelController.java | 167 ++ .../com/threerings/jme/model/ModelMesh.java | 557 ++++++ .../com/threerings/jme/model/ModelNode.java | 407 ++++ .../threerings/jme/model/ModelSpatial.java | 115 ++ .../com/threerings/jme/model/Rotator.java | 128 ++ .../com/threerings/jme/model/SkinMesh.java | 495 +++++ .../threerings/jme/model/TextureProvider.java | 39 + src/java/com/threerings/jme/package.html | 15 + .../threerings/jme/sprite/BallisticPath.java | 92 + .../com/threerings/jme/sprite/LinePath.java | 60 + .../jme/sprite/LineSegmentPath.java | 103 + .../jme/sprite/OrientingBallisticPath.java | 70 + src/java/com/threerings/jme/sprite/Path.java | 51 + .../threerings/jme/sprite/PathObserver.java | 44 + .../com/threerings/jme/sprite/PathUtil.java | 95 + .../com/threerings/jme/sprite/Sprite.java | 244 +++ .../threerings/jme/sprite/SpriteObserver.java | 29 + .../jme/tile/FringeConfiguration.java | 160 ++ .../com/threerings/jme/tile/TileFringer.java | 404 ++++ .../tools/CompileFringeConfigurationTask.java | 76 + .../tools/xml/FringeConfigurationParser.java | 84 + .../threerings/jme/tools/AnimationDef.java | 165 ++ .../threerings/jme/tools/BuildSphereMap.java | 167 ++ .../jme/tools/BuildSphereMapTask.java | 86 + .../threerings/jme/tools/CompileModel.java | 139 ++ .../jme/tools/CompileModelTask.java | 77 + .../threerings/jme/tools/ConvertModel.java | 101 + .../jme/tools/ConvertModelTask.java | 135 ++ .../com/threerings/jme/tools/ModelDef.java | 573 ++++++ .../com/threerings/jme/tools/ModelViewer.java | 1019 ++++++++++ .../jme/tools/xml/AnimationParser.java | 88 + .../threerings/jme/tools/xml/ModelParser.java | 109 ++ .../jme/util/LinearTimeFunction.java | 42 + .../com/threerings/jme/util/TimeFunction.java | 99 + .../com/threerings/media/AbstractMedia.java | 332 ++++ .../media/AbstractMediaManager.java | 335 ++++ .../media/ActiveRepaintManager.java | 502 +++++ .../threerings/media/BackFrameManager.java | 148 ++ .../threerings/media/FlipFrameManager.java | 101 + .../com/threerings/media/FrameInterval.java | 111 ++ .../com/threerings/media/FrameManager.java | 846 ++++++++ .../threerings/media/FrameParticipant.java | 64 + .../com/threerings/media/HourglassView.java | 175 ++ .../com/threerings/media/IconManager.java | 183 ++ src/java/com/threerings/media/Log.java | 63 + .../com/threerings/media/ManagedJFrame.java | 117 ++ .../com/threerings/media/MediaConstants.java | 37 + src/java/com/threerings/media/MediaPanel.java | 783 ++++++++ src/java/com/threerings/media/MediaPrefs.java | 35 + .../com/threerings/media/RegionManager.java | 165 ++ .../com/threerings/media/SafeScrollPane.java | 89 + src/java/com/threerings/media/TimerView.java | 513 +++++ .../com/threerings/media/ViewTracker.java | 18 + .../threerings/media/VirtualMediaPanel.java | 463 +++++ .../threerings/media/VirtualRangeModel.java | 109 ++ .../threerings/media/animation/Animation.java | 169 ++ .../media/animation/AnimationAdapter.java | 38 + .../media/animation/AnimationArranger.java | 68 + .../animation/AnimationFrameSequencer.java | 260 +++ .../media/animation/AnimationManager.java | 81 + .../media/animation/AnimationObserver.java | 39 + .../media/animation/AnimationSequencer.java | 295 +++ .../media/animation/AnimationWaiter.java | 95 + .../media/animation/BlankAnimation.java | 67 + .../media/animation/BlendAnimation.java | 87 + .../media/animation/BobbleAnimation.java | 120 ++ .../media/animation/ExplodeAnimation.java | 336 ++++ .../media/animation/FadeAnimation.java | 85 + .../media/animation/FadeImageAnimation.java | 52 + .../media/animation/FadeLabelAnimation.java | 99 + .../animation/FloatingTextAnimation.java | 248 +++ .../media/animation/GleamAnimation.java | 150 ++ .../media/animation/MultiFrameAnimation.java | 134 ++ .../media/animation/RainAnimation.java | 134 ++ .../media/animation/ScaleAnimation.java | 192 ++ .../animation/SequencedAnimationObserver.java | 35 + .../media/animation/SparkAnimation.java | 257 +++ .../media/animation/SpriteAnimation.java | 102 + .../threerings/media/effects/FadeEffect.java | 125 ++ .../media/image/AWTImageCreator.java | 71 + .../media/image/BackedVolatileMirage.java | 82 + .../threerings/media/image/BlankMirage.java | 77 + .../media/image/BufferedMirage.java | 74 + .../media/image/CachedVolatileMirage.java | 104 + .../threerings/media/image/ColorPository.java | 461 +++++ .../com/threerings/media/image/ColorUtil.java | 57 + .../threerings/media/image/Colorization.java | 194 ++ .../media/image/CompositeMirage.java | 96 + .../threerings/media/image/FastImageIO.java | 174 ++ .../media/image/ImageDataProvider.java | 46 + .../threerings/media/image/ImageManager.java | 615 ++++++ .../com/threerings/media/image/ImageUtil.java | 647 ++++++ .../com/threerings/media/image/Mirage.java | 67 + .../threerings/media/image/MirageIcon.java | 60 + .../com/threerings/media/image/Quantize.java | 776 ++++++++ .../media/image/TransformedMirage.java | 145 ++ .../media/image/VolatileMirage.java | 202 ++ .../media/image/tools/DumpColorPository.java | 54 + .../image/tools/xml/ColorPositoryParser.java | 78 + .../threerings/media/sound/MidiPlayer.java | 178 ++ .../com/threerings/media/sound/ModPlayer.java | 135 ++ .../com/threerings/media/sound/Mp3Player.java | 148 ++ .../threerings/media/sound/MusicManager.java | 353 ++++ .../threerings/media/sound/MusicPlayer.java | 89 + .../com/threerings/media/sound/OggPlayer.java | 401 ++++ .../threerings/media/sound/SoundCodes.java | 57 + .../threerings/media/sound/SoundManager.java | 1044 ++++++++++ .../com/threerings/media/sound/Sounds.java | 49 + .../threerings/media/sprite/ButtonSprite.java | 384 ++++ .../media/sprite/FadableImageSprite.java | 203 ++ .../threerings/media/sprite/ImageSprite.java | 331 ++++ .../threerings/media/sprite/LabelSprite.java | 115 ++ .../media/sprite/OrientableImageSprite.java | 198 ++ .../threerings/media/sprite/PathAdapter.java | 40 + .../threerings/media/sprite/PathObserver.java | 49 + .../com/threerings/media/sprite/Sprite.java | 462 +++++ .../threerings/media/sprite/SpriteIcon.java | 94 + .../media/sprite/SpriteManager.java | 269 +++ .../media/sprite/action/ActionSprite.java | 16 + .../media/sprite/action/ArmingSprite.java | 16 + .../media/sprite/action/CommandSprite.java | 16 + .../sprite/action/DisableableSprite.java | 16 + .../media/sprite/action/HoverSprite.java | 16 + .../media/tile/IMImageProvider.java | 73 + .../threerings/media/tile/ImageProvider.java | 64 + .../media/tile/NoSuchTileSetException.java | 39 + .../com/threerings/media/tile/ObjectTile.java | 232 +++ .../threerings/media/tile/ObjectTileSet.java | 295 +++ .../media/tile/RecolorableTileSet.java | 16 + .../tile/SimpleCachingImageProvider.java | 77 + .../media/tile/SwissArmyTileSet.java | 207 ++ src/java/com/threerings/media/tile/Tile.java | 178 ++ .../com/threerings/media/tile/TileIcon.java | 64 + .../threerings/media/tile/TileManager.java | 247 +++ .../media/tile/TileMultiFrameImage.java | 84 + .../com/threerings/media/tile/TileSet.java | 454 +++++ .../media/tile/TileSetIDBroker.java | 70 + .../media/tile/TileSetRepository.java | 86 + .../com/threerings/media/tile/TileUtil.java | 70 + .../media/tile/TrimmedObjectTileSet.java | 301 +++ .../threerings/media/tile/TrimmedTile.java | 91 + .../threerings/media/tile/TrimmedTileSet.java | 114 ++ .../threerings/media/tile/UniformTileSet.java | 103 + .../media/tile/bundle/BundleUtil.java | 82 + .../tile/bundle/BundledTileSetRepository.java | 232 +++ .../media/tile/bundle/TileSetBundle.java | 148 ++ .../media/tile/bundle/tools/DumpBundle.java | 93 + .../tile/bundle/tools/TileSetBundler.java | 482 +++++ .../tile/bundle/tools/TileSetBundlerTask.java | 143 ++ .../media/tile/tools/DumpTileSetMap.java | 56 + .../tile/tools/MapFileTileSetIDBroker.java | 224 +++ .../media/tile/tools/RenameTileSet.java | 74 + .../tile/tools/xml/ObjectTileSetRuleSet.java | 188 ++ .../tools/xml/SwissArmyTileSetRuleSet.java | 156 ++ .../media/tile/tools/xml/TileSetRuleSet.java | 128 ++ .../tile/tools/xml/UniformTileSetRuleSet.java | 86 + .../tile/tools/xml/XMLTileSetParser.java | 172 ++ .../media/tile/util/TileSetTrimmer.java | 146 ++ .../threerings/media/timer/MediaTimer.java | 52 + .../com/threerings/media/timer/PerfTimer.java | 69 + .../media/timer/SystemMediaTimer.java | 60 + .../threerings/media/tools/RecolorImage.java | 476 +++++ .../threerings/media/util/AStarPathUtil.java | 437 +++++ .../com/threerings/media/util/ArcPath.java | 238 +++ .../media/util/BackgroundTiler.java | 208 ++ .../com/threerings/media/util/BobblePath.java | 191 ++ .../com/threerings/media/util/DelayPath.java | 91 + .../media/util/DelegatingPathable.java | 87 + .../threerings/media/util/FrameSequencer.java | 113 ++ .../com/threerings/media/util/LinePath.java | 151 ++ .../media/util/LineSegmentPath.java | 388 ++++ .../media/util/LinearTimeFunction.java | 22 + .../com/threerings/media/util/MathUtil.java | 162 ++ .../com/threerings/media/util/ModeUtil.java | 99 + .../media/util/MultiFrameImage.java | 58 + .../media/util/MultiFrameImageImpl.java | 75 + src/java/com/threerings/media/util/Path.java | 82 + .../com/threerings/media/util/PathNode.java | 72 + .../threerings/media/util/PathSequence.java | 143 ++ .../com/threerings/media/util/Pathable.java | 77 + .../media/util/PerformanceMonitor.java | 215 ++ .../media/util/PerformanceObserver.java | 39 + .../media/util/SingleFrameImageImpl.java | 75 + .../media/util/SingleTileImageImpl.java | 75 + .../media/util/SmoothBobblePath.java | 86 + .../com/threerings/media/util/TiledArea.java | 61 + .../threerings/media/util/TimeFunction.java | 83 + .../com/threerings/media/util/TimedPath.java | 98 + .../media/util/TrailingAverage.java | 81 + src/java/com/threerings/miso/Log.java | 56 + src/java/com/threerings/miso/MisoConfig.java | 61 + src/java/com/threerings/miso/MisoPrefs.java | 35 + .../threerings/miso/client/DirtyItemList.java | 680 +++++++ .../miso/client/MisoScenePanel.java | 1735 +++++++++++++++++ .../miso/client/ObjectActionHandler.java | 151 ++ .../miso/client/ResolutionView.java | 164 ++ .../threerings/miso/client/SceneBlock.java | 596 ++++++ .../miso/client/SceneBlockResolver.java | 138 ++ .../threerings/miso/client/SceneObject.java | 358 ++++ .../miso/client/SceneObjectActionEvent.java | 48 + .../miso/client/SceneObjectTip.java | 206 ++ .../com/threerings/miso/client/TilePath.java | 144 ++ .../threerings/miso/data/MisoSceneModel.java | 129 ++ .../com/threerings/miso/data/ObjectInfo.java | 168 ++ .../miso/data/SimpleMisoSceneModel.java | 282 +++ .../miso/data/SparseMisoSceneModel.java | 445 +++++ .../miso/data/VirtualMisoSceneModel.java | 58 + .../com/threerings/miso/tile/AutoFringer.java | 390 ++++ .../com/threerings/miso/tile/BaseTile.java | 52 + .../com/threerings/miso/tile/BaseTileSet.java | 81 + .../miso/tile/FringeConfiguration.java | 158 ++ .../threerings/miso/tile/MisoTileManager.java | 92 + .../tools/CompileFringeConfigurationTask.java | 96 + .../tile/tools/xml/BaseTileSetRuleSet.java | 84 + .../tools/xml/FringeConfigurationParser.java | 168 ++ .../miso/tools/xml/SimpleMisoSceneParser.java | 90 + .../tools/xml/SimpleMisoSceneRuleSet.java | 108 + .../miso/tools/xml/SimpleMisoSceneWriter.java | 116 ++ .../miso/tools/xml/SparseMisoSceneParser.java | 97 + .../tools/xml/SparseMisoSceneRuleSet.java | 85 + .../miso/tools/xml/SparseMisoSceneWriter.java | 131 ++ .../com/threerings/miso/util/MisoContext.java | 43 + .../miso/util/MisoSceneMetrics.java | 101 + .../com/threerings/miso/util/MisoUtil.java | 518 +++++ .../com/threerings/miso/util/ObjectSet.java | 182 ++ .../com/threerings/openal/BlankSound.java | 38 + src/java/com/threerings/openal/Clip.java | 41 + .../com/threerings/openal/ClipBuffer.java | 287 +++ .../com/threerings/openal/ClipProvider.java | 33 + src/java/com/threerings/openal/Log.java | 56 + .../com/threerings/openal/OggFileStream.java | 121 ++ src/java/com/threerings/openal/Sound.java | 298 +++ .../com/threerings/openal/SoundGroup.java | 155 ++ .../com/threerings/openal/SoundManager.java | 347 ++++ src/java/com/threerings/openal/Stream.java | 350 ++++ .../openal/WaveDataClipProvider.java | 46 + src/java/com/threerings/resource/Handler.java | 194 ++ src/java/com/threerings/resource/Log.java | 56 + .../threerings/resource/ResourceBundle.java | 418 ++++ .../threerings/resource/ResourceManager.java | 691 +++++++ src/java/com/threerings/util/BrowserUtil.java | 141 ++ .../com/threerings/util/DirectionCodes.java | 104 + .../com/threerings/util/DirectionUtil.java | 338 ++++ src/java/com/threerings/util/IdleTracker.java | 177 ++ .../com/threerings/util/KeyDispatcher.java | 275 +++ .../com/threerings/util/KeyTranslator.java | 79 + .../threerings/util/KeyTranslatorImpl.java | 190 ++ .../com/threerings/util/KeyboardManager.java | 720 +++++++ src/java/com/threerings/util/Log.java | 56 + .../com/threerings/util/keybd/Keyboard.java | 83 + .../com/threerings/util/keybd/Linux/Makefile | 44 + .../com_threerings_util_keybd_Keyboard.c | 87 + .../threerings/util/keybd/Linux/libkeybd.so | Bin 0 -> 8129 bytes .../threerings/util/keybd/Mac OS X/Makefile | 7 + .../threerings/util/keybd/Windows/.cvsignore | 1 + .../threerings/util/keybd/Windows/Makefile | 27 + .../com_threerings_util_keybd_Keyboard.c | 104 + .../com_threerings_util_keybd_Keyboard.h | 29 + .../threerings/util/unsafe/FreeBSD/Makefile | 45 + .../com_threerings_util_unsafe_Unsafe.c | 97 + .../util/unsafe/FreeBSD/libunsafe.so | Bin 0 -> 6809 bytes .../com/threerings/util/unsafe/Linux/Makefile | 44 + .../Linux/com_threerings_util_unsafe_Unsafe.c | 97 + .../threerings/util/unsafe/Linux/libunsafe.so | Bin 0 -> 8251 bytes .../threerings/util/unsafe/Mac OS X/Makefile | 7 + .../com/threerings/util/unsafe/Unsafe.java | 144 ++ .../threerings/util/unsafe/Windows/.cvsignore | 1 + .../threerings/util/unsafe/Windows/Makefile | 49 + .../com_threerings_util_unsafe_Unsafe.c | 52 + .../com_threerings_util_unsafe_Unsafe.h | 47 + tests/bin/miso-viewer | 3 + tests/bin/runjava | 108 + tests/build.xml | 196 ++ tests/rsrc/bundles/components/.cvsignore | 2 + tests/rsrc/bundles/components/actions.xml | 76 + tests/rsrc/bundles/components/classes.xml | 32 + .../rsrc/bundles/components/pirate/.cvsignore | 1 + .../female/feet/barefoot/behind_back.png | Bin 0 -> 11300 bytes .../pirate/female/feet/barefoot/standing.png | Bin 0 -> 11371 bytes .../pirate/female/feet/barefoot/walking.png | Bin 0 -> 32989 bytes .../pirate/female/feet/boots/behind_back.png | Bin 0 -> 12175 bytes .../pirate/female/feet/boots/standing.png | Bin 0 -> 12294 bytes .../pirate/female/feet/boots/walking.png | Bin 0 -> 37845 bytes .../female/feet/buckleshoes/behind_back.png | Bin 0 -> 11899 bytes .../female/feet/buckleshoes/standing.png | Bin 0 -> 12001 bytes .../female/feet/buckleshoes/walking.png | Bin 0 -> 36196 bytes .../feet/pegleg_barefoot/behind_back.png | Bin 0 -> 10916 bytes .../female/feet/pegleg_barefoot/standing.png | Bin 0 -> 11005 bytes .../female/feet/pegleg_barefoot/walking.png | Bin 0 -> 30681 bytes .../female/feet/pegleg_boots/behind_back.png | Bin 0 -> 11364 bytes .../female/feet/pegleg_boots/standing.png | Bin 0 -> 11466 bytes .../female/feet/pegleg_boots/walking.png | Bin 0 -> 33138 bytes .../feet/pegleg_buckleshoes/behind_back.png | Bin 0 -> 11179 bytes .../feet/pegleg_buckleshoes/standing.png | Bin 0 -> 11293 bytes .../feet/pegleg_buckleshoes/walking.png | Bin 0 -> 32226 bytes .../female/hair/long_straight/behind_back.png | Bin 0 -> 15123 bytes .../female/hair/long_straight/standing.png | Bin 0 -> 15006 bytes .../female/hair/long_straight/walking.png | Bin 0 -> 56485 bytes .../female/hair/messy_short/behind_back.png | Bin 0 -> 11874 bytes .../female/hair/messy_short/standing.png | Bin 0 -> 11836 bytes .../female/hair/messy_short/walking.png | Bin 0 -> 36424 bytes .../female/hair/ponytail/behind_back.png | Bin 0 -> 13870 bytes .../pirate/female/hair/ponytail/standing.png | Bin 0 -> 13738 bytes .../pirate/female/hair/ponytail/walking.png | Bin 0 -> 48589 bytes .../female/hand_left/barehand/behind_back.png | Bin 0 -> 8572 bytes .../female/hand_left/barehand/standing.png | Bin 0 -> 8456 bytes .../female/hand_left/barehand/walking.png | Bin 0 -> 16925 bytes .../female/hand_left/hook/behind_back.png | Bin 0 -> 8619 bytes .../pirate/female/hand_left/hook/standing.png | Bin 0 -> 8580 bytes .../pirate/female/hand_left/hook/walking.png | Bin 0 -> 17338 bytes .../hand_right/barehand/behind_back.png | Bin 0 -> 8580 bytes .../female/hand_right/barehand/standing.png | Bin 0 -> 8474 bytes .../female/hand_right/barehand/walking.png | Bin 0 -> 16894 bytes .../female/hat/captains/behind_back.png | Bin 0 -> 14952 bytes .../pirate/female/hat/captains/standing.png | Bin 0 -> 14904 bytes .../pirate/female/hat/captains/walking.png | Bin 0 -> 52256 bytes .../hat/small_feathered/behind_back.png | Bin 0 -> 15811 bytes .../female/hat/small_feathered/standing.png | Bin 0 -> 15716 bytes .../female/hat/small_feathered/walking.png | Bin 0 -> 56551 bytes .../female/hat/tricorne/behind_back.png | Bin 0 -> 16409 bytes .../pirate/female/hat/tricorne/standing.png | Bin 0 -> 16218 bytes .../pirate/female/hat/tricorne/walking.png | Bin 0 -> 62437 bytes .../female/hat/wide_brimmed/behind_back.png | Bin 0 -> 16552 bytes .../female/hat/wide_brimmed/standing.png | Bin 0 -> 16346 bytes .../female/hat/wide_brimmed/walking.png | Bin 0 -> 60511 bytes .../female/head/eyepatch/behind_back.png | Bin 0 -> 12098 bytes .../pirate/female/head/eyepatch/standing.png | Bin 0 -> 12053 bytes .../pirate/female/head/eyepatch/walking.png | Bin 0 -> 35700 bytes .../pirate/female/head/normal/behind_back.png | Bin 0 -> 11976 bytes .../pirate/female/head/normal/standing.png | Bin 0 -> 11946 bytes .../pirate/female/head/normal/walking.png | Bin 0 -> 35226 bytes .../legs/dressbottom_long/behind_back.png | Bin 0 -> 19063 bytes .../female/legs/dressbottom_long/standing.png | Bin 0 -> 19422 bytes .../female/legs/dressbottom_long/walking.png | Bin 0 -> 70442 bytes .../legs/stripey_knickers/behind_back.png | Bin 0 -> 13730 bytes .../female/legs/stripey_knickers/standing.png | Bin 0 -> 13843 bytes .../female/legs/stripey_knickers/walking.png | Bin 0 -> 46207 bytes .../female/torso/bodice/behind_back.png | Bin 0 -> 15117 bytes .../pirate/female/torso/bodice/standing.png | Bin 0 -> 15442 bytes .../pirate/female/torso/bodice/walking.png | Bin 0 -> 56954 bytes .../female/torso/dresstop/behind_back.png | Bin 0 -> 14872 bytes .../pirate/female/torso/dresstop/standing.png | Bin 0 -> 15314 bytes .../pirate/female/torso/dresstop/walking.png | Bin 0 -> 54343 bytes .../male/eyepatch/blackpatch/behind_back.png | Bin 0 -> 8120 bytes .../male/eyepatch/blackpatch/standing.png | Bin 0 -> 8107 bytes .../male/eyepatch/blackpatch/walking.png | Bin 0 -> 15536 bytes .../pirate/male/feet/barefoot/behind_back.png | Bin 0 -> 12523 bytes .../pirate/male/feet/barefoot/standing.png | Bin 0 -> 12443 bytes .../pirate/male/feet/barefoot/walking.png | Bin 0 -> 40260 bytes .../pirate/male/feet/boots/behind_back.png | Bin 0 -> 13113 bytes .../pirate/male/feet/boots/standing.png | Bin 0 -> 13111 bytes .../pirate/male/feet/boots/walking.png | Bin 0 -> 43494 bytes .../male/feet/pegleg_barefoot/behind_back.png | Bin 0 -> 11664 bytes .../male/feet/pegleg_barefoot/standing.png | Bin 0 -> 11659 bytes .../male/feet/pegleg_barefoot/walking.png | Bin 0 -> 35271 bytes .../male/feet/pegleg_boots/behind_back.png | Bin 0 -> 12020 bytes .../male/feet/pegleg_boots/standing.png | Bin 0 -> 12020 bytes .../pirate/male/feet/pegleg_boots/walking.png | Bin 0 -> 37251 bytes .../pirate/male/hair/ponytail/behind_back.png | Bin 0 -> 12663 bytes .../pirate/male/hair/ponytail/standing.png | Bin 0 -> 12644 bytes .../pirate/male/hair/ponytail/walking.png | Bin 0 -> 41819 bytes .../male/hair/princevaliant/behind_back.png | Bin 0 -> 12983 bytes .../male/hair/princevaliant/standing.png | Bin 0 -> 13007 bytes .../male/hair/princevaliant/walking.png | Bin 0 -> 42438 bytes .../male/hand_left/barehand/behind_back.png | Bin 0 -> 8646 bytes .../male/hand_left/barehand/standing.png | Bin 0 -> 8546 bytes .../male/hand_left/barehand/walking.png | Bin 0 -> 17512 bytes .../male/hand_left/hook/behind_back.png | Bin 0 -> 8850 bytes .../pirate/male/hand_left/hook/standing.png | Bin 0 -> 8770 bytes .../pirate/male/hand_left/hook/walking.png | Bin 0 -> 18799 bytes .../male/hand_right/barehand/behind_back.png | Bin 0 -> 8654 bytes .../male/hand_right/barehand/standing.png | Bin 0 -> 8561 bytes .../male/hand_right/barehand/walking.png | Bin 0 -> 17547 bytes .../pirate/male/hat/bandana/behind_back.png | Bin 0 -> 12896 bytes .../pirate/male/hat/bandana/standing.png | Bin 0 -> 12897 bytes .../pirate/male/hat/bandana/walking.png | Bin 0 -> 41822 bytes .../pirate/male/hat/captains/behind_back.png | Bin 0 -> 15623 bytes .../pirate/male/hat/captains/standing.png | Bin 0 -> 15588 bytes .../pirate/male/hat/captains/walking.png | Bin 0 -> 55074 bytes .../male/hat/sleepinghat/behind_back.png | Bin 0 -> 13257 bytes .../pirate/male/hat/sleepinghat/standing.png | Bin 0 -> 13290 bytes .../pirate/male/hat/sleepinghat/walking.png | Bin 0 -> 43562 bytes .../pirate/male/head/bald/behind_back.png | Bin 0 -> 11976 bytes .../pirate/male/head/bald/standing.png | Bin 0 -> 11936 bytes .../pirate/male/head/bald/walking.png | Bin 0 -> 34915 bytes .../pirate/male/head/goatee/behind_back.png | Bin 0 -> 12085 bytes .../pirate/male/head/goatee/standing.png | Bin 0 -> 12055 bytes .../pirate/male/head/goatee/walking.png | Bin 0 -> 35533 bytes .../male/head/shortbeard/behind_back.png | Bin 0 -> 12323 bytes .../pirate/male/head/shortbeard/standing.png | Bin 0 -> 12309 bytes .../pirate/male/head/shortbeard/walking.png | Bin 0 -> 36495 bytes .../pirate/male/legs/pants/behind_back.png | Bin 0 -> 13556 bytes .../pirate/male/legs/pants/standing.png | Bin 0 -> 13612 bytes .../pirate/male/legs/pants/walking.png | Bin 0 -> 46731 bytes .../male/legs/stripeyknickers/behind_back.png | Bin 0 -> 14830 bytes .../male/legs/stripeyknickers/standing.png | Bin 0 -> 14829 bytes .../male/legs/stripeyknickers/walking.png | Bin 0 -> 52122 bytes .../male/torso/shirt_sash/behind_back.png | Bin 0 -> 16901 bytes .../pirate/male/torso/shirt_sash/standing.png | Bin 0 -> 17691 bytes .../pirate/male/torso/shirt_sash/walking.png | Bin 0 -> 71046 bytes .../vest_stripedshirt_belt/behind_back.png | Bin 0 -> 16968 bytes .../torso/vest_stripedshirt_belt/standing.png | Bin 0 -> 17510 bytes .../torso/vest_stripedshirt_belt/walking.png | Bin 0 -> 68282 bytes .../rsrc/bundles/components/vessel/.cvsignore | 1 + .../vessel/navsail/merchgal/sailing.png | Bin 0 -> 151934 bytes .../vessel/navsail/merchgal/sailing_small.png | Bin 0 -> 11714 bytes .../vessel/navsail/smsloop/sailing.png | Bin 0 -> 52331 bytes .../vessel/navsail/smsloop/sailing_small.png | Bin 0 -> 6183 bytes tests/rsrc/bundles/tiles/.cvsignore | 1 + tests/rsrc/bundles/tiles/bundler-config.xml | 28 + tests/rsrc/bundles/tiles/ground/.cvsignore | 1 + tests/rsrc/bundles/tiles/ground/bundle.xml | 70 + tests/rsrc/bundles/tiles/ground/cobble.png | Bin 0 -> 7230 bytes tests/rsrc/bundles/tiles/ground/dirt.png | Bin 0 -> 6625 bytes tests/rsrc/bundles/tiles/ground/fringe.png | Bin 0 -> 14012 bytes .../rsrc/bundles/tiles/ground/fringemask.png | Bin 0 -> 4784 bytes tests/rsrc/bundles/tiles/ground/sand.png | Bin 0 -> 7217 bytes tests/rsrc/bundles/tiles/ground/seafringe.png | Bin 0 -> 26210 bytes tests/rsrc/bundles/tiles/ground/seawater.png | Bin 0 -> 10739 bytes .../rsrc/bundles/tiles/ground/woodplanks.png | Bin 0 -> 6084 bytes tests/rsrc/bundles/tiles/objects/.cvsignore | 1 + .../rsrc/bundles/tiles/objects/bag_cloth.png | Bin 0 -> 4853 bytes .../rsrc/bundles/tiles/objects/barrel_oak.png | Bin 0 -> 5704 bytes tests/rsrc/bundles/tiles/objects/bundle.xml | 137 ++ .../bundles/tiles/objects/chest_purse.png | Bin 0 -> 19129 bytes .../bundles/tiles/objects/chest_treasure.png | Bin 0 -> 22001 bytes tests/rsrc/bundles/tiles/objects/crate.png | Bin 0 -> 8348 bytes tests/rsrc/bundles/tiles/objects/dockedge.png | Bin 0 -> 6365 bytes tests/rsrc/bundles/tiles/objects/house.png | Bin 0 -> 260565 bytes tests/rsrc/bundles/tiles/objects/mooring.png | Bin 0 -> 5986 bytes tests/rsrc/bundles/tiles/objects/tree_oak.png | Bin 0 -> 67720 bytes .../rsrc/bundles/tiles/objects/tree_palm.png | Bin 0 -> 69112 bytes tests/rsrc/bundles/tiles/objects/well.png | Bin 0 -> 22952 bytes tests/rsrc/config/media/iconmgr.properties | 7 + tests/rsrc/config/miso/components.xml | 35 + tests/rsrc/config/miso/scrolling.properties | 59 + tests/rsrc/config/miso/tile/.cvsignore | 1 + tests/rsrc/config/miso/tile/fringeconf.xml | 39 + .../rsrc/config/miso/tilesets-components.xml | 31 + tests/rsrc/config/miso/tilesets.xml | 78 + tests/rsrc/config/miso/viewer.properties | 7 + tests/rsrc/config/resource/editor.properties | 16 + tests/rsrc/config/resource/manager.properties | 16 + tests/rsrc/media/miso/tiles/building.png | Bin 0 -> 158557 bytes .../tiles/components/standing_hat_tri.png | Bin 0 -> 7417 bytes .../miso/tiles/components/standing_torso.png | Bin 0 -> 54712 bytes .../tiles/components/standing_torso_red.png | Bin 0 -> 18005 bytes .../miso/tiles/components/walking_hat_tri.png | Bin 0 -> 17350 bytes .../miso/tiles/components/walking_torso.png | Bin 0 -> 255218 bytes .../tiles/components/walking_torso_red.png | Bin 0 -> 33622 bytes tests/rsrc/media/miso/tiles/faux-building.png | Bin 0 -> 15486 bytes tests/rsrc/media/miso/tiles/landscape.png | Bin 0 -> 8653 bytes tests/rsrc/media/miso/tiles/node-icons.png | Bin 0 -> 369 bytes tests/rsrc/media/miso/tiles/sample.png | Bin 0 -> 19248 bytes tests/rsrc/media/test.wav | Bin 0 -> 96300 bytes tests/rsrc/media/tile/bundle/tools/.cvsignore | 1 + .../rsrc/media/tile/bundle/tools/building.png | Bin 0 -> 158557 bytes tests/rsrc/media/tile/bundle/tools/bundle.xml | 35 + .../tile/bundle/tools/bundler-config.xml | 19 + tests/rsrc/media/tile/bundle/tools/fringe.png | Bin 0 -> 14012 bytes .../media/tile/bundle/tools/node-icons.png | Bin 0 -> 369 bytes tests/rsrc/media/tile/tools/xml/tilesets.xml | 37 + tests/rsrc/scenes/idyll.xml | 19 + tests/rsrc/scenes/wooded.xml | 31 + .../com/threerings/cast/CharSpriteViz.java | 153 ++ .../com/threerings/cast/builder/TestApp.java | 76 + .../threerings/cast/builder/TestFrame.java | 43 + .../BundledComponentRepositoryTest.java | 85 + .../java/com/threerings/geom/NearestViz.java | 101 + .../com/threerings/geom/WhichSideViz.java | 113 ++ .../com/threerings/jme/JmeCanvasTest.java | 62 + .../com/threerings/jme/client/JabberApp.java | 160 ++ .../threerings/jme/client/JabberClient.java | 228 +++ .../jme/client/JabberController.java | 19 + .../com/threerings/jme/client/JabberView.java | 51 + .../com/threerings/jme/data/JabberConfig.java | 26 + .../threerings/jme/server/JabberServer.java | 49 + .../com/threerings/jme/sprite/PathTest.java | 150 ++ .../threerings/media/ImageLoadingSpeed.java | 80 + .../com/threerings/media/TestIconManager.java | 65 + .../threerings/media/sound/SoundTestApp.java | 68 + .../threerings/media/sound/sounds.properties | 7 + .../bundle/BundledTileSetRepositoryTest.java | 70 + .../bundle/tools/BuildTestTileSetBundle.java | 94 + .../tile/tools/xml/XMLTileSetParserTest.java | 78 + .../com/threerings/media/util/PathViz.java | 111 ++ .../com/threerings/media/util/TraceViz.java | 115 ++ .../miso/client/ScrollingFrame.java | 89 + .../miso/client/ScrollingScene.java | 124 ++ .../miso/client/ScrollingTestApp.java | 234 +++ .../com/threerings/miso/viewer/ViewerApp.java | 191 ++ .../threerings/miso/viewer/ViewerFrame.java | 94 + .../miso/viewer/ViewerSceneViewPanel.java | 237 +++ .../threerings/openal/TestSoundManager.java | 55 + .../com/threerings/util/DirectionTest.java | 73 + .../com/threerings/util/DirectionViz.java | 86 + .../java/com/threerings/util/KeyTimerApp.java | 97 + .../threerings/util/KeyboardManagerApp.java | 108 + .../threerings/util/MessageBundleTest.java | 79 + .../src/java/com/threerings/util/UIDTest.java | 30 + 570 files changed, 61913 insertions(+) create mode 100644 LICENSE create mode 100644 README create mode 100644 build.xml create mode 120000 code create mode 100644 docs/media/design.txt create mode 100644 docs/media/notes.txt create mode 100644 docs/miso/design.txt create mode 100644 docs/miso/fringebits.png create mode 100644 docs/miso/render_sort_diagram.dia create mode 100644 docs/miso/render_sort_diagram.png create mode 100644 docs/miso/scene.ps create mode 100644 docs/miso/scenegroup.xml create mode 100644 docs/stylesheet.css create mode 100644 lib/LIBS create mode 100644 lib/README create mode 100644 lib/SOURCE_HEADER create mode 100644 src/java/com/threerings/cast/ActionCache.java create mode 100644 src/java/com/threerings/cast/ActionFrames.java create mode 100644 src/java/com/threerings/cast/ActionSequence.java create mode 100644 src/java/com/threerings/cast/CastPrefs.java create mode 100644 src/java/com/threerings/cast/CharacterComponent.java create mode 100644 src/java/com/threerings/cast/CharacterDescriptor.java create mode 100644 src/java/com/threerings/cast/CharacterManager.java create mode 100644 src/java/com/threerings/cast/CharacterSprite.java create mode 100644 src/java/com/threerings/cast/ComponentClass.java create mode 100644 src/java/com/threerings/cast/ComponentIDBroker.java create mode 100644 src/java/com/threerings/cast/ComponentRepository.java create mode 100644 src/java/com/threerings/cast/CompositedActionFrames.java create mode 100644 src/java/com/threerings/cast/CompositedMaskedImage.java create mode 100644 src/java/com/threerings/cast/CompositedMultiFrameImage.java create mode 100644 src/java/com/threerings/cast/CompositedShadowImage.java create mode 100644 src/java/com/threerings/cast/FrameProvider.java create mode 100644 src/java/com/threerings/cast/Log.java create mode 100644 src/java/com/threerings/cast/NoSuchComponentException.java create mode 100644 src/java/com/threerings/cast/StandardActions.java create mode 100644 src/java/com/threerings/cast/TrimmedMultiFrameImage.java create mode 100644 src/java/com/threerings/cast/builder/BuilderModel.java create mode 100644 src/java/com/threerings/cast/builder/BuilderModelListener.java create mode 100644 src/java/com/threerings/cast/builder/BuilderPanel.java create mode 100644 src/java/com/threerings/cast/builder/ClassEditor.java create mode 100644 src/java/com/threerings/cast/builder/ComponentPanel.java create mode 100644 src/java/com/threerings/cast/builder/SpritePanel.java create mode 100644 src/java/com/threerings/cast/bundle/BundleUtil.java create mode 100644 src/java/com/threerings/cast/bundle/BundledComponentRepository.java create mode 100644 src/java/com/threerings/cast/bundle/tools/ComponentBundlerTask.java create mode 100644 src/java/com/threerings/cast/bundle/tools/DumpBundle.java create mode 100644 src/java/com/threerings/cast/bundle/tools/MetadataBundlerTask.java create mode 100644 src/java/com/threerings/cast/tools/xml/ActionRuleSet.java create mode 100644 src/java/com/threerings/cast/tools/xml/ClassRuleSet.java create mode 100644 src/java/com/threerings/cast/util/CastUtil.java create mode 100644 src/java/com/threerings/geom/GeomUtil.java create mode 100644 src/java/com/threerings/geom/Log.java create mode 100644 src/java/com/threerings/jme/JmeApp.java create mode 100644 src/java/com/threerings/jme/JmeCanvasApp.java create mode 100644 src/java/com/threerings/jme/JmeContext.java create mode 100644 src/java/com/threerings/jme/Log.java create mode 100644 src/java/com/threerings/jme/StatsDisplay.java create mode 100644 src/java/com/threerings/jme/camera/CameraHandler.java create mode 100644 src/java/com/threerings/jme/camera/CameraPath.java create mode 100644 src/java/com/threerings/jme/camera/GodViewHandler.java create mode 100644 src/java/com/threerings/jme/camera/PanPath.java create mode 100644 src/java/com/threerings/jme/camera/SplinePath.java create mode 100644 src/java/com/threerings/jme/camera/SwingPath.java create mode 100644 src/java/com/threerings/jme/camera/rotate_zoom.dia create mode 100644 src/java/com/threerings/jme/camera/rotate_zoom.png create mode 100644 src/java/com/threerings/jme/chat/ChatView.java create mode 100644 src/java/com/threerings/jme/effect/FadeInOutEffect.java create mode 100644 src/java/com/threerings/jme/effect/WindowSlider.java create mode 100644 src/java/com/threerings/jme/model/EmissionController.java create mode 100644 src/java/com/threerings/jme/model/Model.java create mode 100644 src/java/com/threerings/jme/model/ModelController.java create mode 100644 src/java/com/threerings/jme/model/ModelMesh.java create mode 100644 src/java/com/threerings/jme/model/ModelNode.java create mode 100644 src/java/com/threerings/jme/model/ModelSpatial.java create mode 100644 src/java/com/threerings/jme/model/Rotator.java create mode 100644 src/java/com/threerings/jme/model/SkinMesh.java create mode 100644 src/java/com/threerings/jme/model/TextureProvider.java create mode 100644 src/java/com/threerings/jme/package.html create mode 100644 src/java/com/threerings/jme/sprite/BallisticPath.java create mode 100644 src/java/com/threerings/jme/sprite/LinePath.java create mode 100644 src/java/com/threerings/jme/sprite/LineSegmentPath.java create mode 100644 src/java/com/threerings/jme/sprite/OrientingBallisticPath.java create mode 100644 src/java/com/threerings/jme/sprite/Path.java create mode 100644 src/java/com/threerings/jme/sprite/PathObserver.java create mode 100644 src/java/com/threerings/jme/sprite/PathUtil.java create mode 100644 src/java/com/threerings/jme/sprite/Sprite.java create mode 100644 src/java/com/threerings/jme/sprite/SpriteObserver.java create mode 100644 src/java/com/threerings/jme/tile/FringeConfiguration.java create mode 100644 src/java/com/threerings/jme/tile/TileFringer.java create mode 100644 src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java create mode 100644 src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java create mode 100644 src/java/com/threerings/jme/tools/AnimationDef.java create mode 100644 src/java/com/threerings/jme/tools/BuildSphereMap.java create mode 100644 src/java/com/threerings/jme/tools/BuildSphereMapTask.java create mode 100644 src/java/com/threerings/jme/tools/CompileModel.java create mode 100644 src/java/com/threerings/jme/tools/CompileModelTask.java create mode 100644 src/java/com/threerings/jme/tools/ConvertModel.java create mode 100644 src/java/com/threerings/jme/tools/ConvertModelTask.java create mode 100644 src/java/com/threerings/jme/tools/ModelDef.java create mode 100644 src/java/com/threerings/jme/tools/ModelViewer.java create mode 100644 src/java/com/threerings/jme/tools/xml/AnimationParser.java create mode 100644 src/java/com/threerings/jme/tools/xml/ModelParser.java create mode 100644 src/java/com/threerings/jme/util/LinearTimeFunction.java create mode 100644 src/java/com/threerings/jme/util/TimeFunction.java create mode 100644 src/java/com/threerings/media/AbstractMedia.java create mode 100644 src/java/com/threerings/media/AbstractMediaManager.java create mode 100644 src/java/com/threerings/media/ActiveRepaintManager.java create mode 100644 src/java/com/threerings/media/BackFrameManager.java create mode 100644 src/java/com/threerings/media/FlipFrameManager.java create mode 100644 src/java/com/threerings/media/FrameInterval.java create mode 100644 src/java/com/threerings/media/FrameManager.java create mode 100644 src/java/com/threerings/media/FrameParticipant.java create mode 100644 src/java/com/threerings/media/HourglassView.java create mode 100644 src/java/com/threerings/media/IconManager.java create mode 100644 src/java/com/threerings/media/Log.java create mode 100644 src/java/com/threerings/media/ManagedJFrame.java create mode 100644 src/java/com/threerings/media/MediaConstants.java create mode 100644 src/java/com/threerings/media/MediaPanel.java create mode 100644 src/java/com/threerings/media/MediaPrefs.java create mode 100644 src/java/com/threerings/media/RegionManager.java create mode 100644 src/java/com/threerings/media/SafeScrollPane.java create mode 100644 src/java/com/threerings/media/TimerView.java create mode 100644 src/java/com/threerings/media/ViewTracker.java create mode 100644 src/java/com/threerings/media/VirtualMediaPanel.java create mode 100644 src/java/com/threerings/media/VirtualRangeModel.java create mode 100644 src/java/com/threerings/media/animation/Animation.java create mode 100644 src/java/com/threerings/media/animation/AnimationAdapter.java create mode 100644 src/java/com/threerings/media/animation/AnimationArranger.java create mode 100644 src/java/com/threerings/media/animation/AnimationFrameSequencer.java create mode 100644 src/java/com/threerings/media/animation/AnimationManager.java create mode 100644 src/java/com/threerings/media/animation/AnimationObserver.java create mode 100644 src/java/com/threerings/media/animation/AnimationSequencer.java create mode 100644 src/java/com/threerings/media/animation/AnimationWaiter.java create mode 100644 src/java/com/threerings/media/animation/BlankAnimation.java create mode 100644 src/java/com/threerings/media/animation/BlendAnimation.java create mode 100644 src/java/com/threerings/media/animation/BobbleAnimation.java create mode 100644 src/java/com/threerings/media/animation/ExplodeAnimation.java create mode 100644 src/java/com/threerings/media/animation/FadeAnimation.java create mode 100644 src/java/com/threerings/media/animation/FadeImageAnimation.java create mode 100644 src/java/com/threerings/media/animation/FadeLabelAnimation.java create mode 100644 src/java/com/threerings/media/animation/FloatingTextAnimation.java create mode 100644 src/java/com/threerings/media/animation/GleamAnimation.java create mode 100644 src/java/com/threerings/media/animation/MultiFrameAnimation.java create mode 100644 src/java/com/threerings/media/animation/RainAnimation.java create mode 100644 src/java/com/threerings/media/animation/ScaleAnimation.java create mode 100644 src/java/com/threerings/media/animation/SequencedAnimationObserver.java create mode 100644 src/java/com/threerings/media/animation/SparkAnimation.java create mode 100644 src/java/com/threerings/media/animation/SpriteAnimation.java create mode 100644 src/java/com/threerings/media/effects/FadeEffect.java create mode 100644 src/java/com/threerings/media/image/AWTImageCreator.java create mode 100644 src/java/com/threerings/media/image/BackedVolatileMirage.java create mode 100644 src/java/com/threerings/media/image/BlankMirage.java create mode 100644 src/java/com/threerings/media/image/BufferedMirage.java create mode 100644 src/java/com/threerings/media/image/CachedVolatileMirage.java create mode 100644 src/java/com/threerings/media/image/ColorPository.java create mode 100644 src/java/com/threerings/media/image/ColorUtil.java create mode 100644 src/java/com/threerings/media/image/Colorization.java create mode 100644 src/java/com/threerings/media/image/CompositeMirage.java create mode 100644 src/java/com/threerings/media/image/FastImageIO.java create mode 100644 src/java/com/threerings/media/image/ImageDataProvider.java create mode 100644 src/java/com/threerings/media/image/ImageManager.java create mode 100644 src/java/com/threerings/media/image/ImageUtil.java create mode 100644 src/java/com/threerings/media/image/Mirage.java create mode 100644 src/java/com/threerings/media/image/MirageIcon.java create mode 100644 src/java/com/threerings/media/image/Quantize.java create mode 100644 src/java/com/threerings/media/image/TransformedMirage.java create mode 100644 src/java/com/threerings/media/image/VolatileMirage.java create mode 100644 src/java/com/threerings/media/image/tools/DumpColorPository.java create mode 100644 src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java create mode 100644 src/java/com/threerings/media/sound/MidiPlayer.java create mode 100644 src/java/com/threerings/media/sound/ModPlayer.java create mode 100644 src/java/com/threerings/media/sound/Mp3Player.java create mode 100644 src/java/com/threerings/media/sound/MusicManager.java create mode 100644 src/java/com/threerings/media/sound/MusicPlayer.java create mode 100644 src/java/com/threerings/media/sound/OggPlayer.java create mode 100644 src/java/com/threerings/media/sound/SoundCodes.java create mode 100644 src/java/com/threerings/media/sound/SoundManager.java create mode 100644 src/java/com/threerings/media/sound/Sounds.java create mode 100644 src/java/com/threerings/media/sprite/ButtonSprite.java create mode 100644 src/java/com/threerings/media/sprite/FadableImageSprite.java create mode 100644 src/java/com/threerings/media/sprite/ImageSprite.java create mode 100644 src/java/com/threerings/media/sprite/LabelSprite.java create mode 100644 src/java/com/threerings/media/sprite/OrientableImageSprite.java create mode 100644 src/java/com/threerings/media/sprite/PathAdapter.java create mode 100644 src/java/com/threerings/media/sprite/PathObserver.java create mode 100644 src/java/com/threerings/media/sprite/Sprite.java create mode 100644 src/java/com/threerings/media/sprite/SpriteIcon.java create mode 100644 src/java/com/threerings/media/sprite/SpriteManager.java create mode 100644 src/java/com/threerings/media/sprite/action/ActionSprite.java create mode 100644 src/java/com/threerings/media/sprite/action/ArmingSprite.java create mode 100644 src/java/com/threerings/media/sprite/action/CommandSprite.java create mode 100644 src/java/com/threerings/media/sprite/action/DisableableSprite.java create mode 100644 src/java/com/threerings/media/sprite/action/HoverSprite.java create mode 100644 src/java/com/threerings/media/tile/IMImageProvider.java create mode 100644 src/java/com/threerings/media/tile/ImageProvider.java create mode 100644 src/java/com/threerings/media/tile/NoSuchTileSetException.java create mode 100644 src/java/com/threerings/media/tile/ObjectTile.java create mode 100644 src/java/com/threerings/media/tile/ObjectTileSet.java create mode 100644 src/java/com/threerings/media/tile/RecolorableTileSet.java create mode 100644 src/java/com/threerings/media/tile/SimpleCachingImageProvider.java create mode 100644 src/java/com/threerings/media/tile/SwissArmyTileSet.java create mode 100644 src/java/com/threerings/media/tile/Tile.java create mode 100644 src/java/com/threerings/media/tile/TileIcon.java create mode 100644 src/java/com/threerings/media/tile/TileManager.java create mode 100644 src/java/com/threerings/media/tile/TileMultiFrameImage.java create mode 100644 src/java/com/threerings/media/tile/TileSet.java create mode 100644 src/java/com/threerings/media/tile/TileSetIDBroker.java create mode 100644 src/java/com/threerings/media/tile/TileSetRepository.java create mode 100644 src/java/com/threerings/media/tile/TileUtil.java create mode 100644 src/java/com/threerings/media/tile/TrimmedObjectTileSet.java create mode 100644 src/java/com/threerings/media/tile/TrimmedTile.java create mode 100644 src/java/com/threerings/media/tile/TrimmedTileSet.java create mode 100644 src/java/com/threerings/media/tile/UniformTileSet.java create mode 100644 src/java/com/threerings/media/tile/bundle/BundleUtil.java create mode 100644 src/java/com/threerings/media/tile/bundle/BundledTileSetRepository.java create mode 100644 src/java/com/threerings/media/tile/bundle/TileSetBundle.java create mode 100644 src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java create mode 100644 src/java/com/threerings/media/tile/bundle/tools/TileSetBundler.java create mode 100644 src/java/com/threerings/media/tile/bundle/tools/TileSetBundlerTask.java create mode 100644 src/java/com/threerings/media/tile/tools/DumpTileSetMap.java create mode 100644 src/java/com/threerings/media/tile/tools/MapFileTileSetIDBroker.java create mode 100644 src/java/com/threerings/media/tile/tools/RenameTileSet.java create mode 100644 src/java/com/threerings/media/tile/tools/xml/ObjectTileSetRuleSet.java create mode 100644 src/java/com/threerings/media/tile/tools/xml/SwissArmyTileSetRuleSet.java create mode 100644 src/java/com/threerings/media/tile/tools/xml/TileSetRuleSet.java create mode 100644 src/java/com/threerings/media/tile/tools/xml/UniformTileSetRuleSet.java create mode 100644 src/java/com/threerings/media/tile/tools/xml/XMLTileSetParser.java create mode 100644 src/java/com/threerings/media/tile/util/TileSetTrimmer.java create mode 100644 src/java/com/threerings/media/timer/MediaTimer.java create mode 100644 src/java/com/threerings/media/timer/PerfTimer.java create mode 100644 src/java/com/threerings/media/timer/SystemMediaTimer.java create mode 100644 src/java/com/threerings/media/tools/RecolorImage.java create mode 100644 src/java/com/threerings/media/util/AStarPathUtil.java create mode 100644 src/java/com/threerings/media/util/ArcPath.java create mode 100644 src/java/com/threerings/media/util/BackgroundTiler.java create mode 100644 src/java/com/threerings/media/util/BobblePath.java create mode 100644 src/java/com/threerings/media/util/DelayPath.java create mode 100644 src/java/com/threerings/media/util/DelegatingPathable.java create mode 100644 src/java/com/threerings/media/util/FrameSequencer.java create mode 100644 src/java/com/threerings/media/util/LinePath.java create mode 100644 src/java/com/threerings/media/util/LineSegmentPath.java create mode 100644 src/java/com/threerings/media/util/LinearTimeFunction.java create mode 100644 src/java/com/threerings/media/util/MathUtil.java create mode 100644 src/java/com/threerings/media/util/ModeUtil.java create mode 100644 src/java/com/threerings/media/util/MultiFrameImage.java create mode 100644 src/java/com/threerings/media/util/MultiFrameImageImpl.java create mode 100644 src/java/com/threerings/media/util/Path.java create mode 100644 src/java/com/threerings/media/util/PathNode.java create mode 100644 src/java/com/threerings/media/util/PathSequence.java create mode 100644 src/java/com/threerings/media/util/Pathable.java create mode 100644 src/java/com/threerings/media/util/PerformanceMonitor.java create mode 100644 src/java/com/threerings/media/util/PerformanceObserver.java create mode 100644 src/java/com/threerings/media/util/SingleFrameImageImpl.java create mode 100644 src/java/com/threerings/media/util/SingleTileImageImpl.java create mode 100644 src/java/com/threerings/media/util/SmoothBobblePath.java create mode 100644 src/java/com/threerings/media/util/TiledArea.java create mode 100644 src/java/com/threerings/media/util/TimeFunction.java create mode 100644 src/java/com/threerings/media/util/TimedPath.java create mode 100644 src/java/com/threerings/media/util/TrailingAverage.java create mode 100644 src/java/com/threerings/miso/Log.java create mode 100644 src/java/com/threerings/miso/MisoConfig.java create mode 100644 src/java/com/threerings/miso/MisoPrefs.java create mode 100644 src/java/com/threerings/miso/client/DirtyItemList.java create mode 100644 src/java/com/threerings/miso/client/MisoScenePanel.java create mode 100644 src/java/com/threerings/miso/client/ObjectActionHandler.java create mode 100644 src/java/com/threerings/miso/client/ResolutionView.java create mode 100644 src/java/com/threerings/miso/client/SceneBlock.java create mode 100644 src/java/com/threerings/miso/client/SceneBlockResolver.java create mode 100644 src/java/com/threerings/miso/client/SceneObject.java create mode 100644 src/java/com/threerings/miso/client/SceneObjectActionEvent.java create mode 100644 src/java/com/threerings/miso/client/SceneObjectTip.java create mode 100644 src/java/com/threerings/miso/client/TilePath.java create mode 100644 src/java/com/threerings/miso/data/MisoSceneModel.java create mode 100644 src/java/com/threerings/miso/data/ObjectInfo.java create mode 100644 src/java/com/threerings/miso/data/SimpleMisoSceneModel.java create mode 100644 src/java/com/threerings/miso/data/SparseMisoSceneModel.java create mode 100644 src/java/com/threerings/miso/data/VirtualMisoSceneModel.java create mode 100644 src/java/com/threerings/miso/tile/AutoFringer.java create mode 100644 src/java/com/threerings/miso/tile/BaseTile.java create mode 100644 src/java/com/threerings/miso/tile/BaseTileSet.java create mode 100644 src/java/com/threerings/miso/tile/FringeConfiguration.java create mode 100644 src/java/com/threerings/miso/tile/MisoTileManager.java create mode 100644 src/java/com/threerings/miso/tile/tools/CompileFringeConfigurationTask.java create mode 100644 src/java/com/threerings/miso/tile/tools/xml/BaseTileSetRuleSet.java create mode 100644 src/java/com/threerings/miso/tile/tools/xml/FringeConfigurationParser.java create mode 100644 src/java/com/threerings/miso/tools/xml/SimpleMisoSceneParser.java create mode 100644 src/java/com/threerings/miso/tools/xml/SimpleMisoSceneRuleSet.java create mode 100644 src/java/com/threerings/miso/tools/xml/SimpleMisoSceneWriter.java create mode 100644 src/java/com/threerings/miso/tools/xml/SparseMisoSceneParser.java create mode 100644 src/java/com/threerings/miso/tools/xml/SparseMisoSceneRuleSet.java create mode 100644 src/java/com/threerings/miso/tools/xml/SparseMisoSceneWriter.java create mode 100644 src/java/com/threerings/miso/util/MisoContext.java create mode 100644 src/java/com/threerings/miso/util/MisoSceneMetrics.java create mode 100644 src/java/com/threerings/miso/util/MisoUtil.java create mode 100644 src/java/com/threerings/miso/util/ObjectSet.java create mode 100644 src/java/com/threerings/openal/BlankSound.java create mode 100644 src/java/com/threerings/openal/Clip.java create mode 100644 src/java/com/threerings/openal/ClipBuffer.java create mode 100644 src/java/com/threerings/openal/ClipProvider.java create mode 100644 src/java/com/threerings/openal/Log.java create mode 100644 src/java/com/threerings/openal/OggFileStream.java create mode 100644 src/java/com/threerings/openal/Sound.java create mode 100644 src/java/com/threerings/openal/SoundGroup.java create mode 100644 src/java/com/threerings/openal/SoundManager.java create mode 100644 src/java/com/threerings/openal/Stream.java create mode 100644 src/java/com/threerings/openal/WaveDataClipProvider.java create mode 100644 src/java/com/threerings/resource/Handler.java create mode 100644 src/java/com/threerings/resource/Log.java create mode 100644 src/java/com/threerings/resource/ResourceBundle.java create mode 100644 src/java/com/threerings/resource/ResourceManager.java create mode 100644 src/java/com/threerings/util/BrowserUtil.java create mode 100644 src/java/com/threerings/util/DirectionCodes.java create mode 100644 src/java/com/threerings/util/DirectionUtil.java create mode 100644 src/java/com/threerings/util/IdleTracker.java create mode 100644 src/java/com/threerings/util/KeyDispatcher.java create mode 100644 src/java/com/threerings/util/KeyTranslator.java create mode 100644 src/java/com/threerings/util/KeyTranslatorImpl.java create mode 100644 src/java/com/threerings/util/KeyboardManager.java create mode 100644 src/java/com/threerings/util/Log.java create mode 100644 src/java/com/threerings/util/keybd/Keyboard.java create mode 100644 src/java/com/threerings/util/keybd/Linux/Makefile create mode 100644 src/java/com/threerings/util/keybd/Linux/com_threerings_util_keybd_Keyboard.c create mode 100755 src/java/com/threerings/util/keybd/Linux/libkeybd.so create mode 100644 src/java/com/threerings/util/keybd/Mac OS X/Makefile create mode 100644 src/java/com/threerings/util/keybd/Windows/.cvsignore create mode 100644 src/java/com/threerings/util/keybd/Windows/Makefile create mode 100644 src/java/com/threerings/util/keybd/Windows/com_threerings_util_keybd_Keyboard.c create mode 100644 src/java/com/threerings/util/keybd/com_threerings_util_keybd_Keyboard.h create mode 100644 src/java/com/threerings/util/unsafe/FreeBSD/Makefile create mode 100644 src/java/com/threerings/util/unsafe/FreeBSD/com_threerings_util_unsafe_Unsafe.c create mode 100755 src/java/com/threerings/util/unsafe/FreeBSD/libunsafe.so create mode 100644 src/java/com/threerings/util/unsafe/Linux/Makefile create mode 100644 src/java/com/threerings/util/unsafe/Linux/com_threerings_util_unsafe_Unsafe.c create mode 100755 src/java/com/threerings/util/unsafe/Linux/libunsafe.so create mode 100644 src/java/com/threerings/util/unsafe/Mac OS X/Makefile create mode 100644 src/java/com/threerings/util/unsafe/Unsafe.java create mode 100644 src/java/com/threerings/util/unsafe/Windows/.cvsignore create mode 100644 src/java/com/threerings/util/unsafe/Windows/Makefile create mode 100644 src/java/com/threerings/util/unsafe/Windows/com_threerings_util_unsafe_Unsafe.c create mode 100644 src/java/com/threerings/util/unsafe/com_threerings_util_unsafe_Unsafe.h create mode 100755 tests/bin/miso-viewer create mode 100755 tests/bin/runjava create mode 100644 tests/build.xml create mode 100644 tests/rsrc/bundles/components/.cvsignore create mode 100644 tests/rsrc/bundles/components/actions.xml create mode 100644 tests/rsrc/bundles/components/classes.xml create mode 100644 tests/rsrc/bundles/components/pirate/.cvsignore create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/barefoot/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/barefoot/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/barefoot/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/boots/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/boots/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/boots/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/buckleshoes/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/buckleshoes/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/buckleshoes/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/long_straight/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/long_straight/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/long_straight/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/messy_short/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/messy_short/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/messy_short/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/ponytail/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/ponytail/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hair/ponytail/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/barehand/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/barehand/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/barehand/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/hook/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/hook/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_left/hook/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_right/barehand/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_right/barehand/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hand_right/barehand/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/captains/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/captains/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/captains/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/small_feathered/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/small_feathered/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/small_feathered/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/tricorne/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/tricorne/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/tricorne/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/eyepatch/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/eyepatch/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/eyepatch/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/normal/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/normal/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/head/normal/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/bodice/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/bodice/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/bodice/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/dresstop/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/dresstop/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/female/torso/dresstop/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/barefoot/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/barefoot/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/barefoot/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/boots/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/boots/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/boots/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_barefoot/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_barefoot/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_barefoot/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_boots/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_boots/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/feet/pegleg_boots/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/ponytail/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/ponytail/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/ponytail/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/princevaliant/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/princevaliant/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hair/princevaliant/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/barehand/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/barehand/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/barehand/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/hook/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/hook/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_left/hook/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_right/barehand/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_right/barehand/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hand_right/barehand/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/bandana/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/bandana/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/bandana/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/captains/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/captains/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/captains/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/bald/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/bald/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/bald/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/goatee/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/goatee/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/goatee/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/shortbeard/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/shortbeard/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/head/shortbeard/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/pants/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/pants/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/pants/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/walking.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/behind_back.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/standing.png create mode 100644 tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/walking.png create mode 100644 tests/rsrc/bundles/components/vessel/.cvsignore create mode 100644 tests/rsrc/bundles/components/vessel/navsail/merchgal/sailing.png create mode 100644 tests/rsrc/bundles/components/vessel/navsail/merchgal/sailing_small.png create mode 100644 tests/rsrc/bundles/components/vessel/navsail/smsloop/sailing.png create mode 100644 tests/rsrc/bundles/components/vessel/navsail/smsloop/sailing_small.png create mode 100644 tests/rsrc/bundles/tiles/.cvsignore create mode 100644 tests/rsrc/bundles/tiles/bundler-config.xml create mode 100644 tests/rsrc/bundles/tiles/ground/.cvsignore create mode 100644 tests/rsrc/bundles/tiles/ground/bundle.xml create mode 100644 tests/rsrc/bundles/tiles/ground/cobble.png create mode 100644 tests/rsrc/bundles/tiles/ground/dirt.png create mode 100644 tests/rsrc/bundles/tiles/ground/fringe.png create mode 100644 tests/rsrc/bundles/tiles/ground/fringemask.png create mode 100644 tests/rsrc/bundles/tiles/ground/sand.png create mode 100644 tests/rsrc/bundles/tiles/ground/seafringe.png create mode 100644 tests/rsrc/bundles/tiles/ground/seawater.png create mode 100644 tests/rsrc/bundles/tiles/ground/woodplanks.png create mode 100644 tests/rsrc/bundles/tiles/objects/.cvsignore create mode 100644 tests/rsrc/bundles/tiles/objects/bag_cloth.png create mode 100644 tests/rsrc/bundles/tiles/objects/barrel_oak.png create mode 100644 tests/rsrc/bundles/tiles/objects/bundle.xml create mode 100644 tests/rsrc/bundles/tiles/objects/chest_purse.png create mode 100644 tests/rsrc/bundles/tiles/objects/chest_treasure.png create mode 100644 tests/rsrc/bundles/tiles/objects/crate.png create mode 100644 tests/rsrc/bundles/tiles/objects/dockedge.png create mode 100644 tests/rsrc/bundles/tiles/objects/house.png create mode 100644 tests/rsrc/bundles/tiles/objects/mooring.png create mode 100644 tests/rsrc/bundles/tiles/objects/tree_oak.png create mode 100644 tests/rsrc/bundles/tiles/objects/tree_palm.png create mode 100644 tests/rsrc/bundles/tiles/objects/well.png create mode 100644 tests/rsrc/config/media/iconmgr.properties create mode 100644 tests/rsrc/config/miso/components.xml create mode 100644 tests/rsrc/config/miso/scrolling.properties create mode 100644 tests/rsrc/config/miso/tile/.cvsignore create mode 100644 tests/rsrc/config/miso/tile/fringeconf.xml create mode 100644 tests/rsrc/config/miso/tilesets-components.xml create mode 100644 tests/rsrc/config/miso/tilesets.xml create mode 100644 tests/rsrc/config/miso/viewer.properties create mode 100644 tests/rsrc/config/resource/editor.properties create mode 100644 tests/rsrc/config/resource/manager.properties create mode 100644 tests/rsrc/media/miso/tiles/building.png create mode 100644 tests/rsrc/media/miso/tiles/components/standing_hat_tri.png create mode 100644 tests/rsrc/media/miso/tiles/components/standing_torso.png create mode 100644 tests/rsrc/media/miso/tiles/components/standing_torso_red.png create mode 100644 tests/rsrc/media/miso/tiles/components/walking_hat_tri.png create mode 100644 tests/rsrc/media/miso/tiles/components/walking_torso.png create mode 100644 tests/rsrc/media/miso/tiles/components/walking_torso_red.png create mode 100644 tests/rsrc/media/miso/tiles/faux-building.png create mode 100644 tests/rsrc/media/miso/tiles/landscape.png create mode 100644 tests/rsrc/media/miso/tiles/node-icons.png create mode 100644 tests/rsrc/media/miso/tiles/sample.png create mode 100644 tests/rsrc/media/test.wav create mode 100644 tests/rsrc/media/tile/bundle/tools/.cvsignore create mode 100644 tests/rsrc/media/tile/bundle/tools/building.png create mode 100644 tests/rsrc/media/tile/bundle/tools/bundle.xml create mode 100644 tests/rsrc/media/tile/bundle/tools/bundler-config.xml create mode 100644 tests/rsrc/media/tile/bundle/tools/fringe.png create mode 100644 tests/rsrc/media/tile/bundle/tools/node-icons.png create mode 100644 tests/rsrc/media/tile/tools/xml/tilesets.xml create mode 100644 tests/rsrc/scenes/idyll.xml create mode 100644 tests/rsrc/scenes/wooded.xml create mode 100644 tests/src/java/com/threerings/cast/CharSpriteViz.java create mode 100644 tests/src/java/com/threerings/cast/builder/TestApp.java create mode 100644 tests/src/java/com/threerings/cast/builder/TestFrame.java create mode 100644 tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java create mode 100644 tests/src/java/com/threerings/geom/NearestViz.java create mode 100644 tests/src/java/com/threerings/geom/WhichSideViz.java create mode 100644 tests/src/java/com/threerings/jme/JmeCanvasTest.java create mode 100644 tests/src/java/com/threerings/jme/client/JabberApp.java create mode 100644 tests/src/java/com/threerings/jme/client/JabberClient.java create mode 100644 tests/src/java/com/threerings/jme/client/JabberController.java create mode 100644 tests/src/java/com/threerings/jme/client/JabberView.java create mode 100644 tests/src/java/com/threerings/jme/data/JabberConfig.java create mode 100644 tests/src/java/com/threerings/jme/server/JabberServer.java create mode 100644 tests/src/java/com/threerings/jme/sprite/PathTest.java create mode 100644 tests/src/java/com/threerings/media/ImageLoadingSpeed.java create mode 100644 tests/src/java/com/threerings/media/TestIconManager.java create mode 100644 tests/src/java/com/threerings/media/sound/SoundTestApp.java create mode 100644 tests/src/java/com/threerings/media/sound/sounds.properties create mode 100644 tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java create mode 100644 tests/src/java/com/threerings/media/tile/bundle/tools/BuildTestTileSetBundle.java create mode 100644 tests/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParserTest.java create mode 100644 tests/src/java/com/threerings/media/util/PathViz.java create mode 100644 tests/src/java/com/threerings/media/util/TraceViz.java create mode 100644 tests/src/java/com/threerings/miso/client/ScrollingFrame.java create mode 100644 tests/src/java/com/threerings/miso/client/ScrollingScene.java create mode 100644 tests/src/java/com/threerings/miso/client/ScrollingTestApp.java create mode 100644 tests/src/java/com/threerings/miso/viewer/ViewerApp.java create mode 100644 tests/src/java/com/threerings/miso/viewer/ViewerFrame.java create mode 100644 tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java create mode 100644 tests/src/java/com/threerings/openal/TestSoundManager.java create mode 100644 tests/src/java/com/threerings/util/DirectionTest.java create mode 100644 tests/src/java/com/threerings/util/DirectionViz.java create mode 100644 tests/src/java/com/threerings/util/KeyTimerApp.java create mode 100644 tests/src/java/com/threerings/util/KeyboardManagerApp.java create mode 100644 tests/src/java/com/threerings/util/MessageBundleTest.java create mode 100644 tests/src/java/com/threerings/util/UIDTest.java diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..3b204400 --- /dev/null +++ b/LICENSE @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/README b/README new file mode 100644 index 00000000..cf9565e5 --- /dev/null +++ b/README @@ -0,0 +1,69 @@ +The Nenya library +----------------- + +The Nenya library provides various facilities for making networked multiplayer +games. It's various packages include: + + * geom, util - basic tools for doing data structure manipulation and some + geometry math + * resource - tools for bundling, deploying and managing media (images, + sounds, etc.) with a game + * media - a framework for doing "active" rendering in Java + * media.image - tools for loading, caching, manipulating and displaying images + * media.sound - tools for loading, caching, and playing audio + * media.animation, media.sprite - works in concert with the active + rendering system and provides tools for defining and manipulating + sprites (graphical entities that follow paths) and animations + (graphical entities that affect the display in other ways) + * miso - a framework for defining and displaying isometrically rendered scenes + * cast - a framework for defining and using recolorable, composited + characters with different poses and actions + +Documentation is somewhat sparse at the moment, but inspection of the code in +the tests/ directory shows examples of use of many features of the library. + +Building +-------- + +Building the library is very simple. First ensure that the necessary third +party jar files are available in the lib/ directory. See lib/README for a list +of the necessary third party jar files and how to get them. + +The library is built using Ant, a modern build tool written in and for Java. If +you aren't already using Ant for other projects, it can be found here: + + http://ant.apache.org/ + +Invoke ant with any of the following targets: + + all: builds the distribution files and javadoc documentation + compile: builds only the class files (dist/classes) + javadoc: builds only the javadoc documentation (dist/docs) + dist: builds the distribution jar files (dist/*.jar) + +Distribution +------------ + +The Nenya library is released under the LGPL. The most recent version of the +library is available here: + + http://www.threerings.net/code/nenya/ + +Contribution +------------ + +Contributions to Nenya are welcome. Read-only access to the subversion +repository is available at: + +svn://code.threerings.net/narya/trunk + +Patches can be mailed to Michael Bayne . + +Contact Information +------------------- + +Nenya is actively developed by the scurvy dogs at Three Rings Design, Inc. +Contact Michael Bayne with questions, comments and other +wordly endeavors. + +$Id$ diff --git a/build.xml b/build.xml new file mode 100644 index 00000000..71808eec --- /dev/null +++ b/build.xml @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code b/code new file mode 120000 index 00000000..4c91d264 --- /dev/null +++ b/code @@ -0,0 +1 @@ +src/java/com/threerings \ No newline at end of file diff --git a/docs/media/design.txt b/docs/media/design.txt new file mode 100644 index 00000000..91ea2506 --- /dev/null +++ b/docs/media/design.txt @@ -0,0 +1,44 @@ +Media Design Notes -*- mode: outline -*- + +* Tile system +** Classes +Tile +TileSet + +TileManager +TileSetRepository + +TileSetIDBroker + +XMLTileSetParser + +TileSetBundle +BundledTileSetRepository +TileSetBundler + +** Tile management +Managing tilesets by id involves creating tileset bundles from XML tileset +descriptions. + +Tileset bundles contain both the tileset images and the tileset metadata +(in the form of serialized tileset classes?) + +Tileset bundle creation maintains a stable tileset name to tileset id +mapping through the use of a TileSetIDBroker which maintains the name to +id mapping (in a database or however it likes) + +Sample tileset XML description (for uniform tiles): + + + foo/bar/tiles.png + 64 + 48 + 16 + + +* 01/07/2003 +** Image management refactor +x TileSet:ImageProvider needs to provide colorized images +! Probably give tilesets the ImageManager since they have to give the + ImageManager reference to the Tile so that it can lock its colorized + source image diff --git a/docs/media/notes.txt b/docs/media/notes.txt new file mode 100644 index 00000000..6bb95835 --- /dev/null +++ b/docs/media/notes.txt @@ -0,0 +1,14 @@ +Media Notes -*- mode: outline -*- + +* Old notes +- Possibly modify TileSet to load images via image manager (move image + provider up to media so that image manager can use tileset's image + provider to load the image data) so that they can be cached (and more + importantly, flushed from the cache). Presently tilesets are loaded into + memory when tileset bundles are loaded and remain loaded forever. + +* 07/19/2002 +** Virtual media panel +- Make sure doLayout() is getting called soon enough to ensure that we + don't improperly scroll the wrong thing if we're hijacked while in the + middle of scrolling diff --git a/docs/miso/design.txt b/docs/miso/design.txt new file mode 100644 index 00000000..7d07b42e --- /dev/null +++ b/docs/miso/design.txt @@ -0,0 +1,139 @@ +# Miso Notes -*- mode: outline -*- +# +# $Id: design.txt 2236 2003-02-04 03:33:38Z mdb $ + +* Notes +Consider making MISO sufficiently sophisticated to allow the cluster stuff +to be implemented as an extension. This would included allowing the XML +scene stuff to allow extensions, the scene editor to allow extensions and +of course extending the MisoScene class itself. + +* Discussion +Date: 07/10/01 +Venue: General discussion in vast sweeping loft area. +Participants: mdb, shaper. + +Main game play uses an isometric graphical view to display the current +game area. This section of the screen is referred to as the "scene" +hereafter. + +Targetting a screen resolution of 800x600. Toolbar and info areas may +be on the right side of the screen, below, or both, still TBD. Scene +display area will be either 600x600 or 640x480 correspondingly. Will +use JDK 1.2 or 1.3 allowing us to make use of Java 2D and the new Java +Sound APIs, among other happy things. + +Scenes are non-scrollable. Exits are expected to be placed largely, +though not exclusively, around the borders of the scene (esp. at +building entrances.) Moving the mouse over an exit causes an arrow to +appear flashing to illustrate that clicking on the exit will move the +player to a new scene. + +Characters will be displayed in the scene using "fine" coordinates (an +additional grid within each tile) to allow them to move smoothly. + +TBD: art details, how many frames of animation, what kinds of things +can be carried, paper-doll-ing of character clothing, possibility of +color-replacement to allow increased re-use of clothing art. + +* Design +** Scene Description +- sid: unique scene identifier +- name: scene name +- version: scene description file format version +- tile array: full NxM set of tiles for L0, sparse for L1+ +- hot spots: the "zones" wherein people congregate in each scene, a set + of scene coords +- exits: set of scene coords and associated sids that the exits lead to + +** Potential Classes +SceneIDBroker: dynamic scene creation and obtaining/tracking scene ids +SceneManager: scene retrieval, caching +TileManager: tile retrieval, caching +Config: tileset/tile info + +** Tile Sets and Tiles +General high-level categories of tiles: + +3 * outside (three prospective themes) + ship } item (potentially present in all) + house + +Tiles will be identified by a combination of a 16-bit tile set id and +a 16-bit tile id within that set. + +Estimating: + +400 tiles per scene +1000 scenes = (approx) 1.6 MB (highly compressible) + +Tileset config info associated with each tile set includes, for each +row of tiles in the tile set, the "row height" (height of the tiles in +that row), and the "tile count" (number of tiles in that row). + +Buildings in the scene, as an example, will then be comprised of a +contiguous grouping of tiles that are the same width as all other +tiles, but of greater height than the ground tiles. The scene editor +tool could automate the placement of buildings by allowing pre-defined +groupings of tiles and facilitating rotating building tile entities, +etc. as needed, but we'll wait on doing fancy things like this +until/unless we decide we need it since it's not yet clear that we +need particularly fancy scene design tools. + +Note that the scene editing tools should be designed such that they +can be used in part within the game itself, since players will be +allowed some degree of freedom w.r.t. designing and placing their own +homes (and perhaps landscaping?). + +Tilesets are intended to be used as an entity that contains tiles +corresponding to whatever logical groupings seem reasonable. E.g., +perhaps one tileset will contain all "ground" tiles; "spanish house" +tiles; etc. Split tilesets as necessary (multiple ground tilesets +if/when we have enough to warrant it.) Perhaps number the tileset +identifiers into meaningful groupings, i.e., all ground tilesets have +a tileset identifier in the range of 0 - 999, all building in 2000 - +3000, etc. + +Character animation frames may be performed by passing fully qualified +tile id and number of frames to animate, frames must be contiguous +tiles thereafter. character images will likely be handled as a +special case above and beyond our general tile antics. + +Look into using PNG file format for images. PNG supported in JDK 1.3+ +and probably JAI 1.1 for earlier JDK versions. use PNG alpha-channel +rather than separate masks for handling image transparency. + +Look into perhaps using bitmap masks to reduce the drawable area +needed for drawing tiles (e.g. exclude corners of iso squares), but +only if noteworthy perf gain achieved. Perhaps other similar +worthwhile uses. + +** TBD +*** Resource mgmt +When is scene data and art loaded, how big are the chunks of data +downloaded, what's the user experience during download like. + +*** On-screen "map" display of the surrounding scenes +The scenes comprising a town, etc. potentially impacts how we allow +placement of exits in a scene since allowing folks to place exits to their +houses/bldgs willy-nilly may make map generation wacky. perhaps useful +for game designer use as well when laying things out and "surveying the +landscape." + +* 1/14/2003 +** Ground zero +- Render all ground and fringe tiles (unprepared) into a single offscreen + buffer and use that to repaint the ground instead of going from the + original tile images + +* 1/28/2003 +** Scene revamp +- Objects without actions are largely inconsequential (in the model, they + exist only as fqtid and coordinates) +- Objects with actions have extra data: + + the action string + + a location and orientation associated with the object (for building + facades this would be the entrance portal location, for "stations" + this would be where the user stands when occupying that station) +- Scene model is not used by anyone but the scene impl (so that more + sophisticated models and impls can come to exist) diff --git a/docs/miso/fringebits.png b/docs/miso/fringebits.png new file mode 100644 index 0000000000000000000000000000000000000000..7601e231eb8dfe5c9d5b47af5505f91422abfbd3 GIT binary patch literal 43448 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 DDJf<2 literal 0 HcmV?d00001 diff --git a/docs/miso/render_sort_diagram.png b/docs/miso/render_sort_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ee784daee467bc117b2d8cefb62d3e4a514bec GIT binary patch literal 44536 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 literal 0 HcmV?d00001 diff --git a/docs/miso/scene.ps b/docs/miso/scene.ps new file mode 100644 index 00000000..24cd531e --- /dev/null +++ b/docs/miso/scene.ps @@ -0,0 +1,51 @@ +% sort out scaling and translating +36 36 translate +/sf 540 640 div def +sf sf scale + +% width/height ratio +/whr 10 7.5 div def + +% center things vertically +0 whr 640 mul 576 sub 2 div translate + +% translate off to the left one tile and clip +64 neg 0 translate +64 0 640 576 rectclip + +% draw the up moving diagnals +/sx 0 def +/sy 288 def +/ex 384 def +/ey 576 def + +1 1 13 { + sx sy moveto + ex ey lineto + stroke + /sx sx 32 add def + /ex ex 32 add def + /sy sy 24 sub def + /ey ey 24 sub def +} for + +% draw the down moving diagnals +/sx 0 def +/sy 288 def +/ex 384 def +/ey 0 def + +1 1 13 { + sx sy moveto + ex ey lineto + stroke + /sx sx 32 add def + /ex ex 32 add def + /sy sy 24 add def + /ey ey 24 add def +} for + +% box the whole thing in +64 0 640 576 rectstroke + +showpage diff --git a/docs/miso/scenegroup.xml b/docs/miso/scenegroup.xml new file mode 100644 index 00000000..47086b22 --- /dev/null +++ b/docs/miso/scenegroup.xml @@ -0,0 +1,21 @@ + + + + + + + + + + Town Square + South + + + + + Harbour + West + + + + diff --git a/docs/stylesheet.css b/docs/stylesheet.css new file mode 100644 index 00000000..3f0592b8 --- /dev/null +++ b/docs/stylesheet.css @@ -0,0 +1,52 @@ +/* Javadoc style sheet */ + +/* Page background color */ +body { + background-color: #FFFFFF; + font-family: Arial, Helvetica, sans-serif; +} + +pre { + font-family: Courier New, monospace +} + +code { + font-family: Courier New, monospace +} + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ +.TableRowColor { background: #FFFFFF } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} + +.NavBarCell2 { + font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; +} +.NavBarCell3 { + font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; +} + +.example { + padding-top: 5px; + padding-bottom: 5px; + padding-left: 10px; + padding-right: 10px; + margin-left: 20px; + margin-right: 20px; + border: 1px solid black; + background-color: #FFFF99 +} diff --git a/lib/LIBS b/lib/LIBS new file mode 100644 index 00000000..01710013 --- /dev/null +++ b/lib/LIBS @@ -0,0 +1,17 @@ +commons-collections.jar +commons-digester.jar +commons-io.jar +jme-awt.jar +jme-bui.jar +jme-effects.jar +jme.jar +jme-model.jar +jme-sound.jar +jme-terrain.jar +lwjgl.jar +lwjgl_util.jar +narya-base.jar +narya-distrib.jar +retroweaver-all-1.2.2.jar +samskivert.jar +xml-writer.jar diff --git a/lib/README b/lib/README new file mode 100644 index 00000000..ebb92aa2 --- /dev/null +++ b/lib/README @@ -0,0 +1,26 @@ +Required external libraries +--------------------------- + +The following external Java libraries (JAR files) must be placed (or symlinked) +here in the lib/ directory, unless specifically noted as optional. + +* The samskivert library: + http://samskivert.com/code/samskivert/ + +* Apache Commons libraries: collections, digester and io + http://jakarta.apache.org/commons/ + +* Megginson Technologies' XMLWriter 0.2 library: + http://www.megginson.com/Software/xml-writer-0.2.zip + +* Retroweaver libraries for creating 1.4 compatible versions: + http://retroweaver.sourceforge.net/ + +* (Optional) jMonkeyEngine 3D scene graph toolkit built on LWJGL: + http://www.jmonkeyengine.com/ + +Once the jar files are in place (regardless of what they are named), the build +system will automatically include them in the compile-time classpath. + +-- +$Id$ diff --git a/lib/SOURCE_HEADER b/lib/SOURCE_HEADER new file mode 100644 index 00000000..1b4ae8af --- /dev/null +++ b/lib/SOURCE_HEADER @@ -0,0 +1,21 @@ +// +// $Id$ +// +// Nenya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/nenya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + diff --git a/src/java/com/threerings/cast/ActionCache.java b/src/java/com/threerings/cast/ActionCache.java new file mode 100644 index 00000000..fbf7a35f --- /dev/null +++ b/src/java/com/threerings/cast/ActionCache.java @@ -0,0 +1,42 @@ +// +// $Id: ActionCache.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +/** + * A mechanism for caching composited character action animations on disk. + */ +public interface ActionCache +{ + /** + * Fetches from the cache a composited set of images for a particular + * character for a particular action. + */ + public ActionFrames getActionFrames ( + CharacterDescriptor descrip, String action); + + /** + * Requests that the specified set of action frames for the specified + * character be cached. + */ + public void cacheActionFrames ( + CharacterDescriptor descrip, String action, ActionFrames frames); +} diff --git a/src/java/com/threerings/cast/ActionFrames.java b/src/java/com/threerings/cast/ActionFrames.java new file mode 100644 index 00000000..8fe2bb82 --- /dev/null +++ b/src/java/com/threerings/cast/ActionFrames.java @@ -0,0 +1,67 @@ +// +// $Id: ActionFrames.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import com.threerings.media.image.Colorization; +import com.threerings.util.DirectionCodes; + +/** + * Encapsulates a set of frames in each of {@link + * DirectionCodes#DIRECTION_COUNT} orientations that are used to render a + * character sprite. + */ +public interface ActionFrames +{ + /** + * Returns the number of orientations available in this set of action + * frames. + */ + public int getOrientationCount (); + + /** + * Returns the multi-frame image that comprises the frames for the + * specified orientation. + */ + public TrimmedMultiFrameImage getFrames (int orient); + + /** + * Returns the x offset from the upper left of the image to the + * "origin" for this character frame. A sprite with location (x, y) + * will be rendered such that its origin is coincident with that + * location. + */ + public int getXOrigin (int orient, int frameIdx); + + /** + * Returns the y offset from the upper left of the image to the + * "origin" for this character frame. A sprite with location (x, y) + * will be rendered such that its origin is coincident with that + * location. + */ + public int getYOrigin (int orient, int frameIdx); + + /** + * Creates a clone of these action frames which will have the supplied + * colorizations applied to the frame images. + */ + public ActionFrames cloneColorized (Colorization[] zations); +} diff --git a/src/java/com/threerings/cast/ActionSequence.java b/src/java/com/threerings/cast/ActionSequence.java new file mode 100644 index 00000000..a05b6fa1 --- /dev/null +++ b/src/java/com/threerings/cast/ActionSequence.java @@ -0,0 +1,72 @@ +// +// $Id: ActionSequence.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.Point; +import java.io.Serializable; + +/** + * The action sequence class describes a particular character animation + * sequence. An animation sequence consists of one or more frames of + * animation, renders at a particular frame rate, and has an origin point + * that specifies the location of the base of the character in relation to + * the bounds of the animation images. + */ +public class ActionSequence implements Serializable +{ + /** + * Defines the name of the default action sequence. When component + * tilesets are loaded to build a set of composited images for a + * particular action sequence, a check is first made for a component + * tileset specific to the action sequence and then for the + * component's default tileset if the action specific tileset did not + * exist. + */ + public static final String DEFAULT_SEQUENCE = "default"; + + /** The action sequence name. */ + public String name; + + /** The number of frames per second to show when animating. */ + public float framesPerSecond; + + /** The position of the character's base for this sequence. */ + public Point origin = new Point(); + + /** Orientation codes for the orientations available for this + * action. */ + public int[] orients; + + /** + * Returns a string representation of this action sequence. + */ + public String toString () + { + return "[name=" + name + ", framesPerSecond=" + framesPerSecond + + ", origin=" + origin + + ", orients=" + (orients == null ? 0 : orients.length) + "]"; + } + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/cast/CastPrefs.java b/src/java/com/threerings/cast/CastPrefs.java new file mode 100644 index 00000000..c45a3053 --- /dev/null +++ b/src/java/com/threerings/cast/CastPrefs.java @@ -0,0 +1,35 @@ +// +// $Id: CastPrefs.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import com.samskivert.util.Config; + +/** + * Provides access to runtime configuration parameters for this package + * and its subpackages. + */ +public class CastPrefs +{ + /** Used to load our preferences from a properties file and map them + * to the persistent Java preferences repository. */ + public static Config config = new Config("rsrc/config/cast"); +} diff --git a/src/java/com/threerings/cast/CharacterComponent.java b/src/java/com/threerings/cast/CharacterComponent.java new file mode 100644 index 00000000..fc519d2d --- /dev/null +++ b/src/java/com/threerings/cast/CharacterComponent.java @@ -0,0 +1,100 @@ +// +// $Id: CharacterComponent.java 3740 2005-10-20 22:12:45Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.io.Serializable; + +import com.samskivert.util.StringUtil; + +import com.threerings.media.sprite.Sprite; + +/** + * The character component represents a single component that can be + * composited with other character components to generate an image + * representing a complete character displayable in any of the eight + * compass directions as detailed in the {@link Sprite} class direction + * constants. + */ +public class CharacterComponent implements Serializable +{ + /** The unique component identifier. */ + public int componentId; + + /** The component's name. */ + public String name; + + /** The class of components to which this one belongs. */ + public ComponentClass componentClass; + + /** + * Constructs a character component with the specified id of the + * specified class. + */ + public CharacterComponent (int componentId, String name, + ComponentClass compClass, FrameProvider fprov) + { + this.componentId = componentId; + this.name = name; + this.componentClass = compClass; + _frameProvider = fprov; + } + + /** + * Returns the image frames for the specified action animation or null if + * no animation for the specified action is available for this component. + * + * @param type null for the normal action frames or one of the custom + * action sub-types: {@link StandardActions#SHADOW_TYPE}, etc. + */ + public ActionFrames getFrames (String action, String type) + { + return _frameProvider.getFrames(this, action, type); + } + + /** + * Returns true if this component is equal to the other component. The + * comparison is made on componentId. + */ + public boolean equals (Object other) + { + if (other instanceof CharacterComponent) { + return componentId == ((CharacterComponent)other).componentId; + } else { + return false; + } + } + + /** + * Returns a string representation of this character component. + */ + public String toString () + { + return StringUtil.fieldsToString(this); + } + + /** The entity from which we obtain our animation frames. */ + protected FrameProvider _frameProvider; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/cast/CharacterDescriptor.java b/src/java/com/threerings/cast/CharacterDescriptor.java new file mode 100644 index 00000000..b27b2e5e --- /dev/null +++ b/src/java/com/threerings/cast/CharacterDescriptor.java @@ -0,0 +1,144 @@ +// +// $Id: CharacterDescriptor.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.util.Arrays; +import com.samskivert.util.StringUtil; +import com.threerings.media.image.Colorization; + +/** + * The character descriptor object details the components that are + * pieced together to create a single character image. + */ +public class CharacterDescriptor +{ + /** + * Constructs a character descriptor. + * + * @param components the component ids of the individual components + * that make up this character. + * @param zations the colorizations to apply to each of the character + * component images when compositing actions (an array of + * colorizations for each component, elements of which can be null to + * make it easier to support per-component specialized colorizations). + * This can be null if image recolorization is not desired. + */ + public CharacterDescriptor (int[] components, Colorization[][] zations) + { + _components = components; + _zations = zations; + } + + /** + * Returns an array of the component identifiers comprising the + * character described by this descriptor. + */ + public int[] getComponentIds () + { + return _components; + } + + /** + * Returns an array of colorization arrays to be applied to the + * components when compositing action images (one array per + * component). + */ + public Colorization[][] getColorizations () + { + return _zations; + } + + /** + * Updates the colorizations to be used by this character descriptor. + */ + public void setColorizations (Colorization[][] zations) + { + _zations = zations; + } + + /** + * Compute a sensible hashcode for this object. + */ + public int hashCode () + { + int code = 0, clength = _components.length; + for (int i = 0; i < clength; i++) { + code ^= _components[i]; + } + return code; + } + + /** + * Compares this character descriptor to another. + */ + public boolean equals (Object other) + { + if (!(other instanceof CharacterDescriptor)) { + return false; + } + + // both the component ids and the colorizations must be equal + CharacterDescriptor odesc = (CharacterDescriptor)other; + if (!Arrays.equals(_components, odesc._components)) { + return false; + } + + Colorization[][] zations = odesc._zations; + if (zations == null && _zations == null) { + // if neither has colorizations, we're clear + return true; + + } else if (zations == null || _zations == null) { + // if one has colorizations whilst the other doesn't, they + // can't be equal + return false; + } + + // otherwise, all of the colorizations must be equal as well + int zlength = zations.length; + if (zlength != _zations.length) { + return false; + } + for (int ii = 0; ii < zlength; ii++) { + if (!Arrays.equals(_zations[ii], zations[ii])) { + return false; + } + } + + return true; + } + + /** + * Returns a string representation of this character descriptor. + */ + public String toString () + { + return "[cids=" + StringUtil.toString(_components) + + ", colors=" + StringUtil.toString(_zations) + "]"; + } + + /** The component identifiers comprising the character. */ + protected int[] _components; + + /** The colorizations to apply when compositing this character. */ + protected Colorization[][] _zations; +} diff --git a/src/java/com/threerings/cast/CharacterManager.java b/src/java/com/threerings/cast/CharacterManager.java new file mode 100644 index 00000000..55767c0e --- /dev/null +++ b/src/java/com/threerings/cast/CharacterManager.java @@ -0,0 +1,430 @@ +// +// $Id: CharacterManager.java 4022 2006-04-14 21:49:11Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.StringUtil; +import com.samskivert.util.Throttle; +import com.samskivert.util.Tuple; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.ImageManager; +import com.threerings.util.DirectionCodes; + +import com.threerings.cast.CompositedActionFrames.ComponentFrames; +import com.threerings.cast.Log; + +/** + * The character manager provides facilities for constructing sprites that + * are used to represent characters in a scene. It also handles the + * compositing and caching of composited character animations. + */ +public class CharacterManager + implements DirectionCodes +{ + /** + * Constructs the character manager. + */ + public CharacterManager (ImageManager imgr, ComponentRepository crepo) + { + // keep these around + _imgr = imgr; + _crepo = crepo; + + // populate our actions table + Iterator iter = crepo.enumerateActionSequences(); + while (iter.hasNext()) { + ActionSequence action = (ActionSequence)iter.next(); + _actions.put(action.name, action); + } + + // create a cache for our composited action frames + int acsize = _cacheSize.getValue(); + Log.debug("Creating action cache [size=" + acsize + "k]."); + _frameCache = new LRUHashMap(acsize*1024, new LRUHashMap.ItemSizer() { + public int computeSize (Object value) { + return (int)((CompositedMultiFrameImage) + value).getEstimatedMemoryUsage(); + } + }); + _frameCache.setTracking(true); // TODO + } + + /** + * Returns the component repository being used by this manager. + */ + public ComponentRepository getComponentRepository () + { + return _crepo; + } + + /** + * Instructs the character manager to construct instances of this + * derived class of {@link CharacterSprite} when creating new sprites. + * + * @exception IllegalArgumentException thrown if the supplied class + * does not derive from {@link CharacterSprite}. + */ + public void setCharacterClass (Class charClass) + { + // sanity check + if (!CharacterSprite.class.isAssignableFrom(charClass)) { + String errmsg = "Requested to use character sprite class that " + + "does not derive from CharacterSprite " + + "[class=" + charClass.getName() + "]."; + throw new IllegalArgumentException(errmsg); + } + + // make a note of it + _charClass = charClass; + } + + /** + * Instructs the character manager to use the provided cache for + * composited action animations. + */ + public void setActionCache (ActionCache cache) + { + _acache = cache; + } + + /** + * Returns a {@link CharacterSprite} representing the character + * described by the given {@link CharacterDescriptor}, or + * null if an error occurs. + * + * @param desc the character descriptor. + */ + public CharacterSprite getCharacter (CharacterDescriptor desc) + { + return getCharacter(desc, _charClass); + } + + /** + * Returns a {@link CharacterSprite} representing the character + * described by the given {@link CharacterDescriptor}, or + * null if an error occurs. + * + * @param desc the character descriptor. + * @param charClass the {@link CharacterSprite} derived class that + * should be instantiated instead of the configured default (which is + * set via {@link #setCharacterClass}). + */ + public CharacterSprite getCharacter (CharacterDescriptor desc, + Class charClass) + { + try { + CharacterSprite sprite = (CharacterSprite) + charClass.newInstance(); + sprite.init(desc, this); + return sprite; + + } catch (Exception e) { + Log.warning("Failed to instantiate character sprite " + + "[e=" + e + "]."); + Log.logStackTrace(e); + return null; + } + } + + /** + * Obtains the composited animation frames for the specified action for a + * character with the specified descriptor. The resulting composited + * animation will be cached. + * + * @exception NoSuchComponentException thrown if any of the components in + * the supplied descriptor do not exist. + * @exception IllegalArgumentException thrown if any of the components + * referenced in the descriptor do not support the specified action. + */ + public ActionFrames getActionFrames ( + CharacterDescriptor descrip, String action) + throws NoSuchComponentException + { + Tuple key = new Tuple(descrip, action); + ActionFrames frames = (ActionFrames)_actionFrames.get(key); + if (frames == null) { + // this doesn't actually composite the images, but prepares an + // object to be able to do so + frames = createCompositeFrames(descrip, action); + _actionFrames.put(key, frames); + } + + // periodically report our frame image cache performance + if (!_cacheStatThrottle.throttleOp()) { + long size = getEstimatedCacheMemoryUsage(); + int[] eff = _frameCache.getTrackedEffectiveness(); + Log.debug("CharacterManager LRU [mem=" + (size / 1024) + "k" + + ", size=" + _frameCache.size() + ", hits=" + eff[0] + + ", misses=" + eff[1] + "]."); + } + + return frames; + } + + /** + * Informs the character manager that the action sequence for the + * given character descriptor is likely to be needed in the near + * future and so any efforts that can be made to load it into the + * action sequence cache in advance should be undertaken. + * + *

This will eventually be revamped to spiffily load action + * sequences in the background. + */ + public void resolveActionSequence (CharacterDescriptor desc, String action) + { + try { + if (getActionFrames(desc, action) == null) { + Log.warning("Failed to resolve action sequence " + + "[desc=" + desc + ", action=" + action + "]."); + } + + } catch (NoSuchComponentException nsce) { + Log.warning("Failed to resolve action sequence " + + "[nsce=" + nsce + "]."); + } + } + + /** + * Returns the action sequence instance with the specified name or + * null if no such sequence exists. + */ + public ActionSequence getActionSequence (String action) + { + return (ActionSequence)_actions.get(action); + } + + /** + * Returns the estimated memory usage in bytes for all images + * currently cached by the cached action frames. + */ + protected long getEstimatedCacheMemoryUsage () + { + long size = 0; + Iterator iter = _frameCache.values().iterator(); + while (iter.hasNext()) { + size += ((CompositedMultiFrameImage) + iter.next()).getEstimatedMemoryUsage(); + } + return size; + } + + /** + * Generates the composited animation frames for the specified action + * for a character with the specified descriptor. + * + * @exception NoSuchComponentException thrown if any of the components + * in the supplied descriptor do not exist. + * @exception IllegalArgumentException thrown if any of the components + * referenced in the descriptor do not support the specified action. + */ + protected ActionFrames createCompositeFrames ( + CharacterDescriptor descrip, String action) + throws NoSuchComponentException + { + int[] cids = descrip.getComponentIds(); + int ccount = cids.length; + Colorization[][] zations = descrip.getColorizations(); + + Log.debug("Compositing action [action=" + action + + ", descrip=" + descrip + "]."); + + // this will be used to construct any shadow layers + HashMap shadows = null; + + // maps components by class name for masks + HashMap ccomps = new HashMap(); + + // create colorized versions of all of the source action frames + ArrayList sources = new ArrayList(ccount); + for (int ii = 0; ii < ccount; ii++) { + ComponentFrames cframes = new ComponentFrames(); + sources.add(cframes); + CharacterComponent ccomp = + (cframes.ccomp = _crepo.getComponent(cids[ii])); + ccomps.put(ccomp.componentClass.name, ccomp); + + // load up the main component images + ActionFrames source = ccomp.getFrames(action, null); + if (source == null) { + String errmsg = "Cannot composite action frames; no such " + + "action for component [action=" + action + + ", desc=" + descrip + ", comp=" + ccomp + "]"; + throw new RuntimeException(errmsg); + } + cframes.frames = (zations == null || zations[ii] == null) ? + source : source.cloneColorized(zations[ii]); + + // if this component has a shadow, make a note of it + if (ccomp.componentClass.isShadowed()) { + if (shadows == null) { + shadows = new HashMap(); + } + ArrayList shadlist = (ArrayList) + shadows.get(ccomp.componentClass.shadow); + if (shadlist == null) { + shadows.put(ccomp.componentClass.shadow, + shadlist = new ArrayList()); + } + shadlist.add(ccomp); + } + } + + // add any necessary masks + for (int ii = 0; ii < ccount; ii++) { + ComponentFrames cframes = (ComponentFrames)sources.get(ii); + CharacterComponent mcomp = (CharacterComponent)ccomps.get( + cframes.ccomp.componentClass.mask); + if (mcomp != null) { + cframes.frames = compositeMask(action, cframes.ccomp, + cframes.frames, mcomp); + } + } + + // now create any necessary shadow layers + if (shadows != null) { + Iterator iter = shadows.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry)iter.next(); + String sclass = (String)entry.getKey(); + ArrayList scomps = (ArrayList)entry.getValue(); + ComponentFrames scf = compositeShadow(action, sclass, scomps); + if (scf != null) { + sources.add(scf); + } + } + } + + // use those to create an entity that will lazily composite things + // together as they are needed + ComponentFrames[] cfvec = (ComponentFrames[])sources.toArray( + new ComponentFrames[sources.size()]); + return new CompositedActionFrames(_imgr, _frameCache, action, cfvec); + } + + protected ActionFrames compositeMask ( + String action, CharacterComponent ccomp, ActionFrames cframes, + CharacterComponent mcomp) + { + ActionFrames mframes = mcomp.getFrames(action, + StandardActions.CROP_TYPE); + if (mframes == null) { + return cframes; + } + return new CompositedActionFrames( + _imgr, _frameCache, action, new ComponentFrames[] { + new ComponentFrames(ccomp, cframes), + new ComponentFrames(mcomp, mframes) }) { + protected CompositedMultiFrameImage createFrames (int orient) { + return new CompositedMaskedImage( + _imgr, _sources, _action, orient); + } + }; + } + + protected ComponentFrames compositeShadow ( + String action, String sclass, ArrayList scomps) + { + final ComponentClass cclass = _crepo.getComponentClass(sclass); + if (cclass == null) { + Log.warning("Components reference non-existent shadow layer " + + "class [sclass=" + sclass + + ", scomps=" + StringUtil.toString(scomps) + "]."); + return null; + } + + ComponentFrames cframes = new ComponentFrames(); + // create a fake component for the shadow layer + cframes.ccomp = new CharacterComponent(-1, "shadow", cclass, null); + + ArrayList sources = new ArrayList(); + for (int ii = 0, ll = scomps.size(); ii < ll; ii++) { + ComponentFrames source = new ComponentFrames(); + source.ccomp = (CharacterComponent)scomps.get(ii); + source.frames = source.ccomp.getFrames( + action, StandardActions.SHADOW_TYPE); + if (source.frames == null) { + // skip this shadow component + continue; + } + sources.add(source); + } + + // if we ended up with no shadow, no problem! + if (sources.size() == 0) { + return null; + } + + // create custom action frames that use a special compositing + // multi-frame image that does the necessary shadow magic + ComponentFrames[] svec = (ComponentFrames[]) + sources.toArray(new ComponentFrames[sources.size()]); + cframes.frames = new CompositedActionFrames( + _imgr, _frameCache, action, svec) { + protected CompositedMultiFrameImage createFrames (int orient) { + return new CompositedShadowImage( + _imgr, _sources, _action, orient, cclass.shadowAlpha); + } + }; + + return cframes; + } + + /** The image manager with whom we interact. */ + protected ImageManager _imgr; + + /** The component repository. */ + protected ComponentRepository _crepo; + + /** A table of our action sequences. */ + protected HashMap _actions = new HashMap(); + + /** A table of composited action sequences (these don't reference the + * actual image data directly and thus take up little memory). */ + protected HashMap _actionFrames = new HashMap(); + + /** A cache of composited animation frames. */ + protected LRUHashMap _frameCache; + + /** The character class to be created. */ + protected Class _charClass = CharacterSprite.class; + + /** The action animation cache, if we have one. */ + protected ActionCache _acache; + + /** Throttle our cache status logging to once every 30 seconds. */ + protected Throttle _cacheStatThrottle = new Throttle(1, 30000L); + + /** Register our image cache size with the runtime adjustments + * framework. */ + protected static RuntimeAdjust.IntAdjust _cacheSize = + new RuntimeAdjust.IntAdjust( + "Size (in kb of memory used) of the character manager LRU " + + "action cache [requires restart]", "narya.cast.action_cache_size", + CastPrefs.config, 1024); +} diff --git a/src/java/com/threerings/cast/CharacterSprite.java b/src/java/com/threerings/cast/CharacterSprite.java new file mode 100644 index 00000000..801452e3 --- /dev/null +++ b/src/java/com/threerings/cast/CharacterSprite.java @@ -0,0 +1,402 @@ +// +// $Id: CharacterSprite.java 3785 2005-12-15 22:14:37Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import javax.swing.SwingUtilities; + +import com.threerings.media.sprite.ImageSprite; + +/** + * A character sprite is a sprite that animates itself while walking + * about in a scene. + */ +public class CharacterSprite extends ImageSprite + implements StandardActions +{ + /** + * Initializes this character sprite with the specified character + * descriptor and character manager. It will obtain animation data + * from the supplied character manager. + */ + public void init (CharacterDescriptor descrip, CharacterManager charmgr) + { + // keep track of this stuff + _descrip = descrip; + _charmgr = charmgr; + + // sanity check our values + sanityCheckDescrip(); + + // assign an arbitrary starting orientation + _orient = SOUTHWEST; + + // pass the buck to derived classes + didInit(); + } + + /** + * Called after this sprite has been initialized with its character + * descriptor and character manager. Derived classes can do post-init + * business here. + */ + protected void didInit () + { + } + + /** + * Reconfigures this sprite to use the specified character descriptor. + */ + public void setCharacterDescriptor (CharacterDescriptor descrip) + { + // keep the new descriptor + _descrip = descrip; + + // sanity check our values + sanityCheckDescrip(); + + // update our action frames + updateActionFrames(); + } + + /** + * Specifies the action to use when the sprite is at rest. The default + * is STANDING. + */ + public void setRestingAction (String action) + { + _restingAction = action; + } + + /** + * Returns the action to be used when the sprite is at rest. Derived + * classes may wish to override this method and vary the action based + * on external parameters (or randomly). + */ + public String getRestingAction () + { + return _restingAction; + } + + /** + * Specifies the action to use when the sprite is following a path. + * The default is WALKING. + */ + public void setFollowingPathAction (String action) + { + _followingPathAction = action; + } + + /** + * Returns the action to be used when the sprite is following a path. + * Derived classes may wish to override this method and vary the + * action based on external parameters (or randomly). + */ + public String getFollowingPathAction () + { + return _followingPathAction; + } + + /** + * Sets the action sequence used when rendering the character, from + * the set of available sequences. + */ + public void setActionSequence (String action) + { + // sanity check + if (action == null) { + Log.warning("Refusing to set null action sequence " + this + "."); + Thread.dumpStack(); + return; + } + + // no need to noop + if (action.equals(_action)) { + return; + } + _action = action; + updateActionFrames(); + } + + // documentation inherited + public void setOrientation (int orient) + { + if (orient < 0 || orient >= FINE_DIRECTION_COUNT) { + Log.info("Refusing to set invalid orientation [sprite=" + this + + ", orient=" + orient + "]."); + Thread.dumpStack(); + return; + } + + int oorient = _orient; + super.setOrientation(orient); + if (_orient != oorient) { + _frames = null; + } + } + + // documentation inherited + public boolean hitTest (int x, int y) + { + // the irect adjustments are to account for our decorations + return (_frames != null && _ibounds.contains(x, y) && + _frames.hitTest(_frameIdx, x - _ibounds.x, y - _ibounds.y)); + } + + // documentation inherited + public void tick (long tickStamp) + { + // composite our action frames if something since the last call to + // tick caused them to become invalid + compositeActionFrames(); + super.tick(tickStamp); + // composite our action frames if something during tick() caused + // them to become invalid + compositeActionFrames(); + } + + // documentation inherited + public void cancelMove () + { + super.cancelMove(); + halt(); + } + + // documentation inherited + public void pathBeginning () + { + super.pathBeginning(); + + // enable walking animation + setAnimationMode(TIME_BASED); + setActionSequence(getFollowingPathAction()); + } + + // documentation inherited + public void pathCompleted (long timestamp) + { + super.pathCompleted(timestamp); + halt(); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + if (_frames != null) { + decorateBehind(gfx); + // paint the image using _ibounds rather than _bounds which + // has been modified to include the bounds of our decorations + _frames.paintFrame(gfx, _frameIdx, _ibounds.x, _ibounds.y); + decorateInFront(gfx); + + } else { + super.paint(gfx); + } + } + + /** + * Called to paint any decorations that should appear behind the + * character sprite image. + */ + protected void decorateBehind (Graphics2D gfx) + { + } + + /** + * Called to paint any decorations that should appear in front of the + * character sprite image. + */ + protected void decorateInFront (Graphics2D gfx) + { + } + + /** + * Rebuilds our action frames given our current character descriptor + * and action sequence. This is called when either of those two things + * changes. + */ + protected void updateActionFrames () + { + // get a reference to the action sequence so that we can obtain + // our animation frames and configure our frames per second + ActionSequence actseq = _charmgr.getActionSequence(_action); + if (actseq == null) { + String errmsg = "No such action '" + _action + "'."; + throw new IllegalArgumentException(errmsg); + } + + try { + // obtain our animation frames for this action sequence + _aframes = _charmgr.getActionFrames(_descrip, _action); + + // clear out our frames so that we recomposite on next tick + _frames = null; + + // update the sprite render attributes + setFrameRate(actseq.framesPerSecond); + + } catch (NoSuchComponentException nsce) { + Log.warning("Character sprite references non-existent " + + "component [sprite=" + this + ", err=" + nsce + "]."); + + } catch (Exception e) { + Log.warning("Failed to obtain action frames [sprite=" + this + + ", descrip=" + _descrip + ", action=" + _action + "]."); + Log.logStackTrace(e); + } + } + + /** Called to recomposite our action frames if needed. */ + protected final void compositeActionFrames () + { + if (_frames == null && _aframes != null) { + setFrames(_aframes.getFrames(_orient)); + } + } + + /** + * Makes it easier to track down problems with bogus character descriptors. + */ + protected void sanityCheckDescrip () + { + if (_descrip.getComponentIds() == null || + _descrip.getComponentIds().length == 0) { + Log.warning("Invalid character descriptor [sprite=" + this + + ", descrip=" + _descrip + "]."); + Thread.dumpStack(); + } + } + + // documentation inherited + protected boolean tickPath (long tickStamp) + { + boolean moved = super.tickPath(tickStamp); + // composite our action frames if our path caused them to become + // invalid + compositeActionFrames(); + return moved; + } + + // documentation inherited + protected void updateRenderOrigin () + { + super.updateRenderOrigin(); + + // adjust our image bounds to reflect the new location + _ibounds.x = _bounds.x + _ioff.x; + _ibounds.y = _bounds.y + _ioff.y; + } + + // documentation inherited + protected void accomodateFrame (int frameIdx, int width, int height) + { + // this will update our width and height + super.accomodateFrame(frameIdx, width, height); + + // we now need to update the render offset for this frame + if (_aframes == null) { + Log.warning("Have no action frames! " + _aframes + "."); + } else { + _oxoff = _aframes.getXOrigin(_orient, frameIdx); + _oyoff = _aframes.getYOrigin(_orient, frameIdx); + } + + // and cause those changes to be reflected in our bounds + updateRenderOrigin(); + + // start out with our bounds the same as our image bounds + _ibounds.setBounds(_bounds); + + // now we can call down and incorporate the dimensions of any + // decorations that will be rendered along with our image + unionDecorationBounds(_bounds); + + // compute our new render origin + _oxoff = _ox - _bounds.x; + _oyoff = _oy - _bounds.y; + + // track the offset from our expanded bounds to our image bounds + _ioff.x = _ibounds.x - _bounds.x; + _ioff.y = _ibounds.y - _bounds.y; + } + + /** + * Called by {@link #accomodateFrame} to give derived classes an + * opportunity to incorporate the bounds of any decorations that will + * be drawn along with this sprite. The {@link #_ibounds} rectangle + * will contain the bounds of the image that comprises the undecorated + * sprite. From that the position and size of decorations can be + * computed and unioned with the supplied bounds rectangle (most + * likely by using {@link SwingUtilities#computeUnion} which applies + * the union in place rather than creating a new rectangle). + */ + protected void unionDecorationBounds (Rectangle bounds) + { + } + + /** + * Updates the sprite animation frame to reflect the cessation of + * movement and disables any further animation. + */ + protected void halt () + { + // only do something if we're actually animating + if (_animMode != NO_ANIMATION) { + // disable animation + setAnimationMode(NO_ANIMATION); + // come to a halt looking settled and at peace + String rest = getRestingAction(); + if (rest != null) { + setActionSequence(rest); + } + } + } + + /** The action to use when at rest. */ + protected String _restingAction = STANDING; + + /** The action to use when following a path. */ + protected String _followingPathAction = WALKING; + + /** A reference to the descriptor for the character that we're + * visualizing. */ + protected CharacterDescriptor _descrip; + + /** A reference to the character manager that created us. */ + protected CharacterManager _charmgr; + + /** The action we are currently displaying. */ + protected String _action; + + /** The animation frames for the active action sequence in each + * orientation. */ + protected ActionFrames _aframes; + + /** The offset from the upper-left of the total sprite bounds to the + * upper-left of the image within those bounds. */ + protected Point _ioff = new Point(); + + /** The bounds of the current sprite image. */ + protected Rectangle _ibounds = new Rectangle(); +} diff --git a/src/java/com/threerings/cast/ComponentClass.java b/src/java/com/threerings/cast/ComponentClass.java new file mode 100644 index 00000000..200e1241 --- /dev/null +++ b/src/java/com/threerings/cast/ComponentClass.java @@ -0,0 +1,241 @@ +// +// $Id: ComponentClass.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.Color; +import java.io.Serializable; + +import com.samskivert.util.ArrayIntSet; +import com.samskivert.util.ComparableArrayList; +import com.samskivert.util.StringUtil; + +/** + * Denotes a class of components to which {@link CharacterComponent} + * objects belong. Examples include "Hat", "Head", and "Feet". A component + * class dictates a component's rendering priority so that components can + * be rendered in an order that causes them to overlap properly. + * + *

Components support render priority overrides for particular + * actions, orientations or combinations of actions and orientations. The + * system is currently structured with the expectation that the overrides + * will be relatively few (less than fifteen, say) for any given component + * class. A system that relied on many overrides for its components would + * want to implement a more scalable algorithm for determining which, if + * any, override matches a particular action and orientation combination. + */ +public class ComponentClass implements Serializable +{ + /** Used to effect custom render orders for particular actions, + * orientations, etc. */ + public static class PriorityOverride + implements Comparable, Serializable + { + /** The overridden render priority value. */ + public int renderPriority; + + /** The action, if any, for which this override is appropriate. */ + public String action; + + /** The orientations, if any, for which this override is + * appropriate. */ + public ArrayIntSet orients; + + /** + * Determines whether this priority override matches the specified + * action and orientation combination. + */ + public boolean matches (String action, int orient) + { + return (((orients == null) || orients.contains(orient)) && + ((this.action == null) || this.action.equals(action))); + } + + // documentation inherited from interface + public int compareTo (Object other) + { + // overrides with both an action and an orientation should + // come first in the list + PriorityOverride po = (PriorityOverride)other; + int pri = priority(), opri = po.priority(); + if (pri == opri) { + return hashCode() - po.hashCode(); + } else { + return pri - opri; + } + } + + protected int priority () + { + int priority = 0; + if (action != null) { + priority++; + } + if (orients != null) { + priority++; + } + return priority; + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return "[pri=" + renderPriority + ", action=" + action + + ", orients=" + orients + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + } + + /** The component class name. */ + public String name; + + /** The default render priority. */ + public int renderPriority; + + /** The color classes to use when recoloring components of this class. May + * be null if a system does not use recolorable components. */ + public String[] colors; + + /** The class name of the layer from which this component class obtains a + * mask to limit rendering to certain areas. */ + public String mask; + + /** Indicates the class name of the shadow layer to which this component + * class contributes a shadow. */ + public String shadow; + + /** 1.0 for a normal component, the alpha value of the pre-composited + * shadow for the special "shadow" component class. */ + public float shadowAlpha = 1.0f; + + /** + * Creates an uninitialized instance suitable for unserialization or + * population during XML parsing. + */ + public ComponentClass () + { + } + + /** + * Returns the render priority appropriate for the specified action + * and orientation. + */ + public int getRenderPriority (String action, int orientation) + { + // because we expect there to be relatively few priority + // overrides, we simply search linearly through the list for the + // closest match + int ocount = (_overrides != null) ? _overrides.size() : 0; + for (int ii = 0; ii < ocount; ii++) { + PriorityOverride over = (PriorityOverride)_overrides.get(ii); + // based on the way the overrides are sorted, the first match + // is the most specific and the one we want + if (over.matches(action, orientation)) { + return over.renderPriority; + } + } + + return renderPriority; + } + + /** + * Adds the supplied render priority override record to this component + * class. + */ + public void addPriorityOverride (PriorityOverride override) + { + if (_overrides == null) { + _overrides = new ComparableArrayList(); + } + _overrides.insertSorted(override); + } + + /** + * Returns true if this component class contributes a shadow to a + * particular shadow layer. Note: this is different from being a + * shadow layer which is determined by calling {@link #isShadow}. + */ + public boolean isShadowed () + { + return (shadow != null); + } + + /** + * Returns true if this component class is a shadow layer rather than a + * normal component class. + */ + public boolean isShadow () + { + return (shadowAlpha != 1.0f); + } + + /** + * Classes with the same name are the same. + */ + public boolean equals (Object other) + { + if (other instanceof ComponentClass) { + return name.equals(((ComponentClass)other).name); + } else { + return false; + } + } + + /** + * Hashcode is based on component class name. + */ + public int hashCode () + { + return name.hashCode(); + } + + /** + * Returns a string representation of this component class. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + buf.append("name=").append(name); + buf.append(", pri=").append(renderPriority); + if (colors != null) { + buf.append(", colors=").append(StringUtil.toString(colors)); + } + if (mask != null) { + buf.append(", mask=").append(mask); + } + if (shadowAlpha != 1.0f) { + buf.append(", shadow=").append(shadowAlpha); + } else if (shadow != null) { + buf.append(", shadow=").append(shadow); + } + return buf.append("]").toString(); + } + + /** A list of render priority overrides. */ + protected ComparableArrayList _overrides; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 3; +} diff --git a/src/java/com/threerings/cast/ComponentIDBroker.java b/src/java/com/threerings/cast/ComponentIDBroker.java new file mode 100644 index 00000000..c42d17f5 --- /dev/null +++ b/src/java/com/threerings/cast/ComponentIDBroker.java @@ -0,0 +1,63 @@ +// +// $Id: ComponentIDBroker.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import com.samskivert.io.PersistenceException; + +/** + * Brokers component ids. The component repository interface makes + * available a collection of components based on a unique identifier. The + * expectation is that a collection of components will be used to populate + * a repository and in that population process, component ids will be + * assigned to the components. The component id broker system provides a + * means by which named components can be mapped consistently to a set of + * component ids. Humans can then be responsible for assigning unique + * names to the components and the broker will ensure that those names map + * to unique ids that won't change if the repository is rebuilt from the + * source components. + */ +public interface ComponentIDBroker +{ + /** + * Returns the unique identifier for the named component. If no + * identifier has yet been assigned to the specified named component, + * one should be assigned and returned. + * + * @param cclass the name of the class to which the component belongs. + * @param cname the name of the component. + * + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism used to + * store the name to id mappings. + */ + public int getComponentID (String cclass, String cname) + throws PersistenceException; + + /** + * When the user of a component id broker is done obtaining component + * ids, it must call this method to give the component id broker an + * opportunity to flush any newly created component ids back to its + * persistent store. + */ + public void commit () + throws PersistenceException; +} diff --git a/src/java/com/threerings/cast/ComponentRepository.java b/src/java/com/threerings/cast/ComponentRepository.java new file mode 100644 index 00000000..17ca2f41 --- /dev/null +++ b/src/java/com/threerings/cast/ComponentRepository.java @@ -0,0 +1,71 @@ +// +// $Id: ComponentRepository.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.util.Iterator; + +/** + * Makes available a collection of character components and associated + * metadata. Character components are animated sequences that can be + * composited together to create a complete character visualization + * (imagine interchanging pairs of boots, torsos, hats, etc.). + */ +public interface ComponentRepository +{ + /** + * Returns the {@link CharacterComponent} object for the given + * component identifier. + */ + public CharacterComponent getComponent (int componentId) + throws NoSuchComponentException; + + /** + * Returns the {@link CharacterComponent} object with the given + * component class and name. + */ + public CharacterComponent getComponent (String className, String compName) + throws NoSuchComponentException; + + /** + * Returns the {@link ComponentClass} with the specified name or null + * if none exists with that name. + */ + public ComponentClass getComponentClass (String className); + + /** + * Iterates over the {@link ComponentClass} instances representing all + * available character component classes. + */ + public Iterator enumerateComponentClasses (); + + /** + * Iterates over the {@link ActionSequence} instances representing + * every available action sequence. + */ + public Iterator enumerateActionSequences (); + + /** + * Iterates over the component ids of all components in the specified + * class. + */ + public Iterator enumerateComponentIds (ComponentClass compClass); +} diff --git a/src/java/com/threerings/cast/CompositedActionFrames.java b/src/java/com/threerings/cast/CompositedActionFrames.java new file mode 100644 index 00000000..92e911ad --- /dev/null +++ b/src/java/com/threerings/cast/CompositedActionFrames.java @@ -0,0 +1,186 @@ +// +// $Id: CompositedActionFrames.java 3967 2006-03-22 02:41:15Z andrzej $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.ImageManager; +import com.threerings.media.util.MultiFrameImage; + +import com.threerings.cast.CharacterComponent; +import com.threerings.util.DirectionCodes; + +/** + * An implementation of the {@link MultiFrameImage} interface that is used + * to lazily create composited character frames when they are requested. + */ +public class CompositedActionFrames + implements ActionFrames, DirectionCodes +{ + /** Used to associate a {@link CharacterComponent} with its {@link + * ActionFrames} for a particular action. */ + public static class ComponentFrames + { + public CharacterComponent ccomp; + + public ActionFrames frames; + + public ComponentFrames () { + } + + public ComponentFrames ( + CharacterComponent ccomp, ActionFrames frames) { + this.ccomp = ccomp; + this.frames = frames; + } + + public String toString () { + return ccomp + ":" + frames; + } + } + + /** + * Constructs a set of composited action frames with the supplied + * source frames and colorization configuration. The actual component + * frame images will not be composited until they are requested. + */ + public CompositedActionFrames (ImageManager imgr, LRUHashMap frameCache, + String action, ComponentFrames[] sources) + { + // sanity check + if (sources == null || sources.length == 0) { + String errmsg = "Requested to composite invalid set of source " + + "frames! [action=" + action + + ", sources=" + StringUtil.toString(sources) + "]."; + throw new RuntimeException(errmsg); + } + + _imgr = imgr; + _frameCache = frameCache; + _sources = sources; + _action = action; + + // the sources must all have the same orientation count, so we + // just use the first + _orientCount = _sources[0].frames.getOrientationCount(); + } + + // documentation inherited from interface + public int getOrientationCount () + { + return _orientCount; + } + + // documentation inherited from interface + public TrimmedMultiFrameImage getFrames (int orient) + { + _key.setOrient(orient); + CompositedMultiFrameImage cmfi = + (CompositedMultiFrameImage)_frameCache.get(_key); + if (cmfi == null) { + cmfi = createFrames(orient); + _frameCache.put(new CompositedFramesKey(orient), cmfi); + } + return cmfi; + } + + // documentation inherited from interface + public int getXOrigin (int orient, int frameIdx) + { + CompositedMultiFrameImage cmfi = (CompositedMultiFrameImage) + getFrames(orient); + return cmfi.getXOrigin(frameIdx); + } + + // documentation inherited from interface + public int getYOrigin (int orient, int frameIdx) + { + CompositedMultiFrameImage cmfi = (CompositedMultiFrameImage) + getFrames(orient); + return cmfi.getYOrigin(frameIdx); + } + + // documentation inherited from interface + public ActionFrames cloneColorized (Colorization[] zations) + { + throw new RuntimeException("What you talkin' about Willis?"); + } + + /** + * Creates our underlying multi-frame image for a particular orientation. + */ + protected CompositedMultiFrameImage createFrames (int orient) + { + return new CompositedMultiFrameImage(_imgr, _sources, _action, orient); + } + + /** Used to cache composited frames for a particular action and + * orientation. */ + protected class CompositedFramesKey + { + public CompositedFramesKey (int orient) { + _orient = orient; + } + + public void setOrient (int orient) { + _orient = orient; + } + + public CompositedActionFrames getOwner () { + return CompositedActionFrames.this; + } + + public boolean equals (Object other) { + CompositedFramesKey okey = (CompositedFramesKey)other; + return ((getOwner() == okey.getOwner()) && + (_orient == okey._orient)); + } + + public int hashCode () { + return CompositedActionFrames.this.hashCode() ^ _orient; + } + + protected int _orient; + } + + /** The image manager from whom we can obtain prepared volatile images + * onto which to render our composited actions. */ + protected ImageManager _imgr; + + /** Used to cache our composited action frame images. */ + protected LRUHashMap _frameCache; + + /** The action for which we're compositing frames. */ + protected String _action; + + /** The number of orientations. */ + protected int _orientCount; + + /** Our source components and action frames. */ + protected ComponentFrames[] _sources; + + /** Used to avoid creating a new key object every time we do a cache + * lookup. */ + protected CompositedFramesKey _key = new CompositedFramesKey(0); +} diff --git a/src/java/com/threerings/cast/CompositedMaskedImage.java b/src/java/com/threerings/cast/CompositedMaskedImage.java new file mode 100644 index 00000000..21d31e89 --- /dev/null +++ b/src/java/com/threerings/cast/CompositedMaskedImage.java @@ -0,0 +1,131 @@ +// +// $Id: CompositedMultiFrameImage.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Transparency; + +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.Mirage; +import com.threerings.media.image.VolatileMirage; + +import com.threerings.cast.CompositedActionFrames.ComponentFrames; + +/** + * Used to composite action frames with mask frames. + */ +public class CompositedMaskedImage extends CompositedMultiFrameImage +{ + public CompositedMaskedImage ( + ImageManager imgr, ComponentFrames[] sources, String action, + int orient) + { + super(imgr, sources, action, orient); + } + + // documentation inherited from interface + public int getWidth (int index) { + return _sources[0].frames.getFrames(_orient).getWidth(index); + } + + // documentation inherited from interface + public int getHeight (int index) { + return _sources[0].frames.getFrames(_orient).getHeight(index); + } + + public int getXOrigin (int index) { + return _sources[0].frames.getXOrigin(_orient, index); + } + + public int getYOrigin (int index) { + return _sources[0].frames.getYOrigin(_orient, index); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) { + _images[index].paint(g, x + _images[index].getX(), + y + _images[index].getY()); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) { + return _images[index].hitTest(x + _images[index].getX(), + y + _images[index].getY()); + } + + // documentation inherited from interface TrimmedMultiFrameImage + public void getTrimmedBounds (int index, Rectangle bounds) { + bounds.setBounds(_images[index].getX(), _images[index].getY(), + _images[index].getWidth(), _images[index].getHeight()); + } + + // documentation inherited + protected CompositedMirage createCompositedMirage (int index) + { + return new MaskedMirage(index); + } + + /** + * Combines the image in the first source with the mask in the second. */ + protected class MaskedMirage extends CompositedMirage + { + public MaskedMirage (int index) + { + super(index); + } + + // documentation inherited + protected Rectangle combineBounds (Rectangle bounds, Rectangle tbounds) + { + if (bounds.width == 0 && bounds.height == 0) { + bounds.setBounds(tbounds); + } else { + bounds = bounds.intersection(tbounds); + } + return bounds; + } + + // documentation inherited + protected void refreshVolatileImage () + { + Graphics2D g = (Graphics2D)_image.getGraphics(); + try { + TrimmedMultiFrameImage source = + _sources[0].frames.getFrames(_orient), + mask = _sources[1].frames.getFrames(_orient); + source.paintFrame(g, _index, -_bounds.x, -_bounds.y); + g.setComposite(AlphaComposite.DstIn); + mask.paintFrame(g, _index, -_bounds.x, -_bounds.y); + + } finally { + // clean up after ourselves + if (g != null) { + g.dispose(); + } + } + } + } +}; diff --git a/src/java/com/threerings/cast/CompositedMultiFrameImage.java b/src/java/com/threerings/cast/CompositedMultiFrameImage.java new file mode 100644 index 00000000..545547d3 --- /dev/null +++ b/src/java/com/threerings/cast/CompositedMultiFrameImage.java @@ -0,0 +1,254 @@ +// +// $Id: CompositedMultiFrameImage.java 3967 2006-03-22 02:41:15Z andrzej $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Transparency; + +import java.util.Arrays; +import java.util.Comparator; + +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.Mirage; +import com.threerings.media.image.VolatileMirage; + +import com.threerings.cast.CompositedActionFrames.ComponentFrames; +import com.threerings.cast.TrimmedMultiFrameImage; + +/** + * Used to composite the action frames for a particular orientation of a + * {@link CompositedActionFrames}. + */ +public class CompositedMultiFrameImage + implements TrimmedMultiFrameImage +{ + public CompositedMultiFrameImage ( + ImageManager imgr, ComponentFrames[] sources, + String action, int orient) + { + _imgr = imgr; + _sources = sources; + _action = action; + _orient = orient; + + // create our frame images (which will do the compositing) + int fcount = sources[0].frames.getFrames(orient).getFrameCount(); + _images = new CompositedMirage[fcount]; + for (int ii = 0; ii < fcount; ii++) { + _images[ii] = createCompositedMirage(ii); + } + } + + // documentation inherited + public int getFrameCount () { + return _images.length; + } + + // documentation inherited from interface + public int getWidth (int index) { + return _images[index].getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) { + return _images[index].getHeight(); + } + + public int getXOrigin (int index) { + return _images[index].getXOrigin(); + } + + public int getYOrigin (int index) { + return _images[index].getYOrigin(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) { + _images[index].paint(g, x, y); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) { + return _images[index].hitTest(x, y); + } + + // documentation inherited from interface + public void getTrimmedBounds (int index, Rectangle bounds) { + bounds.setBounds(0, 0, getWidth(index), getHeight(index)); + } + + /** + * Returns the estimated memory usage of our composited frame images. + */ + public long getEstimatedMemoryUsage () + { + long size = 0; + for (int ii = 0; ii < _images.length; ii++) { + size += _images[ii].getEstimatedMemoryUsage(); + } + return size; + } + + /** + * Creates a composited image for the specified frame. + */ + protected CompositedMirage createCompositedMirage (int index) + { + return new CompositedMirage(index); + } + + // documentation inherited + protected Mirage getFrame (int orient, int index) + { + return _images[index]; + } + + /** The image manager from whom we load our images. */ + protected ImageManager _imgr; + + /** The action frames from which we obtain our source imagery. */ + protected ComponentFrames[] _sources; + + /** The action we're compositing. */ + protected String _action; + + /** The orientation we're compositing. */ + protected int _orient; + + /** Our composited action frame images. */ + protected CompositedMirage[] _images; + + /** + * Used to create our mirage using the source action frame images. + */ + protected class CompositedMirage extends VolatileMirage + implements Comparator + { + public CompositedMirage (int index) + { + super(CompositedMultiFrameImage.this._imgr, + new Rectangle(0, 0, 0, 0)); + + // keep this for later + _index = index; + + // first we need to determine the bounds of the rectangle that + // will enclose all of our various components + Rectangle tbounds = new Rectangle(); + int scount = _sources.length; + for (int ii = 0; ii < scount; ii++) { + TrimmedMultiFrameImage source = + _sources[ii].frames.getFrames(_orient); + source.getTrimmedBounds(index, tbounds); + _bounds = combineBounds(_bounds, tbounds); + } + + // compute our new origin + _origin.x = (_sources[0].frames.getXOrigin(_orient, index) - + _bounds.x); + _origin.y = (_sources[0].frames.getYOrigin(_orient, index) - + _bounds.y); +// Log.info("New origin [x=" + _origin.x + ", y=" + _origin.y + "]."); + + // render our volatile image for the first time + createVolatileImage(); + } + + public int getXOrigin () + { + return _origin.x; + } + + public int getYOrigin () + { + return _origin.y; + } + + // documentation inherited from interface + public int compare (Object o1, Object o2) + { + ComponentFrames cf1 = (ComponentFrames)o1, + cf2 = (ComponentFrames)o2; + return (cf1.ccomp.componentClass.getRenderPriority( + _action, _orient) - + cf2.ccomp.componentClass.getRenderPriority( + _action, _orient)); + } + + /** + * Combines the working bounds with a new set of bounds. + */ + protected Rectangle combineBounds (Rectangle bounds, Rectangle tbounds) + { + // the first one defines our initial bounds + if (bounds.width == 0 && bounds.height == 0) { + bounds.setBounds(tbounds); + } else { + bounds.add(tbounds); + } + return bounds; + } + + // documentation inherited + protected int getTransparency () + { + return Transparency.BITMASK; + } + + // documentation inherited + protected void refreshVolatileImage () + { +// long start = System.currentTimeMillis(); + + // sort the sources appropriately for this orientation + Arrays.sort(_sources, this); + + // now render each of the components into a composited frame + int scount = _sources.length; + Graphics2D g = (Graphics2D)_image.getGraphics(); + try { + for (int ii = 0; ii < scount; ii++) { + TrimmedMultiFrameImage source = + _sources[ii].frames.getFrames(_orient); + source.paintFrame(g, _index, -_bounds.x, -_bounds.y); + } + } finally { + // clean up after ourselves + if (g != null) { + g.dispose(); + } + } + +// Log.info("Composited [orient=" + _orient + ", index=" + _index + +// ", tbounds=" + StringUtil.toString(_bounds) + "]."); + +// long now = System.currentTimeMillis(); +// Log.info("Composited " + scount + " frames in " + +// (now-start) + " millis."); + } + + protected int _index; + protected Point _origin = new Point(); + } +}; diff --git a/src/java/com/threerings/cast/CompositedShadowImage.java b/src/java/com/threerings/cast/CompositedShadowImage.java new file mode 100644 index 00000000..3c75d8c3 --- /dev/null +++ b/src/java/com/threerings/cast/CompositedShadowImage.java @@ -0,0 +1,92 @@ +// +// $Id: CompositedMultiFrameImage.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.Mirage; +import com.threerings.media.image.VolatileMirage; + +import com.threerings.cast.CompositedActionFrames.ComponentFrames; + +/** + * Used to composite the special shadow action frames for a particular + * orientation of a {@link CompositedActionFrames}. + */ +public class CompositedShadowImage extends CompositedMultiFrameImage +{ + public CompositedShadowImage (ImageManager imgr, ComponentFrames[] sources, + String action, int orient, float shadowAlpha) + { + super(imgr, sources, action, orient); + + // create the appropriate alpha composite for rendering the shadow + _shadowAlpha = AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, shadowAlpha); + } + + // documentation inherited from interface + public int getWidth (int index) { + return _sources[0].frames.getFrames(_orient).getWidth(index); + } + + // documentation inherited from interface + public int getHeight (int index) { + return _sources[0].frames.getFrames(_orient).getHeight(index); + } + + public int getXOrigin (int index) { + return _sources[0].frames.getXOrigin(_orient, index); + } + + public int getYOrigin (int index) { + return _sources[0].frames.getYOrigin(_orient, index); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) { + Composite ocomp = g.getComposite(); + g.setComposite(_shadowAlpha); + _images[index].paint(g, x + _images[index].getX(), + y + _images[index].getY()); + g.setComposite(ocomp); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) { + return _images[index].hitTest(x + _images[index].getX(), + y + _images[index].getY()); + } + + // documentation inherited from interface TrimmedMultiFrameImage + public void getTrimmedBounds (int index, Rectangle bounds) { + bounds.setBounds(_images[index].getX(), _images[index].getY(), + _images[index].getWidth(), _images[index].getHeight()); + } + + /** The alpha value at which we render our shadow. */ + protected AlphaComposite _shadowAlpha; +}; diff --git a/src/java/com/threerings/cast/FrameProvider.java b/src/java/com/threerings/cast/FrameProvider.java new file mode 100644 index 00000000..e1080f95 --- /dev/null +++ b/src/java/com/threerings/cast/FrameProvider.java @@ -0,0 +1,37 @@ +// +// $Id: FrameProvider.java 3740 2005-10-20 22:12:45Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +/** + * Provides a mechanism where by a character component can obtain access + * to its image frames for a particular action in an on demand manner. + */ +public interface FrameProvider +{ + /** + * Returns the animation frames (in the eight sprite directions) for + * the specified action of the specified component. May return null if + * the specified action does not exist for the specified component. + */ + public ActionFrames getFrames ( + CharacterComponent component, String action, String type); +} diff --git a/src/java/com/threerings/cast/Log.java b/src/java/com/threerings/cast/Log.java new file mode 100644 index 00000000..3e54857f --- /dev/null +++ b/src/java/com/threerings/cast/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +/** + * A placeholder class that contains a reference to the log object used by + * the cast package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("cast"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/cast/NoSuchComponentException.java b/src/java/com/threerings/cast/NoSuchComponentException.java new file mode 100644 index 00000000..a18c2f4f --- /dev/null +++ b/src/java/com/threerings/cast/NoSuchComponentException.java @@ -0,0 +1,50 @@ +// +// $Id: NoSuchComponentException.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +/** + * Thrown when an attempt is made to retrieve a non-existent character + * component from the component repository. + */ +public class NoSuchComponentException extends Exception +{ + public NoSuchComponentException (int componentId) + { + super("No such component [componentId=" + componentId + "]"); + _componentId = componentId; + } + + public NoSuchComponentException ( + String componentClass, String componentName) + { + super("No such component [class=" + componentClass + + ", name=" + componentName + "]"); + _componentId = -1; + } + + public int getComponentId () + { + return _componentId; + } + + protected int _componentId; +} diff --git a/src/java/com/threerings/cast/StandardActions.java b/src/java/com/threerings/cast/StandardActions.java new file mode 100644 index 00000000..19e23a4a --- /dev/null +++ b/src/java/com/threerings/cast/StandardActions.java @@ -0,0 +1,42 @@ +// +// $Id: StandardActions.java 3740 2005-10-20 22:12:45Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +/** + * Actions are referenced by name and this interface defines constants for + * standard actions and action suffixes used by the shadow and cropping + * support. + */ +public interface StandardActions +{ + /** The name of the standard standing action. */ + public static final String STANDING = "standing"; + + /** The name of the standard walking action. */ + public static final String WALKING = "walking"; + + /** A special action sub-type for shadow imagery. */ + public static final String SHADOW_TYPE = "shadow"; + + /** A special action sub-type for crop imagery. */ + public static final String CROP_TYPE = "crop"; +} diff --git a/src/java/com/threerings/cast/TrimmedMultiFrameImage.java b/src/java/com/threerings/cast/TrimmedMultiFrameImage.java new file mode 100644 index 00000000..e7d88ae5 --- /dev/null +++ b/src/java/com/threerings/cast/TrimmedMultiFrameImage.java @@ -0,0 +1,41 @@ +// +// $Id: TrimmedMultiFrameImage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.Rectangle; + +import com.threerings.media.util.MultiFrameImage; + +/** + * Used to generate more memory efficient composited images in + * circumstances where we have trimmed underlying component images. + */ +public interface TrimmedMultiFrameImage extends MultiFrameImage +{ + /** + * Fills in the minimum bounding rectangle for this image that + * contains all non-transparent pixels. If this information is + * unavailable, the bounds of the entire image may be returned in + * exchange for improved performance. + */ + public void getTrimmedBounds (int index, Rectangle bounds); +} diff --git a/src/java/com/threerings/cast/builder/BuilderModel.java b/src/java/com/threerings/cast/builder/BuilderModel.java new file mode 100644 index 00000000..04a71e10 --- /dev/null +++ b/src/java/com/threerings/cast/builder/BuilderModel.java @@ -0,0 +1,151 @@ +// +// $Id: BuilderModel.java 4145 2006-05-24 01:24:24Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import com.samskivert.util.CollectionUtil; + +import com.threerings.cast.ComponentRepository; +import com.threerings.cast.ComponentClass; + +/** + * The builder model represents the current state of the character the + * user is building. + */ +public class BuilderModel +{ + /** + * Constructs a builder model. + */ + public BuilderModel (ComponentRepository crepo) + { + gatherComponentInfo(crepo); + } + + /** + * Adds a builder model listener. + * + * @param l the listener. + */ + public void addListener (BuilderModelListener l) + { + if (!_listeners.contains(l)) { + _listeners.add(l); + } + } + + /** + * Notifies all model listeners that the builder model has changed. + */ + protected void notifyListeners (int event) + { + int size = _listeners.size(); + for (int ii = 0; ii < size; ii++) { + ((BuilderModelListener)_listeners.get(ii)).modelChanged(event); + } + } + + /** + * Returns a list of the available component classes. + */ + public List getComponentClasses () + { + return Collections.unmodifiableList(_classes); + } + + /** + * Returns the list of components available in the specified class. + */ + public List getComponents (ComponentClass cclass) + { + List list = (List)_components.get(cclass); + if (list == null) { + list = new ArrayList(); + } + return list; + } + + /** + * Returns the selected components in an array. + */ + public int[] getSelectedComponents () + { + int[] values = new int[_selected.size()]; + Iterator iter = _selected.values().iterator(); + for (int i = 0; iter.hasNext(); i++) { + values[i] = ((Integer)iter.next()).intValue(); + } + return values; + } + + /** + * Sets the selected component for the given component class. + */ + public void setSelectedComponent (ComponentClass cclass, int cid) + { + _selected.put(cclass, Integer.valueOf(cid)); + notifyListeners(BuilderModelListener.COMPONENT_CHANGED); + } + + /** + * Gathers component class and component information from the + * character manager for later reference by others. + */ + protected void gatherComponentInfo (ComponentRepository crepo) + { + // get the list of all component classes + CollectionUtil.addAll(_classes, crepo.enumerateComponentClasses()); + + for (int ii = 0; ii < _classes.size(); ii++) { + // get the list of components available for this class + ComponentClass cclass = (ComponentClass)_classes.get(ii); + Iterator iter = crepo.enumerateComponentIds(cclass); + + while (iter.hasNext()) { + Integer cid = (Integer)iter.next(); + ArrayList clist = (ArrayList)_components.get(cclass); + if (clist == null) { + _components.put(cclass, clist = new ArrayList()); + } + + clist.add(cid); + } + } + } + + /** The currently selected character components. */ + protected HashMap _selected = new HashMap(); + + /** The hashtable of available component ids for each class. */ + protected HashMap _components = new HashMap(); + + /** The list of all available component classes. */ + protected ArrayList _classes = new ArrayList(); + + /** The model listeners. */ + protected ArrayList _listeners = new ArrayList(); +} diff --git a/src/java/com/threerings/cast/builder/BuilderModelListener.java b/src/java/com/threerings/cast/builder/BuilderModelListener.java new file mode 100644 index 00000000..514218d1 --- /dev/null +++ b/src/java/com/threerings/cast/builder/BuilderModelListener.java @@ -0,0 +1,40 @@ +// +// $Id: BuilderModelListener.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +/** + * The builder model listener interface should be implemented by + * classes that would like to be notified when the builder model is + * changed. + * + * @see BuilderModel + */ +public interface BuilderModelListener +{ + /** + * Called by the {@link BuilderModel} when the model is changed. + */ + public void modelChanged (int event); + + /** Notification event constants. */ + public static final int COMPONENT_CHANGED = 0; +} diff --git a/src/java/com/threerings/cast/builder/BuilderPanel.java b/src/java/com/threerings/cast/builder/BuilderPanel.java new file mode 100644 index 00000000..5417e4ad --- /dev/null +++ b/src/java/com/threerings/cast/builder/BuilderPanel.java @@ -0,0 +1,60 @@ +// +// $Id: BuilderPanel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import javax.swing.*; +import com.samskivert.swing.*; + +import com.threerings.cast.CharacterManager; +import com.threerings.cast.ComponentRepository; + +/** + * The builder panel presents the user with an overview of a composited + * character and facilities for altering the individual components that + * comprise the character's display image. + */ +public class BuilderPanel extends JPanel +{ + /** + * Constructs the builder panel. + */ + public BuilderPanel (CharacterManager charmgr, + ComponentRepository crepo, String cprefix) + { + setLayout(new VGroupLayout()); + + // give ourselves a wee bit of a border + setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + GroupLayout gl = new HGroupLayout(GroupLayout.STRETCH); + gl.setOffAxisPolicy(GroupLayout.STRETCH); + + // create the builder model + BuilderModel model = new BuilderModel(crepo); + + // create the component selection and sprite display panels + JPanel sub = new JPanel(gl); + sub.add(new ComponentPanel(model, cprefix)); + sub.add(new SpritePanel(charmgr, model)); + add(sub); + } +} diff --git a/src/java/com/threerings/cast/builder/ClassEditor.java b/src/java/com/threerings/cast/builder/ClassEditor.java new file mode 100644 index 00000000..e72c0477 --- /dev/null +++ b/src/java/com/threerings/cast/builder/ClassEditor.java @@ -0,0 +1,109 @@ +// +// $Id: ClassEditor.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import java.util.List; + +import javax.swing.*; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import com.samskivert.swing.*; + +import com.threerings.cast.ComponentClass; + +/** + * The class editor displays a label and a slider that allow the user to + * select the desired component for a given component class. + */ +public class ClassEditor extends JPanel implements ChangeListener +{ + /** + * Constructs a class editor. + */ + public ClassEditor ( + BuilderModel model, ComponentClass cclass, List components) + { + _model = model; + _components = components; + _cclass = cclass; + + GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH); + gl.setOffAxisPolicy(GroupLayout.STRETCH); + setLayout(gl); + + gl = new HGroupLayout(); + gl.setJustification(GroupLayout.LEFT); + JPanel sub = new JPanel(gl); + + sub.add(new JLabel(cclass.name + ": ")); + sub.add(_clabel = new JLabel("0")); + add(sub); + + // create the slider allowing selection of available components + int max = components.size() - 1; + JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, max, 0); + slider.setSnapToTicks(true); + slider.addChangeListener(this); + add(slider); + + // set the starting component for this class + setSelectedComponent(0); + } + + // documentation inherited + public void stateChanged (ChangeEvent e) + { + JSlider source = (JSlider)e.getSource(); + if (!source.getValueIsAdjusting()) { + int val = source.getValue(); + // update the model with the newly selected component + setSelectedComponent(val); + // update the label with the new value + _clabel.setText(Integer.toString(val)); + } + } + + /** + * Sets the selected component in the builder model for the + * component class associated with this editor to the component at + * the given index in this editor's list of available components. + */ + protected void setSelectedComponent (int idx) + { + int cid = ((Integer)_components.get(idx)).intValue(); + _model.setSelectedComponent(_cclass, cid); + } + + /** The component class associated with this editor. */ + protected ComponentClass _cclass; + + /** The components selectable via this editor. */ + protected List _components; + + /** The label denoting the currently selected component index. */ + protected JLabel _clabel; + + /** The builder model. */ + protected BuilderModel _model; +} diff --git a/src/java/com/threerings/cast/builder/ComponentPanel.java b/src/java/com/threerings/cast/builder/ComponentPanel.java new file mode 100644 index 00000000..f932aba9 --- /dev/null +++ b/src/java/com/threerings/cast/builder/ComponentPanel.java @@ -0,0 +1,74 @@ +// +// $Id: ComponentPanel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import java.util.List; + +import javax.swing.*; + +import com.samskivert.swing.*; + +import com.threerings.cast.Log; +import com.threerings.cast.*; + +/** + * The component panel displays the available components for all + * component classes and allows the user to choose a set of components + * for compositing into a character image. + */ +public class ComponentPanel extends JPanel +{ + /** + * Constructs the component panel. + */ + public ComponentPanel (BuilderModel model, String cprefix) + { + setLayout(new VGroupLayout(GroupLayout.STRETCH)); + // set up a border + setBorder(BorderFactory.createEtchedBorder()); + // add the component editors to the panel + addClassEditors(model, cprefix); + } + + /** + * Adds editor user interface elements for each component class to + * allow the user to select the desired component. + */ + protected void addClassEditors (BuilderModel model, String cprefix) + { + List classes = model.getComponentClasses(); + int size = classes.size(); + for (int ii = 0; ii < size; ii++) { + ComponentClass cclass = (ComponentClass)classes.get(ii); + if (!cclass.name.startsWith(cprefix)) { + continue; + } + List ccomps = model.getComponents(cclass); + if (ccomps.size() > 0) { + add(new ClassEditor(model, cclass, ccomps)); + } else { + Log.info("Not creating editor for empty class " + + "[class=" + cclass + "]."); + } + } + } +} diff --git a/src/java/com/threerings/cast/builder/SpritePanel.java b/src/java/com/threerings/cast/builder/SpritePanel.java new file mode 100644 index 00000000..173050b2 --- /dev/null +++ b/src/java/com/threerings/cast/builder/SpritePanel.java @@ -0,0 +1,131 @@ +// +// $Id: SpritePanel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; + +import javax.swing.JPanel; + +import com.threerings.util.DirectionCodes; + +import com.threerings.cast.CharacterDescriptor; +import com.threerings.cast.CharacterManager; +import com.threerings.cast.CharacterSprite; +import com.threerings.cast.StandardActions; + +/** + * The sprite panel displays a character sprite centered in the panel + * suitable for user perusal. + */ +public class SpritePanel extends JPanel + implements DirectionCodes, BuilderModelListener +{ + /** + * Constructs the sprite panel. + */ + public SpritePanel (CharacterManager charmgr, BuilderModel model) + { + // save off references + _charmgr = charmgr; + _model = model; + + // listen to the builder model so that we can update the + // sprite when a new component is selected + _model.addListener(this); + } + + // documentation inherited + public void paintComponent (Graphics g) + { + super.paintComponent(g); + Graphics2D gfx = (Graphics2D)g; + + if (_sprite != null) { + // render the sprite + _sprite.paint(gfx); + } + } + + // documentation inherited + public void doLayout () + { + super.doLayout(); + generateSprite(); + centerSprite(); + } + + // documentation inherited + public void modelChanged (int event) + { + if (event == COMPONENT_CHANGED) { + generateSprite(); + } + } + + /** + * Generates a new character sprite for display to reflect the + * currently selected character components. + */ + protected void generateSprite () + { + int components[] = _model.getSelectedComponents(); + CharacterDescriptor desc = new CharacterDescriptor(components, null); + CharacterSprite sprite = _charmgr.getCharacter(desc); + setSprite(sprite); + } + + /** + * Sets the sprite to be displayed. + */ + protected void setSprite (CharacterSprite sprite) + { + sprite.setActionSequence(StandardActions.STANDING); + sprite.setOrientation(WEST); + _sprite = sprite; + centerSprite(); + repaint(); + } + + /** + * Sets the sprite's location to render it centered within the panel. + */ + protected void centerSprite () + { + if (_sprite != null) { + Dimension d = getSize(); + int swid = _sprite.getWidth(), shei = _sprite.getHeight(); + int x = d.width / 2, y = (d.height + shei) / 2; + _sprite.setLocation(x, y); + } + } + + /** The sprite displayed by the panel. */ + protected CharacterSprite _sprite; + + /** The character manager. */ + protected CharacterManager _charmgr; + + /** The builder model. */ + protected BuilderModel _model; +} diff --git a/src/java/com/threerings/cast/bundle/BundleUtil.java b/src/java/com/threerings/cast/bundle/BundleUtil.java new file mode 100644 index 00000000..79856f52 --- /dev/null +++ b/src/java/com/threerings/cast/bundle/BundleUtil.java @@ -0,0 +1,110 @@ +// +// $Id: BundleUtil.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; + +import com.samskivert.io.StreamUtil; + +import com.threerings.cast.Log; +import com.threerings.resource.ResourceBundle; + +/** + * Utility functions related to creating and manipulating component + * bundles. + */ +public class BundleUtil +{ + /** The path in the metadata bundle to the serialized action table. */ + public static final String ACTIONS_PATH = "actions.dat"; + + /** The path in the metadata bundle to the serialized action tile sets + * table. */ + public static final String ACTION_SETS_PATH = "action_sets.dat"; + + /** The path in the metadata bundle to the serialized component class + * table. */ + public static final String CLASSES_PATH = "classes.dat"; + + /** The path in the component bundle to the serialized component id to + * class/type mapping. */ + public static final String COMPONENTS_PATH = "components.dat"; + + /** The file extension of our action tile images. */ + public static final String IMAGE_EXTENSION = ".png"; + + /** The serialized tileset extension for our action tilesets. */ + public static final String TILESET_EXTENSION = ".dat"; + + /** + * Attempts to load an object from the supplied resource bundle with + * the specified path. + * + * @param wipeBundleOnFailure if there is an error reading the object + * from the bundle and this parameter is true, we will instruct the + * bundle to delete its underlying jar file before propagating the + * exception with the expectation that it will be redownloaded and + * repaired the next time the application is run. + * + * @return the unserialized object in question. + * + * @exception IOException thrown if an I/O error occurs while reading + * the object from the bundle. + */ + public static Object loadObject (ResourceBundle bundle, String path, + boolean wipeBundleOnFailure) + throws IOException, ClassNotFoundException + { + InputStream bin = null; + try { + bin = bundle.getResource(path); + if (bin == null) { + return null; + } + return new ObjectInputStream(bin).readObject(); + + } catch (InvalidClassException ice) { + Log.warning("Aiya! Serialized object is hosed " + + "[bundle=" + bundle.getSource().getPath() + + ", element=" + path + + ", error=" + ice.getMessage() + "]."); + return null; + + } catch (IOException ioe) { + Log.warning("Error reading resource from bundle " + + "[bundle=" + bundle + ", path=" + path + + ", wiping?=" + wipeBundleOnFailure + "]."); + if (wipeBundleOnFailure) { + StreamUtil.close(bin); + bin = null; + bundle.wipeBundle(false); + } + throw ioe; + + } finally { + StreamUtil.close(bin); + } + } +} diff --git a/src/java/com/threerings/cast/bundle/BundledComponentRepository.java b/src/java/com/threerings/cast/bundle/BundledComponentRepository.java new file mode 100644 index 00000000..931dd7ed --- /dev/null +++ b/src/java/com/threerings/cast/bundle/BundledComponentRepository.java @@ -0,0 +1,528 @@ +// +// $Id: BundledComponentRepository.java 4023 2006-04-14 21:52:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.IntIntMap; +import com.samskivert.util.Tuple; + +import org.apache.commons.collections.iterators.FilterIterator; +import org.apache.commons.collections.Predicate; + +import com.threerings.resource.ResourceBundle; +import com.threerings.resource.ResourceManager; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.FastImageIO; +import com.threerings.media.image.ImageDataProvider; +import com.threerings.media.image.ImageManager; + +import com.threerings.media.tile.IMImageProvider; +import com.threerings.media.tile.Tile; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TrimmedTile; + +import com.threerings.util.DirectionCodes; + +import com.threerings.cast.ActionFrames; +import com.threerings.cast.ActionSequence; +import com.threerings.cast.CharacterComponent; +import com.threerings.cast.ComponentClass; +import com.threerings.cast.ComponentRepository; +import com.threerings.cast.FrameProvider; +import com.threerings.cast.Log; +import com.threerings.cast.NoSuchComponentException; +import com.threerings.cast.StandardActions; +import com.threerings.cast.TrimmedMultiFrameImage; + +/** + * A component repository implementation that obtains information from + * resource bundles. + * + * @see ResourceManager + */ +public class BundledComponentRepository + implements DirectionCodes, ComponentRepository +{ + /** + * Constructs a repository which will obtain its resource set from the + * supplied resource manager. + * + * @param rmgr the resource manager from which to obtain our resource + * set. + * @param imgr the image manager that we'll use to decode and cache + * images. + * @param name the name of the resource set from which we will be + * loading our component data. + * + * @exception IOException thrown if an I/O error occurs while reading + * our metadata from the resource bundles. + */ + public BundledComponentRepository ( + ResourceManager rmgr, ImageManager imgr, String name) + throws IOException + { + // keep this guy around + _imgr = imgr; + + // first we obtain the resource set from whence will come our + // bundles + ResourceBundle[] rbundles = rmgr.getResourceSet(name); + + // look for our metadata info in each of the bundles + try { + int rcount = (rbundles == null) ? 0 : rbundles.length; + for (int i = 0; i < rcount; i++) { + if (_actions == null) { + _actions = (HashMap)BundleUtil.loadObject( + rbundles[i], BundleUtil.ACTIONS_PATH, true); + } + if (_actionSets == null) { + _actionSets = (HashMap)BundleUtil.loadObject( + rbundles[i], BundleUtil.ACTION_SETS_PATH, true); + } + if (_classes == null) { + _classes = (HashMap)BundleUtil.loadObject( + rbundles[i], BundleUtil.CLASSES_PATH, true); + } + } + + // now go back and load up all of the component information + for (int i = 0; i < rcount; i++) { + HashIntMap comps = null; + comps = (HashIntMap)BundleUtil.loadObject( + rbundles[i], BundleUtil.COMPONENTS_PATH, true); + if (comps == null) { + continue; + } + + // create a frame provider for this bundle + FrameProvider fprov = + new ResourceBundleProvider(_imgr, rbundles[i]); + + // now create character component instances for each component + // in the serialized table + Iterator iter = comps.keySet().iterator(); + while (iter.hasNext()) { + int componentId = ((Integer)iter.next()).intValue(); + Tuple info = (Tuple)comps.get(componentId); + createComponent(componentId, (String)info.left, + (String)info.right, fprov); + } + } + + } catch (ClassNotFoundException cnfe) { + throw (IOException) new IOException( + "Internal error unserializing metadata").initCause(cnfe); + } + + // if we failed to load our classes or actions, create empty + // hashtables so that we can safely enumerate our emptiness + if (_actions == null) { + _actions = new HashMap(); + } + if (_classes == null) { + _classes = new HashMap(); + } + } + + /** + * Configures the bundled component repository to wipe any bundles + * that report certain kinds of failure. In the event that an unpacked + * bundle becomes corrupt, this is useful in that it will force the + * bundle to be unpacked on the next application invocation, + * potentially remedying the problem of a corrupt unpacking. + */ + public void setWipeOnFailure (boolean wipeOnFailure) + { + _wipeOnFailure = true; + } + + // documentation inherited + public CharacterComponent getComponent (int componentId) + throws NoSuchComponentException + { + CharacterComponent component = (CharacterComponent) + _components.get(componentId); + if (component == null) { + throw new NoSuchComponentException(componentId); + } + return component; + } + + // documentation inherited + public CharacterComponent getComponent (String className, String compName) + throws NoSuchComponentException + { + // look up the list for that class + ArrayList comps = (ArrayList)_classComps.get(className); + if (comps != null) { + // scan the list for the named component + int ccount = comps.size(); + for (int i = 0; i < ccount; i++) { + CharacterComponent comp = (CharacterComponent)comps.get(i); + if (comp.name.equals(compName)) { + return comp; + } + } + } + throw new NoSuchComponentException(className, compName); + } + + // documentation inherited + public ComponentClass getComponentClass (String className) + { + return (ComponentClass)_classes.get(className); + } + + // documentation inherited + public Iterator enumerateComponentClasses () + { + return _classes.values().iterator(); + } + + // documentation inherited + public Iterator enumerateActionSequences () + { + return _actions.values().iterator(); + } + + // documentation inherited + public Iterator enumerateComponentIds (final ComponentClass compClass) + { + Predicate classP = new Predicate() { + public boolean evaluate (Object input) { + CharacterComponent comp = (CharacterComponent) + _components.get(input); + return comp.componentClass.equals(compClass); + } + }; + return new FilterIterator(_components.keySet().iterator(), classP); + } + + /** + * Creates a component and inserts it into the component table. + */ + protected void createComponent ( + int componentId, String cclass, String cname, FrameProvider fprov) + { + // look up the component class information + ComponentClass clazz = (ComponentClass)_classes.get(cclass); + if (clazz == null) { + Log.warning("Non-existent component class " + + "[class=" + cclass + ", name=" + cname + + ", id=" + componentId + "]."); + return; + } + + // create the component + CharacterComponent component = new CharacterComponent( + componentId, cname, clazz, fprov); + + // stick it into the appropriate tables + _components.put(componentId, component); + + // we have a hash of lists for mapping components by class/name + ArrayList comps = (ArrayList)_classComps.get(cclass); + if (comps == null) { + comps = new ArrayList(); + _classComps.put(cclass, comps); + } + if (!comps.contains(component)) { + comps.add(component); + } else { + Log.info("Requested to register the same component twice? " + + "[component=" + component + "]."); + } + } + + /** + * Instances of these provide images to our component action tilesets + * and frames to our components. + */ + protected class ResourceBundleProvider extends IMImageProvider + implements ImageDataProvider, FrameProvider + { + /** + * Constructs an instance that will obtain image data from the + * specified resource bundle. + */ + public ResourceBundleProvider (ImageManager imgr, ResourceBundle bundle) + { + super(imgr, (String)null); + _dprov = this; + _bundle = bundle; + } + + // documentation inherited from interface + public String getIdent () + { + return "bcr:" + _bundle.getSource(); + } + + // documentation inherited from interface + public BufferedImage loadImage (String path) throws IOException + { + return FastImageIO.read(_bundle.getResourceFile(path)); + } + + // documentation inherited + public ActionFrames getFrames ( + CharacterComponent component, String action, String type) + { + // obtain the action sequence definition for this action + ActionSequence actseq = (ActionSequence)_actions.get(action); + if (actseq == null) { + Log.warning("Missing action sequence definition " + + "[action=" + action + + ", component=" + component + "]."); + return null; + } + + // determine our image path name + String imgpath = action, dimgpath = ActionSequence.DEFAULT_SEQUENCE; + if (type != null) { + imgpath += "_" + type; + dimgpath += "_" + type; + } + + String root = component.componentClass.name + "/" + + component.name + "/"; + String cpath = root + imgpath + BundleUtil.TILESET_EXTENSION; + String dpath = root + dimgpath + BundleUtil.TILESET_EXTENSION; + + // look to see if this tileset is already cached (as the + // custom action or the default action) + TileSet aset = (TileSet)_setcache.get(cpath); + if (aset == null) { + aset = (TileSet)_setcache.get(dpath); + if (aset != null) { + // save ourselves a lookup next time + _setcache.put(cpath, aset); + } + } + + try { + // then try loading up a tileset customized for this action + if (aset == null) { + aset = (TileSet)BundleUtil.loadObject( + _bundle, cpath, false); + } + + // if that failed, try loading the default tileset + if (aset == null) { + aset = (TileSet)BundleUtil.loadObject( + _bundle, dpath, false); + _setcache.put(dpath, aset); + } + + // if that failed too, we're hosed + if (aset == null) { + // if this is a shadow image, no need to freak out as they + // are optional + if (!StandardActions.SHADOW_TYPE.equals(type)) { + Log.warning("Unable to locate tileset for action '" + + imgpath + "' " + component + "."); + if (_wipeOnFailure) { + _bundle.wipeBundle(false); + } + } + return null; + } + + aset.setImageProvider(this); + _setcache.put(cpath, aset); + return new TileSetFrameImage(aset, actseq); + + } catch (Exception e) { + Log.warning("Error loading tileset for action '" + imgpath + + "' " + component + "."); + Log.logStackTrace(e); + return null; + } + } + + /** The resource bundle from which we obtain image data. */ + protected ResourceBundle _bundle; + + /** Cache of tilesets loaded from our bundle. */ + protected HashMap _setcache = new HashMap(); + } + + /** + * Used to provide multiframe images using data obtained from a + * tileset. + */ + protected static class TileSetFrameImage implements ActionFrames + { + /** + * Constructs a tileset frame image with the specified tileset and + * for the specified orientation. + */ + public TileSetFrameImage (TileSet set, ActionSequence actseq) + { + _set = set; + _actseq = actseq; + + // compute these now to avoid pointless recomputation later + _ocount = actseq.orients.length; + _fcount = set.getTileCount() / _ocount; + + // create our mapping from orientation to animation sequence + // index + for (int ii = 0; ii < _ocount; ii++) { + _orients.put(actseq.orients[ii], ii); + } + } + + // documentation inherited from interface + public int getOrientationCount () + { + return _ocount; + } + + // documentation inherited from interface + public TrimmedMultiFrameImage getFrames (final int orient) + { + return new TrimmedMultiFrameImage() { + // documentation inherited + public int getFrameCount () + { + return _fcount; + } + + // documentation inherited from interface + public int getWidth (int index) + { + Tile tile = getTile(orient, index); + return (tile == null) ? 0 : tile.getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) + { + Tile tile = getTile(orient, index); + return (tile == null) ? 0 : tile.getHeight(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) + { + Tile tile = getTile(orient, index); + if (tile != null) { + tile.paint(g, x, y); + } + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) + { + Tile tile = getTile(orient, index); + return (tile != null) ? tile.hitTest(x, y) : false; + } + + // documentation inherited from interface + public void getTrimmedBounds (int index, Rectangle bounds) + { + Tile tile = getTile(orient, index); + if (tile instanceof TrimmedTile) { + ((TrimmedTile)tile).getTrimmedBounds(bounds); + } else { + bounds.setBounds( + 0, 0, tile.getWidth(), tile.getHeight()); + } + } + }; + } + + // documentation inherited from interface + public int getXOrigin (int orient, int index) + { + return _actseq.origin.x; + } + + // documentation inherited from interface + public int getYOrigin (int orient, int index) + { + return _actseq.origin.y; + } + + // documentation inherited from interface + public ActionFrames cloneColorized (Colorization[] zations) + { + return new TileSetFrameImage(_set.clone(zations), _actseq); + } + + /** + * Fetches the requested tile. + */ + protected Tile getTile (int orient, int index) + { + int tileIndex = _orients.get(orient) * _fcount + index; + return _set.getTile(tileIndex); + } + + /** The tileset from which we obtain our frame images. */ + protected TileSet _set; + + /** The action sequence for which we're providing frame images. */ + protected ActionSequence _actseq; + + /** Frame and orientation counts. */ + protected int _fcount, _ocount; + + /** A mapping from orientation code to animation sequence + * index. */ + protected IntIntMap _orients = new IntIntMap(); + } + + /** We use the image manager to decode and cache images. */ + protected ImageManager _imgr; + + /** A table of action sequences. */ + protected HashMap _actions; + + /** A table of action sequence tilesets. */ + protected HashMap _actionSets; + + /** A table of component classes. */ + protected HashMap _classes; + + /** A table of component lists indexed on classname. */ + protected HashMap _classComps = new HashMap(); + + /** The component table. */ + protected HashIntMap _components = new HashIntMap(); + + /** Whether or not we wipe our bundles on any failure. */ + protected boolean _wipeOnFailure; +} diff --git a/src/java/com/threerings/cast/bundle/tools/ComponentBundlerTask.java b/src/java/com/threerings/cast/bundle/tools/ComponentBundlerTask.java new file mode 100644 index 00000000..5b2b8449 --- /dev/null +++ b/src/java/com/threerings/cast/bundle/tools/ComponentBundlerTask.java @@ -0,0 +1,624 @@ +// +// $Id: ComponentBundlerTask.java 4145 2006-05-24 01:24:24Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle.tools; + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.ObjectOutputStream; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import java.util.jar.JarOutputStream; +import java.util.jar.JarEntry; +import java.util.zip.Deflater; + +import org.apache.commons.digester.Digester; + +import com.samskivert.io.PersistenceException; +import com.samskivert.util.ComparableArrayList; +import com.samskivert.util.FileUtil; +import com.samskivert.util.HashIntMap; +import com.samskivert.util.Tuple; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; + +import com.threerings.media.tile.ImageProvider; +import com.threerings.media.tile.SimpleCachingImageProvider; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TrimmedTileSet; +import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet; + +import com.threerings.cast.ComponentIDBroker; +import com.threerings.cast.StandardActions; +import com.threerings.cast.bundle.BundleUtil; +import com.threerings.cast.tools.xml.ActionRuleSet; + +/** + * Ant task for creating component bundles. This task must be configured + * with a number of parameters: + * + *

+ * target=[path to bundle file, which will be created]
+ * mapfile=[path to the component map file which maintains a mapping from
+ *          component id to component class/name, it will be created the
+ *          first time and updated as new components are mapped]
+ * 
+ * + * It should also contain one or more nested <fileset> elements that + * enumerate the action tileset images that should be included in the + * component bundle. + */ +public class ComponentBundlerTask extends Task +{ + /** + * Sets the path to the bundle file that we'll be creating. + */ + public void setTarget (File target) + { + _target = target; + } + + /** + * Sets the path to the component map file that we'll use to obtain + * component ids for the bundled components. + */ + public void setMapfile (File mapfile) + { + _mapfile = mapfile; + } + + /** + * Sets the path to the action tilesets definition file. + */ + public void setActiondef (File actiondef) + { + _actionDef = actiondef; + } + + /** + * Sets the root path which will be stripped from the image paths + * prior to parsing them to obtain the component class, type and + * action names. + */ + public void setRoot (File root) + { + _root = root.getPath(); + } + + /** + * Adds a nested <fileset> element. + */ + public void addFileset (FileSet set) + { + _filesets.add(set); + } + + /** + * Performs the actual work of the task. + */ + public void execute () throws BuildException + { + // make sure everything was set up properly + ensureSet(_target, "Must specify the path to the target bundle " + + "file via the 'target' attribute."); + ensureSet(_mapfile, "Must specify the path to the component map " + + "file via the 'mapfile' attribute."); + ensureSet(_actionDef, "Must specify the action sequence " + + "definitions via the 'actiondef' attribute."); + + // parse in the action tilesets + HashMap actsets = parseActionTileSets(); + + // load up our component ID broker + ComponentIDBroker broker = loadBroker(_mapfile); + + // check to see if any of the source files are newer than the + // target file + ArrayList sources = (ArrayList)_filesets.clone(); + sources.add(_mapfile); + sources.add(_actionDef); + if (!outOfDate(sources, _target)) { + System.out.println(_target.getPath() + " is up to date."); + return; + } + + // create an image provider for loading our component images + ImageProvider improv = new SimpleCachingImageProvider() { + protected BufferedImage loadImage (String path) + throws IOException { + return ImageIO.read(new File(path)); + } + }; + + System.out.println("Generating " + _target.getPath() + "..."); + + try { + // make sure we can create our bundle file + FileOutputStream fout = new FileOutputStream(_target); + JarOutputStream jout = new JarOutputStream(fout); + jout.setLevel(Deflater.BEST_COMPRESSION); + + // we'll fill this with component id to tuple mappings + HashIntMap mapping = new HashIntMap(); + + // herein we'll insert trimmed tileset objects that go along + // with each of the trimmed action images + HashIntMap actionSets = new HashIntMap(); + + // deal with the filesets + for (int i = 0; i < _filesets.size(); i++) { + FileSet fs = (FileSet)_filesets.get(i); + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + File fromDir = fs.getDir(getProject()); + String[] srcFiles = ds.getIncludedFiles(); + + for (int f = 0; f < srcFiles.length; f++) { + File cfile = new File(fromDir, srcFiles[f]); + // determine the [class, name, action] triplet + String[] info = decomposePath(cfile.getPath()); + + // make sure we have an action tileset definition + TileSet aset = (TileSet)actsets.get(info[2]); + if (aset == null) { + System.err.println( + "No tileset definition for component action " + + "[class=" + info[0] + ", name=" + info[1] + + ", action=" + info[2] + "]."); + continue; + } + aset.setImageProvider(improv); + + // obtain the component id from our id broker + int cid = broker.getComponentID(info[0], info[1]); + // add a mapping for this component + mapping.put(cid, new Tuple(info[0], info[1])); + + // process and store the main component image + processComponent(info, aset, cfile, jout); + + // pick up any auxiliary images as well like the shadow or + // crop files + String action = info[2]; + String ext = BundleUtil.IMAGE_EXTENSION; + for (int aa = 0; aa < AUX_EXTS.length; aa++) { + File afile = new File( + FileUtil.resuffix(cfile, ext, AUX_EXTS[aa] + ext)); + if (afile.exists()) { + info[2] = action + AUX_EXTS[aa]; + processComponent(info, aset, afile, jout); + } + } + } + } + + // write our mapping table to the jar file as well + jout.putNextEntry(new JarEntry(BundleUtil.COMPONENTS_PATH)); + ObjectOutputStream oout = new ObjectOutputStream(jout); + oout.writeObject(mapping); + oout.flush(); + + // seal up our jar file + jout.close(); + + } catch (IOException ioe) { + String errmsg = "Unable to create component bundle."; + throw new BuildException(errmsg, ioe); + + } catch (PersistenceException pe) { + String errmsg = "Unable to obtain component ID mapping."; + throw new BuildException(errmsg, pe); + } + + // save our updated component ID broker + saveBroker(_mapfile, broker); + } + + protected void processComponent ( + String[] info, TileSet aset, File cfile, JarOutputStream jout) + throws IOException + { + // construct the path that'll go in the jar file + String ipath = composePath( + info, BundleUtil.IMAGE_EXTENSION); + jout.putNextEntry(new JarEntry(ipath)); + + // create a trimmed tileset based on the source action tileset and + // stuff the new trimmed image into the jar file at the same time + aset.setImagePath(cfile.getPath()); + + TrimmedTileSet tset = null; + try { + tset = TrimmedTileSet.trimTileSet(aset, jout); + tset.setImagePath(ipath); + } catch (Throwable t) { + System.err.println( + "Failure trimming tileset " + + "[class=" + info[0] + ", name=" + info[1] + + ", action=" + info[2] + + ", srcimg=" + aset.getImagePath() + "]."); + t.printStackTrace(System.err); + } + + // then write our trimmed tileset to the jar file + if (tset != null) { + String tpath = composePath( + info, BundleUtil.TILESET_EXTENSION); + jout.putNextEntry(new JarEntry(tpath)); + ObjectOutputStream oout = new ObjectOutputStream(jout); + oout.writeObject(tset); + oout.flush(); + } + } + + protected boolean outOfDate (ArrayList sources, File target) + { + for (int ii = 0; ii < sources.size(); ii++) { + if (outOfDate(sources.get(ii), target)) { + return true; + } + } + return false; + } + + protected boolean outOfDate (Object source, File target) + { + if (source instanceof FileSet) { + FileSet fs = (FileSet)source; + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + File fromDir = fs.getDir(getProject()); + String[] srcFiles = ds.getIncludedFiles(); + for (int f = 0; f < srcFiles.length; f++) { + File cfile = new File(fromDir, srcFiles[f]); + if (newer(cfile, target)) { + return true; + } + } + return false; + + } else if (source instanceof File) { + return newer((File)source, target); + + } else { + System.err.println("Can't compare " + source + + " to " + target + "."); + return true; + } + } + + /** + * Returns true if source is newer than + * target. + */ + protected boolean newer (File source, File target) + { + return source.lastModified() > target.lastModified(); + } + + /** + * Decomposes the full path to a component image into a [class, name, + * action] triplet. + */ + protected String[] decomposePath (String path) + throws BuildException + { + // first strip off the root + if (!path.startsWith(_root)) { + throw new BuildException("Can't bundle images outside the " + + "root directory [root=" + _root + + ", path=" + path + "]."); + } + path = path.substring(_root.length()); + + // strip off any preceding slash + if (path.startsWith("/")) { + path = path.substring(1); + } + + // now strip off the file extension + if (!path.endsWith(BundleUtil.IMAGE_EXTENSION)) { + throw new BuildException("Can't bundle malformed image file " + + "[path=" + path + "]."); + } + path = path.substring(0, path.length() - + BundleUtil.IMAGE_EXTENSION.length()); + + // now decompose the path; the component type and action must + // always be a single string but the class can span multiple + // directories for easier component organization; thus + // "male/head/goatee/standing" will be parsed as [class=male/head, + // type=goatee, action=standing] + String malmsg = "Can't decode malformed image path: '" + path + "'"; + String[] info = new String[3]; + int lsidx = path.lastIndexOf(File.separator); + if (lsidx == -1) { + throw new BuildException(malmsg); + } + info[2] = path.substring(lsidx+1); + int slsidx = path.lastIndexOf(File.separator, lsidx-1); + if (slsidx == -1) { + throw new BuildException(malmsg); + } + info[1] = path.substring(slsidx+1, lsidx); + info[0] = path.substring(0, slsidx); + return info; + } + + /** + * Composes a triplet of [class, name, action] into the path that + * should be supplied to the JarEntry that contains the associated + * image data. + */ + protected String composePath (String[] info, String extension) + { + return (info[0] + File.separator + info[1] + + File.separator + info[2] + extension); + } + + protected void ensureSet (Object value, String errmsg) + throws BuildException + { + if (value == null) { + throw new BuildException(errmsg); + } + } + + /** + * Parses the action tileset definitions and puts them into a hash + * map, keyed on action name. + */ + protected HashMap parseActionTileSets () + { + Digester digester = new Digester(); + SwissArmyTileSetRuleSet srules = new SwissArmyTileSetRuleSet(); + String aprefix = "actions" + ActionRuleSet.ACTION_PATH; + srules.setPrefix(aprefix); + + digester.addRuleSet(srules); + digester.addSetProperties(aprefix); + digester.addSetNext(aprefix + SwissArmyTileSetRuleSet.TILESET_PATH, + "addTileSet", TileSet.class.getName()); + + HashMap actsets = new ActionMap(); + digester.push(actsets); + + try { + FileInputStream fin = new FileInputStream(_actionDef); + BufferedInputStream bin = new BufferedInputStream(fin); + digester.parse(bin); + + } catch (FileNotFoundException fnfe) { + String errmsg = "Unable to load action definition file " + + "[path=" + _actionDef.getPath() + "]."; + throw new BuildException(errmsg, fnfe); + + } catch (Exception e) { + throw new BuildException("Parsing error.", e); + } + + return actsets; + } + + /** Used when parsing action tilesets. */ + public static class ActionMap extends HashMap + { + public void setName (String name) { + _name = name; + } + public void addTileSet (TileSet set) { + set.setName(_name); + put(_name, set); + } + protected String _name; + } + + /** + * Loads the hashmap ID broker from its persistent representation in + * the specified file. + */ + protected HashMapIDBroker loadBroker (File mapfile) + throws BuildException + { + HashMapIDBroker broker = new HashMapIDBroker(); + + try { + BufferedReader bin = new BufferedReader(new FileReader(mapfile)); + broker.readFrom(bin); + bin.close(); + + } catch (FileNotFoundException fnfe) { + // if the file doesn't yet exist, start with a blank broker + + } catch (Exception e) { + throw new BuildException("Error loading component ID map " + + "[mapfile=" + mapfile + "]", e); + } + + return broker; + } + + /** + * Stores a persistent representation of the supplied hashmap ID + * broker in the specified file. + */ + protected void saveBroker (File mapfile, ComponentIDBroker broker) + throws BuildException + { + HashMapIDBroker hbroker = (HashMapIDBroker)broker; + + // bail if the broker wasn't modified + if (!hbroker.isModified()) { + return; + } + + try { + BufferedWriter bout = new BufferedWriter(new FileWriter(mapfile)); + hbroker.writeTo(bout); + bout.close(); + } catch (IOException ioe) { + throw new BuildException("Unable to store component ID map " + + "[mapfile=" + mapfile + "]", ioe); + } + } + + protected static class HashMapIDBroker + extends HashMap implements ComponentIDBroker + { + public int getComponentID (String cclass, String cname) + throws PersistenceException + { + Tuple key = new Tuple(cclass, cname); + Integer cid = (Integer)get(key); + if (cid == null) { + cid = Integer.valueOf(++_nextCID); + put(key, cid); + } + return cid.intValue(); + } + + public void commit () + throws PersistenceException + { + // nothing doing + } + + public boolean isModified () + { + return _nextCID != _startCID; + } + + public void writeTo (BufferedWriter bout) + throws IOException + { + // write out our most recently assigned component id + String cidline = "" + _nextCID; + bout.write(cidline, 0, cidline.length()); + bout.newLine(); + + // write out the keys and values + ComparableArrayList lines = new ComparableArrayList(); + Iterator keys = keySet().iterator(); + while (keys.hasNext()) { + Tuple key = (Tuple)keys.next(); + Integer value = (Integer)get(key); + String line = key.left + SEP_STR + key.right + SEP_STR + value; + lines.add(line); + } + + // sort the output + lines.sort(); + + // now write it to the file + int lcount = lines.size(); + for (int ii = 0; ii < lcount; ii++) { + String line = (String)lines.get(ii); + bout.write(line, 0, line.length()); + bout.newLine(); + } + } + + public void readFrom (BufferedReader bin) + throws IOException + { + // read in our most recently assigned component id + _nextCID = readInt(bin); + // keep track of this so that we can tell if we were modified + _startCID = _nextCID; + + // now read in our keys and values + String line; + while ((line = bin.readLine()) != null) { + String orig = line; + int sidx = line.indexOf(SEP_STR); + if (sidx == -1) { + throw new IOException("Malformed line '" + orig + "'"); + } + String cclass = line.substring(0, sidx); + line = line.substring(sidx + SEP_STR.length()); + sidx = line.indexOf(SEP_STR); + if (sidx == -1) { + throw new IOException("Malformed line '" + orig + "'"); + } + String cname = line.substring(0, sidx); + line = line.substring(sidx + SEP_STR.length()); + try { + put(new Tuple(cclass, cname), Integer.valueOf(line)); + } catch (NumberFormatException nfe) { + String err = "Malformed line, invalid code '" + orig + "'"; + throw new IOException(err); + } + } + } + + protected int readInt (BufferedReader bin) + throws IOException + { + String line = bin.readLine(); + try { + return Integer.parseInt(line); + } catch (NumberFormatException nfe) { + throw new IOException("Expected number, got '" + line + "'"); + } + } + + protected int _nextCID = 0; + protected int _startCID = 0; + } + + /** The path to our component bundle file. */ + protected File _target; + + /** The path to our component map file. */ + protected File _mapfile; + + /** The path to our action tilesets definition file. */ + protected File _actionDef; + + /** The component directory root. */ + protected String _root; + + /** A list of filesets that contain tile images. */ + protected ArrayList _filesets = new ArrayList(); + + /** Used to separate keys and values in the map file. */ + protected static final String SEP_STR = " := "; + + /** Used to process auxilliary tilesets. */ + protected static final String[] AUX_EXTS = { + "_" + StandardActions.SHADOW_TYPE, + "_" + StandardActions.CROP_TYPE }; +} diff --git a/src/java/com/threerings/cast/bundle/tools/DumpBundle.java b/src/java/com/threerings/cast/bundle/tools/DumpBundle.java new file mode 100644 index 00000000..82f0f800 --- /dev/null +++ b/src/java/com/threerings/cast/bundle/tools/DumpBundle.java @@ -0,0 +1,84 @@ +// +// $Id: DumpBundle.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle.tools; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +import com.threerings.resource.ResourceBundle; +import com.threerings.cast.bundle.BundleUtil; + +/** + * Dumps the contents of a component bundle to stdout. + */ +public class DumpBundle +{ + public static void main (String[] args) + { + if (args.length < 1) { + String usage = "Usage: DumpBundle bundle.jar [bundle.jar ...]"; + System.err.println(usage); + System.exit(-1); + } + + for (int i = 0; i < args.length; i++) { + File file = new File(args[i]); + try { + ResourceBundle bundle = new ResourceBundle(file); + + HashMap actions = (HashMap)BundleUtil.loadObject( + bundle, BundleUtil.ACTIONS_PATH, false); + dumpTable("actions: ", actions); + + HashMap actionSets = (HashMap)BundleUtil.loadObject( + bundle, BundleUtil.ACTION_SETS_PATH, false); + dumpTable("actionSets: ", actionSets); + + HashMap classes = (HashMap)BundleUtil.loadObject( + bundle, BundleUtil.CLASSES_PATH, false); + dumpTable("classes: ", classes); + + HashIntMap comps = (HashIntMap)BundleUtil.loadObject( + bundle, BundleUtil.COMPONENTS_PATH, false); + dumpTable("components: ", comps); + + } catch (Exception e) { + System.err.println("Error dumping bundle [path=" + args[i] + + ", error=" + e + "]."); + e.printStackTrace(); + } + } + } + + protected static void dumpTable (String prefix, Map table) + { + if (table != null) { + Iterator iter = table.entrySet().iterator(); + System.out.println(prefix + StringUtil.toString(iter)); + } + } +} diff --git a/src/java/com/threerings/cast/bundle/tools/MetadataBundlerTask.java b/src/java/com/threerings/cast/bundle/tools/MetadataBundlerTask.java new file mode 100644 index 00000000..186cde0a --- /dev/null +++ b/src/java/com/threerings/cast/bundle/tools/MetadataBundlerTask.java @@ -0,0 +1,267 @@ +// +// $Id: MetadataBundlerTask.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle.tools; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +import java.util.ArrayList; +import java.util.HashMap; + +import java.util.jar.JarOutputStream; +import java.util.jar.JarEntry; +import java.util.zip.Deflater; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import org.apache.commons.digester.Digester; + +import com.samskivert.util.Tuple; + +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet; + +import com.threerings.cast.ActionSequence; +import com.threerings.cast.ComponentClass; +import com.threerings.cast.bundle.BundleUtil; + +import com.threerings.cast.tools.xml.ActionRuleSet; +import com.threerings.cast.tools.xml.ClassRuleSet; + +/** + * Ant task for creating metadata bundles, which contain action sequence + * and component class definition information. This task must be + * configured with a number of parameters: + * + *
+ * actiondef=[path to actions.xml]
+ * classdef=[path to classes.xml]
+ * file=[path to metadata bundle, which will be created]
+ * 
+ */ +public class MetadataBundlerTask extends Task +{ + public void setActiondef (String actiondef) + { + _actionDef = actiondef; + } + + public void setClassdef (String classdef) + { + _classDef = classdef; + } + + public void setTarget (File target) + { + _target = target; + } + + /** + * Performs the actual work of the task. + */ + public void execute () + throws BuildException + { + // make sure everythign was set up properly + ensureSet(_actionDef, "Must specify the action sequence " + + "definitions via the 'actiondef' attribute."); + ensureSet(_classDef, "Must specify the component class definitions " + + "via the 'classdef' attribute."); + ensureSet(_target, "Must specify the path to the target bundle " + + "file via the 'target' attribute."); + + // make sure we can write to the target bundle file + FileOutputStream fout = null; + try { + fout = new FileOutputStream(_target); + + // parse our metadata + Tuple tuple = parseActions(); + HashMap actions = (HashMap)tuple.left; + HashMap actionSets = (HashMap)tuple.right; + HashMap classes = parseClasses(); + + // and create the bundle file + JarOutputStream jout = new JarOutputStream(fout); + jout.setLevel(Deflater.BEST_COMPRESSION); + + // throw the serialized actions table in there + JarEntry aentry = new JarEntry(BundleUtil.ACTIONS_PATH); + jout.putNextEntry(aentry); + ObjectOutputStream oout = new ObjectOutputStream(jout); + oout.writeObject(actions); + oout.flush(); + + // throw the serialized action tilesets table in there + JarEntry sentry = new JarEntry(BundleUtil.ACTION_SETS_PATH); + jout.putNextEntry(sentry); + oout = new ObjectOutputStream(jout); + oout.writeObject(actionSets); + oout.flush(); + + // throw the serialized classes table in there + JarEntry centry = new JarEntry(BundleUtil.CLASSES_PATH); + jout.putNextEntry(centry); + oout = new ObjectOutputStream(jout); + oout.writeObject(classes); + oout.flush(); + + // close it up and we're done + jout.close(); + + } catch (IOException ioe) { + String errmsg = "Unable to output to target bundle " + + "[path=" + _target.getPath() + "]."; + throw new BuildException(errmsg, ioe); + + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException ioe) { + // nothing to complain about here + } + } + } + } + + protected Tuple parseActions () + throws BuildException + { + // scan through the XML once to read the actions + Digester digester = new Digester(); + ActionRuleSet arules = new ActionRuleSet(); + arules.setPrefix("actions"); + digester.addRuleSet(arules); + digester.addSetNext("actions" + ActionRuleSet.ACTION_PATH, + "add", Object.class.getName()); + ArrayList actlist = parseList(digester, _actionDef); + + // now go through a second time reading the tileset info + digester = new Digester(); + SwissArmyTileSetRuleSet srules = new SwissArmyTileSetRuleSet(); + srules.setPrefix("actions" + ActionRuleSet.ACTION_PATH); + digester.addRuleSet(srules); + digester.addSetNext("actions" + ActionRuleSet.ACTION_PATH + + SwissArmyTileSetRuleSet.TILESET_PATH, "add", + Object.class.getName()); + ArrayList setlist = parseList(digester, _actionDef); + + // sanity check + if (actlist.size() != setlist.size()) { + String errmsg = "An action is missing its tileset " + + "definition, or something even wackier is going on."; + throw new BuildException(errmsg); + } + + // now create our mappings + HashMap actmap = new HashMap(); + HashMap setmap = new HashMap(); + + // create the action map + for (int i = 0; i < setlist.size(); i++) { + TileSet set = (TileSet)setlist.get(i); + ActionSequence act = (ActionSequence)actlist.get(i); + // make sure nothing was missing in the action sequence + // definition parsed from XML + String errmsg = ActionRuleSet.validate(act); + if (errmsg != null) { + errmsg = "Action sequence invalid [seq=" + act + + ", error=" + errmsg + "]."; + throw new BuildException(errmsg); + } + actmap.put(act.name, act); + setmap.put(act.name, set); + } + + return new Tuple(actmap, setmap); + } + + protected HashMap parseClasses () + throws BuildException + { + // load up our action and class info + Digester digester = new Digester(); + + // add our action rule set and a a rule to grab parsed actions + ClassRuleSet crules = new ClassRuleSet(); + crules.setPrefix("classes"); + digester.addRuleSet(crules); + digester.addSetNext("classes" + ClassRuleSet.CLASS_PATH, + "add", Object.class.getName()); + + ArrayList setlist = parseList(digester, _classDef); + HashMap clmap = new HashMap(); + + // create the action map + for (int i = 0; i < setlist.size(); i++) { + ComponentClass cl = (ComponentClass)setlist.get(i); + clmap.put(cl.name, cl); + } + + return clmap; + } + + protected ArrayList parseList (Digester digester, String path) + throws BuildException + { + try { + FileInputStream fin = new FileInputStream(path); + BufferedInputStream bin = new BufferedInputStream(fin); + + ArrayList setlist = new ArrayList(); + digester.push(setlist); + + // now fire up the digester to parse the stream + try { + digester.parse(bin); + } catch (Exception e) { + throw new BuildException("Parsing error.", e); + } + + return setlist; + + } catch (FileNotFoundException fnfe) { + String errmsg = "Unable to load metadata definition file " + + "[path=" + path + "]."; + throw new BuildException(errmsg, fnfe); + } + } + + protected void ensureSet (Object value, String errmsg) + throws BuildException + { + if (value == null) { + throw new BuildException(errmsg); + } + } + + protected String _actionDef; + protected String _classDef; + protected File _target; +} diff --git a/src/java/com/threerings/cast/tools/xml/ActionRuleSet.java b/src/java/com/threerings/cast/tools/xml/ActionRuleSet.java new file mode 100644 index 00000000..79fb326e --- /dev/null +++ b/src/java/com/threerings/cast/tools/xml/ActionRuleSet.java @@ -0,0 +1,146 @@ +// +// $Id: ActionRuleSet.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.tools.xml; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.RuleSetBase; + +import com.samskivert.util.StringUtil; + +import com.samskivert.xml.CallMethodSpecialRule; +import com.samskivert.xml.SetFieldRule; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.util.DirectionCodes; +import com.threerings.util.DirectionUtil; + +import com.threerings.cast.ActionSequence; + +/** + * The action rule set is used to parse the attributes of an action + * sequence instance. + */ +public class ActionRuleSet extends RuleSetBase +{ + /** The component of the digester path that is appended by the action + * rule set to match a action. This is appended to whatever prefix is + * provided to the action rule set to obtain the complete XML path to + * a matched action. */ + public static final String ACTION_PATH = "/action"; + + /** + * Instructs the action rule set to match actions with the supplied + * prefix. For example, passing a prefix of actions will + * match actions in the following XML file: + * + *
+     * <actions>
+     *   <action>
+     *     // ...
+     *   </action>
+     * </actions>
+     * 
+ * + * This must be called before adding the ruleset to a digester. + */ + public void setPrefix (String prefix) + { + _prefix = prefix; + } + + /** + * Adds the necessary rules to the digester to parse our actions. + */ + public void addRuleInstances (Digester digester) + { + // this creates the appropriate instance when we encounter a + // tag + digester.addObjectCreate(_prefix + ACTION_PATH, + ActionSequence.class.getName()); + + // grab the name attribute from the tag + digester.addRule(_prefix + ACTION_PATH, new SetPropertyFieldsRule()); + + // grab the other attributes from their respective tags + digester.addRule(_prefix + ACTION_PATH + "/framesPerSecond", + new SetFieldRule("framesPerSecond")); + + CallMethodSpecialRule origin = new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + throws Exception { + int[] coords = StringUtil.parseIntArray(bodyText); + if (coords.length != 2) { + String errmsg = "Invalid specification '" + + bodyText + "'."; + throw new Exception(errmsg); + } + ((ActionSequence)target).origin.setLocation( + coords[0], coords[1]); + } + }; + digester.addRule(_prefix + ACTION_PATH + "/origin", origin); + + CallMethodSpecialRule orient = new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + throws Exception { + ActionSequence seq = ((ActionSequence)target); + String[] ostrs = StringUtil.parseStringArray(bodyText); + seq.orients = new int[ostrs.length]; + for (int ii = 0; ii < ostrs.length; ii++) { + int orient = DirectionUtil.fromShortString(ostrs[ii]); + if (orient != DirectionCodes.NONE) { + seq.orients[ii] = orient; + } else { + String errmsg = "Invalid orientation specification " + + "[index=" + ii + ", orient=" + ostrs[ii] + "]."; + throw new Exception(errmsg); + } + } + } + }; + digester.addRule(_prefix + ACTION_PATH + "/orients", orient); + } + + /** + * Validates that all necessary fields have been parsed and set in + * this action sequence object and are valid. + * + * @return null if the sequence is valid, a string explaining the + * invalidity if it is not. + */ + public static String validate (ActionSequence seq) + { + if (StringUtil.isBlank(seq.name)) { + return "Missing 'name' definition."; + } + if (seq.framesPerSecond == 0) { + return "Missing 'framesPerSecond' definition."; + } + if (seq.orients == null) { + return "Missing 'orients' definition."; + } + return null; + } + + /** The prefix at which me match our actions. */ + protected String _prefix; +} diff --git a/src/java/com/threerings/cast/tools/xml/ClassRuleSet.java b/src/java/com/threerings/cast/tools/xml/ClassRuleSet.java new file mode 100644 index 00000000..49020b32 --- /dev/null +++ b/src/java/com/threerings/cast/tools/xml/ClassRuleSet.java @@ -0,0 +1,110 @@ +// +// $Id: ClassRuleSet.java 3729 2005-10-13 00:00:33Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.tools.xml; + +import java.awt.Color; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.RuleSetBase; + +import com.samskivert.util.ArrayIntSet; +import com.samskivert.util.StringUtil; +import com.samskivert.xml.SetPropertyFieldsRule; +import com.samskivert.xml.SetPropertyFieldsRule.FieldParser; + +import com.threerings.cast.ComponentClass.PriorityOverride; +import com.threerings.cast.ComponentClass; +import com.threerings.util.DirectionUtil; + +/** + * The class rule set is used to parse the attributes of a component class + * instance. + */ +public class ClassRuleSet extends RuleSetBase +{ + /** The component of the digester path that is appended by the class + * rule set to match a component class. This is appended to whatever + * prefix is provided to the class rule set to obtain the complete XML + * path to a matched class. */ + public static final String CLASS_PATH = "/class"; + + /** + * Instructs the class rule set to match component classes with the + * supplied prefix. For example, passing a prefix of + * classes will match classes in the following XML file: + * + *
+     * <classes>
+     *   <class .../>
+     * </classes>
+     * 
+ * + * This must be called before adding the ruleset to a digester. + */ + public void setPrefix (String prefix) + { + _prefix = prefix; + } + + /** + * Adds the necessary rules to the digester to parse our classes. + */ + public void addRuleInstances (Digester digester) + { + // this creates the appropriate instance when we encounter a + // tag + digester.addObjectCreate(_prefix + CLASS_PATH, + ComponentClass.class.getName()); + + // grab the attributes from the tag + SetPropertyFieldsRule rule = new SetPropertyFieldsRule(); + rule.addFieldParser("shadowColor", new FieldParser() { + public Object parse (String text) { + int[] values = StringUtil.parseIntArray(text); + return new Color(values[0], values[1], values[2], values[3]); + } + }); + digester.addRule(_prefix + CLASS_PATH, rule); + + // parse render priority overrides + String opath = _prefix + CLASS_PATH + "/override"; + digester.addObjectCreate(opath, PriorityOverride.class.getName()); + rule = new SetPropertyFieldsRule(); + rule.addFieldParser("orients", new FieldParser() { + public Object parse (String text) { + String[] orients = StringUtil.parseStringArray(text); + ArrayIntSet oset = new ArrayIntSet(); + for (int ii = 0; ii < orients.length; ii++) { + oset.add(DirectionUtil.fromShortString(orients[ii])); + } + return oset; + } + }); + digester.addRule(opath, rule); + + digester.addSetNext(opath, "addPriorityOverride", + PriorityOverride.class.getName()); + } + + /** The prefix at which me match our component classes. */ + protected String _prefix; +} diff --git a/src/java/com/threerings/cast/util/CastUtil.java b/src/java/com/threerings/cast/util/CastUtil.java new file mode 100644 index 00000000..22621c3b --- /dev/null +++ b/src/java/com/threerings/cast/util/CastUtil.java @@ -0,0 +1,97 @@ +// +// $Id: CastUtil.java 4188 2006-06-13 18:03:48Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.util; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.samskivert.util.CollectionUtil; +import com.samskivert.util.RandomUtil; + +import com.threerings.cast.CharacterDescriptor; +import com.threerings.cast.ComponentClass; +import com.threerings.cast.ComponentRepository; +import com.threerings.cast.Log; + +/** + * Miscellaneous cast utility routines. + */ +public class CastUtil +{ + /** + * Returns a new character descriptor populated with a random set of + * components. + */ + public static CharacterDescriptor getRandomDescriptor ( + String gender, ComponentRepository crepo) + { + // get all available classes + ArrayList classes = new ArrayList(); + for (int i = 0; i < CLASSES.length; i++) { + String cname = gender + "/" + CLASSES[i]; + ComponentClass cclass = crepo.getComponentClass(cname); + + // make sure the component class exists + if (cclass == null) { + Log.warning("Missing definition for component class " + + "[class=" + cname + "]."); + continue; + } + + // make sure there are some components in this class + Iterator iter = crepo.enumerateComponentIds(cclass); + if (!iter.hasNext()) { + Log.info("Skipping class for which we have no components " + + "[class=" + cclass + "]."); + continue; + } + + classes.add(cclass); + } + + // select the components + int size = classes.size(); + int components[] = new int[size]; + for (int ii = 0; ii < size; ii++) { + ComponentClass cclass = (ComponentClass)classes.get(ii); + + // get the components available for this class + ArrayList choices = new ArrayList(); + Iterator iter = crepo.enumerateComponentIds(cclass); + CollectionUtil.addAll(choices, iter); + + // choose a random component + if (choices.size() > 0) { + int idx = RandomUtil.getInt(choices.size()); + components[ii] = ((Integer)choices.get(idx)).intValue(); + } else { + Log.info("Have no components in class [class=" + cclass + "]."); + } + } + + return new CharacterDescriptor(components, null); + } + + protected static final String[] CLASSES = { + "legs", "feet", "hand_left", "hand_right", "torso", + "head", "hair", "hat", "eyepatch" }; +} diff --git a/src/java/com/threerings/geom/GeomUtil.java b/src/java/com/threerings/geom/GeomUtil.java new file mode 100644 index 00000000..fc4391a5 --- /dev/null +++ b/src/java/com/threerings/geom/GeomUtil.java @@ -0,0 +1,251 @@ +// +// $Id: GeomUtil.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.geom; + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.Point2D; + +/** + * General geometry utilites. + */ +public class GeomUtil +{ + /** + * Computes and returns the dot product of the two vectors. + * + * @param v1s the starting point of the first vector. + * @param v1e the ending point of the first vector. + * @param v2s the starting point of the second vector. + * @param v2e the ending point of the second vector. + */ + public static int dot (Point v1s, Point v1e, Point v2s, Point v2e) + { + return ((v1e.x - v1s.x) * (v2e.x - v2s.x) + + (v1e.y - v1s.y) * (v2e.y - v2s.y)); + } + + /** + * Computes and returns the dot product of the two vectors. See + * {@link #dot(Point,Point,Point,Point)} for an explanation of the + * arguments + */ + public static int dot (int v1sx, int v1sy, int v1ex, int v1ey, + int v2sx, int v2sy, int v2ex, int v2ey) + { + return ((v1ex - v1sx) * (v2ex - v2sx) + (v1ey - v1sy) * (v2ey - v2sy)); + } + + /** + * Computes and returns the dot product of the two vectors. The + * vectors are assumed to start with the same coordinate and end with + * different coordinates. + * + * @param vs the starting point of both vectors. + * @param v1e the ending point of the first vector. + * @param v2e the ending point of the second vector. + */ + public static int dot (Point vs, Point v1e, Point v2e) + { + return ((v1e.x - vs.x) * (v2e.x - vs.x) + + (v1e.y - vs.y) * (v2e.y - vs.y)); + } + + /** + * Computes and returns the dot product of the two vectors. + * See {@link #dot(Point,Point,Point)} for an explanation of the + * arguments + */ + public static int dot (int vsx, int vsy, int v1ex, int v1ey, + int v2ex, int v2ey) + { + return ((v1ex - vsx) * (v2ex - vsx) + (v1ey - vsy) * (v2ey - vsy)); + } + + /** + * Computes the point nearest to the specified point p3 + * on the line defined by the two points p1 and + * p2. The computed point is stored into n. + * Note: p1 and p2 must not be + * coincident. + * + * @param p1 one point on the line. + * @param p2 another point on the line (not equal to p1). + * @param p3 the point to which we wish to be most near. + * @param n the point on the line defined by p1 and + * p2 that is nearest to p. + * + * @return the point object supplied via n. + */ + public static Point nearestToLine (Point p1, Point p2, Point p3, Point n) + { + // see http://astronomy.swin.edu.au/~pbourke/geometry/pointline/ + // for a (not very good) explanation of the math + int Ax = p2.x - p1.x, Ay = p2.y - p1.y; + float u = (p3.x - p1.x) * Ax + (p3.y - p1.y) * Ay; + u /= (Ax * Ax + Ay * Ay); + n.x = p1.x + Math.round(Ax * u); + n.y = p1.y + Math.round(Ay * u); + return n; + } + + /** + * Calculate the intersection of two lines. Either line may be + * considered as a line segment, and the intersecting point + * is only considered valid if it lies upon the segment. + * Note that Point extends Point2D. + * + * @param p1 and p2 the coordinates of the first line. + * @param seg1 if the first line should be considered a segment. + * @param p3 and p4 the coordinates of the second line. + * @param seg2 if the second line should be considered a segment. + * @param result the point that will be filled in with the intersecting + * point. + * + * @return true if result was filled in, or false if the lines + * are parallel or the point of intersection lies outside of a + * segment. + */ + public static boolean lineIntersection ( + Point2D p1, Point2D p2, boolean seg1, + Point2D p3, Point2D p4, boolean seg2, Point2D result) + { + // see http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ + double y43 = p4.getY() - p3.getY(); + double x21 = p2.getX() - p1.getX(); + double x43 = p4.getX() - p3.getX(); + double y21 = p2.getY() - p1.getY(); + double denom = y43 * x21 - x43 * y21; + if (denom == 0) { + return false; + } + + double y13 = p1.getY() - p3.getY(); + double x13 = p1.getX() - p3.getX(); + double ua = (x43 * y13 - y43 * x13) / denom; + if (seg1 && ((ua < 0) || (ua > 1))) { + return false; + } + + if (seg2) { + double ub = (x21 * y13 - y21 * x13) / denom; + if ((ub < 0) || (ub > 1)) { + return false; + } + } + + double x = p1.getX() + ua * x21; + double y = p1.getY() + ua * y21; + result.setLocation(x, y); + return true; + } + + /** + * Returns less than zero if p2 is on the left hand side + * of the line created by p1 and theta and + * greater than zero if it is on the right hand side. In theory, it + * will return zero if the point is on the line, but due to rounding + * errors it almost always decides that it's not exactly on the line. + * + * @param p1 the point on the line whose side we're checking. + * @param theta the (logical) angle defining the line. + * @param p2 the point that lies on one side or the other of the line. + */ + public static int whichSide (Point p1, double theta, Point p2) + { + // obtain the point defining the right hand normal (N) + theta += Math.PI/2; + int x = p1.x + (int)Math.round(1000*Math.cos(theta)), + y = p1.y + (int)Math.round(1000*Math.sin(theta)); + + // now dot the vector from p1->p2 with the vector from p1->N, if + // it's positive, we're on the right hand side, if it's negative + // we're on the left hand side and if it's zero, we're on the line + return dot(p1.x, p1.y, p2.x, p2.y, x, y); + } + + /** + * Shifts the position of the tainer rectangle to ensure + * that it contains the tained rectangle. The + * tainer rectangle must be larger than or equal to the + * size of the tained rectangle. + */ + public static void shiftToContain (Rectangle tainer, Rectangle tained) + { + if (tained.x < tainer.x) { + tainer.x = tained.x; + } + if (tained.y < tainer.y) { + tainer.y = tained.y; + } + if (tained.x + tained.width > tainer.x + tainer.width) { + tainer.x = tained.x - (tainer.width - tained.width); + } + if (tained.y + tained.height > tainer.y + tainer.height) { + tainer.y = tained.y - (tainer.height - tained.height); + } + } + + /** + * Adds the target rectangle to the bounds of the source rectangle. If + * the source rectangle is null, a new rectangle is created that is the + * size of the target rectangle. + * + * @return the source rectangle. + */ + public static Rectangle grow (Rectangle source, Rectangle target) + { + if (target == null) { + Log.warning("Can't grow with null rectangle [src=" + source + + ", tgt=" + target + "]."); + Thread.dumpStack(); + } else if (source == null) { + source = new Rectangle(target); + } else { + source.add(target); + } + return source; + } + + /** + * Returns the rectangle containing the specified tile in the supplied + * larger rectangle. Tiles go from left to right, top to bottom. + */ + public static Rectangle getTile ( + int width, int height, int tileWidth, int tileHeight, int tileIndex) + { + // figure out from whence to crop the tile + int tilesPerRow = width / tileWidth; + + // if we got a bogus region, return bogus tile bounds + if (tilesPerRow == 0) { + return new Rectangle(0, 0, width, height); + } + + int row = tileIndex / tilesPerRow; + int col = tileIndex % tilesPerRow; + + // crop the tile-sized image chunk from the full image + return new Rectangle( + tileWidth*col, tileHeight*row, tileWidth, tileHeight); + } +} diff --git a/src/java/com/threerings/geom/Log.java b/src/java/com/threerings/geom/Log.java new file mode 100644 index 00000000..96e630f6 --- /dev/null +++ b/src/java/com/threerings/geom/Log.java @@ -0,0 +1,63 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.geom; + +/** + * A placeholder class that contains a reference to the log object used by + * this package. + */ +public class Log +{ + public static final String PACKAGE = "geom"; + + public static com.samskivert.util.Log log = + new com.samskivert.util.Log(PACKAGE); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } + + public static int getLevel () + { + return com.samskivert.util.Log.getLevel(PACKAGE); + } +} diff --git a/src/java/com/threerings/jme/JmeApp.java b/src/java/com/threerings/jme/JmeApp.java new file mode 100644 index 00000000..d80cc5d2 --- /dev/null +++ b/src/java/com/threerings/jme/JmeApp.java @@ -0,0 +1,582 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme; + +import java.io.File; + +import com.samskivert.util.Queue; +import com.samskivert.util.RunQueue; +import com.samskivert.util.StringUtil; + +import com.jme.renderer.Camera; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; + +import com.jme.scene.Node; +import com.jme.scene.state.LightState; +import com.jme.scene.state.ZBufferState; + +import com.jme.system.DisplaySystem; +import com.jme.system.JmeException; +import com.jme.system.PropertiesIO; +import com.jme.system.lwjgl.LWJGLPropertiesDialog; + +import com.jme.input.InputHandler; +import com.jme.input.KeyInput; +import com.jme.input.Mouse; +import com.jme.input.MouseInput; +import com.jmex.bui.BRootNode; +import com.jmex.bui.PolledRootNode; + +import com.jme.light.PointLight; +import com.jme.math.Vector3f; +import com.jme.util.Timer; + +import com.threerings.jme.camera.CameraHandler; + +/** + * Defines a basic application framework providing integration with the + *
Presents networking system and + * targeting the framerate of the display. + */ +public class JmeApp + implements RunQueue +{ + /** + * Returns a context implementation that provides access to all the + * necessary bits. + */ + public JmeContext getContext () + { + return _ctx; + } + + /** + * Does the main initialization of the application. This method should + * be called first, and then the {@link #run} method should be called + * to begin the rendering/event loop. Derived classes can override + * this, being sure to call super before doing their own + * initalization. + * + * @return true if the application initialized successfully, false if + * initialization failed. (See {@link #reportInitFailure}.) + */ + public boolean init () + { + try { + // initialize the rendering system + initDisplay(); + if (!_display.isCreated()) { + throw new IllegalStateException( + "Failed to initialize display?"); + } + + // create an appropriate timer + _timer = Timer.getTimer(); + + // start with the target FPS equal to the refresh rate (but + // sometimes the refresh rate is reported as zero so don't let that + // freak us out) + setTargetFPS(Math.max(_display.getFrequency(), 60)); + + // initialize our main camera controls and user input handling + initInput(); + + // initialize the root node + initRoot(); + + // initialize the lighting + initLighting(); + + // initialize the UI support stuff + initInterface(); + + // update everything for the zeroth tick + _iface.updateRenderState(); + _geom.updateRenderState(); + _root.updateGeometricState(0f, true); + _root.updateRenderState(); + + return true; + + } catch (Throwable t) { + reportInitFailure(t); + return false; + } + } + + /** + * Configures whether or not we display FPS and other statistics atop the + * display. + */ + public void displayStatistics (boolean display) + { + if (display && (_stats == null)) { + _stats = new StatsDisplay(_display.getRenderer()); + _stats.updateGeometricState(0f, true); + _stats.updateRenderState(); + } else if (!display && (_stats != null)) { + _stats = null; + } + } + + /** + * Returns true if we are displaying statistics, false if not. + */ + public boolean showingStatistics () + { + return (_stats != null); + } + + /** + * Sets the target frames per second. + * + * @return the old target frames per second. + */ + public int setTargetFPS (int targetFPS) + { + int oldTargetFPS = _targetFPS; + _targetFPS = targetFPS; + _ticksPerFrame = _timer.getResolution() / _targetFPS; + return oldTargetFPS; + } + + /** + * Returns the frames per second averaged over the last 32 frames. + */ + public float getRecentFrameRate () + { + return _timer.getFrameRate(); + } + + /** + * Enables or disables the update and render part of the + * update/render/process events application loop. + */ + public void setEnabled (boolean update, boolean render) + { + _updateEnabled = update; + _renderEnabled = render; + } + + /** + * Starts up the main rendering and event processing loop. This method + * will not return until the application is terminated with a call to + * {@link #stop}. + */ + public void run () + { + synchronized (this) { + _dispatchThread = Thread.currentThread(); + } + + // enter the main rendering and event processing loop + while (!_finished && !_display.isClosing()) { + try { + // render the current frame + long frameStart = processFrame(); + + // and process events until it's time to render the next + PROCESS_EVENTS: + do { + Runnable r = (Runnable)_evqueue.getNonBlocking(); + if (r != null) { + r.run(); + } + if (_timer.getTime() - frameStart >= _ticksPerFrame) { + break PROCESS_EVENTS; + } else { + try { + Thread.sleep(1); + } catch (InterruptedException ie) { + } + } + } while (!_finished); + _failures = 0; + + } catch (Throwable t) { + Log.logStackTrace(t); + // stick a fork in things if we fail too many times in a row + if (++_failures > MAX_SUCCESSIVE_FAILURES) { + stop(); + } + } + } + + try { + cleanup(); + } catch (Throwable t) { + Log.logStackTrace(t); + } finally { + exit(); + } + } + + /** + * Returns the duration (in seconds) between the previous frame and the + * current frame. + */ + public float getFrameTime () + { + return _frameTime; + } + + /** + * Instructs the application to stop the main loop, cleanup and exit. + */ + public void stop () + { + _finished = true; + } + + // documentation inherited from interface RunQueue + public void postRunnable (Runnable r) + { + _evqueue.append(r); + } + + // documentation inherited from interface RunQueue + public boolean isDispatchThread () + { + return Thread.currentThread() == _dispatchThread; + } + + /** + * Determines the display configuration and creates the display. This must + * fill in {@link #_api} as a side-effect. + */ + protected DisplaySystem createDisplay () + { + PropertiesIO props = new PropertiesIO(getConfigPath("jme.cfg")); + if (!props.load()) { + LWJGLPropertiesDialog dialog = + new LWJGLPropertiesDialog(props, (String)null); + while (dialog.isVisible()) { + try { + Thread.sleep(5); + } catch (InterruptedException e) { + Log.warning("Error waiting for dialog system, " + + "using defaults."); + } + } + } + _api = props.getRenderer(); + DisplaySystem display = DisplaySystem.getDisplaySystem(_api); + display.createWindow(props.getWidth(), props.getHeight(), + props.getDepth(), props.getFreq(), + props.getFullscreen()); + return display; + } + + /** + * Initializes the underlying rendering system, creating a display of + * the proper resolution and depth. + */ + protected void initDisplay () + throws JmeException + { + // create the main display system + _display = createDisplay(); + + // create a camera + int width = _display.getWidth(), height = _display.getHeight(); + _camera = _display.getRenderer().createCamera(width, height); + + // start with a black background + _display.getRenderer().setBackgroundColor(ColorRGBA.black); + + // set up the camera + _camera.setFrustumPerspective(45.0f, width/(float)height, 1, 10000); + Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f); + Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f); + Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f); + Vector3f dir = new Vector3f(0.0f, 0f, -1.0f); + _camera.setFrame(loc, left, up, dir); + _camera.update(); + _display.getRenderer().setCamera(_camera); + + // tell the renderer to keep track of rendering information (total + // triangles drawn, etc.) + _display.getRenderer().enableStatistics(true); + } + + /** + * Sets up a main input controller to handle the camera and deal with + * global user input. + */ + protected void initInput () + { + _camhand = createCameraHandler(_camera); + _input = createInputHandler(_camhand); + } + + /** + * Creates the camera handler which provides various camera manipulation + * functionality. + */ + protected CameraHandler createCameraHandler (Camera camera) + { + return new CameraHandler(camera); + } + + /** + * Creates the input handler used to control our camera and manage non-UI + * keyboard input. + */ + protected InputHandler createInputHandler (CameraHandler hand) + { + return new InputHandler(); + } + + /** + * Creates our root node and sets up the basic rendering system. + */ + protected void initRoot () + { + _root = new Node("Root"); + + // set up a node for our geometry + _geom = new Node("Geometry"); + + // make everything opaque by default + _geom.setRenderQueueMode(Renderer.QUEUE_OPAQUE); + + // set up a zbuffer + ZBufferState zbuf = _display.getRenderer().createZBufferState(); + zbuf.setEnabled(true); + zbuf.setFunction(ZBufferState.CF_LEQUAL); + _geom.setRenderState(zbuf); + _root.attachChild(_geom); + } + + /** + * Sets up some default lighting. + */ + protected void initLighting () + { + PointLight light = new PointLight(); + light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); + light.setLocation(new Vector3f(100, 100, 100)); + light.setEnabled(true); + + _lights = _display.getRenderer().createLightState(); + _lights.setEnabled(true); + _lights.attach(light); + _geom.setRenderState(_lights); + } + + /** + * Initializes our user interface bits. + */ + protected void initInterface () + { + // set up a node for our interface + _iface = new Node("Interface"); + _root.attachChild(_iface); + + // create our root node + _rnode = createRootNode(); + _iface.attachChild(_rnode); + + // we don't hide the cursor + MouseInput.get().setCursorVisible(true); + } + + /** + * Allows a customized root node to be created. + */ + protected BRootNode createRootNode () + { + return new PolledRootNode(_timer, _input); + } + + /** + * Called when initialization fails to give the application a chance + * to report the failure to the user. + */ + protected void reportInitFailure (Throwable t) + { + Log.logStackTrace(t); + } + + /** + * Processes a single frame. + */ + protected final long processFrame () + { + // update our simulation and render a frame + long frameStart = _timer.getTime(); + if (_updateEnabled) { + update(frameStart); + } + if (_renderEnabled) { + render(frameStart); + _display.getRenderer().displayBackBuffer(); + } + return frameStart; + } + + /** + * Called every frame to update whatever sort of real time business we + * have that needs updating. + */ + protected void update (long frameTick) + { + // recalculate the frame rate + _timer.update(); + + // update the camera handler + _camhand.update(_frameTime); + + // run all of the controllers attached to nodes + _frameTime = (_lastTick == 0L) ? 0f : (float)(frameTick - _lastTick) / + _timer.getResolution(); + _lastTick = frameTick; + _root.updateGeometricState(_frameTime, true); + + // update our stats display if we have one + if (_stats != null) { + _stats.update(_timer, _display.getRenderer()); + } + } + + /** + * Called every frame to issue the rendering instructions for this frame. + */ + protected void render (float frameTime) + { + // clear out our previous information + _display.getRenderer().clearStatistics(); + _display.getRenderer().clearBuffers(); + + // draw the root node and all of its children + _display.getRenderer().draw(_root); + + // this would render bounding boxes + // _display.getRenderer().drawBounds(_root); + + // draw our stats atop everything + if (_stats != null) { + _display.getRenderer().draw(_stats); + } + } + + /** + * Called when the application is terminating cleanly after having + * successfully completed initialization and begun the main loop. + */ + protected void cleanup () + { + _display.reset(); + KeyInput.destroyIfInitalized(); + MouseInput.destroyIfInitalized(); + } + + /** + * Closes the display and exits the JVM process. + */ + protected void exit () + { + if (_display != null) { + _display.close(); + } + System.exit(0); + } + + /** + * Prepends the necessary bits onto the supplied path to properly + * locate it in our configuration directory. + */ + protected String getConfigPath (String file) + { + String cfgdir = ".narya"; + String home = System.getProperty("user.home"); + if (!StringUtil.isBlank(home)) { + cfgdir = home + File.separator + cfgdir; + } + // create the configuration directory if it does not already exist + File dir = new File(cfgdir); + if (!dir.exists()) { + dir.mkdir(); + } + return cfgdir + File.separator + file; + } + + /** Provides access to various needed bits. */ + protected JmeContext _ctx = new JmeContext() { + public DisplaySystem getDisplay () { + return _display; + } + + public Renderer getRenderer () { + return _display.getRenderer(); + } + + public CameraHandler getCameraHandler () { + return _camhand; + } + + public Node getGeometry () { + return _geom; + } + + public Node getInterface () { + return _iface; + } + + public InputHandler getInputHandler () { + return _input; + } + + public BRootNode getRootNode () { + return _rnode; + } + }; + + protected Timer _timer; + protected Thread _dispatchThread; + protected Queue _evqueue = new Queue(); + protected long _lastTick; + protected float _frameTime; + + protected String _api; + protected DisplaySystem _display; + protected Camera _camera; + protected CameraHandler _camhand; + + protected InputHandler _input; + protected BRootNode _rnode; + + protected long _ticksPerFrame; + protected int _targetFPS; + protected boolean _updateEnabled = true, _renderEnabled = true; + protected boolean _finished; + protected int _failures; + + protected Node _root, _geom, _iface; + protected LightState _lights; + protected StatsDisplay _stats; + + /** If we fail 100 frames in a row, stick a fork in ourselves. */ + protected static final int MAX_SUCCESSIVE_FAILURES = 100; +} diff --git a/src/java/com/threerings/jme/JmeCanvasApp.java b/src/java/com/threerings/jme/JmeCanvasApp.java new file mode 100644 index 00000000..3e7faf58 --- /dev/null +++ b/src/java/com/threerings/jme/JmeCanvasApp.java @@ -0,0 +1,184 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme; + +import java.awt.Canvas; +import java.awt.Graphics; +import java.awt.EventQueue; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +import org.lwjgl.LWJGLException; + +import com.jme.renderer.Renderer; +import com.jme.renderer.lwjgl.LWJGLRenderer; +import com.jme.scene.Node; +import com.jme.system.DisplaySystem; +import com.jmex.awt.JMECanvas; +import com.jmex.awt.JMECanvasImplementor; +import com.jmex.awt.lwjgl.LWJGLCanvas; + +import com.jmex.bui.CanvasRootNode; + +/** + * Extends the basic {@link JmeApp} with the necessary wiring to use the + * GL/AWT bridge to display our GL interface in an AWT component. + */ +public class JmeCanvasApp extends JmeApp +{ + public JmeCanvasApp (int width, int height) + { + _display = DisplaySystem.getDisplaySystem("LWJGL"); + + // create a throwaway canvas so that the display system knows it's + // created, then create our custom canvas + _display.createCanvas(width, height); + try { + _canvas = createCanvas(); + } catch (LWJGLException e) { + Log.warning("Failed to create LWJGL canvas [error=" + e + "]."); + } + ((JMECanvas)_canvas).setImplementor(_winimp); + _canvas.setBounds(0, 0, width, height); + _canvas.addComponentListener(new ComponentAdapter() { + public void componentResized (ComponentEvent ce) { + _winimp.resizeCanvas(_canvas.getWidth(), _canvas.getHeight()); + } + }); + } + + /** + * Returns the AWT canvas that contains our GL display. + */ + public Canvas getCanvas () + { + return _canvas; + } + + public void run () + { + Thread t = new Thread() { + public void run () { + while (!_finished) { + // queue up another repaint + _canvas.repaint(); + try { + Thread.sleep(10); + } catch (Exception e) { + } + } + } + }; + t.setDaemon(true); + t.start(); + } + + // documentation inherited from interface RunQueue + public void postRunnable (Runnable r) + { + EventQueue.invokeLater(r); + } + + // documentation inherited from interface RunQueue + public boolean isDispatchThread () + { + return EventQueue.isDispatchThread(); + } + + /** + * Creates and returns the LWJGL canvas instance. + */ + protected Canvas createCanvas () + throws LWJGLException + { + // LWJGL's canvas releases the context after painting. we make it + // current again, because we want it valid when we process events. + return new LWJGLCanvas() { + public void update (Graphics g) { + super.update(g); + try { + makeCurrent(); + } catch (LWJGLException e) { + Log.warning("Failed to make context current [error=" + + e + "]."); + } + } + }; + } + + // documentation inherited + protected DisplaySystem createDisplay () + { + // we've already created our display earlier so just return it + _api = "LWJGL"; + return _display; + } + + // documentation inherited + protected void initInterface () + { + _iface = new Node("Interface"); + _root.attachChild(_iface); + + _rnode = new CanvasRootNode(_canvas); + _iface.attachChild(_rnode); + } + + /** This is used if we embed our GL display in an AWT component. */ + protected JMECanvasImplementor _winimp = new JMECanvasImplementor() { + public void doSetup () { + super.doSetup(); + + LWJGLRenderer renderer = + new LWJGLRenderer(_canvas.getWidth(), _canvas.getHeight()); + renderer.setHeadless(true); + setRenderer(renderer); + _display.setRenderer(renderer); + DisplaySystem.updateStates(renderer); + + if (!init()) { + Log.warning("JmeCanvasApp init failed."); + } + } + + public void doUpdate () { + } + + public void doRender () { + // here we do our normal frame processing + try { + processFrame(); + // we don't process events as the AWT queue handles them + _failures = 0; + } catch (Throwable t) { + Log.logStackTrace(t); + // stick a fork in things if we fail too many + // times in a row + if (++_failures > MAX_SUCCESSIVE_FAILURES) { + JmeCanvasApp.this.stop(); + } + } + } + }; + + protected Canvas _canvas; +} diff --git a/src/java/com/threerings/jme/JmeContext.java b/src/java/com/threerings/jme/JmeContext.java new file mode 100644 index 00000000..6dcc4c32 --- /dev/null +++ b/src/java/com/threerings/jme/JmeContext.java @@ -0,0 +1,59 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme; + +import com.jme.input.InputHandler; +import com.jme.renderer.Renderer; +import com.jme.scene.Node; +import com.jme.system.DisplaySystem; + +import com.jmex.bui.BRootNode; + +import com.threerings.jme.camera.CameraHandler; + +/** + * Provides access to the various bits needed by things that operate in + * JME land. + */ +public interface JmeContext +{ + /** Returns the display to which we are rendering. */ + public DisplaySystem getDisplay (); + + /** Returns the renderer being used to draw everything. */ + public Renderer getRenderer (); + + /** Returns the handler for the camera being used to view the scene. */ + public CameraHandler getCameraHandler (); + + /** Returns the main geometry of our scene graph. */ + public Node getGeometry (); + + /** Returns the main interface node of our scene graph. */ + public Node getInterface (); + + /** Returns our main input handler. */ + public InputHandler getInputHandler (); + + /** Returns our UI root node. */ + public BRootNode getRootNode (); +} diff --git a/src/java/com/threerings/jme/Log.java b/src/java/com/threerings/jme/Log.java new file mode 100644 index 00000000..da1cee03 --- /dev/null +++ b/src/java/com/threerings/jme/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme; + +/** + * A placeholder class that contains a reference to the log object used by + * this package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("narya.jme"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/jme/StatsDisplay.java b/src/java/com/threerings/jme/StatsDisplay.java new file mode 100644 index 00000000..c03d3ff8 --- /dev/null +++ b/src/java/com/threerings/jme/StatsDisplay.java @@ -0,0 +1,83 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme; + +import com.jme.image.Texture; +import com.jme.renderer.Renderer; +import com.jme.scene.Node; +import com.jme.scene.Text; +import com.jme.scene.state.AlphaState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jme.util.Timer; + +/** + * Tracks and displays render statistics. + */ +public class StatsDisplay extends Node +{ + public StatsDisplay (Renderer renderer) + { + super("StatsNode"); + + // create an alpha state that will allow us to blend the text on + // top of whatever else is below + AlphaState astate = renderer.createAlphaState(); + astate.setBlendEnabled(true); + astate.setSrcFunction(AlphaState.SB_SRC_ALPHA); + astate.setDstFunction(AlphaState.DB_ONE); + astate.setTestEnabled(true); + astate.setTestFunction(AlphaState.TF_GREATER); + astate.setEnabled(true); + + // create a font texture + TextureState font = renderer.createTextureState(); + font.setTexture( + TextureManager.loadTexture( + getClass().getClassLoader().getResource(DEFAULT_JME_FONT), + Texture.MM_LINEAR, Texture.FM_LINEAR)); + font.setEnabled(true); + + _text = new Text("StatsLabel", ""); + _text.setCullMode(CULL_NEVER); + _text.setTextureCombineMode(TextureState.REPLACE); + + attachChild(_text); + setRenderState(font); + setRenderState(astate); + } + + public void update (Timer timer, Renderer renderer) + { + _stats.setLength(0); + _stats.append("FPS: ").append((int)timer.getFrameRate()); + _stats.append(" - ").append(renderer.getStatistics(_temp)); + _text.print(_stats); + } + + protected Text _text; + protected StringBuffer _stats = new StringBuffer(); + protected StringBuffer _temp = new StringBuffer(); + + protected static final String DEFAULT_JME_FONT = + "rsrc/media/jme/defaultfont.tga"; +} diff --git a/src/java/com/threerings/jme/camera/CameraHandler.java b/src/java/com/threerings/jme/camera/CameraHandler.java new file mode 100644 index 00000000..bdb362d8 --- /dev/null +++ b/src/java/com/threerings/jme/camera/CameraHandler.java @@ -0,0 +1,412 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.math.FastMath; +import com.jme.math.Matrix3f; +import com.jme.math.Plane; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +import com.samskivert.util.ObserverList; + +/** + * Provides various useful mechanisms for manipulating the camera. + */ +public class CameraHandler +{ + /** + * Creates a new camera handler. The camera begins life at the origin, + * facing in the negative z direction (pointing at the ground). + */ + public CameraHandler (Camera camera) + { + _camera = camera; + resetAxes(); + } + + /** + * Resets the camera orientation to its initial state. + */ + public void resetAxes () + { + _camera.getDirection().set(0, 0, -1); + _camera.getLeft().set(-1, 0, 0); + _camera.getUp().set(0, 1, 0); + _camera.update(); + + _rxdir.set(1, 0, 0); + _rydir.set(0, 1, 0); + } + + /** + * Configures limits on the camera tilt. + */ + public void setTiltLimits (float minAngle, float maxAngle) + { + _minTilt = minAngle; + _maxTilt = maxAngle; + } + + /** + * Configures limits on the distance the camera can be panned. + * + * @param boundViaFrustum if true instead of bounding the camera's + * position, we will compute the intersections of the view frustum with the + * ground plan and bound that rectangle into the specified bounds. + * Note: the camera must generally be pointing down at the ground + * (up to perhaps 45 degrees or so) for this to work. At higher angles the + * back of the view frustum will intersect the ground plane at or near + * infinity. + */ + public void setPanLimits (float minX, float minY, float maxX, float maxY, + boolean boundViaFrustum) + { + _minX = minX; + _minY = minY; + _maxX = maxX; + _maxY = maxY; + _boundViaFrustum = boundViaFrustum; + } + + /** + * Configures the minimum and maximum zoom values allowed for the + * camera. + */ + public void setZoomLimits (float minZoom, float maxZoom) + { + _minZoom = minZoom; + _maxZoom = maxZoom; + } + + /** + * Enables or disables the current set of limits. + */ + public void setLimitsEnabled (boolean enabled) + { + _limitsEnabled = enabled; + } + + /** + * Sets the camera zoom level to a value between zero (zoomed in maximally) + * and 1 (zoomed out maximally). Zoom limits must have already been set up + * via a call to {@link #setZoomLimits}. + */ + public void setZoomLevel (float level) + { +// Log.info("Zoom " + level + " " + _camera.getLocation()); + level = Math.max(0f, Math.min(level, 1f)); + _camera.getLocation().z = _minZ + (_maxZ - _minZ) * level; + _camera.update(); + } + + /** + * Returns the current camera zoom level. + */ + public float getZoomLevel () + { + return (_camera.getLocation().z - _minZ) / (_maxZ - _minZ); + } + + /** + * Adds a camera path observer. + */ + public void addCameraObserver (CameraPath.Observer camobs) + { + _campathobs.add(camobs); + } + + /** + * Removes a camera path observer. + */ + public void removeCameraObserver (CameraPath.Observer camobs) + { + _campathobs.remove(camobs); + } + + /** + * Starts the camera moving along a path which will be updated every tick + * until it is complete. + */ + public void moveCamera (CameraPath path) + { + if (_campath != null) { + _campath.abort(); + _campathobs.apply(new CompletedOp(_campath)); + } + _campath = path; + } + + /** + * Returns true if the camera is currently animating along a path, false if + * it is not. + */ + public boolean cameraIsMoving () + { + return (_campath != null); + } + + /** + * Skips immediately to the end of the current camera path. + */ + public void skipPath () + { + // fake an update far enough into the future to trick the camera path + // into thinking it's done + update(100); + } + + /** + * This is called by the {@link JmeApp} on every frame to allow the handler + * to update the camera as necessary. + */ + public void update (float frameTime) + { + if (_campath != null) { + if (_campath.tick(frameTime)) { + CameraPath opath = _campath; + _campath = null; + _campathobs.apply(new CompletedOp(opath)); + } + } + } + + /** + * Returns the camera being manipulated by this handler. + */ + public Camera getCamera () + { + return _camera; + } + + /** + * Adjusts the camera's location. The specified location will be bounded + * within the current pan and zoom limits. + */ + public void setLocation (Vector3f location) + { + _camera.setLocation(bound(location)); + _camera.update(); + } + + /** + * Pans the camera the specified distance in the x and y directions. These + * distances will be multiplied by the current "view" x and y axes and + * added to the camera's position. + */ + public void panCamera (float x, float y) + { + Vector3f loc = _camera.getLocation(); + loc.addLocal(_rxdir.mult(x, _temp)); + loc.addLocal(_rydir.mult(y, _temp)); + setLocation(loc); + } + + /** + * Zooms the camera in (distance < 0) and out (distance > 0) by the + * specified amount. The distance is multiplied by the camera's current + * direction and added to its current position, which is then bounded into + * the pan and zoom volume. + */ + public void zoomCamera (float distance) + { + Vector3f loc = _camera.getLocation(); + float dist = getGroundPoint().distance(loc), + ndist = Math.min(Math.max(dist + distance, _minZoom), _maxZoom); + if ((distance = ndist - dist) == 0f) { + return; + } + loc.subtractLocal(_camera.getDirection().mult(distance, _temp)); + setLocation(loc); + } + + /** + * Locates the point on the ground at which the camera is "looking" and + * rotates the camera from that point around the specified vector by the + * specified angle. Additionally zooms the camera in (deltaZoom < 0) or out + * (deltaZoom > 0) along its direction of view by the specified amount. + */ + public void rotateCamera ( + Vector3f spot, Vector3f axis, float deltaAngle, float deltaZoom) + { + // get a vector from the camera's current position to the point around + // which we're going to orbit + Vector3f direction = _camera.getLocation().subtract(spot); + + // if we're rotating around the left vector, impose tilt limits + if (axis == _camera.getLeft()) { + float angle = FastMath.asin(_ground.normal.dot(direction) / + direction.length()); + float nangle = Math.min(Math.max(angle + deltaAngle, _minTilt), + _maxTilt); + if ((deltaAngle = nangle - angle) == 0f) { + return; + } + } + + // create a rotation matrix + _rotm.fromAxisAngle(axis, deltaAngle); + + // rotate the direction vector and the camera itself + _rotm.mult(direction, direction); + _rotm.mult(_camera.getUp(), _camera.getUp()); + _rotm.mult(_camera.getLeft(), _camera.getLeft()); + _rotm.mult(_camera.getDirection(), _camera.getDirection()); + + // if we're rotating around the ground normal, we need to update our + // notion of side-to-side and forward for panning + if (axis == _ground.normal) { + _rotm.mult(_rxdir, _rxdir); + _rotm.mult(_rydir, _rydir); + } + + // finally move the camera to its new location, zooming in or out in + // the process + float scale = 1 + (deltaZoom / direction.length()); + direction.scaleAdd(scale, spot); + setLocation(direction); + } + + /** + * Swings the camera perpendicular to the ground normal, around the point + * on the ground at which it is looking. + */ + public void orbitCamera (float deltaAngle) + { + rotateCamera(getGroundPoint(), _ground.normal, deltaAngle, 0); + } + + /** + * Swings the camera perpendicular to its left vector around the point on + * the ground at which it is looking. + */ + public void tiltCamera (float deltaAngle) + { + rotateCamera(getGroundPoint(), _camera.getLeft(), deltaAngle, 0); + } + + /** + * Returns the point on the ground (z = 0) at which the camera is looking. + */ + public Vector3f getGroundPoint () + { + float dist = -1f * _ground.normal.dot(_camera.getLocation()) / + _ground.normal.dot(_camera.getDirection()); + return _camera.getLocation().add(_camera.getDirection().mult(dist)); + } + + /** + * Returns the ground normal. Z is the default ground plane and the normal + * points in the positive z direction. Do not modify this value. + */ + public Vector3f getGroundNormal () + { + return _ground.normal; + } + + protected Vector3f bound (Vector3f loc) + { + if (!_limitsEnabled) { + return loc; + } + if (_boundViaFrustum) { + bound(_camera.getFrustumLeft(), _camera.getFrustumTop(), loc); + bound(_camera.getFrustumLeft(), _camera.getFrustumBottom(), loc); + bound(_camera.getFrustumRight(), _camera.getFrustumTop(), loc); + bound(_camera.getFrustumRight(), _camera.getFrustumBottom(), loc); + } else { + loc.x = Math.max(Math.min(loc.x, _maxX), _minX); + loc.y = Math.max(Math.min(loc.y, _maxY), _minY); + } + loc.z = Math.max(Math.min(loc.z, _maxZ), _minZ); + return loc; + } + + protected void bound (float left, float up, Vector3f loc) + { + // start with the location of the camera moved out into the near + // frustum plane + _temp.set(loc); + _temp.scaleAdd(_camera.getFrustumNear(), _camera.getDirection(), loc); + + // then slide it over to a corner of the near frustum rectangle + _temp.scaleAdd(left, _camera.getLeft(), _temp); + _temp.scaleAdd(up, _camera.getUp(), _temp); + + // turn this into a vector with origin at the camera's location + _temp.subtractLocal(loc); + _temp.normalizeLocal(); + + // determine the intersection of said vector with the ground plane + float dist = -1f * _ground.normal.dot(loc) / _ground.normal.dot(_temp); + _temp.scaleAdd(dist, _temp, loc); + + // we then assume that if the corner of the "viewable ground rectangle" + // is outside our bounds that we can simply adjust the camera location + // by the amount it is out of bounds + if (_temp.x > _maxX) { + loc.x -= (_temp.x - _maxX); + } else if (_temp.x < _minX) { + loc.x += (_minX - _temp.x); + } + if (_temp.y > _maxY) { + loc.y -= (_temp.y - _maxY); + } else if (_temp.y < _minY) { + loc.y += (_minY - _temp.y); + } + } + + /** Used to dispatch {@link CameraPath.Observer#pathCompleted}. */ + protected static class CompletedOp implements ObserverList.ObserverOp + { + public CompletedOp (CameraPath path) { + _path = path; + } + public boolean apply (Object observer) { + return ((CameraPath.Observer)observer).pathCompleted(_path); + } + protected CameraPath _path; + } + + protected Camera _camera; + protected CameraPath _campath; + protected ObserverList _campathobs = + new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY); + + protected Matrix3f _rotm = new Matrix3f(); + protected Vector3f _temp = new Vector3f(); + + protected boolean _boundViaFrustum, _limitsEnabled = true; + protected float _minX = -Float.MAX_VALUE, _maxX = Float.MAX_VALUE; + protected float _minY = -Float.MAX_VALUE, _maxY = Float.MAX_VALUE; + protected float _minZ = -Float.MAX_VALUE, _maxZ = Float.MAX_VALUE; + protected float _minZoom = 0f, _maxZoom = Float.MAX_VALUE; + protected float _minTilt = -Float.MAX_VALUE, _maxTilt = Float.MAX_VALUE; + + protected Vector3f _rxdir = new Vector3f(1, 0, 0); + protected Vector3f _rydir = new Vector3f(0, 1, 0); + + protected static final Vector3f _xdir = new Vector3f(1, 0, 0); + protected static final Vector3f _ydir = new Vector3f(0, 1, 0); + + protected static final Plane _ground = new Plane(new Vector3f(0, 0, 1), 0); +} diff --git a/src/java/com/threerings/jme/camera/CameraPath.java b/src/java/com/threerings/jme/camera/CameraPath.java new file mode 100644 index 00000000..3837b603 --- /dev/null +++ b/src/java/com/threerings/jme/camera/CameraPath.java @@ -0,0 +1,69 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.renderer.Camera; + +/** + * Used to move the camera along a particular path. + */ +public abstract class CameraPath +{ + /** Used to inform observers when a camera path is completed or aborted. */ + public interface Observer + { + /** + * Called when this path is finished (potentially early because another + * path was set before this path completed). + * + * @param path the path that was completed. + * + * @return true if the observer should remain in the list, false if it + * should be removed following this notification. + */ + public boolean pathCompleted (CameraPath path); + } + + /** + * This is called on every frame to allow the path to adjust the position + * of the camera. + * + * @return true if the path is completed and can be disposed, false if it + * is not yet completed. + */ + public abstract boolean tick (float secondsSince); + + /** + * Called if this path is aborted prior to completion due to being replaced + * by a new camera path. + */ + public void abort () + { + } + + protected CameraPath (CameraHandler camhand) + { + _camhand = camhand; + } + + protected CameraHandler _camhand; +} diff --git a/src/java/com/threerings/jme/camera/GodViewHandler.java b/src/java/com/threerings/jme/camera/GodViewHandler.java new file mode 100644 index 00000000..68c4ec2c --- /dev/null +++ b/src/java/com/threerings/jme/camera/GodViewHandler.java @@ -0,0 +1,191 @@ +// +// $Id$ + +package com.threerings.jme.camera; + +import com.jme.math.FastMath; +import com.jme.math.Matrix3f; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +import com.jme.input.InputHandler; +import com.jme.input.KeyBindingManager; +import com.jme.input.KeyInput; +import com.jme.input.RelativeMouse; +import com.jme.input.action.*; +import com.jme.input.action.InputActionEvent; + +import com.threerings.jme.JmeApp; +import com.threerings.jme.Log; + +/** + * Sets up camera controls for moving around from a top-down perspective, + * suitable for strategy games and their ilk. The "ground" is assumed to be the + * XY plane. + */ +public class GodViewHandler extends InputHandler +{ + /** + * Creates the handler. + * + * @param cam The camera to move with this handler. + */ + public GodViewHandler (CameraHandler camhand) + { + _camhand = camhand; + setKeyBindings(); + addActions(); + } + + protected void setKeyBindings () + { + KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager(); + + // the key bindings for the pan actions + keyboard.set("forward", KeyInput.KEY_W); + keyboard.set("arrow_forward", KeyInput.KEY_UP); + keyboard.set("backward", KeyInput.KEY_S); + keyboard.set("arrow_backward", KeyInput.KEY_DOWN); + keyboard.set("left", KeyInput.KEY_A); + keyboard.set("arrow_left", KeyInput.KEY_LEFT); + keyboard.set("right", KeyInput.KEY_D); + keyboard.set("arrow_right", KeyInput.KEY_RIGHT); + + // the key bindings for the zoom actions + keyboard.set("zoomIn", KeyInput.KEY_UP); + keyboard.set("zoomOut", KeyInput.KEY_DOWN); + + // the key bindings for the orbit actions + keyboard.set("turnRight", KeyInput.KEY_RIGHT); + keyboard.set("turnLeft", KeyInput.KEY_LEFT); + + // the key bindings for the tilt actions + keyboard.set("tiltForward", KeyInput.KEY_HOME); + keyboard.set("tiltBack", KeyInput.KEY_END); + + keyboard.set("screenshot", KeyInput.KEY_F12); + } + + protected void addActions () + { + addAction(new KeyScreenShotAction(), "screenshot", false); + addPanActions(); + addZoomActions(); + addOrbitActions(); + addTiltActions(); + } + + /** + * Adds actions for panning the camera around the scene. + */ + protected void addPanActions () + { + InputAction forward = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.panCamera(0, speed * evt.getTime()); + } + }; + forward.setSpeed(0.5f); + addAction(forward, "forward", true); + addAction(forward, "arrow_forward", true); + + InputAction backward = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.panCamera(0, -speed * evt.getTime()); + } + }; + backward.setSpeed(0.5f); + addAction(backward, "backward", true); + addAction(backward, "arrow_backward", true); + + InputAction left = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.panCamera(-speed * evt.getTime(), 0); + } + }; + left.setSpeed(0.5f); + addAction(left, "left", true); + addAction(left, "arrow_left", true); + + InputAction right = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.panCamera(speed * evt.getTime(), 0); + } + }; + right.setSpeed(0.5f); + addAction(right, "right", true); + addAction(right, "arrow_right", true); + } + + /** + * Adds actions for zooming the camaera in and out. + */ + protected void addZoomActions () + { + InputAction zoomIn = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.zoomCamera(-speed * evt.getTime()); + } + }; + zoomIn.setSpeed(0.5f); + addAction(zoomIn, "zoomIn", true); + + InputAction zoomOut = new InputAction() { + public void performAction (InputActionEvent evt) { + _camhand.zoomCamera(speed * evt.getTime()); + } + }; + zoomOut.setSpeed(0.5f); + addAction(zoomOut, "zoomOut", true); + } + + /** + * Adds actions for orbiting the camera around the viewpoint. + */ + protected void addOrbitActions () + { + addAction(new OrbitAction(-FastMath.PI / 2), "turnRight", true); + addAction(new OrbitAction(FastMath.PI / 2), "turnLeft", true); + } + + /** + * Adds actions for tilting the camera (rotating around the yaw axis). + */ + protected void addTiltActions () + { + addAction(new TiltAction(-FastMath.PI / 2), "tiltForward", true); + addAction(new TiltAction(FastMath.PI / 2), "tiltBack", true); + } + + protected class OrbitAction extends InputAction + { + public OrbitAction (float radPerSec) + { + _radPerSec = radPerSec; + } + + public void performAction (InputActionEvent evt) + { + _camhand.orbitCamera(_radPerSec * evt.getTime()); + } + + protected float _radPerSec; + } + + protected class TiltAction extends InputAction + { + public TiltAction (float radPerSec) + { + _radPerSec = radPerSec; + } + + public void performAction (InputActionEvent evt) + { + _camhand.tiltCamera(_radPerSec * evt.getTime()); + } + + protected float _radPerSec; + } + + protected CameraHandler _camhand; +} diff --git a/src/java/com/threerings/jme/camera/PanPath.java b/src/java/com/threerings/jme/camera/PanPath.java new file mode 100644 index 00000000..ac3fd9df --- /dev/null +++ b/src/java/com/threerings/jme/camera/PanPath.java @@ -0,0 +1,87 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +/** + * Pans the camera to the specified location in the specified amount of time. + */ +public class PanPath extends CameraPath +{ + /** + * Creates a panning path for the specified camera that will retain the + * camera's current orientation. + * + * @param target the target position for the camera. + * @param duration the number of seconds in which to pan the camera. + */ + public PanPath (CameraHandler camhand, Vector3f target, float duration) + { + this(camhand, target, null, duration); + } + + /** + * Creates a panning path for the specified camera. + * + * @param target the target position for the camera. + * @param trot the target rotation for the camera (or null to + * keep its current orientation) + * @param duration the number of seconds in which to pan the camera. + */ + public PanPath (CameraHandler camhand, Vector3f target, Quaternion trot, + float duration) + { + super(camhand); + + Camera cam = camhand.getCamera(); + _start = new Vector3f(cam.getLocation()); + _velocity = target.subtract(_start); + _velocity.divideLocal(duration); + if (trot != null) { + _irot = new Quaternion(); + _irot.fromAxes(cam.getLeft(), cam.getUp(), cam.getDirection()); + _trot = trot; + } + + _duration = duration; + } + + // documentation inherited + public boolean tick (float secondsSince) + { + _elapsed = Math.min(_elapsed + secondsSince, _duration); + _camloc.scaleAdd(_elapsed, _velocity, _start); + _camhand.setLocation(_camloc); + if (_irot != null) { + _camhand.getCamera().setAxes(_axes.slerp(_irot, _trot, + _elapsed / _duration)); + } + return (_elapsed >= _duration); + } + + protected Vector3f _start, _velocity, _camloc = new Vector3f(); + protected Quaternion _irot, _trot, _axes = new Quaternion(); + protected float _elapsed, _duration; +} diff --git a/src/java/com/threerings/jme/camera/SplinePath.java b/src/java/com/threerings/jme/camera/SplinePath.java new file mode 100644 index 00000000..b29697cb --- /dev/null +++ b/src/java/com/threerings/jme/camera/SplinePath.java @@ -0,0 +1,113 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +import com.threerings.jme.Log; + +/** + * Moves the camera along a cubic Hermite spline path defined by the start and + * end locations and directions. Spline formulas obtained from + * Wikipedia. + */ +public class SplinePath extends CameraPath +{ + /** + * Creates a cubic spline path for the camera to follow. + * + * @param tloc the target location + * @param tdir the target direction + * @param axis the heading axis (typically {@link Vector3f#UNIT_Z}) + * @param duration the duration of the path + * @param tension the tension parameter, which can range from zero to one: + * higher tension values create a more direct path with a sharper turn, + * lower values create a rounder path with a smoother turn + */ + public SplinePath (CameraHandler camhand, Vector3f tloc, + Vector3f tdir, Vector3f axis, float duration, float tension) + { + super(camhand); + + // get the spline function coefficients + Camera cam = camhand.getCamera(); + _p0 = new Vector3f(cam.getLocation()); + _p1 = new Vector3f(tloc); + float tscale = (1f - tension) * _p0.distance(_p1); + _m0 = cam.getDirection().mult(tscale); + _m1 = tdir.mult(tscale); + + _axis = axis; + _duration = duration; + } + + // documentation inherited + public boolean tick (float secondsSince) + { + _elapsed = Math.min(_elapsed + secondsSince, _duration); + float t = _elapsed / _duration, t2 = t*t, t3 = t2*t, + h00 = 2*t3 - 3*t2 + 1, + h00p = 6*t2 - 6*t, + h10 = t3 - 2*t2 + t, + h10p = 3*t2 - 4*t + 1, + h01 = -2*t3 + 3*t2, + h01p = -6*t2 + 6*t, + h11 = t3 - t2, + h11p = 3*t2 - 2*t; + + // take the derivative to find the direction + _p0.mult(h00p, _dir); + _dir.scaleAdd(h10p, _m0, _dir); + _dir.scaleAdd(h01p, _p1, _dir); + _dir.scaleAdd(h11p, _m1, _dir); + _dir.normalizeLocal(); + + // evaluate the spline function to find the location + _p0.mult(h00, _loc); + _loc.scaleAdd(h10, _m0, _loc); + _loc.scaleAdd(h01, _p1, _loc); + _loc.scaleAdd(h11, _m1, _loc); + + // compute the left and up vectors using the direction and + // axis vectors + Camera cam = _camhand.getCamera(); + _axis.cross(_dir, _left); + _left.normalizeLocal(); + _dir.cross(_left, _up); + + // update the camera's location and orientation + cam.setFrame(_loc, _left, _up, _dir); + + return _elapsed >= _duration; + } + + /** The parameters of the spline. */ + Vector3f _p0, _m0, _p1, _m1, _axis; + + /** Working vectors. */ + Vector3f _loc = new Vector3f(), _left = new Vector3f(), + _up = new Vector3f(), _dir = new Vector3f(); + + /** The elapsed time and total duration. */ + float _elapsed, _duration; +} diff --git a/src/java/com/threerings/jme/camera/SwingPath.java b/src/java/com/threerings/jme/camera/SwingPath.java new file mode 100644 index 00000000..16836136 --- /dev/null +++ b/src/java/com/threerings/jme/camera/SwingPath.java @@ -0,0 +1,168 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.math.FastMath; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +import com.threerings.jme.Log; + +/** + * Swings the camera around a point of interest (which should be somewhere + * along the camera's view vector). Also optionally pans the camera and/or + * zooms it in or out (moves it along its view vector) in the process. + * + *

+ */ +public class SwingPath extends CameraPath +{ + /** + * Creates a rotating, zooming path for the specified camera. + * + * @param spot the point of interest around which to swing the camera. + * @param axis the axis around which to rotate the camera. + * @param angle the angle through which to rotate the camera. + * @param angvel the (absolute value of the) velocity at which to rotate + * the camera (in radians per second). + * @param zoom the distance to zoom along the camera's view axis (negative + * = in, positive = out). + */ + public SwingPath (CameraHandler camhand, Vector3f spot, Vector3f axis, + float angle, float angvel, float zoom) + { + this(camhand, spot, axis, angle, angvel, null, 0f, null, zoom); + } + + /** + * Creates a rotating, panning, zooming path for the specified camera. + * + * @param spot the point of interest around which to swing the camera. + * @param paxis the primary axis around which to rotate the camera. + * @param pangle the angle through which to rotate the camera about the + * primary axis. + * @param angvel the (absolute value of the) velocity at which to rotate + * the camera (in radians per second) about the primary angle. + * @param saxis the secondary axis around which to rotate the camera, or + * null for none + * @param sangle the angle through which to rotate the camera about the + * secondary axis + * @param pan the amount to pan the camera, or null for none + * @param zoom the distance to zoom along the camera's view axis (negative + * = in, positive = out). + */ + public SwingPath (CameraHandler camhand, Vector3f spot, Vector3f paxis, + float pangle, float angvel, Vector3f saxis, float sangle, + Vector3f pan, float zoom) + { + super(camhand); + + if (pangle == 0) { + Log.warning("Requested to swing camera through zero degrees " + + "[spot=" + spot + ", paxis=" + paxis + + ", angvel=" + angvel + ", zoom=" + zoom + "]."); + pangle = 0.0001f; + } + if (angvel <= 0) { + Log.warning("Requested to swing camera with invalid velocity " + + "[spot=" + spot + ", paxis=" + paxis + ", pangle=" + + pangle + ", angvel=" + angvel + ", zoom=" + zoom + + "]."); + angvel = FastMath.PI; + } + + _spot = new Vector3f(spot); + _paxis = paxis; + _pangle = pangle; + _pangvel = (pangle > 0) ? angvel : -1 * angvel; + _saxis = (saxis == null) ? null : new Vector3f(saxis); + _sangle = sangle; + _sangvel = _sangle * _pangvel / _pangle; + _pan = pan; + if (_pan != null) { + _panvel = _pan.mult(_pangvel / _pangle); + _panned = new Vector3f(); + } + _zoom = zoom; + _zoomvel = _zoom * _pangvel / _pangle; + +// Log.info("Swinging camera [angle=" + _angle + ", angvel=" + _angvel + +// ", zoom=" + _zoom + ", zoomvel=" + _zoomvel + "]."); + } + + // documentation inherited + public boolean tick (float secondsSince) + { + float deltaPAngle = (secondsSince * _pangvel); + float deltaSAngle = (secondsSince * _sangvel); + float deltaZoom = (secondsSince * _zoomvel); + _protated += deltaPAngle; + _srotated += deltaSAngle; + _zoomed += deltaZoom; + if (_pan != null) { + _panvel.mult(secondsSince, _deltaPan); + _panned.addLocal(_deltaPan); + } + + // clamp our rotation at the target angle and determine whether or not + // we're done + boolean done = false; + if (_pangle > 0 && _protated > _pangle || + _pangle < 0 && _protated < _pangle) { + deltaPAngle -= (_protated - _pangle); + deltaSAngle -= (_srotated - _sangle); + deltaZoom -= (_zoomed - _zoom); + if (_pan != null) { + _deltaPan.subtractLocal(_panned).addLocal(_pan); + } + _protated = _pangle; + _srotated = _sangle; + _panned = _pan; + _zoomed = _zoom; + done = true; + } + + // have the camera handler do the necessary rotating, panning, zooming + if (_pan != null) { + _camhand.setLocation( + _camhand.getCamera().getLocation().addLocal(_deltaPan)); + _spot.addLocal(_deltaPan); + } + _camhand.rotateCamera(_spot, _paxis, deltaPAngle, deltaZoom); + if (_saxis != null) { + _rot.fromAngleAxis(deltaPAngle, _paxis).multLocal(_saxis); + _camhand.rotateCamera(_spot, _saxis, deltaSAngle, 0f); + } + + return done; + } + + protected Vector3f _spot, _paxis, _saxis; + protected float _pangle, _pangvel, _protated; + protected float _sangle, _sangvel, _srotated; + protected Vector3f _pan, _panvel, _panned; + protected float _zoom, _zoomvel, _zoomed; + + protected Quaternion _rot = new Quaternion(); + protected Vector3f _deltaPan = new Vector3f(); +} diff --git a/src/java/com/threerings/jme/camera/rotate_zoom.dia b/src/java/com/threerings/jme/camera/rotate_zoom.dia new file mode 100644 index 0000000000000000000000000000000000000000..603bd5cc9de1b4a0407623bb8a8ad1d68226cfae GIT binary patch literal 1672 zcmV;326y=%iwFP!000001MORFkJ>m8{=UB=qF+ak5Cq;9@VS)j^AUo9F3)`QPg}J4S)cFk?fqdBGk7XHpy;sE+rgiB*FIH^KpIfro`II>H!os7 z5mklv>7q&YWKtFFVD>th#pWxGE8!Ck&m)QvhQ9?ow*!pQBpI7zTF(A>o%a7vaciZM z)goF}q3c4j-p_|mOWd^PznXMm;8PJS`d=&Ua`2y@t&8Hi!N-s9dFFJQ)T!DYwxXK#n2DX9@AWi)sjwb|yp=C=v*tp@0Qk^+=9@ zLT~5-OCVqL@*H_yi-SDC;?7o7AisN&U8^M7IL>^05en;_|+t z@tN@c;_*31=ZL&A)>#?rqxqcIFc$C3SOh{@QpmniO2zu6tSu6yfK*bJfcLN^Ymb~4 zW;xJfs*GuLepl_7R{Hlp!#Jlsn{9@;G}pPAHuUsgXoNM@uuvh_!57!Pd%dvn8fK}J zY~YmyRyx7vqraK>!4$Rcb1FW4278;rTE`A6n>XGKbk{vka?v($yDh>acZ_X-bZlqI z!ql&6!=CG9^iN2|2gH(9uhFatnS&AQlT3{`_FKN2C(#b{W zq~0yBbaI|v@$Xq0nb>6BM`z0*ts$47E4c(n_!KEBFz>Z(%)v(jK$0X3!;wTH;Fy;+ zOKargddHm=JgSG>V+)yHJIL1#^0k9}Oa=BKjn}g@so_c4xd>xOFdFz01)*ZS7GVr= zfs5uWlZ1+*2ooXqLljUVTQ2?*3^P95j%w1eW~hKks$!A?2P8PqZ03d35QMk3-1ifj z{8BC(c6M2ycMhHd1scVq&-4yRIDnm{LW)TV`v!`z2$T=6gay62Y?F@l^(v>zFDDy@ z2ZrKOYN1D4%bnR}&vKZix*w)VhDCYEBuTG61tb(OP6{N3 S+4+{#-Oc}ihc=u^JpceP8b`YT literal 0 HcmV?d00001 diff --git a/src/java/com/threerings/jme/camera/rotate_zoom.png b/src/java/com/threerings/jme/camera/rotate_zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..82ce4f88a5f69c41646182fe46f308efe2d50958 GIT binary patch literal 16237 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 ", ColorRGBA.blue); + append(umsg.message + "\n"); + } + + } else if (msg instanceof SystemMessage) { + append(msg.message + "\n", ColorRGBA.red); + + } else { + Log.warning("Received unknown message type: " + msg + "."); + } + } + + // documentation inherited + public void setEnabled (boolean enabled) + { + _input.setEnabled(enabled); + } + + protected void displayError (String message) + { + append(message + "\n", ColorRGBA.red); + } + + protected void append (String text, ColorRGBA color) + { + _text.appendText(text, color); + } + + protected void append (String text) + { + _text.appendText(text); + } + + protected boolean handlesType (String localType) + { + return true; + } + + protected boolean handleInput (String text) + { + if (text.length() == 0) { + // no empty banter + return false; + } + String msg = _chatdtr.requestChat(_spsvc, text, true); + if (msg.equals(ChatCodes.SUCCESS)) { + return true; + } else { + _chatdtr.displayFeedback(null, msg); + return false; + } + } + + protected ChatDirector _chatdtr; + protected SpeakService _spsvc; + protected BTextArea _text; + protected BTextField _input; +} diff --git a/src/java/com/threerings/jme/effect/FadeInOutEffect.java b/src/java/com/threerings/jme/effect/FadeInOutEffect.java new file mode 100644 index 00000000..9898dd65 --- /dev/null +++ b/src/java/com/threerings/jme/effect/FadeInOutEffect.java @@ -0,0 +1,148 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.effect; + +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.scene.Geometry; +import com.jme.scene.Node; +import com.jme.scene.shape.Quad; +import com.jme.scene.state.AlphaState; +import com.jme.system.DisplaySystem; + +import com.threerings.jme.util.LinearTimeFunction; +import com.threerings.jme.util.TimeFunction; + +/** + * Fades a supplied quad (or one that covers the screen) in from a solid color + * or out to a solid color. + */ +public class FadeInOutEffect extends Node +{ + public FadeInOutEffect (ColorRGBA color, float startAlpha, float endAlpha, + float duration, boolean overUI) + { + this(color, new LinearTimeFunction(startAlpha, endAlpha, duration), + overUI); + } + + public FadeInOutEffect (ColorRGBA color, TimeFunction alphaFunc, + boolean overUI) + { + this(null, color, alphaFunc, overUI); + setQuad(createCurtain()); + } + + public FadeInOutEffect (Quad quad, ColorRGBA color, TimeFunction alphaFunc, + boolean overUI) + { + super("FadeInOut"); + + _color = new ColorRGBA( + color.r, color.g, color.b, alphaFunc.getValue(0)); + _alphaFunc = alphaFunc; + + DisplaySystem ds = DisplaySystem.getDisplaySystem(); + _astate = ds.getRenderer().createAlphaState(); + _astate.setBlendEnabled(true); + _astate.setSrcFunction(AlphaState.SB_SRC_ALPHA); + _astate.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA); + _astate.setEnabled(true); + + if (quad != null) { + setQuad(quad); + } + + setRenderQueueMode(Renderer.QUEUE_ORTHO); + setZOrder(overUI ? -1 : 1); + } + + /** + * Configures the quad that will be faded in or out. + */ + public void setQuad (Quad quad) + { + attachChild(quad); + quad.setDefaultColor(_color); + quad.setRenderState(_astate); + quad.updateRenderState(); + } + + /** + * Allows the fade to be paused. + */ + public void setPaused (boolean paused) + { + _paused = paused; + } + + /** + * Indicates whether or not the fade is paused. + */ + public boolean isPaused () + { + return _paused; + } + + // documentation inherited + public void updateGeometricState (float time, boolean initiator) + { + super.updateGeometricState(time, initiator); + if (_paused) { + return; + } + + float alpha = _alphaFunc.getValue(time); + _color.a = Math.min(1f, Math.max(0f, alpha)); + if (_alphaFunc.isComplete()) { + fadeComplete(); + } + } + + /** + * Called (only once) when we have reached the end of our fade. + * Automatically detaches this effect from the hierarchy. + */ + protected void fadeComplete () + { + getParent().detachChild(this); + } + + /** + * Creates a quad that covers the entire screen for full-screen fades. + */ + protected Quad createCurtain () + { + // create a quad the size of the screen + DisplaySystem ds = DisplaySystem.getDisplaySystem(); + float width = ds.getWidth(), height = ds.getHeight(); + Quad curtain = new Quad("curtain" + hashCode(), width, height); + curtain.setLocalTranslation(new Vector3f(width/2, height/2, 0f)); + return curtain; + } + + protected ColorRGBA _color; + protected AlphaState _astate; + protected TimeFunction _alphaFunc; + protected boolean _paused; +} diff --git a/src/java/com/threerings/jme/effect/WindowSlider.java b/src/java/com/threerings/jme/effect/WindowSlider.java new file mode 100644 index 00000000..f8d6151f --- /dev/null +++ b/src/java/com/threerings/jme/effect/WindowSlider.java @@ -0,0 +1,127 @@ +// +// $Id$ + +package com.threerings.jme.effect; + +import com.jme.scene.Node; +import com.jme.system.DisplaySystem; + +import com.jmex.bui.BWindow; + +import com.threerings.jme.util.LinearTimeFunction; +import com.threerings.jme.util.TimeFunction; + +/** + * Slides a window onto the center of the screen from offscreen or offscreen + * from the center of the screen. + */ +public class WindowSlider extends Node +{ + public static final int FROM_TOP = 0; + public static final int FROM_RIGHT = 1; + public static final int TO_TOP = 2; + public static final int TO_RIGHT = 3; + + /** + * Creates a window slider with the specified mode and window that will + * slide the window either onto or off of the screen in the specified + * number of seconds. + * + * @param dx an offset applied to the starting or destination position + * along the x axis (starting for sliding off, destination for sliding on). + * @param dy an offset applied along the y axis. + */ + public WindowSlider (BWindow window, int mode, float duration, + int dx, int dy) + { + super("slider"); + + DisplaySystem ds = DisplaySystem.getDisplaySystem(); + int swidth = ds.getWidth(), sheight = ds.getHeight(); + int wwidth = window.getWidth(), wheight = window.getHeight(); + + int start = 0, end = 0; + switch (mode) { + case FROM_TOP: + start = sheight+wheight; + end = (sheight-wheight)/2 + dy; + window.setLocation((swidth-wwidth)/2 + dx, start); + break; + + case FROM_RIGHT: + start = swidth+wwidth; + end = (swidth-wwidth)/2 + dx; + window.setLocation(start, (sheight-wheight)/2 + dy); + break; + + case TO_TOP: + start = (sheight-wheight)/2 + dy; + end = sheight+wheight; + window.setLocation((swidth-wwidth)/2 + dx, start); + break; + + case TO_RIGHT: + start = (swidth-wwidth)/2 + dx; + end = swidth+wwidth; + window.setLocation(start, (sheight-wheight)/2 + dy); + break; + } + + _mode = mode; + _window = window; + _tfunc = new LinearTimeFunction(start, end, duration); + } + + /** + * Allows some number of ticks to be skipped to give the window that is + * being slid a chance to be layed out before we start keeping track of + * time. The layout may be expensive and cause the frame rate to drop for a + * frame or two, thus booching our smooth sliding onto the screen. + */ + public void setSkipTicks (int skipTicks) + { + _skipTicks = skipTicks; + } + + // documentation inherited + public void updateGeometricState (float time, boolean initiator) + { + super.updateGeometricState(time, initiator); + + // skip ticks as long as we need to + if (_skipTicks-- > 0) { + return; + } + + int winx, winy; + if (_mode % 2 == 1) { + winx = (int)_tfunc.getValue(time); + winy = _window.getY(); + } else { + winx = _window.getX(); + winy = (int)_tfunc.getValue(time); + } + _window.setLocation(winx, winy); + + if (_tfunc.isComplete()) { + slideComplete(); + } + } + + /** + * Called (only once) when we have reached the end of our slide. + * Automatically detaches this effect from the hierarchy. + */ + protected void slideComplete () + { + getParent().detachChild(this); + } + + protected int _mode; + protected BWindow _window; + protected TimeFunction _tfunc; + + // skip two frames by default as that generally handles the normal window + // layout process + protected int _skipTicks = 2; +} diff --git a/src/java/com/threerings/jme/model/EmissionController.java b/src/java/com/threerings/jme/model/EmissionController.java new file mode 100644 index 00000000..26907cdb --- /dev/null +++ b/src/java/com/threerings/jme/model/EmissionController.java @@ -0,0 +1,79 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.util.Properties; + +import com.jme.math.Vector3f; +import com.jme.scene.Geometry; +import com.jme.scene.Spatial; +import com.jme.util.geom.BufferUtils; + +/** + * A model controller whose target represents an emitter. + */ +public abstract class EmissionController extends ModelController +{ + @Override // documentation inherited + public void configure (Properties props, Spatial target) + { + // substitute underlying mesh for geometry targets + if (target instanceof ModelNode) { + Spatial mesh = ((ModelNode)target).getChild("mesh"); + if (mesh != null) { + target = mesh; + } + } + super.configure(props, target); + } + + @Override // documentation inherited + public void init (Model model) + { + super.init(model); + _target.setCullMode(Spatial.CULL_ALWAYS); + } + + /** + * Determines the current location of the emitter in world coordinates. + */ + protected void getEmitterLocation (Vector3f result) + { + result.set(_target.getWorldTranslation()); + } + + /** + * Determines the current direction of the emitter in world coordinates. + */ + protected void getEmitterDirection (Vector3f result) + { + if (_target instanceof Geometry) { + BufferUtils.populateFromBuffer(result, + ((Geometry)_target).getNormalBuffer(0), 0); + } else { + result.set(0f, 0f, -1f); + } + _target.getWorldRotation().multLocal(result); + } + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/Model.java b/src/java/com/threerings/jme/model/Model.java new file mode 100644 index 00000000..d4bf1b90 --- /dev/null +++ b/src/java/com/threerings/jme/model/Model.java @@ -0,0 +1,1036 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.Externalizable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Properties; + +import com.jme.bounding.BoundingVolume; +import com.jme.math.FastMath; +import com.jme.math.Matrix4f; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; +import com.jme.renderer.Renderer; +import com.jme.scene.Controller; +import com.jme.scene.Node; +import com.jme.scene.Spatial; + +import com.samskivert.util.ObserverList; +import com.samskivert.util.RandomUtil; + +import com.threerings.jme.Log; + +/** + * The base node for models. + */ +public class Model extends ModelNode +{ + /** The supported types of animation in decreasing order of complexity. */ + public enum AnimationMode { + SKIN, MORPH, FLIPBOOK + }; + + /** Lets listeners know when animations are completed (which only happens + * for non-repeating animations) or cancelled. */ + public interface AnimationObserver + { + /** + * Called when an animation has started. + * + * @return true to remain on the observer list, false to remove self + */ + public boolean animationStarted (Model model, String anim); + + /** + * Called when a non-repeating animation has finished. + * + * @return true to remain on the observer list, false to remove self + */ + public boolean animationCompleted (Model model, String anim); + + /** + * Called when an animation has been cancelled. + * + * @return true to remain on the observer list, false to remove self + */ + public boolean animationCancelled (Model model, String anim); + } + + /** An animation for the model. */ + public static class Animation + implements Serializable + { + /** The rate of the animation in frames per second. */ + public int frameRate; + + /** The animation repeat type ({@link Controller#RT_CLAMP}, + * {@link Controller#RT_CYCLE}, or {@link Controller#RT_WRAP}). */ + public int repeatType; + + /** The transformation targets of the animation. */ + public Spatial[] transformTargets; + + /** The animation transforms (one transform per target per frame). */ + public transient Transform[][] transforms; + + /** Uniquely identifies this animation within the model. */ + public transient int animId; + + /** For each frame, whether the frame has been stored in meshes. */ + public transient boolean[] stored; + + /** + * Returns this animation's duration in seconds. + */ + public float getDuration () + { + return (float)transforms.length / frameRate; + } + + /** + * Rebinds this animation for a prototype instance. + * + * @param pnodes a mapping from prototype nodes to instance nodes + */ + public Animation rebind (HashMap pnodes) + { + Animation anim = new Animation(); + anim.frameRate = frameRate; + anim.repeatType = repeatType; + anim.transforms = transforms; + anim.transformTargets = new Spatial[transformTargets.length]; + for (int ii = 0; ii < transformTargets.length; ii++) { + anim.transformTargets[ii] = + (Spatial)pnodes.get(transformTargets[ii]); + } + anim.animId = animId; + anim.stored = stored; + return anim; + } + + /** + * Applies the transforms for a frame of this animation. + */ + public void applyFrame (int fidx) + { + Transform[] xforms = transforms[fidx]; + for (int ii = 0; ii < transformTargets.length; ii++) { + xforms[ii].apply(transformTargets[ii]); + } + } + + /** + * Blends the transforms between two frames of this animation. + */ + public void blendFrames (int fidx, int nidx, float alpha) + { + Transform[] xforms = transforms[fidx], nxforms = transforms[nidx]; + for (int ii = 0; ii < transformTargets.length; ii++) { + xforms[ii].blend(nxforms[ii], alpha, transformTargets[ii]); + } + } + + private void writeObject (ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + out.writeInt(transforms.length); + for (int ii = 0; ii < transforms.length; ii++) { + for (int jj = 0; jj < transformTargets.length; jj++) { + transforms[ii][jj].writeExternal(out); + } + } + } + + private void readObject (ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + transforms = new Transform[in.readInt()][transformTargets.length]; + for (int ii = 0; ii < transforms.length; ii++) { + for (int jj = 0; jj < transformTargets.length; jj++) { + transforms[ii][jj] = new Transform(new Vector3f(), + new Quaternion(), new Vector3f()); + transforms[ii][jj].readExternal(in); + } + } + } + + private static final long serialVersionUID = 1; + } + + /** A frame element that manipulates the target's transform. */ + public static final class Transform + implements Externalizable + { + public Transform ( + Vector3f translation, Quaternion rotation, Vector3f scale) + { + _translation = translation; + _rotation = rotation; + _scale = scale; + } + + public void apply (Spatial target) + { + target.getLocalTranslation().set(_translation); + target.getLocalRotation().set(_rotation); + target.getLocalScale().set(_scale); + } + + /** + * Blends between this transform and the next, applying the result to + * the given target. + * + * @param alpha the blend factor: 0.0 for entirely this frame, 1.0 for + * entirely the next + */ + public void blend (Transform next, float alpha, Spatial target) + { + target.getLocalTranslation().interpolate(_translation, + next._translation, alpha); + target.getLocalRotation().slerp(_rotation, next._rotation, alpha); + target.getLocalScale().interpolate(_scale, next._scale, alpha); + } + + // documentation inherited from interface Externalizable + public void writeExternal (ObjectOutput out) + throws IOException + { + _translation.writeExternal(out); + _rotation.writeExternal(out); + _scale.writeExternal(out); + } + + // documentation inherited from interface Externalizable + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + _translation.readExternal(in); + _rotation.readExternal(in); + _scale.readExternal(in); + } + + /** The transform at this frame. */ + protected Vector3f _translation, _scale; + protected Quaternion _rotation; + + private static final long serialVersionUID = 1; + } + + /** Customized clone creator for models. */ + public static class CloneCreator + { + /** A shared seed used to select textures consistently. */ + public int random; + + /** Maps original objects to their copies. */ + public HashMap originalToCopy = new HashMap(); + + public CloneCreator (Model toCopy) + { + _toCopy = toCopy; + addProperty("vertices"); + addProperty("colors"); + addProperty("normals"); + addProperty("texcoords"); + addProperty("vboinfo"); + addProperty("indices"); + addProperty("obbtree"); + addProperty("displaylistid"); + addProperty("bound"); + } + + /** + * Sets the named property. + */ + public void addProperty (String name) + { + _properties.add(name); + } + + /** + * Clears the named property. + */ + public void removeProperty (String name) + { + _properties.remove(name); + } + + /** + * Checks whether the named property has been set. + */ + public boolean isSet (String name) + { + return _properties.contains(name); + } + + /** + * Creates a new copy of the target model. + */ + public Model createCopy () + { + random = RandomUtil.getInt(Integer.MAX_VALUE); + Model copy = (Model)_toCopy.putClone(null, this); + originalToCopy.clear(); // make sure no references remain + return copy; + } + + /** The model to copy. */ + protected Model _toCopy; + + /** The set of added properties. */ + protected HashSet _properties = new HashSet(); + } + + /** + * Attempts to read a model from the specified file. + * + * @param map if true, map buffers into memory directly from the + * file + */ + public static Model readFromFile (File file, boolean map) + throws IOException + { + // read the serialized model and its children + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + Model model; + try { + model = (Model)ois.readObject(); + } catch (ClassNotFoundException e) { + Log.warning("Encountered unknown class [error=" + e + "]."); + return null; + } + + // then either read or map the buffers + FileChannel fc = fis.getChannel(); + if (map) { + long pos = fc.position(); + model.sliceBuffers(fc.map(FileChannel.MapMode.READ_ONLY, + pos, fc.size() - pos)); + } else { + model.readBuffers(fc); + } + ois.close(); + + // initialize the model as a prototype + model.initPrototype(); + + return model; + } + + /** + * No-arg constructor for deserialization. + */ + public Model () + { + } + + /** + * Standard constructor. + */ + public Model (String name, Properties props) + { + super(name); + _props = props; + } + + /** + * Returns a reference to the properties of the model. + */ + public Properties getProperties () + { + return _props; + } + + /** + * Initializes this model as prototype. Only necessary when the prototype + * was not loaded through {@link #readFromFile}. + */ + public void initPrototype () + { + // initialize shared transient animation state + if (_anims != null) { + int nextId = 1; + for (Animation anim : _anims.values()) { + anim.animId = nextId++; + anim.stored = new boolean[anim.transforms.length]; + } + } + setReferenceTransforms(); + cullInvisibleNodes(); + initInstance(); + } + + /** + * Adds an animation to the model's library. This should only be called by + * the model compiler. + */ + public void addAnimation (String name, Animation anim) + { + if (_anims == null) { + _anims = new HashMap(); + } + _anims.put(name, anim); + + // store the original transforms + Transform[] oxforms = new Transform[anim.transformTargets.length]; + for (int ii = 0; ii < anim.transformTargets.length; ii++) { + Spatial target = anim.transformTargets[ii]; + oxforms[ii] = new Transform( + new Vector3f(target.getLocalTranslation()), + new Quaternion(target.getLocalRotation()), + new Vector3f(target.getLocalScale())); + } + + // run through every frame of the animation, expanding the bounding + // volumes of any deformable meshes + for (int ii = 0; ii < anim.transforms.length; ii++) { + for (int jj = 0; jj < anim.transforms[ii].length; jj++) { + anim.transforms[ii][jj].apply(anim.transformTargets[jj]); + } + updateWorldData(0f); + expandModelBounds(); + } + + // restore the original transforms + for (int ii = 0; ii < anim.transformTargets.length; ii++) { + oxforms[ii].apply(anim.transformTargets[ii]); + } + updateWorldData(0f); + } + + /** + * Sets the animation mode to use for this model. This should be set + * on the prototype before any animations are started or any instances + * are created. + */ + public void setAnimationMode (AnimationMode mode) + { + _animMode = mode; + } + + /** + * Returns the animation mode configured for this model. + */ + public AnimationMode getAnimationMode () + { + return _animMode; + } + + /** + * Returns the names of the model's animations. + */ + public String[] getAnimationNames () + { + if (_prototype != null) { + return _prototype.getAnimationNames(); + } + return (_anims == null) ? new String[0] : + _anims.keySet().toArray(new String[_anims.size()]); + } + + /** + * Checks whether the unit has an animation with the given name. + */ + public boolean hasAnimation (String name) + { + if (_prototype != null) { + return _prototype.hasAnimation(name); + } + return (_anims == null) ? false : _anims.containsKey(name); + } + + /** + * Starts the named animation. + * + * @return the duration of the started animation (for looping animations, + * the duration of one cycle), or -1 if the animation was not found + */ + public float startAnimation (String name) + { + Animation anim = getAnimation(name); + if (anim == null) { + return -1f; + } + if (_anim != null) { + _animObservers.apply(new AnimCancelledOp(_animName)); + } + _anim = anim; + _animName = name; + _fidx = 0; + _nidx = 1; + _fdir = +1; + _elapsed = 0f; + _animObservers.apply(new AnimStartedOp(_animName)); + return anim.getDuration() / _animSpeed; + } + + /** + * Fast-forwards the current animation by the given number of seconds. + */ + public void fastForwardAnimation (float time) + { + updateAnimation(time); + } + + /** + * Gets a reference to the animation with the given name. + */ + public Animation getAnimation (String name) + { + if (_anims == null) { + return null; + } + Animation anim = _anims.get(name); + if (anim != null) { + return anim; + } + if (_prototype != null) { + Animation panim = _prototype._anims.get(name); + if (panim != null) { + _anims.put(name, anim = panim.rebind(_pnodes)); + return anim; + } + } + Log.warning("Requested unknown animation [name=" + name + "]."); + return null; + } + + /** + * Returns a reference to the currently running animation, or + * null if no animation is running. + */ + public Animation getAnimation () + { + return _anim; + } + + /** + * Stops the currently running animation. + */ + public void stopAnimation () + { + if (_anim == null) { + return; + } + _anim = null; + _animObservers.apply(new AnimCancelledOp(_animName)); + } + + /** + * Sets the animation speed, which acts as a multiplier for the frame rate + * of each animation. + */ + public void setAnimationSpeed (float speed) + { + _animSpeed = speed; + } + + /** + * Returns the currently configured animation speed. + */ + public float getAnimationSpeed () + { + return _animSpeed; + } + + /** + * Adds an animation observer. + */ + public void addAnimationObserver (AnimationObserver obs) + { + _animObservers.add(obs); + } + + /** + * Removes an animation observer. + */ + public void removeAnimationObserver (AnimationObserver obs) + { + _animObservers.remove(obs); + } + + /** + * Returns a reference to the node that contains this model's emissions + * (in world space, so the emissions do not move with the model). This + * node is created and added when this method is first called. + */ + public Node getEmissionNode () + { + if (_emissionNode == null) { + attachChild(_emissionNode = new Node("emissions") { + public void updateWorldVectors () { + worldTranslation.set(localTranslation); + worldRotation.set(localRotation); + worldScale.set(localScale); + } + }); + } + return _emissionNode; + } + + /** + * Writes this model out to a file. + */ + public void writeToFile (File file) + throws IOException + { + // start out by writing this node and its children + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(this); + + // now traverse the scene graph appending buffers to the + // end of the file + writeBuffers(fos.getChannel()); + oos.close(); + } + + @Override // documentation inherited + public void writeExternal (ObjectOutput out) + throws IOException + { + // don't serialize the emission node; it contains transient geometry + // created by controllers + if (_emissionNode != null) { + detachChild(_emissionNode); + } + super.writeExternal(out); + if (_emissionNode != null) { + attachChild(_emissionNode); + } + out.writeObject(_props); + out.writeObject(_anims); + out.writeObject(getControllers()); + } + + @Override // documentation inherited + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + super.readExternal(in); + _props = (Properties)in.readObject(); + _anims = (HashMap)in.readObject(); + ArrayList controllers = (ArrayList)in.readObject(); + for (Object ctrl : controllers) { + addController((Controller)ctrl); + } + } + + @Override // documentation inherited + public void resolveTextures (TextureProvider tprov) + { + super.resolveTextures(tprov); + for (Object ctrl : getControllers()) { + if (ctrl instanceof ModelController) { + ((ModelController)ctrl).resolveTextures(tprov); + } + } + } + + /** + * Creates and returns a new instance of this model. + */ + public Model createInstance () + { + if (_prototype != null) { + return _prototype.createInstance(); + } + if (_ccreator == null) { + _ccreator = new CloneCreator(this); + } + Model instance = _ccreator.createCopy(); + instance.initInstance(); + return instance; + } + + /** + * Locks the transforms and bounds of this model in the expectation that it + * will never be moved from its current position. + */ + public void lockInstance () + { + // collect the controller targets and lock recursively + HashSet targets = new HashSet(); + for (Object ctrl : getControllers()) { + if (ctrl instanceof ModelController) { + targets.add(((ModelController)ctrl).getTarget()); + } + } + lockInstance(targets); + } + + @Override // documentation inherited + public Spatial putClone (Spatial store, CloneCreator properties) + { + Model mstore = (Model)properties.originalToCopy.get(this); + if (mstore != null) { + return mstore; + } else if (store == null) { + mstore = new Model(getName(), _props); + } else { + mstore = (Model)store; + } + // don't clone the emission node, as it contains transient geometry + if (_emissionNode != null) { + detachChild(_emissionNode); + } + super.putClone(mstore, properties); + if (_emissionNode != null) { + attachChild(_emissionNode); + } + mstore._prototype = this; + if (_anims != null) { + mstore._anims = new HashMap(); + } + mstore._pnodes = (HashMap)properties.originalToCopy.clone(); + mstore._animMode = _animMode; + return mstore; + } + + @Override // documentation inherited + public void updateGeometricState (float time, boolean initiator) + { + // if we were not visible the last time we were rendered, don't do a + // full update; just update the world bound and wait until we come + // into view + boolean wasOutside = _outside; + _outside = isOutsideFrustum() && worldBound != null; + + // slow evvvverything down by the animation speed + time *= _animSpeed; + if (_anim != null) { + updateAnimation(time); + } + + // update controllers and children with accumulated time + _accum += time; + if (_outside) { + if (!wasOutside) { + updateModelBound(); + } + updateWorldVectors(); + worldBound = _modelBound.transform(getWorldRotation(), + getWorldTranslation(), getWorldScale(), worldBound); + + } else { + super.updateGeometricState(_accum, initiator); + _accum = 0f; + } + } + + @Override // documentation inherited + public void onDraw (Renderer r) + { + // if we switch from invisible to visible, we have to do a last-minute + // full update (which only works if our meshes are enqueued) + super.onDraw(r); + if (_outside && !isOutsideFrustum()) { + updateWorldData(0f); + } + } + + @Override // documentation inherited + public void updateModelBound () + { + if (worldBound == null) { + return; + } + setTransform(getWorldTranslation(), getWorldRotation(), + getWorldScale(), _xform); + _xform.invertLocal(); + _xform.toTranslationVector(_trans); + extractScale(_xform, _scale); + _xform.toRotationQuat(_rot); + _modelBound = worldBound.transform(_rot, _trans, _scale, _modelBound); + } + + /** + * Determines whether this node was determined to be entirely outside the + * view frustum. + */ + protected boolean isOutsideFrustum () + { + for (Node node = this; node != null; node = node.getParent()) { + if (node.getLastFrustumIntersection() == Camera.OUTSIDE_FRUSTUM) { + return true; + } + } + return false; + } + + /** + * Initializes the per-instance state of this model. + */ + protected void initInstance () + { + // initialize the controllers + for (Object ctrl : getControllers()) { + if (ctrl instanceof ModelController) { + ((ModelController)ctrl).init(this); + } + } + } + + /** + * Updates the model's state according to the current animation. + */ + protected void updateAnimation (float time) + { + // no need to update between frames for flipbook animation + if (_animMode == AnimationMode.FLIPBOOK && _elapsed > 0f && + _elapsed < 1f) { + _elapsed += (time * _anim.frameRate); + return; + } + + // advance the frame counter if necessary + while (_elapsed > 1f) { + advanceFrameCounter(); + _elapsed -= 1f; + } + + // update the target transforms and animation frame if not outside the + // view frustum + if (!_outside) { + if (_animMode == AnimationMode.FLIPBOOK) { + int frameId = (_anim.animId << 16) | _fidx; + _anim.applyFrame(_fidx); + if (!_anim.stored[_fidx]) { + storeMeshFrame(frameId, false); + updateWorldData(0f); + _anim.stored[_fidx] = true; + } + setMeshFrame(frameId); + + } else if (_animMode == AnimationMode.MORPH) { + int frameId1 = (_anim.animId << 16) | _fidx, + frameId2 = (_anim.animId << 16) | _nidx; + if (!_anim.stored[_fidx]) { + storeMeshFrame(frameId1, true); + _anim.applyFrame(_fidx); + updateWorldData(0f); + _anim.stored[_fidx] = true; + } + if (!_anim.stored[_nidx]) { + storeMeshFrame(frameId2, true); + _anim.applyFrame(_nidx); + updateWorldData(0f); + _anim.stored[_nidx] = true; + } + _anim.blendFrames(_fidx, _nidx, _elapsed); + blendMeshFrames(frameId1, frameId2, _elapsed); + + } else { // _animMode == AnimationMode.SKIN + _anim.blendFrames(_fidx, _nidx, _elapsed); + } + } + + // if the next index is the same as this one, we are finished + if (_fidx == _nidx) { + _anim = null; + _animObservers.apply(new AnimCompletedOp(_animName)); + return; + } + + _elapsed += (time * _anim.frameRate); + } + + /** + * Advances the frame counter by one frame. + */ + protected void advanceFrameCounter () + { + _fidx = _nidx; + int nframes = _anim.transforms.length; + if (_anim.repeatType == Controller.RT_CLAMP) { + _nidx = Math.min(_nidx + 1, nframes - 1); + + } else if (_anim.repeatType == Controller.RT_WRAP) { + _nidx = (_nidx + 1) % nframes; + + } else { // _anim.repeatType == Controller.RT_CYCLE + if ((_nidx + _fdir) < 0 || (_nidx + _fdir) >= nframes) { + _fdir *= -1; // reverse direction + } + _nidx += _fdir; + } + } + + /** + * Extracts the scale factor from the given transform and normalizes it. + */ + protected static void extractScale (Matrix4f m, Vector3f scale) + { + scale.x = FastMath.sqrt(m.m00*m.m00 + m.m01*m.m01 + m.m02*m.m02); + m.m00 /= scale.x; + m.m01 /= scale.x; + m.m02 /= scale.x; + scale.y = FastMath.sqrt(m.m10*m.m10 + m.m11*m.m11 + m.m12*m.m12); + m.m10 /= scale.y; + m.m11 /= scale.y; + m.m12 /= scale.y; + scale.z = FastMath.sqrt(m.m20*m.m20 + m.m21*m.m21 + m.m22*m.m22); + m.m20 /= scale.z; + m.m21 /= scale.z; + m.m22 /= scale.z; + } + + /** A reference to the prototype, or null if this is a + * prototype. */ + protected Model _prototype; + + /** For prototype models, a customized clone creator used to generate + * instances. */ + protected CloneCreator _ccreator; + + /** The animation mode to use for this model. */ + protected AnimationMode _animMode; + + /** For instances, maps prototype nodes to their corresponding instance + * nodes. */ + protected HashMap _pnodes; + + /** The model properties. */ + protected Properties _props; + + /** The model animations. */ + protected HashMap _anims; + + /** The currently running animation, or null for none. */ + protected Animation _anim; + + /** The name of the currently running animation, if any. */ + protected String _animName; + + /** The current animation speed multiplier. */ + protected float _animSpeed = 1f; + + /** The index of the current and next frames. */ + protected int _fidx, _nidx; + + /** The direction for wrapping animations (+1 forward, -1 backward). */ + protected int _fdir; + + /** The frame portion elapsed since the start of the current frame. */ + protected float _elapsed; + + /** The amount of update time accumulated while outside of view frustum. */ + protected float _accum; + + /** The child node that contains the model's emissions in world space. */ + protected Node _emissionNode; + + /** The model space bounding volume. */ + protected BoundingVolume _modelBound; + + /** Whether or not we were outside the frustum at the last update. */ + protected boolean _outside; + + /** Temporary transform variables. */ + protected Matrix4f _xform = new Matrix4f(); + protected Vector3f _trans = new Vector3f(), _scale = new Vector3f(); + protected Quaternion _rot = new Quaternion(); + + /** Animation completion listeners. */ + protected ObserverList _animObservers = + new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); + + /** Used to notify observers of animation initiation. */ + protected class AnimStartedOp + implements ObserverList.ObserverOp + { + public AnimStartedOp (String name) + { + _name = name; + } + + // documentation inherited from interface ObserverOp + public boolean apply (AnimationObserver obs) + { + return obs.animationStarted(Model.this, _name); + } + + /** The name of the animation started. */ + protected String _name; + } + + /** Used to notify observers of animation completion. */ + protected class AnimCompletedOp + implements ObserverList.ObserverOp + { + public AnimCompletedOp (String name) + { + _name = name; + } + + // documentation inherited from interface ObserverOp + public boolean apply (AnimationObserver obs) + { + return obs.animationCompleted(Model.this, _name); + } + + /** The name of the animation completed. */ + protected String _name; + } + + /** Used to notify observers of animation cancellation. */ + protected class AnimCancelledOp + implements ObserverList.ObserverOp + { + public AnimCancelledOp (String name) + { + _name = name; + } + + // documentation inherited from interface ObserverOp + public boolean apply (AnimationObserver obs) + { + return obs.animationCancelled(Model.this, _name); + } + + /** The name of the animation cancelled. */ + protected String _name; + } + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/ModelController.java b/src/java/com/threerings/jme/model/ModelController.java new file mode 100644 index 00000000..f129c7f7 --- /dev/null +++ b/src/java/com/threerings/jme/model/ModelController.java @@ -0,0 +1,167 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Properties; + +import com.jme.scene.Controller; +import com.jme.scene.Node; +import com.jme.scene.Spatial; + +import com.samskivert.util.StringUtil; + +/** + * The superclass of procedural animation controllers for models. + */ +public abstract class ModelController extends Controller + implements Externalizable +{ + /** + * Configures this controller based on the supplied (sub-)properties and + * controller target. + */ + public void configure (Properties props, Spatial target) + { + _target = target; + String[] anims = StringUtil.parseStringArray( + props.getProperty("animations", "")); + if (anims.length == 0) { + return; + } + _animations = new HashSet(); + Collections.addAll(_animations, anims); + } + + /** + * Returns a reference to the controller's target. + */ + public Spatial getTarget () + { + return _target; + } + + /** + * Resolves any textures required by the controller. + */ + public void resolveTextures (TextureProvider tprov) + { + } + + /** + * Initializes this controller. + */ + public void init (Model model) + { + model.addAnimationObserver(_animobs); + if (_animations != null) { + setActive(false); + } + } + + /** + * Creates or populates and returns a clone of this object using the given + * clone properties. + * + * @param store an instance of this class to populate, or null + * to create a new instance + */ + public Controller putClone ( + Controller store, Model.CloneCreator properties) + { + if (store == null) { + return null; + } + ModelController mstore = (ModelController)store; + mstore._target = ((ModelSpatial)_target).putClone(null, properties); + mstore._animations = _animations; + return mstore; + } + + // documentation inherited from interface Externalizable + public void writeExternal (ObjectOutput out) + throws IOException + { + out.writeObject(_target); + out.writeObject(_animations); + } + + // documentation inherited from interface Externalizable + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + _target = (Spatial)in.readObject(); + _animations = (HashSet)in.readObject(); + } + + /** + * Called when an animation is started on the model. + */ + protected void animationStarted (String anim) + { + if (_animations != null && _animations.contains(anim)) { + setActive(true); + } + } + + /** + * Called when an animation is stopped on the model. + */ + protected void animationStopped (String anim) + { + if (_animations != null) { + setActive(false); + } + } + + /** The target to control. */ + protected Spatial _target; + + /** The animations for which this controller should be active, or + * null for all of them. */ + protected HashSet _animations; + + /** Listens to the model's animation state. */ + protected Model.AnimationObserver _animobs = + new Model.AnimationObserver() { + public boolean animationStarted (Model model, String anim) { + ModelController.this.animationStarted(anim); + return true; + } + public boolean animationCompleted (Model model, String anim) { + animationStopped(anim); + return true; + } + public boolean animationCancelled (Model model, String anim) { + animationStopped(anim); + return true; + } + }; + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/ModelMesh.java b/src/java/com/threerings/jme/model/ModelMesh.java new file mode 100644 index 00000000..fdb936a6 --- /dev/null +++ b/src/java/com/threerings/jme/model/ModelMesh.java @@ -0,0 +1,557 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import java.util.Properties; + +import com.jme.bounding.BoundingVolume; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.Renderer; +import com.jme.scene.Controller; +import com.jme.scene.SharedMesh; +import com.jme.scene.Spatial; +import com.jme.scene.TriMesh; +import com.jme.scene.VBOInfo; +import com.jme.scene.batch.TriangleBatch; +import com.jme.scene.state.AlphaState; +import com.jme.scene.state.CullState; +import com.jme.scene.state.RenderState; +import com.jme.scene.state.TextureState; +import com.jme.scene.state.ZBufferState; +import com.jme.system.DisplaySystem; +import com.jme.util.geom.BufferUtils; + +import com.samskivert.util.StringUtil; + +import com.threerings.jme.Log; + +/** + * A {@link TriMesh} with a serialization mechanism tailored to stored models. + */ +public class ModelMesh extends TriMesh + implements Externalizable, ModelSpatial +{ + /** + * No-arg constructor for deserialization. + */ + public ModelMesh () + { + super("mesh"); + } + + /** + * Creates a mesh with no vertex data. + */ + public ModelMesh (String name) + { + super(name); + } + + /** + * Configures this mesh based on the given parameters and (sub-)properties. + * + * @param texture the texture specified in the model export, if any (can be + * overridden by textures specified in the properties) + * @param solid whether or not the mesh allows back face culling + * @param transparent whether or not the mesh is (partially) transparent + */ + public void configure ( + boolean solid, String texture, boolean transparent, Properties props) + { + _textures = (texture == null) ? null : StringUtil.parseStringArray( + props.getProperty(texture, texture)); + _solid = solid; + _transparent = transparent; + } + + /** + * Sets the buffers as {@link ByteBuffer}s, because we can't create byte + * views of non-byte buffers. This method is where the model is + * initialized after loading. + */ + public void reconstruct ( + ByteBuffer vertices, ByteBuffer normals, ByteBuffer colors, + ByteBuffer textures, ByteBuffer indices) + { + reconstruct( + vertices == null ? null : vertices.asFloatBuffer(), + normals == null ? null : normals.asFloatBuffer(), + colors == null ? null : colors.asFloatBuffer(), + textures == null ? null : textures.asFloatBuffer(), + indices == null ? null : indices.asIntBuffer()); + _vertexByteBuffer = vertices; + _normalByteBuffer = normals; + _colorByteBuffer = colors; + _textureByteBuffer = textures; + _indexByteBuffer = indices; + + // initialize the model if we're displaying + if (DisplaySystem.getDisplaySystem() == null) { + return; + } + if (_backCull == null) { + initSharedStates(); + } + if (_solid) { + setRenderState(_backCull); + } + if (_transparent) { + setRenderQueueMode(Renderer.QUEUE_TRANSPARENT); + setRenderState(_blendAlpha); + setRenderState(_overlayZBuffer); + } + } + + /** + * Adjusts the vertices and the transform of the mesh so that the mesh's + * position lies at the center of its bounding volume. + */ + public void centerVertices () + { + Vector3f offset = getBatch(0).getModelBound().getCenter().negate(); + if (!offset.equals(Vector3f.ZERO)) { + getLocalTranslation().subtractLocal(offset); + getBatch(0).getModelBound().getCenter().set(Vector3f.ZERO); + getBatch(0).translatePoints(offset); + } + } + + @Override // documentation inherited + public void reconstruct ( + FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors, + FloatBuffer textures, IntBuffer indices) + { + super.reconstruct(vertices, normals, colors, textures, indices); + + _vertexBufferSize = (vertices == null) ? 0 : vertices.capacity(); + _normalBufferSize = (normals == null) ? 0 : normals.capacity(); + _colorBufferSize = (colors == null) ? 0 : colors.capacity(); + _textureBufferSize = (textures == null) ? 0 : textures.capacity(); + _indexBufferSize = (indices == null) ? 0 : indices.capacity(); + } + + @Override // documentation inherited + public void reconstruct ( + FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors, + FloatBuffer textures) + { + super.reconstruct(vertices, normals, colors, textures); + + _vertexBufferSize = (vertices == null) ? 0 : vertices.capacity(); + _normalBufferSize = (normals == null) ? 0 : normals.capacity(); + _colorBufferSize = (colors == null) ? 0 : colors.capacity(); + _textureBufferSize = (textures == null) ? 0 : textures.capacity(); + } + + // documentation inherited from interface ModelSpatial + public Spatial putClone (Spatial store, Model.CloneCreator properties) + { + ModelMesh mstore = (ModelMesh)properties.originalToCopy.get(this); + if (mstore != null) { + return mstore; + } else if (store == null) { + mstore = new ModelMesh(getName()); + } else { + mstore = (ModelMesh)store; + } + properties.originalToCopy.put(this, mstore); + mstore.normalsMode = normalsMode; + mstore.cullMode = cullMode; + for (int ii = 0; ii < RenderState.RS_MAX_STATE; ii++) { + RenderState rstate = getRenderState(ii); + if (rstate != null) { + mstore.setRenderState(rstate); + } + } + mstore.renderQueueMode = renderQueueMode; + mstore.lockedMode = lockedMode; + mstore.lightCombineMode = lightCombineMode; + mstore.textureCombineMode = textureCombineMode; + mstore.name = name; + mstore.isCollidable = isCollidable; + mstore.localRotation.set(localRotation); + mstore.localTranslation.set(localTranslation); + mstore.localScale.set(localScale); + for (Object controller : getControllers()) { + if (controller instanceof ModelController) { + mstore.addController( + ((ModelController)controller).putClone(null, properties)); + } + } + TriangleBatch batch = (TriangleBatch)getBatch(0), + mbatch = (TriangleBatch)mstore.getBatch(0); + mbatch.setVertexBuffer(properties.isSet("vertices") ? + batch.getVertexBuffer() : + BufferUtils.clone(batch.getVertexBuffer())); + mbatch.setColorBuffer(properties.isSet("colors") ? + batch.getColorBuffer() : + BufferUtils.clone(batch.getColorBuffer())); + mbatch.setNormalBuffer(properties.isSet("normals") ? + batch.getNormalBuffer() : + BufferUtils.clone(batch.getNormalBuffer())); + FloatBuffer texcoords; + for (int ii = 0; (texcoords = batch.getTextureBuffer(ii)) != null; + ii++) { + mbatch.setTextureBuffer(properties.isSet("texcoords") ? + texcoords : BufferUtils.clone(texcoords), ii); + } + mbatch.setIndexBuffer(properties.isSet("indices") ? + batch.getIndexBuffer() : + BufferUtils.clone(batch.getIndexBuffer())); + if (properties.isSet("vboinfo")) { + mbatch.setVBOInfo(batch.getVBOInfo()); + } + if (properties.isSet("obbtree")) { + mbatch.setCollisionTree(batch.getCollisionTree()); + } + if (properties.isSet("displaylistid")) { + mbatch.setDisplayListID(batch.getDisplayListID()); + } + if (batch.getModelBound() != null) { + mbatch.setModelBound(properties.isSet("bound") ? + batch.getModelBound() : batch.getModelBound().clone(null)); + } + if (_textures != null && _textures.length > 1) { + int tidx = properties.random % _textures.length; + mstore._textures = new String[] { _textures[tidx] }; + mstore._tstates = new TextureState[] { _tstates[tidx] }; + mstore.setRenderState(_tstates[tidx]); + } else { + mstore._textures = _textures; + mstore._tstates = _tstates; + } + return mstore; + } + + @Override // documentation inherited + public void updateWorldVectors () + { + if (!_transformLocked) { + super.updateWorldVectors(); + } + } + + // documentation inherited from interface Externalizable + public void writeExternal (ObjectOutput out) + throws IOException + { + out.writeUTF(getName()); + out.writeObject(getLocalTranslation()); + out.writeObject(getLocalRotation()); + out.writeObject(getLocalScale()); + out.writeObject(getBatch(0).getModelBound()); + out.writeInt(_vertexBufferSize); + out.writeInt(_normalBufferSize); + out.writeInt(_colorBufferSize); + out.writeInt(_textureBufferSize); + out.writeInt(_indexBufferSize); + out.writeObject(_textures); + out.writeBoolean(_solid); + out.writeBoolean(_transparent); + } + + // documentation inherited from interface Externalizable + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + setName(in.readUTF()); + setLocalTranslation((Vector3f)in.readObject()); + setLocalRotation((Quaternion)in.readObject()); + setLocalScale((Vector3f)in.readObject()); + setModelBound((BoundingVolume)in.readObject()); + _vertexBufferSize = in.readInt(); + _normalBufferSize = in.readInt(); + _colorBufferSize = in.readInt(); + _textureBufferSize = in.readInt(); + _indexBufferSize = in.readInt(); + _textures = (String[])in.readObject(); + _solid = in.readBoolean(); + _transparent = in.readBoolean(); + } + + // documentation inherited from interface ModelSpatial + public void expandModelBounds () + { + // no-op + } + + // documentation inherited from interface ModelSpatial + public void setReferenceTransforms () + { + // no-op + } + + // documentation inherited from interface ModelSpatial + public void lockStaticMeshes ( + Renderer renderer, boolean useVBOs, boolean useDisplayLists) + { + if (useVBOs && renderer.supportsVBO()) { + VBOInfo vboinfo = new VBOInfo(true); + vboinfo.setVBOIndexEnabled(true); + setVBOInfo(vboinfo); + + } else if (useDisplayLists) { + lockMeshes(renderer); + } + } + + // documentation inherited from interface ModelSpatial + public void resolveTextures (TextureProvider tprov) + { + if (_textures == null) { + return; + } + _tstates = new TextureState[_textures.length]; + for (int ii = 0; ii < _textures.length; ii++) { + _tstates[ii] = tprov.getTexture(_textures[ii]); + } + if (_tstates[0] != null) { + setRenderState(_tstates[0]); + } + } + + // documentation inherited from interface ModelSpatial + public void storeMeshFrame (int frameId, boolean blend) + { + // no-op + } + + // documentation inherited from interface ModelSpatial + public void setMeshFrame (int frameId) + { + // no-op + } + + // documentation inherited from interface ModelSpatial + public void blendMeshFrames (int frameId1, int frameId2, float alpha) + { + // no-op + } + + // documentation inherited from interface ModelSpatial + public void writeBuffers (FileChannel out) + throws IOException + { + if (_vertexBufferSize > 0) { + _vertexByteBuffer.rewind(); + convertOrder(_vertexByteBuffer, ByteOrder.LITTLE_ENDIAN); + out.write(_vertexByteBuffer); + convertOrder(_vertexByteBuffer, ByteOrder.nativeOrder()); + } + if (_normalBufferSize > 0) { + _normalByteBuffer.rewind(); + convertOrder(_normalByteBuffer, ByteOrder.LITTLE_ENDIAN); + out.write(_normalByteBuffer); + convertOrder(_normalByteBuffer, ByteOrder.nativeOrder()); + } + if (_colorBufferSize > 0) { + _colorByteBuffer.rewind(); + convertOrder(_colorByteBuffer, ByteOrder.LITTLE_ENDIAN); + out.write(_colorByteBuffer); + convertOrder(_colorByteBuffer, ByteOrder.nativeOrder()); + } + if (_textureBufferSize > 0) { + _textureByteBuffer.rewind(); + convertOrder(_textureByteBuffer, ByteOrder.LITTLE_ENDIAN); + out.write(_textureByteBuffer); + convertOrder(_textureByteBuffer, ByteOrder.nativeOrder()); + } + if (_indexBufferSize > 0) { + _indexByteBuffer.rewind(); + convertOrder(_indexByteBuffer, ByteOrder.LITTLE_ENDIAN); + out.write(_indexByteBuffer); + convertOrder(_indexByteBuffer, ByteOrder.nativeOrder()); + } + } + + // documentation inherited from interface ModelSpatial + public void readBuffers (FileChannel in) + throws IOException + { + ByteBuffer vbbuf = null, nbbuf = null, cbbuf = null, tbbuf = null, + ibbuf = null; + ByteOrder le = ByteOrder.LITTLE_ENDIAN; + if (_vertexBufferSize > 0) { + vbbuf = ByteBuffer.allocateDirect(_vertexBufferSize*4).order(le); + in.read(vbbuf); + vbbuf.rewind(); + convertOrder(vbbuf, ByteOrder.nativeOrder()); + } + if (_normalBufferSize > 0) { + nbbuf = ByteBuffer.allocateDirect(_normalBufferSize*4).order(le); + in.read(nbbuf); + nbbuf.rewind(); + convertOrder(nbbuf, ByteOrder.nativeOrder()); + } + if (_colorBufferSize > 0) { + cbbuf = ByteBuffer.allocateDirect(_colorBufferSize*4).order(le); + in.read(cbbuf); + cbbuf.rewind(); + convertOrder(cbbuf, ByteOrder.nativeOrder()); + } + if (_textureBufferSize > 0) { + tbbuf = ByteBuffer.allocateDirect(_textureBufferSize*4).order(le); + in.read(tbbuf); + tbbuf.rewind(); + convertOrder(tbbuf, ByteOrder.nativeOrder()); + } + if (_indexBufferSize > 0) { + ibbuf = ByteBuffer.allocateDirect(_indexBufferSize*4).order(le); + in.read(ibbuf); + ibbuf.rewind(); + convertOrder(ibbuf, ByteOrder.nativeOrder()); + } + reconstruct(vbbuf, nbbuf, cbbuf, tbbuf, ibbuf); + } + + // documentation inherited from interface ModelSpatial + public void sliceBuffers (MappedByteBuffer map) + { + ByteBuffer vbbuf = null, nbbuf = null, cbbuf = null, tbbuf = null, + ibbuf = null; + int total = 0; + if (_vertexBufferSize > 0) { + int npos = map.position() + _vertexBufferSize*4; + map.limit(npos); + vbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN); + map.position(npos); + } + if (_normalBufferSize > 0) { + int npos = map.position() + _normalBufferSize*4; + map.limit(npos); + nbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN); + map.position(npos); + } + if (_colorBufferSize > 0) { + int npos = map.position() + _colorBufferSize*4; + map.limit(npos); + cbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN); + map.position(npos); + } + if (_textureBufferSize > 0) { + int npos = map.position() + _textureBufferSize*4; + map.limit(npos); + tbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN); + map.position(npos); + } + if (_indexBufferSize > 0) { + int npos = map.position() + _indexBufferSize*4; + map.limit(npos); + ibbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN); + map.position(npos); + } + reconstruct(vbbuf, nbbuf, cbbuf, tbbuf, ibbuf); + } + + /** + * Locks the transform and bounds of this mesh on the assumption that its + * position will not change. + */ + protected void lockInstance () + { + lockBounds(); + _transformLocked = true; + } + + /** + * Imposes the specified order on the given buffer of 32 bit values. + */ + protected static void convertOrder (ByteBuffer buf, ByteOrder order) + { + if (buf.order() == order) { + return; + } + IntBuffer obuf = buf.asIntBuffer(), + nbuf = buf.order(order).asIntBuffer(); + while (obuf.hasRemaining()) { + nbuf.put(obuf.get()); + } + } + + /** + * Initializes the states shared between all models. Requires an active + * display. + */ + protected static void initSharedStates () + { + Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer(); + _backCull = renderer.createCullState(); + _backCull.setCullMode(CullState.CS_BACK); + _blendAlpha = renderer.createAlphaState(); + _blendAlpha.setBlendEnabled(true); + _overlayZBuffer = renderer.createZBufferState(); + _overlayZBuffer.setFunction(ZBufferState.CF_LEQUAL); + _overlayZBuffer.setWritable(false); + } + + /** The sizes of the various buffers (zero for null). */ + protected int _vertexBufferSize, _normalBufferSize, _colorBufferSize, + _textureBufferSize, _indexBufferSize; + + /** The backing byte buffers for the various buffers. */ + protected ByteBuffer _vertexByteBuffer, _normalByteBuffer, + _colorByteBuffer, _textureByteBuffer, _indexByteBuffer; + + /** The type of bounding volume that this mesh should use. */ + protected int _boundingType; + + /** The name of this model's textures, or null for none. */ + protected String[] _textures; + + /** Whether or not this mesh can enable back-face culling. */ + protected boolean _solid; + + /** Whether or not this mesh must be rendered as transparent. */ + protected boolean _transparent; + + /** For prototype meshes, the resolved texture states. */ + protected TextureState[] _tstates; + + /** Whether or not the transform has been locked. This operates in a + * slightly different way than JME's locking, in that it allows applying + * transformations to display lists. */ + protected boolean _transformLocked; + + /** The shared state for back face culling. */ + protected static CullState _backCull; + + /** The shared state for alpha blending. */ + protected static AlphaState _blendAlpha; + + /** The shared state for checking, but not writing to, the z buffer. */ + protected static ZBufferState _overlayZBuffer; + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/ModelNode.java b/src/java/com/threerings/jme/model/ModelNode.java new file mode 100644 index 00000000..9af6b79e --- /dev/null +++ b/src/java/com/threerings/jme/model/ModelNode.java @@ -0,0 +1,407 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.DataOutput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import java.util.ArrayList; +import java.util.HashSet; + +import com.jme.math.Matrix4f; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.Renderer; +import com.jme.scene.Controller; +import com.jme.scene.Node; +import com.jme.scene.Spatial; +import com.jme.scene.state.RenderState; + +import com.threerings.jme.Log; + +/** + * A {@link Node} with a serialization mechanism tailored to stored models. + */ +public class ModelNode extends Node + implements Externalizable, ModelSpatial +{ + /** + * No-arg constructor for deserialization. + */ + public ModelNode () + { + super("node"); + } + + /** + * Standard constructor. + */ + public ModelNode (String name) + { + super(name); + } + + /** + * Recursively searches the scene graph rooted at this node for a + * node with the provided name. + */ + public Spatial getDescendant (String name) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child.getName().equals(name)) { + return child; + } else if (child instanceof ModelNode) { + child = ((ModelNode)child).getDescendant(name); + if (child != null) { + return child; + } + } + } + return null; + } + + /** + * Returns a reference to the model space transform of the node. + */ + public Matrix4f getModelTransform () + { + return _modelTransform; + } + + @Override // documentation inherited + public void updateWorldData (float time) + { + // we use locked bounds as an indication that we can skip the update + // altogether + if ((lockedMode & LOCKED_BOUNDS) == 0) { + super.updateWorldData(time); + } + } + + @Override // documentation inherited + public void updateWorldBound () + { + // if the node is culled, there are no mesh descendants and thus no + // bounds + if (cullMode != CULL_ALWAYS) { + super.updateWorldBound(); + } + } + + @Override // documentation inherited + public void updateWorldVectors () + { + super.updateWorldVectors(); + if (parent instanceof ModelNode) { + setTransform(getLocalTranslation(), getLocalRotation(), + getLocalScale(), _localTransform); + ((ModelNode)parent).getModelTransform().mult(_localTransform, + _modelTransform); + + } else { + _modelTransform.loadIdentity(); + } + } + + // documentation inherited from interface ModelSpatial + public Spatial putClone (Spatial store, Model.CloneCreator properties) + { + ModelNode mstore = (ModelNode)properties.originalToCopy.get(this); + if (mstore != null) { + return mstore; + } else if (store == null) { + mstore = new ModelNode(getName()); + } else { + mstore = (ModelNode)store; + } + properties.originalToCopy.put(this, mstore); + mstore.normalsMode = normalsMode; + mstore.cullMode = cullMode; + for (int ii = 0; ii < RenderState.RS_MAX_STATE; ii++) { + RenderState rstate = getRenderState(ii); + if (rstate != null) { + mstore.setRenderState(rstate); + } + } + mstore.renderQueueMode = renderQueueMode; + mstore.lockedMode = lockedMode; + mstore.lightCombineMode = lightCombineMode; + mstore.textureCombineMode = textureCombineMode; + mstore.name = name; + mstore.isCollidable = isCollidable; + mstore.localRotation.set(localRotation); + mstore.localTranslation.set(localTranslation); + mstore.localScale.set(localScale); + for (Object controller : getControllers()) { + if (controller instanceof ModelController) { + mstore.addController( + ((ModelController)controller).putClone(null, properties)); + } + } + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + mstore.attachChild( + ((ModelSpatial)child).putClone(null, properties)); + } + } + return mstore; + } + + // documentation inherited from interface Externalizable + public void writeExternal (ObjectOutput out) + throws IOException + { + out.writeUTF(getName()); + out.writeObject(getLocalTranslation()); + out.writeObject(getLocalRotation()); + out.writeObject(getLocalScale()); + out.writeObject(getChildren()); + } + + // documentation inherited from interface Externalizable + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + setName(in.readUTF()); + setLocalTranslation((Vector3f)in.readObject()); + setLocalRotation((Quaternion)in.readObject()); + setLocalScale((Vector3f)in.readObject()); + ArrayList children = (ArrayList)in.readObject(); + if (children != null) { + for (Spatial child : children) { + attachChild(child); + } + } + } + + // documentation inherited from interface ModelSpatial + public void expandModelBounds () + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).expandModelBounds(); + } + } + } + + // documentation inherited from interface ModelSpatial + public void setReferenceTransforms () + { + updateWorldVectors(); + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).setReferenceTransforms(); + } + } + } + + // documentation inherited from interface ModelSpatial + public void lockStaticMeshes ( + Renderer renderer, boolean useVBOs, boolean useDisplayLists) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).lockStaticMeshes(renderer, useVBOs, + useDisplayLists); + } + } + } + + // documentation inherited from interface ModelSpatial + public void resolveTextures (TextureProvider tprov) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).resolveTextures(tprov); + } + } + } + + // documentation inherited from interface ModelSpatial + public void storeMeshFrame (int frameId, boolean blend) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).storeMeshFrame(frameId, blend); + } + } + } + + // documentation inherited from interface ModelSpatial + public void setMeshFrame (int frameId) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).setMeshFrame(frameId); + } + } + } + + // documentation inherited from interface ModelSpatial + public void blendMeshFrames (int frameId1, int frameId2, float alpha) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).blendMeshFrames( + frameId1, frameId2, alpha); + } + } + } + + // documentation inherited from interface ModelSpatial + public void writeBuffers (FileChannel out) + throws IOException + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).writeBuffers(out); + } + } + } + + // documentation inherited from interface ModelSpatial + public void readBuffers (FileChannel in) + throws IOException + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).readBuffers(in); + } + } + } + + // documentation inherited from interface ModelSpatial + public void sliceBuffers (MappedByteBuffer map) + { + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (child instanceof ModelSpatial) { + ((ModelSpatial)child).sliceBuffers(map); + } + } + } + + /** + * Sets the cull state of any nodes that do not contain geometric + * descendants to {@link CULL_ALWAYS} so that they don't waste + * rendering time. + * + * @return true if this node should be drawn, false if it contains + * no mesh descendants + */ + protected boolean cullInvisibleNodes () + { + boolean hasVisibleDescendants = false; + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (!(child instanceof ModelNode) || + ((ModelNode)child).cullInvisibleNodes()) { + hasVisibleDescendants = true; + } + } + setCullMode(hasVisibleDescendants ? CULL_INHERIT : CULL_ALWAYS); + return hasVisibleDescendants; + } + + /** + * Locks the transforms and bounds of this instance with the assumption + * that the position will never change. + * + * @param targets the targets of the model's controllers, which determine + * the subset of nodes that can be locked + * @return true if this node is a target or contains any targets, otherwise + * false + */ + protected boolean lockInstance (HashSet targets) + { + updateWorldVectors(); + lockedMode |= LOCKED_TRANSFORMS; + + boolean containsTargets = false; + for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { + Spatial child = getChild(ii); + if (targets.contains(child) || (child instanceof ModelNode && + ((ModelNode)child).lockInstance(targets))) { + containsTargets = true; + + } else if (child instanceof ModelMesh) { + ((ModelMesh)child).lockInstance(); + } + } + if (containsTargets) { + return true; + } else { + updateWorldBound(); + lockedMode |= LOCKED_BOUNDS; + return false; + } + } + + /** + * Sets a matrix to the transform defined by the given translation, + * rotation, and scale values. + */ + protected static Matrix4f setTransform ( + Vector3f translation, Quaternion rotation, Vector3f scale, + Matrix4f result) + { + result.set(rotation); + result.setTranslation(translation); + + result.m00 *= scale.x; + result.m01 *= scale.y; + result.m02 *= scale.z; + + result.m10 *= scale.x; + result.m11 *= scale.y; + result.m12 *= scale.z; + + result.m20 *= scale.x; + result.m21 *= scale.y; + result.m22 *= scale.z; + + return result; + } + + /** The node's transform in local and model space. */ + protected Matrix4f _localTransform = new Matrix4f(), + _modelTransform = new Matrix4f(); + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/ModelSpatial.java b/src/java/com/threerings/jme/model/ModelSpatial.java new file mode 100644 index 00000000..bb85ce6d --- /dev/null +++ b/src/java/com/threerings/jme/model/ModelSpatial.java @@ -0,0 +1,115 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.Externalizable; +import java.io.IOException; + +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import com.jme.math.Matrix4f; +import com.jme.renderer.Renderer; +import com.jme.scene.Spatial; + +/** + * Contains method common to both {@link ModelNode}s and {@link ModelMesh}es. + */ +public interface ModelSpatial +{ + /** + * Recursively expands the model bounds of any deformable meshes so that + * they include the current vertex positions. + */ + public void expandModelBounds (); + + /** + * Recursively sets the reference transforms for any bones in the model. + */ + public void setReferenceTransforms (); + + /** + * Recursively compiles any static meshes to vertex buffer objects (VBOs) + * or display lists. + * + * @param useVBOs if true, use VBOs if the graphics card supports them + * @param useDisplayLists if true and not using VBOs, compile static + * objects to display lists + */ + public void lockStaticMeshes ( + Renderer renderer, boolean useVBOs, boolean useDisplayLists); + + /** + * Recursively resolves texture references using the given provider. + */ + public void resolveTextures (TextureProvider tprov); + + /** + * Recursively requests that the current state of all skinned meshes be + * stored as an animation frame on the next update. + * + * @param frameId the frame id, which uniquely identifies one frame of + * one animation + * @param blend whether or not the stored frames will be retrieved by + * calls to {@link #blendAnimationFrames} as opposed to + * {@link #setAnimationFrames} + */ + public void storeMeshFrame (int frameId, boolean blend); + + /** + * Recursively switches all skinned meshes to a stored animation frame for + * the next update. + */ + public void setMeshFrame (int frameId); + + /** + * Recursively blends all skinned meshes between two stored animation + * frames for the next update. + */ + public void blendMeshFrames (int frameId1, int frameId2, float alpha); + + /** + * Creates or populates and returns a clone of this object using the given + * clone properties. + * + * @param store an instance of this class to populate, or null + * to create a new instance + */ + public Spatial putClone (Spatial store, Model.CloneCreator properties); + + /** + * Recursively writes any data buffers to the output channel. + */ + public void writeBuffers (FileChannel out) + throws IOException; + + /** + * Recursively reads any data buffers from the input channel. + */ + public void readBuffers (FileChannel in) + throws IOException; + + /** + * Recursively slices any data buffers from the buffer map. + */ + public void sliceBuffers (MappedByteBuffer map); +} diff --git a/src/java/com/threerings/jme/model/Rotator.java b/src/java/com/threerings/jme/model/Rotator.java new file mode 100644 index 00000000..e99da213 --- /dev/null +++ b/src/java/com/threerings/jme/model/Rotator.java @@ -0,0 +1,128 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +import java.util.Properties; + +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.scene.Controller; +import com.jme.scene.Spatial; + +import com.samskivert.util.StringUtil; + +import com.threerings.jme.Log; + +/** + * A procedural animation that rotates a node around at a constant angular + * velocity. + */ +public class Rotator extends ModelController +{ + @Override // documentation inherited + public void configure (Properties props, Spatial target) + { + super.configure(props, target); + String axisstr = props.getProperty("axis", "x"), + rpsstr = props.getProperty("radpersec", "3.14"); + if (axisstr.equalsIgnoreCase("x")) { + _axis = Vector3f.UNIT_X; + } else if (axisstr.equalsIgnoreCase("y")) { + _axis = Vector3f.UNIT_Y; + } else if (axisstr.equalsIgnoreCase("z")) { + _axis = Vector3f.UNIT_Z; + } else { + float[] axis = StringUtil.parseFloatArray(axisstr); + if (axis != null && axis.length == 3) { + _axis = new Vector3f(axis[0], axis[1], + axis[2]).normalizeLocal(); + + } else { + Log.warning("Invalid rotation axis [axis=" + axisstr + "]."); + } + } + try { + _radpersec = Float.parseFloat(rpsstr); + } catch (NumberFormatException e) { + Log.warning("Invalid rotation rate [radpersec=" + rpsstr + "]."); + } + } + + // documentation inherited + public void update (float time) + { + if (!isActive()) { + return; + } + _rot.fromAngleNormalAxis(time * _radpersec, _axis); + _target.getLocalRotation().multLocal(_rot); + } + + @Override // documentation inherited + public Controller putClone ( + Controller store, Model.CloneCreator properties) + { + Rotator rstore; + if (store == null) { + rstore = new Rotator(); + } else { + rstore = (Rotator)store; + } + super.putClone(rstore, properties); + rstore._axis = _axis; + rstore._radpersec = _radpersec; + return rstore; + } + + // documentation inherited from interface Externalizable + public void writeExternal (ObjectOutput out) + throws IOException + { + super.writeExternal(out); + out.writeObject(_axis); + out.writeFloat(_radpersec); + } + + // documentation inherited from interface Externalizable + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + super.readExternal(in); + _axis = (Vector3f)in.readObject(); + _radpersec = in.readFloat(); + } + + /** The axis about which to rotate. */ + protected Vector3f _axis; + + /** The velocity at which to rotate in radians per second. */ + protected float _radpersec; + + /** A temporary quaternion. */ + protected Quaternion _rot = new Quaternion(); + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/SkinMesh.java b/src/java/com/threerings/jme/model/SkinMesh.java new file mode 100644 index 00000000..e9a21e83 --- /dev/null +++ b/src/java/com/threerings/jme/model/SkinMesh.java @@ -0,0 +1,495 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.Serializable; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; + +import com.jme.bounding.BoundingVolume; +import com.jme.math.Matrix4f; +import com.jme.math.Vector3f; +import com.jme.renderer.Renderer; +import com.jme.scene.Spatial; +import com.jme.scene.TriMesh; +import com.jme.scene.VBOInfo; +import com.jme.scene.batch.SharedBatch; +import com.jme.scene.batch.TriangleBatch; +import com.jme.system.DisplaySystem; +import com.jme.util.geom.BufferUtils; + +import com.samskivert.util.HashIntMap; + +import com.threerings.jme.Log; + +/** + * A triangle mesh that deforms according to a bone hierarchy. + */ +public class SkinMesh extends ModelMesh +{ + /** Represents the vertex weights of a group of vertices influenced by the + * same set of bones. */ + public static class WeightGroup + implements Serializable + { + /** The number of vertices in this weight group. */ + public int vertexCount; + + /** The bones influencing this group. */ + public Bone[] bones; + + /** The array of interleaved weights (of length vertexCount * + * boneIndices.length): weights for first vertex, weights for + * second, etc. */ + public float[] weights; + + /** + * Rebinds this weight group for a prototype instance. + * + * @param bmap the mapping from prototype to instance bones + */ + public WeightGroup rebind (HashMap bmap) + { + WeightGroup wgroup = new WeightGroup(); + wgroup.vertexCount = vertexCount; + wgroup.bones = new Bone[bones.length]; + for (int ii = 0; ii < bones.length; ii++) { + wgroup.bones[ii] = bmap.get(bones[ii]); + } + wgroup.weights = weights; + return wgroup; + } + + private static final long serialVersionUID = 1; + } + + /** Represents a bone that influences the mesh. */ + public static class Bone + implements Serializable + { + /** The node that defines the bone's position. */ + public ModelNode node; + + /** The inverse of the bone's model space reference transform. */ + public transient Matrix4f invRefTransform; + + /** The bone's current transform in model space. */ + public transient Matrix4f transform; + + public Bone (ModelNode node) + { + this.node = node; + transform = new Matrix4f(); + } + + /** + * Rebinds this bone for a prototype instance. + * + * @param pnodes a mapping from prototype nodes to instance nodes + */ + public Bone rebind (HashMap pnodes) + { + Bone bone = new Bone((ModelNode)pnodes.get(node)); + bone.invRefTransform = invRefTransform; + bone.transform = new Matrix4f(); + return bone; + } + + /** + * Initializes the bone's transient state. + */ + private void readObject (ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + transform = new Matrix4f(); + } + + private static final long serialVersionUID = 1; + } + + /** + * No-arg constructor for deserialization. + */ + public SkinMesh () + { + } + + /** + * Creates an empty mesh. + */ + public SkinMesh (String name) + { + super(name); + } + + /** + * Sets the array of weight groups that determine how bones affect + * each vertex. + */ + public void setWeightGroups (WeightGroup[] weightGroups) + { + _weightGroups = weightGroups; + + // compile a list of all referenced bones + HashSet bones = new HashSet(); + for (WeightGroup group : weightGroups) { + Collections.addAll(bones, group.bones); + } + _bones = bones.toArray(new Bone[bones.size()]); + } + + @Override // documentation inherited + public void reconstruct ( + ByteBuffer vertices, ByteBuffer normals, ByteBuffer colors, + ByteBuffer textures, ByteBuffer indices) + { + super.reconstruct(vertices, normals, colors, textures, indices); + + // store the current buffers as the originals + storeOriginalBuffers(); + + // initialize the quantized frame table + _frames = new HashIntMap(); + } + + @Override // documentation inherited + public void centerVertices () + { + super.centerVertices(); + storeOriginalBuffers(); + } + + @Override // documentation inherited + public Spatial putClone (Spatial store, Model.CloneCreator properties) + { + SkinMesh mstore = (SkinMesh)properties.originalToCopy.get(this); + if (mstore != null) { + return mstore; + } else if (store == null) { + mstore = new SkinMesh(getName()); + } else { + mstore = (SkinMesh)store; + } + properties.removeProperty("vertices"); + properties.removeProperty("normals"); + properties.removeProperty("displaylistid"); + super.putClone(mstore, properties); + properties.addProperty("vertices"); + properties.addProperty("normals"); + properties.addProperty("displaylistid"); + mstore._frames = _frames; + mstore._useDisplayLists = _useDisplayLists; + mstore._invRefTransform = _invRefTransform; + mstore._bones = new Bone[_bones.length]; + HashMap bmap = new HashMap(); + for (int ii = 0; ii < _bones.length; ii++) { + bmap.put(_bones[ii], mstore._bones[ii] = + _bones[ii].rebind(properties.originalToCopy)); + } + mstore._weightGroups = new WeightGroup[_weightGroups.length]; + for (int ii = 0; ii < _weightGroups.length; ii++) { + mstore._weightGroups[ii] = _weightGroups[ii].rebind(bmap); + } + mstore._ovbuf = _ovbuf; + mstore._onbuf = _onbuf; + mstore._vbuf = new float[_vbuf.length]; + mstore._nbuf = new float[_nbuf.length]; + return mstore; + } + + @Override // documentation inherited + public void writeExternal (ObjectOutput out) + throws IOException + { + super.writeExternal(out); + out.writeObject(_weightGroups); + } + + @Override // documentation inherited + public void readExternal (ObjectInput in) + throws IOException, ClassNotFoundException + { + super.readExternal(in); + setWeightGroups((WeightGroup[])in.readObject()); + } + + @Override // documentation inherited + public void expandModelBounds () + { + BoundingVolume obound = + (BoundingVolume)getBatch(0).getModelBound().clone(null); + updateModelBound(); + getBatch(0).getModelBound().mergeLocal(obound); + } + + @Override // documentation inherited + public void setReferenceTransforms () + { + _invRefTransform = new Matrix4f(); + if (parent instanceof ModelNode) { + Matrix4f transform = new Matrix4f(); + ModelNode.setTransform(getLocalTranslation(), getLocalRotation(), + getLocalScale(), transform); + ((ModelNode)parent).getModelTransform().mult(transform, + _invRefTransform); + _invRefTransform.invertLocal(); + } + for (Bone bone : _bones) { + bone.invRefTransform = + _invRefTransform.mult(bone.node.getModelTransform()).invert(); + } + } + + @Override // documentation inherited + public void lockStaticMeshes ( + Renderer renderer, boolean useVBOs, boolean useDisplayLists) + { + // we can use VBOs for color, texture, and indices + if (useVBOs && renderer.supportsVBO()) { + VBOInfo vboinfo = new VBOInfo(false); + vboinfo.setVBOColorEnabled(true); + vboinfo.setVBOTextureEnabled(true); + vboinfo.setVBOIndexEnabled(true); + setVBOInfo(vboinfo); + } + _useDisplayLists = useDisplayLists; + } + + @Override // documentation inherited + public void storeMeshFrame (int frameId, boolean blend) + { + _storeFrameId = frameId; + _storeBlend = blend; + } + + @Override // documentation inherited + public void setMeshFrame (int frameId) + { + TriangleBatch batch = getBatch(0), + tbatch = (TriangleBatch)_frames.get(frameId); + if (batch instanceof SharedBatch) { + ((SharedBatch)batch).setTarget(tbatch); + } else { + clearBatches(); + addBatch(new SharedBatch(tbatch)); + getBatch(0).updateRenderState(); + } + } + + @Override // documentation inherited + public void blendMeshFrames (int frameId1, int frameId2, float alpha) + { + BlendFrame frame1 = (BlendFrame)_frames.get(frameId1), + frame2 = (BlendFrame)_frames.get(frameId2); + frame1.blend(frame2, alpha, _vbuf, _nbuf); + FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); + vbuf.rewind(); + vbuf.put(_vbuf); + nbuf.rewind(); + nbuf.put(_nbuf); + } + + @Override // documentation inherited + public void updateWorldData (float time) + { + super.updateWorldData(time); + if (_weightGroups == null || _storeFrameId == -1) { + return; + } + // update the bone transforms + for (Bone bone : _bones) { + _invRefTransform.mult(bone.node.getModelTransform(), + bone.transform); + bone.transform.multLocal(bone.invRefTransform); + } + + // deform the mesh according to the positions of the bones (this code + // is ugly as sin because it's optimized at a low level) + Bone[] bones; + int vertexCount, jj, kk, ww; + float[] weights; + Matrix4f m; + float weight, ovx, ovy, ovz, onx, ony, onz, vx, vy, vz, nx, ny, nz; + for (int ii = 0, bidx = 0; ii < _weightGroups.length; ii++) { + vertexCount = _weightGroups[ii].vertexCount; + bones = _weightGroups[ii].bones; + weights = _weightGroups[ii].weights; + for (jj = 0, ww = 0; jj < vertexCount; jj++) { + ovx = _ovbuf[bidx]; + ovy = _ovbuf[bidx + 1]; + ovz = _ovbuf[bidx + 2]; + onx = _onbuf[bidx]; + ony = _onbuf[bidx + 1]; + onz = _onbuf[bidx + 2]; + vx = vy = vz = 0f; + nx = ny = nz = 0f; + for (kk = 0; kk < bones.length; kk++) { + m = bones[kk].transform; + weight = weights[ww++]; + + vx += (ovx*m.m00 + ovy*m.m01 + ovz*m.m02 + m.m03) * weight; + vy += (ovx*m.m10 + ovy*m.m11 + ovz*m.m12 + m.m13) * weight; + vz += (ovx*m.m20 + ovy*m.m21 + ovz*m.m22 + m.m23) * weight; + + nx += (onx*m.m00 + ony*m.m01 + onz*m.m02) * weight; + ny += (onx*m.m10 + ony*m.m11 + onz*m.m12) * weight; + nz += (onx*m.m20 + ony*m.m21 + onz*m.m22) * weight; + } + _vbuf[bidx] = vx; + _vbuf[bidx + 1] = vy; + _vbuf[bidx + 2] = vz; + _nbuf[bidx++] = nx; + _nbuf[bidx++] = ny; + _nbuf[bidx++] = nz; + } + } + + // if skinning in real time, copy the data from arrays to buffers; + // otherwise, store the mesh as an animation frame + if (_storeFrameId == 0) { + FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); + vbuf.rewind(); + vbuf.put(_vbuf); + nbuf.rewind(); + nbuf.put(_nbuf); + } else { + storeFrame(); + _storeFrameId = -1; + } + } + + /** + * Stores the current frame data for later use. + */ + protected void storeFrame () + { + if (_storeBlend) { + _frames.put(_storeFrameId, new BlendFrame( + (float[])_vbuf.clone(), (float[])_nbuf.clone())); + } else { + TriangleBatch batch = getBatch(0), tbatch = new TriangleBatch(); + tbatch.setParentGeom(DUMMY_MESH); + tbatch.setColorBuffer(batch.getColorBuffer()); + tbatch.setTextureBuffer(batch.getTextureBuffer(0), 0); + tbatch.setIndexBuffer(batch.getIndexBuffer()); + tbatch.setVertexBuffer(BufferUtils.createFloatBuffer(_vbuf)); + tbatch.setNormalBuffer(BufferUtils.createFloatBuffer(_nbuf)); + VBOInfo ovboinfo = batch.getVBOInfo(); + if (ovboinfo != null) { + VBOInfo vboinfo = new VBOInfo(true); + vboinfo.setVBOIndexEnabled(true); + vboinfo.setVBOColorID(ovboinfo.getVBOColorID()); + vboinfo.setVBOTextureID(0, ovboinfo.getVBOTextureID(0)); + vboinfo.setVBOIndexID(ovboinfo.getVBOIndexID()); + tbatch.setVBOInfo(vboinfo); + } else if (_useDisplayLists) { + tbatch.lockMeshes( + DisplaySystem.getDisplaySystem().getRenderer()); + } + _frames.put(_storeFrameId, tbatch); + } + } + + /** + * Stores the current vertex and normal buffers for later deformation. + */ + protected void storeOriginalBuffers () + { + FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); + vbuf.rewind(); + nbuf.rewind(); + FloatBuffer.wrap(_ovbuf = new float[vbuf.capacity()]).put(vbuf); + FloatBuffer.wrap(_onbuf = new float[nbuf.capacity()]).put(nbuf); + _vbuf = new float[_ovbuf.length]; + _nbuf = new float[_onbuf.length]; + } + + /** A stored frame used for linear blending. */ + protected static class BlendFrame + { + /** The skinned vertex and normal values. */ + public float[] vbuf, nbuf; + + public BlendFrame (float[] vbuf, float[] nbuf) + { + this.vbuf = vbuf; + this.nbuf = nbuf; + } + + public void blend ( + BlendFrame next, float alpha, float[] rvbuf, float[] rnbuf) + { + float[] nvbuf = next.vbuf, nnbuf = next.nbuf; + float ialpha = 1f - alpha; + for (int ii = 0, nn = vbuf.length; ii < nn; ii++) { + rvbuf[ii] = vbuf[ii] * ialpha + nvbuf[ii] * alpha; + rnbuf[ii] = nbuf[ii] * ialpha + nnbuf[ii] * alpha; + } + } + } + + /** Pre-skinned {@link TriangleBatch}es or {@link BlendFrame}s shared + * between all instances corresponding to frame ids from + * {@link #storeAnimationFrame}. */ + protected HashIntMap _frames; + + /** Whether or to use display lists if VBOs are unavailable for quantized + * meshes. */ + protected boolean _useDisplayLists; + + /** The inverse of the model space reference transform. */ + protected Matrix4f _invRefTransform; + + /** The groups of vertices influenced by different sets of bones. */ + protected WeightGroup[] _weightGroups; + + /** The bones referenced by the weight groups. */ + protected Bone[] _bones; + + /** The original (undeformed) vertex and normal buffers and the deformed + * versions. */ + protected float[] _ovbuf, _onbuf, _vbuf, _nbuf; + + /** The frame id to store on the next update. If 0, don't store any frame + * and skin the mesh as normal. If -1, a frame has been stored and thus + * skinning should only take place when further frames are requested. */ + protected int _storeFrameId; + + /** Whether or not the stored frame id will be used for blending. */ + protected boolean _storeBlend; + + /** A dummy mesh that simply hold transformation values. */ + protected static final TriMesh DUMMY_MESH = new TriMesh(); + + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/model/TextureProvider.java b/src/java/com/threerings/jme/model/TextureProvider.java new file mode 100644 index 00000000..9734f7ad --- /dev/null +++ b/src/java/com/threerings/jme/model/TextureProvider.java @@ -0,0 +1,39 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.model; + +import com.jme.scene.state.TextureState; + +/** + * Provides a means for models to resolve their texture references. + */ +public interface TextureProvider +{ + /** + * Returns a texture state containing the named texture. + * + * @param name the name of the texture, which will be interpreted as an + * absolute resource path if it starts with a forward slash; otherwise, + * as a relative resource path + */ + public TextureState getTexture (String name); +} diff --git a/src/java/com/threerings/jme/package.html b/src/java/com/threerings/jme/package.html new file mode 100644 index 00000000..e6df5fa9 --- /dev/null +++ b/src/java/com/threerings/jme/package.html @@ -0,0 +1,15 @@ + + + + + + + + + Defines extensions to jMonkeyEngine + an OpenGL-based 3D rendering engine. An application framework is + provided that integrates jME with the Presents distributed object + system and other useful bits and bobs are also included. + + + diff --git a/src/java/com/threerings/jme/sprite/BallisticPath.java b/src/java/com/threerings/jme/sprite/BallisticPath.java new file mode 100644 index 00000000..51ad7b83 --- /dev/null +++ b/src/java/com/threerings/jme/sprite/BallisticPath.java @@ -0,0 +1,92 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.math.FastMath; +import com.jme.math.Vector3f; + +/** + * Moves a sprite ballistically. + */ +public class BallisticPath extends Path +{ + /** Gravity: it's the law. */ + public static final float G = -9.8f; + + /** + * Moves the supplied sprite from the starting coordinate (which will + * be modified) using the starting velocity, under the specified + * acceleration. + */ + public BallisticPath (Sprite sprite, Vector3f start, Vector3f velocity, + Vector3f accel, float duration) + { + super(sprite); + _curpos = start; + _velocity = velocity; + _accel = accel; + _duration = duration; + } + + // documentation inherited + public void update (float time) + { + // adjust the position + _velocity.mult(time, _temp); + _curpos.addLocal(_temp); + _sprite.setLocalTranslation(_curpos); + + // check to see if we're done + _accum += time; + if (_accum >= _duration) { + _sprite.pathCompleted(); + } else { + // adjust our velocity due to acceleration + _accel.mult(time, _temp); + _velocity.addLocal(_temp); + } + } + + /** + * Computes and returns the angle of elevation needed to launch a + * ballistic projectile at the specified velocity and have it travel + * the specified range (when it will once again reach the launch + * elevation). + */ + public static float computeElevation (float range, float vel, float accel) + { + return FastMath.asin(accel * range / (vel * vel)) / 2; + } + + /** + * Computes and returns the flight time of a projectile launched at an + * angle previously computed with {@link #computeElevation}.. + */ + public static float computeFlightTime (float range, float vel, float angle) + { + return range / (vel * FastMath.cos(angle)); + } + + protected Vector3f _curpos, _velocity, _accel; + protected float _duration, _accum; + protected Vector3f _temp = new Vector3f(0, 0, 0); +} diff --git a/src/java/com/threerings/jme/sprite/LinePath.java b/src/java/com/threerings/jme/sprite/LinePath.java new file mode 100644 index 00000000..dc973cd4 --- /dev/null +++ b/src/java/com/threerings/jme/sprite/LinePath.java @@ -0,0 +1,60 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.math.Vector3f; + +/** + * Moves a sprite along a straight line. + */ +public class LinePath extends Path +{ + /** + * Moves the supplied sprite from the starting coordinate to the + * specified destination coordinate in the specified time. + */ + public LinePath (Sprite sprite, Vector3f start, Vector3f finish, + float duration) + { + super(sprite); + _start = start; + _finish = finish; + _duration = duration; + } + + // documentation inherited + public void update (float time) + { + _accum += time; + if (_accum >= _duration) { + _sprite.setLocalTranslation(_finish); + _sprite.pathCompleted(); + } else { + _temp.interpolate(_start, _finish, _accum / _duration); + _sprite.setLocalTranslation(_temp); + } + } + + protected Vector3f _start, _finish; + protected float _duration, _accum; + protected Vector3f _temp = new Vector3f(0, 0, 0); +} diff --git a/src/java/com/threerings/jme/sprite/LineSegmentPath.java b/src/java/com/threerings/jme/sprite/LineSegmentPath.java new file mode 100644 index 00000000..9d62f4f9 --- /dev/null +++ b/src/java/com/threerings/jme/sprite/LineSegmentPath.java @@ -0,0 +1,103 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; + +/** + * Moves a sprite along a series of straight lines. + */ +public class LineSegmentPath extends Path +{ + /** + * Creates a path for the supplied sprite traversing the supplied + * series of points with the specified duration between points. + * + * @param points a list of points between which the sprite will be + * moved linearly (the sprite will be moved immediately to the first + * point). + * @param durations defines the elapsed time between each successive + * traversal. This will as a result be shorter by one element than the + * points array. + */ + public LineSegmentPath (Sprite sprite, Vector3f up, Vector3f orient, + Vector3f[] points, float[] durations) + { + super(sprite); + _up = up; + _orient = orient; + _points = points; + _durations = durations; + updateRotation(); + } + + // documentation inherited + public void update (float time) + { + // note the accumulated time + _accum += time; + + // if we have surpassed the time for this segment, subtract the + // segment time and move on to the next segment + while (_current < _durations.length && _accum > _durations[_current]) { + _accum -= _durations[_current]; + advance(); + } + + // if we have completed our path, move the sprite to the final + // position and wrap everything up + if (_current >= _durations.length) { + _sprite.setLocalTranslation(_points[_points.length-1]); + _sprite.pathCompleted(); + return; + } + + // move the sprite to the appropriate position between points + _temp.interpolate(_points[_current], _points[_current+1], + _accum / _durations[_current]); + _sprite.setLocalTranslation(_temp); + } + + protected void advance () + { + _current++; + if (_current < _points.length-1) { + updateRotation(); + } + } + + protected void updateRotation () + { + _points[_current+1].subtract(_points[_current], _temp); + PathUtil.computeRotation(_up, _orient, _temp, _rotate); + _sprite.getLocalRotation().set(_rotate); + } + + protected Vector3f _up, _orient; + protected Vector3f[] _points; + protected float[] _durations; + protected float _accum; + protected int _current; + protected Vector3f _temp = new Vector3f(0, 0, 0); + protected Quaternion _rotate = new Quaternion(); +} diff --git a/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java b/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java new file mode 100644 index 00000000..7f85b38d --- /dev/null +++ b/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java @@ -0,0 +1,70 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; + +/** + * A ballistic path that orients the sprite toward the velocity vector as + * it traverses the path. + */ +public class OrientingBallisticPath extends BallisticPath +{ + /** + * Creates a {@link BallisticPath} that will rotate the sprite so that + * the supplied orient is aligned with the velocity + * vector at all points along the path. If the provided orientation is + * not initially in line with the starting velocity, the sprite will + * be rotated immediately and then adjusted as it follows the path. + */ + public OrientingBallisticPath ( + Sprite sprite, Vector3f orient, Vector3f start, Vector3f velocity, + Vector3f accel, float duration) + { + super(sprite, start, velocity, accel, duration); + + // TODO: handle orient that is not (1, 0, 0) + _orient = orient; + + // compute the up vector (opposite of acceleration) + _up = accel.negate(); + _up.normalizeLocal(); + + _sprite.setLocalRotation( + PathUtil.computeAxisRotation(_up, velocity, _rotate)); + } + + // documentation inherited + public void update (float time) + { + // do the normal update + super.update(time); + + _sprite.setLocalRotation( + PathUtil.computeAxisRotation(_up, _velocity, _rotate)); + } + + protected Vector3f _orient; + protected Vector3f _up; + protected Quaternion _rotate = new Quaternion(); +} diff --git a/src/java/com/threerings/jme/sprite/Path.java b/src/java/com/threerings/jme/sprite/Path.java new file mode 100644 index 00000000..3693d0f5 --- /dev/null +++ b/src/java/com/threerings/jme/sprite/Path.java @@ -0,0 +1,51 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.scene.Controller; + +/** + * Defines a framework for moving sprites around and notifying interested + * parties when the sprite has completed its path or if the path has been + * cancelled. + */ +public abstract class Path extends Controller +{ + /** + * Creates and initializes this path with the sprite it will be + * manipulating. + */ + protected Path (Sprite sprite) + { + _sprite = sprite; + } + + /** + * Called when this path is removed from its sprite (either due to + * completion or cancellation). + */ + public void wasRemoved () + { + } + + protected Sprite _sprite; +} diff --git a/src/java/com/threerings/jme/sprite/PathObserver.java b/src/java/com/threerings/jme/sprite/PathObserver.java new file mode 100644 index 00000000..597bb22e --- /dev/null +++ b/src/java/com/threerings/jme/sprite/PathObserver.java @@ -0,0 +1,44 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +/** + * Implement this interface to find out when a sprite completes or cancels + * its path. + */ +public interface PathObserver extends SpriteObserver +{ + /** + * Called when a sprite's path is cancelled either because a new path + * was started or the path was explicitly cancelled with {@link + * Sprite#cancelMove}. + */ + public void pathCancelled (Sprite sprite, Path path); + + /** + * Called when a sprite completes its traversal of a path. + * + * @param sprite the sprite that completed its path. + * @param path the path that was completed. + */ + public void pathCompleted (Sprite sprite, Path path); +} diff --git a/src/java/com/threerings/jme/sprite/PathUtil.java b/src/java/com/threerings/jme/sprite/PathUtil.java new file mode 100644 index 00000000..7512377d --- /dev/null +++ b/src/java/com/threerings/jme/sprite/PathUtil.java @@ -0,0 +1,95 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.math.FastMath; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; + +/** + * Path related utility functions. + */ +public class PathUtil +{ + /** + * Computes a rotation to align the X axis with the specified + * orientation and stores it in the provided target. The provided up + * vector is crossed with the new orientation to find the left vector + * and the left vector is recrossed with the orientation to find the + * correct up vector. + * + * @return the supplied target quaternion. + */ + public static Quaternion computeAxisRotation ( + Vector3f up, Vector3f orient, Quaternion target) + { + _axes[0].set(orient); + _axes[0].normalizeLocal(); + up.cross(_axes[0], _axes[1]); + _axes[1].normalizeLocal(); + _axes[0].cross(_axes[1], _axes[2]); + target.fromAxes(_axes); + return target; + } + + /** + * Computes a rotation from the one vector to another. + * + * @param axis will be used as the axis of rotation if the two vectors + * are parallel. + */ + public static Quaternion computeRotation ( + Vector3f axis, Vector3f from, Vector3f to, Quaternion target) + { + float angle = computeAngle(from, to); + if (angle == FastMath.PI) { // opposite + target.fromAngleAxis(angle, axis); + } else if (angle == 0) { // coincident + target.x = target.y = target.z = 0; + target.w = 1; + } else { + from.cross(to, _axis); + target.fromAngleAxis(angle, _axis); + } + return target; + } + + /** + * Computes the angle between two arbitrary vectors. + */ + public static float computeAngle (Vector3f one, Vector3f two) + { + return FastMath.acos(one.dot(two) / (one.length() * two.length())); + } + + /** + * Computes the angle between two normalized vectors. + */ + public static float computeAngleNormal (Vector3f one, Vector3f two) + { + return FastMath.acos(one.dot(two)); + } + + protected static Vector3f[] _axes = { + new Vector3f(), new Vector3f(), new Vector3f() }; + protected static Vector3f _axis = new Vector3f(); +} diff --git a/src/java/com/threerings/jme/sprite/Sprite.java b/src/java/com/threerings/jme/sprite/Sprite.java new file mode 100644 index 00000000..8261cf2f --- /dev/null +++ b/src/java/com/threerings/jme/sprite/Sprite.java @@ -0,0 +1,244 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +import com.jme.scene.Node; +import com.jme.scene.Spatial; + +import com.samskivert.util.ObserverList; + +import com.threerings.jme.Log; + +/** + * Represents a visual entity that one controls as a single unit. Sprites + * can be made to follow paths which is one of their primary reasons for + * existence. + */ +public class Sprite extends Node +{ + /** + * Walks down the hierarchy provided setting the animation speed on + * any controllers found along the way. + */ + public static void setAnimationSpeed (Spatial spatial, float speed) + { + for (int ii = 0; ii < spatial.getControllers().size(); ii++) { + spatial.getController(ii).setSpeed(speed); + } + if (spatial instanceof Node) { + Node node = (Node)spatial; + for (int ii = 0; ii < node.getQuantity(); ii++) { + setAnimationSpeed(node.getChild(ii), speed); + } + } + } + + /** + * Walks down the hierarchy provided turning on or off any controllers + * found along the way. + */ + public static void setAnimationActive (Spatial spatial, boolean active) + { + for (int ii = 0; ii < spatial.getControllers().size(); ii++) { + spatial.getController(ii).setActive(active); + } + if (spatial instanceof Node) { + Node node = (Node)spatial; + for (int ii = 0; ii < node.getQuantity(); ii++) { + setAnimationActive(node.getChild(ii), active); + } + } + } + + /** + * Walks down the hierarchy provided setting the animation repeat type on + * any controllers found along the way. + */ + public static void setAnimationRepeatType (Spatial spatial, int repeatType) + { + for (int ii = 0; ii < spatial.getControllers().size(); ii++) { + spatial.getController(ii).setRepeatType(repeatType); + } + if (spatial instanceof Node) { + Node node = (Node)spatial; + for (int ii = 0; ii < node.getQuantity(); ii++) { + setAnimationRepeatType(node.getChild(ii), repeatType); + } + } + } + + public Sprite () + { + super(""); + setName("sprite:" + hashCode()); + } + + /** + * Adds an observer to this sprite. Observers are notified when path + * related events take place. + */ + public void addObserver (SpriteObserver obs) + { + if (_observers == null) { + _observers = new ObserverList( + ObserverList.SAFE_IN_ORDER_NOTIFY); + } + _observers.add(obs); + } + + /** + * Removes the specified observer from this sprite. + */ + public void removeObserver (SpriteObserver obs) + { + if (_observers != null) { + _observers.remove(obs); + } + } + + /** + * Returns true if this sprite is moving along a path, false if not. + */ + public boolean isMoving () + { + return _path != null; + } + + /** + * Instructs this sprite to move along the specified path. Any + * currently executing path will be cancelled. + */ + public void move (Path path) + { + // if there's a previous path, let it know that it's going away + cancelMove(); + + // save off this path + _path = path; + addController(_path); + } + + /** + * Cancels any currently executing path. Any registered observers will + * be notified of the cancellation. + */ + public void cancelMove () + { + if (_path != null) { + Path oldpath = _path; + _path = null; + oldpath.wasRemoved(); + if (_observers != null) { + _observers.apply(new CancelledOp(this, oldpath)); + } + } + } + + /** + * Called by the active path when it has completed. Note: + * don't call this method unless you are implementing a {@link Path}. + */ + public void pathCompleted () + { + if (_path == null) { + Log.warning("pathCompleted() called on pathless sprite " + + "(re-completed?) [sprite=" + this + "]."); + Thread.dumpStack(); + return; + } + + Path oldpath = _path; + _path = null; + removeController(oldpath); + oldpath.wasRemoved(); + if (_observers != null) { + _observers.apply(new CompletedOp(this, oldpath)); + } + } + + /** + * Configures the speed of all controllers in our model hierarchy. + */ + public void setAnimationSpeed (float speed) + { + setAnimationSpeed(this, speed); + } + + /** + * Configures the active state of all controllers in our model hierarchy. + */ + public void setAnimationActive (boolean active) + { + setAnimationActive(this, active); + } + + /** + * Configures the repeat type of all controllers in our model hierarchy. + */ + public void setAnimationRepeatType (int repeatType) + { + setAnimationRepeatType(this, repeatType); + } + + /** Used to dispatch {@link PathObserver#pathCancelled}. */ + protected static class CancelledOp + implements ObserverList.ObserverOp + { + public CancelledOp (Sprite sprite, Path path) { + _sprite = sprite; + _path = path; + } + + public boolean apply (SpriteObserver observer) { + if (observer instanceof PathObserver) { + ((PathObserver)observer).pathCancelled(_sprite, _path); + } + return true; + } + + protected Sprite _sprite; + protected Path _path; + } + + /** Used to dispatch {@link PathObserver#pathCompleted}. */ + protected static class CompletedOp + implements ObserverList.ObserverOp + { + public CompletedOp (Sprite sprite, Path path) { + _sprite = sprite; + _path = path; + } + + public boolean apply (SpriteObserver observer) { + if (observer instanceof PathObserver) { + ((PathObserver)observer).pathCompleted(_sprite, _path); + } + return true; + } + + protected Sprite _sprite; + protected Path _path; + } + + protected ObserverList _observers; + protected Path _path; +} diff --git a/src/java/com/threerings/jme/sprite/SpriteObserver.java b/src/java/com/threerings/jme/sprite/SpriteObserver.java new file mode 100644 index 00000000..4b1249e7 --- /dev/null +++ b/src/java/com/threerings/jme/sprite/SpriteObserver.java @@ -0,0 +1,29 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.sprite; + +/** + * The super-interface for all sprite observers. + */ +public interface SpriteObserver +{ +} diff --git a/src/java/com/threerings/jme/tile/FringeConfiguration.java b/src/java/com/threerings/jme/tile/FringeConfiguration.java new file mode 100644 index 00000000..ba7ca2ee --- /dev/null +++ b/src/java/com/threerings/jme/tile/FringeConfiguration.java @@ -0,0 +1,160 @@ +// +// $Id: FringeConfiguration.java 3403 2005-03-14 23:58:02Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tile; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; + +import com.samskivert.util.StringUtil; + +import com.threerings.jme.Log; + +/** + * Used to manage data about which tiles fringe on which others and how + * they fringe. + */ +public class FringeConfiguration implements Serializable +{ + /** Contains information on a type of tile and all of the fringe + * records associated with it. */ + public static class TileRecord implements Serializable + { + /** The type of tile to which this applies. */ + public String type; + + /** The fringe priority of this type. */ + public int priority; + + /** A list of the fringe records that can be used for fringing. */ + public ArrayList fringes = new ArrayList(); + + /** Used when parsing from an XML definition. */ + public void addFringe (FringeRecord record) + { + if (record.isValid()) { + fringes.add(record); + } else { + Log.warning("Not adding invalid fringe record [tile=" + this + + ", fringe=" + record + "]."); + } + } + + /** Did everything parse well? */ + public boolean isValid () + { + return ((type != null) && (priority > 0)); + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return "[type=" + type + ", priority=" + priority + + ", fringes=" + StringUtil.toString(fringes) + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + } + + /** Used to parse the type fringe definitions. */ + public static class FringeRecord implements Serializable + { + /** The name of the fringe tileset image. */ + public String name; + + /** Is this a mask? */ + public boolean mask; + + /** Did everything parse well? */ + public boolean isValid () + { + return (name != null); + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return "[name=" + name + ", mask=" + mask + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + } + + /** + * Adds a parsed fringe record to this instance. This is used when + * parsing the fringe records from xml. + */ + public void addTileRecord (TileRecord record) + { + if (record.isValid()) { + _trecs.put(record.type, record); + } else { + Log.warning("Refusing to add invalid tile record " + + "[tile=" + record + "]."); + } + } + + /** + * If the first type fringes upon the second, return the fringe + * priority of the first type, otherwise return -1. + */ + public int fringesOn (String fringer, String fringed) + { + TileRecord f1 = (TileRecord)_trecs.get(fringer); + + // we better have a fringe record for the fringer + if (null != f1) { + // it had better have some types defined + if (f1.fringes.size() > 0) { + TileRecord f2 = (TileRecord)_trecs.get(fringed); + // and we only fringe if fringed doesn't have a fringe + // record or has a lower priority + if ((null == f2) || (f1.priority > f2.priority)) { + return f1.priority; + } + } + } + + return -1; + } + + /** + * Get a random FringeRecord from amongst the ones listed for the + * specified type. + */ + public FringeRecord getFringe (String type, int hashValue) + { + TileRecord t = (TileRecord)_trecs.get(type); + return (FringeRecord)t.fringes.get(hashValue % t.fringes.size()); + } + + /** The mapping from tile type to tile record. */ + protected HashMap _trecs = new HashMap(); + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/jme/tile/TileFringer.java b/src/java/com/threerings/jme/tile/TileFringer.java new file mode 100644 index 00000000..6ddb7521 --- /dev/null +++ b/src/java/com/threerings/jme/tile/TileFringer.java @@ -0,0 +1,404 @@ +// +// $Id: TileFringer.java 3177 2004-10-28 17:49:02Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tile; + +import java.awt.Graphics2D; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; + +import com.samskivert.util.QuickSort; + +import com.threerings.media.image.ImageUtil; +import com.threerings.media.tile.TileUtil; + +import com.threerings.jme.Log; + +/** + * Computes fringe tile images according to the rules in an associated + * fringe configuration. + */ +public class TileFringer +{ + public static interface TileSource + { + /** Returns the type of tile at the specified coordinates or -1 if + * there is no tile at this coordinate. */ + public String getTileType (int x, int y); + + /** Returns the tile type to use when a coordinate has no tile. */ + public String getDefaultType (); + } + + public static interface ImageSource extends ImageUtil.ImageCreator + { + /** Creates a blank image into which various fringe images will be + * composited. */ + public BufferedImage createImage ( + int width, int height, int transparency); + + /** Returns the source image for a tile of the specified type. + * This can be randomly selected and change from call to call. */ + public BufferedImage getTileSource (String type); + + /** Returns the named fringe source image (one long strip). */ + public BufferedImage getFringeSource (String name); + } + + /** + * Creates a fringer that will fringe according to the rules in the + * supplied configuration. + */ + public TileFringer (FringeConfiguration config, ImageSource isrc) + { + _config = config; + _isrc = isrc; + } + + /** + * Computes, creates and returns the base tile with the appropriate + * fringe imagery applied to it for the specified location. + * + * @param masks used to cache intermediate images of tiles cut out + * using a fringe mask. + */ + public BufferedImage getFringeTile ( + TileSource tiles, int col, int row, HashMap masks) + { + // get the type of the tile we are considering + String baseType = tiles.getTileType(col, row); + if (baseType == null) { + baseType = tiles.getDefaultType(); + } + + // start with an empty fringer list + FringerRec fringers = null; + + // walk through our influence tiles + for (int y = row - 1, maxy = row + 2; y < maxy; y++) { + for (int x = col - 1, maxx = col + 2; x < maxx; x++) { + // we sensibly do not consider ourselves + if ((x == col) && (y == row)) { + continue; + } + + // determine the type of our fringing neighbor + String fringerType = tiles.getTileType(x, y); + if (fringerType == null) { + fringerType = tiles.getDefaultType(); + } + + // determine if it fringes on our tile + int pri = _config.fringesOn(fringerType, baseType); + if (pri == -1) { + continue; + } + + FringerRec fringer = (fringers == null) ? + null : fringers.find(fringerType); + if (fringer == null) { + fringer = fringers = + new FringerRec(fringerType, pri, fringers); + } + + // now turn on the appropriate fringebits + int dy = y - row, dx = x - col; + fringer.bits |= FLAGMATRIX[dy*3+dx+4]; + } + } + + // if nothing fringed, we're done + if (fringers == null) { + return null; + } + + // otherwise compose a fringe tile from the specified fringes + return composeFringeTile( + baseType, fringers.toArray(), masks, TileUtil.getTileHash(col, row)); + } + + /** + * Compose a fringe tile out of the various fringe images needed. + */ + protected BufferedImage composeFringeTile ( + String baseType, FringerRec[] fringers, HashMap masks, int hashValue) + { + // sort the array so that higher priority fringers get drawn first + QuickSort.sort(fringers); + + BufferedImage source = _isrc.getTileSource(baseType); + if (source == null) { + Log.warning("Missing source tile [type=" + baseType + "]."); + return null; + } + + BufferedImage ftimg = _isrc.createImage( + source.getWidth(), source.getHeight(), Transparency.OPAQUE); + Graphics2D gfx = (Graphics2D)ftimg.getGraphics(); + try { + // start with the base tile image + gfx.drawImage(source, 0, 0, null); + + // and stamp the fringers on top of it + for (int ii = 0; ii < fringers.length; ii++) { + int[] indexes = getFringeIndexes(fringers[ii].bits); + for (int jj = 0; jj < indexes.length; jj++) { + stampTileImage(gfx, fringers[ii].fringerType, + indexes[jj], masks, hashValue); + } + } + + } finally { + gfx.dispose(); + } + return ftimg; + } + + /** + * Looks up or creates the appropriate fringe mask and draws it into + * the supplied graphics context. + */ + protected void stampTileImage ( + Graphics2D gfx, String fringerType, int index, + HashMap masks, int hashValue) + { + FringeConfiguration.FringeRecord frec = + _config.getFringe(fringerType, hashValue); + BufferedImage fsimg = (frec == null) ? null : + _isrc.getFringeSource(frec.name); + if (fsimg == null) { + Log.warning("Missing fringe source image [type=" + fringerType + + ", hash=" + hashValue + ", frec=" + frec + "]."); + return; + } + + if (frec.mask) { + // it's a mask; look for it in the cache + String maskkey = fringerType + ":" + frec.name + ":" + index; + BufferedImage mimg = (BufferedImage)masks.get(maskkey); + if (mimg == null) { + BufferedImage fsrc = getSubimage(fsimg, index); + BufferedImage bsrc = _isrc.getTileSource(fringerType); + mimg = ImageUtil.composeMaskedImage(_isrc, fsrc, bsrc); + masks.put(maskkey, mimg); + } + gfx.drawImage(mimg, 0, 0, null); + + } else { + // this is a non-mask image so just use the data from the + // fringe source image directly + gfx.drawImage(getSubimage(fsimg, index), 0, 0, null); + } + } + + /** + * Returns the indexth tile image from the supplied + * source image. The source image is assumed to be a single strip of + * tile images, each with equal width and height. + */ + protected BufferedImage getSubimage (BufferedImage source, int index) + { + int size = source.getHeight(), x = size * index; + return source.getSubimage(x, 0, size, size); + } + + /** + * Get the fringe index specified by the fringebits. If no index + * is available, try breaking down the bits into contiguous regions of + * bits and look for indexes for those. + */ + protected int[] getFringeIndexes (int bits) + { + int index = BITS_TO_INDEX[bits]; + if (index != -1) { + int[] ret = new int[1]; + ret[0] = index; + return ret; + } + + // otherwise, split the bits into contiguous components + + // look for a zero and start our first split + int start = 0; + while ((((1 << start) & bits) != 0) && (start < NUM_FRINGEBITS)) { + start++; + } + + if (start == NUM_FRINGEBITS) { + // we never found an empty fringebit, and since index (above) + // was already -1, we have no fringe tile for these bits.. sad. + return new int[0]; + } + + ArrayList indexes = new ArrayList(); + int weebits = 0; + for (int ii=(start + 1) % NUM_FRINGEBITS; ii != start; + ii = (ii + 1) % NUM_FRINGEBITS) { + + if (((1 << ii) & bits) != 0) { + weebits |= (1 << ii); + } else if (weebits != 0) { + index = BITS_TO_INDEX[weebits]; + if (index != -1) { + indexes.add(Integer.valueOf(index)); + } + weebits = 0; + } + } + if (weebits != 0) { + index = BITS_TO_INDEX[weebits]; + if (index != -1) { + indexes.add(Integer.valueOf(index)); + } + } + + int[] ret = new int[indexes.size()]; + for (int ii=0; ii < ret.length; ii++) { + ret[ii] = ((Integer) indexes.get(ii)).intValue(); + } + return ret; + } + + /** A record for holding information about a particular fringe as + * we're computing what it will look like. */ + protected static class FringerRec implements Comparable + { + public String fringerType; + public int priority; + public int bits; + public FringerRec next; + + public FringerRec (String type, int pri, FringerRec next) { + fringerType = type; + priority = pri; + this.next = next; + } + + public FringerRec find (String type) + { + if (fringerType.equals(type)) { + return this; + } else if (next != null) { + return next.find(type); + } else { + return null; + } + } + + public FringerRec[] toArray () + { + return toArray(0); + } + + public int compareTo (Object o) { + return priority - ((FringerRec) o).priority; + } + + public String toString () { + return "[type=" + fringerType + ", pri=" + priority + + ", bits=" + Integer.toString(bits, 16) + "]"; + } + + protected FringerRec[] toArray (int index) + { + FringerRec[] array; + if (next == null) { + array = new FringerRec[index+1]; + } else { + array = next.toArray(index+1); + } + array[index] = this; + return array; + } + } + + protected static final int NORTH = 1 << 0; + protected static final int NORTHEAST = 1 << 1; + protected static final int EAST = 1 << 2; + protected static final int SOUTHEAST = 1 << 3; + protected static final int SOUTH = 1 << 4; + protected static final int SOUTHWEST = 1 << 5; + protected static final int WEST = 1 << 6; + protected static final int NORTHWEST = 1 << 7; + + protected static final int NUM_FRINGEBITS = 8; + + /** A matrix mapping adjacent tiles to which fringe bits they affect. + * (x and y are offset by +1, since we can't have -1 as an array index). + * These are "upside down" thanks to OpenGL. */ + protected static final int[] FLAGMATRIX = { + SOUTHWEST, (SOUTHEAST | SOUTH | SOUTHWEST), SOUTHEAST, + (NORTHWEST | WEST | SOUTHWEST), 0, (NORTHEAST | EAST | SOUTHEAST), + NORTHWEST, (NORTHWEST | NORTH | NORTHEAST), NORTHEAST, + }; + + /** The fringe tiles we use. These are the 17 possible tiles made up + * of continuous fringebits sections. */ + protected static final int[] FRINGETILES = { + SOUTHEAST, + SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHWEST, + NORTHEAST | EAST | SOUTHEAST, + NORTHWEST | WEST | SOUTHWEST, + NORTHEAST, + NORTHWEST | NORTH | NORTHEAST, + NORTHWEST, + + SOUTHWEST | WEST | NORTHWEST | NORTH | NORTHEAST, + NORTHWEST | NORTH | NORTHEAST | EAST | SOUTHEAST, + NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, + + NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST, + SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST, + NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, + + // all the directions! + NORTH | NORTHEAST | EAST | SOUTHEAST | SOUTH | SOUTHWEST | + WEST | NORTHWEST + }; + + /** A reverse map of the {@link #FRINGETILES} array, for quickly + * looking up which tile we want. */ + protected static final int[] BITS_TO_INDEX; + + // Construct the BITS_TO_INDEX array. + static { + int num = (1 << NUM_FRINGEBITS); + BITS_TO_INDEX = new int[num]; + + // first clear everything to -1 (meaning there is no tile defined) + for (int ii=0; ii < num; ii++) { + BITS_TO_INDEX[ii] = -1; + } + + // then fill in with the defined tiles. + for (int ii=0; ii < FRINGETILES.length; ii++) { + BITS_TO_INDEX[FRINGETILES[ii]] = ii; + } + } + + protected ImageSource _isrc; + protected FringeConfiguration _config; +} diff --git a/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java b/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java new file mode 100644 index 00000000..6e220862 --- /dev/null +++ b/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java @@ -0,0 +1,76 @@ +// +// $Id: CompileFringeConfigurationTask.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tile.tools; + +import java.io.File; +import java.io.Serializable; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import com.samskivert.io.PersistenceException; +import com.threerings.util.CompiledConfig; + +import com.threerings.jme.tile.tools.xml.FringeConfigurationParser; + +/** + * Compiles a fringe configuration from XML format into binary format. + */ +public class CompileFringeConfigurationTask extends Task +{ + public void setConfig (File config) + { + _config = config; + } + + public void setTarget (File target) + { + _target = target; + } + + public void execute () throws BuildException + { + // make sure the config file exists + if (!_config.exists()) { + throw new BuildException( + "Fringe configuration file not found [path=" + _config + "]."); + } + + FringeConfigurationParser parser = new FringeConfigurationParser(); + Serializable config; + try { + config = parser.parseConfig(_config); + } catch (Exception e) { + throw new BuildException("Failure parsing fringe config", e); + } + + try { + // and write it on out + CompiledConfig.saveConfig(_target, config); + } catch (Exception e) { + throw new BuildException("Failure writing serialized config", e); + } + } + + protected File _config; + protected File _target; +} diff --git a/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java b/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java new file mode 100644 index 00000000..a769ef5c --- /dev/null +++ b/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java @@ -0,0 +1,84 @@ +// +// $Id: FringeConfigurationParser.java 3254 2004-11-30 20:03:47Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tile.tools.xml; + +import java.io.Serializable; + +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.tools.xml.CompiledConfigParser; + +import com.threerings.jme.Log; +import com.threerings.jme.tile.FringeConfiguration.TileRecord; +import com.threerings.jme.tile.FringeConfiguration.FringeRecord; +import com.threerings.jme.tile.FringeConfiguration; + +/** + * Parses fringe config definitions, which look like so (with angle + * brackets instead of square): + *
+ * [fringe]
+ *   [tile type="water" priority="100"]
+ *      [fringe name="water_fringe_1"/]
+ *      [fringe name="water_fringe_2"/]
+ *      [fringe name="water_fringe_3"/]
+ *   [/tile]
+ *   [tile type="dirt" priority="10"]
+ *      [fringe name="dirt_fringe_1" mask="true"/]
+ *   [/tile]
+ *   [tile type="cobble" priority="100"]
+ *      [fringe name="cobble_fringe_1" mask="false"/]
+ *   [/tile]
+ * [/fringe]
+ * 
+ */ +public class FringeConfigurationParser extends CompiledConfigParser +{ + // documentation inherited + protected Serializable createConfigObject () + { + return new FringeConfiguration(); + } + + // documentation inherited + protected void addRules (Digester digest) + { + // configure top-level constraints + String prefix = "fringe"; + digest.addRule(prefix, new SetPropertyFieldsRule()); + + // create and configure fringe config instances + prefix += "/tile"; + digest.addObjectCreate(prefix, TileRecord.class.getName()); + digest.addRule(prefix, new SetPropertyFieldsRule()); + digest.addSetNext(prefix, "addTileRecord"); + + // create the fringe type records in each tile record + prefix += "/fringe"; + digest.addObjectCreate(prefix, FringeRecord.class.getName()); + digest.addRule(prefix, new SetPropertyFieldsRule()); + digest.addSetNext(prefix, "addFringe"); + } +} diff --git a/src/java/com/threerings/jme/tools/AnimationDef.java b/src/java/com/threerings/jme/tools/AnimationDef.java new file mode 100644 index 00000000..709e9117 --- /dev/null +++ b/src/java/com/threerings/jme/tools/AnimationDef.java @@ -0,0 +1,165 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Properties; + +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.scene.Controller; +import com.jme.scene.Spatial; + +import com.threerings.jme.Log; +import com.threerings.jme.model.Model; + +/** + * A basic representation for keyframe animations. + */ +public class AnimationDef +{ + /** The rate of the animation in frames per second. */ + public int frameRate; + + /** A single frame of the animation. */ + public static class FrameDef + { + /** Transform for affected nodes. */ + public ArrayList transforms = + new ArrayList(); + + public void addTransform (TransformDef transform) + { + transforms.add(transform); + } + + /** Adds all transform targets in this frame to the supplied set. */ + public void addTransformTargets ( + HashMap nodes, HashSet targets) + { + for (int ii = 0, nn = transforms.size(); ii < nn; ii++) { + String name = transforms.get(ii).name; + Spatial target = nodes.get(name); + if (target != null) { + targets.add(target); + } else { + Log.debug("Missing animation target [name=" + name + + "]."); + } + } + } + + /** Returns the array of transforms for this frame. */ + public Model.Transform[] getTransforms (Spatial[] targets) + { + Model.Transform[] mtransforms = + new Model.Transform[targets.length]; + for (int ii = 0; ii < targets.length; ii++) { + mtransforms[ii] = getTransform(targets[ii]); + } + return mtransforms; + } + + /** Returns the transform for the supplied target. */ + protected Model.Transform getTransform (Spatial target) + { + String name = target.getName(); + for (int ii = 0, nn = transforms.size(); ii < nn; ii++) { + TransformDef transform = transforms.get(ii); + if (name.equals(transform.name)) { + return transform.getTransform(); + } + } + return null; + } + } + + /** A transform for a single node. */ + public static class TransformDef + { + /** The name of the affected node. */ + public String name; + + /** The transformation parameters. */ + public float[] translation; + public float[] rotation; + public float[] scale; + + /** Returns the live transform object. */ + public Model.Transform getTransform () + { + return new Model.Transform( + new Vector3f(translation[0], translation[1], translation[2]), + new Quaternion(rotation[0], rotation[1], rotation[2], + rotation[3]), + new Vector3f(scale[0], scale[1], scale[2])); + } + } + + /** The individual frames of the animation. */ + public ArrayList frames = new ArrayList(); + + public void addFrame (FrameDef frame) + { + frames.add(frame); + } + + /** + * Creates the "live" animation object that will be serialized with the + * object. + * + * @param props the animation properties + * @param nodes the nodes in the model, mapped by name + */ + public Model.Animation createAnimation ( + Properties props, HashMap nodes) + { + // find all affected nodes + HashSet targets = new HashSet(); + for (int ii = 0, nn = frames.size(); ii < nn; ii++) { + frames.get(ii).addTransformTargets(nodes, targets); + } + + // create and configure the animation + Model.Animation anim = new Model.Animation(); + anim.frameRate = frameRate; + String rtype = props.getProperty("repeat_type", "clamp"); + if (rtype.equals("cycle")) { + anim.repeatType = Controller.RT_CYCLE; + } else if (rtype.equals("wrap")) { + anim.repeatType = Controller.RT_WRAP; + } else { + anim.repeatType = Controller.RT_CLAMP; + } + + // collect all transforms + anim.transformTargets = targets.toArray(new Spatial[targets.size()]); + anim.transforms = new Model.Transform[frames.size()][targets.size()]; + for (int ii = 0; ii < anim.transforms.length; ii++) { + anim.transforms[ii] = + frames.get(ii).getTransforms(anim.transformTargets); + } + return anim; + } +} diff --git a/src/java/com/threerings/jme/tools/BuildSphereMap.java b/src/java/com/threerings/jme/tools/BuildSphereMap.java new file mode 100644 index 00000000..a147893c --- /dev/null +++ b/src/java/com/threerings/jme/tools/BuildSphereMap.java @@ -0,0 +1,167 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.awt.image.BufferedImage; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.jme.image.Texture; +import com.jme.math.FastMath; +import com.jme.math.Vector3f; + +/** + * A tool for converting cube maps (sky boxes) to sphere maps. + */ +public class BuildSphereMap +{ + public static void main (String[] args) + { + if (args.length < 7) { + System.err.println("Usage: BuildSphereMap front.ext back.ext " + + "left.ext right.ext up.ext dest.ext size"); + System.exit(-1); + } + + try { + execute(new File(args[0]), new File(args[1]), new File(args[2]), + new File(args[3]), new File(args[4]), new File(args[5]), + Integer.parseInt(args[6])); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Builds the sphere map. + * + * @param front the file containing the front side of the cube map + * @param back the file containing the back side of the cube map + * @param left the file containing the left side of the cube map + * @param right the file containing the right side of the cube map + * @param up the file containing the up side of the cube map + * @param target the file to contain the sphere map + * @param size the size of the sphere map to generate + */ + public static void execute (File front, File back, File left, File right, + File up, File target, int size) + throws IOException + { + // load up the sides of the cube map + BufferedImage[] sides = new BufferedImage[5]; + sides[FRONT] = ImageIO.read(front); + sides[BACK] = ImageIO.read(back); + sides[LEFT] = ImageIO.read(left); + sides[RIGHT] = ImageIO.read(right); + sides[UP] = ImageIO.read(up); + + // compute the pixels + int[] rgb = new int[size * size]; + Vector3f vec = new Vector3f(); + for (int y = 0, idx = 0; y < size; y++) { + for (int x = 0; x < size; x++, idx++) { + float vx = x / (size*0.5f) - 1f, vy = y / (size*0.5f) - 1f, + d2 = vx*vx + vy*vy; + int p = 0; + if (d2 <= 1f) { + vec.set(vx, vy, FastMath.sqrt(1f - d2)); + rgb[idx] = getCubeMapPixel(vec, sides); + } + } + } + + // create and write the image + BufferedImage image = new BufferedImage(size, size, + BufferedImage.TYPE_INT_RGB); + image.setRGB(0, 0, size, size, rgb, 0, size); + String dest = target.toString(), + ext = dest.substring(dest.lastIndexOf('.')+1); + ImageIO.write(image, ext, target); + } + + /** + * Returns the pixel from the cube map to which the given vector points. + */ + protected static int getCubeMapPixel (Vector3f vec, BufferedImage[] sides) + { + int side = getCubeMapSide(vec); + + float s, t; + switch (side) { + case FRONT: + s = -vec.x / vec.y; + t = vec.z / vec.y; + break; + case BACK: + s = -vec.x / vec.y; + t = -vec.z / vec.y; + break; + case LEFT: + s = vec.y / vec.x; + t = -vec.z / vec.x; + break; + case RIGHT: + s = vec.y / vec.x; + t = vec.z / vec.x; + break; + default: + case UP: + s = vec.x / vec.z; + t = -vec.y / vec.z; + break; + } + int width = sides[side].getWidth(), height = sides[side].getHeight(); + return sides[side].getRGB((int)((width-1) * (s+1f)/2f), + (int)((height-1) * (1f-t)/2f)); + } + + /** + * Returns the side index identifying the face of the cube map to which + * the given vector points. + */ + protected static int getCubeMapSide (Vector3f vec) + { + if (vec.x > vec.z && vec.x > vec.y && vec.x > -vec.y) { + return RIGHT; + + } else if (vec.x < -vec.z && vec.x < -vec.y && vec.x < vec.y) { + return LEFT; + + } else if (vec.y > vec.z) { + return FRONT; + + } else if (vec.y < -vec.z) { + return BACK; + + } else { + return UP; + } + } + + /** The sides of the cube map. */ + protected static final int FRONT = 0, BACK = 1, LEFT = 2, RIGHT = 3, + UP = 4; +} diff --git a/src/java/com/threerings/jme/tools/BuildSphereMapTask.java b/src/java/com/threerings/jme/tools/BuildSphereMapTask.java new file mode 100644 index 00000000..27ad058a --- /dev/null +++ b/src/java/com/threerings/jme/tools/BuildSphereMapTask.java @@ -0,0 +1,86 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.io.File; +import java.io.IOException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +/** + * An ant task for converting cube maps (sky boxes) to sphere maps. + */ +public class BuildSphereMapTask extends Task +{ + public void setFront (File front) + { + _front = front; + } + + public void setBack (File back) + { + _back = back; + } + + public void setLeft (File left) + { + _left = left; + } + + public void setRight (File right) + { + _right = right; + } + + public void setUp (File up) + { + _up = up; + } + + public void setTarget (File target) + { + _target = target; + } + + public void setSize (int size) + { + _size = size; + } + + public void execute () throws BuildException + { + try { + BuildSphereMap.execute(_front, _back, _left, _right, _up, _target, + _size); + + } catch (IOException e) { + throw new BuildException("Failure building sphere map", e); + } + } + + /** The files representing the sides of the cube map and the target. */ + protected File _front, _back, _left, _right, _up, _target; + + /** The size of the target image. */ + protected int _size; +} diff --git a/src/java/com/threerings/jme/tools/CompileModel.java b/src/java/com/threerings/jme/tools/CompileModel.java new file mode 100644 index 00000000..8e5536ea --- /dev/null +++ b/src/java/com/threerings/jme/tools/CompileModel.java @@ -0,0 +1,139 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Properties; +import java.util.logging.Level; + +import com.jme.scene.Spatial; +import com.jme.util.LoggingSystem; +import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; + +import com.samskivert.util.PropertiesUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.jme.model.Model; +import com.threerings.jme.model.ModelMesh; +import com.threerings.jme.model.ModelNode; +import com.threerings.jme.model.SkinMesh; +import com.threerings.jme.tools.xml.AnimationParser; +import com.threerings.jme.tools.xml.ModelParser; + +/** + * An application for compiling 3D models defined in XML to fast-loading binary + * files. + */ +public class CompileModel +{ + /** + * Loads the model described by the given properties file and compiles it + * to a .dat file in the same directory. + * + * @return the loaded model, or null if the compiled version + * is up-to-date + */ + public static Model compile (File source) + throws Exception + { + String spath = source.toString(); + int didx = spath.lastIndexOf('.'); + String root = (didx == -1) ? spath : spath.substring(0, didx); + File content = new File(root + ".mxml"), + target = new File(root + ".dat"); + boolean needsUpdate = false; + if (source.lastModified() >= target.lastModified() || + content.lastModified() >= target.lastModified()) { + needsUpdate = true; + } + + // load the model properties + Properties props = new Properties(); + FileInputStream in = new FileInputStream(source); + props.load(in); + in.close(); + + // locate the animations, if any + String[] anims = + StringUtil.parseStringArray(props.getProperty("animations", "")); + File[] afiles = new File[anims.length]; + File dir = source.getParentFile(); + for (int ii = 0; ii < anims.length; ii++) { + afiles[ii] = new File(dir, anims[ii] + ".mxml"); + if (afiles[ii].lastModified() >= target.lastModified()) { + needsUpdate = true; + } + } + if (!needsUpdate) { + return null; + } + System.out.println("Compiling " + source.getParent() + "..."); + + // load the model content + ModelDef mdef = _mparser.parseModel(content.toString()); + HashMap nodes = new HashMap(); + Model model = mdef.createModel(props, nodes); + model.initPrototype(); + + // load the animations, if any + for (int ii = 0; ii < anims.length; ii++) { + System.out.println(" Adding " + afiles[ii] + "..."); + AnimationDef adef = _aparser.parseAnimation(afiles[ii].toString()); + model.addAnimation(anims[ii], adef.createAnimation( + PropertiesUtil.getSubProperties(props, anims[ii]), nodes)); + } + + // write and return the model + model.writeToFile(target); + return model; + } + + public static void main (String[] args) + { + if (args.length < 1) { + System.err.println("Usage: CompileModel source.properties"); + System.exit(-1); + } + // create a dummy display system + new DummyDisplaySystem(); + LoggingSystem.getLogger().setLevel(Level.WARNING); + + try { + compile(new File(args[0])); + } catch (Exception e) { + System.err.println("Error compiling model: " + e); + } + } + + /** A parser for the model definitions. */ + protected static ModelParser _mparser = new ModelParser(); + + /** A parser for the animation definitions. */ + protected static AnimationParser _aparser = new AnimationParser(); +} diff --git a/src/java/com/threerings/jme/tools/CompileModelTask.java b/src/java/com/threerings/jme/tools/CompileModelTask.java new file mode 100644 index 00000000..2e16bc5b --- /dev/null +++ b/src/java/com/threerings/jme/tools/CompileModelTask.java @@ -0,0 +1,77 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.io.File; + +import java.util.ArrayList; +import java.util.logging.Level; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; + +import com.jme.util.LoggingSystem; +import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; + +/** + * An ant task for compiling 3D models defined in XML to fast-loading binary + * files. + */ +public class CompileModelTask extends Task +{ + public void addFileset (FileSet set) + { + _filesets.add(set); + } + + public void init () throws BuildException + { + // create a dummy display system + new DummyDisplaySystem(); + LoggingSystem.getLogger().setLevel(Level.WARNING); + } + + public void execute () + throws BuildException + { + for (int ii = 0, nn = _filesets.size(); ii < nn; ii++) { + FileSet fs = _filesets.get(ii); + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + File fromDir = fs.getDir(getProject()); + String[] srcFiles = ds.getIncludedFiles(); + + for (int f = 0; f < srcFiles.length; f++) { + File source = new File(fromDir, srcFiles[f]); + try { + CompileModel.compile(source); + } catch (Exception e) { + System.err.println("Error compiling " + source + ": " + e); + } + } + } + } + + /** A list of filesets that contain XML models. */ + protected ArrayList _filesets = new ArrayList(); +} diff --git a/src/java/com/threerings/jme/tools/ConvertModel.java b/src/java/com/threerings/jme/tools/ConvertModel.java new file mode 100644 index 00000000..20e9895f --- /dev/null +++ b/src/java/com/threerings/jme/tools/ConvertModel.java @@ -0,0 +1,101 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; + +import com.jmex.model.XMLparser.Converters.AseToJme; +import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; +import com.jmex.model.XMLparser.Converters.FormatConverter; +import com.jmex.model.XMLparser.Converters.MaxToJme; +import com.jmex.model.XMLparser.Converters.Md2ToJme; +import com.jmex.model.XMLparser.Converters.Md3ToJme; +import com.jmex.model.XMLparser.Converters.ObjToJme; + +/** + * A tool for converting various 3D model formats into JME's internal + * format. + */ +public class ConvertModel +{ + public static void main (String[] args) + { + if (args.length < 2) { + System.err.println("Usage: ConvertModel source.ext dest.jme"); + System.exit(-1); + } + + // create a dummy display system which the converters need + new DummyDisplaySystem(); + + ConvertModel app = new ConvertModel(); + File source = new File(args[0]); + File target = new File(args[1]); + + String path = source.getPath().toLowerCase(); + String type = path.substring(path.lastIndexOf(".") + 1); + + // set up our converter + FormatConverter convert = null; + if (type.equals("obj")) { + convert = new ObjToJme(); + try { + convert.setProperty("mtllib", new URL("file:" + source)); + } catch (Exception e) { + System.err.println("Failed to create material URL: " + e); + System.exit(-1); + } + } else if (type.equals("3ds")) { + convert = new MaxToJme(); + } else if (type.equals("md2")) { + convert = new Md2ToJme(); + } else if (type.equals("md3")) { + convert = new Md3ToJme(); + } else if (type.equals("ase")) { + convert = new AseToJme(); + } else { + System.err.println("Unknown model type '" + type + "'."); + System.exit(-1); + } + + // and do the deed + try { + BufferedOutputStream bout = new BufferedOutputStream( + new FileOutputStream(target)); + BufferedInputStream bin = new BufferedInputStream( + new FileInputStream(source)); + convert.convert(bin, bout); + bout.close(); + } catch (IOException ioe) { + System.err.println("Error converting '" + source + + "' to '" + target + "'."); + ioe.printStackTrace(System.err); + System.exit(-1); + } + } +} diff --git a/src/java/com/threerings/jme/tools/ConvertModelTask.java b/src/java/com/threerings/jme/tools/ConvertModelTask.java new file mode 100644 index 00000000..f59bc9ad --- /dev/null +++ b/src/java/com/threerings/jme/tools/ConvertModelTask.java @@ -0,0 +1,135 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.logging.Level; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; + +import com.jme.util.LoggingSystem; +import com.jmex.model.XMLparser.Converters.AseToJme; +import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; +import com.jmex.model.XMLparser.Converters.FormatConverter; +import com.jmex.model.XMLparser.Converters.MaxToJme; +import com.jmex.model.XMLparser.Converters.Md2ToJme; +import com.jmex.model.XMLparser.Converters.Md3ToJme; +import com.jmex.model.XMLparser.Converters.ObjToJme; + +/** + * An ant task for converting various 3D model formats into JME's internal + * format. + */ +public class ConvertModelTask extends Task +{ + public void addFileset (FileSet set) + { + _filesets.add(set); + } + + public void init () throws BuildException + { + // create a dummy display system which the converters need + new DummyDisplaySystem(); + LoggingSystem.getLogger().setLevel(Level.WARNING); + } + + public void execute () throws BuildException + { + for (int i = 0; i < _filesets.size(); i++) { + FileSet fs = (FileSet)_filesets.get(i); + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + File fromDir = fs.getDir(getProject()); + String[] srcFiles = ds.getIncludedFiles(); + + for (int f = 0; f < srcFiles.length; f++) { + File cfile = new File(fromDir, srcFiles[f]); + String target = srcFiles[f]; + int didx = target.lastIndexOf("."); + target = (didx == -1) ? target : target.substring(0, didx); + target += ".jme"; + convertModel(cfile, new File(fromDir, target)); + } + } + } + + protected void convertModel (File source, File target) + { + if (source.lastModified() < target.lastModified()) { + return; + } + + System.out.println("Converting " + source + "..."); + String path = source.getPath().toLowerCase(); + String type = path.substring(path.lastIndexOf(".") + 1); + + // set up our converter + FormatConverter convert = null; + if (type.equals("obj")) { + convert = new ObjToJme(); + try { + convert.setProperty("mtllib", new URL("file:" + source)); + } catch (Exception e) { + System.err.println("Failed to create material URL: " + e); + return; + } + } else if (type.equals("3ds")) { + convert = new MaxToJme(); + } else if (type.equals("md2")) { + convert = new Md2ToJme(); + } else if (type.equals("md3")) { + convert = new Md3ToJme(); + } else if (type.equals("ase")) { + convert = new AseToJme(); + } else { + System.err.println("Unknown model type '" + type + "'."); + return; + } + + // and do the deed + try { + BufferedOutputStream bout = new BufferedOutputStream( + new FileOutputStream(target)); + BufferedInputStream bin = new BufferedInputStream( + new FileInputStream(source)); + convert.convert(bin, bout); + bout.close(); + } catch (IOException ioe) { + System.err.println("Error converting '" + source + + "' to '" + target + "'."); + ioe.printStackTrace(System.err); + } + } + + /** A list of filesets that contain tileset bundle definitions. */ + protected ArrayList _filesets = new ArrayList(); +} diff --git a/src/java/com/threerings/jme/tools/ModelDef.java b/src/java/com/threerings/jme/tools/ModelDef.java new file mode 100644 index 00000000..84f2f3fd --- /dev/null +++ b/src/java/com/threerings/jme/tools/ModelDef.java @@ -0,0 +1,573 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import com.jme.bounding.BoundingBox; +import com.jme.bounding.BoundingSphere; +import com.jme.math.FastMath; +import com.jme.scene.Spatial; +import com.jme.util.geom.BufferUtils; + +import com.samskivert.util.PropertiesUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.jme.Log; +import com.threerings.jme.model.Model; +import com.threerings.jme.model.ModelController; +import com.threerings.jme.model.ModelMesh; +import com.threerings.jme.model.ModelNode; +import com.threerings.jme.model.SkinMesh; + +/** + * An intermediate representation for models used to store data parsed from + * XML and convert it into JME nodes. + */ +public class ModelDef +{ + /** The base class of nodes in the model. */ + public abstract static class SpatialDef + { + /** The node's name. */ + public String name; + + /** The name of the node's parent. */ + public String parent; + + /** The node's transformation. */ + public float[] translation; + public float[] rotation; + public float[] scale; + + /** Returns a JME node for this definition. */ + public Spatial getSpatial (Properties props) + { + if (_spatial == null) { + _spatial = createSpatial(new NodeProperties(props, name)); + setTransform(); + } + return _spatial; + } + + /** Sets the transform of the created node. */ + protected void setTransform () + { + _spatial.getLocalTranslation().set(translation[0], translation[1], + translation[2]); + _spatial.getLocalRotation().set(rotation[0], rotation[1], + rotation[2], rotation[3]); + _spatial.getLocalScale().set(scale[0], scale[1], scale[2]); + } + + /** Creates a JME node for this definition. */ + public abstract Spatial createSpatial (Properties props); + + /** Resolves any name references using the supplied map. */ + public void resolveReferences ( + HashMap nodes, HashSet referenced) + { + Spatial pnode = nodes.get(parent); + if (pnode instanceof ModelNode) { + ((ModelNode)pnode).attachChild(_spatial); + + } else if (parent != null) { + Log.warning("Missing or invalid parent node [spatial=" + + name + ", parent=" + parent + "]."); + } + } + + /** The JME node created for this definition. */ + protected Spatial _spatial; + } + + /** A rigid triangle mesh. */ + public static class TriMeshDef extends SpatialDef + { + /** The geometry offset transform. */ + public float[] offsetTranslation; + public float[] offsetRotation; + public float[] offsetScale; + + /** Whether or not the mesh allows back face culling. */ + public boolean solid; + + /** The texture of the mesh, if any. */ + public String texture; + + /** Whether or not the mesh is (partially) transparent. */ + public boolean transparent; + + /** The vertices of the mesh. */ + public ArrayList vertices = new ArrayList(); + + /** The triangle indices. */ + public ArrayList indices = new ArrayList(); + + /** Whether or not any of the vertices have texture coordinates. */ + public boolean tcoords; + + public void addVertex (Vertex vertex) + { + int idx = vertices.indexOf(vertex); + if (idx != -1) { + indices.add(idx); + } else { + indices.add(vertices.size()); + vertices.add(vertex); + } + tcoords = tcoords || vertex.tcoords != null; + } + + // documentation inherited + public Spatial createSpatial (Properties props) + { + ModelNode node = new ModelNode(name); + if (indices.size() > 0) { + _mesh = createMesh(); + configureMesh(props); + node.attachChild(_mesh); + } + return node; + } + + /** Creates the mesh to attach to the node. */ + protected ModelMesh createMesh () + { + return new ModelMesh("mesh"); + } + + /** Configures the mesh. */ + protected void configureMesh (Properties props) + { + // set the geometry offset + if (offsetTranslation != null) { + _mesh.getLocalTranslation().set(offsetTranslation[0], + offsetTranslation[1], offsetTranslation[2]); + } + if (offsetRotation != null) { + _mesh.getLocalRotation().set(offsetRotation[0], + offsetRotation[1], offsetRotation[2], offsetRotation[3]); + } + if (offsetScale != null) { + _mesh.getLocalScale().set(offsetScale[0], offsetScale[1], + offsetScale[2]); + } + + // make sure texture is just a filename + int sidx = (texture == null) ? -1 : + Math.max(texture.lastIndexOf('/'), texture.lastIndexOf('\\')); + if (sidx != -1) { + texture = texture.substring(sidx + 1); + } + + // configure using properties + _mesh.configure(solid, texture, transparent, props); + + // set the various buffers + int vsize = vertices.size(); + ByteOrder no = ByteOrder.nativeOrder(); + ByteBuffer vbbuf = ByteBuffer.allocateDirect(vsize*3*4).order(no), + nbbuf = ByteBuffer.allocateDirect(vsize*3*4).order(no), + tbbuf = tcoords ? + ByteBuffer.allocateDirect(vsize*2*4).order(no) : null, + ibbuf = ByteBuffer.allocateDirect(indices.size()*4).order(no); + FloatBuffer vbuf = vbbuf.asFloatBuffer(), + nbuf = nbbuf.asFloatBuffer(), + tbuf = tcoords ? tbbuf.asFloatBuffer() : null; + for (int ii = 0; ii < vsize; ii++) { + vertices.get(ii).setInBuffers(vbuf, nbuf, tbuf); + } + IntBuffer ibuf = ibbuf.asIntBuffer(); + for (int ii = 0, nn = indices.size(); ii < nn; ii++) { + ibuf.put(indices.get(ii)); + } + _mesh.reconstruct(vbbuf, nbbuf, null, tbbuf, ibbuf); + + _mesh.setModelBound("sphere".equals(props.getProperty("bound")) ? + new BoundingSphere() : new BoundingBox()); + _mesh.updateModelBound(); + + // set the mesh's origin to the center of its bounding box + _mesh.centerVertices(); + } + + /** The mesh that contains the actual geometry. */ + protected ModelMesh _mesh; + } + + /** A triangle mesh that deforms according to bone positions. */ + public static class SkinMeshDef extends TriMeshDef + { + @Override // documentation inherited + protected ModelMesh createMesh () + { + return new SkinMesh("mesh"); + } + + @Override // documentation inherited + public void resolveReferences ( + HashMap nodes, HashSet referenced) + { + super.resolveReferences(nodes, referenced); + if (_mesh == null) { + return; + } + + // create and set the final weight groups + SkinMesh.WeightGroup[] wgroups = + new SkinMesh.WeightGroup[_groups.size()]; + HashMap bones = + new HashMap(); + int ii = 0; + for (Map.Entry, WeightGroupDef> entry : + _groups.entrySet()) { + SkinMesh.WeightGroup wgroup = new SkinMesh.WeightGroup(); + wgroup.vertexCount = entry.getValue().indices.size(); + wgroup.bones = new SkinMesh.Bone[entry.getKey().size()]; + int jj = 0; + for (String bname : entry.getKey()) { + SkinMesh.Bone bone = bones.get(bname); + if (bone == null) { + Spatial node = nodes.get(bname); + bones.put(bname, + bone = new SkinMesh.Bone((ModelNode)node)); + referenced.add(node); + } + wgroup.bones[jj++] = bone; + } + wgroup.weights = toArray(entry.getValue().weights); + wgroups[ii++] = wgroup; + } + ((SkinMesh)_mesh).setWeightGroups(wgroups); + } + + @Override // documentation inherited + protected void configureMesh (Properties props) + { + // divide the vertices up by weight groups + _groups = new HashMap, WeightGroupDef>(); + for (int ii = 0, nn = vertices.size(); ii < nn; ii++) { + SkinVertex svertex = (SkinVertex)vertices.get(ii); + Set bones = svertex.boneWeights.keySet(); + WeightGroupDef group = _groups.get(bones); + if (group == null) { + _groups.put(bones, group = new WeightGroupDef()); + } + group.indices.add(ii); + for (String bone : bones) { + group.weights.add(svertex.boneWeights.get(bone).weight); + } + } + + // reorder the vertices by group + ArrayList overts = vertices; + vertices = new ArrayList(); + int[] imap = new int[overts.size()]; + for (Map.Entry, WeightGroupDef> entry : + _groups.entrySet()) { + for (int idx : entry.getValue().indices) { + imap[idx] = vertices.size(); + vertices.add(overts.get(idx)); + } + } + for (int ii = 0, nn = indices.size(); ii < nn; ii++) { + indices.set(ii, imap[indices.get(ii)]); + } + + super.configureMesh(props); + } + + /** The intermediate weight groups, mapped by bone names. */ + protected HashMap, WeightGroupDef> _groups; + } + + /** A generic node. */ + public static class NodeDef extends SpatialDef + { + // documentation inherited + public Spatial createSpatial (Properties props) + { + return new ModelNode(name); + } + } + + /** A basic vertex. */ + public static class Vertex + { + public float[] location; + public float[] normal; + public float[] tcoords; + + public void setInBuffers ( + FloatBuffer vbuf, FloatBuffer nbuf, FloatBuffer tbuf) + { + vbuf.put(location); + nbuf.put(normal); + + if (tbuf != null) { + if (tcoords != null) { + tbuf.put(tcoords); + } else { + tbuf.put(0f); + tbuf.put(0f); + } + } + } + + public boolean equals (Object obj) + { + Vertex overt = (Vertex)obj; + return Arrays.equals(location, overt.location) && + Arrays.equals(normal, overt.normal) && + Arrays.equals(tcoords, overt.tcoords); + } + } + + /** A vertex influenced by a number of bones. */ + public static class SkinVertex extends Vertex + { + /** The bones influencing the vertex, mapped by name. */ + public HashMap boneWeights = + new HashMap(); + + public void addBoneWeight (BoneWeight weight) + { + if (weight.weight == 0f) { + return; + } + BoneWeight bweight = boneWeights.get(weight.bone); + if (bweight != null) { + bweight.weight += weight.weight; + } else { + boneWeights.put(weight.bone, weight); + } + } + + /** Finds the bone nodes influencing this vertex. */ + public HashSet getBones (HashMap nodes) + { + HashSet bones = new HashSet(); + for (String bone : boneWeights.keySet()) { + Spatial node = nodes.get(bone); + if (node instanceof ModelNode) { + bones.add((ModelNode)node); + } else { + Log.warning("Missing or invalid bone for bone weight " + + "[bone=" + bone + "]."); + } + } + return bones; + } + + /** Returns the weight of the given bone. */ + public float getWeight (ModelNode bone) + { + BoneWeight bweight = boneWeights.get(bone.getName()); + return (bweight == null) ? 0f : bweight.weight; + } + } + + /** The influence of a bone on a vertex. */ + public static class BoneWeight + { + /** The name of the influencing bone. */ + public String bone; + + /** The amount of influence. */ + public float weight; + } + + /** A group of vertices influenced by the same bone. */ + public static class WeightGroupDef + { + /** The indices of the affected vertex. */ + public ArrayList indices = new ArrayList(); + + /** The interleaved vertex weights. */ + public ArrayList weights = new ArrayList(); + } + + /** The meshes and bones comprising the model. */ + public ArrayList spatials = new ArrayList(); + + public void addSpatial (SpatialDef spatial) + { + // put nodes before meshes so that bones are updated before skin + spatials.add(spatial instanceof NodeDef ? 0 : spatials.size(), + spatial); + } + + /** + * Creates the model node defined herein. + * + * @param props the properties of the model + * @param nodes a node map to populate + */ + public Model createModel (Properties props, HashMap nodes) + { + Model model = new Model(props.getProperty("name", "model"), props); + + // set the overall scale + model.setLocalScale(Float.parseFloat(props.getProperty("scale", "1"))); + + // start by creating the spatials and mapping them to their names + for (int ii = 0, nn = spatials.size(); ii < nn; ii++) { + Spatial spatial = spatials.get(ii).getSpatial(props); + nodes.put(spatial.getName(), spatial); + } + + // then go through again, resolving any name references and attaching + // root children + HashSet referenced = new HashSet(); + for (int ii = 0, nn = spatials.size(); ii < nn; ii++) { + SpatialDef sdef = spatials.get(ii); + sdef.resolveReferences(nodes, referenced); + if (sdef.getSpatial(props).getParent() == null) { + model.attachChild(sdef.getSpatial(props)); + } + } + + // create any controllers listed + String[] controllers = StringUtil.parseStringArray( + props.getProperty("controllers", "")); + for (int ii = 0; ii < controllers.length; ii++) { + Spatial target = nodes.get(controllers[ii]); + if (target == null) { + Log.warning("Missing controller node [name=" + + controllers[ii] + "]."); + continue; + } + ModelController ctrl = createController( + PropertiesUtil.getSubProperties(props, controllers[ii]), + target); + if (ctrl != null) { + model.addController(ctrl); + } + } + + // get rid of any nodes that serve no purpose + pruneUnusedNodes(model, nodes, referenced); + + return model; + } + + /** Creates, configures, and returns a model controller. */ + protected ModelController createController ( + Properties props, Spatial target) + { + // attempt to create an instance of the controller + ModelController ctrl; + String cname = props.getProperty("class", ""); + try { + ctrl = (ModelController)Class.forName(cname).newInstance(); + } catch (Exception e) { + Log.warning("Error instantiating controller [class=" + cname + + ", error=" + e + "]."); + return null; + } + ctrl.configure(props, target); + return ctrl; + } + + /** Recursively removes any unused nodes. */ + protected boolean pruneUnusedNodes ( + ModelNode node, HashMap nodes, + HashSet referenced) + { + boolean hasValidChildren = false; + for (int ii = node.getQuantity() - 1; ii >= 0; ii--) { + Spatial child = node.getChild(ii); + if (!(child instanceof ModelNode) || + pruneUnusedNodes((ModelNode)child, nodes, referenced)) { + hasValidChildren = true; + } else { + node.detachChildAt(ii); + nodes.remove(child.getName()); + } + } + return referenced.contains(node) || hasValidChildren; + } + + /** Converts a boxed Integer list to an unboxed int array. */ + protected static int[] toArray (ArrayList list) + { + int[] array = new int[list.size()]; + for (int ii = 0, nn = list.size(); ii < nn; ii++) { + array[ii] = list.get(ii); + } + return array; + } + + /** Converts a boxed Float list to an unboxed float array. */ + protected static float[] toArray (ArrayList list) + { + float[] array = new float[list.size()]; + for (int ii = 0, nn = list.size(); ii < nn; ii++) { + array[ii] = list.get(ii); + } + return array; + } + + /** A wrapper for the model properties providing access to the properties + * of a node within the model. */ + protected static class NodeProperties extends Properties + { + public NodeProperties (Properties mprops, String name) + { + _mprops = mprops; + _prefix = name + "."; + } + + @Override // documentation inherited + public String getProperty (String key) + { + return getProperty(key, null); + } + + @Override // documentation inherited + public String getProperty (String key, String defaultValue) + { + return _mprops.getProperty(_prefix + key, + _mprops.getProperty(key, defaultValue)); + } + + /** The properties of the model. */ + protected Properties _mprops; + + /** The node prefix. */ + protected String _prefix; + } +} diff --git a/src/java/com/threerings/jme/tools/ModelViewer.java b/src/java/com/threerings/jme/tools/ModelViewer.java new file mode 100644 index 00000000..b4f45dd8 --- /dev/null +++ b/src/java/com/threerings/jme/tools/ModelViewer.java @@ -0,0 +1,1019 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; + +import java.util.HashMap; +import java.util.logging.Level; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSlider; +import javax.swing.KeyStroke; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.filechooser.FileFilter; + +import com.jme.bounding.BoundingBox; +import com.jme.bounding.BoundingVolume; +import com.jme.image.Texture; +import com.jme.light.DirectionalLight; +import com.jme.math.FastMath; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.scene.Controller; +import com.jme.scene.Line; +import com.jme.scene.Node; +import com.jme.scene.Spatial; +import com.jme.scene.state.LightState; +import com.jme.scene.state.MaterialState; +import com.jme.scene.state.TextureState; +import com.jme.scene.state.WireframeState; +import com.jme.scene.state.ZBufferState; +import com.jme.system.JmeException; +import com.jme.util.LoggingSystem; +import com.jme.util.TextureManager; +import com.jme.util.export.binary.BinaryImporter; +import com.jme.util.geom.Debugger; +import com.jmex.effects.particles.ParticleMesh; + +import com.samskivert.swing.GroupLayout; +import com.samskivert.swing.Spacer; +import com.samskivert.util.Config; +import com.samskivert.util.StringUtil; + +import com.threerings.resource.ResourceManager; +import com.threerings.util.MessageBundle; +import com.threerings.util.MessageManager; + +import com.threerings.jme.JmeCanvasApp; +import com.threerings.jme.Log; +import com.threerings.jme.camera.CameraHandler; +import com.threerings.jme.model.Model; +import com.threerings.jme.model.TextureProvider; + +/** + * A simple viewer application that allows users to examine models and their + * animations by loading them from their uncompiled .properties / + * .mxml representations or their compiled .dat + * representations. + */ +public class ModelViewer extends JmeCanvasApp +{ + public static void main (String[] args) + { + // write standard output and error to a log file + if (System.getProperty("no_log_redir") == null) { + String dlog = "viewer.log"; + try { + PrintStream logOut = new PrintStream( + new FileOutputStream(dlog), true); + System.setOut(logOut); + System.setErr(logOut); + + } catch (IOException ioe) { + Log.warning("Failed to open debug log [path=" + dlog + + ", error=" + ioe + "]."); + } + } + LoggingSystem.getLoggingSystem().setLevel(Level.WARNING); + new ModelViewer(args.length > 0 ? args[0] : null); + } + + /** + * Creates and initializes an instance of the model viewer application. + * + * @param path the path of the model to view, or null for + * none + */ + public ModelViewer (String path) + { + super(1024, 768); + _rsrcmgr = new ResourceManager("rsrc"); + _msg = new MessageManager("rsrc.i18n").getBundle("jme.viewer"); + _path = path; + + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + + _frame = new JFrame(_msg.get("m.title")); + _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JMenuBar menu = new JMenuBar(); + _frame.setJMenuBar(menu); + + JMenu file = new JMenu(_msg.get("m.file_menu")); + file.setMnemonic(KeyEvent.VK_F); + menu.add(file); + Action load = new AbstractAction(_msg.get("m.file_load")) { + public void actionPerformed (ActionEvent e) { + showLoadDialog(); + } + }; + load.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_L); + load.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK)); + file.add(load); + + Action importAction = new AbstractAction(_msg.get("m.file_import")) { + public void actionPerformed (ActionEvent e) { + showImportDialog(); + } + }; + importAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_I); + importAction.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK)); + file.add(importAction); + + file.addSeparator(); + Action quit = new AbstractAction(_msg.get("m.file_quit")) { + public void actionPerformed (ActionEvent e) { + System.exit(0); + } + }; + quit.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_Q); + quit.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_MASK)); + file.add(quit); + + JMenu view = new JMenu(_msg.get("m.view_menu")); + view.setMnemonic(KeyEvent.VK_V); + menu.add(view); + + Action wireframe = new AbstractAction(_msg.get("m.view_wireframe")) { + public void actionPerformed (ActionEvent e) { + _wfstate.setEnabled(!_wfstate.isEnabled()); + } + }; + wireframe.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_W); + wireframe.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK)); + view.add(new JCheckBoxMenuItem(wireframe)); + view.addSeparator(); + + _pivots = new JCheckBoxMenuItem(_msg.get("m.view_pivots")); + _pivots.setMnemonic(KeyEvent.VK_P); + _pivots.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_MASK)); + view.add(_pivots); + + _bounds = new JCheckBoxMenuItem(_msg.get("m.view_bounds")); + _bounds.setMnemonic(KeyEvent.VK_B); + _bounds.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK)); + view.add(_bounds); + + _normals = new JCheckBoxMenuItem(_msg.get("m.view_normals")); + _normals.setMnemonic(KeyEvent.VK_N); + _normals.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK)); + view.add(_normals); + view.addSeparator(); + + JMenu amode = new JMenu(_msg.get("m.animation_mode")); + final JRadioButtonMenuItem flipbook = + new JRadioButtonMenuItem(_msg.get("m.mode_flipbook")), + morph = new JRadioButtonMenuItem(_msg.get("m.mode_morph")), + skin = new JRadioButtonMenuItem(_msg.get("m.mode_skin")); + ButtonGroup mgroup = new ButtonGroup() { + public void setSelected (ButtonModel model, boolean b) { + super.setSelected(model, b); + if (b) { + if (flipbook.isSelected()) { + _animMode = Model.AnimationMode.FLIPBOOK; + } else if (morph.isSelected()) { + _animMode = Model.AnimationMode.MORPH; + } else { + _animMode = Model.AnimationMode.SKIN; + } + if (_loaded != null) { + loadModel(_loaded); // reload + } + } + } + }; + mgroup.add(flipbook); + mgroup.add(morph); + mgroup.add(skin); + mgroup.setSelected(skin.getModel(), true); + amode.add(skin); + amode.add(morph); + amode.add(flipbook); + view.add(amode); + view.addSeparator(); + + Action rlight = new AbstractAction(_msg.get("m.view_light")) { + public void actionPerformed (ActionEvent e) { + if (_rldialog == null) { + _rldialog = new RotateLightDialog(); + _rldialog.pack(); + } + _rldialog.setVisible(true); + } + }; + rlight.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R); + rlight.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_MASK)); + view.add(new JMenuItem(rlight)); + + Action rcamera = new AbstractAction(_msg.get("m.view_recenter")) { + public void actionPerformed (ActionEvent e) { + ((OrbitCameraHandler)_camhand).recenter(); + } + }; + rcamera.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C); + rcamera.putValue(Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK)); + view.add(new JMenuItem(rcamera)); + + _frame.getContentPane().add(getCanvas(), BorderLayout.CENTER); + + JPanel bpanel = new JPanel(new BorderLayout()); + _frame.getContentPane().add(bpanel, BorderLayout.SOUTH); + + _animctrls = new JPanel(); + _animctrls.setBorder(BorderFactory.createEtchedBorder()); + bpanel.add(_animctrls, BorderLayout.NORTH); + _animctrls.add(new JLabel(_msg.get("m.anim_select"))); + _animctrls.add(_animbox = new JComboBox()); + _animctrls.add(new JButton( + new AbstractAction(_msg.get("m.anim_start")) { + public void actionPerformed (ActionEvent e) { + String anim = (String)_animbox.getSelectedItem(); + if (_model.hasAnimation(anim)) { + _model.startAnimation(anim); + } else { // it's a sequence + if (_model.getAnimation() != null) { + _sequence = null; + _model.stopAnimation(); + } + _sequence = StringUtil.parseStringArray( + _model.getProperties().getProperty( + anim + ".animations", "")); + if (_sequence.length == 0) { + _sequence = null; + } else { + _model.startAnimation(_sequence[_seqidx = 0]); + } + } + } + })); + _animctrls.add(_animstop = new JButton( + new AbstractAction(_msg.get("m.anim_stop")) { + public void actionPerformed (ActionEvent e) { + _model.stopAnimation(); + } + })); + _animstop.setEnabled(false); + _animctrls.add(new Spacer(50, 1)); + _animctrls.add(new JLabel(_msg.get("m.anim_speed"))); + _animctrls.add(_animspeed = new JSlider(-100, +100, 0)); + _animspeed.setMajorTickSpacing(10); + _animspeed.setSnapToTicks(true); + _animspeed.setPaintTicks(true); + _animspeed.addChangeListener(new ChangeListener() { + public void stateChanged (ChangeEvent e) { + updateAnimationSpeed(); + } + }); + _animctrls.setVisible(false); + + _status = new JLabel(" "); + _status.setHorizontalAlignment(JLabel.LEFT); + _status.setBorder(BorderFactory.createEtchedBorder()); + bpanel.add(_status, BorderLayout.SOUTH); + + _frame.pack(); + _frame.setVisible(true); + + run(); + } + + @Override // documentation inherited + public boolean init () + { + if (!super.init()) { + return false; + } + if (_path != null) { + loadModel(new File(_path)); + } + return true; + } + + @Override // documentation inherited + protected void initDisplay () + throws JmeException + { + super.initDisplay(); + _ctx.getRenderer().setBackgroundColor(ColorRGBA.gray); + } + + @Override // documentation inherited + protected void initInput () + { + super.initInput(); + + _camhand.setTiltLimits(FastMath.PI / 16.0f, FastMath.PI * 7.0f / 16.0f); + _camhand.setZoomLimits(1f, 100f); + _camhand.tiltCamera(-FastMath.PI * 7.0f / 16.0f); + + MouseOrbiter orbiter = new MouseOrbiter(); + _canvas.addMouseListener(orbiter); + _canvas.addMouseMotionListener(orbiter); + _canvas.addMouseWheelListener(orbiter); + } + + @Override // documentation inherited + protected CameraHandler createCameraHandler (Camera camera) + { + return new OrbitCameraHandler(camera); + } + + @Override // documentation inherited + protected void initRoot () + { + super.initRoot(); + + // set default states + MaterialState mstate = _ctx.getRenderer().createMaterialState(); + mstate.getDiffuse().set(ColorRGBA.white); + mstate.getAmbient().set(ColorRGBA.white); + _ctx.getGeometry().setRenderState(mstate); + _ctx.getGeometry().setRenderState( + _wfstate = _ctx.getRenderer().createWireframeState()); + _ctx.getGeometry().setNormalsMode(Spatial.NM_GL_NORMALIZE_PROVIDED); + _wfstate.setEnabled(false); + + // create a grid on the XY plane to provide some reference + Vector3f[] points = new Vector3f[GRID_SIZE*2 + GRID_SIZE*2]; + float halfLength = (GRID_SIZE - 1) * GRID_SPACING / 2; + int idx = 0; + for (int xx = 0; xx < GRID_SIZE; xx++) { + points[idx++] = new Vector3f( + -halfLength + xx*GRID_SPACING, -halfLength, 0f); + points[idx++] = new Vector3f( + -halfLength + xx*GRID_SPACING, +halfLength, 0f); + } + for (int yy = 0; yy < GRID_SIZE; yy++) { + points[idx++] = new Vector3f( + -halfLength, -halfLength + yy*GRID_SPACING, 0f); + points[idx++] = new Vector3f( + +halfLength, -halfLength + yy*GRID_SPACING, 0f); + + } + Line grid = new Line("grid", points, null, null, null); + grid.getBatch(0).getDefaultColor().set(0.25f, 0.25f, 0.25f, 1f); + grid.setLightCombineMode(LightState.OFF); + grid.setModelBound(new BoundingBox()); + grid.updateModelBound(); + _ctx.getGeometry().attachChild(grid); + grid.updateRenderState(); + + // attach a dummy node to draw debugging views + _ctx.getGeometry().attachChild(new Node("debug") { + public void onDraw (Renderer r) { + if (_model == null) { + return; + } + if (_pivots.getState()) { + drawPivots(_model, r); + } + if (_bounds.getState()) { + Debugger.drawBounds(_model, r); + } + if (_normals.getState()) { + Debugger.drawNormals(_model, r, 5f, true); + } + } + }); + } + + /** + * Draws the pivot axes of the given node and its children. + */ + protected void drawPivots (Spatial spatial, Renderer r) + { + if (_axes == null) { + _axes = new Line("axes", + new Vector3f[] { Vector3f.ZERO, Vector3f.UNIT_X, Vector3f.ZERO, + Vector3f.UNIT_Y, Vector3f.ZERO, Vector3f.UNIT_Z }, null, + new ColorRGBA[] { ColorRGBA.red, ColorRGBA.red, + ColorRGBA.green, ColorRGBA.green, ColorRGBA.blue, + ColorRGBA.blue }, null); + _axes.setRenderQueueMode(Renderer.QUEUE_SKIP); + _axes.setRenderState(r.createZBufferState()); + LightState lstate = r.createLightState(); + lstate.setEnabled(false); + _axes.setRenderState(lstate); + _axes.updateRenderState(); + } + _axes.getRenderState(ZBufferState.RS_ZBUFFER).apply(); + _axes.getRenderState(LightState.RS_LIGHT).apply(); + _axes.getWorldTranslation().set(spatial.getWorldTranslation()); + _axes.getWorldRotation().set(spatial.getWorldRotation()); + _axes.draw(r); + + if (spatial instanceof Node) { + Node node = (Node)spatial; + for (int ii = 0, nn = node.getQuantity(); ii < nn; ii++) { + drawPivots(node.getChild(ii), r); + } + } + } + + @Override // documentation inherited + protected void initLighting () + { + _dlight = new DirectionalLight(); + _dlight.setEnabled(true); + _dlight.getDirection().set(-1f, 0f, -1f).normalizeLocal(); + _dlight.getAmbient().set(0.25f, 0.25f, 0.25f, 1f); + + LightState lstate = _ctx.getRenderer().createLightState(); + lstate.attach(_dlight); + _ctx.getGeometry().setRenderState(lstate); + _ctx.getGeometry().setLightCombineMode(LightState.REPLACE); + } + + /** + * Shows the load model dialog. + */ + protected void showLoadDialog () + { + if (_chooser == null) { + _chooser = new JFileChooser(); + _chooser.setDialogTitle(_msg.get("m.load_title")); + _chooser.setFileFilter(new FileFilter() { + public boolean accept (File file) { + if (file.isDirectory()) { + return true; + } + String path = file.toString().toLowerCase(); + return path.endsWith(".properties") || + path.endsWith(".dat"); + } + public String getDescription () { + return _msg.get("m.load_filter"); + } + }); + File dir = new File(_config.getValue("dir", ".")); + if (dir.exists()) { + _chooser.setCurrentDirectory(dir); + } + } + if (_chooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { + loadModel(_chooser.getSelectedFile()); + } + _config.setValue("dir", _chooser.getCurrentDirectory().toString()); + } + + /** + * Attempts to load a model from the specified location. + */ + protected void loadModel (File file) + { + String fpath = file.toString(); + try { + if (fpath.endsWith(".properties")) { + compileModel(file); + } else if (fpath.endsWith(".dat")) { + loadCompiledModel(file); + } else { + throw new Exception(_msg.get("m.invalid_type")); + } + _status.setText(_msg.get("m.loaded_model", fpath)); + _loaded = file; + + } catch (Exception e) { + e.printStackTrace(); + _status.setText(_msg.get("m.load_error", fpath, e)); + } + } + + /** + * Attempts to compile and load a model. + */ + protected void compileModel (File file) + throws Exception + { + _status.setText(_msg.get("m.compiling_model", file)); + Model model = CompileModel.compile(file); + if (model != null) { + setModel(model, file); + return; + } + // if compileModel returned null, the .dat file is up-to-date + String fpath = file.toString(); + int didx = fpath.lastIndexOf('.'); + fpath = (didx == -1) ? fpath : fpath.substring(0, didx); + loadCompiledModel(new File(fpath + ".dat")); + } + + /** + * Attempts to load a model that has already been compiled. + */ + protected void loadCompiledModel (File file) + throws IOException + { + _status.setText(_msg.get("m.loading_model", file)); + setModel(Model.readFromFile(file, false), file); + } + + /** + * Sets the model once it's been loaded. + * + * @param file the file from which the model was loaded + */ + protected void setModel (Model model, File file) + { + if (_model != null) { + _ctx.getGeometry().detachChild(_model); + } + _ctx.getGeometry().attachChild(_model = model); + _model.setAnimationMode(_animMode); + _model.lockStaticMeshes(_ctx.getRenderer(), true, true); + + // resolve the textures from the file's directory + final File dir = file.getParentFile(); + _model.resolveTextures(new TextureProvider() { + public TextureState getTexture (String name) { + TextureState tstate = _tstates.get(name); + if (tstate == null) { + File file; + if (name.startsWith("/")) { + file = _rsrcmgr.getResourceFile(name.substring(1)); + } else { + file = new File(dir, name); + } + Texture tex = TextureManager.loadTexture(file.toString(), + Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR); + if (tex == null) { + Log.warning("Couldn't find texture [path=" + file + + "]."); + return null; + } + tex.setWrap(Texture.WM_WRAP_S_WRAP_T); + tstate = _ctx.getRenderer().createTextureState(); + tstate.setTexture(tex); + _tstates.put(name, tstate); + } + return tstate; + } + protected HashMap _tstates = + new HashMap(); + }); + _model.updateRenderState(); + + // recenter the camera + _model.updateGeometricState(0f, true); + ((OrbitCameraHandler)_camhand).recenter(); + + // configure the animation panel + String[] anims = _model.getAnimationNames(); + if (anims.length == 0) { + _animctrls.setVisible(false); + return; + } + _model.addAnimationObserver(_animobs); + _animctrls.setVisible(true); + DefaultComboBoxModel abmodel = new DefaultComboBoxModel(anims); + _animbox.setModel(abmodel); + updateAnimationSpeed(); + + // if there are any sequences, add those as well + String[] seqs = StringUtil.parseStringArray( + _model.getProperties().getProperty("sequences", "")); + for (String seq : seqs) { + abmodel.addElement(seq); + } + } + + /** + * Shows the import particle system dialog. + */ + protected void showImportDialog () + { + if (_ichooser == null) { + _ichooser = new JFileChooser(); + _ichooser.setDialogTitle(_msg.get("m.import_title")); + _ichooser.setFileFilter(new FileFilter() { + public boolean accept (File file) { + if (file.isDirectory()) { + return true; + } + String path = file.toString().toLowerCase(); + return path.endsWith(".jme"); + } + public String getDescription () { + return _msg.get("m.import_filter"); + } + }); + File dir = new File(_config.getValue("import_dir", ".")); + if (dir.exists()) { + _ichooser.setCurrentDirectory(dir); + } + } + if (_ichooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { + importFile(_ichooser.getSelectedFile()); + } + _config.setValue("import_dir", + _ichooser.getCurrentDirectory().toString()); + } + + /** + * Attempts to import the specified file as a JME binary scene. + */ + protected void importFile (File file) + { + try { + new ImportDialog(file, + (Spatial)BinaryImporter.getInstance().load( + file)).setVisible(true); + + } catch (Exception e) { + e.printStackTrace(); + _status.setText(_msg.get("m.load_error", file, e)); + } + } + + /** + * Updates the model's animation speed based on the position of the + * animation speed slider. + */ + protected void updateAnimationSpeed () + { + _model.setAnimationSpeed( + FastMath.pow(2f, _animspeed.getValue() / 25f)); + } + + /** The resource manager. */ + protected ResourceManager _rsrcmgr; + + /** The translation bundle. */ + protected MessageBundle _msg; + + /** The path of the initial model to load. */ + protected String _path; + + /** The last model successfully loaded. */ + protected File _loaded; + + /** The viewer frame. */ + protected JFrame _frame; + + /** Debug view switches. */ + protected JCheckBoxMenuItem _pivots, _bounds, _normals; + + /** The animation controls. */ + protected JPanel _animctrls; + + /** The animation selector. */ + protected JComboBox _animbox; + + /** The "stop animation" button. */ + protected JButton _animstop; + + /** The animation speed slider. */ + protected JSlider _animspeed; + + /** The status bar. */ + protected JLabel _status; + + /** The model file chooser. */ + protected JFileChooser _chooser; + + /** The import file chooser. */ + protected JFileChooser _ichooser; + + /** The desired animation mode. */ + protected Model.AnimationMode _animMode; + + /** The light rotation dialog. */ + protected RotateLightDialog _rldialog; + + /** The scene light. */ + protected DirectionalLight _dlight; + + /** Used to toggle wireframe rendering. */ + protected WireframeState _wfstate; + + /** The currently loaded model. */ + protected Model _model; + + /** Reused to draw pivot axes. */ + protected Line _axes; + + /** The current animation sequence, if any. */ + protected String[] _sequence; + + /** The current index in the animation sequence. */ + protected int _seqidx; + + /** Enables and disables the stop button when animations start and stop. */ + protected Model.AnimationObserver _animobs = + new Model.AnimationObserver() { + public boolean animationStarted (Model model, String name) { + _animstop.setEnabled(true); + return true; + } + public boolean animationCompleted (Model model, String name) { + if (_sequence != null && ++_seqidx < _sequence.length) { + _model.startAnimation(_sequence[_seqidx]); + } else { + _animstop.setEnabled(false); + _sequence = null; + } + return true; + } + public boolean animationCancelled (Model model, String name) { + if (_sequence != null && ++_seqidx < _sequence.length && + _model.getAnimation(name).repeatType != Controller.RT_CLAMP) { + _model.startAnimation(_sequence[_seqidx]); + } else { + _animstop.setEnabled(false); + _sequence = null; + } + return true; + } + }; + + /** Allows users to manipulate an imported JME file. */ + protected class ImportDialog extends JDialog + implements ChangeListener + { + public ImportDialog (File file, Spatial spatial) + { + super(_frame, _msg.get("m.import", file), false); + _spatial = spatial; + + // rotate from y-up to z-up and set initial scale + _spatial.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI, + Vector3f.UNIT_X); + _spatial.setLocalScale(0.025f); + + JPanel cpanel = GroupLayout.makeVBox(); + getContentPane().add(cpanel, BorderLayout.CENTER); + + JPanel spanel = new JPanel(); + spanel.add(new JLabel(_msg.get("m.scale"))); + spanel.add(_scale = new JSlider(0, 1000, 250)); + _scale.addChangeListener(this); + cpanel.add(spanel); + + JPanel bpanel = new JPanel(); + bpanel.add(new JButton(new AbstractAction( + _msg.get("m.respawn_particles")) { + public void actionPerformed (ActionEvent e) { + forceRespawn(_spatial); + } + })); + bpanel.add(new JButton(new AbstractAction(_msg.get("m.close")) { + public void actionPerformed (ActionEvent e) { + setVisible(false); + } + })); + getContentPane().add(bpanel, BorderLayout.SOUTH); + pack(); + } + + // documentation inherited from interface ChangeListener + public void stateChanged (ChangeEvent e) + { + _spatial.setLocalScale(_scale.getValue() * 0.0001f); + } + + @Override // documentation inherited + public void setVisible (boolean visible) + { + super.setVisible(visible); + if (visible && _spatial.getParent() == null) { + _ctx.getGeometry().attachChild(_spatial); + } else if (!visible && _spatial.getParent() != null) { + _ctx.getGeometry().detachChild(_spatial); + } + } + + /** + * Recursively forces all particles to respawn. + */ + protected void forceRespawn (Spatial spatial) + { + if (spatial instanceof ParticleMesh) { + ((ParticleMesh)spatial).forceRespawn(); + } else if (spatial instanceof Node) { + Node node = (Node)spatial; + for (int ii = 0, nn = node.getQuantity(); ii < nn; ii++) { + forceRespawn(node.getChild(ii)); + } + } + } + + /** The imported scene. */ + protected Spatial _spatial; + + /** The scale slider. */ + protected JSlider _scale; + } + + /** Allows users to move the directional light around. */ + protected class RotateLightDialog extends JDialog + implements ChangeListener + { + public RotateLightDialog () + { + super(_frame, _msg.get("m.rotate_light"), false); + + JPanel cpanel = GroupLayout.makeVBox(); + getContentPane().add(cpanel, BorderLayout.CENTER); + + JPanel apanel = new JPanel(); + apanel.add(new JLabel(_msg.get("m.azimuth"))); + apanel.add(_azimuth = new JSlider(-180, +180, 0)); + _azimuth.addChangeListener(this); + cpanel.add(apanel); + + JPanel epanel = new JPanel(); + epanel.add(new JLabel(_msg.get("m.elevation"))); + epanel.add(_elevation = new JSlider(-90, +90, 45)); + _elevation.addChangeListener(this); + cpanel.add(epanel); + + JPanel bpanel = new JPanel(); + bpanel.add(new JButton(new AbstractAction(_msg.get("m.close")) { + public void actionPerformed (ActionEvent e) { + setVisible(false); + } + })); + getContentPane().add(bpanel, BorderLayout.SOUTH); + } + + // documentation inherited from interface ChangeListener + public void stateChanged (ChangeEvent e) + { + float az = _azimuth.getValue() * FastMath.DEG_TO_RAD, + el = _elevation.getValue() * FastMath.DEG_TO_RAD; + _dlight.getDirection().set( + -FastMath.cos(az) * FastMath.cos(el), + -FastMath.sin(az) * FastMath.cos(el), + -FastMath.sin(el)); + } + + /** Azimuth and elevation sliders. */ + protected JSlider _azimuth, _elevation; + } + + /** Moves the camera using mouse input. */ + protected class MouseOrbiter extends MouseAdapter + implements MouseMotionListener, MouseWheelListener + { + @Override // documentation inherited + public void mousePressed (MouseEvent e) + { + _mloc.setLocation(e.getX(), e.getY()); + } + + // documentation inherited from interface MouseMotionListener + public void mouseMoved (MouseEvent e) + { + } + + // documentation inherited from interface MouseMotionListener + public void mouseDragged (MouseEvent e) + { + int dx = e.getX() - _mloc.x, dy = e.getY() - _mloc.y; + _mloc.setLocation(e.getX(), e.getY()); + int mods = e.getModifiers(); + if ((mods & MouseEvent.BUTTON1_MASK) != 0) { + _camhand.tiltCamera(dy * FastMath.PI / 1000); + _camhand.orbitCamera(-dx * FastMath.PI / 1000); + } else if ((mods & MouseEvent.BUTTON2_MASK) != 0) { + _camhand.zoomCamera(dy/8f); + } else { + _camhand.panCamera(-dx/8f, dy/8f); + } + } + + // documentation inherited from interface MouseWheelListener + public void mouseWheelMoved (MouseWheelEvent e) + { + _camhand.zoomCamera(e.getWheelRotation() * 10f); + } + + /** The last recorded position of the mouse cursor. */ + protected Point _mloc = new Point(); + } + + /** A camera handler that pans in directions orthogonal to the camera + * direction. */ + protected class OrbitCameraHandler extends CameraHandler + { + public OrbitCameraHandler (Camera camera) + { + super(camera); + _gpoint = super.getGroundPoint(); + } + + @Override // documentation inherited + public void panCamera (float x, float y) { + Vector3f offset = _camera.getLeft().mult(-x).addLocal( + _camera.getUp().mult(y)); + getGroundPoint().addLocal(offset); + _camera.getLocation().addLocal(offset); + _camera.onFrameChange(); + } + + @Override // documentation inherited + public Vector3f getGroundPoint () + { + return _gpoint; + } + + /** + * Resets the ground point to the center of the grid or, if there is + * one, the center of the model. + */ + public void recenter () + { + Vector3f target = new Vector3f(); + if (_model != null) { + BoundingVolume bound = (BoundingVolume)_model.getWorldBound(); + if (bound != null) { + bound.getCenter(target); + } + } + Vector3f offset = target.subtract(_gpoint); + _camera.getLocation().addLocal(offset); + _camera.onFrameChange(); + _gpoint.set(target); + } + + /** The point at which the camera is looking. */ + protected Vector3f _gpoint; + } + + /** The app configuration. */ + protected static Config _config = + new Config("com/threerings/jme/tools/ModelViewer"); + + /** The number of lines on the grid in each direction. */ + protected static final int GRID_SIZE = 32; + + /** The spacing between lines on the grid. */ + protected static final float GRID_SPACING = 2.5f; +} diff --git a/src/java/com/threerings/jme/tools/xml/AnimationParser.java b/src/java/com/threerings/jme/tools/xml/AnimationParser.java new file mode 100644 index 00000000..5da48a96 --- /dev/null +++ b/src/java/com/threerings/jme/tools/xml/AnimationParser.java @@ -0,0 +1,88 @@ +// +// $Id: SceneParser.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools.xml; + +import java.io.FileInputStream; +import java.io.IOException; + +import org.xml.sax.SAXException; +import org.apache.commons.digester.Digester; + +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.jme.tools.AnimationDef; + +/** + * Parses XML files containing animations. + */ +public class AnimationParser +{ + public AnimationParser () + { + // create and configure our digester + _digester = new Digester(); + + // add the rules + String anim = "animation"; + _digester.addObjectCreate(anim, AnimationDef.class.getName()); + _digester.addRule(anim, new SetPropertyFieldsRule()); + _digester.addSetNext(anim, "setAnimation", + AnimationDef.class.getName()); + + String frame = anim + "/frame"; + _digester.addObjectCreate(frame, + AnimationDef.FrameDef.class.getName()); + _digester.addSetNext(frame, "addFrame", + AnimationDef.FrameDef.class.getName()); + + String xform = frame + "/transform"; + _digester.addObjectCreate(xform, + AnimationDef.TransformDef.class.getName()); + _digester.addRule(xform, new SetPropertyFieldsRule()); + _digester.addSetNext(xform, "addTransform", + AnimationDef.TransformDef.class.getName()); + } + + /** + * Parses the XML file at the specified path into an animation + * definition. + */ + public AnimationDef parseAnimation (String path) + throws IOException, SAXException + { + _animation = null; + _digester.push(this); + _digester.parse(new FileInputStream(path)); + return _animation; + } + + /** + * Called by the parser once the animation is parsed. + */ + public void setAnimation (AnimationDef animation) + { + _animation = animation; + } + + protected Digester _digester; + protected AnimationDef _animation; +} diff --git a/src/java/com/threerings/jme/tools/xml/ModelParser.java b/src/java/com/threerings/jme/tools/xml/ModelParser.java new file mode 100644 index 00000000..e55469fa --- /dev/null +++ b/src/java/com/threerings/jme/tools/xml/ModelParser.java @@ -0,0 +1,109 @@ +// +// $Id: SceneParser.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.tools.xml; + +import java.io.FileInputStream; +import java.io.IOException; + +import org.xml.sax.SAXException; +import org.apache.commons.digester.Digester; + +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.jme.tools.ModelDef; + +/** + * Parses XML files containing 3D models. + */ +public class ModelParser +{ + public ModelParser () + { + // create and configure our digester + _digester = new Digester(); + + // add the rules + String model = "model"; + _digester.addObjectCreate(model, ModelDef.class.getName()); + _digester.addSetNext(model, "setModel", ModelDef.class.getName()); + + String tmesh = model + "/triMesh"; + _digester.addObjectCreate(tmesh, ModelDef.TriMeshDef.class.getName()); + _digester.addRule(tmesh, new SetPropertyFieldsRule()); + _digester.addSetNext(tmesh, "addSpatial", + ModelDef.SpatialDef.class.getName()); + + String smesh = model + "/skinMesh"; + _digester.addObjectCreate(smesh, + ModelDef.SkinMeshDef.class.getName()); + _digester.addRule(smesh, new SetPropertyFieldsRule()); + _digester.addSetNext(smesh, "addSpatial", + ModelDef.SpatialDef.class.getName()); + + String node = model + "/node"; + _digester.addObjectCreate(node, ModelDef.NodeDef.class.getName()); + _digester.addRule(node, new SetPropertyFieldsRule()); + _digester.addSetNext(node, "addSpatial", + ModelDef.SpatialDef.class.getName()); + + String vertex = tmesh + "/vertex", svertex = smesh + "/vertex"; + _digester.addObjectCreate(vertex, ModelDef.Vertex.class.getName()); + _digester.addObjectCreate(svertex, + ModelDef.SkinVertex.class.getName()); + _digester.addRule(vertex, new SetPropertyFieldsRule()); + _digester.addRule(svertex, new SetPropertyFieldsRule()); + _digester.addSetNext(vertex, "addVertex", + ModelDef.Vertex.class.getName()); + _digester.addSetNext(svertex, "addVertex", + ModelDef.Vertex.class.getName()); + + String bweight = smesh + "/vertex/boneWeight"; + _digester.addObjectCreate(bweight, + ModelDef.BoneWeight.class.getName()); + _digester.addRule(bweight, new SetPropertyFieldsRule()); + _digester.addSetNext(bweight, "addBoneWeight", + ModelDef.BoneWeight.class.getName()); + } + + /** + * Parses the XML file at the specified path into a model definition. + */ + public ModelDef parseModel (String path) + throws IOException, SAXException + { + _model = null; + _digester.push(this); + _digester.parse(new FileInputStream(path)); + return _model; + } + + /** + * Called by the parser once the model is parsed. + */ + public void setModel (ModelDef model) + { + _model = model; + } + + protected Digester _digester; + protected ModelDef _model; +} diff --git a/src/java/com/threerings/jme/util/LinearTimeFunction.java b/src/java/com/threerings/jme/util/LinearTimeFunction.java new file mode 100644 index 00000000..d29ccd7a --- /dev/null +++ b/src/java/com/threerings/jme/util/LinearTimeFunction.java @@ -0,0 +1,42 @@ +// +// $Id: LinearTimeFunction.java 3122 2004-09-18 22:57:08Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.util; + +/** + * Varies a value linearly with time. + */ +public class LinearTimeFunction extends TimeFunction +{ + public LinearTimeFunction (float start, float end, float duration) + { + super(start, end, duration); + _range = (end - start); + } + + // documentation inherited + protected float computeValue () + { + return (_elapsed * _range / _duration) + _start; + } + + protected float _range; +} diff --git a/src/java/com/threerings/jme/util/TimeFunction.java b/src/java/com/threerings/jme/util/TimeFunction.java new file mode 100644 index 00000000..73afaa0f --- /dev/null +++ b/src/java/com/threerings/jme/util/TimeFunction.java @@ -0,0 +1,99 @@ +// +// $Id: TimeFunction.java 3122 2004-09-18 22:57:08Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.util; + +/** + * Used to vary a value over time where time is provided at discrete increments + * (on the frame tick) and the value is computed appropriately. This can be + * used for fades and other effects where different functions (linear, ease-in + * ease-out, etc.) should be easy to plug in. + */ +public abstract class TimeFunction +{ + /** + * Every time function varies a value from some starting value to some + * ending value over some duration. The way in which it varies + * (linearly, for example) is up to the derived class. + * + * @param start the starting value. + * @param end the ending value. + * @param duration the duration in seconds. + */ + public TimeFunction (float start, float end, float duration) + { + _start = start; + _end = end; + _duration = duration; + } + + /** + * Returns the current value given the supplied elapsed time. The value + * will be bounded to the originally supplied starting and ending values at + * times 0 (and below) and {@link #_duration} (and above) respectively. + * + * @param deltaTime the amount of time that has elapsed since the last call + * to this method. + */ + public float getValue (float deltaTime) + { + _elapsed += deltaTime; + + if (_elapsed <= 0) { + return _start; + } else if (_elapsed >= _duration) { + return _end; + } else { + return computeValue(); + } + } + + /** + * Returns true if this function has proceeded the full length of its + * duration. This should be called after a call to {@link #getValue} has + * been made to update our internal elapsed time. + */ + public boolean isComplete () + { + return _elapsed >= _duration; + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return _start + " to " + _end + ", " + _elapsed + " of " + _duration; + } + + /** + * This must be implemented by our derived class to compute our value given + * the currently stored {@link #_elapsed} time. + */ + protected abstract float computeValue (); + + /** Our starting and ending values. */ + protected float _start, _end; + + /** The number of milliseconds over which we vary our value. */ + protected float _duration; + + /** The number of seconds that have elapsed since we started. */ + protected float _elapsed; +} diff --git a/src/java/com/threerings/media/AbstractMedia.java b/src/java/com/threerings/media/AbstractMedia.java new file mode 100644 index 00000000..da4b7902 --- /dev/null +++ b/src/java/com/threerings/media/AbstractMedia.java @@ -0,0 +1,332 @@ +// +// $Id: AbstractMedia.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; + +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import com.samskivert.util.ObserverList; +import com.samskivert.util.StringUtil; + +/** + * Something that can be rendered on the media panel. + */ +public abstract class AbstractMedia + implements Shape +{ + /** A {@link #_renderOrder} value at or above which, indicates that this + * media is in the HUD (heads up display) and should not scroll when the + * view scrolls. */ + public static final int HUD_LAYER = 65536; + + /** + * Instantiate an abstract media object. + */ + public AbstractMedia (Rectangle bounds) + { + _bounds = bounds; + } + + /** + * Called periodically by this media's manager to give it + * a chance to do its thing. + * + * @param tickStamp a time stamp associated with this tick. + * Note: this is not obtained from a call to {@link + * System#currentTimeMillis} and cannot be compared to timestamps + * obtained there from. + */ + public abstract void tick (long tickStamp); + + /** + * Called by the appropriate manager to request that the + * media render itself with the given graphics context. The + * media may wish to inspect the clipping region that has been set + * on the graphics context to render itself more efficiently. This + * method will only be called after it has been established that this + * media's bounds intersect the clipping region. + */ + public abstract void paint (Graphics2D gfx); + + /** + * Called when the appropriate media manager has been paused for some + * length of time and is then unpaused. Media should adjust any time stamps + * that are maintained internally forward by the delta so that time + * maintains the illusion of flowing smoothly forward. + */ + public void fastForward (long timeDelta) + { + // adjust our first tick stamp + _firstTick += timeDelta; + } + + /** + * Invalidate the media's bounding rectangle for later painting. + */ + public void invalidate () + { + if (_mgr != null) { + _mgr.getRegionManager().invalidateRegion(_bounds); + } + } + + /** + * Set the location. + */ + public void setLocation (int x, int y) + { + _bounds.x = x; + _bounds.y = y; + } + + /** + * Returns a rectangle containing all the pixels rendered by this media. + */ + public Rectangle getBounds () + { + return _bounds; + } + + // documentation inherited from interface Shape + public Rectangle2D getBounds2D () + { + return _bounds; + } + + // documentation inherited from interface Shape + public boolean contains (double x, double y) + { + return _bounds.contains(x, y); + } + + // documentation inherited from interface Shape + public boolean contains (Point2D p) + { + return _bounds.contains(p); + } + + // documentation inherited from interface Shape + public boolean intersects (double x, double y, double w, double h) + { + return _bounds.intersects(x, y, w, h); + } + + // documentation inherited from interface Shape + public boolean intersects (Rectangle2D r) + { + return _bounds.intersects(r); + } + + // documentation inherited from interface Shape + public boolean contains (double x, double y, double w, double h) + { + return _bounds.contains(x, y, w, h); + } + + // documentation inherited from interface Shape + public boolean contains (Rectangle2D r) + { + return _bounds.contains(r); + } + + // documentation inherited from interface Shape + public PathIterator getPathIterator (AffineTransform at) + { + return _bounds.getPathIterator(at); + } + + // documentation inherited from interface Shape + public PathIterator getPathIterator (AffineTransform at, double flatness) + { + return _bounds.getPathIterator(at, flatness); + } + + /** + * Sets the render order associated with this media. Media + * can be rendered in two layers; those with negative render order and + * those with positive render order. In the same layer, they + * will be rendered according to their render order's cardinal value + * (least to greatest). Those with the same render order value will be + * rendered in arbitrary order. + * + *

This method may not be called during a tick. + * + * @see #HUD_LAYER + */ + public void setRenderOrder (int renderOrder) + { + if (_renderOrder != renderOrder) { + _renderOrder = renderOrder; + if (_mgr != null) { + _mgr.renderOrderDidChange(this); + invalidate(); + } + } + } + + /** + * Returns the render order of this media element. + */ + public int getRenderOrder () + { + return _renderOrder; + } + + /** + * Queues the supplied notification up to be dispatched to this + * abstract media's observers. + */ + public void queueNotification (ObserverList.ObserverOp amop) + { + if (_observers != null) { + if (_mgr != null) { + _mgr.queueNotification(_observers, amop); + } else { + Log.warning("Have no manager, dropping notification " + + "[media=" + this + ", op=" + amop + "]."); + } + } + } + + /** + * Called by the {@link AbstractMediaManager} when we are in a + * {@link VirtualMediaPanel} that just scrolled. + */ + public void viewLocationDidChange (int dx, int dy) + { + if (_renderOrder >= HUD_LAYER) { + setLocation(_bounds.x + dx, _bounds.y + dy); + } + } + + /** + * Dumps this media to a String object. + */ + public String toString () + { + StringBuilder buf = new StringBuilder(); + buf.append(StringUtil.shortClassName(this)); + buf.append("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * Initialize the media. + */ + protected final void init (AbstractMediaManager manager) + { + _mgr = manager; + init(); + } + + /** + * Called when the media has had its manager set. + * Derived classes may override this method, but should be sure to + * call super.init(). + */ + protected void init () + { + } + + /** + * Prior to the first call to {@link #tick} on an abstract media, this + * method is called by the {@link AbstractMediaManager}. It is called + * during the normal tick cycle, immediately prior to the first call + * to {@link #tick}. + * + *

Note: It is imperative that + * super.willStart() is called by any entity that + * overrides this method because the {@link AbstractMediaManager} + * depends on the setting of the {@link #_firstTick} value to know + * whether or not to call this method. + */ + protected void willStart (long tickStamp) + { + _firstTick = tickStamp; + } + + /** + * Called by the media manager after the media is removed from service. + * Derived classes may override this method, but should be sure to + * call super.shutdown(). + */ + protected void shutdown () + { + invalidate(); + _mgr = null; + } + + /** + * Add the specified observer to this media element. + */ + protected void addObserver (Object obs) + { + if (_observers == null) { + _observers = new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); + } + _observers.add(obs); + } + + /** + * Remove the specified observer from this media element. + */ + protected void removeObserver (Object obs) + { + if (_observers != null) { + _observers.remove(obs); + } + } + + /** + * This should be overridden by derived classes (which should be sure + * to call super.toString()) to append the derived class + * specific information to the string buffer. + */ + protected void toString (StringBuilder buf) + { + buf.append("bounds=").append(StringUtil.toString(_bounds)); + buf.append(", renderOrder=").append(_renderOrder); + } + + /** The layer in which to render. */ + protected int _renderOrder = 0; + + /** The bounds of the media's rendering area. */ + protected Rectangle _bounds; + + /** Our manager. */ + protected AbstractMediaManager _mgr; + + /** Our observers. */ + protected ObserverList _observers = null; + + /** The tick stamp associated with our first call to {@link #tick}. + * This is set up automatically in {@link #willStart}. */ + protected long _firstTick; +} diff --git a/src/java/com/threerings/media/AbstractMediaManager.java b/src/java/com/threerings/media/AbstractMediaManager.java new file mode 100644 index 00000000..2526e906 --- /dev/null +++ b/src/java/com/threerings/media/AbstractMediaManager.java @@ -0,0 +1,335 @@ +// +// $Id: AbstractMediaManager.java 3551 2005-05-13 22:22:56Z andrzej $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Graphics2D; +import java.awt.Shape; + +import java.util.ArrayList; +import java.util.Comparator; + +import com.samskivert.util.ObserverList.ObserverOp; +import com.samskivert.util.ObserverList; +import com.samskivert.util.SortableArrayList; +import com.samskivert.util.Tuple; + +/** + * Manages, ticks, and paints {@link AbstractMedia}. + */ +public abstract class AbstractMediaManager + implements MediaConstants +{ + /** + * Default constructor. + */ + public AbstractMediaManager (MediaPanel panel) + { + _panel = panel; + _remgr = panel.getRegionManager(); + } + + /** + * Returns region manager in use by this manager. + */ + public RegionManager getRegionManager () + { + return _remgr; + } + + /** + * Returns the media panel with which we are coordinating. + */ + public MediaPanel getMediaPanel () + { + return _panel; + } + + /** + * Must be called every frame so that the media can be properly + * updated. + */ + public void tick (long tickStamp) + { + _tickStamp = tickStamp; + tickAllMedia(tickStamp); + dispatchNotifications(); + // we clear our tick stamp when we're about to be painted, this + // lets us handle situations when yet more media is slipped in + // between our being ticked and our being painted + } + + /** + * This will always be called prior to the {@link #paint} calls for a + * particular tick. Because it is possible that there will be no dirty + * regions and thus no calls to {@link #paint} this method exists so + * that the media manager can guarantee that it will be notified when + * all ticking is complete and the painting phase has begun. + */ + public void willPaint () + { + // now that we're done ticking, we can safely clear this + _tickStamp = 0; + } + + /** + * Renders all registered media in the given layer that intersect + * the supplied clipping rectangle to the given graphics context. + * + * @param layer the layer to render; one of {@link #FRONT}, {@link + * #BACK}, or {@link #ALL}. The front layer contains all animations + * with a positive render order; the back layer contains all + * animations with a negative render order; all, both. + */ + public void paint (Graphics2D gfx, int layer, Shape clip) + { + for (int ii = 0, nn = _media.size(); ii < nn; ii++) { + AbstractMedia media = (AbstractMedia)_media.get(ii); + int order = media.getRenderOrder(); + try { + if (((layer == ALL) || + (layer == FRONT && order >= 0) || + (layer == BACK && order < 0)) && + clip.intersects(media.getBounds())) { + media.paint(gfx); + } + + } catch (Exception e) { + Log.warning("Failed to render media " + + "[media=" + media + ", e=" + e + "]."); + Log.logStackTrace(e); + } + } + } + + /** + * If the manager is paused for some length of time, it should + * be fast forwarded by the appropriate number of milliseconds. This + * allows media to smoothly pick up where they left off rather than + * abruptly jumping into the future, thinking that some outrageous + * amount of time passed since their last tick. + */ + public void fastForward (long timeDelta) + { + if (_tickStamp > 0) { + Log.warning("Egads! Asked to fastForward() during a tick."); + Thread.dumpStack(); + } + + for (int ii=0, nn=_media.size(); ii < nn; ii++) { + ((AbstractMedia) _media.get(ii)).fastForward(timeDelta); + } + } + + /** + * Returns true if the specified media is being managed by this media + * manager. + */ + public boolean isManaged (AbstractMedia media) + { + return _media.contains(media); + } + + /** + * Called by a {@link VirtualMediaPanel} when the view that contains our + * media is scrolled. + * + * @param dx the scrolled distance in the x direction (in pixels). + * @param dy the scrolled distance in the y direction (in pixels). + */ + public void viewLocationDidChange (int dx, int dy) + { + // let our media know + for (int ii = 0, ll = _media.size(); ii < ll; ii++) { + ((AbstractMedia)_media.get(ii)).viewLocationDidChange(dx, dy); + } + } + + /** + * Called by a {@link AbstractMedia} when its render order has changed. + */ + public void renderOrderDidChange (AbstractMedia media) + { + if (_tickStamp > 0) { + Log.warning("Egads! Render order changed during a tick."); + Thread.dumpStack(); + } + + _media.remove(media); + _media.insertSorted(media, RENDER_ORDER); + } + + /** + * Calls {@link AbstractMedia#tick} on all media to give them a chance + * to move about, change their look, generate dirty regions, and so + * forth. + */ + protected void tickAllMedia (long tickStamp) + { + // we use _tickpos so that it can be adjusted if media is added or + // removed during the tick dispatch + for (_tickpos = 0; _tickpos < _media.size(); _tickpos++) { + tickMedia((AbstractMedia) _media.get(_tickpos), tickStamp); + } + _tickpos = -1; + } + + /** + * Inserts the specified media into this manager, return true on + * success. + */ + protected boolean insertMedia (AbstractMedia media) + { + if (_media.contains(media)) { + Log.warning("Attempt to insert media more than once " + + "[media=" + media + "]."); + Thread.dumpStack(); + return false; + } + + media.init(this); + int ipos = _media.insertSorted(media, RENDER_ORDER); + + // if we've started our tick but have not yet painted our media, + // we need to take care that this newly added media will be ticked + // before our upcoming render + if (_tickStamp > 0L) { + if (_tickpos == -1) { + // if we're done with our own call to tick(), we + // definitely need to tick this new media + tickMedia(media, _tickStamp); + } else if (ipos <= _tickpos) { + // otherwise, we're in the middle of our call to tick() + // and we only need to tick this guy if he's being + // inserted before our current tick position (if he's + // inserted after our current position, we'll get to him + // as part of this tick iteration) + _tickpos++; + tickMedia(media, _tickStamp); + } + } + + return true; + } + + /** A helper function used to call {@link AbstractMedia#tick}. */ + protected final void tickMedia (AbstractMedia media, long tickStamp) + { + if (media._firstTick == 0L) { + media.willStart(tickStamp); + } + media.tick(tickStamp); + } + + /** + * Removes the specified media from this manager, return true on + * success. + */ + protected boolean removeMedia (AbstractMedia media) + { + int mpos = _media.indexOf(media); + if (mpos != -1) { + _media.remove(mpos); + media.invalidate(); + media.shutdown(); + // if we're in the middle of ticking, we need to adjust the + // _tickpos if necessary + if (mpos <= _tickpos) { + _tickpos--; + } + return true; + } + Log.warning("Attempt to remove media that wasn't inserted " + + "[media=" + media + "]."); + return false; + } + + /** + * Clears all media from the manager and calls {@link + * AbstractMedia#shutdown} on each. This does not invalidate the + * media's vacated bounds; it is assumed that it will be ok. + */ + protected void clearMedia () + { + if (_tickStamp > 0) { + Log.warning("Egads! Requested to clearMedia() during a tick."); + Thread.dumpStack(); + } + + for (int ii=_media.size() - 1; ii >= 0; ii--) { + AbstractMedia media = (AbstractMedia) _media.remove(ii); + media.shutdown(); + } + } + + /** + * Queues the notification for dispatching after we've ticked all the + * media. + */ + public void queueNotification (ObserverList observers, ObserverOp event) + { + _notify.add(new Tuple(observers, event)); + } + + /** + * Dispatches all queued media notifications. + */ + protected void dispatchNotifications () + { + for (int ii = 0, nn = _notify.size(); ii < nn; ii++) { + Tuple tuple = (Tuple)_notify.get(ii); + ((ObserverList)tuple.left).apply((ObserverOp)tuple.right); + } + _notify.clear(); + } + + /** The media panel we're working with. */ + protected MediaPanel _panel; + + /** The region manager. */ + protected RegionManager _remgr; + + /** List of observers to notify at the end of the tick. */ + protected ArrayList _notify = new ArrayList(); + + /** Our render-order sorted list of media. */ + protected SortableArrayList _media = new SortableArrayList(); + + /** The position in our media list that we're ticking in the middle of + * a call to {@link #tick} otherwise -1. */ + protected int _tickpos = -1; + + /** The tick stamp if the manager is in the midst of a call to {@link + * #tick}, else 0. */ + protected long _tickStamp; + + /** Used to sort media by render order. */ + protected static final Comparator RENDER_ORDER = new Comparator() { + public int compare (Object o1, Object o2) { + int result = (((AbstractMedia)o1)._renderOrder - + ((AbstractMedia)o2)._renderOrder); + return (result != 0) ? result : + // find some other way to keep them stable relative to + // each other + o1.hashCode() - o2.hashCode(); + } + }; +} diff --git a/src/java/com/threerings/media/ActiveRepaintManager.java b/src/java/com/threerings/media/ActiveRepaintManager.java new file mode 100644 index 00000000..fc812378 --- /dev/null +++ b/src/java/com/threerings/media/ActiveRepaintManager.java @@ -0,0 +1,502 @@ +// +// $Id: ActiveRepaintManager.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.applet.Applet; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Window; + +import javax.swing.CellRendererPane; +import javax.swing.JComponent; +import javax.swing.JEditorPane; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.RepaintManager; +import javax.swing.SwingUtilities; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import com.samskivert.util.ListUtil; +import com.samskivert.util.RunAnywhere; +import com.samskivert.util.StringUtil; + +/** + * Used to get Swing's repainting to jive with our active rendering + * strategy. + * + * @see FrameManager + */ +public class ActiveRepaintManager extends RepaintManager +{ + /** + * Components that are rooted in this component (which must be a {@link + * Window} or an {@link Applet}) will be rendered into the offscreen buffer + * managed by the frame manager. Other components will be rendered into + * separate offscreen buffers and repainted in the normal Swing manner. + */ + public ActiveRepaintManager (Component root) + { + _root = root; + } + + // documentation inherited + public synchronized void addInvalidComponent (JComponent comp) + { + Component vroot = null; + if (DEBUG) { + Log.info("Maybe invalidating " + toString(comp) + "."); + } + + // locate the validation root for this component + for (Component c = comp; c != null; c = c.getParent()) { + // if the component is not part of an active widget hierarcy, + // we can stop now; if the component is a cell render pane, + // we're apparently supposed to ignore it as wel + if (!c.isDisplayable() || c instanceof CellRendererPane) { + return; + } + + // skip non-Swing components + if (!(c instanceof JComponent)) { + continue; + } + + // if we find our validate root, we can stop looking; NOTE: + // JTextField incorrectly claims to be a validate root thereby + // fucking up the program something serious; we jovially + // ignore it's claims here and restore order to the universe; + // see bug #403550 for more fallout from Sun's fuckup + if (!(c instanceof JTextField) && + !(c instanceof JScrollPane) && + ((JComponent)c).isValidateRoot()) { + vroot = c; + break; + } + } + + // if we found no validation root we can abort as this component + // is not part of any valid widget hierarchy + if (vroot == null) { + if (DEBUG) { + Log.info("Skipping vrootless component: " + toString(comp)); + } + + return; + } + + // make sure that the component is actually in a window or applet + // that is showing + if (getRoot(vroot) == null) { + if (DEBUG) { + Log.info("Skipping rootless component " + + "[comp=" + toString(comp) + + ", vroot=" + toString(vroot) + "]."); + } + return; + } + + // add the invalid component to our list and we'll validate it on + // the next frame + if (!ListUtil.containsRef(_invalid, vroot)) { + if (DEBUG) { + Log.info("Invalidating " + toString(vroot) + "."); + } + _invalid = ListUtil.add(_invalid, vroot); + + // on the mac, components frequently do not repaint themselves + // after being invalidated so we have to force a repaint from + // the validation roon on down + if (RunAnywhere.isMacOS() && vroot instanceof JComponent) { + addDirtyRegion((JComponent)vroot, 0, 0, + vroot.getWidth(), vroot.getHeight()); + } + } + } + + // documentation inherited + public synchronized void addDirtyRegion ( + JComponent comp, int x, int y, int width, int height) + { + // ignore invalid requests + if ((width <= 0) || (height <= 0) || (comp == null) || + (comp.getWidth() <= 0) || (comp.getHeight() <= 0)) { +// Log.info("Skipping bogus region " + comp.getClass().getName() + +// ", x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "."); + return; + } + + // if this component is already dirty, simply expand their + // existing dirty rectangle + Rectangle drect = (Rectangle)_dirty.get(comp); + if (drect != null) { + drect.add(x, y); + drect.add(x+width, y+height); + return; + } + + // make sure this component has a valid root + if (getRoot(comp) == null) { +// Log.info("Skipping rootless repaint " + comp + "."); + return; + } + + if (DEBUG) { + Log.info("Dirtying component [comp=" + toString(comp) + + ", drect=" + StringUtil.toString( + new Rectangle(x, y, width, height)) + "]."); + } + + // if we made it this far, we can queue up a dirty region for this + // component to be repainted on the next tick + _dirty.put(comp, new Rectangle(x, y, width, height)); + } + + /** + * Returns the root component for the supplied component or null if it + * is not part of a rooted hierarchy or if any parent along the way is + * found to be hidden or without a peer. + */ + protected Component getRoot (Component comp) + { + for (Component c = comp; c != null; c = c.getParent()) { + boolean hidden = !c.isDisplayable(); + // on the mac, the JRootPane is invalidated before it is + // visible and is never again invalidated or repainted, so we + // punt and allow all invisible components to be invalidated + // and revalidated + if (!RunAnywhere.isMacOS()) { + hidden |= !c.isVisible(); + } + if (hidden) { + return null; + } + if (c instanceof Window || c instanceof Applet) { + return c; + } + } + return null; + } + + // documentation inherited + public synchronized Rectangle getDirtyRegion (JComponent comp) + { + Rectangle drect = (Rectangle)_dirty.get(comp); + // copy the rectangle if we found one, otherwise create an empty + // rectangle because we don't want them leaving empty handed + return (drect == null) ? + new Rectangle(0, 0, 0, 0) : new Rectangle(drect); + } + + // documentation inherited + public synchronized void markCompletelyClean (JComponent comp) + { + _dirty.remove(comp); + } + + /** + * Validates the invalid components that have been queued up since the + * last frame tick. + */ + public void validateComponents () + { + // swap out our invalid array + Object[] invalid = null; + synchronized (this) { + invalid = _invalid; + _invalid = null; + } + + // if there's nothing to validate, we're home free + if (invalid == null) { + return; + } + + // validate everything therein + int icount = invalid.length; + for (int ii = 0; ii < icount; ii++) { + if (invalid[ii] != null) { + if (DEBUG) { + Log.info("Validating " + invalid[ii]); + } + ((Component)invalid[ii]).validate(); + } + } + } + + /** + * Paints the components that have become dirty since the last tick. + * + * @return true if any components were painted. + */ + public boolean paintComponents (Graphics g, FrameManager fmgr) + { + synchronized (this) { + // exit now if there are no dirty rectangles to paint + if (_dirty.isEmpty()) { + return false; + } + + // otherwise, swap our hashmaps + HashMap tmap = _spare; + _spare = _dirty; + _dirty = tmap; + } + + // scan through the list, looking for components for whom a parent + // component is also dirty. in such a case, the dirty rectangle + // for the parent component is expanded to contain the dirty + // rectangle of the child and the child is removed from the + // repaint list (painting the parent will repaint the child) + Iterator iter = _spare.entrySet().iterator(); + PRUNE: + while (iter.hasNext()) { + Entry entry = (Entry)iter.next(); + JComponent comp = (JComponent)entry.getKey(); + Rectangle drect = (Rectangle)entry.getValue(); + int x = comp.getX() + drect.x, y = comp.getY() + drect.y; + + // climb up the parent hierarchy, looking for the first opaque + // parent as well as the root component + for (Component c = comp.getParent(); c != null; c = c.getParent()) { + // stop looking for combinable parents for non-visible or + // non-JComponents + if (!c.isVisible() || !c.isDisplayable() || + !(c instanceof JComponent)) { + break; + } + + // check to see if this parent is dirty + Rectangle prect = (Rectangle)_spare.get(c); + if (prect != null) { + // that we were going to merge it with its parent and + // blow it away + drect.x = x; + drect.y = y; + + if (DEBUG) { + Log.info("Found dirty parent " + + "[comp=" + toString(comp) + + ", drect=" + StringUtil.toString(drect) + + ", pcomp=" + toString(c) + + ", prect=" + StringUtil.toString(prect) + + "]."); + } + prect.add(drect); + + if (DEBUG) { + Log.info("New prect " + StringUtil.toString(prect)); + } + + // remove the child component and be on our way + iter.remove(); + continue PRUNE; + } + + // translate the coordinates into this component's + // coordinate system + x += c.getX(); + y += c.getY(); + } + } + + // now paint each of the dirty components, by setting the clipping + // rectangle appropriately and calling paint() on the associated + // root component + iter = _spare.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = (Entry)iter.next(); + JComponent comp = (JComponent)entry.getKey(); + Rectangle drect = (Rectangle)entry.getValue(); + + // get the root component, adjust the clipping (dirty) + // rectangle and obtain the bounds of the client in absolute + // coordinates + Component root = null, ocomp = null; + + // start with the components bounds which we'll switch to the + // opaque parent component's bounds if and when we find one + _cbounds.setBounds(0, 0, comp.getWidth(), comp.getHeight()); + + // climb up the parent hierarchy, looking for the first opaque + // parent as well as the root component + for (Component c = comp; c != null; c = c.getParent()) { + if (!c.isVisible() || !c.isDisplayable()) { + break; + } + + if (c instanceof JComponent) { + // make a note of the first opaque parent we find + if (ocomp == null && ((JComponent)c).isOpaque()) { + ocomp = c; + // we need to obtain the opaque parent's coordinates + // in the root coordinate system for when we repaint + _cbounds.setBounds( + 0, 0, ocomp.getWidth(), ocomp.getHeight()); + } + + } else { + // oh god the hackery. apparently the fscking + // JEditorPane wraps a heavy weight component around + // every swing component it uses when doing forms + Component tp = c.getParent(); + if (!(tp instanceof JEditorPane)) { + root = c; + break; + } + } + + // translate the coordinates into this component's + // coordinate system + drect.x += c.getX(); + drect.y += c.getY(); + _cbounds.x += c.getX(); + _cbounds.y += c.getY(); + + // clip the dirty region to the bounds of this component + SwingUtilities.computeIntersection( + c.getX(), c.getY(), c.getWidth(), c.getHeight(), drect); + } + + // if we found no opaque parent, just paint the component + // itself (this seems to happen with the top-level layered + // pane) + if (ocomp == null) { + ocomp = comp; + } + + // if this component is rooted in our frame, repaint it into + // the supplied graphics instance + if (root == _root) { + if (DEBUG) { + Log.info("Repainting [comp=" + toString(comp) + + StringUtil.toString(_cbounds) + + ", ocomp=" + toString(ocomp) + + ", drect=" + StringUtil.toString(drect) + "]."); + } + + g.setClip(drect); + g.translate(_cbounds.x, _cbounds.y); + try { + // some components are ill-behaved and may throw an + // exception while painting themselves, and so we + // needs must deal with these fellows gracefully + ocomp.paint(g); + + } catch (Exception e) { + Log.warning("Exception while painting component " + + "[comp=" + ocomp + ", e=" + e + "]."); + Log.logStackTrace(e); + } + g.translate(-_cbounds.x, -_cbounds.y); + + // we also need to repaint any components in this layer + // that are above our freshly repainted component + fmgr.renderLayers((Graphics2D)g, ocomp, _cbounds, _clipped); + + } else if (root != null) { + if (DEBUG) { + Log.info("Repainting old-school " + + "[comp=" + toString(comp) + + ", ocomp=" + toString(ocomp) + + ", root=" + toString(root) + + ", bounds=" + StringUtil.toString(_cbounds) + + "]."); + dumpHierarchy(comp); + } + + // otherwise, repaint with standard swing double buffers + Image obuf = getOffscreenBuffer( + ocomp, _cbounds.width, _cbounds.height); + Graphics og = null, cg = null; + try { + og = obuf.getGraphics(); + ocomp.paint(og); + cg = ocomp.getGraphics(); + cg.drawImage(obuf, 0, 0, null); + + } finally { + if (og != null) { + og.dispose(); + } + if (cg != null) { + cg.dispose(); + } + } + } + } + + // clear out the mapping of dirty components + _spare.clear(); + + return true; + } + + /** + * Used to dump a component when debugging. + */ + protected static String toString (Component comp) + { + return comp.getClass().getName() + + StringUtil.toString(comp.getBounds()); + } + + /** + * Dumps the containment hierarchy for the supplied component. + */ + protected static void dumpHierarchy (Component comp) + { + for (String indent = ""; comp != null; indent += " ") { + Log.info(indent + toString(comp)); + comp = comp.getParent(); + } + } + + /** The root of our interface. */ + protected Component _root; + + /** A list of invalid components. */ + protected Object[] _invalid; + + /** A mapping of invalid rectangles for each widget that is dirty. */ + protected HashMap _dirty = new HashMap(); + + /** A spare hashmap that we swap in while repainting dirty components + * in the old hashmap. */ + protected HashMap _spare = new HashMap(); + + /** Used to compute dirty components' bounds. */ + protected Rectangle _cbounds = new Rectangle(); + + /** Used when rendering "layered" components. */ + protected boolean[] _clipped = new boolean[] { true }; + + /** We debug so much that we have to make it easy to enable and + * disable debug logging. Yay! */ + protected static final boolean DEBUG = false; +} diff --git a/src/java/com/threerings/media/BackFrameManager.java b/src/java/com/threerings/media/BackFrameManager.java new file mode 100644 index 00000000..f8488ac2 --- /dev/null +++ b/src/java/com/threerings/media/BackFrameManager.java @@ -0,0 +1,148 @@ +// +// $Id: BackFrameManager.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; +import java.awt.image.VolatileImage; + +/** + * A {@link FrameManager} extension that uses a volatile off-screen image + * to do its rendering. + */ +public class BackFrameManager extends FrameManager +{ + // documentation inherited + protected void paint (long tickStamp) + { + // start out assuming we can do an incremental render + boolean incremental = true; + + do { + GraphicsConfiguration gc = _window.getGraphicsConfiguration(); + + // create our off-screen buffer if necessary + if (_backimg == null || _backimg.getWidth() != _window.getWidth() || + _backimg.getHeight() != _window.getHeight()) { + createBackBuffer(gc); + } + + // make sure our back buffer hasn't disappeared + int valres = _backimg.validate(gc); + + // if we've changed resolutions, recreate the buffer + if (valres == VolatileImage.IMAGE_INCOMPATIBLE) { + Log.info("Back buffer incompatible, recreating."); + createBackBuffer(gc); + } + + // if the image wasn't A-OK, we need to rerender the whole + // business rather than just the dirty parts + if (valres != VolatileImage.IMAGE_OK) { + // Log.info("Lost back buffer, redrawing " + valres); + if (_bgfx != null) { + _bgfx.dispose(); + } + _bgfx = (Graphics2D)_backimg.getGraphics(); + if (_fgfx != null) { + _fgfx.dispose(); + _fgfx = null; + } + incremental = false; + } + + // dirty everything if we're not incrementally rendering + if (!incremental) { + _root.getRootPane().revalidate(); + _root.getRootPane().repaint(); + } + + if (!paint(_bgfx)) { + return; + } + + // we cache our frame's graphics object so that we can avoid + // instantiating a new one on every tick + if (_fgfx == null) { + _fgfx = (Graphics2D)_window.getGraphics(); + } + _fgfx.drawImage(_backimg, 0, 0, null); + + // if we loop through a second time, we'll need to rerender + // everything + incremental = false; + + } while (_backimg.contentsLost()); + } + + // documentation inherited + protected void restoreFromBack (Rectangle dirty) + { + if (_fgfx == null || _backimg == null) { + return; + } +// Log.info("Restoring from back " + StringUtil.toString(dirty) + "."); + _fgfx.setClip(dirty); + _fgfx.drawImage(_backimg, 0, 0, null); + _fgfx.setClip(null); + } + + /** + * Creates the off-screen buffer used to perform double buffered + * rendering of the animated panel. + */ + protected void createBackBuffer (GraphicsConfiguration gc) + { + // if we have an old image, clear it out + if (_backimg != null) { + _backimg.flush(); + _bgfx.dispose(); + } + + // create the offscreen buffer + int width = _window.getWidth(), height = _window.getHeight(); + _backimg = gc.createCompatibleVolatileImage(width, height); + + // fill the back buffer with white + _bgfx = (Graphics2D)_backimg.getGraphics(); + _bgfx.fillRect(0, 0, width, height); + + // clear out our frame graphics in case that became invalid for + // the same reasons our back buffer became invalid + if (_fgfx != null) { + _fgfx.dispose(); + _fgfx = null; + } + +// Log.info("Created back buffer [" + width + "x" + height + "]."); + } + + /** The image used to render off-screen. */ + protected VolatileImage _backimg; + + /** The graphics object from our back buffer. */ + protected Graphics2D _bgfx; + + /** The graphics object from our frame. */ + protected Graphics2D _fgfx; +} diff --git a/src/java/com/threerings/media/FlipFrameManager.java b/src/java/com/threerings/media/FlipFrameManager.java new file mode 100644 index 00000000..0e309b55 --- /dev/null +++ b/src/java/com/threerings/media/FlipFrameManager.java @@ -0,0 +1,101 @@ +// +// $Id: FlipFrameManager.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.Graphics2D; +import java.awt.ImageCapabilities; +import java.awt.Rectangle; +import java.awt.image.BufferStrategy; + +/** + * A {@link FrameManager} extension that uses a flip-buffer (via {@link + * BufferStrategy} to do its rendering. + */ +public class FlipFrameManager extends FrameManager +{ + // documentation inherited + protected void paint (long tickStamp) + { + // create our buffer strategy if we don't already have one + if (_bufstrat == null) { + BufferCapabilities cap = new BufferCapabilities( + new ImageCapabilities(true), new ImageCapabilities(true), + BufferCapabilities.FlipContents.COPIED); + try { + _window.createBufferStrategy(2, cap); + } catch (AWTException ae) { + Log.warning("Failed creating flip bufstrat: " + ae + "."); + // fall back to one without custom capabilities + _window.createBufferStrategy(2); + } + _bufstrat = _window.getBufferStrategy(); + } + + // start out assuming we can do an incremental render + boolean incremental = true; + + do { + Graphics2D gfx = null; + try { + gfx = (Graphics2D)_bufstrat.getDrawGraphics(); + + // dirty everything if we're not incrementally rendering + if (!incremental) { + Log.info("Doing non-incremental render; contents lost " + + "[lost=" + _bufstrat.contentsLost() + + ", rest=" + _bufstrat.contentsRestored() + "]."); + _root.getRootPane().revalidate(); + _root.getRootPane().repaint(); + } + + // request to paint our participants and components and bail + // if they paint nothing + if (!paint(gfx)) { + return; + } + + // flip our buffer to visible + _bufstrat.show(); + + // if we loop through a second time, we'll need to rerender + // everything + incremental = false; + + } finally { + if (gfx != null) { + gfx.dispose(); + } + } + } while (_bufstrat.contentsLost()); + } + + // documentation inherited + protected void restoreFromBack (Rectangle dirty) + { + // nothing doing + } + + /** The buffer strategy used to do our rendering. */ + protected BufferStrategy _bufstrat; +} diff --git a/src/java/com/threerings/media/FrameInterval.java b/src/java/com/threerings/media/FrameInterval.java new file mode 100644 index 00000000..f168c396 --- /dev/null +++ b/src/java/com/threerings/media/FrameInterval.java @@ -0,0 +1,111 @@ +package com.threerings.media; + +import java.awt.Component; + +import com.threerings.media.FrameManager; +import com.threerings.media.FrameParticipant; + +public abstract class FrameInterval + implements FrameParticipant +{ + /** + * Constructor - registers the interval as a frame participant + */ + public FrameInterval (FrameManager mgr) + { + _mgr = mgr; + } + + // documentation inhertied from FrameParticipant + public Component getComponent () + { + return null; + } + + // documentation inherited from FrameParticipant + public boolean needsPaint () + { + return false; + } + + // documentation inherited from FrameParticipant + public void tick (long tickStamp) + { + if (_nextTime == -1) { + // First time through + _nextTime = tickStamp + _initDelay; + } else if (tickStamp >= _nextTime) { + + // If we're repeating, set the next time to run, otherwise, reset + if (_repeatDelay != 0L) { + _nextTime += _repeatDelay; + } else { + _nextTime = -1; + cancel(); + } + expired(); + } + } + + /** + * + * The main method where your interval should do its work. + * + */ + public abstract void expired (); + + /** + * Schedule the interval to execute once, after the specified delay. + * Supersedes any previous schedule that this Interval may have had. + */ + public final void schedule (long delay) + { + schedule(delay, 0L); + } + + /** + * Schedule the interval to execute repeatedly, with the same delay. + * Supersedes any previous schedule that this Interval may have had. + */ + public final void schedule (long delay, boolean repeat) + { + schedule(delay, repeat ? delay : 0L); + } + + /** + * Schedule the interval to execute repeatedly with the specified + * initial delay and repeat delay. + * Supersedes any previous schedule that this Interval may have had. + */ + public final void schedule (long initialDelay, long repeatDelay) + { + if (!_mgr.isRegisteredFrameParticipant(this)) { + _mgr.registerFrameParticipant(this); + } + + _repeatDelay = repeatDelay; + _initDelay = initialDelay; + _nextTime = -1; + } + + /** + * Cancel the current schedule, and ensure that any expirations that + * are queued up but have not yet run do not run. + */ + public final void cancel () + { + _mgr.removeFrameParticipant(this); + } + + /** Time of the next expiration. */ + protected long _nextTime; + + /** Time between expirations. */ + protected long _repeatDelay; + + /** Time between expirations. */ + protected long _initDelay; + + /** The context whose FrameManager we are using. */ + protected FrameManager _mgr; +} diff --git a/src/java/com/threerings/media/FrameManager.java b/src/java/com/threerings/media/FrameManager.java new file mode 100644 index 00000000..ef73e9e2 --- /dev/null +++ b/src/java/com/threerings/media/FrameManager.java @@ -0,0 +1,846 @@ +// +// $Id: FrameManager.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.applet.Applet; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; +import java.awt.Rectangle; +import java.awt.Window; + +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +import java.awt.EventQueue; + +import javax.swing.JLayeredPane; +import javax.swing.RepaintManager; +import javax.swing.JRootPane; +import javax.swing.RootPaneContainer; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; + +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.util.ListUtil; +import com.samskivert.util.RunAnywhere; +import com.samskivert.util.StringUtil; + +import com.threerings.media.timer.MediaTimer; +import com.threerings.media.timer.SystemMediaTimer; +import com.threerings.media.util.TrailingAverage; +import com.threerings.util.unsafe.Unsafe; + +/** + * Provides a central point from which the computation for each "frame" or tick + * can be dispatched. This assumed that the application structures its activity + * around the rendering of each frame, which is a common architecture for + * games. The animation and sprite support provided by other classes in this + * package are structured for use in an application that uses a frame manager + * to tick everything once per frame. + * + *

The frame manager goes through a simple two part procedure every frame: + * + *

    + *
  • Ticking all of the frame participants: in {@link + * FrameParticipant#tick}, any processing that need be performed during this + * frame should be performed. Care should be taken not to execute code that + * will take unduly long, instead such processing should be broken up so that + * it can be performed in small pieces every frame (or performed on a separate + * thread with the results safely communicated back to the frame participants + * for incorporation into the rendering loop). + * + *
  • Painting the user interface hierarchy: the top-level component (the + * frame) is painted (via a call to {@link JRootPane#paint}) into a flip buffer + * (if supported, an off-screen buffer if not). Updates that were computed + * during the tick should be rendered in this call to paint. The paint call + * will propagate down to all components in the UI hierarchy, some of which may + * be {@link FrameParticipant}s and will have prepared themselves for their + * upcoming painting in the previous call to {@link + * FrameParticipant#tick}. When the call to paint completes, the flip buffer is + * flipped and the process starts all over again.
+ * + *

The ticking and rendering takes place on the AWT thread so as to + * avoid the need for complicated coordination between AWT event handler + * code and frame code. However, this means that all AWT (and Swing) event + * handlers must not perform any complicated processing. After + * each frame, control of the AWT thread is given back to the AWT which + * processes all pending AWT events before giving the frame manager an + * opportunity to process the next frame. Thus the convenience of + * everything running on the AWT thread comes with the price of requiring + * that AWT event handlers not block or perform any intensive processing. + * In general, this is a sensible structure for an application anyhow, so + * this organization tends to be preferable to an organization where the + * AWT and frame threads are separate and must tread lightly so as not to + * collide. + * + *

Note: the way that JScrollPane goes about improving + * performance when scrolling complicated contents cannot work with active + * rendering. If you use a JScrollPane in an application that + * uses the frame manager, you should either use the provided {@link + * SafeScrollPane} or set your scroll panes' viewports to + * SIMPLE_SCROLL_MODE. + */ +public abstract class FrameManager +{ + /** + * Normally, the frame manager will repaint any component in a {@link + * JLayeredPane} layer (popups, overlays, etc.) that overlaps a frame + * participant on every tick because the frame participant could + * have changed underneath the overlay which would require that the overlay + * be repainted. If the application knows that the frame participant + * beneath the overlay will never change, it can have its overlay implement + * this interface and avoid the expense of forcibly fully repainting the + * overlay on every frame. + */ + public static interface SafeLayerComponent + { + } + + /** + * Creates a frame manager that will use a {@link SystemMediaTimer} to + * obtain timing information, which is available on every platform, but + * returns inaccurate time stamps on many platforms. + * + * @see #newInstance(Window, RootPaneContainer, MediaTimer) + */ + public static FrameManager newInstance ( + Window window, RootPaneContainer root) + { + // first try creating a PerfTimer which is the best if we're using + // JDK1.4.2 + MediaTimer timer = null; + try { + timer = (MediaTimer)Class.forName(PERF_TIMER).newInstance(); + } catch (Throwable t) { + Log.info("Can't use PerfTimer (" + t + ") reverting to " + + "System.currentTimeMillis() based timer."); + timer = new SystemMediaTimer(); + } + return newInstance(window, root, timer); + } + + /** + * Constructs a frame manager that will do its rendering to the + * supplied frame. It is likely that the caller will want to have put + * the frame into full-screen exclusive mode prior to providing it to + * the frame manager so that the frame manager can take advantage of + * optimizations available in that mode. + * + * @see GraphicsDevice#setFullScreenWindow + */ + public static FrameManager newInstance ( + Window window, RootPaneContainer root, MediaTimer timer) + { + FrameManager fmgr; + if (_useFlip.getValue()) { + Log.info("Creating flip frame manager."); + fmgr = new FlipFrameManager(); + } else { + Log.info("Creating back frame manager."); + fmgr = new BackFrameManager(); + } + fmgr.init(window, root, timer); + return fmgr; + } + + /** + * Initializes this frame manager and prepares it for operation. + */ + protected void init ( + Window window, RootPaneContainer root, MediaTimer timer) + { + _window = window; + _root = root; + if (window instanceof ManagedJFrame) { + ((ManagedJFrame)window).init(this); + } + _timer = timer; + + // set up our custom repaint manager + _remgr = new ActiveRepaintManager(_window); + RepaintManager.setCurrentManager(_remgr); + + // turn off double buffering for the whole business because we + // handle repaints + _remgr.setDoubleBufferingEnabled(false); + + if (DEBUG_EVENTS) { + addTestListeners(); + } + } + + /** + * Adds a variety of listeners to the frame in order to provide + * visibility into the various events received by the frame. + */ + protected void addTestListeners () + { + // add a test window listener + _window.addWindowListener(new WindowListener() { + public void windowActivated (WindowEvent e) { + Log.info("Window activated [evt=" + e + "]."); + } + + public void windowClosed (WindowEvent e) { + Log.info("Window closed [evt=" + e + "]."); + } + + public void windowClosing (WindowEvent e) { + Log.info("Window closing [evt=" + e + "]."); + } + + public void windowDeactivated (WindowEvent e) { + Log.info("Window deactivated [evt=" + e + "]."); + } + + public void windowDeiconified (WindowEvent e) { + Log.info("Window deiconified [evt=" + e + "]."); + } + + public void windowIconified (WindowEvent e) { + Log.info("Window iconified [evt=" + e + "]."); + } + + public void windowOpened (WindowEvent e) { + Log.info("Window opened [evt=" + e + "]."); + } + }); + + // add a component listener + _window.addComponentListener(new ComponentListener() { + public void componentHidden (ComponentEvent e) { + Log.info("Window component hidden [evt=" + e + "]."); + } + + public void componentShown (ComponentEvent e) { + Log.info("Window component shown [evt=" + e + "]."); + } + + public void componentMoved (ComponentEvent e) { + Log.info("Window component moved [evt=" + e + "]."); + } + + public void componentResized (ComponentEvent e) { + Log.info("Window component resized [evt=" + e + "]."); + } + }); + + // add test ancestor focus listener + _root.getRootPane().addAncestorListener( + new AncestorListener() { + public void ancestorAdded (AncestorEvent e) { + Log.info("Root pane ancestor added [e=" + e + "]."); + } + + public void ancestorRemoved (AncestorEvent e) { + Log.info("Root pane ancestor removed [e=" + e + "]."); + } + + public void ancestorMoved (AncestorEvent e) { + Log.info("Root pane ancestor moved [e=" + e + "]."); + } + }); + + // add test key event dispatcher + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addKeyEventDispatcher(new KeyEventDispatcher() { + public boolean dispatchKeyEvent (KeyEvent e) { +// if ((e.getModifiersEx() & KeyEvent.ALT_DOWN_MASK) != 0 && +// e.getKeyCode() == KeyEvent.VK_TAB) { +// Log.info("Detected alt-tab key event " + +// "[e=" + e + "]."); +// // attempt to eat the event so that windows +// // doesn't alt-tab into unhappy land +// e.consume(); +// return true; +// } + + return false; + } + }); + } + + /** + * Instructs the frame manager to target the specified number of + * frames per second. If the computation and rendering for a frame are + * completed with time to spare, the frame manager will wait until the + * proper time to begin processing for the next frame. If a frame + * takes longer than its alotted time, the frame manager will + * immediately begin processing on the next frame. + */ + public void setTargetFrameRate (int fps) + { + // compute the number of milliseconds per frame + _millisPerFrame = 1000/fps; + } + + /** + * Registers a frame participant. The participant will be given the + * opportunity to do processing and rendering on each frame. + */ + public void registerFrameParticipant (FrameParticipant participant) + { + Object[] nparts = ListUtil.testAndAddRef(_participants, participant); + if (nparts == null) { + Log.warning("Refusing to add duplicate frame participant! " + + participant); + } else { + _participants = nparts; + } + } + + /** + * Returns true if the specified participant is registered. + */ + public boolean isRegisteredFrameParticipant (FrameParticipant participant) + { + return ListUtil.containsRef(_participants, participant); + } + + /** + * Removes a frame participant. + */ + public void removeFrameParticipant (FrameParticipant participant) + { + ListUtil.clearRef(_participants, participant); + } + + /** + * Returns a millisecond granularity time stamp using the {@link + * MediaTimer} with which this frame manager was configured. + * Note: this should only be called from the AWT thread. + */ + public long getTimeStamp () + { + return _timer.getElapsedMillis(); + } + + /** + * Starts up the per-frame tick + */ + public void start () + { + if (_ticker == null) { + _ticker = new Ticker(); + _ticker.start(); + _lastTickStamp = 0; + } + } + + /** + * Stops the per-frame tick. + */ + public synchronized void stop () + { + if (_ticker != null) { + _ticker.cancel(); + _ticker = null; + } + } + + /** + * Returns true if the tick interval is be running (not necessarily at + * that instant, but in general). + */ + public synchronized boolean isRunning () + { + return (_ticker != null); + } + + /** + * Returns the number of ticks executed in the last second. + */ + public int getPerfTicks () + { + return Math.round(_fps[1]); + } + + /** + * Returns the number of ticks requested in the last second. + */ + public int getPerfTries () + { + return Math.round(_fps[0]); + } + + /** + * Returns debug performance metrics. + */ + public TrailingAverage[] getPerfMetrics () + { + if (_metrics == null) { + _metrics = new TrailingAverage[] { + new TrailingAverage(150), + new TrailingAverage(150), + new TrailingAverage(150) }; + } + return _metrics; + } + + /** + * Called to perform the frame processing and rendering. + */ + protected void tick (long tickStamp) + { + long start = 0L, paint = 0L; + if (MediaPanel._perfDebug.getValue()) { + start = paint = _timer.getElapsedMicros(); + } + // if our frame is not showing (or is impossibly sized), don't try + // rendering anything + if (_window.isShowing() && + _window.getWidth() > 0 && _window.getHeight() > 0) { + // tick our participants + tickParticipants(tickStamp); + paint = _timer.getElapsedMicros(); + // repaint our participants and components + paint(tickStamp); + } + if (MediaPanel._perfDebug.getValue()) { + long end = _timer.getElapsedMicros(); + getPerfMetrics()[1].record((int)(paint-start)/100); + getPerfMetrics()[2].record((int)(end-paint)/100); + } + } + + /** + * Called once per frame to invoke {@link FrameParticipant#tick} on + * all of our frame participants. + */ + protected void tickParticipants (long tickStamp) + { + long gap = tickStamp - _lastTickStamp; + if (_lastTickStamp != 0 && gap > (HANG_DEBUG ? HANG_GAP : BIG_GAP)) { + Log.debug("Long tick delay [delay=" + gap + "ms]."); + } + _lastTickStamp = tickStamp; + + // validate any invalid components + try { + _remgr.validateComponents(); + } catch (Throwable t) { + Log.warning("Failure validating components."); + Log.logStackTrace(t); + } + + // tick all of our frame participants + for (int ii = 0; ii < _participants.length; ii++) { + FrameParticipant part = (FrameParticipant)_participants[ii]; + if (part == null) { + continue; + } + + try { + long start = 0L; + if (HANG_DEBUG) { + start = System.currentTimeMillis(); + } + + part.tick(tickStamp); + + if (HANG_DEBUG) { + long delay = (System.currentTimeMillis() - start); + if (delay > HANG_GAP) { + Log.info("Whoa nelly! Ticker took a long time " + + "[part=" + part + ", time=" + delay + "ms]."); + } + } + + } catch (Throwable t) { + Log.warning("Frame participant choked during tick " + + "[part=" + StringUtil.safeToString(part) + "]."); + Log.logStackTrace(t); + } + } + } + + /** + * Called once per frame to invoke {@link Component#paint} on all of + * our frame participants' components and all dirty components managed + * by our {@link ActiveRepaintManager}. + */ + protected abstract void paint (long tickStamp); + + /** + * Paints our frame participants and any dirty components via the + * repaint manager. + * + * @return true if anything was painted, false if not. + */ + protected boolean paint (Graphics2D gfx) + { + // paint our frame participants (which want to be handled + // specially) + int painted = 0; + for (int ii = 0; ii < _participants.length; ii++) { + FrameParticipant part = (FrameParticipant)_participants[ii]; + if (part == null) { + continue; + } + + Component pcomp = part.getComponent(); + if (pcomp == null || !part.needsPaint()) { + continue; + } + + long start = 0L; + if (HANG_DEBUG) { + start = System.currentTimeMillis(); + } + + // get the bounds of this component + pcomp.getBounds(_tbounds); + + // the bounds adjustment we're about to call will add in the + // components initial bounds offsets, so we remove them here + _tbounds.setLocation(0, 0); + + // convert them into top-level coordinates; also note that if + // this component does not have a valid or visible root, we + // don't want to paint it either + if (getRoot(pcomp, _tbounds) == null) { + continue; + } + + try { + // render this participant; we don't set the clip because + // frame participants are expected to handle clipping + // themselves; otherwise we might pointlessly set the clip + // here, creating a few Rectangle objects in the process, + // only to have the frame participant immediately set the + // clip to something more sensible + gfx.translate(_tbounds.x, _tbounds.y); + pcomp.paint(gfx); + gfx.translate(-_tbounds.x, -_tbounds.y); + painted++; + + } catch (Throwable t) { + String ptos = StringUtil.safeToString(part); + Log.warning("Frame participant choked during paint " + + "[part=" + ptos + "]."); + Log.logStackTrace(t); + } + + // render any components in our layered pane that are not in + // the default layer + _clipped[0] = false; + renderLayers(gfx, pcomp, _tbounds, _clipped); + + if (HANG_DEBUG) { + long delay = (System.currentTimeMillis() - start); + if (delay > HANG_GAP) { + Log.warning("Whoa nelly! Painter took a long time " + + "[part=" + part + ", time=" + delay + "ms]."); + } + } + } + + // repaint any widgets that have declared they need to be + // repainted since the last tick + boolean pcomp = _remgr.paintComponents(gfx, this); + + // let the caller know if anybody painted anything + return ((painted > 0) || pcomp); + } + + /** + * Called by the {@link ManagedJFrame} when our window was hidden and + * reexposed. + */ + protected abstract void restoreFromBack (Rectangle dirty); + + /** + * Renders all components in all {@link JLayeredPane} layers that + * intersect the supplied bounds. + */ + protected void renderLayers (Graphics2D g, Component pcomp, + Rectangle bounds, boolean[] clipped) + { + JLayeredPane lpane = + JLayeredPane.getLayeredPaneAbove(pcomp); + if (lpane != null) { + renderLayer(g, bounds, lpane, clipped, JLayeredPane.PALETTE_LAYER); + renderLayer(g, bounds, lpane, clipped, JLayeredPane.MODAL_LAYER); + renderLayer(g, bounds, lpane, clipped, JLayeredPane.POPUP_LAYER); + renderLayer(g, bounds, lpane, clipped, JLayeredPane.DRAG_LAYER); + } + } + + /** + * Renders all components in the specified layer of the supplied + * layered pane that intersect the supplied bounds. + */ + protected void renderLayer (Graphics2D g, Rectangle bounds, + JLayeredPane pane, boolean[] clipped, + Integer layer) + { + // stop now if there are no components in that layer + int ccount = pane.getComponentCountInLayer(layer.intValue()); + if (ccount == 0) { + return; + } + + // render them up + Component[] comps = pane.getComponentsInLayer(layer.intValue()); + for (int ii = 0; ii < ccount; ii++) { + Component comp = comps[ii]; + if (!comp.isVisible() || comp instanceof SafeLayerComponent) { + continue; + } + + // if this overlay does not intersect the component we just + // rendered, we don't need to repaint it + _tbounds.setBounds(0, 0, comp.getWidth(), comp.getHeight()); + getRoot(comp, _tbounds); + if (!_tbounds.intersects(bounds)) { + continue; + } + + // if the clipping region has not yet been set during this + // render pass, the time has come to do so + if (!clipped[0]) { + g.setClip(bounds); + clipped[0] = true; + } + + // translate into the components coordinate system and render + g.translate(_tbounds.x, _tbounds.y); + try { + comp.paint(g); + } catch (Exception e) { + Log.warning("Component choked while rendering."); + Log.logStackTrace(e); + } + g.translate(-_tbounds.x, -_tbounds.y); + } + } + + // documentation inherited + public void checkpoint (String name, int ticks) + { + Log.info("Frames in last second: " + ticks); + } + + /** + * Returns the root component for the supplied component or null if it + * is not part of a rooted hierarchy or if any parent along the way is + * found to be hidden or without a peer. Along the way, it adjusts the + * supplied component-relative rectangle to be relative to the + * returned root component. + */ + public static Component getRoot (Component comp, Rectangle rect) + { + for (Component c = comp; c != null; c = c.getParent()) { + if (!c.isVisible() || !c.isDisplayable()) { + return null; + } + if (c instanceof Window || c instanceof Applet) { + return c; + } + rect.x += c.getX(); + rect.y += c.getY(); + } + return null; + } + + /** Used to effect periodic calls to {@link #tick}. */ + protected class Ticker extends Thread + { + public void run () + { + Log.info("Frame manager ticker running " + + "[sleepGran=" + _sleepGranularity.getValue() + "]."); + while (_running) { + long start = 0L; + if (MediaPanel._perfDebug.getValue()) { + start = _timer.getElapsedMicros(); + } + Unsafe.sleep(_sleepGranularity.getValue()); + + long woke = _timer.getElapsedMicros(); + if (start > 0L) { + getPerfMetrics()[0].record((int)(woke-start)/100); + int elapsed = (int)(woke-start); + if (elapsed > _sleepGranularity.getValue()*1500) { + Log.warning("Long tick [elapsed=" + elapsed + "us]."); + } + } + + // work around sketchy bug on WinXP that causes the clock + // to leap into the past from time to time + if (woke < _lastAttempt) { + Log.warning("Zoiks! We've leapt into the past, coping " + + "as best we can [dt=" + + (woke - _lastAttempt) + "]."); + _lastAttempt = woke; + } + + if (woke - _lastAttempt >= _millisPerFrame * 1000) { + _lastAttempt = woke; + if (testAndSet()) { + EventQueue.invokeLater(_awtTicker); + } + // else: drop the frame + } + } + } + + public void cancel () + { + _running = false; + } + + protected final synchronized boolean testAndSet () + { + _tries++; + if (!_ticking) { + _ticking = true; + return true; + } + return false; + } + + protected final synchronized void clearTicking (long elapsed) + { + if (++_ticks == 100) { + long time = (elapsed - _lastTick); + _fps[0] = _tries * 1000f / time; + _fps[1] = _ticks * 1000f / time; + _lastTick = elapsed; + _ticks = _tries = 0; + } + _ticking = false; + } + + /** Used to invoke the call to {@link #tick} on the AWT event + * queue thread. */ + protected Runnable _awtTicker = new Runnable () + { + public void run () + { + long elapsed = _timer.getElapsedMillis(); + try { + tick(elapsed); + } finally { + clearTicking(elapsed); + } + } + }; + + /** Used to stick a fork in our ticker when desired. */ + protected transient boolean _running = true; + + /** Used to detect when we need to drop frames. */ + protected boolean _ticking; + + /** The time at which we last attempted to tick. */ + protected long _lastAttempt; + + /** Used to compute metrics. */ + protected int _tries, _ticks, _time; + + /** Used to compute metrics. */ + protected long _lastTick; + }; + + /** The window into which we do our rendering. */ + protected Window _window; + + /** Provides access to our Swing bits. */ + protected RootPaneContainer _root; + + /** Used to obtain timing measurements. */ + protected MediaTimer _timer; + + /** Our custom repaint manager. */ + protected ActiveRepaintManager _remgr; + + /** The number of milliseconds per frame (14 by default, which gives + * an fps of ~71). */ + protected long _millisPerFrame = 14; + + /** Used to track big delays in calls to our tick method. */ + protected long _lastTickStamp; + + /** The thread that dispatches our frame ticks. */ + protected Ticker _ticker; + + /** Used to track and report frames per second. */ + protected float[] _fps = new float[2]; + + /** Used to track performance metrics. */ + protected TrailingAverage[] _metrics; + + /** A temporary bounds rectangle used to avoid lots of object creation. */ + protected Rectangle _tbounds = new Rectangle(); + + /** Used to lazily set the clip when painting popups and other + * "layered" components. */ + protected boolean[] _clipped = new boolean[1]; + + /** The entites that are ticked each frame. */ + protected Object[] _participants = new Object[4]; + + /** If we don't get ticked for 500ms, that's worth complaining about. */ + protected static final long BIG_GAP = 500L; + + /** If we don't get ticked for 100ms and we're hang debugging, + * complain. */ + protected static final long HANG_GAP = 100L; + + /** Enable this to log warnings when ticking or painting takes too + * long. */ + protected static final boolean HANG_DEBUG = false; + + /** A debug hook that toggles debug rendering of sprite paths. */ + protected static RuntimeAdjust.BooleanAdjust _useFlip = + new RuntimeAdjust.BooleanAdjust( + "When active a flip-buffer will be used to manage our " + + "rendering, otherwise a volatile back buffer is used " + + "[requires restart]", "narya.media.frame", + // back buffer rendering doesn't work on the Mac, so we + // default to flip buffer on that platform; we still allow it + // to be toggled so that we can easily test things when they + // release new JVMs + MediaPrefs.config, RunAnywhere.isMacOS()); + + /** Allows us to tweak the sleep granularity. */ + protected static RuntimeAdjust.IntAdjust _sleepGranularity = + new RuntimeAdjust.IntAdjust( + "The number of milliseconds slept before checking to see if " + + "it's time to queue up a new frame tick.", "narya.media.sleep_gran", + MediaPrefs.config, RunAnywhere.isWindows() ? 10 : 7); + + /** Whether to enable AWT event debugging for the frame. */ + protected static final boolean DEBUG_EVENTS = false; + + /** The name of the high-performance timer class we attempt to load. */ + protected static final String PERF_TIMER = + "com.threerings.media.timer.PerfTimer"; +} diff --git a/src/java/com/threerings/media/FrameParticipant.java b/src/java/com/threerings/media/FrameParticipant.java new file mode 100644 index 00000000..9611101d --- /dev/null +++ b/src/java/com/threerings/media/FrameParticipant.java @@ -0,0 +1,64 @@ +// +// $Id: FrameParticipant.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Component; + +/** + * Provides a mechanism for participating in the frame tick managed by the + * {@link FrameManager}. + */ +public interface FrameParticipant +{ + /** + * This is called on all registered frame participants, one for every + * frame. Following the tick the interface will be rendered, so + * participants can prepare themselves for their upcoming render in + * this method (making use of the timestamp provided for the frame if + * choreography is desired between different participants). + */ + public void tick (long tickStamp); + + /** + * Called immediately prior to {@link #getComponent} and then {@link + * Component#paint} on said component, to determine whether or not + * this frame participant needs to be painted. + */ + public boolean needsPaint (); + + /** + * If a frame participant wishes also to be actively rendered every + * frame rather than use passive rendering (which for Swing, at least, + * is hijacked when using the frame manager such that we take care of + * repainting dirty Swing components every frame into our off-screen + * buffer), it can return a component here which will have {@link + * Component#paint} called on it once per frame with a translated but + * unclipped graphics object. + * + *

Because clipping is expensive in terms of rectangle object + * allocation, frame participants are given the opportunity to do + * their own clipping because they are likely to want to clip to a + * more fine grained region than their entire bounds. If a particpant + * does not wish to be actively rendered, it can safely return null. + */ + public Component getComponent (); +} diff --git a/src/java/com/threerings/media/HourglassView.java b/src/java/com/threerings/media/HourglassView.java new file mode 100644 index 00000000..50dc608c --- /dev/null +++ b/src/java/com/threerings/media/HourglassView.java @@ -0,0 +1,175 @@ +// +// $Id: HourglassView.java 18862 2005-01-27 00:34:51Z tedv $ + +package com.threerings.media; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.JComponent; + +import com.samskivert.util.Interval; +import com.samskivert.util.ResultListener; + +import com.threerings.media.image.Mirage; +import com.threerings.media.util.MultiFrameImage; + +/** + * Displays an hourglass with the sand level representing the amount of + * time remaining. + */ +public class HourglassView extends TimerView +{ + /** + * Constructs an hourglass view. + */ + public HourglassView (FrameManager fmgr, JComponent host, int x, int y, + Mirage glassImage, Mirage topImage, Rectangle topRect, + Mirage botImage, Rectangle botRect, + MultiFrameImage sandTrickle) + { + this(fmgr, host, x, y, glassImage, topImage, topRect, new Point(0, 0), + botImage, botRect, new Point(0, 0), sandTrickle); + } + + /** + * Constructs an hourglass view. + */ + public HourglassView ( + FrameManager fmgr, JComponent host, int x, int y, Mirage glassImage, + Mirage topImage, Rectangle topRect, Point topOff, + Mirage botImage, Rectangle botRect, Point botOff, + MultiFrameImage sandTrickle) + { + super(fmgr, host, new Rectangle(x, y, glassImage.getWidth(), + glassImage.getHeight())); + + // Store relevant coordinate data + _topRect = topRect; + _topOff = topOff; + _botRect = botRect; + _botOff = botOff; + + // Save hourglass images + _hourglass = glassImage; + _sandTop = topImage; + _sandBottom = botImage; + _sandTrickle = sandTrickle; + + // Initialize the falling grain of sand + _sandY = 0; + + // Percentage changes smaller than one pixel in the hourglass + // itself definitely won't be noticed + _changeThreshold = 1.0f / _bounds.height; + } + + // documentation inherited + public void changeComplete (float complete) + { + super.changeComplete(complete); + setSandTrickleY(); + } + + // documentation inherited + public void tick (long tickStamp) + { + // Let the parent handle its stuff + super.tick(tickStamp); + + // check if the sand should be updated + if (_enabled && _running && tickStamp > _sandStamp) { + + // update the sand frame + setSandTrickleY(); + _sandFrame = (_sandFrame + 1) % _sandTrickle.getFrameCount(); + _sandStamp = tickStamp + SAND_RATE; + + // Make sure the timer gets repainted + invalidate(); + } + } + + // documentation inherited + public void paint (Graphics2D gfx, float completed) + { + // Handle processing from parent class + super.paint(gfx, completed); + + // Paint the hourglass + gfx.translate(_bounds.x, _bounds.y); + _hourglass.paint(gfx, 0, 0); + + // Paint the remaining top sand level + Shape oclip = gfx.getClip(); + int top = _topRect.y + (int)(_topRect.height * completed); + gfx.clipRect(_topRect.x, top, _topRect.width, + _topRect.height - (top-_topRect.y)); + _sandTop.paint(gfx, _topOff.x, _topOff.y); + + // paint the current sand frame + gfx.setClip(oclip); + int sandtop = _topRect.y + _topRect.height; + if (_sandY < _botRect.height) { + gfx.clipRect(_botRect.x, sandtop, _botRect.width, _sandY); + } + _sandTrickle.paintFrame(gfx, _sandFrame, + _botRect.x + (_botRect.width - _sandTrickle.getWidth(_sandFrame))/2, + sandtop); + gfx.setClip(oclip); + + // Paint the current bottom sand level + top = getSandBottomTop(completed); + gfx.clipRect(_botRect.x, top, _botRect.width, + _botRect.height-(top-_botRect.y)); + _sandBottom.paint(gfx, _botOff.x, _botOff.y); + gfx.setClip(oclip); + + // untranslate + gfx.translate(-_bounds.x, -_bounds.y); + } + + /** + * Set the y position of the trickle. + */ + protected void setSandTrickleY () + { + _sandY = (int) (_botRect.height * Math.min(1f, (_complete / .025))); + } + + /** + * Returns the current top coordinate of the bottom sand pile. + */ + protected int getSandBottomTop (float completed) + { + return _botRect.y + _botRect.height - + (int)(_botRect.height * completed); + } + + /** The bounds of the sand within the top and bottom sand images. */ + protected Rectangle _topRect, _botRect; + + /** Offsets at which to render the sand images. */ + protected Point _topOff, _botOff; + + /** Our images. */ + protected Mirage _hourglass, _sandTop, _sandBottom; + + /** The sand trickle. */ + protected MultiFrameImage _sandTrickle; + + /** The last time the sand updated moved. */ + protected long _sandStamp; + + /** The next sand frame to be painted. */ + protected int _sandFrame; + + /** The position of the top of the sand. */ + protected int _sandY; + + /** How often the sand frame updates. */ + protected static final long SAND_RATE = 80; +} diff --git a/src/java/com/threerings/media/IconManager.java b/src/java/com/threerings/media/IconManager.java new file mode 100644 index 00000000..c3aedf17 --- /dev/null +++ b/src/java/com/threerings/media/IconManager.java @@ -0,0 +1,183 @@ +// +// $Id: IconManager.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.io.IOException; +import java.util.Properties; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; + +import javax.swing.Icon; +import javax.swing.ImageIcon; + +import com.samskivert.util.ConfigUtil; +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.ImageUtil; + +import com.threerings.media.tile.TileIcon; +import com.threerings.media.tile.TileManager; +import com.threerings.media.tile.TileSet; + +/** + * Manages the creation of icons from tileset images. The icon manager is + * provided with a configuration file, which maps icon set identifiers to + * uniform tilesets and provides the metric information for said tilesets. + * UI code can subsequently request icons from the icon manager based on + * icon set identifier and index. + * + *

The configuration might look like the following: + * + *

+ * arrows.path = /rsrc/media/icons/arrows.png
+ * arrows.metrics = 20, 25  # icons that are 20 pixels wide and 25 pixels tall
+ *
+ * smileys.path = /rsrc/media/icons/smileys.png
+ * smileys.metrics = 16, 16  # icons that are 16 pixels square
+ * 
+ * + * A user could then request an arrows icon like so: + * + *
+ * Icon icon = iconmgr.getIcon("arrows", 2);
+ * 
+ */ +public class IconManager +{ + /** + * Creates an icon manager that will obtain tilesets from the supplied + * tile manager and which will load its configuration information from + * the specified properties file. + * + * @param tmgr the tile manager to use when fetching tilesets. + * @param configPath the path (relative to the classpath) from which + * the icon manager configuration can be loaded. + * + * @exception IOException thrown if an error occurs loading the + * configuration file. + */ + public IconManager (TileManager tmgr, String configPath) + throws IOException + { + this(tmgr, ConfigUtil.loadProperties(configPath)); + } + + /** + * Creates an icon manager that will obtain tilesets from the supplied + * tile manager and which will read its configuration information from + * the supplied properties file. + */ + public IconManager (TileManager tmgr, Properties config) + { + // save these for later + _tilemgr = tmgr; + _config = config; + } + + /** + * If icon images should be loaded from a set of resource bundles + * rather than the classpath, that set can be set here. + */ + public void setSource (String resourceSet) + { + _rsrcSet = resourceSet; + } + + /** + * Fetches the icon with the specified index from the named icon set. + */ + public Icon getIcon (String iconSet, int index) + { + try { + // see if the tileset is already loaded + TileSet set = (TileSet)_icons.get(iconSet); + + // load it up if not + if (set == null) { + String path = _config.getProperty(iconSet + PATH_SUFFIX); + if (StringUtil.isBlank(path)) { + throw new Exception("No path specified for icon set"); + } + + String metstr = _config.getProperty(iconSet + METRICS_SUFFIX); + if (StringUtil.isBlank(metstr)) { + throw new Exception("No metrics specified for icon set"); + } + + int[] metrics = StringUtil.parseIntArray(metstr); + if (metrics == null || metrics.length != 2) { + throw new Exception("Invalid icon set metrics " + + "[metrics=" + metstr + "]"); + } + + // load up the tileset + if (_rsrcSet == null) { + set = _tilemgr.loadTileSet( + path, metrics[0], metrics[1]); + } else { + set = _tilemgr.loadTileSet( + _rsrcSet, path, metrics[0], metrics[1]); + } + + // cache it + _icons.put(iconSet, set); + } + + // fetch the appropriate image and create an image icon + return new TileIcon(set.getTile(index)); + + } catch (Exception e) { + Log.warning("Unable to load icon [iconSet=" + iconSet + + ", index=" + index + ", error=" + e + "]."); + } + + // return an error icon + return new ImageIcon(ImageUtil.createErrorImage(32, 32)); + } + + /** The tile manager we use to load tilesets. */ + protected TileManager _tilemgr; + + /** Our configuration information. */ + protected Properties _config; + + /** The resource bundle from which we load icon images, or null if + * they should be loaded from the classpath. */ + protected String _rsrcSet; + + /** A cache of our icon tilesets. */ + protected LRUHashMap _icons = new LRUHashMap(ICON_CACHE_SIZE); + + /** The suffix we append to an icon set name to obtain the tileset + * image path configuration parameter. */ + protected static final String PATH_SUFFIX = ".path"; + + /** The suffix we append to an icon set name to obtain the tileset + * metrics configuration parameter. */ + protected static final String METRICS_SUFFIX = ".metrics"; + + /** The maximum number of icon tilesets that may be cached at once. */ + protected static final int ICON_CACHE_SIZE = 10; +} diff --git a/src/java/com/threerings/media/Log.java b/src/java/com/threerings/media/Log.java new file mode 100644 index 00000000..4a98701a --- /dev/null +++ b/src/java/com/threerings/media/Log.java @@ -0,0 +1,63 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +/** + * A placeholder class that contains a reference to the log object used by + * the media services package. + */ +public class Log +{ + public static final String PACKAGE = "media"; + + public static com.samskivert.util.Log log = + new com.samskivert.util.Log(PACKAGE); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } + + public static int getLevel () + { + return com.samskivert.util.Log.getLevel(PACKAGE); + } +} diff --git a/src/java/com/threerings/media/ManagedJFrame.java b/src/java/com/threerings/media/ManagedJFrame.java new file mode 100644 index 00000000..fdc1182e --- /dev/null +++ b/src/java/com/threerings/media/ManagedJFrame.java @@ -0,0 +1,117 @@ +// +// $Id: ManagedJFrame.java 3285 2004-12-28 03:48:40Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.JFrame; + +import com.samskivert.util.StringUtil; +import com.threerings.media.Log; + +/** + * When using the {@link FrameManager}, one must use this top-level frame + * class. + */ +public class ManagedJFrame extends JFrame +{ + /** + * Constructs a managed frame with no title. + */ + public ManagedJFrame () + { + this(""); + } + + /** + * Constructs a managed frame with the specified title. + */ + public ManagedJFrame (String title) + { + super(title); + } + + /** + * Constructs a managed frame in the specified graphics configuration. + */ + public ManagedJFrame (GraphicsConfiguration gc) + { + super(gc); + } + + /** + * Called by our frame manager when it's ready to go. + */ + public void init (FrameManager fmgr) + { + _fmgr = fmgr; + } + + /** + * Returns the frame manager managing this frame. + */ + public FrameManager getFrameManager () + { + return _fmgr; + } + + /** + * We catch paint requests and forward them on to the repaint + * infrastructure. + */ + public void paint (Graphics g) + { + update(g); + } + + /** + * We catch update requests and forward them on to the repaint + * infrastructure. + */ + public void update (Graphics g) + { + Shape clip = g.getClip(); + Rectangle dirty; + if (clip != null) { + dirty = clip.getBounds(); + } else { + dirty = getRootPane().getBounds(); + // account for our frame insets + Insets insets = getInsets(); + dirty.x += insets.left; + dirty.y += insets.top; + } + + if (_fmgr != null) { + _fmgr.restoreFromBack(dirty); + } else { + Log.info("Dropping AWT dirty rect " + StringUtil.toString(dirty) + + " [clip=" + StringUtil.toString(clip) + "]."); + } + } + + protected FrameManager _fmgr; +} diff --git a/src/java/com/threerings/media/MediaConstants.java b/src/java/com/threerings/media/MediaConstants.java new file mode 100644 index 00000000..2f063541 --- /dev/null +++ b/src/java/com/threerings/media/MediaConstants.java @@ -0,0 +1,37 @@ +// +// $Id: MediaConstants.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +/** + * Constants specific to the media package. + */ +public interface MediaConstants +{ + /** Identifies the back "layer" of sprites and animations. */ + public static final int BACK = 1; + + /** Identifies the front "layer" of sprites and animations. */ + public static final int FRONT = 2; + + /** Identifies the all "layers" of sprites and animations. */ + public static final int ALL = 3; +} diff --git a/src/java/com/threerings/media/MediaPanel.java b/src/java/com/threerings/media/MediaPanel.java new file mode 100644 index 00000000..abe2e174 --- /dev/null +++ b/src/java/com/threerings/media/MediaPanel.java @@ -0,0 +1,783 @@ +// +// $Id: MediaPanel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Shape; + +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.event.AncestorEvent; +import javax.swing.event.MouseInputAdapter; + +import java.util.Arrays; +import java.util.ArrayList; + +import com.samskivert.swing.Controller; +import com.samskivert.swing.Label; +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.swing.event.AncestorAdapter; +import com.samskivert.swing.event.CommandEvent; +import com.samskivert.util.IntListUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.media.timer.MediaTimer; + +import com.threerings.media.animation.Animation; +import com.threerings.media.animation.AnimationManager; + +import com.threerings.media.sprite.ButtonSprite; +import com.threerings.media.sprite.Sprite; +import com.threerings.media.sprite.SpriteManager; + +import com.threerings.media.sprite.action.ActionSprite; +import com.threerings.media.sprite.action.ArmingSprite; +import com.threerings.media.sprite.action.CommandSprite; +import com.threerings.media.sprite.action.DisableableSprite; +import com.threerings.media.sprite.action.HoverSprite; + +/** + * Provides a useful extensible framework for rendering animated displays + * that use sprites and animations. Sprites and animations can be added to + * this panel and they will automatically be ticked and rendered (see + * {@link #addSprite} and {@link #addAnimation}). + * + *

To facilitate optimized sprite and animation rendering, the panel + * provides a dirty region manager which is used to only repaint dirtied + * regions on each frame. Derived classes can add dirty regions to the + * scene and/or augment the dirty regions created by moving sprites and + * changing animations. + * + *

Sprite and animation rendering is done in two layers: front and + * back. Callbacks are provided to render behind the back layer ({@link + * #paintBehind}), in between front and back ({@link #paintBetween}) and + * in front of the front layer ({@link #paintInFront}). + * + *

The animated panel automatically registers with the {@link + * FrameManager} to participate in the frame tick. It only does so while + * it is a visible part of the UI hierarchy, so animations and sprites are + * paused while the animated panel is hidden. + */ +public class MediaPanel extends JComponent + implements FrameParticipant, MediaConstants +{ + /** + * Constructs a media panel. + */ + public MediaPanel (FrameManager framemgr) + { + // keep this for later + _framemgr = framemgr; + setOpaque(true); // our repaints shouldn't cause other jcomponents to + + // create our region manager + _remgr = new RegionManager(); + + // create our animation and sprite managers + _animmgr = new AnimationManager(this); + _spritemgr = new SpriteManager(this); + + // participate in the frame when we're visible + addAncestorListener(new AncestorAdapter() { + public void ancestorAdded (AncestorEvent event) { + _framemgr.registerFrameParticipant(MediaPanel.this); + } + public void ancestorRemoved (AncestorEvent event) { + _framemgr.removeFrameParticipant(MediaPanel.this); + } + }); + } + + /** + * Get the bounds of the viewport, in media coordinates. For the base + * MediaPanel, this will always be (0, 0, width, height). + */ + public Rectangle getViewBounds () + { + return new Rectangle(getWidth(), getHeight()); + } + + /** + * Returns a reference to the animation manager used by this media + * panel. + */ + public AnimationManager getAnimationManager () + { + return _animmgr; + } + + /** + * Returns a reference to the sprite manager used by this media panel. + */ + public SpriteManager getSpriteManager () + { + return _spritemgr; + } + + /** + * Pauses the sprites and animations that are currently active on this + * media panel. Also stops listening to the frame tick while paused. + */ + public void setPaused (boolean paused) + { + // sanity check + if ((paused && (_pauseTime != 0)) || + (!paused && (_pauseTime == 0))) { + Log.warning("Requested to pause when paused or vice-versa " + + "[paused=" + paused + "]."); + return; + } + + if (_paused = paused) { + // make a note of our pause time + _pauseTime = _framemgr.getTimeStamp(); + + } else { + // let the animation and sprite managers know that we just + // warped into the future + long delta = _framemgr.getTimeStamp() - _pauseTime; + _animmgr.fastForward(delta); + _spritemgr.fastForward(delta); + + // clear out our pause time + _pauseTime = 0; + } + } + + /** + * Returns a reference to the region manager that is used to + * accumulate dirty regions each frame. + */ + public RegionManager getRegionManager () + { + return _remgr; + } + + /** + * Returns a timestamp from the {@link MediaTimer} used to track time + * intervals for this media panel. Note: this should only be + * called from the AWT thread. + */ + public long getTimeStamp () + { + return _framemgr.getTimeStamp(); + } + + // documentation inherited from interface + public void getPerformanceStatus (StringBuilder buf) + { + } + + /** + * Adds a sprite to this panel. + */ + public void addSprite (Sprite sprite) + { + _spritemgr.addSprite(sprite); + + if (((sprite instanceof ActionSprite) || + (sprite instanceof HoverSprite)) && (_actionSpriteCount++ == 0)) { + if (_actionHandler == null) { + _actionHandler = createActionSpriteHandler(); + } + addMouseListener(_actionHandler); + addMouseMotionListener(_actionHandler); + } + } + + /** + * @return true if the sprite is already added to this panel. + */ + public boolean isManaged (Sprite sprite) + { + return _spritemgr.isManaged(sprite); + } + + /** + * Removes a sprite from this panel. + */ + public void removeSprite (Sprite sprite) + { + _spritemgr.removeSprite(sprite); + + if (((sprite instanceof ActionSprite) || + (sprite instanceof HoverSprite)) && (--_actionSpriteCount == 0)) { + removeMouseListener(_actionHandler); + removeMouseMotionListener(_actionHandler); + } + } + + /** + * Removes all sprites from this panel. + */ + public void clearSprites () + { + _spritemgr.clearMedia(); + + if (_actionHandler != null) { + removeMouseListener(_actionHandler); + removeMouseMotionListener(_actionHandler); + _actionSpriteCount = 0; + } + } + + /** + * Adds an animation to this panel. Animations are automatically + * removed when they finish. + */ + public void addAnimation (Animation anim) + { + _animmgr.registerAnimation(anim); + } + + /** + * @return true if the animation is already added to this panel. + */ + public boolean isManaged (Animation anim) + { + return _animmgr.isManaged(anim); + } + + /** + * Aborts a currently running animation and removes it from this + * panel. Animations are normally automatically removed when they + * finish. + */ + public void abortAnimation (Animation anim) + { + _animmgr.unregisterAnimation(anim); + } + + /** + * Removes all animations from this panel. + */ + public void clearAnimations () + { + _animmgr.clearMedia(); + } + + // documentation inherited from interface + public void tick (long tickStamp) + { + // bail if ticking is currently disabled + if (_paused) { + return; + } + + // let derived classes do their business + willTick(tickStamp); + + // now tick our animations and sprites + _animmgr.tick(tickStamp); + _spritemgr.tick(tickStamp); + + // if performance debugging is enabled, + if (_perfDebug.getValue()) { + if (_perfLabel == null) { + _perfLabel = new Label( + "", Label.OUTLINE, Color.white, Color.black, + new Font("Arial", Font.PLAIN, 10)); + } + if (_perfRect == null) { + _perfRect = new Rectangle(5, 5, 0, 0); + } + + StringBuilder perf = new StringBuilder(); + perf.append("[FPS: "); + perf.append(_framemgr.getPerfTicks()).append("/"); + perf.append(_framemgr.getPerfTries()); + perf.append(" PM:"); + StringUtil.toString(perf, _framemgr.getPerfMetrics()); +// perf.append(" MP:").append(_dirtyPerTick); + perf.append("]"); + + String perfStatus = perf.toString(); + if (!_perfStatus.equals(perfStatus)) { + _perfStatus = perfStatus; + _perfLabel.setText(perfStatus); + + Graphics2D gfx = (Graphics2D)getGraphics(); + if (gfx != null) { + _perfLabel.layout(gfx); + gfx.dispose(); + + // make sure the region we dirty contains the old and + // the new text (which we ensure by never letting the + // rect shrink) + Dimension psize = _perfLabel.getSize(); + _perfRect.width = Math.max(_perfRect.width, psize.width); + _perfRect.height = Math.max(_perfRect.height, psize.height); + dirtyScreenRect(new Rectangle(_perfRect)); + } + } + } + + // let derived classes do their business + didTick(tickStamp); + + // make a note that the next paint will correspond to a call to + // tick() + _tickPaintPending = true; + } + + /** + * Derived classes can override this method and perform computation + * prior to the ticking of the sprite and animation managers. + */ + protected void willTick (long tickStamp) + { + } + + /** + * Derived classes can override this method and perform computation + * subsequent to the ticking of the sprite and animation managers. + */ + protected void didTick (long tickStamp) + { + } + + // documentation inherited from interface + public boolean needsPaint () + { + // compute our average dirty regions per tick + if (_tick++ == 99) { + _tick = 0; + int dirty = IntListUtil.sum(_dirty); + Arrays.fill(_dirty, 0); + _dirtyPerTick = (float)dirty/100; + } + + // if we have no dirty regions, clear our pending tick indicator + // because we're not going to get painted + boolean needsPaint = _remgr.haveDirtyRegions(); + if (!needsPaint) { + _tickPaintPending = false; + } + + // regardless of whether or not we paint, we need to let our + // abstract media managers know that we've gotten to the point of + // painting because they need to remain prepared to deal with + // media changes that happen any time between the tick() and the + // paint() and thus need to know when paint() happens + _animmgr.willPaint(); + _spritemgr.willPaint(); + + return needsPaint; + } + + // documentation inherited from interface + public Component getComponent () + { + return this; + } + + // documentation inherited + public void setOpaque (boolean opaque) + { + if (!opaque) { + Log.warning("Media panels shouldn't be setOpaque(false)."); + Thread.dumpStack(); + } + super.setOpaque(true); + } + + // documentation inherited + public void repaint (long tm, int x, int y, int width, int height) + { + if (width > 0 && height > 0) { + dirtyScreenRect(new Rectangle(x, y, width, height)); + } + } + + // documentation inherited + public void paint (Graphics g) + { + Graphics2D gfx = (Graphics2D)g; + + // no use in painting if we're not showing or if we've not yet + // been validated + if (!isValid() || !isShowing()) { + return; + } + + // if this isn't a tick paint, then we need to grab the clipping + // rectangle and mark it as dirty + if (!_tickPaintPending) { + Shape clip = g.getClip(); + if (clip == null) { + // mark the whole component as dirty + repaint(); + } else { + dirtyScreenRect(clip.getBounds()); + } + + // we used to bail out here and not render until our next + // tick, but it turns out that we need to render here because + // Swing may have repainted our parent over us and expect that + // we're going to paint ourselves on top of whatever it just + // painted, so we go ahead and paint now to avoid flashing + + } else { + _tickPaintPending = false; + } + + // if we have no invalid rects, there's no need to repaint + if (!_remgr.haveDirtyRegions()) { + return; + } + + // get our dirty rectangles and delegate the main painting to a + // method that can be more easily overridden + Rectangle[] dirty = _remgr.getDirtyRegions(); + _dirty[_tick] = dirty.length; + try { + paint(gfx, dirty); + } catch (Throwable t) { + Log.warning(this + " choked in paint(" + dirty + ")."); + Log.logStackTrace(t); + } + + // render our performance debugging if it's enabled + if (_perfRect != null && _perfDebug.getValue()) { + gfx.setClip(null); + _perfLabel.render(gfx, _perfRect.x, _perfRect.y); + } + } + + /** + * Performs the actual painting of the media panel. Derived methods + * can override this method if they wish to perform pre- and/or + * post-paint activities or if they wish to provide their own painting + * mechanism entirely. + */ + protected void paint (Graphics2D gfx, Rectangle[] dirty) + { + int dcount = dirty.length; + + for (int ii = 0; ii < dcount; ii++) { + Rectangle clip = dirty[ii]; + // sanity-check the dirty rectangle + if (clip == null) { + Log.warning("Found null dirty rect painting media panel?!"); + Thread.dumpStack(); + continue; + } + + // constrain this dirty region to the bounds of the component + constrainToBounds(clip); + + // ignore rectangles that were reduced to nothingness + if (clip.width == 0 || clip.height == 0) { + continue; + } + + // clip to this dirty region + clipToDirtyRegion(gfx, clip); + + // paint the region + paintDirtyRect(gfx, clip); + } + } + + /** + * Paints all the layers of the specified dirty region. + */ + protected void paintDirtyRect (Graphics2D gfx, Rectangle rect) + { + // paint the behind the scenes stuff + paintBehind(gfx, rect); + + // paint back sprites and animations + paintBits(gfx, AnimationManager.BACK, rect); + + // paint the between the scenes stuff + paintBetween(gfx, rect); + + // paint front sprites and animations + paintBits(gfx, AnimationManager.FRONT, rect); + + // paint anything in front + paintInFront(gfx, rect); + } + + /** + * Called by the main rendering code to constrain this dirty rectangle + * to the bounds of the media panel. If a derived class is using dirty + * rectangles that live in some sort of virtual coordinate system, + * they'll want to override this method and constraint the rectangles + * properly. + */ + protected void constrainToBounds (Rectangle dirty) + { + SwingUtilities.computeIntersection( + 0, 0, getWidth(), getHeight(), dirty); + } + + /** + * This is called to clip the rendering output to the supplied dirty + * region. This should use {@link Graphics#setClip} because the + * clipping region will need to be replaced as we iterate through our + * dirty regions. By default, a region is assumed to represent screen + * coordinates, but if a derived class wishes to maintain dirty + * regions in non-screen coordinates, it can override this method to + * properly clip to the dirty region. + */ + protected void clipToDirtyRegion (Graphics2D gfx, Rectangle dirty) + { +// Log.info("MP: Clipping to [clip=" + StringUtil.toString(dirty) + "]."); + gfx.setClip(dirty); + } + + /** + * Called to mark the specified rectangle (in screen coordinates) as + * dirty. The rectangle will be bent, folded and mutilated, so be sure + * you're not passing a rectangle into this method that is being used + * elsewhere. + * + *

If derived classes wish to convert from screen coordinates to + * some virtual coordinate system to be used by their repaint manager, + * this is the place to do it. + */ + protected void dirtyScreenRect (Rectangle rect) + { + _remgr.addDirtyRegion(rect); + } + + /** + * Paints behind all sprites and animations. The supplied invalid + * rectangle should be redrawn in the supplied graphics context. + * Sub-classes should override this method to do the actual rendering + * for their display. + */ + protected void paintBehind (Graphics2D gfx, Rectangle dirtyRect) + { + } + + /** + * Paints between the front and back layer of sprites and animations. + * The supplied invalid rectangle should be redrawn in the supplied + * graphics context. Sub-classes should override this method to do the + * actual rendering for their display. + */ + protected void paintBetween (Graphics2D gfx, Rectangle dirtyRect) + { + } + + /** + * Paints in front of all sprites and animations. The supplied invalid + * rectangle should be redrawn in the supplied graphics context. + * Sub-classes should override this method to do the actual rendering + * for their display. + */ + protected void paintInFront (Graphics2D gfx, Rectangle dirtyRect) + { + } + + /** + * Renders the sprites and animations that intersect the supplied + * dirty region in the specified layer. Derived classes can override + * this method if they need to do custom sprite or animation rendering + * (if they need to do special sprite z-order handling, for example). + * The clipping region will already be set appropriately. + */ + protected void paintBits (Graphics2D gfx, int layer, Rectangle dirty) + { + if (layer == FRONT) { + _spritemgr.paint(gfx, layer, dirty); + _animmgr.paint(gfx, layer, dirty); + } else { + _animmgr.paint(gfx, layer, dirty); + _spritemgr.paint(gfx, layer, dirty); + } + } + + /** + * Creates the mouse listener that will handle action sprites and their + * variants. + */ + protected ActionSpriteHandler createActionSpriteHandler () + { + return new ActionSpriteHandler(); + } + + /** The frame manager with whom we register. */ + protected FrameManager _framemgr; + + /** The animation manager in use by this panel. */ + protected AnimationManager _animmgr; + + /** The sprite manager in use by this panel. */ + protected SpriteManager _spritemgr; + + /** Used to accumulate and merge dirty regions on each tick. */ + protected RegionManager _remgr; + + /** Used to correlate tick()s with paint()s. */ + protected boolean _tickPaintPending = false; + + /** Whether we're currently paused. */ + protected boolean _paused; + + /** Used to track the clock time at which we were paused. */ + protected long _pauseTime; + + /** Used to keep metrics. */ + protected int[] _dirty = new int[200]; + + /** Used to keep metrics. */ + protected int _tick; + + /** Used to keep metrics. */ + protected float _dirtyPerTick; + + /** Handles ActionSprite/HoverSprite/ArmingSprite manipulation. */ + protected class ActionSpriteHandler extends MouseInputAdapter + { + // documentation inherited + public void mousePressed (MouseEvent me) + { + if (_activeSprite == null) { + // see if we can find one + Sprite s = getHit(me); + if (s instanceof ActionSprite) { + _activeSprite = s; + } + } + + if (_activeSprite instanceof ArmingSprite) { + ((ArmingSprite) _activeSprite).setArmed(true); + } + } + + // documentation inherited + public void mouseReleased (MouseEvent me) + { + if (_activeSprite instanceof ArmingSprite) { + ((ArmingSprite)_activeSprite).setArmed(false); + } + + if ((_activeSprite instanceof ActionSprite) && + _activeSprite.hitTest(me.getX(), me.getY())) { + ActionEvent event; + if (_activeSprite instanceof CommandSprite) { + CommandSprite cs = (CommandSprite) _activeSprite; + event = new CommandEvent( + MediaPanel.this, cs.getActionCommand(), + cs.getCommandArgument(), me.getWhen(), + me.getModifiers()); + + } else { + ActionSprite as = (ActionSprite) _activeSprite; + event = new ActionEvent( + MediaPanel.this, ActionEvent.ACTION_PERFORMED, + as.getActionCommand(), me.getWhen(), me.getModifiers()); + } + Controller.postAction(event); + } + + if (!(_activeSprite instanceof HoverSprite)) { + _activeSprite = null; + } + + mouseMoved(me); + } + + // documentation inherited + public void mouseDragged (MouseEvent me) + { + if (_activeSprite instanceof ArmingSprite) { + ((ArmingSprite) _activeSprite).setArmed( + _activeSprite.hitTest(me.getX(), me.getY())); + } + } + + // documentation inherited + public void mouseMoved (MouseEvent me) + { + Sprite s = getHit(me); + if (_activeSprite == s) { + return; + } + if (_activeSprite instanceof HoverSprite) { + ((HoverSprite) _activeSprite).setHovered(false); + } + _activeSprite = s; + if (_activeSprite instanceof HoverSprite) { + ((HoverSprite) _activeSprite).setHovered(true); + } + } + + /** + * Utility method, get the highest non-disabled action/hover sprite. + */ + protected Sprite getHit (MouseEvent me) + { + ArrayList list = new ArrayList(); + _spritemgr.getHitSprites(list, me.getX(), me.getY()); + for (int ii = 0, nn = list.size(); ii < nn; ii++) { + Object o = list.get(ii); + if ((o instanceof HoverSprite || o instanceof ActionSprite) && + (!(o instanceof DisableableSprite) || + ((DisableableSprite) o).isEnabled())) { + return (Sprite) o; + } + } + return null; + } + + /** The active hover sprite, or action sprite. */ + protected Sprite _activeSprite; + } + + /** The action sprite handler, or null for none. */ + protected ActionSpriteHandler _actionHandler; + + /** The number of action/hover sprites being managed. */ + protected int _actionSpriteCount; + + // used to render performance metrics + protected String _perfStatus = ""; + protected Label _perfLabel; + protected static Rectangle _perfRect; + + /** A debug hook that toggles FPS rendering. */ + protected static RuntimeAdjust.BooleanAdjust _perfDebug = + new RuntimeAdjust.BooleanAdjust( + "Toggles frames per second and dirty regions per tick rendering.", + "narya.media.fps_display", MediaPrefs.config, false) { + protected void adjusted (boolean newValue) { + // clear out some things if we're turned off + if (!newValue) { + _perfRect = null; + } + } + }; +} diff --git a/src/java/com/threerings/media/MediaPrefs.java b/src/java/com/threerings/media/MediaPrefs.java new file mode 100644 index 00000000..1cd06317 --- /dev/null +++ b/src/java/com/threerings/media/MediaPrefs.java @@ -0,0 +1,35 @@ +// +// $Id: MediaPrefs.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import com.samskivert.util.Config; + +/** + * Provides access to runtime configuration parameters for the media + * package and its subpackages. + */ +public class MediaPrefs +{ + /** Used to load our preferences from a properties file and map them + * to the persistent Java preferences repository. */ + public static Config config = new Config("rsrc/config/media"); +} diff --git a/src/java/com/threerings/media/RegionManager.java b/src/java/com/threerings/media/RegionManager.java new file mode 100644 index 00000000..72df0423 --- /dev/null +++ b/src/java/com/threerings/media/RegionManager.java @@ -0,0 +1,165 @@ +// +// $Id: RegionManager.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.EventQueue; +import java.awt.Rectangle; + +import java.util.ArrayList; + +import com.samskivert.util.StringUtil; + +/** + * Manages regions (rectangles) that are invalidated in the process of + * ticking animations and sprites and generally doing other display + * related business. + */ +public class RegionManager +{ + /** + * Invalidates the specified region. + */ + public void invalidateRegion (int x, int y, int width, int height) + { + if (isValidSize(width, height)) { + addDirtyRegion(new Rectangle(x, y, width, height)); + } + } + + /** + * Invalidates the specified region (the supplied rectangle will be + * cloned as the region manager fiddles with the rectangles it uses + * internally). + */ + public void invalidateRegion (Rectangle rect) + { + if (isValidSize(rect.width, rect.height)) { + addDirtyRegion((Rectangle)rect.clone()); + } + } + + /** + * Adds the supplied rectangle to the dirty regions. Control of the + * rectangle is given to the region manager as it may choose to bend, + * fold or mutilate it later. If you don't want the region manager + * messing with your rectangle, use {@link #invalidateRegion}. + */ + public void addDirtyRegion (Rectangle rect) + { + // make sure we're on an AWT thread + if (!EventQueue.isDispatchThread()) { + Log.warning("Oi! Region dirtied on non-AWT thread " + + "[rect=" + rect + "]."); + Thread.dumpStack(); + } + + // sanity check + if (rect == null) { + Log.warning("Attempt to dirty a null rect!?"); + Thread.dumpStack(); + return; + } + + // more sanity checking + long x = rect.x, y = rect.y; + if ((Math.abs(x) > Integer.MAX_VALUE/2) || + (Math.abs(y) > Integer.MAX_VALUE/2)) { + Log.warning("Requested to dirty questionable region " + + "[rect=" + StringUtil.toString(rect) + "]."); + if (Log.getLevel() == Log.log.DEBUG) { + Thread.dumpStack(); + } + return; // Let's not do it! + } + + if (isValidSize(rect.width, rect.height)) { + // Log.info("Invalidating " + StringUtil.toString(rect)); + _dirty.add(rect); + } + } + + /** Used to ensure our dirty regions are not invalid. */ + protected final boolean isValidSize (int width, int height) + { + if (width < 0 || height < 0) { + Log.warning("Attempt to add invalid dirty region?! " + + "[size=" + width + "x" + height + "]."); + Thread.dumpStack(); + return false; + + } else if (width == 0 || height == 0) { + // no need to complain about zero sized rectangles, just + // ignore them + return false; + + } else { + return true; + } + } + + /** + * Returns true if dirty regions have been accumulated since the last + * call to {@link #getDirtyRegions}. + */ + public boolean haveDirtyRegions () + { + return (_dirty.size() > 0); + } + + /** + * Merges all outstanding dirty regions into a single list of + * rectangles and returns that to the caller. Interally, the list of + * accumulated dirty regions is cleared out and prepared for the next + * frame. + */ + public Rectangle[] getDirtyRegions () + { + ArrayList merged = new ArrayList(); + + for (int ii = _dirty.size() - 1; ii >= 0; ii--) { + // pop the next rectangle from the dirty list + Rectangle mr = (Rectangle)_dirty.remove(ii); + + // merge in any overlapping rectangles + for (int jj = ii - 1; jj >= 0; jj--) { + Rectangle r = (Rectangle)_dirty.get(jj); + if (mr.intersects(r)) { + // remove the overlapping rectangle from the list + _dirty.remove(jj); + ii--; + // grow the merged dirty rectangle + mr.add(r); + } + } + + // add the merged rectangle to the list + merged.add(mr); + } + + Rectangle[] rects = new Rectangle[merged.size()]; + merged.toArray(rects); + return rects; + } + + /** A list of dirty rectangles. */ + protected ArrayList _dirty = new ArrayList(); +} diff --git a/src/java/com/threerings/media/SafeScrollPane.java b/src/java/com/threerings/media/SafeScrollPane.java new file mode 100644 index 00000000..0e978cae --- /dev/null +++ b/src/java/com/threerings/media/SafeScrollPane.java @@ -0,0 +1,89 @@ +// +// $Id: SafeScrollPane.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; + +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import javax.swing.JViewport; + +/** + * A scroll pane that is safe to use in frame managed views. + */ +public class SafeScrollPane extends JScrollPane +{ + public SafeScrollPane () + { + } + + public SafeScrollPane (Component view) + { + super(view); + } + + public SafeScrollPane (Component view, int owidth, int oheight) + { + super(view); + if (owidth != 0 || oheight != 0) { + _override = new Dimension(owidth, oheight); + } + } + + // documentation inherited + public Dimension getPreferredSize () + { + Dimension d = super.getPreferredSize(); + if (_override != null) { + if (_override.width != 0) { + d.width = _override.width; + } + if (_override.height != 0) { + d.height = _override.height; + } + } + return d; + } + + protected JViewport createViewport () + { + JViewport vp = new JViewport() { + public void setViewPosition (Point p) { + super.setViewPosition(p); + // simple scroll mode results in setViewPosition causing + // our view to become invalid, but nothing ever happens to + // queue up a revalidate for said view, so we have to do + // it here + Component c = getView(); + if (c instanceof JComponent) { + ((JComponent)c).revalidate(); + } + } + }; + vp.setScrollMode(JViewport.SIMPLE_SCROLL_MODE); + return vp; + } + + protected Dimension _override; +} diff --git a/src/java/com/threerings/media/TimerView.java b/src/java/com/threerings/media/TimerView.java new file mode 100644 index 00000000..c3767e32 --- /dev/null +++ b/src/java/com/threerings/media/TimerView.java @@ -0,0 +1,513 @@ +// +// $Id: HourglassView.java 18697 2005-01-19 01:18:47Z tedv $ + +package com.threerings.media; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; + +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; + +import javax.swing.JComponent; +import javax.swing.event.AncestorEvent; + +import com.samskivert.swing.event.AncestorAdapter; +import com.samskivert.util.ResultListener; + +/** + * A generic timer class that can be rendered on screen. + * + * NOTE: This base class doesn't actually render anything, but it's still + * useful for triggering user supplied callback functions. Derived classes + * are more than welcome to setup their own rendering, of course. + */ +public class TimerView + implements FrameParticipant, HierarchyListener +{ + /** + * Constructs a timer view that fires at the default rate. + */ + public TimerView (FrameManager fmgr, JComponent host, Rectangle bounds) + { + // Cache the input arguments + _fmgr = fmgr; + _host = host; + _bounds = new Rectangle(bounds); + + // Watch for changes in the timer's state so it can effectively + // register or unregister with the frame manager as necessary + _host.addHierarchyListener(this); + checkFrameParticipation(); + } + + /** + * Sets whether this timer should be rendered. + */ + public void setEnabled (boolean enabled) + { + if (_enabled != enabled) + { + _enabled = enabled; + invalidate(); + } + } + + /** + * Get the amount of time it takes to render digital changes in the + * completion state. + */ + public long getTransitionTime () + { + return _transitionTime; + } + + /** + * Set the amount of time it takes to render digital changes in the + * completion state (probably due to a timer reset). + */ + public void setTransitionTime (long time) + { + _transitionTime = Math.max(0, time); + } + + /** + * Setup a warning to trigger after the timer is "warnPercent" + * or more completed. If "warner" is non-null, it will be + * called at that time. + */ + public void setWarning (float warnPercent, ResultListener warner) + { + // This warning hasn't triggered yet + _warned = false; + + // Here are the details + _warnPercent = warnPercent; + _warner = warner; + } + + /** + * Remove any warning this timer might have had. + */ + public void removeWarning () + { + // Don't trigger any warnings + _warned = false; + _warnPercent = -1; + _warner = null; + } + + /** Test if the timer is running right now. */ + public boolean running () + { + return _running; + } + + /** + * Start the timer running from the specified percentage complete, + * to expire at the specified time. + * + * @param startPercent a value in [0f, 1f) indicating how much + * hourglass time has already elapsed when the timer starts. + * @param duration The time interval over which the timer would + * run if it started at 0%. + * @param finisher a listener that will be notified when the timer + * finishes, or null if nothing should be notified. + */ + public void start (float startPercent, long duration, + ResultListener finisher) + { + // Sanity check input arguments + if (startPercent < 0.0f || startPercent >= 1.0f) { + throw new IllegalArgumentException( + "Invalid starting percent " + startPercent); + } + if (duration < 0) { + throw new IllegalArgumentException("Invalid duration " + duration); + } + + // Stop any current processing + stop(); + + // Record the timer's full duration and effective start time + _duration = duration; + + // Change the completion percent and make sure the starting + // time gets updated on the next tick + changeComplete(startPercent); + _start = Long.MIN_VALUE; + + // Thank you sir; would you kindly take a chair in the waiting room? + _finisher = finisher; + + // The warning and completion handlers haven't been triggered yet + _warned = false; + _completed = false; + + // Start things running + _running = true; + } + + /** + * Reset the timer. + */ + public void reset () + { + // Stop processing permanently + stop(); + + // Reset the completion percent + changeComplete(0f); + } + + /** + * Stop the timer. + */ + public void stop () + { + // Stop processing + pause(); + + // Prevent it from being unpaused + _lastUpdate = Long.MIN_VALUE; + } + + /** + * Pause the timer from processing. + */ + public void pause () + { + // Stop processing + _running = false; + } + + /** + * Unpause the timer. + */ + public void unpause () + { + // Don't unpause the timer if it wasn't paused to begin with + if (_lastUpdate == Long.MIN_VALUE || _start == Long.MIN_VALUE) { + return; + } + + // Adjust the starting time when the timer next ticks + _processUnpause = true; + + // Start things running again + _running = true; + } + + /** + * Generate an unexpected change in the timer's completion and + * set up the necessary details to render interpolation from the old + * to new states + */ + public void changeComplete (float complete) + { + // Store the new state + _complete = complete; + + // Determine the percentage difference between the "actual" + // completion state and the completion amount to render during + // the smooth interpolation + _renderOffset = _renderComplete - _complete; + + // When the timer next ticks, find out when this interpolation + // should start + _renderOffsetTime = Long.MIN_VALUE; + } + + /** + * Updates the timer for the current inputted time. + */ + protected void update (long now) + { + } + + /** + * Test if the warning was triggered and needs to be processed. + */ + protected boolean triggeredWarning () + { + // Trigger a warning if it exists, it hasn't occured yet, + // and the timer has passed the warning threshold. + return ((_warnPercent >= 0f) && + !_warned && (_warnPercent <= _complete)); + } + + /** + * Test if the completion was triggered and needs to be processed. + */ + protected boolean triggeredCompleted () + { + return (!_completed && (1.0 <= _complete)); + } + + /** + * Handle the trigger of the warning. + */ + protected void handleWarning () + { + // Remember that this warning was handled + _warned = true; + + // Execute the warning listener if one was supplied + if (_warner != null) { + _warner.requestCompleted(this); + } + } + + /** + * Handle the trigger of the timer's completion. + */ + protected void handleCompleted () + { + // Remember that the completion was handled + _completed = true; + + // Stop the timer + stop(); + + // Handle the trigger function if one was supplied + if (_finisher != null) { + _finisher.requestCompleted(this); + } + } + + /** + * Invalidates this view's bounds via the host component. + */ + protected void invalidate () + { + // Schedule the timer's location on screen to get repainted + _invalidated = true; + _host.repaint(_bounds.x, _bounds.y, _bounds.width, _bounds.height); + } + + /** + * Renders the timer to the given graphics context if enabled. + */ + public void render (Graphics2D gfx) + { + // Paint the timer if its enabled + if (_enabled) { + paint(gfx, _renderComplete); + } + _invalidated = false; + } + + /** + * Paint the timer into the given graphics context at the inputted + * percent complete (0f means just started, 1f means just finished). + */ + public void paint (Graphics2D gfx, float complete) + { + // Inheriting classes will want to implement their own + // version of this function. Remember to call this one though! + + // Remember the completion level the last time the timer was painted + _paintComplete = complete; + } + + // documentation inherited + public void tick (long now) + { + if (!_enabled) { + return; + } + + // Initialize the starting time if necessary + if (_start == Long.MIN_VALUE) { + _start = now - Math.round(_duration * _complete); + } + + // Initialize the timestamp of the rendering error if necessary + if (_renderOffsetTime == Long.MIN_VALUE) { + _renderOffsetTime = now; + } + + // If the timer was just unpaused, handle the updates that + // need a timestamp + if (_processUnpause) { + _processUnpause = false; + _start += now - _lastUpdate; + } + + // Update the completion and triggers when the timer is running + if (running()) + { + // Figure out how what percent the timer has completed + _lastUpdate = now; + _complete = ((float) (_lastUpdate - _start)) / _duration; + + // Handle warning trigger if necessary + if (triggeredWarning()) { + handleWarning(); + } + + // Handle completion trigger if necessary + if (triggeredCompleted()) { + handleCompleted(); + } + } + + // Add error to the render completion percent if the interpolation + // hasn't finished yet + _renderComplete = _complete; + float error = _renderOffset; + if (_renderOffsetTime + _transitionTime > now) { + + _renderComplete += _renderOffset * + (1f - (now - _renderOffsetTime) / (float) _transitionTime); + _renderComplete = Math.max(0f, Math.min(1f, _renderComplete)); + } + + // Possibly orce a repaint if the render level changed (highly + // probable but not guaranteed) + if (_renderComplete != _paintComplete) + { + // Always force a repaint when changing to or from a boundary + if (_renderComplete <= 0f || _paintComplete <= 0f || + _renderComplete >= 1f || _paintComplete >= 1f) + { + invalidate(); + } + + // Also force a repaint if the completion state sufficiently + // changed + else if (Math.abs(_renderComplete - _paintComplete) > + _changeThreshold) + { + invalidate(); + } + } + } + + // documentation inherited + public boolean needsPaint () + { + // Always paint if the timer was invalidated + return _invalidated; + } + + // documentation inherited + public Component getComponent () + { + return null; + } + + // documentation inherited + public void hierarchyChanged (HierarchyEvent e) + { + checkFrameParticipation(); + } + + /** Check that the frame knows about the timer. */ + public void checkFrameParticipation () + { + // Determine whether or not the timer should participate in + // media ticks + boolean participate = _host.isShowing(); + + // Start participating if necessary + if (participate && !_participating) + { + _fmgr.registerFrameParticipant(this); + _participating = true; + } + + // Stop participating if necessary + else if (!participate && _participating) + { + _fmgr.removeFrameParticipant(this); + _participating = false; + } + } + + /** The frame manager that manages our animated view. */ + protected FrameManager _fmgr; + + /** The media panel containing the view. */ + protected JComponent _host; + + /** The screen coordinates of the timer's bounding box. */ + protected Rectangle _bounds; + + /** Whether to render the timer. */ + protected boolean _enabled = true; + + /** Whether the timer is running. */ + protected boolean _running = false; + + /** Whether the timer is participating in media tick updates. */ + protected boolean _participating = false; + + /** The last time the timer updated while running. */ + protected long _lastUpdate = Long.MIN_VALUE; + + /** The total amount of time in the timer when it was 0% done. */ + protected long _duration; + + /** The timestamp when the timer effectively started. */ + protected long _start; + + /** The percent of the duration time completed. */ + protected float _complete = 0f; + + /** The difference between the old rendered completion percent and the + * new completion percent the last time the completion percent had + * an unexpected change. In other words, this is the greatest amount + * that _renderComplete will differ from _complete during an + * state interpolation. + */ + protected float _renderOffset = 0f; + + /** The timestamp of _renderOffset. */ + protected long _renderOffsetTime = Long.MIN_VALUE; + + /** The amount of time it takes to fully interpolation a render + * transition from completion 0.0 to 1.0. */ + protected long _transitionTime = 0; + + /** The completion percent at which to render the timer. */ + protected float _renderComplete = 0f; + + /** The completion percent last time the timer was repainted. */ + protected float _paintComplete = -1; + + /** + * The timer will not invalidate itself until the completion level + * to render changes by at least this much from the previous time it + * was invalidated. + */ + protected float _changeThreshold = 0.0f; + + /** True if the timer has been invalidated since its last repaint. */ + protected boolean _invalidated; + + /** Trigger the warning when at least this much time has elapsed, + * or -1 for no warning. */ + protected float _warnPercent = -1; + + /** True if the warning has already been processed. */ + protected boolean _warned; + + /** True if the completion has already been processed. */ + protected boolean _completed; + + /** True if the code should process everything required for an unpause + * on the next tick(). */ + protected boolean _processUnpause = false; + + /** A listener to be notified when the timer finishes. */ + protected ResultListener _finisher; + + /** A listener to be notified when the warning time occurs. */ + protected ResultListener _warner; + + /** The default update date. */ + protected static final long DEFAULT_RATE = 100L; +} diff --git a/src/java/com/threerings/media/ViewTracker.java b/src/java/com/threerings/media/ViewTracker.java new file mode 100644 index 00000000..1f3687cc --- /dev/null +++ b/src/java/com/threerings/media/ViewTracker.java @@ -0,0 +1,18 @@ +// +// $Id: ViewTracker.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media; + +/** + * An interface used by entities that wish to respond to the scrolling of a + * {@link VirtualMediaPanel}. + * + * @see VirtualMediaPanel#addViewTracker + */ +public interface ViewTracker +{ + /** + * Called by a {@link VirtualMediaPanel} when it scrolls. + */ + public void viewLocationDidChange (int dx, int dy); +} diff --git a/src/java/com/threerings/media/VirtualMediaPanel.java b/src/java/com/threerings/media/VirtualMediaPanel.java new file mode 100644 index 00000000..6ac4aecd --- /dev/null +++ b/src/java/com/threerings/media/VirtualMediaPanel.java @@ -0,0 +1,463 @@ +// +// $Id: VirtualMediaPanel.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.util.ArrayList; + +import javax.swing.SwingUtilities; + +import com.samskivert.util.RunAnywhere; + +import com.threerings.media.image.ImageUtil; +import com.threerings.media.image.Mirage; +import com.threerings.media.util.MathUtil; +import com.threerings.media.util.Pathable; + +/** + * Extends the base media panel with the notion of a virtual coordinate + * system. All entities in the virtual media panel have virtual + * coordinates and the virtual media panel displays a window into that + * virtual view. The panel can be made to scroll by adjusting the view + * offset slightly at the start of each tick and it will efficiently copy + * the unmodified view data and generate repaint requests for the exposed + * regions. + */ +public class VirtualMediaPanel extends MediaPanel +{ + /** The code for the pathable following mode wherein we keep the view + * centered on the pathable's location. */ + public static final byte CENTER_ON_PATHABLE = 0; + + /** The code for the pathable following mode wherein we ensure that + * the marked pathable is always kept within the visible bounds of the + * view. */ + public static final byte ENCLOSE_PATHABLE = 1; + + /** The code for the pathable following mode wherein we set the upper-left + * corner of the view to the coordinates of the pathable. */ + public static final byte TRACK_PATHABLE = 2; + + /** + * Constructs a virtual media panel. + */ + public VirtualMediaPanel (FrameManager framemgr) + { + super(framemgr); + } + + /** + * Set a background image to tile the background of the media panel. + */ + public void setBackground (Mirage background) + { + _background = background; + } + + /** + * Sets the upper-left coordinate of the view port in virtual + * coordinates. The view will be as efficient as possible about + * repainting itself to achieve this new virtual location (meaning + * that if we need only to move one pixel to the left, it will use + * {@link Graphics#copyArea} to move our rendered view over one pixel + * and generate a dirty region for the exposed area). The new location + * will not take effect until the view is {@link #tick}ed, so only the + * last call to this method during a tick will have any effect. + */ + public void setViewLocation (int x, int y) + { + // make a note of our new x and y offsets + _nx = x; + _ny = y; + } + + /** + * Returns the bounds of the viewport in virtual coordinates. The + * returned rectangle must not be modified. + */ + public Rectangle getViewBounds () + { + return _vbounds; + } + + /** + * Adds an entity that will be informed when the view scrolls. + */ + public void addViewTracker (ViewTracker tracker) + { + _trackers.add(tracker); + } + + /** + * Removes an entity from the view trackers list. + */ + public void removeViewTracker (ViewTracker tracker) + { + _trackers.remove(tracker); + } + /** + * Instructs the view to follow the supplied pathable; ensuring that + * the view's coordinates are adjusted according to the follow mode. + * + * @param pable the pathable to follow. + * @param followMode the strategy for keeping the pathable in view. + */ + public void setFollowsPathable (Pathable pable, byte followMode) + { + _fmode = followMode; + _fpath = pable; + trackPathable(); // immediately update our location + } + + /** + * Clears out the pathable that was being enclosed or followed due to + * a previous call to {@link #setFollowsPathable}. + */ + public void clearPathable () + { + _fpath = null; + _fmode = (byte) -1; + } + + /** + * We overload this to translate mouse events into the proper + * coordinates before they are dispatched to any of the mouse + * listeners. + */ + protected void processMouseEvent (MouseEvent event) + { + event.translatePoint(_vbounds.x, _vbounds.y); + super.processMouseEvent(event); + } + + /** + * We overload this to translate mouse events into the proper + * coordinates before they are dispatched to any of the mouse + * listeners. + */ + protected void processMouseMotionEvent (MouseEvent event) + { + event.translatePoint(_vbounds.x, _vbounds.y); + super.processMouseMotionEvent(event); + } + + /** + * We overload this to translate mouse events into the proper + * coordinates before they are dispatched to any of the mouse + * listeners. + */ + protected void processMouseWheelEvent (MouseWheelEvent event) + { + event.translatePoint(_vbounds.x, _vbounds.y); + super.processMouseWheelEvent(event); + } + + // documentation inherited + protected void dirtyScreenRect (Rectangle rect) + { + // translate the screen rect into happy coordinates + rect.translate(_vbounds.x, _vbounds.y); + _remgr.addDirtyRegion(rect); + } + + // documentation inherited + public void doLayout () + { + super.doLayout(); + + // we need to obtain our absolute screen coordinates to work + // around the Windows copyArea() bug + findRootBounds(); + } + + // documentation inherited + public void setBounds (int x, int y, int width, int height) + { + super.setBounds(x, y, width, height); + + // keep track of the size of the viewport + _vbounds.width = getWidth(); + _vbounds.height = getHeight(); + + // we need to obtain our absolute screen coordinates to work + // around the Windows copyArea() bug + findRootBounds(); + } + + /** + * Determines the absolute screen coordinates at which this panel is + * located and stores them for reference later when rendering. This + * is necessary in order to work around the Windows + * copyArea() bug. + */ + protected void findRootBounds () + { + _abounds.setLocation(0, 0); + FrameManager.getRoot(this, _abounds); + } + + // documentation inherited + protected void didTick (long tickStamp) + { + super.didTick(tickStamp); + + int width = getWidth(), height = getHeight(); + + // adjusts our view location to track any pathable we might be + // tracking + trackPathable(); + + // if we have a new target location, we'll need to generate dirty + // regions for the area exposed by the scrolling + if (_nx != _vbounds.x || _ny != _vbounds.y) { + // determine how far we'll be moving on this tick + int dx = _nx - _vbounds.x, dy = _ny - _vbounds.y; + +// Log.info("Scrolling into place [n=(" + _nx + ", " + _ny + +// "), t=(" + _vbounds.x + ", " + _vbounds.y + +// "), d=(" + dx + ", " + dy + +// "), width=" + width + ", height=" + height + "]."); + + + // Mac OS X's redraw breaks on scrolling, so we repaint the + // entire panel + if (RunAnywhere.isMacOS()) { + _remgr.invalidateRegion(_nx, _ny, width, height); + } else { + _dx = dx; + _dy = dy; + + // these are used to prevent the vertical strip from + // overlapping the horizontal strip + int sy = _ny, shei = height; + + // and add invalid rectangles for the exposed areas + if (dy > 0) { + shei = Math.max(shei - dy, 0); + _remgr.invalidateRegion(_nx, _ny + height - dy, width, dy); + } else if (dy < 0) { + sy -= dy; + _remgr.invalidateRegion(_nx, _ny, width, -dy); + } + if (dx > 0) { + _remgr.invalidateRegion(_nx + width - dx, sy, dx, shei); + } else if (dx < 0) { + _remgr.invalidateRegion(_nx, sy, -dx, shei); + } + } + + + // now go ahead and update our location so that changes in + // between here and the call to paint() for this tick don't + // booch everything + _vbounds.x = _nx; _vbounds.y = _ny; + + // let derived classes react if they so desire + viewLocationDidChange(dx, dy); + } + } + + /** + * Called during our tick when we have adjusted the view location. The + * {@link #_vbounds} will already have been updated to reflect our new + * view coordinates. + * + * @param dx the delta scrolled in the x direction (in pixels). + * @param dy the delta scrolled in the y direction (in pixels). + */ + protected void viewLocationDidChange (int dx, int dy) + { + if (_perfRect != null) { + Rectangle sdirty = new Rectangle(_perfRect); + sdirty.translate(-dx, -dy); + dirtyScreenRect(sdirty); + } + + // inform our view trackers + for (int ii = 0, ll = _trackers.size(); ii < ll; ii++) { + ((ViewTracker)_trackers.get(ii)).viewLocationDidChange(dx, dy); + } + + // let our sprites and animations know what's up + _animmgr.viewLocationDidChange(dx, dy); + _spritemgr.viewLocationDidChange(dx, dy); + } + + /** + * Implements the standard pathable tracking support. Derived classes + * may wish to override this if they desire custom tracking + * functionality. + */ + protected void trackPathable () + { + // if we're tracking a pathable, adjust our view coordinates + if (_fpath == null) { + return; + } + + int width = getWidth(), height = getHeight(); + int nx = _vbounds.x, ny = _vbounds.y; + + // figure out where to move + switch (_fmode) { + case TRACK_PATHABLE: + nx = _fpath.getX(); + ny = _fpath.getY(); + break; + + case CENTER_ON_PATHABLE: + nx = _fpath.getX() - width/2; + ny = _fpath.getY() - height/2; + break; + + case ENCLOSE_PATHABLE: + Rectangle bounds = _fpath.getBounds(); + if (nx > bounds.x) { + nx = bounds.x; + } else if (nx + width < bounds.x + bounds.width) { + nx = bounds.x + bounds.width - width; + } + if (ny > bounds.y) { + ny = bounds.y; + } else if (ny + height < bounds.y + bounds.height) { + ny = bounds.y + bounds.height - height; + } + break; + + default: + Log.warning("Eh? Set to invalid pathable mode " + + "[mode=" + _fmode + "]."); + break; + } + +// Log.info("Tracking pathable [mode=" + _fmode + +// ", pable=" + _fpath + ", nx=" + nx + ", ny=" + ny + "]."); + + setViewLocation(nx, ny); + } + + // documentation inherited + protected void paint (Graphics2D gfx, Rectangle[] dirty) + { + // if we're scrolling, go ahead and do the business + if (_dx != 0 || _dy != 0) { + int width = getWidth(), height = getHeight(); + int cx = (_dx > 0) ? _dx : 0; + int cy = (_dy > 0) ? _dy : 0; + + // set the clip to the bounds of the component (we can't + // assume the clip is anything sensible upon entry to paint() + // because the frame manager expects us to set our own clip) + gfx.setClip(0, 0, width, height); + + // on windows, attempting to call copyArea() on a translated + // graphics context results in boochness; so we have to + // untranslate the graphics context, do our copyArea() and + // then translate it back + if (RunAnywhere.isWindows()) { + gfx.translate(-_abounds.x, -_abounds.y); + gfx.copyArea(_abounds.x + cx, _abounds.y + cy, + width - Math.abs(_dx), + height - Math.abs(_dy), -_dx, -_dy); + gfx.translate(_abounds.x, _abounds.y); + } else if (RunAnywhere.isMacOS()) { + try { + gfx.copyArea(cx, cy, + width - Math.abs(_dx), + height - Math.abs(_dy), -_dx, -_dy); + } catch (Exception e) { + // HACK when it throws an exception trying to do the + // copy area, just repaint everything + dirty = new Rectangle[] { new Rectangle(_vbounds) }; + } + } else { + gfx.copyArea(cx, cy, + width - Math.abs(_dx), + height - Math.abs(_dy), -_dx, -_dy); + } + + // and clear out our scroll deltas + _dx = 0; _dy = 0; + } + + // translate into happy space + gfx.translate(-_vbounds.x, -_vbounds.y); + + // now do the actual painting + super.paint(gfx, dirty); + + // translate back out of happy space + gfx.translate(_vbounds.x, _vbounds.y); + } + + // documentation inherited + protected void constrainToBounds (Rectangle dirty) + { + SwingUtilities.computeIntersection( + _vbounds.x, _vbounds.y, getWidth(), getHeight(), dirty); + } + + // documentation inherited + protected void paintBehind (Graphics2D gfx, Rectangle dirtyRect) + { + // if we have a background image specified, tile it! + if (_background != null) { + // make sure it's aligned + int iw = _background.getWidth(); + int ih = _background.getHeight(); + int lowx = iw * MathUtil.floorDiv(dirtyRect.x, iw); + int lowy = ih * MathUtil.floorDiv(dirtyRect.y, ih); + ImageUtil.tileImage(gfx, _background, lowx, lowy, + dirtyRect.width + (dirtyRect.x - lowx), + dirtyRect.height + (dirtyRect.y - lowy)); + } + } + + /** Our viewport bounds in virtual coordinates. */ + protected Rectangle _vbounds = new Rectangle(); + + /** Our target offsets to be effected on the next tick. */ + protected int _nx, _ny; + + /** Our scroll offsets. */ + protected int _dx, _dy; + + /** Our tiling background image. */ + protected Mirage _background; + + /** The mode we're using when following a pathable. */ + protected byte _fmode = -1; + + /** The pathable being followed. */ + protected Pathable _fpath; + + /** We need to know our absolute coordinates in order to work around + * the Windows copyArea() bug. */ + protected Rectangle _abounds = new Rectangle(); + + /** A list of entities to be informed when the view scrolls. */ + protected ArrayList _trackers = new ArrayList(); +} diff --git a/src/java/com/threerings/media/VirtualRangeModel.java b/src/java/com/threerings/media/VirtualRangeModel.java new file mode 100644 index 00000000..fdc80c01 --- /dev/null +++ b/src/java/com/threerings/media/VirtualRangeModel.java @@ -0,0 +1,109 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.Rectangle; + +import javax.swing.BoundedRangeModel; +import javax.swing.DefaultBoundedRangeModel; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import com.threerings.media.util.MathUtil; + +/** + * Provides a {@link BoundedRangeModel} interface to a virtual media panel + * so that it can easily be wired up to scroll bars or other scrolling + * controls. + */ +public class VirtualRangeModel + implements ChangeListener +{ + /** + * Creates a virtual media panel range model that will interact with + * the supplied virtual media panel. + */ + public VirtualRangeModel (VirtualMediaPanel panel) + { + _panel = panel; + + // listen to our range models and scroll our badself + _hrange.addChangeListener(this); + _vrange.addChangeListener(this); + } + + /** + * Informs the virtual range model the extent of the area over which + * we can scroll. + */ + public void setScrollableArea (int x, int y, int width, int height) + { + Rectangle vb = _panel.getViewBounds(); + int hmax = x + width, vmax = y + height, value; + + if (width > vb.width) { + value = MathUtil.bound(x, _hrange.getValue(), hmax - vb.width); + _hrange.setRangeProperties(value, vb.width, x, hmax, false); + } else { + // Let's center it and lock it down. + int newx = x - (vb.width - width)/2; + _hrange.setRangeProperties(newx, 0, newx, newx, false); + } + if (height > vb.height) { + value = MathUtil.bound(y, _vrange.getValue(), vmax - vb.height); + _vrange.setRangeProperties(value, vb.height, y, vmax, false); + } else { + // Let's center it and lock it down. + int newy = y - (vb.height - height)/2; + _vrange.setRangeProperties(newy, 0, newy, newy, false); + } + } + + /** + * Returns a range model that controls the scrollability of the scene + * in the horizontal direction. + */ + public BoundedRangeModel getHorizModel () + { + return _hrange; + } + + /** + * Returns a range model that controls the scrollability of the scene + * in the vertical direction. + */ + public BoundedRangeModel getVertModel () + { + return _vrange; + } + + // documentation inherited from interface ChangeListener + public void stateChanged (ChangeEvent e) + { + _panel.setViewLocation(_hrange.getValue(), _vrange.getValue()); + } + + protected VirtualMediaPanel _panel; + protected BoundedRangeModel _hrange = new DefaultBoundedRangeModel(); + protected BoundedRangeModel _vrange = new DefaultBoundedRangeModel(); +} diff --git a/src/java/com/threerings/media/animation/Animation.java b/src/java/com/threerings/media/animation/Animation.java new file mode 100644 index 00000000..d0be45d5 --- /dev/null +++ b/src/java/com/threerings/media/animation/Animation.java @@ -0,0 +1,169 @@ +// +// $Id: Animation.java 3822 2006-01-27 03:28:04Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Rectangle; + +import com.samskivert.util.ObserverList; + +import com.threerings.media.AbstractMedia; + +/** + * The animation class is an abstract class that should be extended to + * provide animation functionality. It is generally used in conjunction + * with an {@link AnimationManager}. + */ +public abstract class Animation extends AbstractMedia +{ + /** + * Constructs an animation. + * + * @param bounds the animation rendering bounds. + */ + public Animation (Rectangle bounds) + { + super(bounds); + } + + /** + * Returns true if the animation has finished all of its business, + * false if not. + */ + public boolean isFinished () + { + return _finished; + } + + /** + * If this animation has run to completion, it can be reset to prepare + * it for another go. + */ + public void reset () + { + _finished = false; + } + + // documentation inherited + public void setLocation (int x, int y) + { + if (_bounds.x == x && _bounds.y == y) { + return; // no-op + } + + // start with our current bounds + Rectangle dirty = new Rectangle(_bounds); + + // move ourselves + super.setLocation(x, y); + + // grow the dirty rectangle to incorporate our new bounds and pass + // the dirty region to our region manager + if (_mgr != null) { + // if our new bounds intersect our old bounds, grow a single + // dirty rectangle to incorporate them both + if (_bounds.intersects(dirty)) { + dirty.add(_bounds); + } else { + // otherwise invalidate our new bounds separately + _mgr.getRegionManager().invalidateRegion(_bounds); + } + _mgr.getRegionManager().addDirtyRegion(dirty); + } + } + + // documentation inherited + protected void willStart (long tickStamp) + { + super.willStart(tickStamp); + queueNotification(new AnimStartedOp(this, tickStamp)); + } + + /** + * Called when the animation is finished and the animation manager is + * about to remove it from service. + */ + protected void willFinish (long tickStamp) + { + queueNotification(new AnimCompletedOp(this, tickStamp)); + } + + /** + * Called when the animation is finished and the animation manager has + * removed it from service. + */ + protected void didFinish (long tickStamp) + { + } + + /** + * Adds an animation observer to this animation's list of observers. + */ + public void addAnimationObserver (AnimationObserver obs) + { + addObserver(obs); + } + + /** + * Removes an animation observer from this animation's list of observers. + */ + public void removeAnimationObserver (AnimationObserver obs) + { + removeObserver(obs); + } + + /** Whether the animation is finished. */ + protected boolean _finished = false; + + /** Used to dispatch {@link AnimationObserver#animationStarted}. */ + protected static class AnimStartedOp implements ObserverList.ObserverOp + { + public AnimStartedOp (Animation anim, long when) { + _anim = anim; + _when = when; + } + + public boolean apply (Object observer) { + ((AnimationObserver)observer).animationStarted(_anim, _when); + return true; + } + + protected Animation _anim; + protected long _when; + } + + /** Used to dispatch {@link AnimationObserver#animationCompleted}. */ + protected static class AnimCompletedOp implements ObserverList.ObserverOp + { + public AnimCompletedOp (Animation anim, long when) { + _anim = anim; + _when = when; + } + + public boolean apply (Object observer) { + ((AnimationObserver)observer).animationCompleted(_anim, _when); + return true; + } + + protected Animation _anim; + protected long _when; + } +} diff --git a/src/java/com/threerings/media/animation/AnimationAdapter.java b/src/java/com/threerings/media/animation/AnimationAdapter.java new file mode 100644 index 00000000..1e1900d0 --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationAdapter.java @@ -0,0 +1,38 @@ +// +// $Id: AnimationAdapter.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +/** + * An adapter class for {@link AnimationObserver}. + */ +public class AnimationAdapter implements AnimationObserver +{ + // documentation inherited from interface + public void animationStarted (Animation anim, long when) + { + } + + // documentation inherited from interface + public void animationCompleted (Animation anim, long when) + { + } +} diff --git a/src/java/com/threerings/media/animation/AnimationArranger.java b/src/java/com/threerings/media/animation/AnimationArranger.java new file mode 100644 index 00000000..fafd0b4c --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationArranger.java @@ -0,0 +1,68 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Rectangle; + +import java.util.ArrayList; + +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.Log; + +/** + * A utility class for positioning animations such that they don't overlap, + * as best as possible. + */ +public class AnimationArranger +{ + /** + * Position the specified animation so that it is not overlapping + * any still-running animations previously passed to this method. + */ + public void positionAvoidAnimation (Animation anim, Rectangle viewBounds) + { + Rectangle abounds = new Rectangle(anim.getBounds()); + ArrayList avoidables = (ArrayList) _avoidAnims.clone(); + // if we are able to place it somewhere, do so + if (SwingUtil.positionRect(abounds, viewBounds, avoidables)) { + anim.setLocation(abounds.x, abounds.y); + } + + // add the animation to the list of avoidables + _avoidAnims.add(anim); + // keep an eye on it so that we can remove it when it's finished + anim.addAnimationObserver(_avoidAnimObs); + } + + /** The animations that other animations may wish to avoid. */ + protected ArrayList _avoidAnims = new ArrayList(); + + /** Automatically removes avoid animations when they're done. */ + protected AnimationAdapter _avoidAnimObs = new AnimationAdapter() { + public void animationCompleted (Animation anim, long when) { + if (!_avoidAnims.remove(anim)) { + Log.warning("Couldn't remove avoid animation?! " + anim + "."); + } + } + }; +} diff --git a/src/java/com/threerings/media/animation/AnimationFrameSequencer.java b/src/java/com/threerings/media/animation/AnimationFrameSequencer.java new file mode 100644 index 00000000..f2a55c25 --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationFrameSequencer.java @@ -0,0 +1,260 @@ +// +// $Id: AnimationFrameSequencer.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import com.samskivert.util.ObserverList; + +import com.threerings.media.util.FrameSequencer; +import com.threerings.media.util.MultiFrameImage; + +/** + * Used to control animation timing when displaying an animation. + */ +public interface AnimationFrameSequencer extends FrameSequencer +{ + /** + * Called after init to set the animation. + */ + public void setAnimation (Animation anim); + + /** + * A sequencer that can step through a series of frames in any order + * and speed and notify (via {@link SequencedAnimationObserver}) when + * specific frames are reached. + */ + public static class MultiFunction implements AnimationFrameSequencer + { + /** + * Creates the simplest multifunction frame sequencer. + * + * @param sequence the ordering to display the frames. + * @param msPerFrame the number of ms to display each frame. + * @param loop if false, the sequencer will report the end of + * the animation after progressing through all of the frames once, + * otherwise it will loop indefinitely. + */ + public MultiFunction (int[] sequence, long msPerFrame, boolean loop) + { + _length = sequence.length; + _sequence = sequence; + setDelay(msPerFrame); + _marks = new boolean[_length]; + _loop = loop; + } + + /** + * Creates a fully-specified multifunction frame sequencer. + * + * @param sequence the ordering to display the frames. + * @param msPerFrame the number of ms to display each frame. + * @param marks if true for a frame, a FrameReachedEvent will + * be generated when that frame is reached. + * @param loop if false, the sequencer will report the end of + * the animation after progressing through all of the frames once, + * otherwise it will loop indefinitely. + */ + public MultiFunction ( + int[] sequence, long[] msPerFrame, boolean[] marks, boolean loop) + { + _length = sequence.length; + if ((_length != msPerFrame.length) || (_length != marks.length)) { + throw new IllegalArgumentException( + "All MultiFunction FrameSequencer arrays must be " + + "the same length."); + } + + _sequence = sequence; + _delays = msPerFrame; + _marks = marks; + _loop = loop; + } + + /** + * Set the delay to use. + */ + public void setDelay (long msPerFrame) + { + _delays = null; + _delay = msPerFrame; + } + + /** + * Set the length of the sequence we are to use, or 0 means set + * it to the length of the sequence array that we were constructed with. + */ + public void setLength (int len) + { + _length = (len == 0) ? _sequence.length : len; + if (_curIdx >= _length) { + _curIdx = 0; + } + } + + /** + * Do we reset the animation on init? Default is true. + */ + public void setResetOnInit (boolean resets) + { + _resets = resets; + } + + // documentation inherited from interface + public void init (MultiFrameImage source) + { + int framecount = source.getFrameCount(); + // let's make sure our frames are valid + for (int ii=0; ii < _length; ii++) { + if (_sequence[ii] >= framecount) { + throw new IllegalArgumentException( + "MultiFunction FrameSequencer was initialized " + + "with a MultiFrameImage with not enough frames " + + "to match the sequence it was constructed with."); + } + } + + if (_resets) { + _lastStamp = 0L; + _curIdx = 0; + } + } + + // documentation inherited from interface + public void setAnimation (Animation anim) + { + _animation = anim; + } + + // documentation inherited from interface + public int tick (long tickStamp) + { + // obtain our starting timestamp if we don't already have one + if (_lastStamp == 0L) { + _lastStamp = tickStamp; + // we might need to notify on the first frame + checkNotify(tickStamp); + } + + // we may have rushed through more than one frame since the last + // tick, but we want to always notify even if we never displayed + long curdelay = getDelay(_curIdx); + while (tickStamp >= (_lastStamp + curdelay)) { + _lastStamp += curdelay; + _curIdx++; + if (_curIdx == _length) { + if (_loop) { + _curIdx = 0; + } else { + return -1; + } + } + checkNotify(tickStamp); + + // get the delay for checking the next frame + curdelay = getDelay(_curIdx); + } + + // return the right frame + return _sequence[_curIdx]; + } + + // documentation inherited from interface + public void fastForward (long timeDelta) + { + // this method should be called "unpause" + _lastStamp += timeDelta; + } + + /** + * Get the delay to use for the specified frame. + */ + protected final long getDelay (int index) + { + return (_delays == null) ? _delay : _delays[index]; + } + + /** + * Check to see if we need to notify that we've reached a marked frame. + */ + protected void checkNotify (long tickStamp) + { + if (_marks[_curIdx]) { + _animation.queueNotification( + new FrameReachedOp(_animation, tickStamp, + _sequence[_curIdx], _curIdx)); + } + } + + /** The current sequence index. */ + protected int _curIdx = 0; + + /** The length of our animation sequence. */ + protected int _length; + + /** Do we reset on init? */ + protected boolean _resets = true; + + /** The sequence of frames to display. */ + protected int[] _sequence; + + /** The corresponding delay for each frame, in ms. */ + protected long[] _delays; + + /** Or a single delay for all frames. */ + protected long _delay; + + /** Whether to send a FrameReachedEvent on a sequence index. */ + protected boolean[] _marks; + + /** Does the animation loop? */ + protected boolean _loop; + + /** The time at which we were last ticked. */ + protected long _lastStamp; + + /** The animation that we're sequencing for. */ + protected Animation _animation; + + /** Used to dispatch {@link SequencedAnimationObserver#frameReached}. */ + protected static class FrameReachedOp implements ObserverList.ObserverOp + { + public FrameReachedOp (Animation anim, long when, + int frameIdx, int frameSeq) { + _anim = anim; + _when = when; + _frameIdx = frameIdx; + _frameSeq = frameSeq; + } + + public boolean apply (Object observer) { + if (observer instanceof SequencedAnimationObserver) { + ((SequencedAnimationObserver)observer).frameReached( + _anim, _when, _frameIdx, _frameSeq); + } + return true; + } + + protected Animation _anim; + protected long _when; + protected int _frameIdx, _frameSeq; + } + } +} diff --git a/src/java/com/threerings/media/animation/AnimationManager.java b/src/java/com/threerings/media/animation/AnimationManager.java new file mode 100644 index 00000000..23a06607 --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationManager.java @@ -0,0 +1,81 @@ +// +// $Id: AnimationManager.java 3347 2005-02-14 03:00:58Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import com.threerings.media.AbstractMediaManager; +import com.threerings.media.MediaPanel; + +/** + * Manages a collection of animations, ticking them when the animation + * manager itself is ticked and generating events when animations finish + * and suchlike. + */ +public class AnimationManager extends AbstractMediaManager +{ + /** + * Construct and initialize the animation manager which readies itself + * to manage animations. + */ + public AnimationManager (MediaPanel panel) + { + super(panel); + } + + /** + * Registers the given {@link Animation} with the animation manager + * for ticking and painting. + */ + public void registerAnimation (Animation anim) + { + insertMedia(anim); + } + + /** + * Un-registers the given {@link Animation} from the animation + * manager. The bounds of the animation will automatically be + * invalidated so that they are properly rerendered in the absence of + * the animation. + */ + public void unregisterAnimation (Animation anim) + { + removeMedia(anim); + } + + // documentation inherited + protected void tickAllMedia (long tickStamp) + { + super.tickAllMedia(tickStamp); + + for (int ii = _media.size() - 1; ii >= 0; ii--) { + Animation anim = (Animation)_media.get(ii); + if (!anim.isFinished()) { + continue; + } + + // as the anim is finished, remove it and notify observers + anim.willFinish(tickStamp); + unregisterAnimation(anim); + anim.didFinish(tickStamp); + // Log.info("Removed finished animation " + anim + "."); + } + } +} diff --git a/src/java/com/threerings/media/animation/AnimationObserver.java b/src/java/com/threerings/media/animation/AnimationObserver.java new file mode 100644 index 00000000..a35ad11c --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationObserver.java @@ -0,0 +1,39 @@ +// +// $Id: AnimationObserver.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +/** + * An interface to be implemented by classes that would like to observe an + * {@link Animation} and be notified of interesting events relating to it. + */ +public interface AnimationObserver +{ + /** + * Called the first time this animation is ticked. + */ + public void animationStarted (Animation anim, long when); + + /** + * Called when the observed animation has completed. + */ + public void animationCompleted (Animation anim, long when); +} diff --git a/src/java/com/threerings/media/animation/AnimationSequencer.java b/src/java/com/threerings/media/animation/AnimationSequencer.java new file mode 100644 index 00000000..0bbdda69 --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationSequencer.java @@ -0,0 +1,295 @@ +// +// $Id: AnimationSequencer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import java.util.ArrayList; + +import com.samskivert.util.StringUtil; + +import com.threerings.media.Log; + +/** + * An animation that provides facilities for adding a sequence of + * animations that are fired after a fixed time interval has elapsed or + * after previous animations in the sequence have completed. Facilities + * are also provided for running code upon the completion of animations in + * the sequence. + */ +public class AnimationSequencer extends Animation +{ + /** + * Constructs an animation sequencer with the expectation that + * animations will be added via subsequent calls to {@link + * #addAnimation}. + * + * @param animmgr the animation manager to which to add our animations + * when they are ready to start. + */ + public AnimationSequencer (AnimationManager animmgr) + { + super(new Rectangle()); + _animmgr = animmgr; + } + + /** + * Adds the supplied animation to the sequence with the given + * parameters. Note that care should be taken if this is called after + * the animation sequence has begun firing animations. Do not add new + * animations after the final animation in the sequence has been + * started or you run the risk of attempting to add an animation to + * the sequence after it thinks that it has finished (in which case + * this method will fail). + * + * @param anim the animation to be sequenced, or null if the + * completion action should be run immediately when this "animation" + * is ready to fired. + * @param delta the number of milliseconds following the + * start of the previous animation in the queue that this + * animation should be started; 0 if it should be started + * simultaneously with its predecessor int the queue; -1 if it should + * be started when its predecessor has completed. + * @param completionAction a runnable to be executed when this + * animation completes. + */ + public void addAnimation ( + Animation anim, long delta, Runnable completionAction) + { + // sanity check + if (_finished) { + throw new IllegalStateException( + "Animation added to finished sequencer"); + } + + // if this guy is triggering on a previous animation, grab that + // good fellow here + AnimRecord trigger = null; + if (delta == -1) { + if (_queued.size() > 0) { + // if there are queued animations we want the most + // recently queued animation + trigger = (AnimRecord)_queued.get(_queued.size()-1); + } else if (_running.size() > 0) { + // otherwise, if there are running animations, we want the + // last one in that list + trigger = (AnimRecord)_running.get(_running.size()-1); + } + // otherwise we have no trigger, we'll just start ASAP + } + + AnimRecord arec = new AnimRecord( + anim, delta, trigger, completionAction); +// Log.info("Queued " + arec + "."); + _queued.add(arec); + } + + /** + * Clears out the animations being managed by this sequencer. + */ + public void clear () + { + _queued.clear(); + _lastStamp = 0; + } + + // documentation inherited + public void tick (long tickStamp) + { + if (_lastStamp == 0) { + _lastStamp = tickStamp; + } + + // add all animations whose time has come + while (_queued.size() > 0) { + AnimRecord arec = (AnimRecord)_queued.get(0); + if (!arec.readyToFire(tickStamp, _lastStamp)) { + // if it's not time to add this animation, all subsequent + // animations must surely wait as well + break; + } + + // remove it from queued and put it on the running list + _queued.remove(0); + _running.add(arec); + + // note that we've advanced to the next animation + _lastStamp = tickStamp; + + // fire in the hole! + arec.fire(tickStamp); + } + + // we're done when both lists are empty +// boolean finished = _finished; + _finished = ((_queued.size() + _running.size()) == 0); +// if (!finished && _finished) { +// Log.info("Finishing sequence at " + (tickStamp%10000) + "."); +// } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + // don't care + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _lastStamp += timeDelta; + } + + // documentation inherited + public void viewLocationDidChange (int dx, int dy) + { + super.viewLocationDidChange(dx, dy); + + // track cumulative view location changes so that we can adjust our + // animations before we start them + _vdx += dx; + _vdy += dy; + } + + /** + * Called when the time comes to start an animation. Derived classes + * may override this method and pass the animation on to their + * animation manager and do whatever else they need to do with + * operating animations. The default implementation simply adds them + * to the media panel supplied when we were constructed. + * + * @param anim the animation to be displayed. + * @param tickStamp the timestamp at which this animation was fired. + */ + protected void startAnimation (Animation anim, long tickStamp) + { + // account for any view scrolling that happened before this animation + // was actually added to the view + if (_vdx != 0 || _vdy != 0) { + anim.viewLocationDidChange(_vdx, _vdy); + } + + _animmgr.registerAnimation(anim); + } + + protected class AnimRecord extends AnimationAdapter + { + public AnimRecord (Animation anim, long delta, AnimRecord trigger, + Runnable completionAction) { + _anim = anim; + _delta = delta; + _trigger = trigger; + _completionAction = completionAction; + } + + public boolean readyToFire (long now, long lastStamp) + { + if (_delta == -1) { + // if we have no trigger, that means we should start + // immediately, otherwise we wait until our trigger is no + // longer running (they are guaranteed not to be still + // queued at this point because readyToFire is only called + // on an animation after all animations previous in the + // queue have been started) + return (_trigger == null) ? + true : !_running.contains(_trigger); + + } else { + return (lastStamp + _delta <= now); + } + } + + public void fire (long when) + { +// Log.info("Firing " + this + " at " + (when%10000) + "."); + + // if we have an animation, start it up and await its + // completion + if (_anim != null) { + startAnimation(_anim, when); + _anim.addAnimationObserver(this); + + } else { + // since there's no animation, we need to fire our + // completion routine immediately + fireCompletion(when); + } + } + + public void fireCompletion (long when) + { +// Log.info("Completing " + this + " at " + (when%10000) + "."); + + // call the completion action, if there is one + if (_completionAction != null) { + try { + _completionAction.run(); + } catch (Throwable t) { + Log.logStackTrace(t); + } + } + + // make a note that this animation is complete + _running.remove(this); + + // kids, don't try this at home; we call tick() immediately so + // that any animations triggered on the completion of previous + // animations can trigger on the completion of this animation + // rather than having to wait until the next tick to do so + tick(when); + } + + public void animationCompleted (Animation anim, long when) + { + fireCompletion(when); + } + + public String toString () + { + return "[anim=" + StringUtil.shortClassName(_anim) + + ((_anim == null) ? "" : ("/" + _anim.hashCode())) + + ", action=" + _completionAction + + ", delta=" + _delta + ", trig=" + (_trigger != null) + "]"; + } + + protected Animation _anim; + protected Runnable _completionAction; + protected long _delta; + protected AnimRecord _trigger; + } + + /** The animation manager in which we run animations. */ + protected AnimationManager _animmgr; + + /** Animations that have not been fired. */ + protected ArrayList _queued = new ArrayList(); + + /** Animations that are currently running. */ + protected ArrayList _running = new ArrayList(); + + /** The timestamp at which we fired the last animation. */ + protected long _lastStamp; + + /** Used to track view scrolling while animations are in limbo. */ + protected int _vdx, _vdy; +} diff --git a/src/java/com/threerings/media/animation/AnimationWaiter.java b/src/java/com/threerings/media/animation/AnimationWaiter.java new file mode 100644 index 00000000..f1dad948 --- /dev/null +++ b/src/java/com/threerings/media/animation/AnimationWaiter.java @@ -0,0 +1,95 @@ +// +// $Id: AnimationWaiter.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +/** + * An abstract class that simplifies a common animation usage case in + * which a number of animations are created and the creator would like to + * be able to perform specific actions when each animation has completed + * (see {@link #animationDidFinish} and/or when all animations are + * finished (see {@link #allAnimationsFinished}.) + */ +public abstract class AnimationWaiter + implements AnimationObserver +{ + /** + * Adds an animation to the animation waiter for observation. + */ + public void addAnimation (Animation anim) + { + anim.addAnimationObserver(this); + _animCount++; + } + + /** + * Adds the supplied animations to the animation waiter for + * observation. + */ + public void addAnimations (Animation[] anims) + { + int acount = anims.length; + for (int ii = 0; ii < acount; ii++) { + addAnimation(anims[ii]); + } + } + + // documentation inherited from interface + public void animationStarted (Animation anim, long when) + { + } + + // documentation inherited from interface + public void animationCompleted (Animation anim, long when) + { + // note that the animation is finished + animationDidFinish(anim); + _animCount--; + + // let derived classes know when all is done + if (_animCount == 0) { + allAnimationsFinished(); + } + } + + /** + * Called when an animation being observed by the waiter has + * completed its business. Derived classes may wish to override + * this method to engage in their unique antics. + */ + protected void animationDidFinish (Animation anim) + { + // nothing for now + } + + /** + * Called when all animations being observed by the waiter have + * completed their business. Derived classes may wish to override + * this method to engage in their unique antics. + */ + protected void allAnimationsFinished () + { + // nothing for now + } + + /** The number of animations. */ + protected int _animCount; +} diff --git a/src/java/com/threerings/media/animation/BlankAnimation.java b/src/java/com/threerings/media/animation/BlankAnimation.java new file mode 100644 index 00000000..db53fb28 --- /dev/null +++ b/src/java/com/threerings/media/animation/BlankAnimation.java @@ -0,0 +1,67 @@ +// +// $Id: BlankAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * Displays nothing, but does so for a specified amount of time. Useful + * when you want to get an animation completed event in some period of + * time but don't actually need to display anything. + */ +public class BlankAnimation extends Animation +{ + public BlankAnimation (long duration) + { + super(new Rectangle(0, 0, 0, 0)); + _duration = duration; + } + + // documentation inherited + public void tick (long timestamp) + { + if (_start == 0) { + // initialize our starting time + _start = timestamp; + } + + // check whether we're done + _finished = (timestamp - _start >= _duration); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + if (_start > 0) { + _start += timeDelta; + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + // nothing doing + } + + protected long _duration, _start; +} diff --git a/src/java/com/threerings/media/animation/BlendAnimation.java b/src/java/com/threerings/media/animation/BlendAnimation.java new file mode 100644 index 00000000..8ffc2bf5 --- /dev/null +++ b/src/java/com/threerings/media/animation/BlendAnimation.java @@ -0,0 +1,87 @@ +// +// $Id: BlendAnimation.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.image.Mirage; +import com.threerings.media.util.LinearTimeFunction; +import com.threerings.media.util.TimeFunction; + +/** + * Blends between a series of images using alpha. + */ +public class BlendAnimation extends Animation +{ + /** + * Blends from the starting image through each successive image in the + * specified amount of time (blending between each image takes place + * in delay milliseconds). + */ + public BlendAnimation (int x, int y, Mirage[] images, int delay) + { + super(new Rectangle(x, y, images[0].getWidth(), images[0].getHeight())); + _images = images; + int fades = images.length-1; + _tfunc = new LinearTimeFunction(0, 100 * fades, delay * fades); + } + + // documentation inherited + public void tick (long timestamp) + { + // check to see if our blend level has changed + int level = _tfunc.getValue(timestamp); + if (level == _level) { + return; + } + // stop if we reach the end + if (level == 100*(_images.length-1)) { + _finished = true; + } + _level = level; + invalidate(); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _tfunc.fastForward(timeDelta); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + int index = _level / 100; + float alpha = 1f - (_level % 100) / 100f; + + Composite ocomp = gfx.getComposite(); + gfx.setComposite(AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, alpha)); + _images[index].paint(gfx, _bounds.x, _bounds.y); + if (index < _images.length-1) { + gfx.setComposite(AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, 1f-alpha)); + _images[index+1].paint(gfx, _bounds.x, _bounds.y); + } + gfx.setComposite(ocomp); + } + + /** The images between which we are blending. */ + protected Mirage[] _images; + + /** The time function we're using to time our blends. */ + protected TimeFunction _tfunc; + + /** Our current blend level and image index all wrapped into one. */ + protected int _level; + + /** The alpha composite used to render our current image. */ + protected AlphaComposite _currentComp; + + /** The alpha composite used to render our "next" image. */ + protected AlphaComposite _nextComp; +} diff --git a/src/java/com/threerings/media/animation/BobbleAnimation.java b/src/java/com/threerings/media/animation/BobbleAnimation.java new file mode 100644 index 00000000..29085fc1 --- /dev/null +++ b/src/java/com/threerings/media/animation/BobbleAnimation.java @@ -0,0 +1,120 @@ +// +// $Id: BobbleAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.samskivert.util.RandomUtil; +import com.threerings.media.image.Mirage; + +/** + * An animation that bobbles an image around within a specific horizontal + * and vertical pixel range for a given period of time. + */ +public class BobbleAnimation extends Animation +{ + /** + * Constructs a bobble animation. + * + * @param image the image to animate. + * @param sx the starting x-position. + * @param sy the starting y-position. + * @param rx the horizontal bobble range. + * @param ry the vertical bobble range. + * @param duration the time to animate in milliseconds. + */ + public BobbleAnimation ( + Mirage image, int sx, int sy, int rx, int ry, int duration) + { + super(new Rectangle(sx - rx, sy - ry, sx + image.getWidth() + rx, + sy + image.getHeight() + ry)); + + // save things off + _image = image; + _sx = sx; + _sy = sy; + _rx = rx; + _ry = ry; + + // calculate animation ending time + _duration = duration; + } + + // documentation inherited + public void tick (long tickStamp) + { + // grab our ending time on our first tick + if (_end == 0L) { + _end = tickStamp + _duration; + } + + _finished = (tickStamp >= _end); + invalidate(); + + // calculate the latest position + int dx = RandomUtil.getInt(_rx); + int dy = RandomUtil.getInt(_ry); + _x = (_sx + dx) * ((RandomUtil.getInt(2) == 0) ? -1 : 1); + _y = (_sy + dy) * ((RandomUtil.getInt(2) == 0) ? -1 : 1); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _end += timeDelta; + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + _image.paint(gfx, _x, _y); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + + buf.append(", x=").append(_x); + buf.append(", y=").append(_y); + buf.append(", rx=").append(_rx); + buf.append(", ry=").append(_ry); + buf.append(", sx=").append(_sx); + buf.append(", sy=").append(_sy); + } + + /** The current position of the image. */ + protected int _x, _y; + + /** The horizontal and vertical bobbling range. */ + protected int _rx, _ry; + + /** The starting position. */ + protected int _sx, _sy; + + /** The image to animate. */ + protected Mirage _image; + + /** Animation ending timing information. */ + protected long _duration, _end; +} diff --git a/src/java/com/threerings/media/animation/ExplodeAnimation.java b/src/java/com/threerings/media/animation/ExplodeAnimation.java new file mode 100644 index 00000000..a272b085 --- /dev/null +++ b/src/java/com/threerings/media/animation/ExplodeAnimation.java @@ -0,0 +1,336 @@ +// +// $Id: ExplodeAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; + +import com.samskivert.util.RandomUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.Mirage; + +/** + * An animation that displays an object exploding into chunks, fading out + * as they fly apart. The animation ends when all chunks have exited the + * animation bounds, or when the given delay time (if any is specified) + * has elapsed. + */ +public class ExplodeAnimation extends Animation +{ + /** + * A class that describes an explosion's attributes. + */ + public static class ExplodeInfo + { + /** The bounds within which to animate. */ + public Rectangle bounds; + + /** The number of image chunks on each axis. */ + public int xchunk, ychunk; + + /** The maximum chunk velocity on each axis in pixels per + * millisecond. */ + public float xvel, yvel; + + /** The y-axis chunk acceleration in pixels per millisecond. */ + public float yacc; + + /** The chunk rotational velocity in rotations per millisecond. */ + public float rvel; + + /** The animation length in milliseconds, or -1 if the animation + * should continue until all pieces are outside the bounds. */ + public long delay; + + /** Returns a string representation of this instance. */ + public String toString () + { + return StringUtil.fieldsToString(this); + } + } + + /** + * Constructs an explode animation with the chunks represented as + * filled rectangles of the specified color. + * + * @param color the color to render the chunks in. + * @param info the explode info object. + * @param x the x-position of the object. + * @param y the y-position of the object. + * @param width the width of the object. + * @param height the height of the object. + */ + public ExplodeAnimation ( + Color color, ExplodeInfo info, int x, int y, int width, int height) + { + super(info.bounds); + + _color = color; + init(info, x, y, width, height); + } + + /** + * Constructs an explode animation with the chunks represented as + * portions of the actual image. + * + * @param image the image to animate. + * @param info the explode info object. + * @param x the x-position of the object. + * @param y the y-position of the object. + * @param width the width of the object. + * @param height the height of the object. + */ + public ExplodeAnimation ( + Mirage image, ExplodeInfo info, int x, int y, int width, int height) + { + super(info.bounds); + + _image = image; + init(info, x, y, width, height); + } + + /** + * Initializes the animation with the attributes of the given explode + * info object. + */ + protected void init (ExplodeInfo info, int x, int y, int width, int height) + { + _info = info; + _ox = x; + _oy = y; + _owid = width; + _ohei = height; + + _info.rvel = (float)((2.0f * Math.PI) * _info.rvel); + _chunkcount = (_info.xchunk * _info.ychunk); + _cxpos = new int[_chunkcount]; + _cypos = new int[_chunkcount]; + _sxvel = new float[_chunkcount]; + _syvel = new float[_chunkcount]; + + // determine chunk dimensions + _cwid = _owid / _info.xchunk; + _chei = _ohei / _info.ychunk; + _hcwid = _cwid / 2; + _hchei = _chei / 2; + + // initialize all chunks + for (int ii = 0; ii < _chunkcount; ii++) { + // initialize chunk position + int xpos = ii % _info.xchunk; + int ypos = ii / _info.xchunk; + _cxpos[ii] = _ox + (xpos * _cwid); + _cypos[ii] = _oy + (ypos * _chei); + + // initialize chunk velocity + _sxvel[ii] = RandomUtil.getFloat(_info.xvel) * + ((xpos < (_info.xchunk / 2)) ? -1.0f : 1.0f); + _syvel[ii] = -(RandomUtil.getFloat(_info.yvel)); + } + + // initialize the chunk rotation angle + _angle = 0.0f; + } + + // documentation inherited + public void fastForward (long timeDelta) + { + if (_start > 0) { + _start += timeDelta; + _end += timeDelta; + } + } + + // documentation inherited + public void tick (long timestamp) + { + if (_start == 0) { + // initialize our starting time + _start = timestamp; + if (_info.delay != -1) { + _end = _start + _info.delay; + } + } + + // figure out the distance the chunks have travelled + long msecs = timestamp - _start; + + if (_info.delay != -1) { + // calculate the alpha level with which to render the chunks + float pctdone = msecs / (float)_info.delay; + _alpha = Math.max(0.1f, Math.min(1.0f, 1.0f - pctdone)); + } + + // move all chunks and check whether any remain to be animated + int inside = 0; + for (int ii = 0; ii < _chunkcount; ii++) { + // determine the chunk travel distance + int xtrav = (int)(_sxvel[ii] * msecs); + int ytrav = (int) + ((_syvel[ii] * msecs) + (0.5f * _info.yacc * (msecs * msecs))); + + // determine the chunk movement direction + int xpos = ii % _info.xchunk; + int ypos = ii / _info.xchunk; + + // update the chunk position + _cxpos[ii] = _ox + (xpos * _cwid) + xtrav; + _cypos[ii] = _oy + (ypos * _chei) + ytrav; + + // note whether this chunk is still within our bounds + _wrect.setBounds(_cxpos[ii], _cypos[ii], _cwid, _chei); + if (_bounds.intersects(_wrect)) { + inside++; + } + } + + // increment the rotation angle + _angle += _info.rvel; + + // note whether we're finished + _finished = (inside == 0) || (_info.delay != -1 && timestamp >= _end); + + // dirty ourselves + invalidate(); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + Shape oclip = gfx.getClip(); + Composite ocomp = null; + + if (_info.delay != -1) { + // set the alpha composite to reflect the current fade-out + ocomp = gfx.getComposite(); + gfx.setComposite( + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha)); + } + + for (int ii = 0; ii < _chunkcount; ii++) { + // get the chunk position within the image + int xpos = ii % _info.xchunk; + int ypos = ii / _info.xchunk; + + // calculate image chunk offset + int xoff = -(xpos * _cwid); + int yoff = -(ypos * _chei); + + // translate the origin to center on the chunk + int tx = _cxpos[ii] + _hcwid, ty = _cypos[ii] + _hchei; + gfx.translate(tx, ty); + + // set up the desired rotation + gfx.rotate(_angle); + + if (_image != null) { + // draw the image chunk + gfx.clipRect(-_hcwid, -_hchei, _cwid, _chei); + _image.paint(gfx, -_hcwid + xoff, -_hchei + yoff); + + } else { + // draw the color chunk + gfx.setColor(_color); + gfx.fillRect(-_hcwid, -_hchei, _cwid, _chei); + } + + // restore the original transform and clip + gfx.rotate(-_angle); + gfx.translate(-tx, -ty); + gfx.setClip(oclip); + } + + if (_info.delay != -1) { + // restore the original composite + gfx.setComposite(ocomp); + } + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + + buf.append(", ox=").append(_ox); + buf.append(", oy=").append(_oy); + buf.append(", cwid=").append(_cwid); + buf.append(", chei=").append(_chei); + buf.append(", hcwid=").append(_hcwid); + buf.append(", hchei=").append(_hchei); + buf.append(", chunkcount=").append(_chunkcount); + buf.append(", info=").append(_info); + } + + /** The current chunk rotation. */ + protected float _angle; + + /** The starting x-axis velocity of each chunk. */ + protected float[] _sxvel; + + /** The starting y-axis velocity of each chunk. */ + protected float[] _syvel; + + /** The current x-axis position of each chunk. */ + protected int[] _cxpos; + + /** The current y-axis position of each chunk. */ + protected int[] _cypos; + + /** The individual chunk dimensions in pixels. */ + protected int _cwid, _chei; + + /** The individual chunk dimensions in pixels, halved for handy use in + * repeated calculations. */ + protected int _hcwid, _hchei; + + /** The total number of image chunks. */ + protected int _chunkcount; + + /** The explode info. */ + protected ExplodeInfo _info; + + /** The exploding object position and dimensions. */ + protected int _ox, _oy, _owid, _ohei; + + /** The color to render the object chunks in if we're using a color. */ + protected Color _color; + + /** The image to animate if we're using an image. */ + protected Mirage _image; + + /** The starting animation time. */ + protected long _start; + + /** The ending animation time. */ + protected long _end; + + /** The percent alpha with which to render the chunks. */ + protected float _alpha; + + /** A reusable working rectangle. */ + protected Rectangle _wrect = new Rectangle(); +} diff --git a/src/java/com/threerings/media/animation/FadeAnimation.java b/src/java/com/threerings/media/animation/FadeAnimation.java new file mode 100644 index 00000000..5c0c7309 --- /dev/null +++ b/src/java/com/threerings/media/animation/FadeAnimation.java @@ -0,0 +1,85 @@ +// +// $Id: FadeAnimation.java 3427 2005-03-24 04:50:52Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.Log; +import com.threerings.media.effects.FadeEffect; + +/** + * An animation that displays an image fading from one alpha level to + * another in specified increments over time. The animation is finished + * when the specified target alpha is reached. + */ +public abstract class FadeAnimation extends Animation +{ + /** + * Constructs a fade animation. + * + * @param bounds our bounds. + * @param alpha the starting alpha. + * @param step the alpha amount to step by each millisecond. + * @param target the target alpha level. + */ + protected FadeAnimation ( + Rectangle bounds, float alpha, float step, float target) + { + super(bounds); + _effect = new FadeEffect(alpha, step, target); + } + + // documentation inherited + public void tick (long timestamp) + { + if (_effect.tick(timestamp)) { + _finished = _effect.finished(); + invalidate(); + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + _effect.beforePaint(gfx); + paintAnimation(gfx); + _effect.afterPaint(gfx); + } + + // documentation inherited + protected void willStart (long tickStamp) + { + super.willStart(tickStamp); + _effect.init(tickStamp); + } + + /** + * Here is where derived animations actually render their image. + */ + protected abstract void paintAnimation (Graphics2D gfx); + + /** This handles the main work of fading. */ + protected FadeEffect _effect; +} diff --git a/src/java/com/threerings/media/animation/FadeImageAnimation.java b/src/java/com/threerings/media/animation/FadeImageAnimation.java new file mode 100644 index 00000000..11814efb --- /dev/null +++ b/src/java/com/threerings/media/animation/FadeImageAnimation.java @@ -0,0 +1,52 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.image.Mirage; + +/** + * Fades an image in or out by varying the alpha level during rendering. + */ +public class FadeImageAnimation extends FadeAnimation +{ + /** + * Creates an image fading animation. + */ + public FadeImageAnimation (Mirage image, int x, int y, + float alpha, float step, float target) + { + super(new Rectangle(x, y, image.getWidth(), image.getHeight()), + alpha, step, target); + _image = image; + } + + // documentation inherited + protected void paintAnimation (Graphics2D gfx) + { + _image.paint(gfx, _bounds.x, _bounds.y); + } + + protected Mirage _image; +} diff --git a/src/java/com/threerings/media/animation/FadeLabelAnimation.java b/src/java/com/threerings/media/animation/FadeLabelAnimation.java new file mode 100644 index 00000000..68837883 --- /dev/null +++ b/src/java/com/threerings/media/animation/FadeLabelAnimation.java @@ -0,0 +1,99 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; + +import com.samskivert.swing.Label; +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.Log; + +/** + * Does something extraordinary. + */ +public class FadeLabelAnimation extends FadeAnimation +{ + /** + * Creates a label fading animation. + */ + public FadeLabelAnimation (Label label, int x, int y, + float alpha, float step, float target) + { + super(new Rectangle(x, y, 0, 0), alpha, step, target); + _label = label; + } + + /** + * Indicates that our label should be rendered with antialiased text. + */ + public void setAntiAliased (boolean antiAliased) + { + _antiAliased = antiAliased; + } + + // documentation inherited + protected void init () + { + super.init(); + + // if our label is not yet laid out, do the deed + if (!_label.isLaidOut()) { + Graphics2D gfx = (Graphics2D)_mgr.getMediaPanel().getGraphics(); + if (gfx != null) { + gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + _antiAliased ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + _label.layout(gfx); + gfx.dispose(); + } + } + + // size the bounds to fit our label + Dimension size = _label.getSize(); + _bounds.width = size.width; + _bounds.height = size.height; + } + + // documentation inherited + protected void paintAnimation (Graphics2D gfx) + { + Object ohints = null; + if (_antiAliased) { + ohints = SwingUtil.activateAntiAliasing(gfx); + } + _label.render(gfx, _bounds.x, _bounds.y); + if (_antiAliased) { + SwingUtil.restoreAntiAliasing(gfx, ohints); + } + } + + /** The label we are rendering. */ + protected Label _label; + + /** Whether or not to use anti-aliased rendering. */ + protected boolean _antiAliased; +} diff --git a/src/java/com/threerings/media/animation/FloatingTextAnimation.java b/src/java/com/threerings/media/animation/FloatingTextAnimation.java new file mode 100644 index 00000000..d0f25131 --- /dev/null +++ b/src/java/com/threerings/media/animation/FloatingTextAnimation.java @@ -0,0 +1,248 @@ +// +// $Id: FloatingTextAnimation.java 3212 2004-11-12 00:33:38Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.samskivert.swing.Label; + +public class FloatingTextAnimation extends Animation +{ + /** + * Constructs an animation for the given text centered at the given + * coordinates. + */ + public FloatingTextAnimation (Label label, int x, int y) + { + this(label, x, y, DEFAULT_FLOAT_PERIOD); + } + + /** + * Constructs an animation for the given text centered at the given + * coordinates. The animation will float up the screen for 30 pixels. + */ + public FloatingTextAnimation (Label label, int x, int y, long floatPeriod) + { + this(label, x, y, x, y - DELTA_Y, floatPeriod); + } + + /** + * Constructs an animation for the given text starting at the given + * coordinates and floating toward the specified coordinates. + */ + public FloatingTextAnimation (Label label, int sx, int sy, + int destx, int desty, long floatPeriod) + { + super(new Rectangle(sx, sy, label.getSize().width, + label.getSize().height)); + + // save things off + _label = label; + _startX = _x = sx; + _startY = _y = sy; + _destx = destx; + _desty = desty; + _floatPeriod = floatPeriod; + + // calculate our deltas + _dx = (destx - sx); + _dy = (desty - sy); + + // initialize our starting alpha + _alpha = 1.0f; + } + + /** + * Called to change the direction 180 degrees. + */ + public void flipDirection () + { + _dx = -_dx; + _dy = -_dy; + } + + /** + * Returns the label used to render this score animation. + */ + public Label getLabel () + { + return _label; + } + + // documentation inherited + public void setLocation (int x, int y) + { + super.setLocation(x, y); + + // update our destination coordinates + _destx += (x - _startX); + _desty += (y - _startY); + + // update our initial coordinates + _startX = _x = x; + _startY = _y = y; + + // recalculate our deltas + _dx = (_destx - x); + _dy = (_desty - y); + } + + /** + * Sets the duration of this score animation to the specified time in + * milliseconds. This should be called before the animation is added + * to the animation manager. + */ + public void setFloatPeriod (long floatPeriod) + { + _floatPeriod = floatPeriod; + } + + // documentation inherited + public void tick (long timestamp) + { + boolean invalid = false; + if (_start == 0) { + // initialize our starting time + _start = timestamp; + // we need to make sure to invalidate ourselves initially + invalid = true; + } + + long fadeDelay = _floatPeriod/2; + long fadePeriod = _floatPeriod - fadeDelay; + + // figure out the current alpha + long msecs = timestamp - _start; + float oalpha = _alpha; + if (msecs > fadeDelay) { + long rmsecs = msecs - fadeDelay; + _alpha = Math.max(1.0f - (rmsecs / (float)fadePeriod), 0.0f); + _alpha = Math.min(_alpha, 1.0f); + } + + // get the alpha composite + _comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha); + + // determine the new y-position of the score + float pctdone = (float)msecs / _floatPeriod; + int ox = _x, oy = _y; + _x = _startX + (int)(_dx * pctdone); + _y = _startY + (int)(_dy * pctdone); + + // only update our location and dirty ourselves if we actually + // moved or our alpha changed + if (ox != _x || oy != _y) { + // dirty our old location + invalidate(); + _bounds.setLocation(_x, _y); + invalid = true; + + } else if (oalpha != _alpha) { + invalid = true; + } + + if (invalid) { + // dirty our current location + invalidate(); + } + + // note whether we're done + _finished = (msecs >= _floatPeriod); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + if (_start > 0) { + _start += timeDelta; + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + Composite ocomp = gfx.getComposite(); + if (_comp != null) { + gfx.setComposite(_comp); + } + paintLabels(gfx, _x, _y); + gfx.setComposite(ocomp); + } + + /** + * Derived classes may wish to extend score animation and render more than + * just the standard single label. + * + * @param x the upper left coordinate of the animation. + * @param y the upper left coordinate of the animation. + */ + protected void paintLabels (Graphics2D gfx, int x, int y) + { + _label.render(gfx, x, y); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + + buf.append(", x=").append(_x); + buf.append(", y=").append(_y); + buf.append(", alpha=").append(_alpha); + } + + /** The starting animation time. */ + protected long _start; + + /** The label we're animating. */ + protected Label _label; + + /** The starting coordinates of the score. */ + protected int _startX, _startY; + + /** The current coordinates of the score. */ + protected int _x, _y; + + /** The destination coordinates towards which the animation travels. */ + protected int _destx, _desty; + + /** The distance to be traveled by the score animation. */ + protected int _dx, _dy; + + /** The duration for which we float up the screen. */ + protected long _floatPeriod; + + /** The current alpha level used to render the score. */ + protected float _alpha; + + /** The composite used to render the score. */ + protected Composite _comp; + + /** The time in milliseconds during which the score is visible. */ + protected static final long DEFAULT_FLOAT_PERIOD = 1500L; + + /** The total vertical distance the score travels. */ + protected static final int DELTA_Y = 30; +} diff --git a/src/java/com/threerings/media/animation/GleamAnimation.java b/src/java/com/threerings/media/animation/GleamAnimation.java new file mode 100644 index 00000000..30531248 --- /dev/null +++ b/src/java/com/threerings/media/animation/GleamAnimation.java @@ -0,0 +1,150 @@ +// +// $Id: GleamAnimation.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Transparency; + +import com.threerings.media.sprite.Sprite; +import com.threerings.media.sprite.SpriteManager; +import com.threerings.media.util.LinearTimeFunction; +import com.threerings.media.util.TimeFunction; + +/** + * Washes all non-transparent pixels in a sprite with a particular color + * (by compositing them with the solid color with progressively higher + * alpha values) and then back again. + */ +public class GleamAnimation extends Animation +{ + /** + * Creates a gleam animation with the supplied sprite. The sprite will + * be faded to the specified color and then back again. The sprite may + * be already added to the supplied sprite manager or not, but when + * the animation is complete, it will have been added. + * + * @param fadeIn if true, the sprite itself will be faded in as we + * fade up to the gleam color and the gleam color will fade out, + * leaving just the sprite imagery. + */ + public GleamAnimation (SpriteManager spmgr, Sprite sprite, Color color, + int upmillis, int downmillis, boolean fadeIn) + { + super(sprite.getBounds()); + _spmgr = spmgr; + _sprite = sprite; + _color = color; + _upfunc = new LinearTimeFunction(0, 750, upmillis); + _downfunc = new LinearTimeFunction(750, 0, downmillis); + _fadeIn = fadeIn; + } + + // documentation inherited + public void tick (long timestamp) + { + int alpha; + if (_upfunc != null) { + if ((alpha = _upfunc.getValue(timestamp)) == 750) { + _upfunc = null; + } + } else if (_downfunc != null) { + if ((alpha = _downfunc.getValue(timestamp)) == 0) { + _downfunc = null; + } + } else { + _finished = true; + _spmgr.addSprite(_sprite); + return; + } + + if (_alpha != alpha) { + _alpha = alpha; + invalidate(); + } + } + + // documentation inherited + public void fastForward (long timeDelta) + { + if (_upfunc != null) { + _upfunc.fastForward(timeDelta); + } else if (_downfunc != null) { + _downfunc.fastForward(timeDelta); + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + // TODO: recreate our off image if the sprite bounds changed; we + // also need to change the bounds of our animation which might + // require some jockeying (especially if we shrink) + if (_offimg == null) { + _offimg = gfx.getDeviceConfiguration().createCompatibleImage( + _bounds.width, _bounds.height, Transparency.TRANSLUCENT); + } + + // create a mask image with our sprite and the appropriate color + Graphics2D ogfx = (Graphics2D)_offimg.getGraphics(); + try { + ogfx.setColor(_color); + ogfx.fillRect(0, 0, _bounds.width, _bounds.height); + ogfx.setComposite(AlphaComposite.DstAtop); + ogfx.translate(-_sprite.getX(), -_sprite.getY()); + _sprite.paint(ogfx); + } finally { + ogfx.dispose(); + } + + Composite ocomp = null; + Composite ncomp = AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, _alpha/1000f); + + // if we're fading the sprite in on the way up, set our alpha + // composite before we render the sprite + if (_fadeIn && _upfunc != null) { + ocomp = gfx.getComposite(); + gfx.setComposite(ncomp); + } + + // next render the sprite + _sprite.paint(gfx); + + // if we're not fading in, we still need to alpha the white bits + if (ocomp == null) { + ocomp = gfx.getComposite(); + gfx.setComposite(ncomp); + } + + // now alpha composite our mask atop the sprite + gfx.drawImage(_offimg, _sprite.getX(), _sprite.getY(), null); + gfx.setComposite(ocomp); + } + + // documentation inherited + protected void willStart (long tickStamp) + { + super.willStart(tickStamp); + + // remove the sprite we're fiddling with from the manager; we'll + // add it back when we're done + if (_spmgr.isManaged(_sprite)) { + _spmgr.removeSprite(_sprite); + } + } + + protected SpriteManager _spmgr; + protected Sprite _sprite; + protected Color _color; + protected Image _offimg; + protected boolean _fadeIn; + + protected TimeFunction _upfunc; + protected TimeFunction _downfunc; + protected int _alpha = -1; +} diff --git a/src/java/com/threerings/media/animation/MultiFrameAnimation.java b/src/java/com/threerings/media/animation/MultiFrameAnimation.java new file mode 100644 index 00000000..98a48dfd --- /dev/null +++ b/src/java/com/threerings/media/animation/MultiFrameAnimation.java @@ -0,0 +1,134 @@ +// +// $Id: MultiFrameAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.util.FrameSequencer; +import com.threerings.media.util.MultiFrameImage; + +/** + * Animates a sequence of image frames in place with a particular frame + * rate. + */ +public class MultiFrameAnimation extends Animation +{ + /** + * Creates a multi-frame animation with the specified source image + * frames and the specified target frame rate (in frames per second). + * + * @param frames the source frames of the animation. + * @param fps the target number of frames per second. + * @param loop whether the animation should loop indefinitely or + * finish after one shot. + */ + public MultiFrameAnimation ( + MultiFrameImage frames, double fps, boolean loop) + { + this(frames, new FrameSequencer.ConstantRate(fps, loop)); + } + + /** + * Creates a multi-frame animation with the specified source image + * frames and the specified target frame rate (in frames per second). + */ + public MultiFrameAnimation (MultiFrameImage frames, FrameSequencer seeker) + { + // we'll set up our bounds via setLocation() and in reset() + super(new Rectangle()); + + _frames = frames; + _seeker = seeker; + + // reset ourselves to start things off + reset(); + } + + // documentation inherited + public Rectangle getBounds () + { + // fill in the bounds with our current animation frame's bounds + return _bounds; + } + + /** + * If this animation has run to completion, it can be reset to prepare + * it for another go. + */ + public void reset () + { + super.reset(); + + // set the frame number to -1 so that we don't ignore the + // transition to frame zero on the first call to tick() + _fidx = -1; + + // reset our frame sequencer + _seeker.init(_frames); + if (_seeker instanceof AnimationFrameSequencer) { + ((AnimationFrameSequencer) _seeker).setAnimation(this); + } + } + + // documentation inherited + public void tick (long tickStamp) + { + int fidx = _seeker.tick(tickStamp); + if (fidx == -1) { + _finished = true; + + } else if (fidx != _fidx) { + // update our frame index and bounds + setFrameIndex(fidx); + + // and have ourselves repainted + invalidate(); + } + } + + /** + * Sets the frame index and updates our dimensions. + */ + protected void setFrameIndex (int fidx) + { + _fidx = fidx; + _bounds.width = _frames.getWidth(_fidx); + _bounds.height = _frames.getHeight(_fidx); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + _frames.paintFrame(gfx, _fidx, _bounds.x, _bounds.y); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _seeker.fastForward(timeDelta); + } + + protected MultiFrameImage _frames; + protected FrameSequencer _seeker; + protected int _fidx; +} diff --git a/src/java/com/threerings/media/animation/RainAnimation.java b/src/java/com/threerings/media/animation/RainAnimation.java new file mode 100644 index 00000000..931600af --- /dev/null +++ b/src/java/com/threerings/media/animation/RainAnimation.java @@ -0,0 +1,134 @@ +// +// $Id: RainAnimation.java 4188 2006-06-13 18:03:48Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.samskivert.util.RandomUtil; + +/** + * An animation that displays raindrops spattering across an image. + */ +public class RainAnimation extends Animation +{ + /** + * Constructs a rain animation with reasonable defaults for the number + * of raindrops and their dimensions. + * + * @param bounds the bounding rectangle for the animation. + * @param duration the number of seconds the animation should last. + */ + public RainAnimation (Rectangle bounds, long duration) + { + super(bounds); + + init(duration, DEFAULT_COUNT, DEFAULT_WIDTH, DEFAULT_HEIGHT); + } + + /** + * Constructs a rain animation. + * + * @param bounds the bounding rectangle for the animation. + * @param duration the number of seconds the animation should last. + * @param count the number of raindrops to render in each frame. + * @param wid the width of a raindrop's bounding rectangle. + * @param hei the height of a raindrop's bounding rectangle. + */ + public RainAnimation ( + Rectangle bounds, long duration, int count, int wid, int hei) + { + super(bounds); + init(duration, count, wid, hei); + } + + protected void init (long duration, int count, int wid, int hei) + { + // save things off + _count = count; + _wid = wid; + _hei = hei; + + // create the raindrop array + _drops = new int[count]; + + // calculate ending time + _duration = duration; + } + + // documentation inherited + public void tick (long tickStamp) + { + // grab our ending time on our first tick + if (_end == 0L) { + _end = tickStamp + _duration; + } + + _finished = (tickStamp >= _end); + + // calculate the latest raindrop locations + for (int ii = 0; ii < _count; ii++) { + int x = RandomUtil.getInt(_bounds.width); + int y = RandomUtil.getInt(_bounds.height); + _drops[ii] = (x << 16 | y); + } + + invalidate(); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _end += timeDelta; + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + gfx.setColor(Color.white); + for (int ii = 0; ii < _count; ii++) { + int x = _drops[ii] >> 16; + int y = _drops[ii] & 0xFFFF; + gfx.drawLine(x, y, x + _wid, y + _hei); + } + } + + /** The number of raindrops. */ + protected static final int DEFAULT_COUNT = 300; + + /** The raindrop streak dimensions. */ + protected static final int DEFAULT_WIDTH = 13; + protected static final int DEFAULT_HEIGHT = 10; + + /** The number of raindrops. */ + protected int _count; + + /** The dimensions of each raindrop's bounding rectangle. */ + protected int _wid, _hei; + + /** The raindrop locations. */ + protected int[] _drops; + + /** Animation ending timing information. */ + protected long _duration, _end; +} diff --git a/src/java/com/threerings/media/animation/ScaleAnimation.java b/src/java/com/threerings/media/animation/ScaleAnimation.java new file mode 100644 index 00000000..bc612752 --- /dev/null +++ b/src/java/com/threerings/media/animation/ScaleAnimation.java @@ -0,0 +1,192 @@ +// +// $Id: ScaleAnimation.java 3123 2004-09-18 22:58:39Z mdb $ + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Image; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Transparency; + +import java.awt.image.BufferedImage; + +import com.threerings.media.image.Mirage; +import com.threerings.media.sprite.Sprite; +import com.threerings.media.sprite.SpriteManager; +import com.threerings.media.util.LinearTimeFunction; +import com.threerings.media.util.TimeFunction; + +/** + * Animates an image changing size about its center point. + */ +public class ScaleAnimation extends Animation +{ + /** + * Creates a scale animation with the supplied image. If the image's + * size would ever be 0 or less, it is not drawn. + * + * @param image The image to paint. + * + * @param center The screen coordinates of the pixel upon which the + * image's center should always be rendered. + * + * @param startScale The amount to scale the image when it is rendered + * at time 0. + * + * @param endScale The amount to scale the image at the final frame + * of animation. + * + * @param duration The time in milliseconds the anim takes to complete. + */ + public ScaleAnimation (Mirage image, Point center, + float startScale, float endScale, int duration) + { + super(getBounds(Math.max(startScale, endScale), center, image)); + + // Save inputted variables + _image = image; + _bufferedImage = _image.getSnapshot(); + _center = new Point(center); + _startScale = startScale; + _endScale = endScale; + _duration = duration; + + // Hack the LinearTimeFunction to use fixed point rationals + // + // FIXME: This class doesn't seem to be saving me a lot of + // work, since I have to repackage the outputs into floats + // anyway. Find some way to make the LinearTimeFunction do + // more of this work for us, or write a new class that does. + // Maybe IntLinearTimeFunction and FloatLinearTimeFunction + // classes would be useful. + _scaleFunc = new LinearTimeFunction(0, 10000, duration); + } + + /** + * Java wants the first call in a constructor to be super() + * if it exists at all, so we have to trick it with this function. + * + * Oh, and this function computes how big the bounding box needs + * to be to bound the inputted image scaled to the inputted size + * centered around the inputted center poitn. + */ + public static Rectangle getBounds (float scale, Point center, Mirage image) + { + Point size = getSize(scale, image); + Point corner = getCorner(center, size); + return new Rectangle(corner.x, corner.y, size.x, size.y); + } + + /** + * Compute the bounds to use to render the animation's image + * right now. + */ + public Rectangle getBounds () + { + return getBounds(_scale, _center, _image); + } + + /** Computes the width and height to which an image should be scaled. */ + public static Point getSize (float scale, Mirage image) + { + int width = Math.max(0, Math.round(image.getWidth() * scale)); + int height = Math.max(0, Math.round(image.getHeight() * scale)); + return new Point(width, height); + } + + /** + * Computes the upper left corner where the image should be drawn, + * given the center and dimensions to which the image should be scaled. + */ + public static Point getCorner (Point center, Point size) + { + return new Point(center.x - size.x/2, center.y - size.y/2); + } + + // documentation inherited + public void tick (long tickStamp) + { + // Compute the new scaling value + float weight = _scaleFunc.getValue(tickStamp) / 10000.0f; + float scale = ((1.0f - weight) * _startScale) + + (( weight) * _endScale); + + // Update the animation if the scaling changes + if (_scale != scale) + { + _scale = scale; + invalidate(); + } + + // Check if the animation completed + if (weight >= 1.0f) { + _finished = true; + } + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _scaleFunc.fastForward(timeDelta); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + // Compute the bounding box to render this image + Rectangle bounds = getBounds(); + + // Paint nothing if the image was scaled to nothing + if (bounds.width <= 0 || bounds.height <= 0) { + return; + } + + // Smooth out the image scaling + // + // FIXME: Should this be turned off when the painting is done? + gfx.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + // Paint the image scaled to this location + gfx.drawImage(_bufferedImage, + bounds.x, + bounds.y, + bounds.x + bounds.width, + bounds.y + bounds.height, + 0, + 0, + _bufferedImage.getWidth(), + _bufferedImage.getHeight(), + null); + } + + /** The image to scale. */ + protected Mirage _image; + + /** The image converted to a format Graphics2D likes, and cached. */ + protected BufferedImage _bufferedImage; + + /** The center pixel to render the image around. */ + protected Point _center; + + /** The amount of time the animation should last. */ + //XXX Is this needed? + protected long _duration; + + /** The amount to scale the image at the start of the animation. */ + protected float _startScale; + + /** The amount to scale the image at the end of the animation. */ + protected float _endScale; + + /** The current amount of scaling to render. */ + protected float _scale; + + /** Computes the image scaling to use at the specified time. */ + protected TimeFunction _scaleFunc; +} diff --git a/src/java/com/threerings/media/animation/SequencedAnimationObserver.java b/src/java/com/threerings/media/animation/SequencedAnimationObserver.java new file mode 100644 index 00000000..f0e38d84 --- /dev/null +++ b/src/java/com/threerings/media/animation/SequencedAnimationObserver.java @@ -0,0 +1,35 @@ +// +// $Id: SequencedAnimationObserver.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +/** + * Extends the animation observer interface with extra goodies. + */ +public interface SequencedAnimationObserver extends AnimationObserver +{ + /** + * Called when the observed animation -- previously configured with an + * {@link AnimationFrameSequencer} -- reached the specified frame. + */ + public void frameReached (Animation anim, long when, + int frameIdx, int frameSeq); +} diff --git a/src/java/com/threerings/media/animation/SparkAnimation.java b/src/java/com/threerings/media/animation/SparkAnimation.java new file mode 100644 index 00000000..9e6af1da --- /dev/null +++ b/src/java/com/threerings/media/animation/SparkAnimation.java @@ -0,0 +1,257 @@ +// +// $Id: SparkAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; + +import com.samskivert.util.RandomUtil; + +import com.threerings.media.animation.Animation; +import com.threerings.media.image.Mirage; + +import com.threerings.media.Log; + +/** + * Displays a set of spark images originating from a specified position + * and flying outward in random directions, fading out as they go, for a + * specified period of time. + */ +public class SparkAnimation extends Animation +{ + /** + * Constructs a spark animation with the supplied parameters. + * + * @param bounds the bounding rectangle for the animation. + * @param x the starting x-position for the sparks. + * @param y the starting y-position for the sparks. + * @param xjog the maximum X distance by which to "jog" the initial spark + * positions, or 0 if no jogging is desired. + * @param yjog the maximum Y distance by which to "jog" the initial spark + * positions, or 0 if no jogging is desired. + * @param minxvel the minimum starting x-velocity of the sparks. + * @param minyvel the minimum starting y-velocity of the sparks. + * @param maxxvel the maximum x-velocity of the sparks. + * @param maxyvel the maximum y-velocity of the sparks. + * @param xacc the x axis acceleration, or 0 if none is desired. + * @param yacc the y axis acceleration, or 0 if none is desired. + * @param images the spark images to be animated. + * @param delay the duration of the animation in milliseconds. + * @param fade do the fade thing + */ + public SparkAnimation (Rectangle bounds, int x, int y, int xjog, int yjog, + float minxvel, float minyvel, + float maxxvel, float maxyvel, + float xacc, float yacc, + Mirage[] images, long delay, boolean fade) + { + super(bounds); + + // save things off + _xacc = xacc; + _yacc = yacc; + _images = images; + _delay = delay; + _fade = fade; + + // initialize various things + _icount = images.length; + _ox = new int[_icount]; + _oy = new int[_icount]; + _xpos = new int[_icount]; + _ypos = new int[_icount]; + _sxvel = new float[_icount]; + _syvel = new float[_icount]; + + for (int ii = 0; ii < _icount; ii++) { + // initialize spark position + _ox[ii] = x + + ((xjog == 0) ? 0 : RandomUtil.getInt(xjog) * randomDirection()); + _oy[ii] = y + + ((yjog == 0) ? 0 : RandomUtil.getInt(yjog) * randomDirection()); + + // Choose random X and Y axis velocities between the inputted + // bounds + _sxvel[ii] = minxvel + RandomUtil.getFloat(1) * (maxxvel - minxvel); + _syvel[ii] = minyvel + RandomUtil.getFloat(1) * (maxyvel - minyvel); + + // If accelerationes were given, make the starting velocities + // move against that acceleration; otherwise pick directions + // at random + if (_xacc > 0) { + _sxvel[ii] = -_sxvel[ii]; + } else if (_xacc == 0) { + _sxvel[ii] *= randomDirection(); + } + if (_yacc > 0) { + _syvel[ii] = -_syvel[ii]; + } else if (_yacc == 0) { + _syvel[ii] *= randomDirection(); + } + } + + if (_fade) { + _alpha = 1.0f; + _comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha); + } + } + + /** + * Returns at random -1 for negative direction or +1 for positive. + */ + protected int randomDirection () + { + return (RandomUtil.getInt(2) == 0) ? -1 : 1; + } + + // documentation inherited + protected void willStart (long stamp) + { + super.willStart(stamp); + _start = stamp; + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _start += timeDelta; + } + + // documentation inherited + public void tick (long timestamp) + { + // figure out the distance the chunks have travelled + long msecs = Math.max(timestamp - _start, 0); + long msecsSq = msecs * msecs; + + // calculate the alpha level with which to render the chunks + if (_fade) { + float pctdone = msecs / (float)_delay; + _alpha = Math.max(0.1f, Math.min(1.0f, 1.0f - pctdone)); + _comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha); + } + + // assume all sparks have moved outside the bounds + boolean allOutside = true; + + // move all sparks and check whether any remain to be animated + for (int ii = 0; ii < _icount; ii++) { + // determine the travel distance + int xtrav = (int) + ((_sxvel[ii] * msecs) + (0.5f * _xacc * msecsSq)); + int ytrav = (int) + ((_syvel[ii] * msecs) + (0.5f * _yacc * msecsSq)); + + // update the position + _xpos[ii] = _ox[ii] + xtrav; + _ypos[ii] = _oy[ii] + ytrav; + + // check to see if any are still in. Stop looking + // when we find one + if (allOutside && _bounds.intersects(_xpos[ii], _ypos[ii], + _images[ii].getWidth(), _images[ii].getHeight())) { + allOutside = false; + } + } + + // note whether we're finished + _finished = allOutside || (msecs >= _delay); + + // dirty ourselves + // TODO: only do this if at least one spark actually moved + invalidate(); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + Shape oclip = gfx.getClip(); + gfx.clip(_bounds); + Composite ocomp = gfx.getComposite(); + + if (_fade) { + // set the alpha composite to reflect the current fade-out + gfx.setComposite(_comp); + } + + // draw all sparks + for (int ii = 0; ii < _icount; ii++) { + _images[ii].paint(gfx, _xpos[ii], _ypos[ii]); + } + + // restore the original gfx settings + gfx.setComposite(ocomp); + gfx.setClip(oclip); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + + buf.append(", ox=").append(_ox); + buf.append(", oy=").append(_oy); + buf.append(", alpha=").append(_alpha); + } + + /** The spark images we're animating. */ + protected Mirage[] _images; + + /** The number of images we're animating. */ + protected int _icount; + + /** The x axis acceleration in pixels per millisecond. */ + protected float _xacc; + + /** The y axis acceleration in pixels per millisecond. */ + protected float _yacc; + + /** The starting x-axis velocity of each chunk. */ + protected float[] _sxvel; + + /** The starting y-axis velocity of each chunk. */ + protected float[] _syvel; + + /** The starting 'jog' positions for each spark. */ + protected int[] _ox, _oy; + + /** The current positions of each spark. */ + protected int[] _xpos, _ypos; + + /** The starting animation time. */ + protected long _start; + + /** Whether or not we should fade the sparks out. */ + protected boolean _fade; + + /** The percent alpha with which to render the images. */ + protected float _alpha; + + /** The alpha composite with which to render the images. */ + protected AlphaComposite _comp; + + /** The duration of the spark animation in milliseconds. */ + protected long _delay; +} diff --git a/src/java/com/threerings/media/animation/SpriteAnimation.java b/src/java/com/threerings/media/animation/SpriteAnimation.java new file mode 100644 index 00000000..9e9a5e54 --- /dev/null +++ b/src/java/com/threerings/media/animation/SpriteAnimation.java @@ -0,0 +1,102 @@ +// +// $Id: SpriteAnimation.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.animation; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.sprite.Sprite; +import com.threerings.media.sprite.SpriteManager; +import com.threerings.media.sprite.PathObserver; +import com.threerings.media.util.Path; + +public class SpriteAnimation extends Animation + implements PathObserver +{ + /** + * Constructs a sprite animation for the given sprite. The first time + * the animation is ticked, the sprite will be added to the given + * sprite manager and started along the supplied path. + */ + public SpriteAnimation (SpriteManager spritemgr, Sprite sprite, Path path) + { + super(new Rectangle()); + + // save things off + _spritemgr = spritemgr; + _sprite = sprite; + _path = path; + + // set up our sprite business + _sprite.addSpriteObserver(this); + } + + /** + * Derived classes can override tick if they want to end the animation + * in some other way than the sprite completing a path. + */ + public void tick (long timestamp) + { + // start the sprite moving on its path on our first tick + if (_path != null) { + _spritemgr.addSprite(_sprite); + _sprite.move(_path); + _path = null; + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + // nothing for now + } + + // documentation inherited from interface + public void pathCancelled (Sprite sprite, Path path) + { + _finished = true; + } + + // documentation inherited from interface + public void pathCompleted (Sprite sprite, Path path, long when) + { + _finished = true; + } + + // documentation inherited + protected void didFinish (long tickStamp) + { + super.didFinish(tickStamp); + + _spritemgr.removeSprite(_sprite); + _sprite = null; + } + + /** The sprite associated with this animation. */ + protected Sprite _sprite; + + /** The sprite manager managing our sprite. */ + protected SpriteManager _spritemgr; + + /** The path along which we'll move our sprite. */ + protected Path _path; +} diff --git a/src/java/com/threerings/media/effects/FadeEffect.java b/src/java/com/threerings/media/effects/FadeEffect.java new file mode 100644 index 00000000..e475b4ef --- /dev/null +++ b/src/java/com/threerings/media/effects/FadeEffect.java @@ -0,0 +1,125 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.effects; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +/** + * Handles the math and timing of doing a fade effect in a sprite or animation. + */ +public class FadeEffect +{ + public FadeEffect (float alpha, float step, float target) + { + if ((step == 0f) || (alpha > target && step > 0f) || + (alpha < target && step < 0f)) { + throw new IllegalArgumentException("Step specified is illegal: " + + "Fade would never finish (start=" + alpha + ", step=" + step + + ", target=" + target + ")"); + } + + // save things off + _startAlpha = alpha; + _step = step; + _target = target; + + // create the initial composite + _alpha = Math.max(0f, Math.min(1f, _startAlpha)); + _comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha); + } + + public void init (long tickStamp) + { + _finished = false; + _initStamp = tickStamp; + } + + public boolean finished () + { + return _finished; + } + + public float getAlpha () + { + return _alpha; + } + + public boolean tick (long tickStamp) + { + // figure out the current alpha + long msecs = tickStamp - _initStamp; + float alpha = _startAlpha + (msecs * _step); + _finished = (_startAlpha < _target) ? (alpha >= _target) + : (alpha <= _target); + if (alpha < 0.0f) { + alpha = 0.0f; + } else if (alpha > 1.0f) { + alpha = 1.0f; + } + + if (_alpha != alpha) { + _alpha = alpha; + _comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _alpha); + return true; + } + + // return false, unless we're finished + return _finished; + } + + public void beforePaint (Graphics2D gfx) + { + _ocomp = gfx.getComposite(); + gfx.setComposite(_comp); + } + + public void afterPaint (Graphics2D gfx) + { + gfx.setComposite(_ocomp); + } + + /** The composite used to render the image with the current alpha. */ + protected Composite _comp; + + /** The composite in effect outside our faded render. */ + protected Composite _ocomp; + + /** The current alpha of the image. */ + protected float _alpha; + + /** The target alpha. */ + protected float _target; + + /** The alpha step per millisecond. */ + protected float _step; + + /** The starting alpha. */ + protected float _startAlpha; + + /** Time zero. */ + protected long _initStamp; + + /** True when we're finished. */ + protected boolean _finished; +} diff --git a/src/java/com/threerings/media/image/AWTImageCreator.java b/src/java/com/threerings/media/image/AWTImageCreator.java new file mode 100644 index 00000000..92cbfeb6 --- /dev/null +++ b/src/java/com/threerings/media/image/AWTImageCreator.java @@ -0,0 +1,71 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Component; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Transparency; +import java.awt.image.BufferedImage; + +/** + * If the user of the image manager services intends to create and display + * images using the AWT, they can use this image creator which will use the + * AWT to determine the optimal image format. + */ +public class AWTImageCreator + implements ImageManager.OptimalImageCreator +{ + /** + * Create an image creator that will rely on the AWT to determine the + * optimal image format. + * + * @param context if non-null, the graphics configuration will be obtained + * therefrom; otherwise {@link GraphicsDevice#getDefaultConfiguration} + * will be used. + */ + public AWTImageCreator (Component context) + { + // obtain our graphics configuration + if (context != null) { + _gc = context.getGraphicsConfiguration(); + } else { + _gc = ImageUtil.getDefGC(); + } + } + + // documentation inherited from interface ImageManager.OptimalImageCreator + public BufferedImage createImage (int width, int height, int trans) + { + // DEBUG: override transparency for the moment on all images + trans = Transparency.TRANSLUCENT; + if (_gc != null) { + return _gc.createCompatibleImage(width, height, trans); + } else { + // if we're running in headless mode, do everything in 24-bit + return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + } + } + + /** The graphics configuration for the default screen device. */ + protected GraphicsConfiguration _gc; +} diff --git a/src/java/com/threerings/media/image/BackedVolatileMirage.java b/src/java/com/threerings/media/image/BackedVolatileMirage.java new file mode 100644 index 00000000..233d3292 --- /dev/null +++ b/src/java/com/threerings/media/image/BackedVolatileMirage.java @@ -0,0 +1,82 @@ +// +// $Id: BackedVolatileMirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.threerings.media.Log; + +/** + * Provides a volatile mirage that is backed by a buffered image that is + * not obtained from the image manager but is instead provided at + * construct time and completely circumvents the image manager's cache. As + * such, this should not be used unless you know what you're doing. + */ +public class BackedVolatileMirage extends VolatileMirage +{ + /** + * Creates a mirage with the supplied regeneration informoation and + * prepared image. + */ + public BackedVolatileMirage (ImageManager imgr, BufferedImage source) + { + super(imgr, new Rectangle(0, 0, source.getWidth(), source.getHeight())); + _source = source; + + // create our volatile image for the first time + createVolatileImage(); + } + + // documentation inherited + protected int getTransparency () + { + return _source.getColorModel().getTransparency(); + } + + // documentation inherited + protected void refreshVolatileImage () + { + Graphics gfx = null; + try { + gfx = _image.getGraphics(); + gfx.drawImage(_source, -_bounds.x, -_bounds.y, null); + + } catch (Exception e) { + Log.warning("Failure refreshing mirage " + this + "."); + Log.logStackTrace(e); + + } finally { + gfx.dispose(); + } + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", src=").append(_source); + } + + protected BufferedImage _source; +} diff --git a/src/java/com/threerings/media/image/BlankMirage.java b/src/java/com/threerings/media/image/BlankMirage.java new file mode 100644 index 00000000..a75d4ef3 --- /dev/null +++ b/src/java/com/threerings/media/image/BlankMirage.java @@ -0,0 +1,77 @@ +// +// $Id: BlankMirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/** + * A mirage implementation that contains no image data. Generally only + * useful for testing. + */ +public class BlankMirage implements Mirage +{ + public BlankMirage (int width, int height) + { + _width = width; + _height = height; + } + + // documentation inherited from interface + public void paint (Graphics2D gfx, int x, int y) + { + // nothing doing + } + + // documentation inherited from interface + public int getWidth () + { + return _width; + } + + // documentation inherited from interface + public int getHeight () + { + return _height; + } + + // documentation inherited from interface + public boolean hitTest (int x, int y) + { + return false; + } + + // documentation inherited from interface + public long getEstimatedMemoryUsage () + { + return 0; + } + + // documentation inherited from interface + public BufferedImage getSnapshot () + { + return null; + } + + protected int _width; + protected int _height; +} diff --git a/src/java/com/threerings/media/image/BufferedMirage.java b/src/java/com/threerings/media/image/BufferedMirage.java new file mode 100644 index 00000000..0420f233 --- /dev/null +++ b/src/java/com/threerings/media/image/BufferedMirage.java @@ -0,0 +1,74 @@ +// +// $Id: BufferedMirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/** + * A simple mirage implementation that uses a buffered image. + */ +public class BufferedMirage implements Mirage +{ + public BufferedMirage (BufferedImage image) + { + _image = image; + } + + // documentation inherited from interface + public void paint (Graphics2D gfx, int x, int y) + { + gfx.drawImage(_image, x, y, null); + } + + // documentation inherited from interface + public int getWidth () + { + return _image.getWidth(); + } + + // documentation inherited from interface + public int getHeight () + { + return _image.getHeight(); + } + + // documentation inherited from interface + public boolean hitTest (int x, int y) + { + return ImageUtil.hitTest(_image, x, y); + } + + // documentation inherited from interface + public long getEstimatedMemoryUsage () + { + return ImageUtil.getEstimatedMemoryUsage(_image.getRaster()); + } + + // documentation inherited from interface + public BufferedImage getSnapshot () + { + return _image; + } + + protected BufferedImage _image; +} diff --git a/src/java/com/threerings/media/image/CachedVolatileMirage.java b/src/java/com/threerings/media/image/CachedVolatileMirage.java new file mode 100644 index 00000000..7725080c --- /dev/null +++ b/src/java/com/threerings/media/image/CachedVolatileMirage.java @@ -0,0 +1,104 @@ +// +// $Id: CachedVolatileMirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Transparency; +import java.awt.image.BufferedImage; + +import com.threerings.media.Log; + +/** + * A mirage implementation which allows the image to be maintained in + * video memory and refetched from the image manager in the event that our + * target screen resolution changes or we are flushed from video memory + * for some other reason. + * + *

These objects are never created directly, but always obtained from + * the {@link ImageManager}. + */ +public class CachedVolatileMirage extends VolatileMirage +{ + /** + * Creates a mirage with the supplied regeneration informoation and + * prepared image. + */ + protected CachedVolatileMirage ( + ImageManager imgr, ImageManager.ImageKey source, + Rectangle bounds, Colorization[] zations) + { + super(imgr, bounds); + + _source = source; + _zations = zations; + + // create our volatile image for the first time + createVolatileImage(); + } + + // documentation inherited + protected int getTransparency () + { + BufferedImage source = _imgr.getImage(_source, _zations); + return (source == null) ? Transparency.OPAQUE : + source.getColorModel().getTransparency(); + } + + // documentation inherited + protected void refreshVolatileImage () + { + Graphics gfx = null; + try { + BufferedImage source = _imgr.getImage(_source, _zations); + if (source != null) { + gfx = _image.getGraphics(); + gfx.drawImage(source, -_bounds.x, -_bounds.y, null); + } + + } catch (Exception e) { + Log.warning("Failure refreshing mirage " + this + "."); + Log.logStackTrace(e); + + } finally { + if (gfx != null) { + gfx.dispose(); + } + } + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", key=").append(_source); + buf.append(", zations=").append(_zations); + } + + /** The key that identifies the image data used to create our volatile + * image. */ + protected ImageManager.ImageKey _source; + + /** Optional colorizations that are applied to our source image when + * creating our mirage. */ + protected Colorization[] _zations; +} diff --git a/src/java/com/threerings/media/image/ColorPository.java b/src/java/com/threerings/media/image/ColorPository.java new file mode 100644 index 00000000..210401bb --- /dev/null +++ b/src/java/com/threerings/media/image/ColorPository.java @@ -0,0 +1,461 @@ +// +// $Id: ColorPository.java 4188 2006-06-13 18:03:48Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Iterator; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import java.text.ParseException; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.RandomUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.media.Log; +import com.threerings.resource.ResourceManager; +import com.threerings.util.CompiledConfig; + +/** + * A repository of image recoloration information. It was called the + * recolor repository but the re-s cancelled one another out. + */ +public class ColorPository implements Serializable +{ + /** + * Used to store information on a class of colors. These are public to + * simplify the XML parsing process, so pay them no mind. + */ + public static class ClassRecord implements Serializable + { + /** An integer identifier for this class. */ + public int classId; + + /** The name of the color class. */ + public String name; + + /** The source color to use when recoloring colors in this class. */ + public Color source; + + /** Data identifying the range of colors around the source color + * that will be recolored when recoloring using this class. */ + public float[] range; + + /** The default starting legality value for this color class. See + * {@link ColorRecord#starter}. */ + public boolean starter; + + /** The default colorId to use for recoloration in this class, or + * 0 if there is no default defined. */ + public int defaultId; + + /** A table of target colors included in this class. */ + public HashIntMap colors = new HashIntMap(); + + /** Used when parsing the color definitions. */ + public void addColor (ColorRecord record) + { + // validate the color id + if (record.colorId > 255) { + Log.warning("Refusing to add color record; colorId > 255 " + + "[class=" + this + ", record=" + record + "]."); + } else { + record.cclass = this; + colors.put(record.colorId, record); + } + } + + /** + * Translants a color identified in string form into the id that + * should be used to look up its information. Throws an + * exception if no color could be found that associates with + * that name. + * + * FIXME: This lookup could be sped up a lot with some cached + * data tables if it looked like this function would get called + * in time critical situations. + */ + public int getColorId (String name) + throws ParseException + { + // Check if the string is itself a number + try { + int id = Integer.parseInt(name); + if (colors.containsKey(id)) { + return id; + } + } catch (NumberFormatException e) { + // Guess it must be something else + } + + // Look for name matches among all colors + Iterator iter = colors.values().iterator(); + while (iter.hasNext()) { + ColorRecord color = (ColorRecord)iter.next(); + if (color.name.equalsIgnoreCase(name)) { + return color.colorId; + } + } + + // That input wasn't a color + throw new ParseException("No color named '" + name + "'", 0); + } + + /** Returns a random starting id from the entries in this + * class. */ + public ColorRecord randomStartingColor () + { + // figure out our starter ids if we haven't already + if (_starters == null) { + ArrayList list = new ArrayList(); + Iterator iter = colors.values().iterator(); + while (iter.hasNext()) { + ColorRecord color = (ColorRecord)iter.next(); + if (color.starter) { + list.add(color); + } + } + _starters = (ColorRecord[]) + list.toArray(new ColorRecord[list.size()]); + } + + // sanity check + if (_starters.length < 1) { + Log.warning("Requested random starting color from " + + "colorless component class " + this + "]."); + return null; + } + + // return a random entry from the array + return _starters[RandomUtil.getInt(_starters.length)]; + } + + /** + * Get the default ColorRecord defined for this color class, or + * null if none. + */ + public ColorRecord getDefault () + { + return (ColorRecord) colors.get(defaultId); + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + return "[id=" + classId + ", name=" + name + ", source=#" + + Integer.toString(source.getRGB() & 0xFFFFFF, 16) + + ", range=" + StringUtil.toString(range) + + ", starter=" + starter + ", colors=" + + StringUtil.toString(colors.values().iterator()) + "]"; + } + + protected transient ColorRecord[] _starters; + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } + + /** + * Used to store information on a particular color. These are public + * to simplify the XML parsing process, so pay them no mind. + */ + public static class ColorRecord implements Serializable + { + /** The colorization class to which we belong. */ + public ClassRecord cclass; + + /** A unique colorization identifier (used in fingerprints). */ + public int colorId; + + /** The name of the target color. */ + public String name; + + /** Data indicating the offset (in HSV color space) from the + * source color to recolor to this color. */ + public float[] offsets; + + /** Tags this color as a legal starting color or not. This is a + * shameful copout, placing application-specific functionality + * into a general purpose library class. */ + public boolean starter; + + /** + * Returns a value that is the composite of our class id and color + * id which can be used to identify a colorization record. This + * value will always be a positive integer that fits into 16 bits. + */ + public int getColorPrint () + { + return ((cclass.classId << 8) | colorId); + } + + /** + * Returns the data in this record configured as a colorization + * instance. + */ + public Colorization getColorization () + { +// if (_zation == null) { +// _zation = new Colorization(getColorPrint(), cclass.source, +// cclass.range, offsets); +// } +// return _zation; + return new Colorization(getColorPrint(), cclass.source, + cclass.range, offsets); + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + return "[id=" + colorId + ", name=" + name + + ", offsets=" + StringUtil.toString(offsets) + + ", starter=" + starter + "]"; + } + + /** Our data represented as a colorization. */ + protected transient Colorization _zation; + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } + + /** + * Returns an iterator over all color classes in this pository. + */ + public Iterator enumerateClasses () + { + return _classes.values().iterator(); + } + + /** + * Returns an array containing the records for the colors in the + * specified class. + */ + public ColorRecord[] enumerateColors (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + if (record == null) { + return null; + } + + // create the array + ColorRecord[] crecs = new ColorRecord[record.colors.size()]; + Iterator iter = record.colors.values().iterator(); + for (int i = 0; iter.hasNext(); i++) { + crecs[i] = ((ColorRecord)iter.next()); + } + return crecs; + } + + /** + * Returns an array containing the ids of the colors in the specified + * class. + */ + public int[] enumerateColorIds (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + if (record == null) { + return null; + } + + int[] cids = new int[record.colors.size()]; + Iterator crecs = record.colors.values().iterator(); + for (int i = 0; crecs.hasNext(); i++) { + cids[i] = ((ColorRecord)crecs.next()).colorId; + } + return cids; + } + + /** + * Returns true if the specified color is legal for use at character + * creation time. false is always returned for non-existent colors or + * classes. + */ + public boolean isLegalStartColor (int classId, int colorId) + { + ColorRecord color = getColorRecord(classId, colorId); + return (color == null) ? false : color.starter; + } + + /** + * Returns a random starting color from the specified color class. + */ + public ColorRecord getRandomStartingColor (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + return (record == null) ? null : record.randomStartingColor(); + } + + /** + * Looks up a colorization by id. + */ + public Colorization getColorization (int classId, int colorId) + { + ColorRecord color = getColorRecord(classId, colorId); + return (color == null) ? null : color.getColorization(); + } + + /** + * Looks up a colorization by color print. + */ + public Colorization getColorization (int colorPrint) + { + return getColorization(colorPrint >> 8, colorPrint & 0xFF); + } + + /** + * Looks up a colorization by name. + */ + public Colorization getColorization (String className, int colorId) + { + ClassRecord crec = getClassRecord(className); + if (crec != null) { + ColorRecord color = (ColorRecord)crec.colors.get(colorId); + if (color != null) { + return color.getColorization(); + } + } + return null; + } + + /** + * Loads up a colorization class by name and logs a warning if it + * doesn't exist. + */ + public ClassRecord getClassRecord (String className) + { + Iterator iter = _classes.values().iterator(); + while (iter.hasNext()) { + ClassRecord crec = (ClassRecord)iter.next(); + if (crec.name.equals(className)) { + return crec; + } + } + Log.warning("No such color class [class=" + className + "]."); + Thread.dumpStack(); + return null; + } + + /** + * Looks up the requested color record. + */ + public ColorRecord getColorRecord (int classId, int colorId) + { + ClassRecord record = (ClassRecord)_classes.get(classId); + if (record == null) { + // if they request color class zero, we assume they're just + // decoding a blank colorprint, otherwise we complain + if (classId != 0) { + Log.warning("Requested unknown color class " + + "[classId=" + classId + + ", colorId=" + colorId + "]."); + Thread.dumpStack(); + } + return null; + } + return (ColorRecord)record.colors.get(colorId); + } + + /** + * Adds a fully configured color class record to the pository. This is + * only called by the XML parsing code, so pay it no mind. + */ + public void addClass (ClassRecord record) + { + // validate the class id + if (record.classId > 255) { + Log.warning("Refusing to add class; classId > 255 " + record + "."); + } else { + _classes.put(record.classId, record); + } + } + + /** + * Loads up a serialized color pository from the supplied resource + * manager. + */ + public static ColorPository loadColorPository (ResourceManager rmgr) + { + try { + return loadColorPository(rmgr.getResource(CONFIG_PATH)); + } catch (IOException ioe) { + Log.warning("Failure loading color pository [path=" + CONFIG_PATH + + ", error=" + ioe + "]."); + return new ColorPository(); + } + } + + /** + * Loads up a serialized color pository from the supplied resource + * manager. + */ + public static ColorPository loadColorPository (InputStream source) + { + try { + return (ColorPository)CompiledConfig.loadConfig(source); + } catch (IOException ioe) { + Log.warning("Failure loading color pository: " + ioe + "."); + return new ColorPository(); + } + } + + /** + * Serializes and saves color pository to the supplied file. + */ + public static void saveColorPository (ColorPository posit, File root) + { + File path = new File(root, CONFIG_PATH); + try { + CompiledConfig.saveConfig(path, posit); + } catch (IOException ioe) { + Log.warning("Failure saving color pository " + + "[path=" + path + ", error=" + ioe + "]."); + } + } + + /** Our mapping from class names to class records. */ + protected HashIntMap _classes = new HashIntMap(); + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + + /** + * The path (relative to the resource directory) at which the + * serialized recolorization repository should be loaded and stored. + */ + protected static final String CONFIG_PATH = "config/media/colordefs.dat"; +} diff --git a/src/java/com/threerings/media/image/ColorUtil.java b/src/java/com/threerings/media/image/ColorUtil.java new file mode 100644 index 00000000..76f58813 --- /dev/null +++ b/src/java/com/threerings/media/image/ColorUtil.java @@ -0,0 +1,57 @@ +// +// $Id: ColorUtil.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Color; + +/** + * Utilities to manipulate colors. + */ +public class ColorUtil +{ + /** + * Blends the two supplied colors. + * + * @return a color halfway between the two colors. + */ + public static final Color blend (Color c1, Color c2) + { + return new Color((c1.getRed() + c2.getRed()) >> 1, + (c1.getGreen() + c2.getGreen()) >> 1, + (c1.getBlue() + c2.getBlue()) >> 1); + } + + /** + * Blends the two supplied colors, using the supplied percentage + * as the amount of the first color to use. + * + * @param firstperc The percentage of the first color to use, from 0.0f + * to 1.0f inclusive. + */ + public static final Color blend (Color c1, Color c2, float firstperc) + { + float p2 = 1.0f - firstperc; + return new Color((int) (c1.getRed() * firstperc + c2.getRed() * p2), + (int) (c1.getGreen() * firstperc + c2.getGreen() * p2), + (int) (c1.getBlue() * firstperc + c2.getBlue() * p2)); + } +} diff --git a/src/java/com/threerings/media/image/Colorization.java b/src/java/com/threerings/media/image/Colorization.java new file mode 100644 index 00000000..afc28072 --- /dev/null +++ b/src/java/com/threerings/media/image/Colorization.java @@ -0,0 +1,194 @@ +// +// $Id: Colorization.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Color; + +import com.samskivert.util.StringUtil; + +/** + * Used to support recoloring images. + */ +public class Colorization +{ + /** Every colorization must have a unique id that can be used to + * compare a particular colorization record with another. */ + public int colorizationId; + + /** The root color for the colorization. */ + public Color rootColor; + + /** The range around the root color that will be colorized (in + * delta-hue, delta-saturation, delta-value. */ + public float[] range; + + /** The adjustments to make to hue, saturation and value. */ + public float[] offsets; + + /** + * Constructs a colorization record with the specified identifier. + */ + public Colorization (int colorizationId, Color rootColor, + float[] range, float[] offsets) + { + this.colorizationId = colorizationId; + this.rootColor = rootColor; + this.range = range; + this.offsets = offsets; + + // compute our HSV and fixed HSV + _hsv = Color.RGBtoHSB(rootColor.getRed(), rootColor.getGreen(), + rootColor.getBlue(), null); + _fhsv = toFixedHSV(_hsv, null); + } + + /** + * Returns the root color adjusted by the colorization. + */ + public Color getColorizedRoot () + { + return new Color(recolorColor(_hsv)); + } + + /** + * Adjusts the supplied color by the offests in this colorization, + * taking the appropriate measures for hue (wrapping it around) and + * saturation and value (clipping). + * + * @return the RGB value of the recolored color. + */ + public int recolorColor (float[] hsv) + { + // for hue, we wrap around + float hue = hsv[0] + offsets[0]; + if (hue > 1.0) { + hue -= 1.0; + } + + // otherwise we clip + float sat = Math.min(Math.max(hsv[1] + offsets[1], 0), 1); + float val = Math.min(Math.max(hsv[2] + offsets[2], 0), 1); + + // convert back to RGB space + return Color.HSBtoRGB(hue, sat, val); + } + + /** + * Returns true if this colorization matches the supplied color, false + * otherwise. + * + * @param hsv the HSV values for the color in question. + * @param fhsv the HSV values converted to fixed point via {@link + * #toFixedHSV} for the color in question. + */ + public boolean matches (float[] hsv, int[] fhsv) + { + // check to see that this color is sufficiently "close" to the + // root color based on the supplied distance parameters + if (distance(fhsv[0], _fhsv[0], Short.MAX_VALUE) >= + range[0] * Short.MAX_VALUE) { + return false; + } + + // saturation and value don't wrap around like hue + if (Math.abs(_hsv[1] - hsv[1]) >= range[1] || + Math.abs(_hsv[2] - hsv[2]) >= range[2]) { + return false; + } + + return true; + } + + // documentation inherited + public int hashCode () + { + return colorizationId ^ rootColor.hashCode(); + } + + /** + * Compares this colorization to another based on id. + */ + public boolean equals (Object other) + { + if (other instanceof Colorization) { + return ((Colorization)other).colorizationId == colorizationId; + } else { + return false; + } + } + + /** + * Returns a string representation of this colorization. + */ + public String toString () + { + return String.valueOf(colorizationId); + } + + /** + * Returns a long string representation of this colorization. + */ + public String toVerboseString () + { + return StringUtil.fieldsToString(this); + } + + /** + * Converts floating point HSV values to a fixed point integer + * representation. + * + * @param hsv the HSV values to be converted. + * @param fhsv the destination array into which the fixed values will + * be stored. If this is null, a new array will be created of the + * appropriate length. + * + * @return the fhsv parameter if it was non-null or the + * newly created target array. + */ + public static int[] toFixedHSV (float[] hsv, int[] fhsv) + { + if (fhsv == null) { + fhsv = new int[hsv.length]; + } + for (int i = 0; i < hsv.length; i++) { + // fhsv[i] = (int)(hsv[i]*Integer.MAX_VALUE); + fhsv[i] = (int)(hsv[i]*Short.MAX_VALUE); + } + return fhsv; + } + + /** + * Returns the distance between the supplied to numbers modulo N. + */ + public static int distance (int a, int b, int N) + { + return (a > b) ? Math.min(a-b, b+N-a) : Math.min(b-a, a+N-b); + } + + /** Fixed HSV values for our root color; used when calculating + * recolorizations using this colorization. */ + protected int[] _fhsv; + + /** HSV values for our root color; used when calculating + * recolorizations using this colorization. */ + protected float[] _hsv; +} diff --git a/src/java/com/threerings/media/image/CompositeMirage.java b/src/java/com/threerings/media/image/CompositeMirage.java new file mode 100644 index 00000000..e1a18a16 --- /dev/null +++ b/src/java/com/threerings/media/image/CompositeMirage.java @@ -0,0 +1,96 @@ +package com.threerings.media.image; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class CompositeMirage implements Mirage +{ + public CompositeMirage (Mirage[] mirages) + { + _mirages = mirages; + } + + public CompositeMirage (Mirage mirage1, Mirage mirage2) + { + _mirages = new Mirage[]{mirage1, mirage2}; + } + + // documentation inherited from interface Mirage + public long getEstimatedMemoryUsage () + { + // Return the total memory of our component mirages. + long mem = 0; + for (Mirage m : _mirages) { + mem += m.getEstimatedMemoryUsage(); + } + + return mem; + } + + // documentation inherited from interface Mirage + public int getHeight () + { + // Return the maximal height of our component mirages. + int height = 0; + for (Mirage m : _mirages) { + height = Math.max(height, m.getHeight()); + } + + return height; + } + + // documentation inherited from interface Mirage + public int getWidth () + { + // Return the maximal width of our component mirages. + int width = 0; + for (Mirage m : _mirages) { + width = Math.max(width, m.getWidth()); + } + + return width; + } + + // documentation inheritd from interface Mirage + public BufferedImage getSnapshot () + { + BufferedImage img = new BufferedImage(getWidth(), getHeight(), + BufferedImage.TYPE_INT_ARGB); + Graphics2D gfx = img.createGraphics(); + + try { + for (Mirage m : _mirages) { + m.paint(gfx, 0, 0); + } + } finally { + gfx.dispose(); + } + + return img; + } + + // documentation inheritd from interface Mirage + public boolean hitTest (int x, int y) + { + // If it hits any of our mirages, it hits us. + for (Mirage m : _mirages) { + if (m.hitTest(x, y)) { + return true; + } + } + + return false; + } + + // documentation inheritd from interface Mirage + public void paint (Graphics2D gfx, int x, int y) + { + // Paint everyone. + for (Mirage m : _mirages) { + m.paint(gfx, x, y); + } + } + + /** All the component mirages we're made up of. */ + protected Mirage[] _mirages; +} diff --git a/src/java/com/threerings/media/image/FastImageIO.java b/src/java/com/threerings/media/image/FastImageIO.java new file mode 100644 index 00000000..fba2020b --- /dev/null +++ b/src/java/com/threerings/media/image/FastImageIO.java @@ -0,0 +1,174 @@ +// +// $Id: FastImageIO.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Point; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.IndexColorModel; +import java.awt.image.PixelInterleavedSampleModel; +import java.awt.image.WritableRaster; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; + +import java.nio.IntBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +/** + * Provides routines for writing and reading uncompressed 8-bit color + * mapped images in a manner that is extremely fast and generates a + * minimal amount of garbage during the loading process. + */ +public class FastImageIO +{ + /** A suffix for use when storing raw images in bundles or on the file + * system. */ + public static final String FILE_SUFFIX = ".raw"; + + /** + * Returns true if the supplied image is of a format that is supported + * by the fast image I/O services, false if not. + */ + public static boolean canWrite (BufferedImage image) + { + return (image.getColorModel() instanceof IndexColorModel) && + (image.getRaster().getDataBuffer() instanceof DataBufferByte); + } + + /** + * Writes the supplied image to the supplied output stream. + * + * @exception IOException thrown if an error occurs writing to the + * output stream. + */ + public static void write (BufferedImage image, OutputStream out) + throws IOException + { + DataOutputStream dout = new DataOutputStream(out); + + // write the image dimensions + int width = image.getWidth(), height = image.getHeight(); + dout.writeInt(width); + dout.writeInt(height); + + // write the color model information + IndexColorModel cmodel = (IndexColorModel)image.getColorModel(); + int tpixel = cmodel.getTransparentPixel(); + dout.writeInt(tpixel); + int msize = cmodel.getMapSize(); + int[] map = new int[msize]; + cmodel.getRGBs(map); + dout.writeInt(msize); + for (int ii = 0; ii < map.length; ii++) { + dout.writeInt(map[ii]); + } + + // write the raster data + DataBufferByte dbuf = (DataBufferByte)image.getRaster().getDataBuffer(); + byte[] data = dbuf.getData(); + if (data.length != width * height) { + String errmsg = "Raster data not same size as image! [" + + width + "x" + height + " != " + data.length + "]"; + throw new IllegalStateException(errmsg); + } + dout.write(data); + dout.flush(); + } + + /** + * Reads an image from the supplied file (which must contain an image + * previously written via a call to {@link #write}). + * + * @exception IOException thrown if an error occurs reading from the + * file. + */ + public static BufferedImage read (File file) + throws IOException + { + RandomAccessFile raf = new RandomAccessFile(file, "r"); + FileChannel fchan = raf.getChannel(); + + try { + MappedByteBuffer mbuf = fchan.map( + FileChannel.MapMode.READ_ONLY, 0, file.length()); + + // read in our integer fields + IntBuffer ibuf = mbuf.asIntBuffer(); + int width = ibuf.get(); + int height = ibuf.get(); + int tpixel = ibuf.get(); + int msize = ibuf.get(); + + if (width > Short.MAX_VALUE || width < 0 || + height > Short.MAX_VALUE || height < 0) { + throw new IOException("Bogus image size " + + width + "x" + height); + } + + IndexColorModel cmodel; + synchronized (_origin) { // any old object will do + // make sure our colormap array is big enough + if (_cmap == null || _cmap.length < msize) { + _cmap = new int[msize]; + } + // read in the data and create our colormap + ibuf.get(_cmap, 0, msize); + cmodel = new IndexColorModel( + 8, msize, _cmap, 0, DataBuffer.TYPE_BYTE, null); + } + + // advance the byte buffer accordingly + mbuf.position(ibuf.position() * 4); + + // read in the image data itself + byte[] data = new byte[width*height]; + mbuf.get(data); + + // create the image from our component parts + DataBuffer dbuf = new DataBufferByte(data, data.length, 0); + int[] offsets = new int[] { 0 }; + PixelInterleavedSampleModel smodel = + new PixelInterleavedSampleModel( + DataBuffer.TYPE_BYTE, width, height, 1, width, offsets); + WritableRaster raster = WritableRaster.createWritableRaster( + smodel, dbuf, _origin); + return new BufferedImage(cmodel, raster, false, null); + + } finally { + fchan.close(); + raf.close(); + } + } + + /** Used when loading our color map. */ + protected static int[] _cmap; + + /** Used when creating our writable raster. */ + protected static Point _origin = new Point(0, 0); +} diff --git a/src/java/com/threerings/media/image/ImageDataProvider.java b/src/java/com/threerings/media/image/ImageDataProvider.java new file mode 100644 index 00000000..78abbc6d --- /dev/null +++ b/src/java/com/threerings/media/image/ImageDataProvider.java @@ -0,0 +1,46 @@ +// +// $Id: ImageDataProvider.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.io.IOException; +import java.awt.image.BufferedImage; + +/** + * Provides access to image data for the image with the specified + * path. Images loaded from different data providers (which are + * differentiated by reference equality) will be considered distinct + * images with respect to caching. + */ +public interface ImageDataProvider +{ + /** + * Returns a string identifier for this image data provider which wil + * be used to differentiate it from other providers and thus should be + * unique. + */ + public String getIdent (); + + /** + * Returns the image at the specified path. + */ + public BufferedImage loadImage (String path) throws IOException; +} diff --git a/src/java/com/threerings/media/image/ImageManager.java b/src/java/com/threerings/media/image/ImageManager.java new file mode 100644 index 00000000..d0f71250 --- /dev/null +++ b/src/java/com/threerings/media/image/ImageManager.java @@ -0,0 +1,615 @@ +// +// $Id: ImageManager.java 4007 2006-04-10 08:59:30Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Transparency; +import java.awt.image.BufferedImage; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageInputStream; + +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.StringUtil; +import com.samskivert.util.Throttle; +import com.samskivert.util.Tuple; + +import com.threerings.media.Log; +import com.threerings.media.MediaPrefs; +import com.threerings.resource.ResourceManager; + +/** + * Provides a single point of access for image retrieval and caching. + */ +public class ImageManager + implements ImageUtil.ImageCreator +{ + /** + * Used to identify an image for caching and reconstruction. + */ + public static class ImageKey + { + /** The data provider from which this image's data is loaded. */ + public ImageDataProvider daprov; + + /** The path used to identify the image to the data provider. */ + public String path; + + protected ImageKey (ImageDataProvider daprov, String path) + { + this.daprov = daprov; + this.path = path; + } + + public int hashCode () + { + return path.hashCode() ^ daprov.getIdent().hashCode(); + } + + public boolean equals (Object other) + { + if (other == null || !(other instanceof ImageKey)) { + return false; + } + + ImageKey okey = (ImageKey)other; + return ((okey.daprov.getIdent().equals(daprov.getIdent())) && + (okey.path.equals(path))); + } + + public String toString () + { + return daprov.getIdent() + ":" + path; + } + } + + /** + * This interface allows the image manager to create images that are in a + * format optimal for rendering to the screen. + */ + public interface OptimalImageCreator + { + /** + * Requests that a blank image be created that is in a format and of a + * depth that are optimal for rendering to the screen. + */ + public BufferedImage createImage (int width, int height, int trans); + } + + /** + * Construct an image manager with the specified {@link ResourceManager} + * from which it will obtain its data. + */ + public ImageManager (ResourceManager rmgr, OptimalImageCreator icreator) + { + _rmgr = rmgr; + _icreator = icreator; + + // create our image cache + int icsize = _cacheSize.getValue(); + Log.debug("Creating image cache [size=" + icsize + "k]."); + _ccache = new LRUHashMap(icsize * 1024, new LRUHashMap.ItemSizer() { + public int computeSize (Object value) { + return (int)((CacheRecord)value).getEstimatedMemoryUsage(); + } + }); + _ccache.setTracking(true); + } + + /** + * A convenience constructor that creates an {@link AWTImageCreator} for + * use by the image manager. + */ + public ImageManager (ResourceManager rmgr, Component context) + { + this(rmgr, new AWTImageCreator(context)); + } + + /** + * Creates a buffered image, optimized for display on our graphics + * device. + */ + public BufferedImage createImage (int width, int height, int transparency) + { + return _icreator.createImage(width, height, transparency); + } + + /** + * Loads (and caches) the specified image from the resource manager + * using the supplied path to identify the image. + */ + public BufferedImage getImage (String path) + { + return getImage(null, path, null); + } + + /** + * Like {@link #getImage(String)} but the specified colorizations are + * applied to the image before it is returned. + */ + public BufferedImage getImage (String path, Colorization[] zations) + { + return getImage(null, path, zations); + } + + /** + * Like {@link #getImage(String)} but the image is loaded from the + * specified resource set rathern than the default resource set. + */ + public BufferedImage getImage (String rset, String path) + { + return getImage(rset, path, null); + } + + /** + * Like {@link #getImage(String,String)} but the specified + * colorizations are applied to the image before it is returned. + */ + public BufferedImage getImage (String rset, String path, + Colorization[] zations) + { + if (StringUtil.isBlank(path)) { + String errmsg = "Invalid image path [rset=" + rset + + ", path=" + path + "]"; + throw new IllegalArgumentException(errmsg); + } + + return getImage(getImageKey(rset, path), zations); + } + + /** + * Loads (and caches) the specified image from the resource manager + * using the supplied path to identify the image. + * + *

Additionally the image is optimized for display in the current + * graphics configuration. Consider using {@link #getMirage(ImageKey)} + * instead of prepared images as they (some day) will automatically + * use volatile images to increase performance. + */ + public BufferedImage getPreparedImage (String path) + { + return getPreparedImage(null, path, null); + } + + /** + * Loads (and caches) the specified image from the resource manager, + * obtaining the image from the supplied resource set. + * + *

Additionally the image is optimized for display in the current + * graphics configuration. Consider using {@link #getMirage(ImageKey)} + * instead of prepared images as they (some day) will automatically + * use volatile images to increase performance. + */ + public BufferedImage getPreparedImage (String rset, String path) + { + return getPreparedImage(rset, path, null); + } + + /** + * Loads (and caches) the specified image from the resource manager, + * obtaining the image from the supplied resource set and applying the + * using the supplied path to identify the image. + * + *

Additionally the image is optimized for display in the current + * graphics configuration. Consider using {@link + * #getMirage(ImageKey,Colorization[])} instead of prepared images as + * they (some day) will automatically use volatile images to increase + * performance. + */ + public BufferedImage getPreparedImage ( + String rset, String path, Colorization[] zations) + { + BufferedImage image = getImage(rset, path, zations); + BufferedImage prepped = null; + if (image != null) { + prepped = createImage(image.getWidth(), image.getHeight(), + image.getColorModel().getTransparency()); + Graphics2D pg = prepped.createGraphics(); + pg.drawImage(image, 0, 0, null); + pg.dispose(); + } + return prepped; + } + + /** + * Returns an image key that can be used to fetch the image identified + * by the specified resource set and image path. + */ + public ImageKey getImageKey (String rset, String path) + { + return getImageKey(getDataProvider(rset), path); + } + + /** + * Returns an image key that can be used to fetch the image identified + * by the specified data provider and image path. + */ + public ImageKey getImageKey (ImageDataProvider daprov, String path) + { + return new ImageKey(daprov, path); + } + + /** + * Obtains the image identified by the specified key, caching if + * possible. The image will be recolored using the supplied + * colorizations if requested. + */ + public BufferedImage getImage (ImageKey key, Colorization[] zations) + { + CacheRecord crec = null; + synchronized (_ccache) { + crec = (CacheRecord)_ccache.get(key); + } + if (crec != null) { +// Log.info("Cache hit [key=" + key + ", crec=" + crec + "]."); + return crec.getImage(zations); + } +// Log.info("Cache miss [key=" + key + ", crec=" + crec + "]."); + + // load up the raw image + BufferedImage image = loadImage(key); + if (image == null) { + Log.warning("Failed to load image " + key + "."); + // create a blank image instead + image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_INDEXED); + } + +// Log.info("Loaded " + key.path + ", image=" + image + +// ", size=" + ImageUtil.getEstimatedMemoryUsage(image)); + + // create a cache record + crec = new CacheRecord(key, image); + synchronized (_ccache) { + _ccache.put(key, crec); + } + _keySet.add(key); + + // periodically report our image cache performance + reportCachePerformance(); + + return crec.getImage(zations); + } + + /** + * Returns the data provider configured to obtain image data from the + * specified resource set. + */ + protected ImageDataProvider getDataProvider (final String rset) + { + if (rset == null) { + return _defaultProvider; + } + + ImageDataProvider dprov = (ImageDataProvider)_providers.get(rset); + if (dprov == null) { + dprov = new ImageDataProvider() { + public BufferedImage loadImage (String path) + throws IOException { + // first attempt to load the image from the specified + // resource set + try { + return read(_rmgr.getImageResource(rset, path)); + } catch (FileNotFoundException fnfe) { + // fall back to trying the classpath + return read(_rmgr.getImageResource(path)); + } + } + + public String getIdent () { + return "rmgr:" + rset; + } + }; + _providers.put(rset, dprov); + } + + return dprov; + } + + /** + * Loads and returns the image with the specified key from the + * supplied data provider. + */ + protected BufferedImage loadImage (ImageKey key) + { +// if (EventQueue.isDispatchThread()) { +// Log.info("Loading image on AWT thread " + key + "."); +// } + + BufferedImage image = null; + try { + Log.debug("Loading image " + key + "."); + image = key.daprov.loadImage(key.path); + if (image == null) { + Log.warning("ImageIO.read(" + key + ") returned null."); + } + + } catch (Exception e) { + Log.warning("Unable to load image '" + key + "'."); + Log.logStackTrace(e); + + // create a blank image in its stead + image = createImage(1, 1, Transparency.OPAQUE); + } + + return image; + } + + /** + * Helper function for loading images. + */ + protected static BufferedImage read (ImageInputStream iis) + throws IOException + { + BufferedImage image = ImageIO.read(iis); + closeIIS(iis); + return image; + } + + /** + * Helper function for closing image input streams. + */ + protected static void closeIIS (ImageInputStream iis) + { + if (iis == null) { + return; + } + + try { + iis.close(); + } catch (IOException ioe) { + // jesus fucking hoppalong cassidy christ on a polyester pogo + // stick! ImageInputStreamImpl.close() throws a fucking + // IOException if it's already closed; there's no way to find + // out if it's already closed or not, so we have to check for + // their bullshit exception; as if we should just "trust" + // ImageIO.read() to close the fucking input stream when it's + // done, especially after the goddamned fiasco with + // PNGImageReader not closing it's fucking inflaters; for the + // love of humanity + if (!"closed".equals(ioe.getMessage())) { + Log.warning("Failure closing image input '" + iis + "'."); + Log.logStackTrace(ioe); + } + } + } + + /** + * Creates a mirage which is an image optimized for display on our + * current display device and which will be stored into video memory + * if possible. + */ + public Mirage getMirage (ImageKey key) + { + return getMirage(key, null, null); + } + + /** + * Like {@link #getMirage(ImageKey)} but that only the specified + * subimage of the source image is used to build the mirage. + */ + public Mirage getMirage (ImageKey key, Rectangle bounds) + { + return getMirage(key, bounds, null); + } + + /** + * Like {@link #getMirage(ImageKey)} but the supplied colorizations + * are applied to the source image before creating the mirage. + */ + public Mirage getMirage (ImageKey key, Colorization[] zations) + { + return getMirage(key, null, zations); + } + + /** + * Like {@link #getMirage(ImageKey,Colorization[])} except that the + * mirage is created using only the specified subset of the original + * image. + */ + public Mirage getMirage (ImageKey key, Rectangle bounds, + Colorization[] zations) + { + BufferedImage src = null; + + if (bounds == null) { + // if they specified no bounds, we need to load up the raw + // image and determine its bounds so that we can pass those + // along to the created mirage + src = getImage(key, zations); + bounds = new Rectangle(0, 0, src.getWidth(), src.getHeight()); + + } else if (!_prepareImages.getValue()) { + src = getImage(key, zations); + src = src.getSubimage(bounds.x, bounds.y, + bounds.width, bounds.height); + } + + if (_runBlank.getValue()) { + return new BlankMirage(bounds.width, bounds.height); + } else if (_prepareImages.getValue()) { + return new CachedVolatileMirage(this, key, bounds, zations); + } else { + return new BufferedMirage(src); + } + } + + /** + * Returns the image creator that can be used to create buffered images + * optimized for rendering to the screen. + */ + public OptimalImageCreator getImageCreator () + { + return _icreator; + } + + /** + * Reports statistics detailing the image manager cache performance + * and the current size of the cached images. + */ + protected void reportCachePerformance () + { + if (/* Log.getLevel() != Log.log.DEBUG || */ + _cacheStatThrottle.throttleOp()) { + return; + } + + // compute our estimated memory usage + long size = 0; + + int[] eff = null; + synchronized (_ccache) { + Iterator iter = _ccache.values().iterator(); + while (iter.hasNext()) { + size += ((CacheRecord)iter.next()).getEstimatedMemoryUsage(); + } + eff = _ccache.getTrackedEffectiveness(); + } + Log.info("ImageManager LRU [mem=" + (size / 1024) + "k" + + ", size=" + _ccache.size() + ", hits=" + eff[0] + + ", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "]."); + } + + /** Maintains a source image and a set of colorized versions in the + * image cache. */ + protected static class CacheRecord + { + public CacheRecord (ImageKey key, BufferedImage source) + { + _key = key; + _source = source; + } + + public BufferedImage getImage (Colorization[] zations) + { + if (zations == null) { + return _source; + } + + if (_colorized == null) { + _colorized = new ArrayList(); + } + + // we search linearly through our list of colorized copies + // because it is not likely to be very long + int csize = _colorized.size(); + for (int ii = 0; ii < csize; ii++) { + Tuple tup = (Tuple)_colorized.get(ii); + Colorization[] tzations = (Colorization[])tup.left; + if (Arrays.equals(zations, tzations)) { + return (BufferedImage)tup.right; + } + } + + try { + BufferedImage cimage = ImageUtil.recolorImage(_source, zations); + _colorized.add(new Tuple(zations, cimage)); + return cimage; + + } catch (Exception re) { + Log.warning("Failure recoloring image [source" + _key + + ", zations=" + StringUtil.toString(zations) + + ", error=" + re + "]."); + // return the uncolorized version + return _source; + } + } + + public long getEstimatedMemoryUsage () + { + return ImageUtil.getEstimatedMemoryUsage(_source); + } + + public String toString () + { + return "[key=" + _key + ", wid=" + _source.getWidth() + + ", hei=" + _source.getHeight() + + ", ccount=" + ((_colorized == null) ? 0 : _colorized.size()) + + "]"; + } + + protected ImageKey _key; + protected BufferedImage _source; + protected ArrayList _colorized; + } + + /** A reference to the resource manager via which we load image data + * by default. */ + protected ResourceManager _rmgr; + + /** We use this to create images optimized for rendering. */ + protected OptimalImageCreator _icreator; + + /** A cache of loaded images. */ + protected LRUHashMap _ccache; + + /** The set of all keys we've ever seen. */ + protected HashSet _keySet = new HashSet(); + + /** Throttle our cache status logging to once every 300 seconds. */ + protected Throttle _cacheStatThrottle = new Throttle(1, 300000L); + + /** Our default data provider. */ + protected ImageDataProvider _defaultProvider = new ImageDataProvider() { + public BufferedImage loadImage (String path) throws IOException { + return read(_rmgr.getImageResource(path)); + } + + public String getIdent () { + return "rmgr:default"; + } + }; + + /** Data providers for different resource sets. */ + protected HashMap _providers = new HashMap(); + + /** Register our image cache size with the runtime adjustments + * framework. */ + protected static RuntimeAdjust.IntAdjust _cacheSize = + new RuntimeAdjust.IntAdjust( + "Size (in kb of memory used) of the image manager LRU cache " + + "[requires restart]", "narya.media.image.cache_size", + MediaPrefs.config, 2048); + + /** Controls whether or not we prepare images or use raw versions. */ + protected static RuntimeAdjust.BooleanAdjust _prepareImages = + new RuntimeAdjust.BooleanAdjust( + "Cause image manager to optimize all images for display.", + "narya.media.image.prep_images", MediaPrefs.config, true); + + /** A debug toggle for running entirely without rendering images. */ + protected static RuntimeAdjust.BooleanAdjust _runBlank = + new RuntimeAdjust.BooleanAdjust( + "Cause image manager to return blank images.", + "narya.media.image.run_blank", MediaPrefs.config, false); +} diff --git a/src/java/com/threerings/media/image/ImageUtil.java b/src/java/com/threerings/media/image/ImageUtil.java new file mode 100644 index 00000000..fb6172e2 --- /dev/null +++ b/src/java/com/threerings/media/image/ImageUtil.java @@ -0,0 +1,647 @@ +// +// $Id: ImageUtil.java 3965 2006-03-21 02:32:27Z mthomas $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Transparency; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +import java.util.Arrays; +import java.util.Iterator; + +import com.samskivert.swing.Label; + +/** + * Image related utility functions. + */ +public class ImageUtil +{ + public static interface ImageCreator + { + /** Used by routines that need to create new images to allow the + * caller to dictate the format (which may mean using + * createCompatibleImage). */ + public BufferedImage createImage ( + int width, int height, int transparency); + } + + /** + * Creates a new buffered image with the same sample model and color + * model as the source image but with the new width and height. + */ + public static BufferedImage createCompatibleImage ( + BufferedImage source, int width, int height) + { + WritableRaster raster = + source.getRaster().createCompatibleWritableRaster(width, height); + return new BufferedImage(source.getColorModel(), raster, false, null); + } + + /** + * Creates an image with the word "Error" written in it. + */ + public static BufferedImage createErrorImage (int width, int height) + { + BufferedImage img = new BufferedImage( + width, height, BufferedImage.TYPE_BYTE_INDEXED); + Graphics2D g = (Graphics2D)img.getGraphics(); + g.setColor(Color.red); + Label l = new Label("Error"); + l.layout(g); + Dimension d = l.getSize(); + // fill that sucker with errors + for (int yy = 0; yy < height; yy += d.height) { + for (int xx = 0; xx < width; xx += (d.width+5)) { + l.render(g, xx, yy); + } + } + g.dispose(); + return img; + } + + /** + * Used to recolor images by shifting bands of color (in HSV color + * space) to a new hue. The source images must be 8-bit color mapped + * images, as the recoloring process works by analysing the color map + * and modifying it. + */ + public static BufferedImage recolorImage ( + BufferedImage image, Color rootColor, float[] dists, float[] offsets) + { + return recolorImage(image, new Colorization[] { + new Colorization(-1, rootColor, dists, offsets) }); + } + + /** + * Recolors the supplied image as in {@link + * #recolorImage(BufferedImage,Color,float[],float[])} obtaining the + * recoloring parameters from the supplied {@link Colorization} + * instance. + */ + public static BufferedImage recolorImage ( + BufferedImage image, Colorization cz) + { + return recolorImage(image, new Colorization[] { cz }); + } + + /** + * Recolors the supplied image using the supplied colorizations. + */ + public static BufferedImage recolorImage ( + BufferedImage image, Colorization[] zations) + { + ColorModel cm = image.getColorModel(); + if (!(cm instanceof IndexColorModel)) { + String errmsg = "Unable to recolor images with non-index color " + + "model [cm=" + cm.getClass() + "]"; + throw new RuntimeException(errmsg); + } + + // now process the image + IndexColorModel icm = (IndexColorModel)cm; + int size = icm.getMapSize(); + int zcount = zations.length; + int[] rgbs = new int[size]; + + // fetch the color data + icm.getRGBs(rgbs); + + // convert the colors to HSV + float[] hsv = new float[3]; + int[] fhsv = new int[3]; + int tpixel = -1; + for (int i = 0; i < size; i++) { + int value = rgbs[i]; + + // don't fiddle with alpha pixels + if ((value & 0xFF000000) == 0) { + tpixel = i; + continue; + } + + // convert the color to HSV + int red = (value >> 16) & 0xFF; + int green = (value >> 8) & 0xFF; + int blue = (value >> 0) & 0xFF; + Color.RGBtoHSB(red, green, blue, hsv); + Colorization.toFixedHSV(hsv, fhsv); + + // see if this color matches and of our colorizations and + // recolor it if it does + for (int z = 0; z < zcount; z++) { + Colorization cz = zations[z]; + if (cz != null && cz.matches(hsv, fhsv)) { + // massage the HSV bands and update the RGBs array + rgbs[i] = cz.recolorColor(hsv); + break; + } + } + } + + // create a new image with the adjusted color palette + IndexColorModel nicm = new IndexColorModel( + icm.getPixelSize(), size, rgbs, 0, icm.hasAlpha(), + icm.getTransparentPixel(), icm.getTransferType()); + return new BufferedImage(nicm, image.getRaster(), false, null); + } + + /** + * Paints multiple copies of the supplied image using the supplied + * graphics context such that the requested area is filled with the + * image. + */ + public static void tileImage ( + Graphics2D gfx, Mirage image, int x, int y, int width, int height) + { + int iwidth = image.getWidth(), iheight = image.getHeight(); + int xnum = width / iwidth, xplus = width % iwidth; + int ynum = height / iheight, yplus = height % iheight; + Shape oclip = gfx.getClip(); + + for (int ii=0; ii < ynum; ii++) { + // draw the full copies of the image across + int xx = x; + for (int jj=0; jj < xnum; jj++) { + image.paint(gfx, xx, y); + xx += iwidth; + } + + if (xplus > 0) { + gfx.clipRect(xx, y, xplus, iheight); + image.paint(gfx, xx, y); + gfx.setClip(oclip); + } + + y += iheight; + } + + if (yplus > 0) { + int xx = x; + for (int jj=0; jj < xnum; jj++) { + gfx.clipRect(xx, y, iwidth, yplus); + image.paint(gfx, xx, y); + gfx.setClip(oclip); + xx += iwidth; + } + + if (xplus > 0) { + gfx.clipRect(xx, y, xplus, yplus); + image.paint(gfx, xx, y); + gfx.setClip(oclip); + } + } + } + + /** + * Paints multiple copies of the supplied image using the supplied + * graphics context such that the requested width is filled with the + * image. + */ + public static void tileImageAcross (Graphics2D gfx, Mirage image, + int x, int y, int width) + { + tileImage(gfx, image, x, y, width, image.getHeight()); + } + + /** + * Paints multiple copies of the supplied image using the supplied + * graphics context such that the requested height is filled with the + * image. + */ + public static void tileImageDown (Graphics2D gfx, Mirage image, + int x, int y, int height) + { + tileImage(gfx, image, x, y, image.getWidth(), height); + } + + // Not fully added because we're not using it anywhere, plus + // it's probably a little sketchy to create Area objects with all + // this pixely data. + // Also, the Area was getting zeroed out when it was translated. Something + // to look into someday if anyone wants to use this method. +// /** +// * Creates a mask that is opaque in the non-transparent areas of the +// * source image. +// */ +// public static Area createImageMask (BufferedImage src) +// { +// Raster srcdata = src.getData(); +// int wid = src.getWidth(), hei = src.getHeight(); +// Log.info("creating area of (" + wid + ", " + hei + ")"); +// Area a = new Area(new Rectangle(wid, hei)); +// Rectangle r = new Rectangle(1, 1); +// +// for (int yy=0; yy < hei; yy++) { +// for (int xx=0; xx < wid; xx++) { +// if (srcdata.getSample(xx, yy, 0) == 0) { +// r.setLocation(xx, yy); +// a.subtract(new Area(r)); +// } +// } +// } +// +// return a; +// } + + /** + * Creates and returns a new image consisting of the supplied image + * traced with the given color and thickness. + */ + public static BufferedImage createTracedImage ( + ImageCreator isrc, BufferedImage src, Color tcolor, int thickness) + { + return createTracedImage(isrc, src, tcolor, thickness, 1.0f, 1.0f); + } + + /** + * Creates and returns a new image consisting of the supplied image + * traced with the given color, thickness and alpha transparency. + */ + public static BufferedImage createTracedImage ( + ImageCreator isrc, BufferedImage src, Color tcolor, int thickness, + float startAlpha, float endAlpha) + { + // create the destination image + int wid = src.getWidth(), hei = src.getHeight(); + BufferedImage dest = isrc.createImage( + wid, hei, Transparency.TRANSLUCENT); + return createTracedImage( + src, dest, tcolor, thickness, startAlpha, endAlpha); + } + + /** + * Creates and returns a new image consisting of the supplied image + * traced with the given color, thickness and alpha transparency. + */ + public static BufferedImage createTracedImage ( + BufferedImage src, BufferedImage dest, Color tcolor, int thickness, + float startAlpha, float endAlpha) + { + // prepare various bits of working data + int wid = src.getWidth(), hei = src.getHeight(); + int spixel = (tcolor.getRGB() & RGB_MASK); + int salpha = (int)(startAlpha * 255); + int tpixel = (spixel | (salpha << 24)); + boolean[] traced = new boolean[wid * hei]; + int stepAlpha = (thickness <= 1) ? 0 : + (int)(((startAlpha - endAlpha) * 255) / (thickness - 1)); + + // TODO: this could be made more efficient, e.g., if we made four + // passes through the image in a vertical scan, horizontal scan, + // and opposing diagonal scans, making sure each non-transparent + // pixel found during each scan is traced on both sides of the + // respective scan direction. for now, we just naively check all + // eight pixels surrounding each pixel in the image and fill the + // center pixel with the tracing color if it's transparent but has + // a non-transparent pixel around it. + for (int tt = 0; tt < thickness; tt++) { + if (tt > 0) { + // clear out the array of pixels traced this go-around + Arrays.fill(traced, false); + // use the destination image as our new source + src = dest; + // decrement the trace pixel alpha-level + salpha -= Math.max(0, stepAlpha); + tpixel = (spixel | (salpha << 24)); + } + + for (int yy = 0; yy < hei; yy++) { + for (int xx = 0; xx < wid; xx++) { + // get the pixel we're checking + int argb = src.getRGB(xx, yy); + + if ((argb & TRANS_MASK) != 0) { + // copy any pixel that isn't transparent + dest.setRGB(xx, yy, argb); + + } else if (bordersNonTransparentPixel( + src, wid, hei, traced, xx, yy)) { + dest.setRGB(xx, yy, tpixel); + // note that we traced this pixel this pass so + // that it doesn't impact other-pixel borderedness + traced[(yy*wid)+xx] = true; + } + } + } + } + + return dest; + } + + /** + * Returns whether the given pixel is bordered by any non-transparent + * pixel. + */ + protected static boolean bordersNonTransparentPixel ( + BufferedImage data, int wid, int hei, boolean[] traced, int x, int y) + { + // check the three-pixel row above the pixel + if (y > 0) { + for (int rxx = x - 1; rxx <= x + 1; rxx++) { + if (rxx < 0 || rxx >= wid || traced[((y-1)*wid)+rxx]) { + continue; + } + + if ((data.getRGB(rxx, y - 1) & TRANS_MASK) != 0) { + return true; + } + } + } + + // check the pixel to the left + if (x > 0 && !traced[(y*wid)+(x-1)]) { + if ((data.getRGB(x - 1, y) & TRANS_MASK) != 0) { + return true; + } + } + + // check the pixel to the right + if (x < wid - 1 && !traced[(y*wid)+(x+1)]) { + if ((data.getRGB(x + 1, y) & TRANS_MASK) != 0) { + return true; + } + } + + // check the three-pixel row below the pixel + if (y < hei - 1) { + for (int rxx = x - 1; rxx <= x + 1; rxx++) { + if (rxx < 0 || rxx >= wid || traced[((y+1)*wid)+rxx]) { + continue; + } + + if ((data.getRGB(rxx, y + 1) & TRANS_MASK) != 0) { + return true; + } + } + } + + return false; + } + + /** + * Create an image using the alpha channel from the first and the RGB + * values from the second. + */ + public static BufferedImage composeMaskedImage ( + ImageCreator isrc, BufferedImage mask, BufferedImage base) + { + int wid = base.getWidth(); + int hei = base.getHeight(); + + Raster maskdata = mask.getData(); + Raster basedata = base.getData(); + + // create a new image using the rasters if possible + if (maskdata.getNumBands() == 4 && basedata.getNumBands() >= 3) { + WritableRaster target = + basedata.createCompatibleWritableRaster(wid, hei); + + // copy the alpha from the mask image + int[] adata = maskdata.getSamples(0, 0, wid, hei, 3, (int[]) null); + target.setSamples(0, 0, wid, hei, 3, adata); + + // copy the RGB from the base image + for (int ii=0; ii < 3; ii++) { + int[] cdata = basedata.getSamples( + 0, 0, wid, hei, ii, (int[]) null); + target.setSamples(0, 0, wid, hei, ii, cdata); + } + + return new BufferedImage(mask.getColorModel(), target, true, null); + + } else { + // otherwise composite them by rendering them with an alpha + // rule + BufferedImage target = isrc.createImage( + wid, hei, Transparency.TRANSLUCENT); + Graphics2D g2 = target.createGraphics(); + try { + g2.drawImage(mask, 0, 0, null); + g2.setComposite(AlphaComposite.SrcIn); + g2.drawImage(base, 0, 0, null); + } finally { + g2.dispose(); + } + return target; + } + } + + /** + * Create a new image using the supplied shape as a mask from which to + * cut out pixels from the supplied image. Pixels inside the shape + * will be added to the final image, pixels outside the shape will be + * clear. + */ + public static BufferedImage composeMaskedImage ( + ImageCreator isrc, Shape mask, BufferedImage base) + { + int wid = base.getWidth(); + int hei = base.getHeight(); + + // alternate method for composition: + // 1. create WriteableRaster with base data + // 2. test each pixel with mask.contains() and set the alpha + // channel to fully-alpha if false + // 3. create buffered image from raster + // (I didn't use this method because it depends on the colormodel + // of the source image, and was booching when the souce image was + // a cut-up from a tileset, and it seems like it would take + // longer than the method we are using. + // But it's something to consider) + + // composite them by rendering them with an alpha rule + BufferedImage target = isrc.createImage( + wid, hei, Transparency.TRANSLUCENT); + Graphics2D g2 = target.createGraphics(); + try { + g2.setColor(Color.BLACK); // whatever, really + g2.fill(mask); + g2.setComposite(AlphaComposite.SrcIn); + g2.drawImage(base, 0, 0, null); + } finally { + g2.dispose(); + } + return target; + } + + /** + * Returns true if the supplied image contains a non-transparent pixel + * at the specified coordinates, false otherwise. + */ + public static boolean hitTest (BufferedImage image, int x, int y) + { + // it's only a hit if the pixel is non-transparent + int argb = image.getRGB(x, y); + return (argb >> 24) != 0; + } + + /** + * Computes the bounds of the smallest rectangle that contains all + * non-transparent pixels of this image. This isn't extremely + * efficient, so you shouldn't be doing this anywhere exciting. + */ + public static void computeTrimmedBounds ( + BufferedImage image, Rectangle tbounds) + { + // this could be more efficient, but it's run as a batch process + // and doesn't really take that long anyway + int width = image.getWidth(), height = image.getHeight(); + + int firstrow = -1, lastrow = -1, minx = width, maxx = 0; + for (int yy = 0; yy < height; yy++) { + + int firstidx = -1, lastidx = -1; + for (int xx = 0; xx < width; xx++) { + // if this pixel is transparent, do nothing + int argb = image.getRGB(xx, yy); + if ((argb >> 24) == 0) { + continue; + } + + // otherwise, if we've not seen a non-transparent pixel, + // make a note that this is the first non-transparent + // pixel in the row + if (firstidx == -1) { + firstidx = xx; + } + // keep track of the last non-transparent pixel we saw + lastidx = xx; + } + + // if we saw no pixels on this row, we can bail now + if (firstidx == -1) { + continue; + } + + // update our min and maxx + minx = Math.min(firstidx, minx); + maxx = Math.max(lastidx, maxx); + + // otherwise keep track of the first row on which we see + // pixels and the last row on which we see pixels + if (firstrow == -1) { + firstrow = yy; + } + lastrow = yy; + } + + // fill in the dimensions + if (firstrow != -1) { + tbounds.x = minx; + tbounds.y = firstrow; + tbounds.width = maxx - minx + 1; + tbounds.height = lastrow - firstrow + 1; + } else { + // Entirely blank image. Return 1x1 blank image. + tbounds.x = 0; + tbounds.y = 0; + tbounds.width = 1; + tbounds.height = 1; + } + } + + /** + * Returns the estimated memory usage in bytes for the specified + * image. + */ + public static long getEstimatedMemoryUsage (BufferedImage image) + { + if (image != null) { + return getEstimatedMemoryUsage(image.getRaster()); + } else { + return 0; + } + } + + /** + * Returns the estimated memory usage in bytes for the specified + * raster. + */ + public static long getEstimatedMemoryUsage (Raster raster) + { + // we assume that the data buffer stores each element in a + // byte-rounded memory element; maybe the buffer is smarter about + // things than this, but we're better to err on the safe side + DataBuffer db = raster.getDataBuffer(); + int bpe = (int)Math.ceil( + DataBuffer.getDataTypeSize(db.getDataType()) / 8f); + return bpe * db.getSize(); + } + + /** + * Returns the estimated memory usage in bytes for all buffered images + * in the supplied iterator. + */ + public static long getEstimatedMemoryUsage (Iterator iter) + { + long size = 0; + while (iter.hasNext()) { + BufferedImage image = (BufferedImage)iter.next(); + size += getEstimatedMemoryUsage(image); + } + return size; + } + + /** + * Obtains the default graphics configuration for this VM. If the JVM + * is in headless mode, this method will return null. + */ + protected static GraphicsConfiguration getDefGC () + { + if (_gc == null) { + // obtain information on our graphics environment + try { + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = env.getDefaultScreenDevice(); + _gc = gd.getDefaultConfiguration(); + } catch (HeadlessException e) { + // no problem, just return null + } + } + return _gc; + } + + /** The graphics configuration for the default screen device. */ + protected static GraphicsConfiguration _gc; + + /** Used when seeking fully transparent pixels for outlining. */ + protected static final int TRANS_MASK = (0xFF << 24); + + /** Used when outlining. */ + protected static final int RGB_MASK = 0x00FFFFFF; +} diff --git a/src/java/com/threerings/media/image/Mirage.java b/src/java/com/threerings/media/image/Mirage.java new file mode 100644 index 00000000..3e05da42 --- /dev/null +++ b/src/java/com/threerings/media/image/Mirage.java @@ -0,0 +1,67 @@ +// +// $Id: Mirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/** + * Provides an interface via which images can be accessed in a way that + * allows them to optionally be located in video memory where that affords + * performance improvements. + */ +public interface Mirage +{ + /** + * Renders this mirage at the specified position in the supplied + * graphics context. + */ + public void paint (Graphics2D gfx, int x, int y); + + /** + * Returns the width of this mirage. + */ + public int getWidth (); + + /** + * Returns the height of this mirage. + */ + public int getHeight (); + + /** + * Returns true if this mirage contains a non-transparent pixel at the + * specified coordinate. + */ + public boolean hitTest (int x, int y); + + /** + * Returns a snapshot of this mirage as a buffered image. The snapshot + * should not be modified by the caller. + */ + public BufferedImage getSnapshot (); + + /** + * Returns an estimate of the memory consumed by this mirage's image + * raster data. + */ + public long getEstimatedMemoryUsage (); +} diff --git a/src/java/com/threerings/media/image/MirageIcon.java b/src/java/com/threerings/media/image/MirageIcon.java new file mode 100644 index 00000000..d26be90c --- /dev/null +++ b/src/java/com/threerings/media/image/MirageIcon.java @@ -0,0 +1,60 @@ +// +// $Id: MirageIcon.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Graphics; + +import javax.swing.Icon; + +/** + * Implements the Swing {@link Icon} interface with a mirage providing the + * image information. + */ +public class MirageIcon implements Icon +{ + public MirageIcon (Mirage mirage) + { + _mirage = mirage; + } + + // documentation inherited from interface + public void paintIcon (Component c, Graphics g, int x, int y) + { + _mirage.paint((Graphics2D)g, x, y); + } + + // documentation inherited from interface + public int getIconWidth() + { + return _mirage.getWidth(); + } + + // documentation inherited from interface + public int getIconHeight() + { + return _mirage.getHeight(); + } + + protected Mirage _mirage; +} diff --git a/src/java/com/threerings/media/image/Quantize.java b/src/java/com/threerings/media/image/Quantize.java new file mode 100644 index 00000000..8a6cfecc --- /dev/null +++ b/src/java/com/threerings/media/image/Quantize.java @@ -0,0 +1,776 @@ +// +// $Id: Quantize.java 4031 2006-04-18 20:35:28Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +package com.threerings.media.image; + +/* + * @(#)Quantize.java 0.90 9/19/00 Adam Doppelt + */ + +/** + * Calculates a reduced color + * + * Three Rings note: Code taken from + * Adam Doppelt, who + * adapted it from other code. Feel the love.

+ * + * RenderingHints is supposed to provide a way to block dithering, but I have + * not been able to get that to work. It always dithers, so we use this + * class instead. + *

+ * + * The following modifications were added to the original code: + * - Made it work with image data with transparent pixels. + * - Clarified documentation of the main method. + * - Changed the 'QUICK' constant to false for better quantization. + * - Fixed an integer overflow that caused a bug quantizing large images. + * + *

+ * + * Original headers follow: + * + * + * + * + * An efficient color quantization algorithm, adapted from the C++ + * implementation quantize.c in ImageMagick. The pixels for + * an image are placed into an oct tree. The oct tree is reduced in + * size, and the pixels from the original image are reassigned to the + * nodes in the reduced tree.

+ * + * Here is the copyright notice from ImageMagick: + * + *

+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%  Permission is hereby granted, free of charge, to any person obtaining a    %
+%  copy of this software and associated documentation files ("ImageMagick"),  %
+%  to deal in ImageMagick without restriction, including without limitation   %
+%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
+%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
+%  ImageMagick is furnished to do so, subject to the following conditions:    %
+%                                                                             %
+%  The above copyright notice and this permission notice shall be included in %
+%  all copies or substantial portions of ImageMagick.                         %
+%                                                                             %
+%  The software is provided "as is", without warranty of any kind, express or %
+%  implied, including but not limited to the warranties of merchantability,   %
+%  fitness for a particular purpose and noninfringement.  In no event shall   %
+%  E. I. du Pont de Nemours and Company be liable for any claim, damages or   %
+%  other liability, whether in an action of contract, tort or otherwise,      %
+%  arising from, out of or in connection with ImageMagick or the use or other %
+%  dealings in ImageMagick.                                                   %
+%                                                                             %
+%  Except as contained in this notice, the name of the E. I. du Pont de       %
+%  Nemours and Company shall not be used in advertising or otherwise to       %
+%  promote the sale, use or other dealings in ImageMagick without prior       %
+%  written authorization from the E. I. du Pont de Nemours and Company.       %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ * + * + * @version 0.90 19 Sep 2000 + * @author Adam Doppelt + */ +public class Quantize { + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% QQQ U U AAA N N TTTTT IIIII ZZZZZ EEEEE % +% Q Q U U A A NN N T I ZZ E % +% Q Q U U AAAAA N N N T I ZZZ EEEEE % +% Q QQ U U A A N NN T I ZZ E % +% QQQQ UUU A A N N T IIIII ZZZZZ EEEEE % +% % +% % +% Reduce the Number of Unique Colors in an Image % +% % +% % +% Software Design % +% John Cristy % +% July 1992 % +% % +% % +% Copyright 1998 E. I. du Pont de Nemours and Company % +% % +% Permission is hereby granted, free of charge, to any person obtaining a % +% copy of this software and associated documentation files ("ImageMagick"), % +% to deal in ImageMagick without restriction, including without limitation % +% the rights to use, copy, modify, merge, publish, distribute, sublicense, % +% and/or sell copies of ImageMagick, and to permit persons to whom the % +% ImageMagick is furnished to do so, subject to the following conditions: % +% % +% The above copyright notice and this permission notice shall be included in % +% all copies or substantial portions of ImageMagick. % +% % +% The software is provided "as is", without warranty of any kind, express or % +% implied, including but not limited to the warranties of merchantability, % +% fitness for a particular purpose and noninfringement. In no event shall % +% E. I. du Pont de Nemours and Company be liable for any claim, damages or % +% other liability, whether in an action of contract, tort or otherwise, % +% arising from, out of or in connection with ImageMagick or the use or other % +% dealings in ImageMagick. % +% % +% Except as contained in this notice, the name of the E. I. du Pont de % +% Nemours and Company shall not be used in advertising or otherwise to % +% promote the sale, use or other dealings in ImageMagick without prior % +% written authorization from the E. I. du Pont de Nemours and Company. % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Realism in computer graphics typically requires using 24 bits/pixel to +% generate an image. Yet many graphic display devices do not contain +% the amount of memory necessary to match the spatial and color +% resolution of the human eye. The QUANTIZE program takes a 24 bit +% image and reduces the number of colors so it can be displayed on +% raster device with less bits per pixel. In most instances, the +% quantized image closely resembles the original reference image. +% +% A reduction of colors in an image is also desirable for image +% transmission and real-time animation. +% +% Function Quantize takes a standard RGB or monochrome images and quantizes +% them down to some fixed number of colors. +% +% For purposes of color allocation, an image is a set of n pixels, where +% each pixel is a point in RGB space. RGB space is a 3-dimensional +% vector space, and each pixel, pi, is defined by an ordered triple of +% red, green, and blue coordinates, (ri, gi, bi). +% +% Each primary color component (red, green, or blue) represents an +% intensity which varies linearly from 0 to a maximum value, cmax, which +% corresponds to full saturation of that color. Color allocation is +% defined over a domain consisting of the cube in RGB space with +% opposite vertices at (0,0,0) and (cmax,cmax,cmax). QUANTIZE requires +% cmax = 255. +% +% The algorithm maps this domain onto a tree in which each node +% represents a cube within that domain. In the following discussion +% these cubes are defined by the coordinate of two opposite vertices: +% The vertex nearest the origin in RGB space and the vertex farthest +% from the origin. +% +% The tree's root node represents the the entire domain, (0,0,0) through +% (cmax,cmax,cmax). Each lower level in the tree is generated by +% subdividing one node's cube into eight smaller cubes of equal size. +% This corresponds to bisecting the parent cube with planes passing +% through the midpoints of each edge. +% +% The basic algorithm operates in three phases: Classification, +% Reduction, and Assignment. Classification builds a color +% description tree for the image. Reduction collapses the tree until +% the number it represents, at most, the number of colors desired in the +% output image. Assignment defines the output image's color map and +% sets each pixel's color by reclassification in the reduced tree. +% Our goal is to minimize the numerical discrepancies between the original +% colors and quantized colors (quantization error). +% +% Classification begins by initializing a color description tree of +% sufficient depth to represent each possible input color in a leaf. +% However, it is impractical to generate a fully-formed color +% description tree in the classification phase for realistic values of +% cmax. If colors components in the input image are quantized to k-bit +% precision, so that cmax= 2k-1, the tree would need k levels below the +% root node to allow representing each possible input color in a leaf. +% This becomes prohibitive because the tree's total number of nodes is +% 1 + sum(i=1,k,8k). +% +% A complete tree would require 19,173,961 nodes for k = 8, cmax = 255. +% Therefore, to avoid building a fully populated tree, QUANTIZE: (1) +% Initializes data structures for nodes only as they are needed; (2) +% Chooses a maximum depth for the tree as a function of the desired +% number of colors in the output image (currently log2(colormap size)). +% +% For each pixel in the input image, classification scans downward from +% the root of the color description tree. At each level of the tree it +% identifies the single node which represents a cube in RGB space +% containing the pixel's color. It updates the following data for each +% such node: +% +% n1: Number of pixels whose color is contained in the RGB cube +% which this node represents; +% +% n2: Number of pixels whose color is not represented in a node at +% lower depth in the tree; initially, n2 = 0 for all nodes except +% leaves of the tree. +% +% Sr, Sg, Sb: Sums of the red, green, and blue component values for +% all pixels not classified at a lower depth. The combination of +% these sums and n2 will ultimately characterize the mean color of a +% set of pixels represented by this node. +% +% E: The distance squared in RGB space between each pixel contained +% within a node and the nodes' center. This represents the quantization +% error for a node. +% +% Reduction repeatedly prunes the tree until the number of nodes with +% n2 > 0 is less than or equal to the maximum number of colors allowed +% in the output image. On any given iteration over the tree, it selects +% those nodes whose E count is minimal for pruning and merges their +% color statistics upward. It uses a pruning threshold, Ep, to govern +% node selection as follows: +% +% Ep = 0 +% while number of nodes with (n2 > 0) > required maximum number of colors +% prune all nodes such that E <= Ep +% Set Ep to minimum E in remaining nodes +% +% This has the effect of minimizing any quantization error when merging +% two nodes together. +% +% When a node to be pruned has offspring, the pruning procedure invokes +% itself recursively in order to prune the tree from the leaves upward. +% n2, Sr, Sg, and Sb in a node being pruned are always added to the +% corresponding data in that node's parent. This retains the pruned +% node's color characteristics for later averaging. +% +% For each node, n2 pixels exist for which that node represents the +% smallest volume in RGB space containing those pixel's colors. When n2 +% > 0 the node will uniquely define a color in the output image. At the +% beginning of reduction, n2 = 0 for all nodes except a the leaves of +% the tree which represent colors present in the input image. +% +% The other pixel count, n1, indicates the total number of colors +% within the cubic volume which the node represents. This includes n1 - +% n2 pixels whose colors should be defined by nodes at a lower level in +% the tree. +% +% Assignment generates the output image from the pruned tree. The +% output image consists of two parts: (1) A color map, which is an +% array of color descriptions (RGB triples) for each color present in +% the output image; (2) A pixel array, which represents each pixel as +% an index into the color map array. +% +% First, the assignment phase makes one pass over the pruned color +% description tree to establish the image's color map. For each node +% with n2 > 0, it divides Sr, Sg, and Sb by n2 . This produces the +% mean color of all pixels that classify no lower than this node. Each +% of these colors becomes an entry in the color map. +% +% Finally, the assignment phase reclassifies each pixel in the pruned +% tree to identify the deepest node containing the pixel's color. The +% pixel's value in the pixel array becomes the index of this node's mean +% color in the color map. +% +% With the permission of USC Information Sciences Institute, 4676 Admiralty +% Way, Marina del Rey, California 90292, this code was adapted from module +% ALCOLS written by Paul Raveling. +% +% The names of ISI and USC are not used in advertising or publicity +% pertaining to distribution of the software without prior specific +% written permission from ISI. +% +*/ + + final static boolean QUICK = false; + + final static int MAX_RGB = 255; + final static int MAX_NODES = 266817; + final static int MAX_TREE_DEPTH = 8; + + // these are precomputed in advance + static int SQUARES[]; + static int SHIFT[]; + + static { + SQUARES = new int[MAX_RGB + MAX_RGB + 1]; + for (int i= -MAX_RGB; i <= MAX_RGB; i++) { + SQUARES[i + MAX_RGB] = i * i; + } + + SHIFT = new int[MAX_TREE_DEPTH + 1]; + for (int i = 0; i < MAX_TREE_DEPTH + 1; ++i) { + SHIFT[i] = 1 << (15 - i); + } + } + + /** + * Reduce the image to the given number of colors. + * + * @param pixels an in/out parameter that should initially contain + * [A]RGB values but that will contain color palette indicies upon return. + * + * @return The new color palette. + */ + public static int[] quantizeImage(int pixels[][], int max_colors) { + Cube cube = new Cube(pixels, max_colors); + cube.classification(); + cube.reduction(); + cube.assignment(); + return cube.colormap; + } + + static class Cube { + int pixels[][]; + int max_colors; + int colormap[]; + + // do we have transparent pixels? + boolean hasTrans = false; + + Node root; + int depth; + + // counter for the number of colors in the cube. this gets + // recalculated often. + int colors; + + // counter for the number of nodes in the tree + int nodes; + + Cube(int pixels[][], int max_colors) { + this.pixels = pixels; + this.max_colors = max_colors; + + int i = max_colors; + // tree_depth = log max_colors + // 4 + for (depth = 1; i != 0; depth++) { + i /= 4; + } + if (depth > 1) { + --depth; + } + if (depth > MAX_TREE_DEPTH) { + depth = MAX_TREE_DEPTH; + } else if (depth < 2) { + depth = 2; + } + + root = new Node(this); + } + + /* + * Procedure Classification begins by initializing a color + * description tree of sufficient depth to represent each + * possible input color in a leaf. However, it is impractical + * to generate a fully-formed color description tree in the + * classification phase for realistic values of cmax. If + * colors components in the input image are quantized to k-bit + * precision, so that cmax= 2k-1, the tree would need k levels + * below the root node to allow representing each possible + * input color in a leaf. This becomes prohibitive because the + * tree's total number of nodes is 1 + sum(i=1,k,8k). + * + * A complete tree would require 19,173,961 nodes for k = 8, + * cmax = 255. Therefore, to avoid building a fully populated + * tree, QUANTIZE: (1) Initializes data structures for nodes + * only as they are needed; (2) Chooses a maximum depth for + * the tree as a function of the desired number of colors in + * the output image (currently log2(colormap size)). + * + * For each pixel in the input image, classification scans + * downward from the root of the color description tree. At + * each level of the tree it identifies the single node which + * represents a cube in RGB space containing It updates the + * following data for each such node: + * + * number_pixels : Number of pixels whose color is contained + * in the RGB cube which this node represents; + * + * unique : Number of pixels whose color is not represented + * in a node at lower depth in the tree; initially, n2 = 0 + * for all nodes except leaves of the tree. + * + * total_red/green/blue : Sums of the red, green, and blue + * component values for all pixels not classified at a lower + * depth. The combination of these sums and n2 will + * ultimately characterize the mean color of a set of pixels + * represented by this node. + */ + void classification() { + int pixels[][] = this.pixels; + + int width = pixels.length; + int height = pixels[0].length; + + // convert to indexed color + for (int x = width; x-- > 0; ) { + for (int y = height; y-- > 0; ) { + int pixel = pixels[x][y]; + int alpha = (pixel >> 24) & 0xFF; + if (alpha != 255) { + hasTrans = true; + continue; // don't add transparent pixels to the cube + } + int red = (pixel >> 16) & 0xFF; + int green = (pixel >> 8) & 0xFF; + int blue = (pixel >> 0) & 0xFF; + + // a hard limit on the number of nodes in the tree + if (nodes > MAX_NODES) { + System.out.println("pruning"); + root.pruneLevel(); + --depth; + } + + // walk the tree to depth, increasing the + // number_pixels count for each node + Node node = root; + for (int level = 1; level <= depth; ++level) { + int id = (((red > node.mid_red ? 1 : 0) << 0) | + ((green > node.mid_green ? 1 : 0) << 1) | + ((blue > node.mid_blue ? 1 : 0) << 2)); + if (node.child[id] == null) { + new Node(node, id, level); + } + node = node.child[id]; + node.number_pixels += SHIFT[level]; + } + + ++node.unique; + node.total_red += red; + node.total_green += green; + node.total_blue += blue; + } + } + + // if we have transparent pixels, that cuts into the number + // of other colors we can use. + if (hasTrans) { + this.max_colors--; + } + } + + /* + * reduction repeatedly prunes the tree until the number of + * nodes with unique > 0 is less than or equal to the maximum + * number of colors allowed in the output image. + * + * When a node to be pruned has offspring, the pruning + * procedure invokes itself recursively in order to prune the + * tree from the leaves upward. The statistics of the node + * being pruned are always added to the corresponding data in + * that node's parent. This retains the pruned node's color + * characteristics for later averaging. + */ + void reduction() { + long threshold = 1; + while (colors > max_colors) { + colors = 0; + threshold = root.reduce(threshold, Long.MAX_VALUE); + } + } + + /** + * The result of a closest color search. + */ + static class Search { + int distance; + int color_number; + } + + /* + * Procedure assignment generates the output image from the + * pruned tree. The output image consists of two parts: (1) A + * color map, which is an array of color descriptions (RGB + * triples) for each color present in the output image; (2) A + * pixel array, which represents each pixel as an index into + * the color map array. + * + * First, the assignment phase makes one pass over the pruned + * color description tree to establish the image's color map. + * For each node with n2 > 0, it divides Sr, Sg, and Sb by n2. + * This produces the mean color of all pixels that classify no + * lower than this node. Each of these colors becomes an entry + * in the color map. + * + * Finally, the assignment phase reclassifies each pixel in + * the pruned tree to identify the deepest node containing the + * pixel's color. The pixel's value in the pixel array becomes + * the index of this node's mean color in the color map. + */ + void assignment() { + colormap = new int[colors]; + colors = 0; + root.colormap(); + + int pixels[][] = this.pixels; + + int width = pixels.length; + int height = pixels[0].length; + + Search search = new Search(); + + int transPad = hasTrans ? 1 : 0; + + // convert to indexed color + for (int x = width; x-- > 0; ) { + for (int y = height; y-- > 0; ) { + int pixel = pixels[x][y]; + int alpha = (pixel >> 24) & 0xFF; + if (alpha != 255) { + pixels[x][y] = 0; // transparent + continue; + } + int red = (pixel >> 16) & 0xFF; + int green = (pixel >> 8) & 0xFF; + int blue = (pixel >> 0) & 0xFF; + + // walk the tree to find the cube containing that color + Node node = root; + for ( ; ; ) { + int id = (((red > node.mid_red ? 1 : 0) << 0) | + ((green > node.mid_green ? 1 : 0) << 1) | + ((blue > node.mid_blue ? 1 : 0) << 2) ); + if (node.child[id] == null) { + break; + } + node = node.child[id]; + } + + if (QUICK) { + // if QUICK is set, just use that + // node. Strictly speaking, this isn't + // necessarily best match. + pixels[x][y] = node.color_number + transPad; + } else { + // Find the closest color. + search.distance = Integer.MAX_VALUE; + node.parent.closestColor(red, green, blue, search); + pixels[x][y] = search.color_number + transPad; + } + } + } + + // expand the colormap by one to account for the transparent + if (hasTrans) { + int[] newcmap = new int[colormap.length + 1]; + System.arraycopy(colormap, 0, newcmap, 1, colormap.length); + colormap = newcmap; + } + } + + /** + * A single Node in the tree. + */ + static class Node { + Cube cube; + + // parent node + Node parent; + + // child nodes + Node child[]; + int nchild; + + // our index within our parent + int id; + // our level within the tree + int level; + // our color midpoint + int mid_red; + int mid_green; + int mid_blue; + + // the pixel count for this node and all children + long number_pixels; + + // the pixel count for this node + int unique; + // the sum of all pixels contained in this node + int total_red; + int total_green; + int total_blue; + + // used to build the colormap + int color_number; + + Node(Cube cube) { + this.cube = cube; + this.parent = this; + this.child = new Node[8]; + this.id = 0; + this.level = 0; + + this.number_pixels = Long.MAX_VALUE; + + this.mid_red = (MAX_RGB + 1) >> 1; + this.mid_green = (MAX_RGB + 1) >> 1; + this.mid_blue = (MAX_RGB + 1) >> 1; + } + + Node(Node parent, int id, int level) { + this.cube = parent.cube; + this.parent = parent; + this.child = new Node[8]; + this.id = id; + this.level = level; + + // add to the cube + ++cube.nodes; + if (level == cube.depth) { + ++cube.colors; + } + + // add to the parent + ++parent.nchild; + parent.child[id] = this; + + // figure out our midpoint + int bi = (1 << (MAX_TREE_DEPTH - level)) >> 1; + mid_red = parent.mid_red + ((id & 1) > 0 ? bi : -bi); + mid_green = parent.mid_green + ((id & 2) > 0 ? bi : -bi); + mid_blue = parent.mid_blue + ((id & 4) > 0 ? bi : -bi); + } + + /** + * Remove this child node, and make sure our parent + * absorbs our pixel statistics. + */ + void pruneChild() { + --parent.nchild; + parent.unique += unique; + parent.total_red += total_red; + parent.total_green += total_green; + parent.total_blue += total_blue; + parent.child[id] = null; + --cube.nodes; + cube = null; + parent = null; + } + + /** + * Prune the lowest layer of the tree. + */ + void pruneLevel() { + if (nchild != 0) { + for (int id = 0; id < 8; id++) { + if (child[id] != null) { + child[id].pruneLevel(); + } + } + } + if (level == cube.depth) { + pruneChild(); + } + } + + /** + * Remove any nodes that have fewer than threshold + * pixels. Also, as long as we're walking the tree: + * + * - figure out the color with the fewest pixels + * - recalculate the total number of colors in the tree + */ + long reduce(long threshold, long next_threshold) { + if (nchild != 0) { + for (int id = 0; id < 8; id++) { + if (child[id] != null) { + next_threshold = child[id].reduce(threshold, next_threshold); + } + } + } + if (number_pixels <= threshold) { + pruneChild(); + } else { + if (unique != 0) { + cube.colors++; + } + if (number_pixels < next_threshold) { + next_threshold = number_pixels; + } + } + return next_threshold; + } + + /* + * colormap traverses the color cube tree and notes each + * colormap entry. A colormap entry is any node in the + * color cube tree where the number of unique colors is + * not zero. + */ + void colormap() { + if (nchild != 0) { + for (int id = 0; id < 8; id++) { + if (child[id] != null) { + child[id].colormap(); + } + } + } + if (unique != 0) { + int r = ((total_red + (unique >> 1)) / unique); + int g = ((total_green + (unique >> 1)) / unique); + int b = ((total_blue + (unique >> 1)) / unique); + cube.colormap[cube.colors] = ((( 0xFF) << 24) | + ((r & 0xFF) << 16) | + ((g & 0xFF) << 8) | + ((b & 0xFF) << 0)); + color_number = cube.colors++; + } + } + + /* ClosestColor traverses the color cube tree at a + * particular node and determines which colormap entry + * best represents the input color. + */ + void closestColor(int red, int green, int blue, Search search) { + if (nchild != 0) { + for (int id = 0; id < 8; id++) { + if (child[id] != null) { + child[id].closestColor(red, green, blue, search); + } + } + } + + if (unique != 0) { + int color = cube.colormap[color_number]; + int distance = distance(color, red, green, blue); + if (distance < search.distance) { + search.distance = distance; + search.color_number = color_number; + } + } + } + + /** + * Figure out the distance between this node and som color. + */ + final static int distance(int color, int r, int g, int b) { + return (SQUARES[((color >> 16) & 0xFF) - r + MAX_RGB] + + SQUARES[((color >> 8) & 0xFF) - g + MAX_RGB] + + SQUARES[((color >> 0) & 0xFF) - b + MAX_RGB]); + } + + public String toString() { + StringBuilder buf = new StringBuilder(); + if (parent == this) { + buf.append("root"); + } else { + buf.append("node"); + } + buf.append(' '); + buf.append(level); + buf.append(" ["); + buf.append(mid_red); + buf.append(','); + buf.append(mid_green); + buf.append(','); + buf.append(mid_blue); + buf.append(']'); + return new String(buf); + } + } + } +} diff --git a/src/java/com/threerings/media/image/TransformedMirage.java b/src/java/com/threerings/media/image/TransformedMirage.java new file mode 100644 index 00000000..87e06fa2 --- /dev/null +++ b/src/java/com/threerings/media/image/TransformedMirage.java @@ -0,0 +1,145 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.image.BufferedImage; + +import com.threerings.media.Log; + +/** + * Draws a mirage combined with an arbitrary AffineTransform. + */ +public class TransformedMirage + implements Mirage +{ + /** + * Constructor. + */ + public TransformedMirage (Mirage base, AffineTransform transform) + { + _base = base; + + // clone the transform so that it doesn't get changed on us. + _transform = (AffineTransform) transform.clone(); + computeTransformedBounds(); + _transform.preConcatenate( + AffineTransform.getTranslateInstance(-_bounds.x, -_bounds.y)); + } + + // documentation inherited from interface Mirage + public void paint (Graphics2D gfx, int x, int y) + { + AffineTransform otrans = gfx.getTransform(); + gfx.translate(x, y); + gfx.transform(_transform); + _base.paint(gfx, 0, 0); + gfx.setTransform(otrans); + } + + // documentation inherited from interface Mirage + public int getWidth () + { + return _bounds.width; + } + + // documentation inherited from interface Mirage + public int getHeight () + { + return _bounds.height; + } + + // documentation inherited from interface Mirage + public boolean hitTest (int x, int y) + { + Point p = new Point(x, y); + try { + _transform.createInverse().transform(p, p); + return _base.hitTest(p.x, p.y); + + } catch (NoninvertibleTransformException nte) { + // grumble, grumble + // TODO: log something? + return ImageUtil.hitTest(getSnapshot(), x, y); + } + } + + // documentation inherited from interface Mirage + public BufferedImage getSnapshot () + { + BufferedImage baseSnap = _base.getSnapshot(); + BufferedImage img = new BufferedImage(_bounds.width, _bounds.height, + baseSnap.getType()); + Graphics2D gfx = (Graphics2D) img.getGraphics(); + try { + gfx.transform(_transform); + gfx.drawImage(baseSnap, 0, 0, null); + } finally { + gfx.dispose(); + } + return img; + } + + // documentation inherited from interface Mirage + public long getEstimatedMemoryUsage () + { + return _base.getEstimatedMemoryUsage(); + } + + /** + * Compute the bounds of the base Mirage after it has been + * transformed. + */ + protected void computeTransformedBounds () + { + int w = _base.getWidth(); + int h = _base.getHeight(); + Point[] points = new Point[] { + new Point(0, 0), new Point(w, 0), new Point(0, h), new Point(w, h) }; + _transform.transform(points, 0, points, 0, 4); + int minX, minY, maxX, maxY; + minX = minY = Integer.MAX_VALUE; + maxX = maxY = Integer.MIN_VALUE; + for (int ii=0; ii < 4; ii++) { + minX = Math.min(minX, points[ii].x); + maxX = Math.max(maxX, points[ii].x); + minY = Math.min(minY, points[ii].y); + maxY = Math.max(maxY, points[ii].y); + } + + _bounds = new Rectangle(minX, minY, maxX - minX, maxY - minY); + } + + /** The base mirage. */ + protected Mirage _base; + + /** Our transformed bounds. */ + protected Rectangle _bounds; + + /** The transform we apply when painting the base mirage. */ + protected AffineTransform _transform; +} diff --git a/src/java/com/threerings/media/image/VolatileMirage.java b/src/java/com/threerings/media/image/VolatileMirage.java new file mode 100644 index 00000000..8717f7fd --- /dev/null +++ b/src/java/com/threerings/media/image/VolatileMirage.java @@ -0,0 +1,202 @@ +// +// $Id: VolatileMirage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.samskivert.util.StringUtil; + +/** + * A mirage implementation which allows the image to be maintained in + * video memory and rebuilt from some source image or images in the event + * that our target screen resolution changes or we are flushed from video + * memory for some other reason. + */ +public abstract class VolatileMirage implements Mirage +{ + /** + * Informs the base class of its image manager and image bounds. + */ + protected VolatileMirage (ImageManager imgr, Rectangle bounds) + { + _imgr = imgr; + _bounds = bounds; + } + + // documentation inherited from interface + public void paint (Graphics2D gfx, int x, int y) + { + // create our volatile image for the first time if necessary + if (_image == null) { + createVolatileImage(); + } + +// int renders = 0; +// do { +// // validate that our image is compatible with the target GC +// switch (_image.validate(_imgr.getGraphicsConfiguration())) { +// case VolatileImage.IMAGE_RESTORED: +// refreshVolatileImage(); // need to rerender it +// break; +// case VolatileImage.IMAGE_INCOMPATIBLE: +// createVolatileImage(); // need to recreate it +// break; +// } + +// // now we can render it +// gfx.drawImage(_image, x, y, null); +// renders++; + +// // don't try forever +// } while (_image.contentsLost() && (renders < 10)); + + if (IMAGE_DEBUG) { + gfx.setColor(new Color(_image.getRGB(_bounds.width/2, + _bounds.height/2))); + gfx.fillRect(x, y, _bounds.width, _bounds.height); + } else { + gfx.drawImage(_image, x, y, null); + } + + // TODO: note number of attempted renders for performance + } + + /** + * Returns the x offset into our source image, which is generally zero but + * may be non-zero for a mirage that obtains its data from a region of its + * source image. + */ + public int getX () + { + return _bounds.x; + } + + /** + * Returns the y offset into our source image, which is generally zero but + * may be non-zero for a mirage that obtains its data from a region of its + * source image. + */ + public int getY () + { + return _bounds.y; + } + + // documentation inherited from interface + public int getWidth () + { + return _bounds.width; + } + + // documentation inherited from interface + public int getHeight () + { + return _bounds.height; + } + + // documentation inherited from interface + public boolean hitTest (int x, int y) + { +// return ImageUtil.hitTest(_image.getSnapshot(), x, y); + return ImageUtil.hitTest(_image, x, y); + } + + // documentation inherited from interface + public long getEstimatedMemoryUsage () + { + return ImageUtil.getEstimatedMemoryUsage(_image.getRaster()); + } + + // documentation inherited from interface + public BufferedImage getSnapshot () + { +// return _image.getSnapshot(); + return _image; + } + + /** + * Creates our volatile image from the information in our source + * image. + */ + protected void createVolatileImage () + { + // release any previous volatile image we might hold + if (_image != null) { + _image.flush(); + } + + // create a new, compatible, volatile image +// _image = _imgr.createVolatileImage( +// _bounds.width, _bounds.height, getTransparency()); + _image = _imgr.createImage( + _bounds.width, _bounds.height, getTransparency()); + + // render our source image into the volatile image + refreshVolatileImage(); + } + + /** + * Returns the transparency that should be used when creating our + * volatile image. + */ + protected abstract int getTransparency (); + + /** + * Rerenders our volatile image from the its source image data. + */ + protected abstract void refreshVolatileImage (); + + /** + * Generates a string representation of this instance. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * Generates a string representation of this instance. + */ + protected void toString (StringBuilder buf) + { + buf.append("bounds=").append(StringUtil.toString(_bounds)); + } + + /** The image manager with whom we interoperate. */ + protected ImageManager _imgr; + + /** The bounds of the region of our source image which we desire for + * this mirage (possibly the whole thing). */ + protected Rectangle _bounds; + + /** Our volatile image which lives in video memory and can go away at + * any time. */ +// protected VolatileImage _image; + protected BufferedImage _image; + + /** Turns off image rendering for testing. */ + protected static final boolean IMAGE_DEBUG = false; +} diff --git a/src/java/com/threerings/media/image/tools/DumpColorPository.java b/src/java/com/threerings/media/image/tools/DumpColorPository.java new file mode 100644 index 00000000..83b35317 --- /dev/null +++ b/src/java/com/threerings/media/image/tools/DumpColorPository.java @@ -0,0 +1,54 @@ +// +// $Id: DumpColorPository.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image.tools; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Iterator; + +import com.threerings.media.image.ColorPository; + +/** + * Simple tool for dumping a serialized color pository. + */ +public class DumpColorPository +{ + public static void main (String[] args) + { + if (args.length == 0) { + System.err.println("Usage: DumpColorPository colorpos.dat"); + System.exit(-1); + } + + try { + ColorPository pos = ColorPository.loadColorPository( + new FileInputStream(args[0])); + Iterator iter = pos.enumerateClasses(); + while (iter.hasNext()) { + System.out.println(iter.next()); + } + + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } + } +} diff --git a/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java b/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java new file mode 100644 index 00000000..e3add99b --- /dev/null +++ b/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java @@ -0,0 +1,78 @@ +// +// $Id: ColorPositoryParser.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.image.tools.xml; + +import java.io.Serializable; + +import org.xml.sax.Attributes; +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.Rule; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.tools.xml.CompiledConfigParser; + +import com.threerings.media.image.ColorPository.ClassRecord; +import com.threerings.media.image.ColorPository.ColorRecord; +import com.threerings.media.image.ColorPository; + +/** + * Parses the XML color repository definition and creates a {@link + * ColorPository} instance that reflects its contents. + */ +public class ColorPositoryParser extends CompiledConfigParser +{ + // documentation inherited + protected Serializable createConfigObject () + { + return new ColorPository(); + } + + // documentation inherited + protected void addRules (Digester digest) + { + // create and configure class record instances + String prefix = "colors/class"; + digest.addObjectCreate(prefix, ClassRecord.class.getName()); + digest.addRule(prefix, new SetPropertyFieldsRule()); + digest.addSetNext(prefix, "addClass", ClassRecord.class.getName()); + + // create and configure color record instances + prefix += "/color"; + digest.addRule(prefix, new Rule() { + public void begin (String namespace, String name, + Attributes attributes) throws Exception { + // we want to inherit settings from the color class when + // creating the record, so we do some custom stuff + ColorRecord record = new ColorRecord(); + ClassRecord clrec = (ClassRecord)digester.peek(); + record.starter = clrec.starter; + digester.push(record); + } + + public void end (String namespace, String name) throws Exception { + digester.pop(); + } + }); + digest.addRule(prefix, new SetPropertyFieldsRule()); + digest.addSetNext(prefix, "addColor", ColorRecord.class.getName()); + } +} diff --git a/src/java/com/threerings/media/sound/MidiPlayer.java b/src/java/com/threerings/media/sound/MidiPlayer.java new file mode 100644 index 00000000..2642be7a --- /dev/null +++ b/src/java/com/threerings/media/sound/MidiPlayer.java @@ -0,0 +1,178 @@ +// +// $Id: MidiPlayer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.BufferedInputStream; +import java.io.InputStream; + +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiChannel; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; + +/** + * Plays midi/rmf sounds using Java's sequencer, which is susceptible + * to the accuracy of System.currentTimeMillis() and so currently sounds + * like "ass" under Windows. + */ +public class MidiPlayer extends MusicPlayer + implements MetaEventListener +{ + // documentation inherited + public void init () + throws Exception + { + _sequencer = MidiSystem.getSequencer(); + _sequencer.open(); + if (_sequencer instanceof Synthesizer) { + _channels = ((Synthesizer) _sequencer).getChannels(); + } + } + + // documentation inherited + public void shutdown () + { + _sequencer.close(); + } + + // documentation inherited + public void start (InputStream stream) + throws Exception + { + _sequencer.setSequence(new BufferedInputStream(stream)); + _sequencer.start(); + _sequencer.addMetaEventListener(this); + } + + // documentation inherited + public void stop () + { + _sequencer.removeMetaEventListener(this); + _sequencer.stop(); + } + + // documentation inherited + public void setVolume (float volume) + { + if (_channels != null) { + int setting = (int) (volume * 127.0); + for (int ii=0; ii < _channels.length; ii++) { + _channels[ii].controlChange(VOLUME_CONTROL, setting); + } + } + } + + // documentation inherited from interface MetaEventListener + public void meta (MetaMessage msg) + { + if (msg.getType() == END_OF_TRACK) { + _musicListener.musicStopped(); + } + } + +// STUFF FROM ANOTHER TIME +// /** +// * Get a list of alternate midi devices. +// */ +// public MidiDevice.Info[] getAlternateMidiDevices () +// { +// ArrayList infos = new ArrayList(); +// CollectionUtil.addAll(infos, MidiSystem.getMidiDeviceInfo()); +// +// // remove the synth/seqs, leaving only hardware midi thingies +// for (Iterator iter=infos.iterator(); iter.hasNext(); ) { +// try { +// MidiDevice dev = MidiSystem.getMidiDevice( +// (MidiDevice.Info) iter.next()); +// if ((dev instanceof Sequencer) || +// (dev instanceof Synthesizer)) { +// iter.remove(); +// } +// } catch (MidiUnavailableException mue) { +// iter.remove(); +// } +// } +// +// return (MidiDevice.Info[]) infos.toArray( +// new MidiDevice.Info[infos.size()]); +// } +// +// /** +// * Attempt to use the alternate midi device for output. +// * Return true if we're using it. +// */ +// public boolean useAlternateDevice (MidiDevice.Info devinfo) +// { +// Log.info("Trying alternate device: " + devinfo); +// try { +// MidiDevice dev = MidiSystem.getMidiDevice(devinfo); +// Receiver rec = dev.getReceiver(); +// if (rec == null) { +// Log.info("Got no device!"); +// return false; +// } +// _stoppingSong = true; +// _sequencer.stop(); +// _sequencer.close(); +// +// Receiver old = _sequencer.getTransmitter().getReceiver(); +// Log.info("Old receiver: " + old); +// if (old != null) { +// old.close(); +// } +// _sequencer.open(); +// +// // THIS DOESN'T WORK. +// // See bug #4347135, specifically notes on the bottom. +// _sequencer.getTransmitter().setReceiver(rec); +// playTopSong(); +// +// // possibly shut down an old receiver +// if (_receiver != null) { +// _receiver.close(); +// } +// // set the new receiver +// _receiver = rec; +// +// return true; +// +// } catch (MidiUnavailableException mue) { +// Log.warning("Use of alternate device failed [e=" + mue + +// ", device=" + devinfo + "]."); +// return false; +// } +// } + + /** This is apparently the midi code for end of track. Wack. */ + protected static final int END_OF_TRACK = 47; + + /** The midi control for volume is 7. Ooooooo. */ + protected static final int VOLUME_CONTROL = 7; + + /** The sequencer. */ + protected Sequencer _sequencer; + + /** The channels in the sequencer, which we'll use to fuxor volumes. */ + protected MidiChannel[] _channels; +} diff --git a/src/java/com/threerings/media/sound/ModPlayer.java b/src/java/com/threerings/media/sound/ModPlayer.java new file mode 100644 index 00000000..af06330f --- /dev/null +++ b/src/java/com/threerings/media/sound/ModPlayer.java @@ -0,0 +1,135 @@ +// +// $Id: ModPlayer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.DataInputStream; +import java.io.InputStream; + +import micromod.MicroMod; +import micromod.Module; +import micromod.ModuleLoader; +import micromod.output.JavaSoundOutputDevice; +import micromod.output.OutputDeviceException; +import micromod.output.converters.SS16LEAudioFormatConverter; +import micromod.resamplers.LinearResampler; + +/** + * A player that plays .mod format music. + */ +public class ModPlayer extends MusicPlayer +{ + // documentation inherited + public void init () + throws Exception + { + _device = new NaryaSoundDevice(); + _device.start(); + } + + // documentation inherited + public void shutdown () + { + _device.stop(); + } + + // documentation inherited + public void start (InputStream stream) + throws Exception + { + Module module = ModuleLoader.read(new DataInputStream(stream)); + + final MicroMod mod = new MicroMod( + module, _device, new LinearResampler()); + + _player = new Thread("narya mod player") { + public void run () { + + while (mod.getSequenceLoopCount() == 0) { + + mod.doRealTimePlayback(); + try { + Thread.sleep(20); + } catch (InterruptedException ie) { + // WFCares + } + + if (_player != Thread.currentThread()) { + // we were stopped! + return; + } + } + _device.drain(); + _musicListener.musicStopped(); + } + }; + + _player.setDaemon(true); + _player.start(); + } + + // documentation inherited + public void stop () + { + _player = null; + } + + // documentation inherited + public void setVolume (float vol) + { + _device.setVolume(vol); + } + + /** + * A class that allows us to access the dataline so we can adjust + * the volume. + */ + protected static class NaryaSoundDevice extends JavaSoundOutputDevice + { + public NaryaSoundDevice () + throws OutputDeviceException + { + super(new SS16LEAudioFormatConverter(), 44100, 1000); + } + + /** + * Adjust the volume of the line that we're sending our mod data to. + */ + public void setVolume (float vol) + { + SoundManager.adjustVolume(sourceDataLine, vol); + } + + /** + * Access the drain method of the line. + */ + public void drain () + { + sourceDataLine.drain(); + } + } + + /** The thread that does the work. */ + protected Thread _player; + + /** The sound output device. */ + protected NaryaSoundDevice _device; +} diff --git a/src/java/com/threerings/media/sound/Mp3Player.java b/src/java/com/threerings/media/sound/Mp3Player.java new file mode 100644 index 00000000..8765faa5 --- /dev/null +++ b/src/java/com/threerings/media/sound/Mp3Player.java @@ -0,0 +1,148 @@ +// +// $Id: Mp3Player.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +import com.threerings.media.Log; + +/** + * Plays mp3 files. Depends on three external jar files that aren't even + * imported here: + * tritonus_share.jar + * tritonus_mp3.jar + * javalayer.jar + */ +public class Mp3Player extends MusicPlayer +{ + // documentation inherited + public void init () + { + // TODO: some stuff needs to move here, like setting up the line + // but we don't yet know the audio format, so I need to figure that + // out (the format might always be known..). + } + + // documentation inherited + public void shutdown () + { + } + + // documentation inherited + public void start (final InputStream stream) + throws Exception + { + // TODO: some stuff needs to come out of here and into init/shutdown + // but we'll deal with all that later, d00d. + _player = new Thread("narya mp3 relay") { + public void run () { + AudioInputStream inStream = null; + try { + inStream = AudioSystem.getAudioInputStream( + new BufferedInputStream(stream, BUFFER_SIZE)); + } catch (Exception e) { + Log.warning("MP3 fuckola. [e=" + e + "]."); + return; + } + + AudioFormat sourceFormat = inStream.getFormat(); + AudioFormat.Encoding targetEnc = + AudioFormat.Encoding.PCM_SIGNED; + + inStream = AudioSystem.getAudioInputStream( + targetEnc, inStream); + AudioFormat format = inStream.getFormat(); + + DataLine.Info info = new DataLine.Info( + SourceDataLine.class, format); + + try { + _line = (SourceDataLine) AudioSystem.getLine(info); + _line.open(format); + } catch (LineUnavailableException lue) { + Log.warning("MP3 line unavailable: " + lue); + return; + } + + _line.start(); + + byte[] data = new byte[BUFFER_SIZE]; + int count = 0; + while (count >= 0) { + try { + count = inStream.read(data, 0, data.length); + } catch (IOException ioe) { + Log.warning("Error reading MP3: " + ioe); + break; + } + if (count >= 0) { + _line.write(data, 0, count); + } + if (_player != Thread.currentThread()) { + return; + } + } + + _line.drain(); + _line.close(); + _musicListener.musicStopped(); + } + }; + + _player.setDaemon(true); + //_player.setPriority(_player.getPriority() + 1); + _player.start(); + } + + // documentation inherited + public void stop () + { + _player = null; + } + + // documentation inherited + public void setVolume (float volume) + { + // TODO : line won't be null when we initialize it in the right place + if (_line != null) { + SoundManager.adjustVolume(_line, volume); + } + } + + /** The thread that transfers data to the line. */ + protected Thread _player; + + /** The line that we play through. */ + protected SourceDataLine _line; + + /** The size of our buffer. */ + protected static final int BUFFER_SIZE = 8192; +} diff --git a/src/java/com/threerings/media/sound/MusicManager.java b/src/java/com/threerings/media/sound/MusicManager.java new file mode 100644 index 00000000..caa03ff9 --- /dev/null +++ b/src/java/com/threerings/media/sound/MusicManager.java @@ -0,0 +1,353 @@ +// +// $Id: SoundManager.java 3290 2004-12-29 21:56:58Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.util.Iterator; +import java.util.LinkedList; + +import com.samskivert.util.Config; +import com.samskivert.util.RandomUtil; +import com.samskivert.util.RunQueue; + +import com.threerings.media.Log; + +/** + * Manages the playing of audio files. + */ +// TODO: +// - fade music out when stopped? +// - be able to pause music +public class MusicManager +{ + /** + * Constructs a music manager. + * + * @param smgr The soundManager we work with. + * @param runQueue the client event run queue. + * + */ + public MusicManager (SoundManager smgr, RunQueue runQueue) + { + _smgr = smgr; + _runQueue = runQueue; + } + + /** + * Shut the damn thing off. + */ + public void shutdown () + { + _musicStack.clear(); + stopMusicPlayer(); + } + + /** + * Returns a string summarizing our volume settings and disabled sound + * types. + */ + public String summarizeState () + { + StringBuilder buf = new StringBuilder(); + buf.append("musicVol=").append(_musicVol); + return buf.append("]").toString(); + } + + /** + * Sets the volume for music. + * + * @param vol a volume parameter between 0f and 1f, inclusive. + */ + public void setMusicVolume (float vol) + { + float oldvol = _musicVol; + _musicVol = Math.max(0f, Math.min(1f, vol)); + if (_musicPlayer != null) { + _musicPlayer.setVolume(_musicVol); + } + + if ((oldvol == 0f) && (_musicVol != 0f)) { + playTopMusic(); + } else if ((oldvol != 0f) && (_musicVol == 0f)) { + stopMusicPlayer(); + } + } + + /** + * Get the music volume. + */ + public float getMusicVolume () + { + return _musicVol; + } + + /** + * Start playing the specified music repeatedly. + */ + public void pushMusic (String pkgPath, String key) + { + pushMusic(pkgPath, key, -1); + } + + /** + * Start playing music for the specified number of loops. If no other + * music is pushed, the specified music will play for the number of loops + * specified, and will then be popped off the stack. + */ + public void pushMusic (String pkgPath, String key, int numloops) + { + MusicKey mkey = new MusicKey(pkgPath, key, numloops); + + // stop any existing playing music + if (_musicPlayer != null) { + _musicPlayer.stop(); + handleMusicStopped(); + } + + // add the new song + _musicStack.addFirst(mkey); + + // and play it + playTopMusic(); + } + + /** + * Remove the specified music from the playlist. If it is currently + * playing, it will be stopped and the previous song will be started. + */ + public void removeMusic (String pkgPath, String key) + { + MusicKey mkey = new MusicKey(pkgPath, key, -1); + + if (!_musicStack.isEmpty()) { + MusicKey current = (MusicKey) _musicStack.getFirst(); + + // if we're currently playing this song.. + if (mkey.equals(current)) { + // stop it + if (_musicPlayer != null) { + _musicPlayer.stop(); + } + + // remove it from the stack + _musicStack.removeFirst(); + // start playing the next.. + playTopMusic(); + return; + + } else { + // we aren't currently playing this song. Simply remove. + for (Iterator iter=_musicStack.iterator(); iter.hasNext(); ) { + if (key.equals(iter.next())) { + iter.remove(); + return; + } + } + + } + } + + Log.debug("Sequence stopped that wasn't in the stack anymore " + + "[key=" + mkey + "]."); + } + + /** + * Start the specified sequence. + */ + protected void playTopMusic () + { + if (_musicStack.isEmpty()) { + return; + } + + // if the volume is off, we don't actually want to play anything + // but we want to at least decrement any loopers by one + // and keep them on the top of the queue + if (_musicVol == 0f) { + handleMusicStopped(); + return; + } + + MusicKey info = (MusicKey) _musicStack.getFirst(); + + Config c = _smgr.getConfig(info); + String[] names = c.getValue(info.key, (String[])null); + if ((names == null) || (names.length == 0)) { + Log.warning("No such music [key=" + info + "]."); + _musicStack.removeFirst(); + playTopMusic(); + return; + } + String music = names[RandomUtil.getInt(names.length)]; + + Class playerClass = getMusicPlayerClass(music); + + // if we don't have a player for this song, play the next song + if (playerClass == null) { + _musicStack.removeFirst(); + playTopMusic(); + return; + } + + // shutdown the old player if we're switching music types + if (! playerClass.isInstance(_musicPlayer)) { + if (_musicPlayer != null) { + _musicPlayer.shutdown(); + } + + // set up the new player + try { + _musicPlayer = (MusicPlayer) playerClass.newInstance(); + _musicPlayer.init(_playerListener); + + } catch (Exception e) { + Log.warning("Unable to instantiate music player [class=" + + playerClass + ", e=" + e + "]."); + + // scrap it, try again with the next song + _musicPlayer = null; + _musicStack.removeFirst(); + playTopMusic(); + return; + } + + _musicPlayer.setVolume(_musicVol); + } + + // play! + String bundle = c.getValue("bundle", (String)null); + try { + // TODO: buffer for the music player? + _musicPlayer.start(_smgr._rmgr.getResource(bundle, music)); + } catch (Exception e) { + Log.warning("Error playing music, skipping [e=" + e + + ", bundle=" + bundle + ", music=" + music + "]."); + _musicStack.removeFirst(); + playTopMusic(); + return; + } + } + + /** + * Get the appropriate music player for the specified music file. + */ + protected static Class getMusicPlayerClass (String path) + { + path = path.toLowerCase(); + +// if (path.endsWith(".mid") || path.endsWith(".rmf")) { +// return MidiPlayer.class; + +// } else if (path.endsWith(".mod")) { +// return ModPlayer.class; + +// } else if (path.endsWith(".mp3")) { +// return Mp3Player.class; + +// } else if (path.endsWith(".ogg")) { +// return OggPlayer.class; + +// } else { + return null; +// } + } + + /** + * Stop whatever song is currently playing and deal with the + * MusicKey associated with it. + */ + protected void handleMusicStopped () + { + if (_musicStack.isEmpty()) { + return; + } + + // see what was playing + MusicKey current = (MusicKey) _musicStack.getFirst(); + + // see how many times the song was to loop and act accordingly + switch (current.loops) { + default: + current.loops--; + break; + + case 1: + // sorry charlie + _musicStack.removeFirst(); + break; + } + } + + /** + * Stop the current music player. + */ + protected void stopMusicPlayer () + { + if (_musicPlayer != null) { + _musicPlayer.stop(); + _musicPlayer.shutdown(); + _musicPlayer = null; + } + } + + /** + * A class that tracks the information about our playing music files. + */ + protected static class MusicKey extends SoundManager.SoundKey + { + /** How many times to loop, or -1 for forever. */ + public int loops; + + public MusicKey (String set, String path, int loops) + { + super((byte) -1, set, path); + this.loops = loops; + } + } + + /** The sound manager we work with. */ + protected SoundManager _smgr; + + /** The client event run queue. */ + protected RunQueue _runQueue; + + /** Volume level for music. */ + protected float _musicVol = 1f; + + /** The stack of songs that we're playing. */ + protected LinkedList _musicStack = new LinkedList(); + + /** The current music player, if any. */ + protected MusicPlayer _musicPlayer; + + /** Event listener for receiving information about a song ending. */ + protected MusicPlayer.MusicEventListener _playerListener = + new MusicPlayer.MusicEventListener() { + public void musicStopped () { + _runQueue.postRunnable(new Runnable() { + public void run() { + handleMusicStopped(); + playTopMusic(); + } + }); + } + }; +} diff --git a/src/java/com/threerings/media/sound/MusicPlayer.java b/src/java/com/threerings/media/sound/MusicPlayer.java new file mode 100644 index 00000000..b42c2a80 --- /dev/null +++ b/src/java/com/threerings/media/sound/MusicPlayer.java @@ -0,0 +1,89 @@ +// +// $Id: MusicPlayer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.InputStream; + +/** + * Abstract music player. + */ +public abstract class MusicPlayer +{ + /** + * A watcher interested in music events. + */ + public interface MusicEventListener + { + /** + * A callback that all players should use when the song they are + * playing has finished playing (completely). + */ + public void musicStopped(); + } + + /** + * Initialize the music player. + */ + public final void init (MusicEventListener musicListener) + throws Exception + { + _musicListener = musicListener; + + init(); + } + + /** + * Do your init here. + */ + public void init () + throws Exception + { + } + + /** + * Shutdown and free all resources. + */ + public void shutdown () + { + } + + /** + * Start playing song data from the specified stream. + */ + public abstract void start (InputStream stream) + throws Exception; + + /** + * Stop playing the specified song. + */ + public abstract void stop (); + + /** + * Set the volume. + * + * @param volume 0f - 1f, inclusive. + */ + public abstract void setVolume (float volume); + + /** Tell this guy about it when a song stops. */ + protected MusicEventListener _musicListener; +} diff --git a/src/java/com/threerings/media/sound/OggPlayer.java b/src/java/com/threerings/media/sound/OggPlayer.java new file mode 100644 index 00000000..15b33bd8 --- /dev/null +++ b/src/java/com/threerings/media/sound/OggPlayer.java @@ -0,0 +1,401 @@ +// +// $Id: OggPlayer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +import com.jcraft.jorbis.*; +import com.jcraft.jogg.*; + +/** + * Plays Ogg Vorbis streams. + * + * Hacked together from NASTY code from JOrbis. + */ +// TODO- this would need to be greatly cleaned up if we were serious about +// using it. +public class OggPlayer extends MusicPlayer +{ + // documentation inherited + public void start (final InputStream stream) + { + _player = new Thread("narya ogg player") { + public void run () { + playStream(stream); + } + }; + _player.setDaemon(true); + _player.start(); + } + + // documentation inherited + public void stop () + { + _player = null; + } + + static final int BUFSIZE=4096*2; + static int convsize=BUFSIZE*2; + static byte[] convbuffer=new byte[convsize]; + + SyncState oy; + StreamState os; + Page og; + Packet op; + Info vi; + Comment vc; + DspState vd; + Block vb; + + byte[] buffer=null; + int bytes=0; + + int format; + int rate=0; + int channels=0; + SourceDataLine outputLine=null; + + int frameSizeInBytes; + int bufferLengthInBytes; + + void init_jorbis(){ + oy=new SyncState(); + os=new StreamState(); + og=new Page(); + op=new Packet(); + + vi=new Info(); + vc=new Comment(); + vd=new DspState(); + vb=new Block(vd); + + buffer=null; + bytes=0; + + oy.init(); + } + + SourceDataLine getOutputLine(int channels, int rate){ + if(outputLine!=null || this.rate!=rate || this.channels!=channels){ + if(outputLine!=null){ + outputLine.drain(); + outputLine.stop(); + outputLine.close(); + } + init_audio(channels, rate); + outputLine.start(); + } + return outputLine; + } + + void init_audio(int channels, int rate){ + try { + //ClassLoader originalClassLoader=null; + //try{ + // originalClassLoader=Thread.currentThread().getContextClassLoader(); + // Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); + //} + //catch(Exception ee){ + // System.out.println(ee); + //} + AudioFormat audioFormat = + new AudioFormat((float)rate, + 16, + channels, + true, // PCM_Signed + false // littleEndian + ); + DataLine.Info info = + new DataLine.Info(SourceDataLine.class, + audioFormat, + AudioSystem.NOT_SPECIFIED); + if (!AudioSystem.isLineSupported(info)) { + //System.out.println("Line " + info + " not supported."); + return; + } + + try{ + outputLine = (SourceDataLine) AudioSystem.getLine(info); + //outputLine.addLineListener(this); + outputLine.open(audioFormat); + } + catch (LineUnavailableException ex) { + System.out.println("Unable to open the sourceDataLine: " + ex); + return; + } + catch (IllegalArgumentException ex) { + System.out.println("Illegal Argument: " + ex); + return; + } + + frameSizeInBytes = audioFormat.getFrameSize(); + int bufferLengthInFrames = outputLine.getBufferSize()/frameSizeInBytes/2; + bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes; + + //buffer = new byte[bufferLengthInBytes]; + //if(originalClassLoader!=null) + // Thread.currentThread().setContextClassLoader(originalClassLoader); + + this.rate=rate; + this.channels=channels; + } + catch(Exception ee){ + System.out.println(ee); + } + } + + protected void playStream (InputStream stream) + { + init_jorbis(); + + loop: + while (true) { + int eos = 0; + + int index = oy.buffer(BUFSIZE); + buffer = oy.data; + try { + bytes = stream.read(buffer, index, BUFSIZE); + } catch (Exception e) { + System.err.println(e); + return; + } + oy.wrote(bytes); + + if (oy.pageout(og) != 1) { + if (bytes < BUFSIZE) { + break; + } + System.err.println("Input does not appear to be an Ogg bitstream."); + return; + } + + os.init(og.serialno()); + os.reset(); + + vi.init(); + vc.init(); + + if (os.pagein(og) < 0) { + // error; stream version mismatch perhaps + System.err.println("Error reading first page of Ogg bitstream data."); + return; + } + + if (os.packetout(op) != 1) { + // no page? must not be vorbis + System.err.println("Error reading initial header packet."); + break; + // return; + } + + if (vi.synthesis_headerin(vc, op) < 0) { + // error case; not a vorbis header + System.err.println("This Ogg bitstream does not contain Vorbis audio data."); + return; + } + + int i=0; + + while (i < 2) { + while (i < 2) { + int result = oy.pageout(og); + if (result==0) { + break; // Need more data + } + if (result==1) { + os.pagein(og); + while (i < 2) { + result = os.packetout(op); + if (result == 0) { + break; + } + if (result == -1) { + System.err.println("Corrupt secondary header. Exiting."); + //return; + break loop; + } + vi.synthesis_headerin(vc, op); + i++; + } + } + } + + index = oy.buffer(BUFSIZE); + buffer = oy.data; + try { + bytes = stream.read(buffer, index, BUFSIZE); + } + catch(Exception e){ + System.err.println(e); + return; + } + + if (bytes == 0 && i < 2) { + System.err.println("End of file before finding all Vorbis headers!"); + return; + } + oy.wrote(bytes); + } + + convsize=BUFSIZE/vi.channels; + + vd.synthesis_init(vi); + vb.init(vd); + + double[][][] _pcm=new double[1][][]; + float[][][] _pcmf=new float[1][][]; + int[] _index=new int[vi.channels]; + + getOutputLine(vi.channels, vi.rate); + + while (eos == 0) { + while (eos == 0) { + + if (_player != Thread.currentThread()) { + //System.err.println("bye."); + try { + //outputLine.drain(); + //outputLine.stop(); + //outputLine.close(); + stream.close(); + } catch(Exception ee) { + } + return; + } + + int result = oy.pageout(og); + if (result == 0) { + break; // need more data + } + if (result == -1) { // missing or corrupt data at this page position + // System.err.println("Corrupt or missing data in bitstream; continuing..."); + + } else { + os.pagein(og); + while (true) { + result = os.packetout(op); + if (result == 0) break; // need more data + if (result == -1) { // missing or corrupt data at this page position + // no reason to complain; already complained above + } else { + // we have a packet. Decode it + int samples; + if (vb.synthesis(op) == 0) { // test for success! + vd.synthesis_blockin(vb); + } + while ((samples = + vd.synthesis_pcmout(_pcmf, _index)) > 0) { + + double[][] pcm = _pcm[0]; + float[][] pcmf = _pcmf[0]; + boolean clipflag = false; + int bout = Math.min(samples, convsize); + + // convert doubles to 16 bit signed ints (host order) and + // interleave + for (i = 0; i < vi.channels; i++) { + int ptr = i*2; + //int ptr=i; + int mono = _index[i]; + for (int j = 0; j < bout; j++) { + int val = (int) + (pcmf[i][mono+j] * 32767.); + if (val > 32767){ + val = 32767; + clipflag = true; + + } else if (val < -32768) { + val = -32768; + clipflag = true; + } + if (val < 0) { + val = val | 0x8000; + } + convbuffer[ptr] = (byte)(val); + convbuffer[ptr+1] = (byte)(val>>>8); + ptr += 2 * (vi.channels); + } + } + outputLine.write(convbuffer, 0, + 2 * vi.channels * bout); + vd.synthesis_read(bout); + } + } + } + if (og.eos() != 0) { + eos=1; + } + } + } + + if (eos==0) { + index = oy.buffer(BUFSIZE); + buffer = oy.data; + try { + bytes = stream.read(buffer,index,BUFSIZE); + + } catch (Exception e) { + System.err.println(e); + return; + } + if (bytes == -1) { + break; + } + oy.wrote(bytes); + if (bytes==0) { + eos=1; + } + } + } + + os.clear(); + vb.clear(); + vd.clear(); + vi.clear(); + } + + oy.clear(); + + //System.err.println("Done."); + + try { + if (stream != null) { + stream.close(); + } + } catch (Exception e) { + } + } + + public void setVolume (float volume) + { + // TODO + } + + protected Thread _player; +} diff --git a/src/java/com/threerings/media/sound/SoundCodes.java b/src/java/com/threerings/media/sound/SoundCodes.java new file mode 100644 index 00000000..ef88ca05 --- /dev/null +++ b/src/java/com/threerings/media/sound/SoundCodes.java @@ -0,0 +1,57 @@ +// +// $Id: SoundCodes.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import com.threerings.media.sound.SoundManager.SoundType; + +/** + * A basic set of sound types. + */ +public interface SoundCodes +{ + /** + * Alert sounds are the type of sounds a player would hear when + * getting a puzzle challenge. + */ + public static final SoundType ALERT = new SoundType("alert"); + + /** + * Feedback sounds are the type of sounds a player would here when + * clicking on buttons or performing an action. + */ + public static final SoundType FEEDBACK = new SoundType("feedback"); + + /** + * Ambient sounds are birds chirping, waves lapping, boats creaking. + */ + public static final SoundType AMBIENT = new SoundType("ambient"); + + /** + * Game alert sounds are used to indicate that it's a player's turn. + */ + public static final SoundType GAME_ALERT = new SoundType("game_alert"); + + /** + * General game sound effects. + */ + public static final SoundType GAME_FX =new SoundType("game_fx"); +} diff --git a/src/java/com/threerings/media/sound/SoundManager.java b/src/java/com/threerings/media/sound/SoundManager.java new file mode 100644 index 00000000..43fc626d --- /dev/null +++ b/src/java/com/threerings/media/sound/SoundManager.java @@ -0,0 +1,1044 @@ +// +// $Id: SoundManager.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; + +import org.apache.commons.io.IOUtils; + +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.util.Config; +import com.samskivert.util.ConfigUtil; +import com.samskivert.util.Interval; +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.Queue; +import com.samskivert.util.RandomUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.resource.ResourceManager; + +import com.threerings.media.Log; +import com.threerings.media.MediaPrefs; + +/** + * Manages the playing of audio files. + */ +public class SoundManager +{ + /** A pan value indicating that a sound should play from the left only. */ + public static final float PAN_LEFT = -1f; + + /** A pan value indicating that a sound should play from the right only. */ + public static final float PAN_RIGHT = 1f; + + /** A pan value indicating that a sound should play from center. */ + public static final float PAN_CENTER = 0f; + + /** + * Create instances of this for your application to differentiate + * between different types of sounds. + */ + public static class SoundType + { + /** + * Construct a new SoundType. + * Which should be a static variable stashed somewhere for the + * entire application to share. + * + * @param strname a short string identifier, preferably without spaces. + */ + public SoundType (String strname) + { + _strname = strname; + } + + public String toString () + { + return _strname; + } + + protected String _strname; + } + + /** + * A control for sounds. + */ + public static interface Frob + { + /** + * Stop playing or looping the sound. + * At present, the granularity of this command is limited to the + * buffer size of the line spooler, or about 8k of data. Thus, + * if playing an 11khz sample, it could take 8/11ths of a second + * for the sound to actually stop playing. + */ + public void stop (); + + /** + * Set the volume of the sound. + */ + public void setVolume (float vol); + + /** + * Get the volume of this sound. + */ + public float getVolume (); + + /** + * Set the pan value for the sound. Valid values are + * -1 for left-only, 0 is centered, all the way to +1 for right-only. + */ + public void setPan (float pan); + + /** + * Get the pan value of this sound. + */ + public float getPan (); + } + + /** The default sound type. */ + public static final SoundType DEFAULT = new SoundType("default"); + + /** + * Constructs a sound manager. + */ + public SoundManager (ResourceManager rmgr) + { + this(rmgr, null, null); + } + + /** + * Constructs a sound manager. + * + * @param defaultClipBundle + * @param defaultClipPath The pathname of a sound clip to use as a + * fallback if another sound clip cannot be located. + */ + public SoundManager ( + ResourceManager rmgr, String defaultClipBundle, String defaultClipPath) + { + // save things off + _rmgr = rmgr; + _defaultClipBundle = defaultClipBundle; + _defaultClipPath = defaultClipPath; + } + + /** + * Shut the damn thing off. + */ + public void shutdown () + { + // TODO: we need to stop any looping sounds + synchronized (_queue) { + _queue.clear(); + if (_spoolerCount > 0) { + _queue.append(new SoundKey(DIE)); // signal death + } + } + synchronized (_clipCache) { + _lockedClips.clear(); + _configs.clear(); + } + } + + /** + * Returns a string summarizing our volume settings and disabled sound + * types. + */ + public String summarizeState () + { + StringBuilder buf = new StringBuilder(); + buf.append("clipVol=").append(_clipVol); + buf.append(", disabled=["); + int ii = 0; + for (Iterator iter = _disabledTypes.iterator(); iter.hasNext(); ) { + if (ii++ > 0) { + buf.append(", "); + } + buf.append(iter.next()); + } + return buf.append("]").toString(); + } + + /** + * Is the specified soundtype enabled? + */ + public boolean isEnabled (SoundType type) + { + // by default, types are enabled.. + return (!_disabledTypes.contains(type)); + } + + /** + * Turns on or off the specified sound type. + */ + public void setEnabled (SoundType type, boolean enabled) + { + if (enabled) { + _disabledTypes.remove(type); + } else { + _disabledTypes.add(type); + } + } + + /** + * Sets the volume for all sound clips. + * + * @param vol a volume parameter between 0f and 1f, inclusive. + */ + public void setClipVolume (float vol) + { + _clipVol = Math.max(0f, Math.min(1f, vol)); + } + + /** + * Get the volume for all sound clips. + */ + public float getClipVolume () + { + return _clipVol; + } + + /** + * Optionally lock the sound data prior to playing, to guarantee + * that it will be quickly available for playing. + */ + public void lock (String pkgPath, String key) + { + enqueue(new SoundKey(LOCK, pkgPath, key), true); + } + + /** + * Unlock the specified sound so that its resources can be freed. + */ + public void unlock (String pkgPath, String key) + { + enqueue(new SoundKey(UNLOCK, pkgPath, key), true); + } + + /** + * Batch lock a list of sounds. + */ + public void lock (String pkgPath, String[] keys) + { + for (int ii=0; ii < keys.length; ii++) { + enqueue(new SoundKey(LOCK, pkgPath, keys[ii]), (ii == 0)); + } + } + + /** + * Batch unlock a list of sounds. + */ + public void unlock (String pkgPath, String[] keys) + { + for (int ii=0; ii < keys.length; ii++) { + enqueue(new SoundKey(UNLOCK, pkgPath, keys[ii]), (ii == 0)); + } + } + + /** + * Play the specified sound as the specified type of sound, immediately. + * Note that a sound need not be locked prior to playing. + */ + public void play (SoundType type, String pkgPath, String key) + { + play(type, pkgPath, key, 0, PAN_CENTER); + } + + /** + * Play the specified sound as the specified type of sound, immediately, + * with the specified pan value. + * Note that a sound need not be locked prior to playing. + * + * @param pan a value from -1f (all left) to +1f (all right). + */ + public void play (SoundType type, String pkgPath, String key, float pan) + { + play(type, pkgPath, key, 0, pan); + } + + /** + * Play the specified sound after the specified delay. + * @param delay the delay in milliseconds. + */ + public void play (SoundType type, String pkgPath, String key, int delay) + { + play(type, pkgPath, key, delay, PAN_CENTER); + } + + /** + * Play the specified sound after the specified delay. + * @param delay the delay in milliseconds. + * @param pan a value from -1f (all left) to +1f (all right). + */ + public void play ( + SoundType type, String pkgPath, String key, int delay, float pan) + { + if (type == null) { + type = DEFAULT; // let the lazy kids play too + } + + if ((_clipVol != 0f) && isEnabled(type)) { + final SoundKey skey = new SoundKey(PLAY, pkgPath, key, delay, + _clipVol, pan); + if (delay > 0) { + new Interval() { + public void expired () { + addToPlayQueue(skey); + } + }.schedule(delay); + } else { + addToPlayQueue(skey); + } + } + } + + /** + * Loop the specified sound. + */ + public Frob loop (SoundType type, String pkgPath, String key) + { + return loop(type, pkgPath, key, PAN_CENTER); + } + + /** + * Loop the specified sound. + */ + public Frob loop (SoundType type, String pkgPath, String key, float pan) + { + if (type == null) { + type = DEFAULT; + } + + if (!isEnabled(type)) { + return null; + } + SoundKey skey = new SoundKey(LOOP, pkgPath, key, 0, _clipVol, pan); + addToPlayQueue(skey); + return skey; // it is a frob + } + + // ==== End of public methods ==== + + /** + * Add the sound clip key to the queue to be played. + */ + protected void addToPlayQueue (SoundKey skey) + { + boolean queued = enqueue(skey, true); + if (queued) { + if (_verbose.getValue()) { + Log.info("Sound request [key=" + skey.key + "]."); + } + + } else /* if (_verbose.getValue()) */ { + Log.warning("SoundManager not playing sound because " + + "too many sounds in queue [key=" + skey + "]."); + } + } + + /** + * Enqueue a new SoundKey. + */ + protected boolean enqueue (SoundKey key, boolean okToStartNew) + { + boolean add; + boolean queued; + synchronized (_queue) { + if (key.cmd == PLAY && _queue.size() > MAX_QUEUE_SIZE) { + queued = add = false; + } else { + _queue.appendLoud(key); + queued = true; + add = okToStartNew && (_freeSpoolers == 0) && + (_spoolerCount < MAX_SPOOLERS); + if (add) { + _spoolerCount++; + } + } + } + + // and if we need a new thread, add it + if (add) { + Thread spooler = new Thread("narya SoundManager line spooler") { + public void run () { + spoolerRun(); + } + }; + spooler.setDaemon(true); + spooler.start(); + } + + return queued; + } + + /** + * This is the primary run method of the sound-playing threads. + */ + protected void spoolerRun () + { + while (true) { + try { + SoundKey key; + synchronized (_queue) { + _freeSpoolers++; + key = (SoundKey) _queue.get(MAX_WAIT_TIME); + _freeSpoolers--; + + if (key == null || key.cmd == DIE) { + _spoolerCount--; + // if dieing and there are others to kill, do so + if (key != null && _spoolerCount > 0) { + _queue.appendLoud(key); + } + return; + } + } + + // process the command + processKey(key); + + } catch (Exception e) { + Log.logStackTrace(e); + } + } + } + + /** + * Process the requested command in the specified SoundKey. + */ + protected void processKey (SoundKey key) + throws Exception + { + switch (key.cmd) { + case PLAY: + case LOOP: + playSound(key); + break; + + case LOCK: + if (!isTesting()) { + synchronized (_clipCache) { + try { + getClipData(key); // preload + // copy cached to lock map + _lockedClips.put(key, _clipCache.get(key)); + } catch (Exception e) { + // don't whine about LOCK failures unless + // we are verbosely logging + if (_verbose.getValue()) { + throw e; + } + } + } + } + break; + + case UNLOCK: + synchronized (_clipCache) { + _lockedClips.remove(key); + } + break; + } + } + + /** + * On a spooling thread, + */ + protected void playSound (SoundKey key) + { + if (!key.running) { + return; + } + key.thread = Thread.currentThread(); + SourceDataLine line = null; + try { + // get the sound data from our LRU cache + byte[] data = getClipData(key); + if (data == null) { + return; // borked! + + } else if (key.isExpired()) { + if (_verbose.getValue()) { + Log.info("Sound expired [key=" + key.key + "]."); + } + return; + + } + + AudioInputStream stream = AudioSystem.getAudioInputStream( + new ByteArrayInputStream(data)); + if (key.cmd == LOOP) { + stream.mark(data.length); + } + + // open the sound line + AudioFormat format = stream.getFormat(); + line = (SourceDataLine) AudioSystem.getLine( + new DataLine.Info(SourceDataLine.class, format)); + line.open(format, LINEBUF_SIZE); + float setVolume = 1; + float setPan = PAN_CENTER; + line.start(); + _soundSeemsToWork = true; + + byte[] buffer = new byte[LINEBUF_SIZE]; + do { + // play the sound + int count = 0; + while (key.running && count != -1) { + float vol = key.volume; + if (vol != setVolume) { + adjustVolume(line, vol); + setVolume = vol; + } + float pan = key.pan; + if (pan != setPan) { + adjustPan(line, pan); + setPan = pan; + } + try { + count = stream.read(buffer, 0, buffer.length); + } catch (IOException e) { + // this shouldn't ever ever happen because the stream + // we're given is from a reliable source + Log.warning("Error reading clip data! [e=" + e + "]."); + return; + } + + if (count >= 0) { + line.write(buffer, 0, count); + } + } + + // if we're going to loop, reset the stream to the beginning + if (key.cmd == LOOP) { + stream.reset(); + } + } while (key.cmd == LOOP && key.running); + + // sleep the drain time. We never trust line.drain() because + // it is buggy and locks up on natively multithreaded systems + // (linux, winXP with HT). + float sampleRate = format.getSampleRate(); + if (sampleRate == AudioSystem.NOT_SPECIFIED) { + sampleRate = 11025; // most of our sounds are + } + int sampleSize = format.getSampleSizeInBits(); + if (sampleSize == AudioSystem.NOT_SPECIFIED) { + sampleSize = 16; + } + int drainTime = (int) Math.ceil( + (LINEBUF_SIZE * 8 * 1000) / (sampleRate * sampleSize)); + + // add in a fudge factor of half a second + drainTime += 500; + + try { + Thread.sleep(drainTime); + } catch (InterruptedException ie) { + } + + } catch (IOException ioe) { + Log.warning("Error loading sound file [key=" + key + + ", e=" + ioe + "]."); + + } catch (UnsupportedAudioFileException uafe) { + Log.warning("Unsupported sound format [key=" + key + + ", e=" + uafe + "]."); + + } catch (LineUnavailableException lue) { + String err = "Line not available to play sound [key=" + key.key + + ", e=" + lue + "]."; + if (_soundSeemsToWork) { + Log.warning(err); + } else { + // this error comes every goddamned time we play a sound on + // someone with a misconfigured sound card, so let's just keep + // it to ourselves + Log.debug(err); + } + + } finally { + if (line != null) { + line.close(); + } + key.thread = null; + } + } + + /** + * @return true if we're using a test sound directory. + */ + protected boolean isTesting () + { + return !StringUtil.isBlank(_testDir.getValue()); + } + + /** + * Called by spooling threads, loads clip data from the resource + * manager or the cache. + */ + protected byte[] getClipData (SoundKey key) + throws IOException, UnsupportedAudioFileException + { + byte[][] data; + boolean verbose = _verbose.getValue(); + synchronized (_clipCache) { + // if we're testing, clear all non-locked sounds every time + if (isTesting()) { + _clipCache.clear(); + } + + data = (byte[][]) _clipCache.get(key); + + // see if it's in the locked cache (we first look in the regular + // clip cache so that locked clips that are still cached continue + // to be moved to the head of the LRU queue) + if (data == null) { + data = (byte[][]) _lockedClips.get(key); + } + + if (data == null) { + // if there is a test sound, JUST use the test sound. + InputStream stream = getTestClip(key); + if (stream != null) { + data = new byte[1][]; + data[0] = IOUtils.toByteArray(stream); + + } else { + // otherwise, randomize between all available sounds + Config c = getConfig(key); + String[] names = c.getValue(key.key, (String[])null); + if (names == null) { + Log.warning("No such sound [key=" + key + "]."); + return null; + } + + data = new byte[names.length][]; + String bundle = c.getValue("bundle", (String)null); + for (int ii=0; ii < names.length; ii++) { + data[ii] = loadClipData(bundle, names[ii]); + } + } + + _clipCache.put(key, data); + } + } + + return (data.length > 0) ? data[RandomUtil.getInt(data.length)] : null; + } + + protected InputStream getTestClip (SoundKey key) + { + String testDirectory = _testDir.getValue(); + if (StringUtil.isBlank(testDirectory)) { + return null; + } + + final String namePrefix = key.key; + File f = new File(testDirectory); + File[] list = f.listFiles(new FilenameFilter() { + public boolean accept (File f, String name) + { + if (name.startsWith(namePrefix)) { + String backhalf = name.substring(namePrefix.length()); + int dot = backhalf.indexOf('.'); + if (dot == -1) { + dot = backhalf.length(); + } + + // allow the file if the portion of the name + // after the prefix but before the extension is blank + // or a parsable integer + String extra = backhalf.substring(0, dot); + if ("".equals(extra)) { + return true; + } else { + try { + Integer.parseInt(extra); + // success! + return true; + } catch (NumberFormatException nfe) { + // not a number, we fall through... + } + } + // else fall through + } + return false; + } + }); + int size = (list == null) ? 0 : list.length; + if (size > 0) { + File pick = list[RandomUtil.getInt(size)]; + try { + return new FileInputStream(pick); + } catch (Exception e) { + Log.warning("Error reading test sound [e=" + e + ", file=" + + pick + "]."); + } + } + return null; + } + + /** + * Read the data from the resource manager. + */ + protected byte[] loadClipData (String bundle, String path) + throws IOException + { + InputStream clipin = null; + try { + clipin = _rmgr.getResource(bundle, path); + } catch (FileNotFoundException fnfe) { + // try from the classpath + try { + clipin = _rmgr.getResource(path); + } catch (FileNotFoundException fnfe2) { + // only play the default sound if we have verbose sound + // debuggin turned on. + if (_verbose.getValue()) { + Log.warning("Could not locate sound data [bundle=" + + bundle + ", path=" + path + "]."); + if (_defaultClipPath != null) { + try { + clipin = _rmgr.getResource( + _defaultClipBundle, _defaultClipPath); + } catch (FileNotFoundException fnfe3) { + try { + clipin = _rmgr.getResource(_defaultClipPath); + } catch (FileNotFoundException fnfe4) { + Log.warning("Additionally, the default " + + "fallback sound could not be located " + + "[bundle=" + _defaultClipBundle + + ", path=" + _defaultClipPath + "]."); + } + } + } else { + Log.warning("No fallback default sound specified!"); + } + } + // if we couldn't load the default, rethrow + if (clipin == null) { + throw fnfe2; + } + } + } + + return IOUtils.toByteArray(clipin); + } + + /** + * Get the cached Config. + */ + protected Config getConfig (SoundKey key) + { + Config c = (Config) _configs.get(key.pkgPath); + if (c == null) { + String propPath = key.pkgPath + Sounds.PROP_NAME; + Properties props = new Properties(); + try { + props = ConfigUtil.loadInheritedProperties( + propPath + ".properties", _rmgr.getClassLoader()); + } catch (IOException ioe) { + Log.warning("Failed to load sound properties " + + "[path=" + propPath + ", error=" + ioe + "]."); + } + c = new Config(propPath, props); + _configs.put(key.pkgPath, c); + } + return c; + } + +// /** +// * Adjust the volume of this clip. +// */ +// protected static void adjustVolumeIdeally (Line line, float volume) +// { +// if (line.isControlSupported(FloatControl.Type.VOLUME)) { +// FloatControl vol = (FloatControl) +// line.getControl(FloatControl.Type.VOLUME); +// +// float min = vol.getMinimum(); +// float max = vol.getMaximum(); +// +// float ourval = (volume * (max - min)) + min; +// Log.debug("adjust vol: [min=" + min + ", ourval=" + ourval + +// ", max=" + max + "]."); +// vol.setValue(ourval); +// +// } else { +// // fall back +// adjustVolume(line, volume); +// } +// } + + /** + * Use the gain control to implement volume. + */ + protected static void adjustVolume (Line line, float vol) + { + FloatControl control = (FloatControl) + line.getControl(FloatControl.Type.MASTER_GAIN); + + // the only problem is that gain is specified in decibals, + // which is a logarithmic scale. + // Since we want max volume to leave the sample unchanged, our + // maximum volume translates into a 0db gain. + float gain; + if (vol == 0f) { + gain = control.getMinimum(); + } else { + gain = (float) ((Math.log(vol) / Math.log(10.0)) * 20.0); + } + + control.setValue(gain); + //Log.info("Set gain: " + gain); + } + + /** + * Set the pan value for the specified line. + */ + protected static void adjustPan (Line line, float pan) + { + try { + FloatControl control = + (FloatControl) line.getControl(FloatControl.Type.PAN); + control.setValue(pan); + } catch (Exception e) { + Log.debug("Cannot set pan on line: " + e); + } + } + + /** + * A key for tracking sounds. + */ + protected static class SoundKey + implements Frob + { + public byte cmd; + + public String pkgPath; + + public String key; + + public long stamp; + + /** Should we still be running? */ + public volatile boolean running = true; + + public volatile float volume; + + /** The pan, or 0 to center the sound. */ + public volatile float pan; + + /** The player thread, if it's playing us. */ + public Thread thread; + + /** + * Create a SoundKey that just contains the specified command. + * DIE. + */ + public SoundKey (byte cmd) + { + this.cmd = cmd; + } + + /** + * Quicky constructor for music keys and lock operations. + */ + public SoundKey (byte cmd, String pkgPath, String key) + { + this(cmd); + this.pkgPath = pkgPath; + this.key = key; + } + + /** + * Constructor for a sound effect soundkey. + */ + public SoundKey (byte cmd, String pkgPath, String key, int delay, + float volume, float pan) + { + this(cmd, pkgPath, key); + + stamp = System.currentTimeMillis() + delay; + setVolume(volume); + setPan(pan); + } + + // documentation inherited from interface Frob + public void stop () + { + running = false; + Thread t = thread; + if (t != null) { + // doesn't actually ever seem to do much + t.interrupt(); + } + } + + // documentation inherited from interface Frob + public void setVolume (float vol) + { + volume = Math.max(0f, Math.min(1f, vol)); + } + + // documentation inherited from interface Frob + public float getVolume () + { + return volume; + } + + // documentation inherited from interface Frob + public void setPan (float newPan) + { + pan = Math.max(PAN_LEFT, Math.min(PAN_RIGHT, newPan)); + } + + // documentation inherited from interface Frob + public float getPan () + { + return pan; + } + + /** + * Has this sound key expired. + */ + public boolean isExpired () + { + return (stamp + MAX_SOUND_DELAY < System.currentTimeMillis()); + } + + // documentation inherited + public String toString () + { + return "SoundKey{cmd=" + cmd + ", pkgPath=" + pkgPath + + ", key=" + key + "}"; + } + + // documentation inherited + public int hashCode () + { + return pkgPath.hashCode() ^ key.hashCode(); + } + + // documentation inherited + public boolean equals (Object o) + { + if (o instanceof SoundKey) { + SoundKey that = (SoundKey) o; + return this.pkgPath.equals(that.pkgPath) && + this.key.equals(that.key); + } + return false; + } + } + + /** The path of the default sound to use for missing sounds. */ + protected String _defaultClipBundle, _defaultClipPath; + + /** The resource manager from which we obtain audio files. */ + protected ResourceManager _rmgr; + + /** The queue of sound clips to be played. */ + protected Queue _queue = new Queue(); + + /** The number of currently active LineSpoolers. */ + protected int _spoolerCount, _freeSpoolers; + + /** If we every play a sound successfully, this is set to true. */ + protected boolean _soundSeemsToWork = false; + + /** Volume level for sound clips. */ + protected float _clipVol = 1f; + + /** The cache of recent audio clips . */ + protected LRUHashMap _clipCache = new LRUHashMap(10); + + /** The set of locked audio clips; this is separate from the LRU so + * that locking clips doesn't booch up an otherwise normal caching + * agenda. */ + protected HashMap _lockedClips = new HashMap(); + + /** A set of soundTypes for which sound is enabled. */ + protected HashSet _disabledTypes = new HashSet(); + + /** A cache of config objects we've created. */ + protected LRUHashMap _configs = new LRUHashMap(5); + + /** Soundkey command constants. */ + protected static final byte PLAY = 0; + protected static final byte LOCK = 1; + protected static final byte UNLOCK = 2; + protected static final byte DIE = 3; + protected static final byte LOOP = 4; + + /** A pref that specifies a directory for us to get test sounds from. */ + protected static RuntimeAdjust.FileAdjust _testDir = + new RuntimeAdjust.FileAdjust( + "Test sound directory", "narya.media.sound.test_dir", + MediaPrefs.config, true, ""); + + protected static RuntimeAdjust.BooleanAdjust _verbose = + new RuntimeAdjust.BooleanAdjust( + "Verbose sound event logging", "narya.media.sound.verbose", + MediaPrefs.config, false); + + /** The queue size at which we start to ignore requests to play sounds. */ + protected static final int MAX_QUEUE_SIZE = 25; + + /** The maximum time after which we throw away a sound rather + * than play it. */ + protected static final long MAX_SOUND_DELAY = 400L; + + /** The size of the line's buffer. */ + protected static final int LINEBUF_SIZE = 8 * 1024; + + /** The maximum time a spooler will wait for a stream before + * deciding to shut down. */ + protected static final long MAX_WAIT_TIME = 30000L; + + /** The maximum number of spoolers we'll allow. This is a lot. */ + protected static final int MAX_SPOOLERS = 12; +} diff --git a/src/java/com/threerings/media/sound/Sounds.java b/src/java/com/threerings/media/sound/Sounds.java new file mode 100644 index 00000000..ecca07a7 --- /dev/null +++ b/src/java/com/threerings/media/sound/Sounds.java @@ -0,0 +1,49 @@ +// +// $Id: Sounds.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +/** + * A base class for sound repository classes. These would extend this + * class and define keys for the various sounds that are mapped in the + * properties file associated with that sound repository. + */ +public class Sounds +{ + /** The name of the sound repository configuration file. */ + public static final String PROP_NAME = "sounds"; + + /** + * Return the package path prefix of the supplied class. + * + * Generates the key for the sound repository configuration file in + * the package associated with the class. For example, if a the class + * com.threerings.happy.fun.GameSounds were supplied to + * this method, it would return + * com/threerings/happy/fun/sounds/ which would reference + * a sounds.properties file in the + * com.threerings.happy.fun package. + */ + protected static String getPackagePath (Class clazz) + { + return clazz.getPackage().getName().replace('.', '/') + "/"; + } +} diff --git a/src/java/com/threerings/media/sprite/ButtonSprite.java b/src/java/com/threerings/media/sprite/ButtonSprite.java new file mode 100644 index 00000000..e79e3c6b --- /dev/null +++ b/src/java/com/threerings/media/sprite/ButtonSprite.java @@ -0,0 +1,384 @@ +// +// $Id: ButtonSprite.java 3509 2005-04-20 17:15:36Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Shape; + +import com.samskivert.swing.Label; +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.sprite.action.ArmingSprite; +import com.threerings.media.sprite.action.CommandSprite; +import com.threerings.media.sprite.action.DisableableSprite; + +/** + * A sprite that acts as a button. + */ +public class ButtonSprite extends Sprite + implements CommandSprite, ArmingSprite, DisableableSprite +{ + /** The normal, square button style. */ + public static final int NORMAL = 0; + + /** The rounded button style. */ + public static final int ROUNDED = 1; + + /** + * Constructs a button sprite. + * + * @param label the label to render on the button + * @param style the style of button to render (NORMAL or ROUNDED) + * @param backgroundColor the background color of the button + * @param alternateColor the alternate (outline) color + * @param actionCommand the button's command + * @param commandArgument the button's command argument + */ + public ButtonSprite (Label label, int style, Color backgroundColor, + Color alternateColor, String actionCommand, Object commandArgument) + { + _label = label; + _style = style; + _backgroundColor = backgroundColor; + _alternateColor = alternateColor; + _actionCommand = actionCommand; + _commandArgument = commandArgument; + } + + /** + * Constructs a button sprite. + * + * @param label the label to render on the button + * @param style the style of button to render (NORMAL or ROUNDED) + * @param arcWidth the width of the corner arcs for rounded buttons + * @param arcHeight the height of the corner arcs for rounded buttons + * @param backgroundColor the background color of the button + * @param alternateColor the alternate (outline) color + * @param actionCommand the button's command + * @param commandArgument the button's command argument + */ + public ButtonSprite (Label label, int style, int arcWidth, int arcHeight, + Color backgroundColor, Color alternateColor, String actionCommand, + Object commandArgument) + { + _label = label; + _style = style; + _arcWidth = arcWidth; + _arcHeight = arcHeight; + _backgroundColor = backgroundColor; + _alternateColor = alternateColor; + _actionCommand = actionCommand; + _commandArgument = commandArgument; + } + + /** + * Returns a reference to the label displayed by this sprite. + */ + public Label getLabel () + { + return _label; + } + + /** + * Updates this sprite's bounds after a change to the label. + */ + public void updateBounds () + { + // invalidate the old... + invalidate(); + + // size the bounds to fit our label + Dimension size = _label.getSize(); + _bounds.width = size.width + PADDING*2 + + (_style == ROUNDED ? _arcWidth : 0); + _bounds.height = size.height + PADDING*2; + + // ...and the new + invalidate(); + } + + /** + * Sets the style of this button. + */ + public void setStyle (int style) + { + _style = style; + updateBounds(); + } + + /** + * Returns the style of this button. + */ + public int getStyle () + { + return _style; + } + + /** + * Sets the arc width for rounded buttons. + */ + public void setArcWidth (int arcWidth) + { + _arcWidth = arcWidth; + updateBounds(); + } + + /** + * Returns the arc width for rounded buttons. + */ + public int getArcWidth () + { + return _arcWidth; + } + + /** + * Sets the arc height for rounded buttons. + */ + public void setArcHeight (int arcHeight) + { + _arcHeight = arcHeight; + updateBounds(); + } + + /** + * Returns the arc height for rounded buttons. + */ + public int getArcHeight () + { + return _arcHeight; + } + + /** + * Sets the background color of this button. + */ + public void setBackgroundColor (Color backgroundColor) + { + _backgroundColor = backgroundColor; + } + + /** + * Returns the background color of this button. + */ + public Color getBackgroundColor () + { + return _backgroundColor; + } + + /** + * Sets the action command generated by this button. + */ + public void setActionCommand (String actionCommand) + { + _actionCommand = actionCommand; + } + + // documentation inherited from interface CommandSprite + public String getActionCommand () + { + return _actionCommand; + } + + /** + * Sets the command argument generated by this button. + */ + public void setCommandArgument (Object commandArgument) + { + _commandArgument = commandArgument; + } + + // documentation inherited from interface CommandSprite + public Object getCommandArgument () + { + return _commandArgument; + } + + /** + * Sets whether or not this button is enabled. + */ + public void setEnabled (boolean enabled) + { + if (_enabled != enabled) { + _enabled = enabled; + invalidate(); + } + } + + // documentation inherited from interface DisableableSprite + public boolean isEnabled () + { + return _enabled; + } + + // documentation inherited from interface ArmingSprite + public void setArmed (boolean pressed) + { + if (_pressed != pressed) { + _pressed = pressed; + invalidate(); + } + } + + /** + * Checks whether or not this button appears pressed. + */ + public boolean isArmed () + { + return _pressed; + } + + // documentation inherited + protected void init () + { + super.init(); + + // lay out the label if not already + if (!_label.isLaidOut()) { + _label.layout(_mgr.getMediaPanel()); + } + + updateBounds(); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + Color baseTextColor = _label.getTextColor(), + baseAlternateColor = _label.getAlternateColor(); + + if (!_enabled) { + _label.setTextColor(baseTextColor.darker()); + _label.setAlternateColor(baseAlternateColor.darker()); + } + + switch (_style) { + case NORMAL: + gfx.setColor(_enabled ? _backgroundColor : + _backgroundColor.darker()); + gfx.fill3DRect(_bounds.x, _bounds.y, _bounds.width, + _bounds.height, !_pressed); + _label.render(gfx, _bounds.x + (_pressed ? PADDING : + PADDING - 1), _bounds.y + (_pressed ? PADDING : + PADDING - 1)); + break; + case ROUNDED: + Object aaState = SwingUtil.activateAntiAliasing(gfx); + // draw outline + gfx.setColor(_alternateColor); + gfx.fillRoundRect(_bounds.x, _bounds.y, _bounds.width, + _bounds.height, _arcWidth, _arcHeight); + // draw foreground + gfx.setColor(_enabled ? _backgroundColor : + _backgroundColor.darker()); + int innerBoundsX = _bounds.x+1, innerBoundsY = _bounds.y+1, + innerBoundsWidth = _bounds.width-2, + innerBoundsHeight = _bounds.height-2, + innerBoundsArcWidth = _arcWidth-2, + innerBoundsArcHeight = _arcHeight-2; + gfx.fillRoundRect(innerBoundsX, innerBoundsY, + innerBoundsWidth, innerBoundsHeight, + innerBoundsArcWidth, innerBoundsArcHeight); + Color brighter = _enabled ? _backgroundColor.brighter() : + _backgroundColor, darker = _enabled ? + _backgroundColor.darker() : + _backgroundColor.darker().darker(); + // draw the upper left/lower right corners (always dark) + gfx.setColor(darker); + gfx.drawArc(innerBoundsX, innerBoundsY, innerBoundsArcWidth, + innerBoundsArcHeight, 90, 90); + gfx.drawArc(innerBoundsX + innerBoundsWidth - + innerBoundsArcWidth - 1, + innerBoundsY + innerBoundsHeight - + innerBoundsArcHeight - 1, + innerBoundsArcWidth, innerBoundsArcHeight, 270, 90); + // draw the upper right (dark when pressed) + gfx.setColor(_pressed ? darker : brighter); + gfx.drawLine(innerBoundsX + innerBoundsArcWidth/2, + innerBoundsY, innerBoundsX + innerBoundsWidth - + innerBoundsArcWidth/2, innerBoundsY); + gfx.drawArc(innerBoundsX + innerBoundsWidth - + innerBoundsArcWidth - 1, innerBoundsY, + innerBoundsArcWidth, innerBoundsArcHeight, 0, 90); + gfx.drawLine(innerBoundsX + innerBoundsWidth - 1, + innerBoundsY + innerBoundsArcHeight/2, + innerBoundsX + innerBoundsWidth - 1, innerBoundsY + + innerBoundsHeight - innerBoundsArcHeight/2); + // draw the lower left (light when pressed) + gfx.setColor(_pressed ? brighter : darker); + gfx.drawLine(innerBoundsX, innerBoundsY + + innerBoundsArcHeight/2, innerBoundsX, + innerBoundsY + innerBoundsHeight - + innerBoundsArcHeight/2); + gfx.drawArc(innerBoundsX, innerBoundsY + innerBoundsHeight - + innerBoundsArcHeight - 1, + innerBoundsArcWidth, innerBoundsArcHeight, 180, 90); + gfx.drawLine(innerBoundsX + innerBoundsArcWidth/2, + innerBoundsY + innerBoundsHeight - 1, + innerBoundsX + innerBoundsWidth - innerBoundsArcWidth/2, + innerBoundsY + innerBoundsHeight - 1); + SwingUtil.restoreAntiAliasing(gfx, aaState); + _label.render(gfx, _bounds.x + PADDING + _arcWidth/2 - + (_pressed ? 2 : 1), + _bounds.y + PADDING + (_pressed ? 1 : 0)); + break; + } + + if (!_enabled) { + _label.setTextColor(baseTextColor); + _label.setAlternateColor(baseAlternateColor); + } + } + + /** The number of pixels to add between the text and the border. */ + protected static final int PADDING = 2; + + /** The label associated with this sprite. */ + protected Label _label; + + /** The button style. */ + protected int _style; + + /** The width of the corner arcs for rounded rectangle buttons. */ + protected int _arcWidth; + + /** The height of the corner arcs for rounded rectangle buttons. */ + protected int _arcHeight; + + /** The action command generated by this button. */ + protected String _actionCommand; + + /** The command argument generated by this button. */ + protected Object _commandArgument; + + /** The background color of this sprite. */ + protected Color _backgroundColor; + + /** The alternate (outline) color of this sprite. */ + protected Color _alternateColor; + + /** Whether or not the button is currently enabled. */ + protected boolean _enabled = true; + + /** Whether or not the button is currently pressed. */ + protected boolean _pressed; +} diff --git a/src/java/com/threerings/media/sprite/FadableImageSprite.java b/src/java/com/threerings/media/sprite/FadableImageSprite.java new file mode 100644 index 00000000..6d9a5be0 --- /dev/null +++ b/src/java/com/threerings/media/sprite/FadableImageSprite.java @@ -0,0 +1,203 @@ +package com.threerings.media.sprite; + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.Composite; + +import com.threerings.media.util.Path; + +public class FadableImageSprite extends OrientableImageSprite +{ + /** + * Fades this sprite in over the specified duration after + * waiting for the specified delay. + */ + public void fadeIn (long delay, long duration) + { + setAlpha(0.0f); + + _fadeStamp = 0; + _fadeDelay = delay; + _fadeInDuration = duration; + } + + /** + * Puts this sprite on the specified path and fades it in over + * the specified duration. + * + * @param path the path to move along + * @param fadePortion the portion of time to spend fading in, from 0.0f + * (no time) to 1.0f (the entire time) + */ + public void moveAndFadeIn (Path path, long pathDuration, float fadePortion) + { + move(path); + + setAlpha(0.0f); + + _fadeInDuration = (long)(pathDuration*fadePortion); + } + + /** + * Puts this sprite on the specified path and fades it out over + * the specified duration. + * + * @param path the path to move along + * @param pathDuration the duration of the path + * @param fadePortion the portion of time to spend fading out, from 0.0f + * (no time) to 1.0f (the entire time) + */ + public void moveAndFadeOut (Path path, long pathDuration, float fadePortion) + { + move(path); + + setAlpha(1.0f); + + _pathDuration = pathDuration; + _fadeOutDuration = (long)(pathDuration*fadePortion); + } + + /** + * Puts this sprite on the specified path, fading it in over the specified + * duration at the beginning and fading it out at the end. + * + * @param path the path to move along + * @param pathDuration the duration of the path + * @param fadePortion the portion of time to spend fading in/out, from + * 0.0f (no time) to 1.0f (the entire time) + */ + public void moveAndFadeInAndOut (Path path, long pathDuration, + float fadePortion) + { + move(path); + + setAlpha(0.0f); + + _pathDuration = pathDuration; + _fadeInDuration = _fadeOutDuration = (long)(pathDuration*fadePortion); + } + + // Documentation inherited. + public void tick (long tickStamp) + { + super.tick(tickStamp); + + if (_fadeInDuration != -1) { + if (_path != null && (tickStamp-_pathStamp) <= _fadeInDuration) { + // fading in while moving + float alpha = (float)(tickStamp-_pathStamp)/_fadeInDuration; + if (alpha >= 1.0f) { + // fade-in complete + setAlpha(1.0f); + _fadeInDuration = -1; + + } else { + setAlpha(alpha); + } + + } else { + // fading in while stationary + if (_fadeStamp == 0) { + // store the time at which fade started + _fadeStamp = tickStamp; + } + if (tickStamp > _fadeStamp + _fadeDelay) { + // initial delay has passed + float alpha = (float)(tickStamp-_fadeStamp-_fadeDelay)/ + _fadeInDuration; + if (alpha >= 1.0f) { + // fade-in complete + setAlpha(1.0f); + _fadeInDuration = -1; + + } else { + setAlpha(alpha); + } + } + } + + } else if (_fadeOutDuration != -1 && _pathStamp+_pathDuration-tickStamp + <= _fadeOutDuration) { + // fading out while moving + float alpha = (float)(_pathStamp+_pathDuration-tickStamp)/ + _fadeOutDuration; + setAlpha(alpha); + } + } + + // Documentation inherited. + public void pathCompleted (long timestamp) + { + super.pathCompleted(timestamp); + + if (_fadeInDuration != -1) { + setAlpha(1.0f); + _fadeInDuration = -1; + + } else if (_fadeOutDuration != -1) { + setAlpha(0.0f); + _fadeOutDuration = -1; + } + } + + // Documentation inherited. + public void paint (Graphics2D gfx) + { + if (_alphaComposite.getAlpha() < 1.0f) { + Composite ocomp = gfx.getComposite(); + gfx.setComposite(_alphaComposite); + super.paint(gfx); + gfx.setComposite(ocomp); + + } else { + super.paint(gfx); + } + } + + /** + * Sets the alpha value of this sprite. + */ + public void setAlpha (float alpha) + { + if (alpha < 0.0f) { + alpha = 0.0f; + + } else if (alpha > 1.0f) { + alpha = 1.0f; + } + if (alpha != _alphaComposite.getAlpha()) { + _alphaComposite = + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); + if (_mgr != null) { + _mgr.getRegionManager().invalidateRegion(_bounds); + } + } + } + + /** + * Returns the alpha value of this sprite. + */ + public float getAlpha () + { + return _alphaComposite.getAlpha(); + } + + /** The alpha composite. */ + protected AlphaComposite _alphaComposite = + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f); + + /** If fading in, the fade-in duration (otherwise -1). */ + protected long _fadeInDuration = -1; + + /** If fading in without moving, the fade-in delay. */ + protected long _fadeDelay; + + /** The time at which fading started. */ + protected long _fadeStamp = -1; + + /** If fading out, the fade-out duration (otherwise -1). */ + protected long _fadeOutDuration = -1; + + /** If fading out, the path duration. */ + protected long _pathDuration; +} diff --git a/src/java/com/threerings/media/sprite/ImageSprite.java b/src/java/com/threerings/media/sprite/ImageSprite.java new file mode 100644 index 00000000..a590db6c --- /dev/null +++ b/src/java/com/threerings/media/sprite/ImageSprite.java @@ -0,0 +1,331 @@ +// +// $Id: ImageSprite.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.threerings.media.image.Mirage; +import com.threerings.media.util.MultiFrameImage; +import com.threerings.media.util.SingleFrameImageImpl; + +/** + * Extends the sprite class to support rendering the sprite with one or + * more frames of image animation. Overrides various methods to provide + * correspondingly desirable functionality, e.g., {@link #hitTest} only + * reports a hit if the specified point is within a non-transparent pixel + * for the sprite's current image frame. + */ +public class ImageSprite extends Sprite +{ + /** Default frame rate. */ + public static final int DEFAULT_FRAME_RATE = 15; + + /** Animation mode indicating no animation. */ + public static final int NO_ANIMATION = 0; + + /** Animation mode indicating movement cued animation. */ + public static final int MOVEMENT_CUED = 1; + + /** Animation mode indicating time based animation. */ + public static final int TIME_BASED = 2; + + /** Animation mode indicating sequential progressive animation. + * Frame 0 is guaranteed to be shown first for the full duration, and + * so on. */ + public static final int TIME_SEQUENTIAL = 3; + + /** + * Constructs an image sprite without any associated frames and with + * an invalid default initial location. The sprite should be populated + * with a set of frames used to display it via a subsequent call to + * {@link #setFrames}, and its location updated with {@link + * #setLocation}. + */ + public ImageSprite () + { + this((MultiFrameImage)null); + } + + /** + * Constructs an image sprite. + * + * @param frames the multi-frame image used to display the sprite. + */ + public ImageSprite (MultiFrameImage frames) + { + // initialize frame animation member data + _frames = frames; + _frameIdx = 0; + _animMode = NO_ANIMATION; + _frameDelay = 1000L/DEFAULT_FRAME_RATE; + } + + /** + * Constructs an image sprite that will display the supplied single + * image when rendering itself. + */ + public ImageSprite (Mirage image) + { + this(new SingleFrameImageImpl(image)); + } + + // documentation inherited + protected void init () + { + super.init(); + + // now that we have our sprite manager, we can lay ourselves out + // and initialize our frames + layout(); + } + + /** + * Returns true if the sprite's bounds contain the specified point, + * and if there is a non-transparent pixel in the sprite's image at + * the specified point, false if not. + */ + public boolean hitTest (int x, int y) + { + // first check to see that we're in the sprite's bounds and that + // we've got a frame image (if we've got no image, there's nothing + // to be hit) + if (!super.hitTest(x, y) || _frames == null) { + return false; + } + + return _frames.hitTest(_frameIdx, x - _bounds.x, y - _bounds.y); + } + + /** + * Sets the animation mode for this sprite. The available modes are: + * + *
    + *
  • TIME_BASED: cues the animation based on a target + * frame rate (specified via {@link #setFrameRate}). + *
  • MOVEMENT_CUED: ticks the animation to the next + * frame every time the sprite is moved along its path. + *
  • NO_ANIMATION: disables animation. + *
+ * + * @param mode the desired animation mode. + */ + public void setAnimationMode (int mode) + { + _animMode = mode; + } + + /** + * Sets the number of frames per second desired for the sprite + * animation. This is only used when the animation mode is + * TIME_BASED. + * + * @param fps the desired frames per second. + */ + public void setFrameRate (float fps) + { + _frameDelay = (long)(1000/fps); + } + + /** + * Set the image to be used for this sprite. + */ + public void setMirage (Mirage mirage) + { + setFrames(new SingleFrameImageImpl(mirage)); + } + + /** + * Set the image array used to render the sprite. + * + * @param frames the sprite images. + */ + public void setFrames (MultiFrameImage frames) + { + if (frames == null) { + // Log.warning("Someone set up us the null frames! " + + // "[sprite=" + this + "]."); + return; + } + + // if these are the same frames we already had, no need to do a + // bunch of pointless business + if (frames == _frames) { + return; + } + + // set and init our frames + _frames = frames; + _frameIdx = 0; + layout(); + } + + /** + * Instructs this sprite to lay out its current frame and any + * accoutrements. + */ + public void layout () + { + if (_frames != null) { + setFrameIndex(_frameIdx, true); + } + } + + /** + * Instructs the sprite to display the specified frame index. + */ + protected void setFrameIndex (int frameIdx, boolean forceUpdate) + { + // make sure we're displaying a valid frame + frameIdx = (frameIdx % _frames.getFrameCount()); + + // if this is the same frame we're already displaying and we're + // not being forced to update, we can stop now + if (frameIdx == _frameIdx && !forceUpdate) { + return; + } else { + _frameIdx = frameIdx; + } + + // start with our old bounds + Rectangle dirty = new Rectangle(_bounds); + + // determine our drawing offsets and rendered rectangle size + accomodateFrame(_frameIdx, _frames.getWidth(_frameIdx), + _frames.getHeight(_frameIdx)); + + // add our new bounds + dirty.add(_bounds); + + // give the dirty rectangle to the region manager + if (_mgr != null) { + _mgr.getRegionManager().addDirtyRegion(dirty); + } + } + + /** + * Must adjust the bounds to accomodate the our new frame. This + * includes changing the width and height to reflect the size of the + * new frame and also updating the render origin (if necessary) and + * calling {@link #updateRenderOrigin} to reflect those changes in the + * sprite's bounds. + * + * @param frameIdx the index of our new frame. + * @param width the width of the new frame. + * @param height the height of the new frame. + */ + protected void accomodateFrame (int frameIdx, int width, int height) + { + _bounds.width = width; + _bounds.height = height; + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + if (_frames != null) { +// // DEBUG: fill our background with an alpha'd rectangle +// Composite ocomp = gfx.getComposite(); +// gfx.setComposite(ALPHA_BOUNDS); +// gfx.setColor(Color.blue); +// gfx.fill(_bounds); +// gfx.setComposite(ocomp); + + // render our frame + _frames.paintFrame(gfx, _frameIdx, _bounds.x, _bounds.y); + + } else { + super.paint(gfx); + } + } + + // documentation inherited + public void tick (long timestamp) + { + // if we have no frames, we're hosulated (to use a Greenwell term) + if (_frames == null) { + return; + } + + int fcount = _frames.getFrameCount(); + boolean moved = false; + + // move the sprite along toward its destination, if any + moved = tickPath(timestamp); + + // increment the display image if performing image animation + int nfidx = _frameIdx; + switch (_animMode) { + case NO_ANIMATION: + // nothing doing + break; + + case TIME_BASED: + nfidx = (int)((timestamp/_frameDelay) % fcount); + break; + + case TIME_SEQUENTIAL: + if (_firstStamp == 0L) { + _firstStamp = timestamp; + } + nfidx = (int) (((timestamp - _firstStamp) / _frameDelay) % fcount); + break; + + case MOVEMENT_CUED: + // update the frame if the sprite moved + if (moved) { + nfidx = (_frameIdx + 1) % fcount; + } + break; + } + + // update our frame (which will do nothing if this is the same as + // our existing frame index) + setFrameIndex(nfidx, false); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", fidx=").append(_frameIdx); + } + + /** The images used to render the sprite. */ + protected MultiFrameImage _frames; + + /** The current frame index to render. */ + protected int _frameIdx; + + /** What type of animation is desired for this sprite. */ + protected int _animMode; + + /** For how many milliseconds to display an animation frame. */ + protected long _frameDelay; + + /** The first timestamp seen (in TIME_SEQUENTIAL mode). */ + protected long _firstStamp = 0L; + +// /** DEBUG: The alpha level used when rendering our bounds. */ +// protected static final Composite ALPHA_BOUNDS = +// AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f); +} diff --git a/src/java/com/threerings/media/sprite/LabelSprite.java b/src/java/com/threerings/media/sprite/LabelSprite.java new file mode 100644 index 00000000..00c930d1 --- /dev/null +++ b/src/java/com/threerings/media/sprite/LabelSprite.java @@ -0,0 +1,115 @@ +// +// $Id: LabelSprite.java 3542 2005-05-06 03:01:43Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +import com.samskivert.swing.Label; + +/** + * A sprite that uses a label to render itself. If the label has not been + * previously laid out (see {@link Label#layout}) it will be done when the + * sprite is added to a media panel. If the label is altered after the + * sprite is created, {@link #updateBounds} should be called. + */ +public class LabelSprite extends Sprite +{ + /** + * Constructs a label sprite that renders itself with the specified + * label. + */ + public LabelSprite (Label label) + { + _label = label; + } + + /** + * Returns the label displayed by this sprite. + */ + public Label getLabel () + { + return _label; + } + + /** + * Indicates that our label should be rendered with antialiased text. + */ + public void setAntiAliased (boolean antiAliased) + { + _antiAliased = antiAliased; + } + + /** + * Updates the bounds of the sprite after a change to the label. + */ + public void updateBounds () + { + Dimension size = _label.getSize(); + _bounds.width = size.width; + _bounds.height = size.height; + } + + // documentation inherited + protected void init () + { + super.init(); + + // if our label is not yet laid out, do the deed + if (!_label.isLaidOut()) { + layoutLabel(); + } + + // size the bounds to fit our label + updateBounds(); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + _label.render(gfx, _bounds.x, _bounds.y); + } + + /** + * Lays out our underlying label which must be done if the text is + * changed. + */ + protected void layoutLabel () + { + Graphics2D gfx = (Graphics2D)_mgr.getMediaPanel().getGraphics(); + if (gfx != null) { + gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + (_antiAliased) ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + _label.layout(gfx); + gfx.dispose(); + } + } + + /** The label associated with this sprite. */ + protected Label _label; + + /** Whether or not to use anti-aliased rendering. */ + protected boolean _antiAliased; +} diff --git a/src/java/com/threerings/media/sprite/OrientableImageSprite.java b/src/java/com/threerings/media/sprite/OrientableImageSprite.java new file mode 100644 index 00000000..bbee94fa --- /dev/null +++ b/src/java/com/threerings/media/sprite/OrientableImageSprite.java @@ -0,0 +1,198 @@ +// +// $Id: OrientableImageSprite.java 3586 2005-06-05 16:41:10Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; + +import java.awt.image.*; + +import com.threerings.media.image.Mirage; + +import com.threerings.media.util.MultiFrameImage; + +/** + * An image sprite that uses AWT's rotation methods to render itself in + * different orientations. + */ +public class OrientableImageSprite extends ImageSprite +{ + /** + * Creates a new orientable image sprite. + */ + public OrientableImageSprite () + {} + + /** + * Creates a new orientable image sprite. + * + * @param image the image to render + */ + public OrientableImageSprite (Mirage image) + { + super(image); + } + + /** + * Creates a new orientable image sprite. + * + * @param frames the frames to render + */ + public OrientableImageSprite (MultiFrameImage frames) + { + super(frames); + } + + /** + * Computes and returns the rotation transform for this + * sprite. + * + * @return the newly computed rotation transform + */ + private AffineTransform getRotationTransform () + { + double theta; + + switch (_orient) { + case NORTH: + default: + theta = 0.0; + break; + + case SOUTH: + theta = Math.PI; + break; + + case EAST: + theta = Math.PI*0.5; + break; + + case WEST: + theta = -Math.PI*0.5; + break; + + case NORTHEAST: + theta = Math.PI*0.25; + break; + + case NORTHWEST: + theta = -Math.PI*0.25; + break; + + case SOUTHEAST: + theta = Math.PI*0.75; + break; + + case SOUTHWEST: + theta = -Math.PI*0.75; + break; + + case NORTHNORTHEAST: + theta = -Math.PI*0.125; + break; + + case NORTHNORTHWEST: + theta = Math.PI*0.125; + break; + + case SOUTHSOUTHEAST: + theta = -Math.PI*0.875; + break; + + case SOUTHSOUTHWEST: + theta = Math.PI*0.875; + break; + + case EASTNORTHEAST: + theta = -Math.PI*0.375; + break; + + case EASTSOUTHEAST: + theta = -Math.PI*0.625; + break; + + case WESTNORTHWEST: + theta = Math.PI*0.375; + break; + + case WESTSOUTHWEST: + theta = Math.PI*0.625; + break; + } + + return AffineTransform.getRotateInstance( + theta, + (_ox - _oxoff) + _frames.getWidth(_frameIdx)/2, + (_oy - _oyoff) + _frames.getHeight(_frameIdx)/2 + ); + } + + // Documentation inherited. + protected void accomodateFrame (int frameIdx, int width, int height) + { + Area area = new Area( + new Rectangle( + (_ox - _oxoff), + (_oy - _oyoff), + width, + height + ) + ); + + area.transform(getRotationTransform()); + + _bounds = area.getBounds(); + } + + // Documentation inherited. + public void setOrientation (int orient) + { + super.setOrientation(orient); + + layout(); + } + + // Documentation inherited. + public void paint (Graphics2D graphics) + { + AffineTransform at = graphics.getTransform(); + + graphics.transform(getRotationTransform()); + + if (_frames != null) { + _frames.paintFrame( + graphics, + _frameIdx, + _ox - _oxoff, + _oy - _oyoff + ); + } + else { + super.paint(graphics); + } + + graphics.setTransform(at); + } +} diff --git a/src/java/com/threerings/media/sprite/PathAdapter.java b/src/java/com/threerings/media/sprite/PathAdapter.java new file mode 100644 index 00000000..f4378401 --- /dev/null +++ b/src/java/com/threerings/media/sprite/PathAdapter.java @@ -0,0 +1,40 @@ +// +// $Id: PathAdapter.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import com.threerings.media.util.Path; + +/** + * An adapter class for {@link PathObserver}. + */ +public class PathAdapter implements PathObserver +{ + // documentation inherited from interface + public void pathCancelled (Sprite sprite, Path path) + { + } + + // documentation inherited from interface + public void pathCompleted (Sprite sprite, Path path, long when) + { + } +} diff --git a/src/java/com/threerings/media/sprite/PathObserver.java b/src/java/com/threerings/media/sprite/PathObserver.java new file mode 100644 index 00000000..de6cbfc8 --- /dev/null +++ b/src/java/com/threerings/media/sprite/PathObserver.java @@ -0,0 +1,49 @@ +// +// $Id: PathObserver.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import com.threerings.media.util.Path; + +/** + * An interface to be implemented by classes that would like to be + * notified when a sprite completes or cancels its path. + */ +public interface PathObserver +{ + /** + * Called when a sprite's path is cancelled either because a new path + * was started or the path was explicitly cancelled with {@link + * Sprite#cancelMove}. + */ + public void pathCancelled (Sprite sprite, Path path); + + /** + * Called when a sprite completes its traversal of a path. + * + * @param sprite the sprite that completed its path. + * @param path the path that was completed. + * @param when the tick stamp of the media tick on which the path was + * completed (see {@link SpriteManager#tick}) (this may not be in the + * same time domain as {@link System#currentTimeMillis}). + */ + public void pathCompleted (Sprite sprite, Path path, long when); +} diff --git a/src/java/com/threerings/media/sprite/Sprite.java b/src/java/com/threerings/media/sprite/Sprite.java new file mode 100644 index 00000000..9abf1c6a --- /dev/null +++ b/src/java/com/threerings/media/sprite/Sprite.java @@ -0,0 +1,462 @@ +// +// $Id: Sprite.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; + +import com.samskivert.util.ObserverList; +import com.threerings.util.DirectionCodes; + +import com.threerings.media.AbstractMedia; +import com.threerings.media.util.Path; +import com.threerings.media.util.Pathable; + +import com.threerings.media.Log; + +/** + * The sprite class represents a single moveable object in an animated + * view. A sprite has a position and orientation within the view, and can + * be moved along a path. + */ +public abstract class Sprite extends AbstractMedia + implements DirectionCodes, Pathable +{ + /** + * Constructs a sprite with an initially invalid location. Because + * sprite derived classes generally want to get in on the business + * when a sprite's location is set, it is not safe to do so in the + * constructor because their derived methods will be called before + * their constructor has been called. Thus a sprite should be fully + * constructed and then its location should be set. + */ + public Sprite () + { + this(0, 0); + } + + /** + * Constructs a sprite with the supplied dimensions. Because + * sprite derived classes generally want to get in on the business + * when a sprite's location is set, it is not safe to do so in the + * constructor because their derived methods will be called before + * their constructor has been called. Thus a sprite should be fully + * constructed and then its location should be set. + */ + public Sprite (int width, int height) + { + super(new Rectangle(0, 0, width, height)); + } + + /** + * Returns the sprite's x position in screen coordinates. This is the + * x coordinate of the sprite's origin, not the upper left of its + * bounds. + */ + public int getX () + { + return _ox; + } + + /** + * Returns the sprite's y position in screen coordinates. This is the + * y coordinate of the sprite's origin, not the upper left of its + * bounds. + */ + public int getY () + { + return _oy; + } + + /** + * Returns the offset to the sprite's origin from the upper-left of + * the sprite's image. + */ + public int getXOffset () + { + return _oxoff; + } + + /** + * Returns the offset to the sprite's origin from the upper-left of + * the sprite's image. + */ + public int getYOffset () + { + return _oyoff; + } + + /** + * Returns the sprite's width in pixels. + */ + public int getWidth () + { + return _bounds.width; + } + + /** + * Returns the sprite's height in pixels. + */ + public int getHeight () + { + return _bounds.height; + } + + /** + * Sprites have an orientation in one of the eight cardinal + * directions: NORTH, NORTHEAST, etc. + * Derived classes can choose to override this member function and + * select a different set of images based on their orientation, or + * they can ignore the orientation information. + * + * @see DirectionCodes + */ + public void setOrientation (int orient) + { + _orient = orient; + } + + /** + * Returns the sprite's orientation as one of the eight cardinal + * directions: NORTH, NORTHEAST, etc. + * + * @see DirectionCodes + */ + public int getOrientation () + { + return _orient; + } + + // documentation inherited + public void setLocation (int x, int y) + { + if (x == _ox && y == _oy) { + return; // no-op + } + + // start with our current bounds + Rectangle dirty = new Rectangle(_bounds); + + // move ourselves + _ox = x; + _oy = y; + + // we need to update our draw position which is based on the size + // of our current bounds + updateRenderOrigin(); + + // grow the dirty rectangle to incorporate our new bounds and pass + // the dirty region to our region manager + if (_mgr != null) { + // if our new bounds intersect our old bounds, grow a single + // dirty rectangle to incorporate them both + if (_bounds.intersects(dirty)) { + dirty.add(_bounds); + } else { + // otherwise invalidate our new bounds separately + _mgr.getRegionManager().invalidateRegion(_bounds); + } + _mgr.getRegionManager().addDirtyRegion(dirty); + } + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + gfx.drawRect(_bounds.x, _bounds.y, _bounds.width-1, _bounds.height-1); + } + + /** + * Paint the sprite's path, if any, to the specified graphics context. + * + * @param gfx the graphics context. + */ + public void paintPath (Graphics2D gfx) + { + if (_path != null) { + _path.paint(gfx); + } + } + + /** + * Returns true if the sprite's bounds contain the specified point, + * false if not. + */ + public boolean contains (int x, int y) + { + return _bounds.contains(x, y); + } + + /** + * Returns true if the sprite's bounds contain the specified point, + * false if not. + */ + public boolean hitTest (int x, int y) + { + return _bounds.contains(x, y); + } + + /** + * Returns whether the sprite is inside the given shape in pixel + * coordinates. + */ + public boolean inside (Shape shape) + { + return shape.contains(_ox, _oy); + } + + /** + * Returns whether the sprite's drawn rectangle intersects the given + * shape in pixel coordinates. + */ + public boolean intersects (Shape shape) + { + return shape.intersects(_bounds); + } + + /** + * Returns true if this sprite is currently following a path, false if + * it is not. + */ + public boolean isMoving () + { + return (_path != null); + } + + /** + * Set the sprite's active path and start moving it along its merry + * way. If the sprite is already moving along a previous path the old + * path will be lost and the new path will begin to be traversed. + * + * @param path the path to follow. + */ + public void move (Path path) + { + // if there's a previous path, let it know that it's going away + cancelMove(); + + // save off this path + _path = path; + + // we'll initialize it on our next tick thanks to a zero path stamp + _pathStamp = 0; + } + + /** + * Cancels any path that the sprite may currently be moving along. + */ + public void cancelMove () + { + if (_path != null) { + Path oldpath = _path; + _path = null; + oldpath.wasRemoved(this); + if (_observers != null) { + _observers.apply(new CancelledOp(this, oldpath)); + } + } + } + + /** + * Returns the path being followed by this sprite or null if the + * sprite is not following a path. + */ + public Path getPath () + { + return _path; + } + + /** + * Called by the active path when it begins. + */ + public void pathBeginning () + { + // nothing for now + } + + /** + * Called by the active path when it has completed. + */ + public void pathCompleted (long timestamp) + { + Path oldpath = _path; + _path = null; + oldpath.wasRemoved(this); + if (_observers != null) { + _observers.apply(new CompletedOp(this, oldpath, timestamp)); + } + } + + // documentation inherited + public void tick (long tickStamp) + { + tickPath(tickStamp); + } + + /** + * Ticks any path assigned to this sprite. + * + * @return true if the path relocated the sprite as a result of this + * tick, false if it remained in the same position. + */ + protected boolean tickPath (long tickStamp) + { + if (_path == null) { + return false; + } + + // initialize the path if we haven't yet + if (_pathStamp == 0) { + _path.init(this, _pathStamp = tickStamp); + } + + // it's possible that as a result of init() the path completed and + // removed itself with a call to pathCompleted(), so we have to be + // careful here + return (_path == null) ? true : _path.tick(this, tickStamp); + } + + // documentation inherited + public void fastForward (long timeDelta) + { + // fast forward any path we're following + if (_path != null) { + _path.fastForward(timeDelta); + } + } + + /** + * Update the coordinates at which the sprite image is drawn to + * reflect the sprite's current position. + */ + protected void updateRenderOrigin () + { + // our bounds origin may differ from the sprite's origin + _bounds.x = _ox - _oxoff; + _bounds.y = _oy - _oyoff; + } + + /** + * Add a sprite observer to observe this sprite's events. + * + * @param obs the sprite observer. + */ + public void addSpriteObserver (Object obs) + { + addObserver(obs); + } + + /** + * Remove a sprite observer. + */ + public void removeSpriteObserver (Object obs) + { + removeObserver(obs); + } + + // documentation inherited + public void viewLocationDidChange (int dx, int dy) + { + if (_renderOrder >= HUD_LAYER) { + setLocation(_ox + dx, _oy + dy); + } + } + + // documentation inherited + protected void shutdown () + { + super.shutdown(); + cancelMove(); // cancel any active path + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", ox=").append(_ox); + buf.append(", oy=").append(_oy); + buf.append(", oxoff=").append(_oxoff); + buf.append(", oyoff=").append(_oyoff); + } + + /** Used to dispatch {@link PathObserver#pathCancelled}. */ + protected static class CancelledOp implements ObserverList.ObserverOp + { + public CancelledOp (Sprite sprite, Path path) { + _sprite = sprite; + _path = path; + } + + public boolean apply (Object observer) { + if (observer instanceof PathObserver) { + ((PathObserver)observer).pathCancelled(_sprite, _path); + } + return true; + } + + protected Sprite _sprite; + protected Path _path; + } + + /** Used to dispatch {@link PathObserver#pathCompleted}. */ + protected static class CompletedOp implements ObserverList.ObserverOp + { + public CompletedOp (Sprite sprite, Path path, long when) { + _sprite = sprite; + _path = path; + _when = when; + } + + public boolean apply (Object observer) { + if (observer instanceof PathObserver) { + ((PathObserver)observer).pathCompleted(_sprite, _path, _when); + } + return true; + } + + protected Sprite _sprite; + protected Path _path; + protected long _when; + } + + /** The location of the sprite's origin in pixel coordinates. If the + * sprite positions itself via a hotspot that is not the upper left + * coordinate of the sprite's bounds, the offset to the hotspot should + * be maintained in {@link #_oxoff} and {@link #_oyoff}. */ + protected int _ox = Integer.MIN_VALUE, _oy = Integer.MIN_VALUE; + + /** The offsets from our upper left coordinate to our origin (or hot + * spot). Derived classes will need to update these values if the + * sprite's origin is not coincident with the upper left coordinate of + * its bounds. */ + protected int _oxoff, _oyoff; + + /** The orientation of this sprite. */ + protected int _orient = NONE; + + /** When moving, the path the sprite is traversing. */ + protected Path _path; + + /** The timestamp at which we started along our path. */ + protected long _pathStamp; +} diff --git a/src/java/com/threerings/media/sprite/SpriteIcon.java b/src/java/com/threerings/media/sprite/SpriteIcon.java new file mode 100644 index 00000000..d8d3c9a3 --- /dev/null +++ b/src/java/com/threerings/media/sprite/SpriteIcon.java @@ -0,0 +1,94 @@ +// +// $Id: SpriteIcon.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; + +import javax.swing.Icon; + +/** + * Implements the icon interface, using a {@link Sprite} to render the + * icon image. + */ +public class SpriteIcon implements Icon +{ + /** + * Creates a sprite icon that will use the supplied sprite to render + * itself. This sprite should not be used for anything else while + * being used in this icon because it will be "moved" when the icon is + * rendered. The sprite's origin will be set to the bottom center of + * the label. + */ + public SpriteIcon (Sprite sprite) + { + this(sprite, 0); + } + + /** + * Creates a sprite icon that will use the supplied sprite to render + * itself. This sprite should not be used for anything else while + * being used in this icon because it will be "moved" when the icon is + * rendered. The sprite's origin will be set to the bottom center of + * the label. + * + * @param sprite the sprite to render in this label. + * @param padding the number of pixels of blank space to put on all + * four sides of the sprite. + */ + public SpriteIcon (Sprite sprite, int padding) + { + _sprite = sprite; + // the sprite should be ticked once so that we can safely paint it + _sprite.tick(System.currentTimeMillis()); + _padding = padding; + } + + // documentation inherited from interface + public void paintIcon (Component c, Graphics g, int x, int y) + { + // move the sprite to a "location" that results in its image being + // in the upper left of the rectangle we desire + _sprite.setLocation(x + _sprite.getXOffset() + _padding, + y + _sprite.getYOffset() + _padding); + _sprite.paint((Graphics2D)g); + } + + // documentation inherited from interface + public int getIconWidth () + { + return _sprite.getWidth() + 2*_padding; + } + + // documentation inherited from interface + public int getIconHeight () + { + return _sprite.getHeight() + 2*_padding; + } + + /** The sprite used to render this icon. */ + protected Sprite _sprite; + + /** Used to put a bit of padding around the sprite image. */ + protected int _padding; +} diff --git a/src/java/com/threerings/media/sprite/SpriteManager.java b/src/java/com/threerings/media/sprite/SpriteManager.java new file mode 100644 index 00000000..d78081c5 --- /dev/null +++ b/src/java/com/threerings/media/sprite/SpriteManager.java @@ -0,0 +1,269 @@ +// +// $Id: SpriteManager.java 3733 2005-10-13 19:00:08Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sprite; + +import java.awt.Graphics2D; +import java.awt.Shape; + +import java.util.Collections; +import java.util.List; +import java.util.Iterator; + +import com.threerings.media.AbstractMediaManager; +import com.threerings.media.MediaPanel; + +/** + * The sprite manager manages the sprites running about in the game. + */ +public class SpriteManager extends AbstractMediaManager +{ + /** A predicate used to operate on sprites (see {@link #removeSprites}. */ + public static interface Predicate + { + /** Returns true if this sprite is to be included by the predicate, + * false if it should be excluded. */ + public boolean evaluate (Sprite sprite); + } + + /** + * Construct and initialize the sprite manager. + */ + public SpriteManager (MediaPanel panel) + { + super(panel); + } + + /** + * When an animated view processes its dirty rectangles, it may + * require an expansion of the dirty region which may in turn + * require the invalidation of more sprites than were originally + * invalid. In such cases, the animated view can call back to the + * sprite manager, asking it to append the sprites that intersect + * a particular region to the given list. + * + * @param list the list to fill with any intersecting sprites. + * @param shape the shape in which we have interest. + */ + public void getIntersectingSprites (List list, Shape shape) + { + int size = _media.size(); + for (int ii = 0; ii < size; ii++) { + Sprite sprite = (Sprite)_media.get(ii); + if (sprite.intersects(shape)) { + list.add(sprite); + } + } + } + + /** + * When an animated view is determining what entity in its view is + * under the mouse pointer, it may require a list of sprites that are + * "hit" by a particular pixel. The sprites' bounds are first checked + * and sprites with bounds that contain the supplied point are further + * checked for a non-transparent at the specified location. + * + * @param list the list to fill with any intersecting sprites, the + * sprites with the highest render order provided first. + * @param x the x (screen) coordinate to be checked. + * @param y the y (screen) coordinate to be checked. + */ + public void getHitSprites (List list, int x, int y) + { + for (int ii = _media.size() - 1; ii >= 0; ii--) { + Sprite sprite = (Sprite)_media.get(ii); + if (sprite.hitTest(x, y)) { + list.add(sprite); + } + } + } + + /** + * Finds the sprite with the highest render order that hits the + * specified pixel. + * + * @param x the x (screen) coordinate to be checked + * @param y the y (screen) coordinate to be checked + * @return the highest sprite hit + */ + public Sprite getHighestHitSprite (int x, int y) + { + // since they're stored in lowest -> highest order.. + for (int ii = _media.size() - 1; ii >= 0; ii--) { + Sprite sprite = (Sprite)_media.get(ii); + if (sprite.hitTest(x, y)) { + return sprite; + } + } + return null; + } + + /** + * Add a sprite to the set of sprites managed by this manager. + * + * @param sprite the sprite to add. + */ + public void addSprite (Sprite sprite) + { + if (insertMedia(sprite)) { + // and invalidate the sprite's original position + sprite.invalidate(); + } + } + + /** + * Returns a list of all sprites registered with the sprite manager. + * The returned list is immutable, sprites should be added or removed + * using {@link #addSprite} or {@link #removeSprite}. + */ + public List getSprites () + { + return Collections.unmodifiableList(_media); + } + + /** + * Returns an iterator over our managed sprites. Do not call + * {@link Iterator#remove}. + */ + public Iterator enumerateSprites () + { + return _media.iterator(); + } + + /** + * Removes the specified sprite from the set of sprites managed by + * this manager. + * + * @param sprite the sprite to remove. + */ + public void removeSprite (Sprite sprite) + { + removeMedia(sprite); + } + + /** + * Removes all sprites that match the supplied predicate. + */ + public void removeSprites (Predicate pred) + { + int idxoff = 0; + for (int ii = 0, ll = _media.size(); ii < ll; ii++) { + Sprite sprite = (Sprite)_media.get(ii-idxoff); + if (pred.evaluate(sprite)) { + _media.remove(sprite); + sprite.invalidate(); + sprite.shutdown(); + // we need to preserve the original "index" relative to the + // current tick position, so we don't decrement ii directly + idxoff++; + if (ii <= _tickpos) { + _tickpos--; + } + } + } + } + + /** + * Render the sprite paths to the given graphics context. + * + * @param gfx the graphics context. + */ + public void renderSpritePaths (Graphics2D gfx) + { + for (int ii=0, nn=_media.size(); ii < nn; ii++) { + Sprite sprite = (Sprite)_media.get(ii); + sprite.paintPath(gfx); + } + } + +// NOTE- collision handling code is turned off for now. To re-implement, +// a new array should be kept with sprites sorted in some sort of x/y order +// +// /** +// * Check all sprites for collisions with others and inform any +// * sprite observers. +// */ +// protected void handleCollisions () +// { +// // gather a list of all sprite collisions +// int size = _sprites.size(); +// for (int ii = 0; ii < size; ii++) { +// Sprite sprite = (Sprite)_sprites.get(ii); +// checkCollisions(ii, size, sprite); +// } +// } +// +// /** +// * Check a sprite for collision with any other sprites in the +// * sprite list and notify the sprite observers associated with any +// * sprites that do indeed collide. +// * +// * @param idx the starting sprite index. +// * @param size the total number of sprites. +// * @param sprite the sprite to check against other sprites for +// * collisions. +// */ +// protected void checkCollisions (int idx, int size, Sprite sprite) +// { +// // TODO: make this handle quickly moving objects that may pass +// // through each other. +// +// // if we're the last sprite we know we've already handled any +// // collisions +// if (idx == (size - 1)) { +// return; +// } +// +// // calculate the x-position of the right edge of the sprite we're +// // checking for collisions +// Rectangle bounds = sprite.getBounds(); +// int edgeX = bounds.x + bounds.width; +// +// for (int ii = (idx + 1); ii < size; ii++) { +// Sprite other = (Sprite)_sprites.get(ii); +// Rectangle obounds = other.getBounds(); +// if (obounds.x > edgeX) { +// // since sprites are stored in the list sorted by +// // ascending x-position, we know this sprite and any +// // other sprites farther on in the list can't possibly +// // intersect with the sprite we're checking, so we're +// // done. +// return; +// +// } else if (obounds.intersects(bounds)) { +// sprite.notifyObservers(new CollisionEvent(sprite, other)); +// } +// } +// } +// /** The comparator used to sort sprites by horizontal position. */ +// protected static final Comparator SPRITE_COMP = new SpriteComparator(); +// +// /** Used to sort sprites. */ +// protected static class SpriteComparator implements Comparator +// { +// public int compare (Object o1, Object o2) +// { +// Sprite s1 = (Sprite)o1; +// Sprite s2 = (Sprite)o2; +// return (s2.getX() - s1.getX()); +// } +// } +} diff --git a/src/java/com/threerings/media/sprite/action/ActionSprite.java b/src/java/com/threerings/media/sprite/action/ActionSprite.java new file mode 100644 index 00000000..30bb6158 --- /dev/null +++ b/src/java/com/threerings/media/sprite/action/ActionSprite.java @@ -0,0 +1,16 @@ +// +// $Id$ + +package com.threerings.media.sprite.action; + +/** + * An Action sprite is a sprite that may be pressed to generate an + * ActionEvent that will be posted to the Controller hierarchy. + */ +public interface ActionSprite +{ + /** + * @return the action command to submit if this sprite is clicked. + */ + public String getActionCommand (); +} diff --git a/src/java/com/threerings/media/sprite/action/ArmingSprite.java b/src/java/com/threerings/media/sprite/action/ArmingSprite.java new file mode 100644 index 00000000..8d0763f3 --- /dev/null +++ b/src/java/com/threerings/media/sprite/action/ArmingSprite.java @@ -0,0 +1,16 @@ +// +// $Id$ + +package com.threerings.media.sprite.action; + +/** + * An ActionSprite that wishes to be notified of events when it is armed + * or not. + */ +public interface ArmingSprite extends ActionSprite +{ + /** + * Render this sprite such that is is drawn "armed". + */ + public void setArmed (boolean armed); +} diff --git a/src/java/com/threerings/media/sprite/action/CommandSprite.java b/src/java/com/threerings/media/sprite/action/CommandSprite.java new file mode 100644 index 00000000..8384be2b --- /dev/null +++ b/src/java/com/threerings/media/sprite/action/CommandSprite.java @@ -0,0 +1,16 @@ +// +// $Id$ + +package com.threerings.media.sprite.action; + +/** + * Extends CommandSprite to be a sprite that posts CommandEvents to + * the Controller hierarchy. + */ +public interface CommandSprite extends ActionSprite +{ + /** + * @return the argument to the action command. + */ + public Object getCommandArgument(); +} diff --git a/src/java/com/threerings/media/sprite/action/DisableableSprite.java b/src/java/com/threerings/media/sprite/action/DisableableSprite.java new file mode 100644 index 00000000..c19a7d8b --- /dev/null +++ b/src/java/com/threerings/media/sprite/action/DisableableSprite.java @@ -0,0 +1,16 @@ +// +// $Id$ + +package com.threerings.media.sprite.action; + +/** + * Indicates a Sprite that may or may not be enabled to receive + * action / hover / arming notifications. + */ +public interface DisableableSprite +{ + /** + * @return true if this sprite is currently enabled. + */ + public boolean isEnabled (); +} diff --git a/src/java/com/threerings/media/sprite/action/HoverSprite.java b/src/java/com/threerings/media/sprite/action/HoverSprite.java new file mode 100644 index 00000000..409da3da --- /dev/null +++ b/src/java/com/threerings/media/sprite/action/HoverSprite.java @@ -0,0 +1,16 @@ +// +// $Id$ + +package com.threerings.media.sprite.action; + +/** + * An interface indicating that a sprite wishes to be notified when + * the mouse hovers over it. + */ +public interface HoverSprite +{ + /** + * Set the current hover state. + */ + public void setHovered (boolean hovered); +} diff --git a/src/java/com/threerings/media/tile/IMImageProvider.java b/src/java/com/threerings/media/tile/IMImageProvider.java new file mode 100644 index 00000000..d738bd90 --- /dev/null +++ b/src/java/com/threerings/media/tile/IMImageProvider.java @@ -0,0 +1,73 @@ +// +// $Id: IMImageProvider.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.ImageDataProvider; +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.Mirage; + +/** + * Provides images to a tileset given a reference to the image manager and + * an image data provider. + */ +public class IMImageProvider implements ImageProvider +{ + public IMImageProvider (ImageManager imgr, ImageDataProvider dprov) + { + _imgr = imgr; + _dprov = dprov; + } + + public IMImageProvider (ImageManager imgr, String rset) + { + _imgr = imgr; + _rset = rset; + } + + // documentation inherited from interface + public BufferedImage getTileSetImage (String path, Colorization[] zations) + { + return _imgr.getImage(getImageKey(path), zations); + } + + // documentation inherited from interface + public Mirage getTileImage (String path, Rectangle bounds, + Colorization[] zations) + { + return _imgr.getMirage(getImageKey(path), bounds, zations); + } + + protected final ImageManager.ImageKey getImageKey (String path) + { + return (_dprov == null) ? + _imgr.getImageKey(_rset, path) : + _imgr.getImageKey(_dprov, path); + } + + protected ImageManager _imgr; + protected ImageDataProvider _dprov; + protected String _rset; +} diff --git a/src/java/com/threerings/media/tile/ImageProvider.java b/src/java/com/threerings/media/tile/ImageProvider.java new file mode 100644 index 00000000..9046e2a5 --- /dev/null +++ b/src/java/com/threerings/media/tile/ImageProvider.java @@ -0,0 +1,64 @@ +// +// $Id: ImageProvider.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.Mirage; + +/** + * Provides a generic interface via which tileset images may be loaded. In + * most cases, a running application will want to obtain images via the + * {@link ImageManager}, but in some circumstances a simpler image + * provider may be desirable to avoid the overhead of the image manager + * infrastructure when simple image loading is all that is desired. + */ +public interface ImageProvider +{ + /** + * Returns the raw tileset image with the specified path. + * + * @param path the path that identifies the desired image (corresponds + * to the image path from the tileset). + * @param zations if non-null, colorizations to apply to the source + * image before returning it. + */ + public BufferedImage getTileSetImage (String path, Colorization[] zations); + + /** + * Obtains the tile image with the specified path in the form of a + * {@link Mirage}. It should be cropped from the tileset image + * identified by the supplied path. + * + * @param path the path that identifies the desired image (corresponds + * to the image path from the tileset). + * @param bounds if non-null, the region of the image to be returned + * as a mirage. If null, the entire image should be returned. + * @param zations if non-null, colorizations to apply to the image + * before converting it into a mirage. + */ + public Mirage getTileImage (String path, Rectangle bounds, + Colorization[] zations); +} diff --git a/src/java/com/threerings/media/tile/NoSuchTileSetException.java b/src/java/com/threerings/media/tile/NoSuchTileSetException.java new file mode 100644 index 00000000..22e48c07 --- /dev/null +++ b/src/java/com/threerings/media/tile/NoSuchTileSetException.java @@ -0,0 +1,39 @@ +// +// $Id: NoSuchTileSetException.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +/** + * Thrown when an attempt is made to retrieve a non-existent tile set from + * the tile set manager. + */ +public class NoSuchTileSetException extends Exception +{ + public NoSuchTileSetException (String tileSetName) + { + super("No tile set named '" + tileSetName + "'"); + } + + public NoSuchTileSetException (int tileSetId) + { + super("No tile set with id '" + tileSetId + "'"); + } +} diff --git a/src/java/com/threerings/media/tile/ObjectTile.java b/src/java/com/threerings/media/tile/ObjectTile.java new file mode 100644 index 00000000..b5d8cf01 --- /dev/null +++ b/src/java/com/threerings/media/tile/ObjectTile.java @@ -0,0 +1,232 @@ +// +// $Id: ObjectTile.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Dimension; +import java.awt.Point; + +import com.samskivert.util.ListUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.util.DirectionUtil; + +/** + * An object tile extends the base tile to provide support for objects + * whose image spans more than one unit tile. + * + *

An object tile is generally positioned based on its origin rather + * than the upper left of its image. Generally this origin is in the + * bottom center of the object image, but can be configured to be anywhere + * that the natural center point of "contact" is for the object. Note that + * this does not automatically adjust the semantics of {@link #paint}, it + * is just expected that the caller will account for the object tile's + * origin when painting, if appropriate. + * + *

An object tile has dimensions (in tile units) that represent its + * footprint or "shadow". + */ +public class ObjectTile extends Tile +{ + /** + * Returns the object footprint width in tile units. + */ + public int getBaseWidth () + { + return _base.width; + } + + /** + * Returns the object footprint height in tile units. + */ + public int getBaseHeight () + { + return _base.height; + } + + /** + * Sets the object footprint in tile units. + */ + protected void setBase (int width, int height) + { + _base.width = width; + _base.height = height; + } + + /** + * Returns the x offset into the tile image of the origin (which will + * be aligned with the bottom center of the origin tile) or + * Integer.MIN_VALUE if the origin is not explicitly + * specified and should be computed from the image size and tile + * footprint. + */ + public int getOriginX () + { + return _origin.x; + } + + /** + * Returns the y offset into the tile image of the origin (which will + * be aligned with the bottom center of the origin tile) or + * Integer.MIN_VALUE if the origin is not explicitly + * specified and should be computed from the image size and tile + * footprint. + */ + public int getOriginY () + { + return _origin.y; + } + + /** + * Sets the offset in pixels from the origin of the tile image to the + * origin of the object. The object will be rendered such that its + * origin is at the bottom center of its origin tile. If no origin is + * specified, the bottom of the image is aligned with the bottom of + * the origin tile and the left side of the image is aligned with the + * left edge of the left-most base tile. + */ + protected void setOrigin (int x, int y) + { + _origin.x = x; + _origin.y = y; + } + + /** + * Returns this object tile's default render priority. + */ + public int getPriority () + { + return _priority; + } + + /** + * Sets this object tile's default render priority. + */ + protected void setPriority (int priority) + { + _priority = priority; + } + + /** + * Configures the "spot" associated with this object. + */ + public void setSpot (int x, int y, byte orient) + { + _spot = new Point(x, y); + _sorient = orient; + } + + /** + * Returns true if this object has a spot. + */ + public boolean hasSpot () + { + return (_spot != null); + } + + /** + * Returns the x-coordinate of the "spot" associated with this object. + */ + public int getSpotX () + { + return (_spot == null) ? 0 : _spot.x; + } + + /** + * Returns the x-coordinate of the "spot" associated with this object. + */ + public int getSpotY () + { + return (_spot == null) ? 0 : _spot.y; + } + + /** + * Returns the orientation of the "spot" associated with this object. + */ + public int getSpotOrient () + { + return _sorient; + } + + /** + * Returns the list of constraints associated with this object, or + * null if the object has no constraints. + */ + public String[] getConstraints () + { + return _constraints; + } + + /** + * Checks whether this object has the given constraint. + */ + public boolean hasConstraint (String constraint) + { + return (_constraints == null) ? false : + ListUtil.contains(_constraints, constraint); + } + + /** + * Configures this object's constraints. + */ + public void setConstraints (String[] constraints) + { + _constraints = constraints; + } + + // documentation inherited + public void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", base=").append(StringUtil.toString(_base)); + buf.append(", origin=").append(StringUtil.toString(_origin)); + buf.append(", priority=").append(_priority); + if (_spot != null) { + buf.append(", spot=").append(StringUtil.toString(_spot)); + buf.append(", sorient="); + buf.append(DirectionUtil.toShortString(_sorient)); + } + if (_constraints != null) { + buf.append(", constraints=").append(StringUtil.toString( + _constraints)); + } + } + + /** The object footprint width in unit tile units. */ + protected Dimension _base = new Dimension(1, 1); + + /** The offset from the origin of the tile image to the object's + * origin or MIN_VALUE if the origin should be calculated based on the + * footprint. */ + protected Point _origin = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); + + /** This object tile's default render priority. */ + protected int _priority; + + /** The coordinates of the "spot" associated with this object. */ + protected Point _spot; + + /** The orientation of the "spot" associated with this object. */ + protected byte _sorient; + + /** The list of constraints associated with this object. */ + protected String[] _constraints; +} diff --git a/src/java/com/threerings/media/tile/ObjectTileSet.java b/src/java/com/threerings/media/tile/ObjectTileSet.java new file mode 100644 index 00000000..d32c2bda --- /dev/null +++ b/src/java/com/threerings/media/tile/ObjectTileSet.java @@ -0,0 +1,295 @@ +// +// $Id: ObjectTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import com.samskivert.util.ListUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.Colorization; + +/** + * The object tileset supports the specification of object information for + * object tiles in addition to all of the features of the swiss army + * tileset. + * + * @see ObjectTile + */ +public class ObjectTileSet extends SwissArmyTileSet + implements RecolorableTileSet +{ + /** A constraint prefix indicating that the object must have empty space in + * the suffixed direction (N, E, S, or W). */ + public static final String SPACE = "SPACE_"; + + /** A constraint indicating that the object is a surface (e.g., table). */ + public static final String SURFACE = "SURFACE"; + + /** A constraint indicating that the object must be placed on a surface. */ + public static final String ON_SURFACE = "ON_SURFACE"; + + /** A constraint prefix indicating that the object is a wall facing the + * suffixed direction (N, E, S, or W). */ + public static final String WALL = "WALL_"; + + /** A constraint prefix indicating that the object must be placed on a + * wall facing the suffixed direction (N, E, S, or W). */ + public static final String ON_WALL = "ON_WALL_"; + + /** A constraint prefix indicating that the object must be attached to a + * wall facing the suffixed direction (N, E, S, or W). */ + public static final String ATTACH = "ATTACH_"; + + /** The low suffix for walls and attachments. Low attachments can be placed + * on low or normal walls; normal attachments can only be placed on normal + * walls. */ + public static final String LOW = "_LOW"; + + /** + * Sets the widths (in unit tile count) of the objects in this + * tileset. This must be accompanied by a call to {@link + * #setObjectHeights}. + */ + public void setObjectWidths (int[] objectWidths) + { + _owidths = objectWidths; + } + + /** + * Sets the heights (in unit tile count) of the objects in this + * tileset. This must be accompanied by a call to {@link + * #setObjectWidths}. + */ + public void setObjectHeights (int[] objectHeights) + { + _oheights = objectHeights; + } + + /** + * Sets the x offset in pixels to the image origin. + */ + public void setXOrigins (int[] xorigins) + { + _xorigins = xorigins; + } + + /** + * Sets the y offset in pixels to the image origin. + */ + public void setYOrigins (int[] yorigins) + { + _yorigins = yorigins; + } + + /** + * Sets the default render priorities for our object tiles. + */ + public void setPriorities (byte[] priorities) + { + _priorities = priorities; + } + + /** + * Provides a set of colorization classes that apply to objects in + * this tileset. + */ + public void setColorizations (String[] zations) + { + _zations = zations; + } + + /** + * Sets the x offset to the "spots" associated with our object tiles. + */ + public void setXSpots (short[] xspots) + { + _xspots = xspots; + } + + /** + * Sets the y offset to the "spots" associated with our object tiles. + */ + public void setYSpots (short[] yspots) + { + _yspots = yspots; + } + + /** + * Sets the orientation of the "spots" associated with our object + * tiles. + */ + public void setSpotOrients (byte[] sorients) + { + _sorients = sorients; + } + + /** + * Sets the lists of constraints associated with our object tiles. + */ + public void setConstraints (String[][] constraints) + { + _constraints = constraints; + } + + /** + * Returns the x coordinate of the spot associated with the specified + * tile index. + */ + public int getXSpot (int tileIdx) + { + return (_xspots == null) ? 0 : _xspots[tileIdx]; + } + + /** + * Returns the y coordinate of the spot associated with the specified + * tile index. + */ + public int getYSpot (int tileIdx) + { + return (_yspots == null) ? 0 : _yspots[tileIdx]; + } + + /** + * Returns the orientation of the spot associated with the specified + * tile index. + */ + public int getSpotOrient (int tileIdx) + { + return (_sorients == null) ? 0 : _sorients[tileIdx]; + } + + /** + * Returns the list of constraints associated with the specified tile + * index, or null if the index has no constraints. + */ + public String[] getConstraints (int tileIdx) + { + return (_constraints == null) ? null : _constraints[tileIdx]; + } + + /** + * Checks whether the tile at the specified index has the given constraint. + */ + public boolean hasConstraint (int tileIdx, String constraint) + { + return (_constraints == null) ? false : + ListUtil.contains(_constraints[tileIdx], constraint); + } + + // documentation inherited from interface RecolorableTileSet + public String[] getColorizations () + { + return _zations; + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", owidths=").append(StringUtil.toString(_owidths)); + buf.append(", oheights=").append(StringUtil.toString(_oheights)); + buf.append(", xorigins=").append(StringUtil.toString(_xorigins)); + buf.append(", yorigins=").append(StringUtil.toString(_yorigins)); + buf.append(", prios=").append(StringUtil.toString(_priorities)); + buf.append(", zations=").append(StringUtil.toString(_zations)); + buf.append(", xspots=").append(StringUtil.toString(_xspots)); + buf.append(", yspots=").append(StringUtil.toString(_yspots)); + buf.append(", sorients=").append(StringUtil.toString(_sorients)); + buf.append(", constraints=").append(StringUtil.toString(_constraints)); + } + + // documentation inherited + protected Colorization[] getColorizations (int tileIndex, Colorizer rizer) + { + Colorization[] zations = null; + if (rizer != null && _zations != null) { + zations = new Colorization[_zations.length]; + for (int ii = 0; ii < _zations.length; ii++) { + zations[ii] = rizer.getColorization(ii, _zations[ii]); + } + } + return zations; + } + + // documentation inherited + protected Tile createTile () + { + return new ObjectTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + + ObjectTile otile = (ObjectTile)tile; + if (_owidths != null) { + otile.setBase(_owidths[tileIndex], _oheights[tileIndex]); + } + if (_xorigins != null) { + otile.setOrigin(_xorigins[tileIndex], _yorigins[tileIndex]); + } + if (_priorities != null) { + otile.setPriority(_priorities[tileIndex]); + } + if (_xspots != null) { + otile.setSpot(_xspots[tileIndex], _yspots[tileIndex], + _sorients[tileIndex]); + } + if (_constraints != null) { + otile.setConstraints(_constraints[tileIndex]); + } + } + + /** The width (in tile units) of our object tiles. */ + protected int[] _owidths; + + /** The height (in tile units) of our object tiles. */ + protected int[] _oheights; + + /** The x offset in pixels to the origin of the tile images. */ + protected int[] _xorigins; + + /** The y offset in pixels to the origin of the tile images. */ + protected int[] _yorigins; + + /** The default render priorities of our objects. */ + protected byte[] _priorities; + + /** Colorization classes that apply to our objects. */ + protected String[] _zations; + + /** The x offset to the "spots" associated with our tiles. */ + protected short[] _xspots; + + /** The y offset to the "spots" associated with our tiles. */ + protected short[] _yspots; + + /** The orientation of the "spots" associated with our tiles. */ + protected byte[] _sorients; + + /** Lists of constraints associated with our tiles. */ + protected String[][] _constraints; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; +} diff --git a/src/java/com/threerings/media/tile/RecolorableTileSet.java b/src/java/com/threerings/media/tile/RecolorableTileSet.java new file mode 100644 index 00000000..1e6e9a71 --- /dev/null +++ b/src/java/com/threerings/media/tile/RecolorableTileSet.java @@ -0,0 +1,16 @@ +// +// $Id: RecolorableTileSet.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media.tile; + +/** + * Indicates that a tileset has recolorization classes defined. + */ +public interface RecolorableTileSet +{ + /** + * Returns the colorization classes that should be used to recolor + * objects in this tileset. + */ + public String[] getColorizations (); +} diff --git a/src/java/com/threerings/media/tile/SimpleCachingImageProvider.java b/src/java/com/threerings/media/tile/SimpleCachingImageProvider.java new file mode 100644 index 00000000..131624bd --- /dev/null +++ b/src/java/com/threerings/media/tile/SimpleCachingImageProvider.java @@ -0,0 +1,77 @@ +// +// $Id: SimpleCachingImageProvider.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import com.samskivert.util.LRUHashMap; + +import com.threerings.media.Log; +import com.threerings.media.image.BufferedMirage; +import com.threerings.media.image.Colorization; +import com.threerings.media.image.Mirage; + +/** + * An image provider that can be used by command line tools to load images + * and provide them to tilesets when doing things like preprocessing + * tileset images. + */ +public abstract class SimpleCachingImageProvider implements ImageProvider +{ + // documentation inherited from interface + public BufferedImage getTileSetImage (String path, Colorization[] zations) + { + BufferedImage image = (BufferedImage)_cache.get(path); + if (image == null) { + try { + image = loadImage(path); + _cache.put(path, image); + } catch (IOException ioe) { + Log.warning("Failed to load image [path=" + path + + ", ioe=" + ioe + "]."); + } + } + return image; + } + + // documentation inherited from interface + public Mirage getTileImage (String path, Rectangle bounds, + Colorization[] zations) + { + // mostly fake it + BufferedImage tsimg = getTileSetImage(path, zations); + tsimg = tsimg.getSubimage(bounds.x, bounds.y, + bounds.width, bounds.height); + return new BufferedMirage(tsimg); + } + + /** + * Derived classes must implement this method to actually load the raw + * source images. + */ + protected abstract BufferedImage loadImage (String path) + throws IOException; + + protected LRUHashMap _cache = new LRUHashMap(10); +} diff --git a/src/java/com/threerings/media/tile/SwissArmyTileSet.java b/src/java/com/threerings/media/tile/SwissArmyTileSet.java new file mode 100644 index 00000000..8068b7a1 --- /dev/null +++ b/src/java/com/threerings/media/tile/SwissArmyTileSet.java @@ -0,0 +1,207 @@ +// +// $Id: SwissArmyTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; + +import java.io.IOException; +import java.io.ObjectInputStream; + +import com.samskivert.util.StringUtil; + +/** + * The swiss army tileset supports a diverse variety of tiles in the + * tileset image. Each row can contain varying numbers of tiles and each + * row can have its own width and height. Tiles can be separated from the + * edge of the tileset image by some border offset and can be separated + * from one another by a gap distance. + */ +public class SwissArmyTileSet extends TileSet +{ + // documentation inherited + public int getTileCount () + { + return _numTiles; + } + + /** + * Sets the tile counts which are the number of tiles in each row of + * the tileset image. Each row can have an arbitrary number of tiles. + */ + public void setTileCounts (int[] tileCounts) + { + _tileCounts = tileCounts; + + // compute our total tile count + computeTileCount(); + } + + /** + * Returns the tile count settings. + */ + public int[] getTileCounts () + { + return _tileCounts; + } + + /** + * Computes our total tile count from the individual counts for each + * row. + */ + protected void computeTileCount () + { + // compute our number of tiles + _numTiles = 0; + for (int i = 0; i < _tileCounts.length; i++) { + _numTiles += _tileCounts[i]; + } + } + + /** + * Sets the tile widths for each row. Each row can have tiles of a + * different width. + */ + public void setWidths (int[] widths) + { + _widths = widths; + } + + /** + * Returns the width settings. + */ + public int[] getWidths () + { + return _widths; + } + + /** + * Sets the tile heights for each row. Each row can have tiles of a + * different height. + */ + public void setHeights (int[] heights) + { + _heights = heights; + } + + /** + * Returns the height settings. + */ + public int[] getHeights () + { + return _heights; + } + + /** + * Sets the offset in pixels of the upper left corner of the first + * tile in the first row. If the tileset image has a border, this can + * be set to account for it. + */ + public void setOffsetPos (Point offsetPos) + { + _offsetPos = offsetPos; + } + + /** + * Sets the size of the gap between tiles (in pixels). If the tiles + * have space between them, this can be set to account for it. + */ + public void setGapSize (Dimension gapSize) + { + _gapSize = gapSize; + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", widths=").append(StringUtil.toString(_widths)); + buf.append(", heights=").append(StringUtil.toString(_heights)); + buf.append(", tileCounts=").append(StringUtil.toString(_tileCounts)); + buf.append(", offsetPos=").append(StringUtil.toString(_offsetPos)); + buf.append(", gapSize=").append(StringUtil.toString(_gapSize)); + } + + // documentation inherited + protected Rectangle computeTileBounds (int tileIndex) + { + // find the row number containing the sought-after tile + int ridx, tcount, ty, tx; + ridx = tcount = 0; + + // start tile image position at image start offset + tx = _offsetPos.x; + ty = _offsetPos.y; + + while ((tcount += _tileCounts[ridx]) < tileIndex + 1) { + // increment tile image position by row height and gap distance + ty += (_heights[ridx++] + _gapSize.height); + } + + // determine the horizontal index of this tile in the row + int xidx = tileIndex - (tcount - _tileCounts[ridx]); + + // final image x-position is based on tile width and gap distance + tx += (xidx * (_widths[ridx] + _gapSize.width)); + +// Log.info("Computed tile bounds [tileIndex=" + tileIndex + +// ", ridx=" + ridx + ", xidx=" + xidx + +// ", tx=" + tx + ", ty=" + ty + "]."); + + // crop the tile-sized image chunk from the full image + return new Rectangle(tx, ty, _widths[ridx], _heights[ridx]); + } + + private void readObject (ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + // compute our total tile count + computeTileCount(); + } + + /** The number of tiles in each row. */ + protected int[] _tileCounts; + + /** The number of tiles in the tileset. */ + protected int _numTiles; + + /** The width of the tiles in each row in pixels. */ + protected int[] _widths; + + /** The height of the tiles in each row in pixels. */ + protected int[] _heights; + + /** The offset distance (x, y) in pixels from the top-left of the + * image to the start of the first tile image. */ + protected Point _offsetPos = new Point(); + + /** The distance (x, y) in pixels between each tile in each row + * horizontally, and between each row of tiles vertically. */ + protected Dimension _gapSize = new Dimension(); + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/media/tile/Tile.java b/src/java/com/threerings/media/tile/Tile.java new file mode 100644 index 00000000..7597014d --- /dev/null +++ b/src/java/com/threerings/media/tile/Tile.java @@ -0,0 +1,178 @@ +// +// $Id: Tile.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Graphics2D; +import java.util.Arrays; + +import com.threerings.media.image.Colorization; +import com.threerings.media.image.Mirage; + +/** + * A tile represents a single square in a single layer in a scene. + */ +public class Tile // implements Cloneable +{ + /** Used when caching tiles. */ + public static class Key + { + public TileSet tileSet; + public int tileIndex; + public Colorization[] zations; + + public Key (TileSet tileSet, int tileIndex, Colorization[] zations) { + this.tileSet = tileSet; + this.tileIndex = tileIndex; + this.zations = zations; + } + + public boolean equals (Object other) { + if (other instanceof Key) { + Key okey = (Key)other; + return (tileSet == okey.tileSet && + tileIndex == okey.tileIndex && + Arrays.equals(zations, okey.zations)); + } else { + return false; + } + } + + public int hashCode () { + int code = (tileSet == null) ? tileIndex : + (tileSet.hashCode() ^ tileIndex); + int zcount = (zations == null) ? 0 : zations.length; + for (int ii = 0; ii < zcount; ii++) { + if (zations[ii] != null) { + code ^= zations[ii].hashCode(); + } + } + return code; + } + } + + /** The key associated with this tile. */ + public Key key; + + /** + * Configures this tile with its tile image. + */ + public void setImage (Mirage image) + { + if (_mirage != null) { + _totalTileMemory -= _mirage.getEstimatedMemoryUsage(); + } + _mirage = image; + if (_mirage != null) { + _totalTileMemory += _mirage.getEstimatedMemoryUsage(); + } + } + + /** + * Returns the width of this tile. + */ + public int getWidth () + { + return _mirage.getWidth(); + } + + /** + * Returns the height of this tile. + */ + public int getHeight () + { + return _mirage.getHeight(); + } + + /** + * Returns the estimated memory usage of our underlying tile image. + */ + public long getEstimatedMemoryUsage () + { + return _mirage.getEstimatedMemoryUsage(); + } + + /** + * Render the tile image at the specified position in the given + * graphics context. + */ + public void paint (Graphics2D gfx, int x, int y) + { + _mirage.paint(gfx, x, y); + } + + /** + * Returns true if the specified coordinates within this tile contains + * a non-transparent pixel. + */ + public boolean hitTest (int x, int y) + { + return _mirage.hitTest(x, y); + } + +// /** +// * Creates a shallow copy of this tile object. +// */ +// public Object clone () +// { +// try { +// return (Tile)super.clone(); +// } catch (CloneNotSupportedException cnse) { +// String errmsg = "All is wrong with the universe: " + cnse; +// throw new RuntimeException(errmsg); +// } +// } + + /** + * Return a string representation of this tile. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * This should be overridden by derived classes (which should be sure + * to call super.toString()) to append the derived class + * specific tile information to the string buffer. + */ + protected void toString (StringBuilder buf) + { + buf.append(_mirage.getWidth()).append("x"); + buf.append(_mirage.getHeight()); + } + + /** Decrement total tile memory by our value. */ + protected void finalize () + { + if (_mirage != null) { + _totalTileMemory -= _mirage.getEstimatedMemoryUsage(); + } + } + + /** Our tileset image. */ + protected Mirage _mirage; + + /** Used to track total (estimated) memory in use by tiles. */ + protected static long _totalTileMemory = 0L; +} diff --git a/src/java/com/threerings/media/tile/TileIcon.java b/src/java/com/threerings/media/tile/TileIcon.java new file mode 100644 index 00000000..7f379479 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileIcon.java @@ -0,0 +1,64 @@ +// +// $Id: TileIcon.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Graphics; + +import javax.swing.Icon; + +/** + * Implements the icon interface, using a {@link Tile} to render the icon + * image. + */ +public class TileIcon implements Icon +{ + /** + * Creates a tile icon that will use the supplied tile to render itself. + */ + public TileIcon (Tile tile) + { + _tile = tile; + } + + // documentation inherited from interface + public void paintIcon (Component c, Graphics g, int x, int y) + { + _tile.paint((Graphics2D)g, x, y); + } + + // documentation inherited from interface + public int getIconWidth () + { + return _tile.getWidth(); + } + + // documentation inherited from interface + public int getIconHeight () + { + return _tile.getHeight(); + } + + /** The tile used to render this icon. */ + protected Tile _tile; +} diff --git a/src/java/com/threerings/media/tile/TileManager.java b/src/java/com/threerings/media/tile/TileManager.java new file mode 100644 index 00000000..5f66b057 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileManager.java @@ -0,0 +1,247 @@ +// +// $Id: TileManager.java 3392 2005-03-10 01:30:34Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.lang.ref.SoftReference; + +import java.util.HashMap; + +import com.samskivert.io.PersistenceException; + +import com.threerings.media.Log; +import com.threerings.media.image.ImageManager; + +/** + * The tile manager provides a simplified interface for retrieving and + * caching tiles. Tiles can be loaded in two different ways. An + * application can load a tileset by hand, specifying the path to the + * tileset image and all of the tileset metadata necessary for extracting + * the image tiles, or it can provide a tileset repository which loads up + * tilesets using whatever repository mechanism is implemented by the + * supplied repository. In the latter case, tilesets are loaded by a + * unique identifier. + * + *

Loading tilesets by hand is intended for things like toolbar icons + * or games with a single set of tiles (think Stratego, for example). + * Loading tilesets from a repository supports games with vast numbers of + * tiles to which more tiles may be added on the fly (think the tiles for + * an isometric-display graphical MUD). + */ +public class TileManager +{ + /** + * Creates a tile manager and provides it with a reference to the + * image manager from which it will load tileset images. + * + * @param imgr the image manager via which the tile manager will + * decode and cache images. + */ + public TileManager (ImageManager imgr) + { + _imgr = imgr; + _defaultProvider = new IMImageProvider(_imgr, (String)null); + } + + /** + * Loads up a tileset from the specified image with the specified + * metadata parameters. + */ + public UniformTileSet loadTileSet (String imgPath, int width, int height) + { + return loadCachedTileSet("", imgPath, width, height); + } + + /** + * Loads up a tileset from the specified image (located in the + * specified resource set) with the specified metadata parameters. + */ + public UniformTileSet loadTileSet ( + String rset, String imgPath, int width, int height) + { + return loadTileSet( + getImageProvider(rset), rset, imgPath, width, height); + } + + /** + */ + public UniformTileSet loadTileSet ( + ImageProvider improv, String improvKey, String imgPath, + int width, int height) + { + UniformTileSet uts = loadCachedTileSet( + improvKey, imgPath, width, height); + uts.setImageProvider(improv); + return uts; + } + + /** + * Returns an image provider that will load images from the specified + * resource set. + */ + public ImageProvider getImageProvider (String rset) + { + return new IMImageProvider(_imgr, rset); + } + + /** + * Used to load and cache tilesets loaded via {@link #loadTileSet}. + */ + protected UniformTileSet loadCachedTileSet ( + String bundle, String imgPath, int width, int height) + { + String key = bundle + "::" + imgPath; + SoftReference ref = (SoftReference) _handcache.get(key); + UniformTileSet uts = (ref == null) ? null + : (UniformTileSet) ref.get(); + if (uts == null) { + uts = new UniformTileSet(); + uts.setImageProvider(_defaultProvider); + uts.setImagePath(imgPath); + uts.setWidth(width); + uts.setHeight(height); + _handcache.put(key, new SoftReference(uts)); + } + return uts; + } + + /** + * Sets the tileset repository that will be used by the tile manager + * when tiles are requested by tileset id. + */ + public void setTileSetRepository (TileSetRepository setrep) + { + _setrep = setrep; + } + + /** + * Returns the tileset repository currently in use. + */ + public TileSetRepository getTileSetRepository () + { + return _setrep; + } + + /** + * Returns the tileset with the specified id. Tilesets are fetched + * from the tileset repository supplied via {@link + * #setTileSetRepository}, and are subsequently cached. + * + * @param tileSetId the unique identifier for the desired tileset. + * + * @exception NoSuchTileSetException thrown if no tileset exists with + * the specified id or if an underlying error occurs with the tileset + * repository's persistence mechanism. + */ + public TileSet getTileSet (int tileSetId) + throws NoSuchTileSetException + { + // make sure we have a repository configured + if (_setrep == null) { + throw new NoSuchTileSetException(tileSetId); + } + + try { + return _setrep.getTileSet(tileSetId); + } catch (PersistenceException pe) { + Log.warning("Failure loading tileset [id=" + tileSetId + + ", error=" + pe + "]."); + throw new NoSuchTileSetException(tileSetId); + } + } + + /** + * Returns the tileset with the specified name. + * + * @throws NoSuchTileSetException if no tileset with the specified + * name is available via our configured tile set repository. + */ + public TileSet getTileSet (String name) + throws NoSuchTileSetException + { + // make sure we have a repository configured + if (_setrep == null) { + throw new NoSuchTileSetException(name); + } + + try { + return _setrep.getTileSet(name); + } catch (PersistenceException pe) { + Log.warning("Failure loading tileset [name=" + name + + ", error=" + pe + "]."); + throw new NoSuchTileSetException(name); + } + } + + /** + * Returns the {@link Tile} object with the specified fully qualified + * tile id. + * + * @see TileUtil#getFQTileId + */ + public Tile getTile (int fqTileId) + throws NoSuchTileSetException + { + return getTile(TileUtil.getTileSetId(fqTileId), + TileUtil.getTileIndex(fqTileId), null); + } + + /** + * Returns the {@link Tile} object with the specified fully qualified + * tile id. The supplied colorizer will be used to recolor the tile. + * + * @see TileUtil#getFQTileId + */ + public Tile getTile (int fqTileId, TileSet.Colorizer rizer) + throws NoSuchTileSetException + { + return getTile(TileUtil.getTileSetId(fqTileId), + TileUtil.getTileIndex(fqTileId), rizer); + } + + /** + * Returns the {@link Tile} object from the specified tileset at the + * specified index. + * + * @param tileSetId the tileset id. + * @param tileIndex the index of the tile to be retrieved. + * + * @return the tile object. + */ + public Tile getTile (int tileSetId, int tileIndex, TileSet.Colorizer rizer) + throws NoSuchTileSetException + { + TileSet set = getTileSet(tileSetId); + return set.getTile(tileIndex, rizer); + } + + /** The entity through which we decode and cache images. */ + protected ImageManager _imgr; + + /** A cache of tilesets that have been loaded by hand. */ + protected HashMap _handcache = new HashMap(); + + /** The tile set repository. */ + protected TileSetRepository _setrep; + + /** Used to load tileset images from the default resource source. */ + protected ImageProvider _defaultProvider; +} diff --git a/src/java/com/threerings/media/tile/TileMultiFrameImage.java b/src/java/com/threerings/media/tile/TileMultiFrameImage.java new file mode 100644 index 00000000..c02b5e64 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileMultiFrameImage.java @@ -0,0 +1,84 @@ +// +// $Id: TileMultiFrameImage.java 3559 2005-05-17 00:42:12Z tedv $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Graphics2D; + +import com.threerings.media.image.Colorization; +import com.threerings.media.util.MultiFrameImage; + +/** + * A {@link MultiFrameImage} implementation that obtains its image frames + * from a tileset. + */ +public class TileMultiFrameImage implements MultiFrameImage +{ + /** + * Creates a tile MFI which will obtain its image frames from the + * specified source tileset. + */ + public TileMultiFrameImage (TileSet source) + { + _source = source; + } + + /** + * Creates a recoolored tile MFI which will obtain its image frames + * from the specified source tileset. + */ + public TileMultiFrameImage (TileSet source, Colorization[] zations) + { + this(source.clone(zations)); + } + + // documentation inherited from interface + public int getFrameCount () + { + return _source.getTileCount(); + } + + // documentation inherited from interface + public int getWidth (int index) + { + return _source.getTile(index).getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) + { + return _source.getTile(index).getHeight(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) + { + _source.getTile(index).paint(g, x, y); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) + { + return _source.getTile(index).hitTest(x, y); + } + + protected TileSet _source; +} diff --git a/src/java/com/threerings/media/tile/TileSet.java b/src/java/com/threerings/media/tile/TileSet.java new file mode 100644 index 00000000..546a28ac --- /dev/null +++ b/src/java/com/threerings/media/tile/TileSet.java @@ -0,0 +1,454 @@ +// +// $Id: TileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.Serializable; +import java.lang.ref.SoftReference; +import java.util.HashMap; +import java.util.Iterator; + +import com.samskivert.util.StringUtil; +import com.samskivert.util.Throttle; + +import com.threerings.media.Log; +import com.threerings.media.image.Colorization; +import com.threerings.media.image.Mirage; +import com.threerings.media.image.ImageUtil; +import com.threerings.media.image.BufferedMirage; +import com.threerings.media.util.MultiFrameImage; +import com.threerings.media.util.MultiFrameImageImpl; + +/** + * A tileset stores information on a single logical set of tiles. It + * provides a clean interface for the {@link TileManager} or other + * entities to retrieve individual tiles from the tile set and + * encapsulates the potentially sophisticated process of extracting the + * tile image from a composite tileset image. + * + *

Tiles are referenced by their tile id. The tile id is essentially + * the tile number, assuming the tile at the top-left of the image is tile + * id zero and tiles are numbered, in ascending order, left to right, top + * to bottom. + * + *

This class is serializable and will be serialized, so derived + * classes should be sure to mark non-persistent fields as + * transient. + */ +public abstract class TileSet + implements Cloneable, Serializable +{ + /** Used to assign colorizations to tiles that require them. */ + public static interface Colorizer + { + /** + * Returns the colorization to be used for the specified named + * colorization class. + * + * @param index the index of the colorization being requested in + * the tileset's colorization list. + */ + public Colorization getColorization (int index, String zation); + } + + /** + * Configures this tileset with an image provider that it can use to + * load its tileset image. This will be called automatically when the + * tileset is fetched via the {@link TileManager}. + */ + public void setImageProvider (ImageProvider improv) + { + _improv = improv; + } + + /** + * Returns the tileset name. + */ + public String getName () + { + return (_name == null) ? _imagePath : _name; + } + + /** + * Specifies the tileset name. + */ + public void setName (String name) + { + _name = name; + } + + /** + * Sets the path to the image that will be used by this tileset. This + * must be called before the first call to {@link #getTile}. + */ + public void setImagePath (String imagePath) + { + _imagePath = imagePath; + } + + /** + * Returns the path to the composite image used by this tileset. + */ + public String getImagePath () + { + return _imagePath; + } + + /** + * Returns the number of tiles in the tileset. + */ + public abstract int getTileCount (); + + /** + * Creates a copy of this tileset which will apply the supplied + * colorizations to its tileset image when creating tiles. + */ + public TileSet clone (Colorization[] zations) + { + try { + TileSet tset = (TileSet)clone(); + tset._zations = zations; + return tset; + + } catch (CloneNotSupportedException cnse) { + Log.warning("Unable to clone tileset prior to colorization " + + "[tset=" + this + + ", zations=" + StringUtil.toString(zations) + + ", error=" + cnse + "]."); + return null; + } + } + + /** + * Returns a new tileset that is a clone of this tileset with the + * image path updated to reference the given path. Useful for + * configuring a single tileset and then generating additional + * tilesets with new images with the same configuration. + */ + public TileSet clone (String imagePath) + throws CloneNotSupportedException + { + TileSet dup = (TileSet)clone(); + dup.setImagePath(imagePath); + return dup; + } + + /** + * Equivalent to {@link #getTile(int,Colorizer)} with a null + * Colorizer argument. + */ + public Tile getTile (int tileIndex) + { + return getTile(tileIndex, _zations); + } + + /** + * Creates a {@link Tile} object from this tileset corresponding to + * the specified tile id and returns that tile. A null tile will never + * be returned, but one with an error image may be returned if a + * problem occurs loading the underlying tileset image. + * + * @param tileIndex the index of the tile in the tileset. Tile indexes + * start with zero as the upper left tile and increase by one as the + * tiles move left to right and top to bottom over the source image. + * @param rizer an entity that will be used to obtain colorizations + * for tilesets that are recolorizable. Passing null if the tileset is + * known not to be recolorizable is valid. + * + * @return the tile object. + */ + public Tile getTile (int tileIndex, Colorizer rizer) + { + return getTile(tileIndex, getColorizations(tileIndex, rizer)); + } + + /** + * Creates a {@link Tile} object from this tileset corresponding to + * the specified tile id and returns that tile. A null tile will never + * be returned, but one with an error image may be returned if a + * problem occurs loading the underlying tileset image. + * + * @param tileIndex the index of the tile in the tileset. Tile indexes + * start with zero as the upper left tile and increase by one as the + * tiles move left to right and top to bottom over the source image. + * @param zations colorizations to be applied to the tile image prior + * to returning it. These may be null for uncolorized images. + * + * @return the tile object. + */ + public Tile getTile (int tileIndex, Colorization[] zations) + { + Tile tile = null; + + // first look in the active set; if it's in use by anyone or in + // the cache, it will be in the active set + synchronized (_atiles) { + _key.tileSet = this; + _key.tileIndex = tileIndex; + _key.zations = zations; + SoftReference sref = (SoftReference)_atiles.get(_key); + if (sref != null) { + tile = (Tile)sref.get(); + } + } + + // if it's not in the active set, it's not in memory; so load it + if (tile == null) { + tile = createTile(); + tile.key = new Tile.Key(this, tileIndex, zations); + initTile(tile, tileIndex, zations); + synchronized (_atiles) { + _atiles.put(tile.key, new SoftReference(tile)); + } + } + + // periodically report our image cache performance + reportCachePerformance(); + + return tile; + } + + /** + * Returns a prepared version of the image that would be used by the + * tile at the specified index. Because tilesets are often used simply + * to provide access to a collection of uniform images, this method is + * provided to bypass the creation of a {@link Tile} object when all + * that is desired is access to the underlying image. + */ + public Mirage getTileMirage (int tileIndex) + { + return getTileMirage(tileIndex, getColorizations(tileIndex, null)); + } + + /** + * Returns a prepared version of the image that would be used by the + * tile at the specified index. Because tilesets are often used simply + * to provide access to a collection of uniform images, this method is + * provided to bypass the creation of a {@link Tile} object when all + * that is desired is access to the underlying image. + */ + public Mirage getTileMirage (int tileIndex, Colorization[] zations) + { + Rectangle bounds = computeTileBounds(tileIndex); + Mirage mirage = null; + if (checkTileIndex(tileIndex)) { + if (_improv == null) { + Log.warning("Aiya! Tile set missing image provider " + + "[path=" + _imagePath + "]."); + } else { + mirage = _improv.getTileImage(_imagePath, bounds, zations); + } + } + if (mirage == null) { + mirage = new BufferedMirage( + ImageUtil.createErrorImage(bounds.width, bounds.height)); + } + return mirage; + } + + /** + * Returns the entire, raw, uncut, unprepared tileset source image. + * Don't use this method unless you know what you're doing! This image + * should not be rendered directly to the screen, you should obtain a + * tile ({@link #getTile}), or a tile mirage ({@link #getTileMirage}). + */ + public BufferedImage getRawTileSetImage () + { + return _improv.getTileSetImage(_imagePath, _zations); + } + + /** + * Returns the raw (unprepared) image that would be used by the tile + * at the specified index. Don't use this method unless you know what + * you're doing! If you're going to be painting this image onto the + * screen directly, use {@link #getTileMirage} because that prepares + * the image for display. Only use this if you're going to do further + * processing and prepare the subsequent image for display onscreen. + */ + public BufferedImage getRawTileImage (int tileIndex) + { + Rectangle bounds = computeTileBounds(tileIndex); + BufferedImage img = null; + if (checkTileIndex(tileIndex)) { + BufferedImage timg = getRawTileSetImage(); + if (timg != null) { + img = timg.getSubimage(bounds.x, bounds.y, + bounds.width, bounds.height); + } else { + Log.warning("Missing source image " + this); + } + } + if (img == null) { + img = ImageUtil.createErrorImage(bounds.width, bounds.height); + } + return img; + } + + /** + * Returns colorizations for the specified tile image. The default is + * to return any colorizations associated with the tileset via a call + * to {@link #clone(Colorization[])}, however derived classes may have + * dynamic colorization policies that look up colorization assignments + * from the supplied colorizer. + */ + protected Colorization[] getColorizations (int tileIndex, Colorizer rizer) + { + return _zations; + } + + /** + * Used to ensure that the specified tile index is valid. + */ + protected boolean checkTileIndex (int tileIndex) + { + int tcount = getTileCount(); + if (tileIndex >= 0 && tileIndex < tcount) { + return true; + } else { + Log.warning("Requested invalid tile [tset=" + this + + ", index=" + tileIndex + "]."); + Thread.dumpStack(); + return false; + } + } + + /** + * Computes and returns the bounds for the specified tile based on the + * mechanism used by the derived class to do such things. The width + * and height of the bounds should be the size of the tile image and + * the x and y offset should be the offset in the tileset image for + * the image data of the specified tile. + * + * @param tileIndex the index of the tile whose bounds are to be + * computed. + */ + protected abstract Rectangle computeTileBounds (int tileIndex); + + /** + * Creates a blank tile of the appropriate type for this tileset. + * + * @return a blank tile ready to be populated with its image and + * metadata. + */ + protected Tile createTile () + { + return new Tile(); + } + + /** + * Initializes the supplied tile. Derived classes can override this + * method to add in their own tile information, but should be sure to + * call super.initTile(). + * + * @param tile the tile to initialize. + * @param tileIndex the index of the tile. + * @param zations the colorizations to be used when generating the + * tile image. + */ + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + if (_improv != null) { + tile.setImage(getTileMirage(tileIndex, zations)); + } + } + + /** + * Generates a string representation of the tileset information. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * Reports statistics detailing the image manager cache performance + * and the current size of the cached images. + */ + protected void reportCachePerformance () + { + if (/* Log.getLevel() != Log.log.DEBUG || */ + _improv == null || + _cacheStatThrottle.throttleOp()) { + return; + } + + // compute our estimated memory usage + long amem = 0; + int asize = 0; + synchronized (_atiles) { + // first total up the active tiles + Iterator iter = _atiles.values().iterator(); + while (iter.hasNext()) { + SoftReference sref = (SoftReference)iter.next(); + Tile tile = (Tile)sref.get(); + if (tile != null) { + asize++; + amem += tile.getEstimatedMemoryUsage(); + } + } + } + Log.info("Tile caches [amem=" + (amem / 1024) + "k" + + ", tmem=" + (Tile._totalTileMemory / 1024) + "k" + + ", seen=" + _atiles.size() + ", asize=" + asize + "]."); + } + + /** + * Derived classes can override this, calling + * super.toString(buf) and then appending additional + * information to the buffer. + */ + protected void toString (StringBuilder buf) + { + buf.append("name=").append(_name); + buf.append(", path=").append(_imagePath); + buf.append(", tileCount=").append(getTileCount()); + } + + /** The path to the file containing the tile images. */ + protected String _imagePath; + + /** The tileset name. */ + protected String _name; + + /** Colorizations to be applied to tiles created from this tileset. */ + protected transient Colorization[] _zations; + + /** The entity from which we obtain our tile image. */ + protected transient ImageProvider _improv; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + + /** A map containing weak references to all "active" tiles. */ + protected static HashMap _atiles = new HashMap(); + + /** A key used to look things up in the cache without creating + * craploads of keys unduly. */ + protected static Tile.Key _key = new Tile.Key(null, 0, null); + + /** Throttle our cache status logging to once every 300 seconds. */ + protected static Throttle _cacheStatThrottle = new Throttle(1, 300000L); +} diff --git a/src/java/com/threerings/media/tile/TileSetIDBroker.java b/src/java/com/threerings/media/tile/TileSetIDBroker.java new file mode 100644 index 00000000..fd250d78 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileSetIDBroker.java @@ -0,0 +1,70 @@ +// +// $Id: TileSetIDBroker.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import com.samskivert.io.PersistenceException; + +/** + * Brokers tileset ids. The tileset repository interface makes available a + * collection of tilesets based on a unique identifier. The expectation is + * that a collection of tilesets will be used to populate a repository and + * in that population process, tileset ids will be assigned to the + * tilesets. The tileset id broker system provides a means by which named + * tilesets can be mapped consistently to a set of tileset ids. Humans can + * then be responsible for assigning unique names to the tilesets and the + * broker will ensure that those names map to unique ids that won't change + * if the repository is rebuilt from the source tilesets. + */ +public interface TileSetIDBroker +{ + /** + * Returns the unique identifier for the named tileset. If no + * identifier has yet been assigned to the specified named tileset, + * one should be assigned and returned. + * + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism used to + * store the name to id mappings. + */ + public int getTileSetID (String tileSetName) + throws PersistenceException; + + /** + * Returns true if the specified tileset name is currently mapped to + * some value by this broker. + * + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism used to + * store the name to id mappings. + */ + public boolean tileSetMapped (String tileSetName) + throws PersistenceException; + + /** + * When the user of a tilset id broker is done obtaining tileset ids, + * it must call this method to give the tileset id broker an + * opportunity to flush any newly created tileset ids back to its + * persistent store. + */ + public void commit () + throws PersistenceException; +} diff --git a/src/java/com/threerings/media/tile/TileSetRepository.java b/src/java/com/threerings/media/tile/TileSetRepository.java new file mode 100644 index 00000000..c9f49dcb --- /dev/null +++ b/src/java/com/threerings/media/tile/TileSetRepository.java @@ -0,0 +1,86 @@ +// +// $Id: TileSetRepository.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.util.Iterator; + +import com.samskivert.io.PersistenceException; + +/** + * The tileset repository interface should be implemented by classes that + * provide access to tilesets keyed on a unique tileset identifier. The + * tileset id space is up to the repository implementation, which may or + * may not desire to use a {@link TileSetIDBroker} to manage the space. + */ +public interface TileSetRepository +{ + /** + * Returns an iterator over the identifiers of all {@link TileSet} + * objects available. + */ + public Iterator enumerateTileSetIds () + throws PersistenceException; + + /** + * Returns an iterator over all {@link TileSet} objects available. + */ + public Iterator enumerateTileSets () + throws PersistenceException; + + /** + * Returns the {@link TileSet} with the specified tile set + * identifier. The repository is responsible for configuring the tile + * set with an image provider. + * + * @exception NoSuchTileSetException thrown if no tileset exists with + * the specified identifier. + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism. + */ + public TileSet getTileSet (int tileSetId) + throws NoSuchTileSetException, PersistenceException; + + /** + * Returns the unique identifier of the {@link TileSet} with the + * specified tile set name. + * + * @exception NoSuchTileSetException thrown if no tileset exists with + * the specified name. + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism. + */ + public int getTileSetId (String setName) + throws NoSuchTileSetException, PersistenceException; + + /** + * Returns the {@link TileSet} with the specified tile set name. The + * repository is responsible for configuring the tile set with an + * image provider. + * + * @exception NoSuchTileSetException thrown if no tileset exists with + * the specified name. + * @exception PersistenceException thrown if an error occurs + * communicating with the underlying persistence mechanism. + */ + public TileSet getTileSet (String setName) + throws NoSuchTileSetException, PersistenceException; +} diff --git a/src/java/com/threerings/media/tile/TileUtil.java b/src/java/com/threerings/media/tile/TileUtil.java new file mode 100644 index 00000000..6ca17090 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileUtil.java @@ -0,0 +1,70 @@ +// +// $Id: TileUtil.java 3628 2005-06-28 17:42:55Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +/** + * Miscellaneous utility routines for working with tiles. + */ +public class TileUtil +{ + /** + * Generates a fully-qualified tile id given the supplied tileset id + * and tile index. + */ + public static int getFQTileId (int tileSetId, int tileIndex) + { + return (tileSetId << 16) | tileIndex; + } + + /** + * Extracts the tile set id from the supplied fully qualified tile id. + */ + public static int getTileSetId (int fqTileId) + { + return (fqTileId >> 16); + } + + /** + * Extracts the tile index from the supplied fully qualified tile id. + */ + public static int getTileIndex (int fqTileId) + { + return (fqTileId & 0xFFFF); + } + + /** + * Compute some hash value for "randomizing" tileset picks + * based on x and y coordinates. + * + * @return a positive, seemingly random number based on x and y. + */ + public static int getTileHash (int x, int y) + { + long seed = ((x ^ y) ^ MULTIPLIER) & MASK; + long hash = (seed * MULTIPLIER + ADDEND) & MASK; + return (int) (hash >>> 30); + } + + protected static final long MULTIPLIER = 0x5DEECE66DL; + protected static final long ADDEND = 0xBL; + protected static final long MASK = (1L << 48) - 1; +} diff --git a/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java b/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java new file mode 100644 index 00000000..5318c76d --- /dev/null +++ b/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java @@ -0,0 +1,301 @@ +// +// $Id: TrimmedObjectTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; + +import com.samskivert.util.ListUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.Colorization; +import com.threerings.media.tile.util.TileSetTrimmer; + +/** + * An object tileset in which the objects have been trimmed to the + * smallest possible images that still contain all of their + * non-transparent pixels. The objects' origins are adjusted so that the + * objects otherwise behave exactly as the untrimmed objects and are thus + * interchangeable (and more memory efficient). + */ +public class TrimmedObjectTileSet extends TileSet + implements RecolorableTileSet +{ + // documentation inherited + public int getTileCount () + { + return _bounds.length; + } + + /** + * Returns the x coordinate of the spot associated with the specified + * tile index. + */ + public int getXSpot (int tileIdx) + { + return (_bits == null) ? 0 : _bits[tileIdx].xspot; + } + + /** + * Returns the y coordinate of the spot associated with the specified + * tile index. + */ + public int getYSpot (int tileIdx) + { + return (_bits == null) ? 0 : _bits[tileIdx].yspot; + } + + /** + * Returns the orientation of the spot associated with the specified + * tile index, or -1 if the object has no associated + * spot. + */ + public int getSpotOrient (int tileIdx) + { + return (_bits == null) ? -1 : _bits[tileIdx].sorient; + } + + /** + * Returns the constraints associated with the specified tile index, or + * null if the object has no associated constraints. + */ + public String[] getConstraints (int tileIdx) + { + return (_bits == null) ? null : _bits[tileIdx].constraints; + } + + /** + * Checks whether the tile at the specified index has the given constraint. + */ + public boolean hasConstraint (int tileIdx, String constraint) + { + return (_bits == null || _bits[tileIdx].constraints == null) ? false : + ListUtil.contains(_bits[tileIdx].constraints, constraint); + } + + // documentation inherited from interface RecolorableTileSet + public String[] getColorizations () + { + return _zations; + } + + /** + * Returns the base width for the specified object index. + */ + public int getBaseWidth (int tileIdx) + { + return _ometrics[tileIdx].width; + } + + /** + * Returns the base height for the specified object index. + */ + public int getBaseHeight (int tileIdx) + { + return _ometrics[tileIdx].height; + } + + // documentation inherited + protected Rectangle computeTileBounds (int tileIndex) + { + return _bounds[tileIndex]; + } + + // documentation inherited + protected Colorization[] getColorizations (int tileIndex, Colorizer rizer) + { + Colorization[] zations = null; + if (rizer != null && _zations != null) { + zations = new Colorization[_zations.length]; + for (int ii = 0; ii < _zations.length; ii++) { + zations[ii] = rizer.getColorization(ii, _zations[ii]); + } + } + return zations; + } + + // documentation inherited + protected Tile createTile () + { + return new ObjectTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + + ObjectTile otile = (ObjectTile)tile; + otile.setBase(_ometrics[tileIndex].width, _ometrics[tileIndex].height); + otile.setOrigin(_ometrics[tileIndex].x, _ometrics[tileIndex].y); + if (_bits != null) { + Bits bits = _bits[tileIndex]; + otile.setPriority(bits.priority); + if (bits.sorient != -1) { + otile.setSpot(bits.xspot, bits.yspot, bits.sorient); + } + otile.setConstraints(bits.constraints); + } + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", ometrics=").append(StringUtil.toString(_ometrics)); + buf.append(", bounds=").append(StringUtil.toString(_bounds)); + buf.append(", bits=").append(StringUtil.toString(_bits)); + buf.append(", zations=").append(StringUtil.toString(_zations)); + } + + /** + * Creates a trimmed object tileset from the supplied source object + * tileset. The image path must be set by hand to the appropriate path + * based on where the image data that is written to the + * destImage parameter is actually stored on the file + * system. See {@link TileSetTrimmer#trimTileSet} for further + * information. + */ + public static TrimmedObjectTileSet trimObjectTileSet ( + ObjectTileSet source, OutputStream destImage) + throws IOException + { + final TrimmedObjectTileSet tset = new TrimmedObjectTileSet(); + tset.setName(source.getName()); + int tcount = source.getTileCount(); + +// System.out.println("Trimming object tile set " + +// "[source=" + source + "]."); + + // create our metrics arrays + tset._bounds = new Rectangle[tcount]; + tset._ometrics = new Rectangle[tcount]; + + // create our bits if needed + if (source._priorities != null || + source._xspots != null || + source._constraints != null) { + tset._bits = new Bits[tcount]; + } + + // copy our colorizations + tset._zations = source.getColorizations(); + + // fill in the original object metrics + for (int ii = 0; ii < tcount; ii++) { + tset._ometrics[ii] = new Rectangle(); + if (source._xorigins != null) { + tset._ometrics[ii].x = source._xorigins[ii]; + } + if (source._yorigins != null) { + tset._ometrics[ii].y = source._yorigins[ii]; + } + tset._ometrics[ii].width = source._owidths[ii]; + tset._ometrics[ii].height = source._oheights[ii]; + + // fill in our bits + if (tset._bits != null) { + tset._bits[ii] = new Bits(); + } + if (source._priorities != null) { + tset._bits[ii].priority = source._priorities[ii]; + } + if (source._xspots != null) { + tset._bits[ii].xspot = source._xspots[ii]; + tset._bits[ii].yspot = source._yspots[ii]; + tset._bits[ii].sorient = source._sorients[ii]; + } + if (source._constraints != null) { + tset._bits[ii].constraints = source._constraints[ii]; + } + } + + // create the trimmed tileset image + TileSetTrimmer.TrimMetricsReceiver tmr = + new TileSetTrimmer.TrimMetricsReceiver() { + public void trimmedTile (int tileIndex, int imageX, int imageY, + int trimX, int trimY, + int trimWidth, int trimHeight) { + tset._ometrics[tileIndex].x -= trimX; + tset._ometrics[tileIndex].y -= trimY; + tset._bounds[tileIndex] = + new Rectangle(imageX, imageY, trimWidth, trimHeight); + } + }; + TileSetTrimmer.trimTileSet(source, destImage, tmr); + +// Log.info("Trimmed object tileset " + +// "[bounds=" + StringUtil.toString(tset._bounds) + +// ", metrics=" + StringUtil.toString(tset._ometrics) + "]."); + + return tset; + } + + /** Extra bits related to object tiles. */ + protected static class Bits implements Serializable + { + /** The default render priority for this object. */ + public byte priority; + + /** The x coordinate of the "spot" associated with this object. */ + public short xspot; + + /** The y coordinate of the "spot" associated with this object. */ + public short yspot; + + /** The orientation of the "spot" associated with this object. */ + public byte sorient = -1; + + /** The constraints associated with this object. */ + public String[] constraints; + + /** Generates a string representation of this instance. */ + public String toString () + { + return StringUtil.fieldsToString(this); + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } + + /** Contains the width and height of each object tile and the offset + * into the tileset image of their image data. */ + protected Rectangle[] _bounds; + + /** Contains the origin offset for each object tile and the object + * footprint width and height (in tile units). */ + protected Rectangle[] _ometrics; + + /** Extra bits relating to our objects. */ + protected Bits[] _bits; + + /** Colorization classes that apply to our objects. */ + protected String[] _zations; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/media/tile/TrimmedTile.java b/src/java/com/threerings/media/tile/TrimmedTile.java new file mode 100644 index 00000000..88ee888a --- /dev/null +++ b/src/java/com/threerings/media/tile/TrimmedTile.java @@ -0,0 +1,91 @@ +// +// $Id: TrimmedTile.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.samskivert.util.StringUtil; + +/** + * Behaves just like a regular tile, but contains a "trimmed" image which + * is one where the source image has been trimmed to the smallest + * rectangle that contains all the non-transparent pixels of the original + * image. + */ +public class TrimmedTile extends Tile +{ + /** + * Sets the trimmed bounds of this tile. + * + * @param tbounds contains the width and height of the + * untrimmed tile, but the x and y offset of the + * trimmed tile image in the original untrimmed tile image. + */ + public void setTrimmedBounds (Rectangle tbounds) + { + _tbounds = tbounds; + } + + // documentation inherited + public int getWidth () + { + return _tbounds.width; + } + + // documentation inherited + public int getHeight () + { + return _tbounds.height; + } + + // documentation inherited + public void paint (Graphics2D gfx, int x, int y) + { + _mirage.paint(gfx, x + _tbounds.x, y + _tbounds.y); + } + + /** + * Fills in the bounds of the trimmed image within the coordinate + * system defined by the complete virtual tile. + */ + public void getTrimmedBounds (Rectangle tbounds) + { + tbounds.setBounds(_tbounds.x, _tbounds.y, + _mirage.getWidth(), _mirage.getHeight()); + } + + // documentation inherited + public boolean hitTest (int x, int y) + { + return super.hitTest(x - _tbounds.x, y - _tbounds.y); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + buf.append(", tbounds=").append(StringUtil.toString(_tbounds)); + } + + /** Our extra trimmed image dimension information. */ + protected Rectangle _tbounds; +} diff --git a/src/java/com/threerings/media/tile/TrimmedTileSet.java b/src/java/com/threerings/media/tile/TrimmedTileSet.java new file mode 100644 index 00000000..c60a9ed4 --- /dev/null +++ b/src/java/com/threerings/media/tile/TrimmedTileSet.java @@ -0,0 +1,114 @@ +// +// $Id: TrimmedTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; + +import java.io.IOException; +import java.io.OutputStream; + +import com.threerings.media.image.Colorization; +import com.threerings.media.tile.util.TileSetTrimmer; + +/** + * Contains the necessary information to create a set of trimmed tiles + * from a base image and the associated trim metrics. + */ +public class TrimmedTileSet extends TileSet +{ + // documentation inherited + public int getTileCount () + { + return _obounds.length; + } + + // documentation inherited + protected Rectangle computeTileBounds (int tileIndex) + { + return _obounds[tileIndex]; + } + + // documentation inherited + protected Tile createTile () + { + return new TrimmedTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + ((TrimmedTile)tile).setTrimmedBounds(_tbounds[tileIndex]); + } + + /** + * Creates a trimmed tileset from the supplied source tileset. The + * image path must be set by hand to the appropriate path based on + * where the image data that is written to the destImage + * parameter is actually stored on the file system. See {@link + * TileSetTrimmer#trimTileSet} for further information. + */ + public static TrimmedTileSet trimTileSet ( + TileSet source, OutputStream destImage) + throws IOException + { + final TrimmedTileSet tset = new TrimmedTileSet(); + tset.setName(source.getName()); + int tcount = source.getTileCount(); + tset._tbounds = new Rectangle[tcount]; + tset._obounds = new Rectangle[tcount]; + + // grab the dimensions of the original tiles + for (int ii = 0; ii < tcount; ii++) { + tset._tbounds[ii] = source.computeTileBounds(ii); + } + + // create the trimmed tileset image + TileSetTrimmer.TrimMetricsReceiver tmr = + new TileSetTrimmer.TrimMetricsReceiver() { + public void trimmedTile (int tileIndex, int imageX, int imageY, + int trimX, int trimY, + int trimWidth, int trimHeight) { + tset._tbounds[tileIndex].x = trimX; + tset._tbounds[tileIndex].y = trimY; + tset._obounds[tileIndex] = + new Rectangle(imageX, imageY, trimWidth, trimHeight); + } + }; + TileSetTrimmer.trimTileSet(source, destImage, tmr); + + return tset; + } + + /** The width and height of the trimmed tile, and the x and y offset + * of the trimmed image within our tileset image. */ + protected Rectangle[] _obounds; + + /** The width and height of the untrimmed image and the x and y offset + * within the untrimmed image at which the trimmed image should be + * rendered. */ + protected Rectangle[] _tbounds; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/media/tile/UniformTileSet.java b/src/java/com/threerings/media/tile/UniformTileSet.java new file mode 100644 index 00000000..c3e5fe72 --- /dev/null +++ b/src/java/com/threerings/media/tile/UniformTileSet.java @@ -0,0 +1,103 @@ +// +// $Id: UniformTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.threerings.geom.GeomUtil; + +/** + * A uniform tileset is one that is composed of tiles that are all the + * same width and height and are arranged into rows, with each row having + * the same number of tiles except possibly the final row which can + * contain the same as or less than the number of tiles contained by the + * previous rows. + */ +public class UniformTileSet extends TileSet +{ + // documentation inherited + public int getTileCount () + { + BufferedImage tsimg = getRawTileSetImage(); + int perRow = tsimg.getWidth() / _width; + int perCol = tsimg.getHeight() / _height; + return perRow * perCol; + } + + /** + * Specifies the width of the tiles in this tileset. + */ + public void setWidth (int width) + { + _width = width; + } + + /** + * Returns the width of the tiles in this tileset. + */ + public int getWidth () + { + return _width; + } + + /** + * Specifies the height of the tiles in this tileset. + */ + public void setHeight (int height) + { + _height = height; + } + + /** + * Returns the height of the tiles in this tileset. + */ + public int getHeight () + { + return _height; + } + + // documentation inherited + protected Rectangle computeTileBounds (int tileIndex) + { + BufferedImage tsimg = getRawTileSetImage(); + return GeomUtil.getTile(tsimg.getWidth(), tsimg.getHeight(), + _width, _height, tileIndex); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", width=").append(_width); + buf.append(", height=").append(_height); + } + + /** The width (in pixels) of the tiles in this tileset. */ + protected int _width; + + /** The height (in pixels) of the tiles in this tileset. */ + protected int _height; + + /** Our historic serialization version id. */ + private static final long serialVersionUID = 3536616655149232917L; +} diff --git a/src/java/com/threerings/media/tile/bundle/BundleUtil.java b/src/java/com/threerings/media/tile/bundle/BundleUtil.java new file mode 100644 index 00000000..20a6e826 --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/BundleUtil.java @@ -0,0 +1,82 @@ +// +// $Id: BundleUtil.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; + +import com.samskivert.io.StreamUtil; + +import com.threerings.resource.ResourceBundle; + +/** + * Bundle related utility functions. + */ +public class BundleUtil +{ + /** The path to the metadata resource that we will attempt to load + * from our resource set. */ + public static final String METADATA_PATH = "tsbundles.dat"; + + /** + * Extracts, but does not initialize, a serialized tileset bundle + * instance from the supplied resource bundle. + */ + public static TileSetBundle extractBundle (ResourceBundle bundle) + throws IOException, ClassNotFoundException + { + // unserialize the tileset bundles array + InputStream tbin = null; + try { + tbin = bundle.getResource(METADATA_PATH); + ObjectInputStream oin = new ObjectInputStream( + new BufferedInputStream(tbin)); + TileSetBundle tsb = (TileSetBundle)oin.readObject(); + return tsb; + } finally { + StreamUtil.close(tbin); + } + } + + /** + * Extracts, but does not initialize, a serialized tileset bundle + * instance from the supplied file. + */ + public static TileSetBundle extractBundle (File file) + throws IOException, ClassNotFoundException + { + // unserialize the tileset bundles array + FileInputStream fin = new FileInputStream(file); + try { + ObjectInputStream oin = new ObjectInputStream( + new BufferedInputStream(fin)); + TileSetBundle tsb = (TileSetBundle)oin.readObject(); + return tsb; + } finally { + StreamUtil.close(fin); + } + } +} diff --git a/src/java/com/threerings/media/tile/bundle/BundledTileSetRepository.java b/src/java/com/threerings/media/tile/bundle/BundledTileSetRepository.java new file mode 100644 index 00000000..0b8e0876 --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/BundledTileSetRepository.java @@ -0,0 +1,232 @@ +// +// $Id: BundledTileSetRepository.java 3608 2005-06-20 22:59:07Z andrzej $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle; + +import java.util.HashMap; +import java.util.Iterator; + +import com.samskivert.io.PersistenceException; +import com.samskivert.util.HashIntMap; +import com.threerings.resource.ResourceBundle; +import com.threerings.resource.ResourceManager; + +import com.threerings.media.Log; +import com.threerings.media.image.ImageManager; +import com.threerings.media.tile.IMImageProvider; +import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TileSetRepository; + +/** + * Loads tileset data from a set of resource bundles. + * + * @see ResourceManager + */ +public class BundledTileSetRepository + implements TileSetRepository +{ + /** + * Constructs a repository which will obtain its resource set from the + * supplied resource manager. + * + * @param rmgr the resource manager from which to obtain our resource + * set. + * @param imgr the image manager through which we will configure the + * tile sets to load their images, or null if image tiles + * should not be loaded (only the tile metadata) + * @param name the name of the resource set from which we will be + * loading our tile data. + */ + public BundledTileSetRepository (final ResourceManager rmgr, + final ImageManager imgr, + final String name) + { + _imgr = imgr; + + // unpack our bundles in the background + new Thread(new Runnable() { + public void run () { + initBundles(rmgr, name); + } + }).start(); + } + + /** + * Initializes our bundles, + */ + protected void initBundles (ResourceManager rmgr, String name) + { + // first we obtain the resource set from which we will load up our + // tileset bundles + ResourceBundle[] rbundles = rmgr.getResourceSet(name); + + // sanity check + if (rbundles == null) { + Log.warning("Unable to fetch tileset resource set " + + "[name=" + name + "]. Perhaps it's not defined " + + "in the resource manager config?"); + return; + } + + HashIntMap idmap = new HashIntMap(); + HashMap namemap = new HashMap(); + + // iterate over the resource bundles in the set, loading up the + // tileset bundles in each resource bundle + for (int i = 0; i < rbundles.length; i++) { + addBundle(idmap, namemap, rbundles[i]); + } + + // fill in our bundles array and wake up any waiters + synchronized (this) { + _idmap = idmap; + _namemap = namemap; + notifyAll(); + } + } + + /** + * Registers the bundle with the tileset repository, overriding any + * bundle with the same id or name. + */ + public void addBundle (ResourceBundle bundle) + { + addBundle(_idmap, _namemap, bundle); + } + + /** + * Extracts the tileset bundle from the supplied resource bundle + * and registers it. + */ + protected void addBundle (HashIntMap idmap, HashMap namemap, + ResourceBundle bundle) + { + try { + TileSetBundle tsb = BundleUtil.extractBundle(bundle); + // initialize it and add it to the list + tsb.init(bundle); + addBundle(idmap, namemap, tsb); + + } catch (Exception e) { + Log.warning("Unable to load tileset bundle '" + + BundleUtil.METADATA_PATH + "' from resource " + + "bundle [rbundle=" + bundle + + ", error=" + e + "]."); + Log.logStackTrace(e); + } + } + + /** + * Adds the tilesets in the supplied bundle to our tileset mapping + * tables. Any tilesets with the same name or id will be overwritten. + */ + protected void addBundle (HashIntMap idmap, HashMap namemap, + TileSetBundle bundle) + { + IMImageProvider improv = (_imgr == null) ? + null : new IMImageProvider(_imgr, bundle); + + // map all of the tilesets in this bundle + for (Iterator iter = bundle.entrySet().iterator(); iter.hasNext(); ) { + HashIntMap.Entry entry = (HashIntMap.Entry)iter.next(); + Integer tsid = (Integer)entry.getKey(); + TileSet tset = (TileSet)entry.getValue(); + tset.setImageProvider(improv); + idmap.put(tsid.intValue(), tset); + namemap.put(tset.getName(), tsid); + } + } + + // documentation inherited from interface + public Iterator enumerateTileSetIds () + throws PersistenceException + { + waitForBundles(); + return _idmap.keySet().iterator(); + } + + // documentation inherited from interface + public Iterator enumerateTileSets () + throws PersistenceException + { + waitForBundles(); + return _idmap.values().iterator(); + } + + // documentation inherited from interface + public TileSet getTileSet (int tileSetId) + throws NoSuchTileSetException, PersistenceException + { + waitForBundles(); + TileSet tset = (TileSet)_idmap.get(tileSetId); + if (tset == null) { + throw new NoSuchTileSetException(tileSetId); + } + return tset; + } + + // documentation inherited from interface + public int getTileSetId (String setName) + throws NoSuchTileSetException, PersistenceException + { + waitForBundles(); + Integer tsid = (Integer)_namemap.get(setName); + if (tsid != null) { + return tsid.intValue(); + } + throw new NoSuchTileSetException(setName); + } + + // documentation inherited from interface + public TileSet getTileSet (String setName) + throws NoSuchTileSetException, PersistenceException + { + waitForBundles(); + TileSet tset = null; + Integer tsid = (Integer)_namemap.get(setName); + if (tsid != null) { + return getTileSet(tsid.intValue()); + } + throw new NoSuchTileSetException(setName); + } + + /** Used to allow bundle unpacking to proceed asynchronously. */ + protected synchronized void waitForBundles () + { + while (_idmap == null) { + try { + wait(); + } catch (InterruptedException ie) { + Log.warning("Interrupted waiting for bundles " + ie); + } + } + } + + /** The image manager via which we load our images. */ + protected ImageManager _imgr; + + /** A mapping from tileset id to tileset. */ + protected HashIntMap _idmap; + + /** A mapping from tileset name to tileset id. */ + protected HashMap _namemap; +} diff --git a/src/java/com/threerings/media/tile/bundle/TileSetBundle.java b/src/java/com/threerings/media/tile/bundle/TileSetBundle.java new file mode 100644 index 00000000..effc9297 --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/TileSetBundle.java @@ -0,0 +1,148 @@ +// +// $Id: TileSetBundle.java 4007 2006-04-10 08:59:30Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Iterator; + +import javax.imageio.ImageIO; + +import com.samskivert.util.HashIntMap; +import com.threerings.resource.ResourceBundle; + +import com.threerings.media.image.FastImageIO; +import com.threerings.media.image.ImageDataProvider; +import com.threerings.media.tile.TileSet; + +/** + * A tileset bundle is used to load up tilesets by id from a persistent + * bundle of tilesets stored on the local filesystem. + */ +public class TileSetBundle extends HashIntMap + implements Serializable, ImageDataProvider +{ + /** + * Initializes this resource bundle with a reference to the jarfile + * from which it was loaded and from which it can load image data. The + * image manager will be used to decode the images. + */ + public void init (ResourceBundle bundle) + { + _bundle = bundle; + } + + /** + * Returns the bundle file from which our tiles are fetched. + */ + public File getSource () + { + return _bundle.getSource(); + } + + /** + * Adds a tileset to this tileset bundle. + */ + public final void addTileSet (int tileSetId, TileSet set) + { + put(tileSetId, set); + } + + /** + * Retrieves a tileset from this tileset bundle. + */ + public final TileSet getTileSet (int tileSetId) + { + return (TileSet)get(tileSetId); + } + + /** + * Enumerates the tileset ids in this tileset bundle. + */ + public Iterator enumerateTileSetIds () + { + return keySet().iterator(); + } + + /** + * Enumerates the tilesets in this tileset bundle. + */ + public Iterator enumerateTileSets () + { + return values().iterator(); + } + + // documentation inherited from interface + public String getIdent () + { + return "tsb:" + _bundle.getSource(); + } + + // documentation inherited from interface + public BufferedImage loadImage (String path) + throws IOException + { + if (path.endsWith(FastImageIO.FILE_SUFFIX)) { + return FastImageIO.read(_bundle.getResourceFile(path)); + } else { + return ImageIO.read(_bundle.getResourceFile(path)); + } + } + + // custom serialization process + private void writeObject (ObjectOutputStream out) + throws IOException + { + out.writeInt(size()); + + Iterator entries = intEntrySet().iterator(); + while (entries.hasNext()) { + IntEntry entry = (IntEntry)entries.next(); + out.writeInt(entry.getIntKey()); + out.writeObject(entry.getValue()); + } + } + + // custom unserialization process + private void readObject (ObjectInputStream in) + throws IOException, ClassNotFoundException + { + int count = in.readInt(); + + for (int i = 0; i < count; i++) { + int tileSetId = in.readInt(); + TileSet set = (TileSet)in.readObject(); + put(tileSetId, set); + } + } + + /** That from which we load our tile images. */ + protected transient ResourceBundle _bundle; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } diff --git a/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java b/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java new file mode 100644 index 00000000..0083ea80 --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java @@ -0,0 +1,93 @@ +// +// $Id: DumpBundle.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle.tools; + +import java.io.File; +import java.util.Iterator; + +import com.threerings.resource.ResourceManager; +import com.threerings.resource.ResourceBundle; + +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.bundle.BundleUtil; +import com.threerings.media.tile.bundle.TileSetBundle; + +/** + * Dumps the contents of a tileset bundle to stdout (just the serialized + * object info, not the image data). + */ +public class DumpBundle +{ + public static void main (String[] args) + { + boolean dumpTiles = false; + + if (args.length < 1) { + String usage = "Usage: DumpBundle [-tiles] " + + "(bundle.jar|tsbundle.dat) [...]"; + System.err.println(usage); + System.exit(-1); + } + + // create a resource and image manager in case they want to dump + // the tiles + ResourceManager rmgr = new ResourceManager("rsrc"); + + for (int i = 0; i < args.length; i++) { + // oh the hackery + if (args[i].equals("-tiles")) { + dumpTiles = true; + continue; + } + + File file = new File(args[i]); + try { + TileSetBundle tsb = null; + if (args[i].endsWith(".jar")) { + ResourceBundle bundle = new ResourceBundle(file); + tsb = BundleUtil.extractBundle(bundle); + tsb.init(bundle); + } else { + tsb = BundleUtil.extractBundle(file); + } + + Iterator tsids = tsb.enumerateTileSetIds(); + while (tsids.hasNext()) { + Integer tsid = (Integer)tsids.next(); + TileSet set = tsb.getTileSet(tsid.intValue()); + System.out.println(tsid + " => " + set); + if (dumpTiles) { + for (int t = 0, nn = set.getTileCount(); t < nn; t++) { + System.out.println(" " + t + " => " + + set.getTile(t)); + } + } + } + + } catch (Exception e) { + System.err.println("Error dumping bundle [path=" + args[i] + + ", error=" + e + "]."); + e.printStackTrace(); + } + } + } +} diff --git a/src/java/com/threerings/media/tile/bundle/tools/TileSetBundler.java b/src/java/com/threerings/media/tile/bundle/tools/TileSetBundler.java new file mode 100644 index 00000000..d679b16e --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/tools/TileSetBundler.java @@ -0,0 +1,482 @@ +// +// $Id: TileSetBundler.java 3788 2005-12-20 02:09:18Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle.tools; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.Deflater; + +import javax.imageio.ImageIO; + +import org.apache.commons.digester.Digester; +import org.apache.commons.io.CopyUtils; +import org.xml.sax.SAXException; + +import com.samskivert.io.PersistenceException; + +import com.threerings.media.Log; +import com.threerings.media.image.FastImageIO; +import com.threerings.media.image.ImageUtil; + +import com.threerings.media.tile.ImageProvider; +import com.threerings.media.tile.ObjectTileSet; +import com.threerings.media.tile.SimpleCachingImageProvider; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TileSetIDBroker; +import com.threerings.media.tile.TrimmedObjectTileSet; +import com.threerings.media.tile.UniformTileSet; +import com.threerings.media.tile.bundle.BundleUtil; +import com.threerings.media.tile.bundle.TileSetBundle; +import com.threerings.media.tile.tools.xml.TileSetRuleSet; + +/** + * The tileset bundler is used to create tileset bundles from a set of XML + * tileset descriptions in a bundle description file. The bundles contain + * a serialized representation of the tileset objects along with the + * actual image files referenced by those tilesets. + * + *

The organization of the bundle description file is customizable + * based on the an XML configuration file provided to the tileset bundler + * when constructed. The bundler configuration maps XML paths to tileset + * parsers. An example configuration follows: + * + *

+ * <bundler-config>
+ *   <mapping>
+ *     <path>bundle.tilesets.uniform</path>
+ *     <ruleset>
+ *       com.threerings.media.tile.tools.xml.UniformTileSetRuleSet
+ *     </ruleset>
+ *   </mapping>
+ *   <mapping>
+ *     <path>bundle.tilesets.object</path>
+ *     <ruleset>
+ *       com.threerings.media.tile.tools.xml.ObjectTileSetRuleSet
+ *     </ruleset>
+ *   </mapping>
+ * </bundler-config>
+ * 
+ * + * This configuration would be used to parse a bundle description that + * looked something like the following: + * + *
+ * <bundle>
+ *   <tilesets>
+ *     <uniform>
+ *       <tileset>
+ *         <!-- ... -->
+ *       </tileset>
+ *     </uniform>
+ *     <object>
+ *       <tileset>
+ *         <!-- ... -->
+ *       </tileset>
+ *     </object>
+ *   </tilesets>
+ * 
+ * + * The class specified in the ruleset element must derive + * from {@link TileSetRuleSet}. The images that will be included in the + * bundle must be in the same directory as the bundle description file and + * the tileset descriptions must reference the images without a preceding + * path. + */ +public class TileSetBundler +{ + /** + * Constructs a tileset bundler with the specified path to a bundler + * configuration file. The configuration file will be loaded and used + * to configure this tileset bundler. + */ + public TileSetBundler (String configPath) + throws IOException + { + this(new File(configPath)); + } + + /** + * Constructs a tileset bundler with the specified bundler config + * file. + */ + public TileSetBundler (File configFile) + throws IOException + { + // we parse our configuration with a digester + Digester digester = new Digester(); + + // push our mappings array onto the stack + ArrayList mappings = new ArrayList(); + digester.push(mappings); + + // create a mapping object for each mapping entry and append it to + // our mapping list + digester.addObjectCreate("bundler-config/mapping", + Mapping.class.getName()); + digester.addSetNext("bundler-config/mapping", + "add", "java.lang.Object"); + + // configure each mapping object with the path and ruleset + digester.addCallMethod("bundler-config/mapping", "init", 2); + digester.addCallParam("bundler-config/mapping/path", 0); + digester.addCallParam("bundler-config/mapping/ruleset", 1); + + // now go like the wind + FileInputStream fin = new FileInputStream(configFile); + try { + digester.parse(fin); + } catch (SAXException saxe) { + String errmsg = "Failure parsing bundler config file " + + "[file=" + configFile.getPath() + "]"; + throw (IOException) new IOException(errmsg).initCause(saxe); + } + fin.close(); + + // create our digester + _digester = new Digester(); + + // use the mappings we parsed to configure our actual digester + int msize = mappings.size(); + for (int i = 0; i < msize; i++) { + Mapping map = (Mapping)mappings.get(i); + try { + TileSetRuleSet ruleset = (TileSetRuleSet) + Class.forName(map.ruleset).newInstance(); + + // configure the ruleset + ruleset.setPrefix(map.path); + // add it to the digester + _digester.addRuleSet(ruleset); + // and add a rule to stick the parsed tilesets onto the + // end of an array list that we'll put on the stack + _digester.addSetNext(map.path + TileSetRuleSet.TILESET_PATH, + "add", "java.lang.Object"); + + } catch (Exception e) { + String errmsg = "Unable to create tileset rule set " + + "instance [mapping=" + map + "]."; + throw (IOException) new IOException(errmsg).initCause(e); + } + } + } + + /** + * Creates a tileset bundle at the location specified by the + * targetPath parameter, based on the description + * provided via the bundleDesc parameter. + * + * @param idBroker the tileset id broker that will be used to map + * tileset names to tileset ids. + * @param bundleDesc a file object pointing to the bundle description + * file. + * @param targetPath the path of the tileset bundle file that will be + * created. + * + * @exception IOException thrown if an error occurs reading, writing + * or processing anything. + */ + public void createBundle ( + TileSetIDBroker idBroker, File bundleDesc, String targetPath) + throws IOException + { + createBundle(idBroker, bundleDesc, new File(targetPath)); + } + + /** + * Creates a tileset bundle at the location specified by the + * targetPath parameter, based on the description + * provided via the bundleDesc parameter. + * + * @param idBroker the tileset id broker that will be used to map + * tileset names to tileset ids. + * @param bundleDesc a file object pointing to the bundle description + * file. + * @param target the tileset bundle file that will be created. + * + * @return true if the bundle was rebuilt, false if it was not because + * the bundle file was newer than all involved source files. + * + * @exception IOException thrown if an error occurs reading, writing + * or processing anything. + */ + public boolean createBundle ( + TileSetIDBroker idBroker, final File bundleDesc, File target) + throws IOException + { + // stick an array list on the top of the stack into which we will + // collect parsed tilesets + ArrayList sets = new ArrayList(); + _digester.push(sets); + + // parse the tilesets + FileInputStream fin = new FileInputStream(bundleDesc); + try { + _digester.parse(fin); + } catch (SAXException saxe) { + String errmsg = "Failure parsing bundle description file " + + "[path=" + bundleDesc.getPath() + "]"; + throw (IOException) new IOException(errmsg).initCause(saxe); + } finally { + fin.close(); + } + + // we want to make sure that at least one of the tileset image + // files or the bundle definition file is newer than the bundle + // file, otherwise consider the bundle up to date + long newest = bundleDesc.lastModified(); + + // create a tileset bundle to hold our tilesets + TileSetBundle bundle = new TileSetBundle(); + + // add all of the parsed tilesets to the tileset bundle + try { + for (int i = 0; i < sets.size(); i++) { + TileSet set = (TileSet)sets.get(i); + String name = set.getName(); + + // let's be robust + if (name == null) { + Log.warning("Tileset was parsed, but received no name " + + "[set=" + set + "]. Skipping."); + continue; + } + + // make sure this tileset's image file exists and check + // it's last modified date + File tsfile = new File(bundleDesc.getParent(), + set.getImagePath()); + if (!tsfile.exists()) { + System.err.println("Tile set missing image file " + + "[bundle=" + bundleDesc.getPath() + + ", name=" + set.getName() + + ", imgpath=" + tsfile.getPath() + "]."); + continue; + } + if (tsfile.lastModified() > newest) { + newest = tsfile.lastModified(); + } + + // assign a tilset id to the tileset and bundle it + try { + int tileSetId = idBroker.getTileSetID(name); + bundle.addTileSet(tileSetId, set); + } catch (PersistenceException pe) { + String errmsg = "Failure obtaining a tileset id for " + + "tileset [set=" + set + "]."; + throw (IOException) new IOException(errmsg).initCause(pe); + } + } + + // clear out our array list in preparation for another go + sets.clear(); + + } finally { + // before we go, we have to commit our brokered tileset ids + // back to the broker's persistent store + try { + idBroker.commit(); + } catch (PersistenceException pe) { + Log.warning("Failure committing brokered tileset ids " + + "back to broker's persistent store " + + "[error=" + pe + "]."); + } + } + + // see if our newest file is newer than the tileset bundle + if (newest < target.lastModified()) { + return false; + } + + // create an image provider for loading our tileset images + SimpleCachingImageProvider improv = new SimpleCachingImageProvider() { + protected BufferedImage loadImage (String path) + throws IOException { + return ImageIO.read(new File(bundleDesc.getParent(), path)); + } + }; + + return createBundle(target, bundle, improv, bundleDesc.getParent()); + } + + /** + * Finish the creation of a tileset bundle jar file. + * + * @param target the tileset bundle file that will be created. + * @param bundle contains the tilesets we'd like to save out to the + * bundle. + * @param improv the image provider. + * @param imageBase the base directory for getting images for non + * ObjectTileSet tilesets. + */ + public static boolean createBundle ( + File target, TileSetBundle bundle, ImageProvider improv, + String imageBase) + throws IOException + { + // now we have to create the actual bundle file + FileOutputStream fout = new FileOutputStream(target); + Manifest manifest = new Manifest(); + JarOutputStream jar = new JarOutputStream(fout, manifest); + jar.setLevel(Deflater.BEST_COMPRESSION); + + try { + // write all of the image files to the bundle, converting the + // tilesets to trimmed tilesets in the process + Iterator iditer = bundle.enumerateTileSetIds(); + while (iditer.hasNext()) { + int tileSetId = ((Integer)iditer.next()).intValue(); + TileSet set = bundle.getTileSet(tileSetId); + String imagePath = set.getImagePath(); + + // sanity checks + if (imagePath == null) { + Log.warning("Tileset contains no image path " + + "[set=" + set + "]. It ain't gonna work."); + continue; + } + + // if this is an object tileset, we can't trim it! + if (set instanceof ObjectTileSet) { + // set the tileset up with an image provider; we + // need to do this so that we can trim it! + set.setImageProvider(improv); + + // we're going to trim it, so adjust the path + imagePath = adjustImagePath(imagePath); + jar.putNextEntry(new JarEntry(imagePath)); + + try { + // create a trimmed object tileset, which will + // write the trimmed tileset image to the jar + // output stream + TrimmedObjectTileSet tset = + TrimmedObjectTileSet.trimObjectTileSet( + (ObjectTileSet)set, jar); + tset.setImagePath(imagePath); + // replace the original set with the trimmed + // tileset in the tileset bundle + bundle.addTileSet(tileSetId, tset); + + } catch (Exception e) { + System.err.println("Error adding tileset to bundle " + + "[set=" + set.getName() + + ", ipath=" + imagePath + "]."); + e.printStackTrace(System.err); + // replace the tileset with an error tileset + UniformTileSet ets = new UniformTileSet(); + ets.setName(set.getName()); + ets.setWidth(50); + ets.setHeight(50); + ets.setImagePath(imagePath); + bundle.addTileSet(tileSetId, ets); + // and write an error image to the jar file + ImageIO.write(ImageUtil.createErrorImage(50, 50), + "PNG", jar); + } + + } else { + // read the image file and convert it to our custom + // format in the bundle + File ifile = new File(imageBase, imagePath); + try { + BufferedImage image = ImageIO.read(ifile); + if (FastImageIO.canWrite(image)) { + imagePath = adjustImagePath(imagePath); + jar.putNextEntry(new JarEntry(imagePath)); + set.setImagePath(imagePath); + FastImageIO.write(image, jar); + } else { + jar.putNextEntry(new JarEntry(imagePath)); + FileInputStream imgin = new FileInputStream(ifile); + CopyUtils.copy(imgin, jar); + } + } catch (Exception e) { + String msg = "Failure bundling image " + ifile + + ": " + e; + throw (IOException) new IOException(msg).initCause(e); + } + } + } + + // now write a serialized representation of the tileset bundle + // object to the bundle jar file + JarEntry entry = new JarEntry(BundleUtil.METADATA_PATH); + jar.putNextEntry(entry); + ObjectOutputStream oout = new ObjectOutputStream(jar); + oout.writeObject(bundle); + oout.flush(); + + // finally close up the jar file and call ourself done + jar.close(); + + return true; + + } catch (Exception e) { + // remove the incomplete jar file and rethrow the exception + jar.close(); + if (!target.delete()) { + Log.warning("Failed to close botched bundle '" + target + "'."); + } + String errmsg = "Failed to create bundle " + target + ": " + e; + throw (IOException) new IOException(errmsg).initCause(e); + } + } + + /** Replaces the image suffix with .raw. */ + protected static String adjustImagePath (String imagePath) + { + int didx = imagePath.lastIndexOf("."); + return ((didx == -1) ? imagePath : + imagePath.substring(0, didx)) + ".raw"; + } + + /** Used to parse our configuration. */ + public static class Mapping + { + public String path; + public String ruleset; + + public void init (String path, String ruleset) + { + this.path = path; + this.ruleset = ruleset; + } + + public String toString () + { + return "[path=" + path + ", ruleset=" + ruleset + "]"; + } + } + + /** The digester we use to parse bundle descriptions. */ + protected Digester _digester; +} diff --git a/src/java/com/threerings/media/tile/bundle/tools/TileSetBundlerTask.java b/src/java/com/threerings/media/tile/bundle/tools/TileSetBundlerTask.java new file mode 100644 index 00000000..bcfefe5f --- /dev/null +++ b/src/java/com/threerings/media/tile/bundle/tools/TileSetBundlerTask.java @@ -0,0 +1,143 @@ +// +// $Id: TileSetBundlerTask.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle.tools; + +import java.io.File; +import java.util.ArrayList; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; + +import com.threerings.media.tile.tools.MapFileTileSetIDBroker; + +/** + * Ant task for creating tilset bundles. + */ +public class TileSetBundlerTask extends Task +{ + /** + * Sets the path to the bundler configuration file that we'll use when + * creating the bundle. + */ + public void setConfig (File config) + { + _config = config; + } + + /** + * Sets the path to the tileset id mapping file we'll use when + * creating the bundle. + */ + public void setMapfile (File mapfile) + { + _mapfile = mapfile; + } + + /** + * Adds a nested <fileset> element. + */ + public void addFileset (FileSet set) + { + _filesets.add(set); + } + + /** + * Performs the actual work of the task. + */ + public void execute () throws BuildException + { + // make sure everything was set up properly + ensureSet(_config, "Must specify the path to the bundler config " + + "file via the 'config' attribute."); + ensureSet(_mapfile, "Must specify the path to the tileset id map " + + "file via the 'mapfile' attribute."); + + File cfile = null; + try { + // create a tileset bundler + TileSetBundler bundler = new TileSetBundler(_config); + + // create our tileset id broker + MapFileTileSetIDBroker broker = + new MapFileTileSetIDBroker(_mapfile); + + // deal with the filesets + for (int i = 0; i < _filesets.size(); i++) { + FileSet fs = (FileSet)_filesets.get(i); + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + File fromDir = fs.getDir(getProject()); + String[] srcFiles = ds.getIncludedFiles(); + + for (int f = 0; f < srcFiles.length; f++) { + cfile = new File(fromDir, srcFiles[f]); + + // figure out the bundle file based on the definition + // file + String cpath = cfile.getPath(); + if (!cpath.endsWith(".xml")) { + System.err.println("Can't infer bundle name from " + + "bundle config name " + + "[path=" + cpath + "].\n" + + "Config file should end with .xml."); + continue; + } + String bpath = + cpath.substring(0, cpath.length()-4) + ".jar"; + File bfile = new File(bpath); + + // create the bundle + if (bundler.createBundle(broker, cfile, bfile)) { + System.out.println( + "Created bundle from '" + cpath + "'..."); + } else { + System.out.println( + "Tileset bundle up to date '" + bpath + "'."); + } + } + } + + // commit changes to the tileset id mapping + broker.commit(); + + } catch (Exception e) { + String errmsg = "Failure creating tileset bundle [source=" + cfile + + "]: " + e.getMessage(); + throw new BuildException(errmsg, e); + } + } + + protected void ensureSet (Object value, String errmsg) + throws BuildException + { + if (value == null) { + throw new BuildException(errmsg); + } + } + + protected File _config; + protected File _mapfile; + + /** A list of filesets that contain tileset bundle definitions. */ + protected ArrayList _filesets = new ArrayList(); +} diff --git a/src/java/com/threerings/media/tile/tools/DumpTileSetMap.java b/src/java/com/threerings/media/tile/tools/DumpTileSetMap.java new file mode 100644 index 00000000..4f627cc7 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/DumpTileSetMap.java @@ -0,0 +1,56 @@ +// +// $Id: DumpTileSetMap.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools; + +import java.io.File; +import java.util.Iterator; + +import com.samskivert.io.PersistenceException; + +/** + * Prints out the tileset mappings in a {@link MapFileTileSetIDBroker}. + */ +public class DumpTileSetMap +{ + public static void main (String[] args) + { + if (args.length < 1) { + System.err.println("Usage: DumpTileSetMap tileset.map"); + System.exit(-1); + } + + try { + MapFileTileSetIDBroker broker = + new MapFileTileSetIDBroker(new File(args[0])); + Iterator iter = broker.enumerateMappings(); + while (iter.hasNext()) { + String tsname = iter.next().toString(); + System.out.println(tsname + " => " + + broker.getTileSetID(tsname)); + } + + } catch (PersistenceException pe) { + System.err.println("Unable to dump mapping: " + pe); + System.exit(-1); + } + } +} diff --git a/src/java/com/threerings/media/tile/tools/MapFileTileSetIDBroker.java b/src/java/com/threerings/media/tile/tools/MapFileTileSetIDBroker.java new file mode 100644 index 00000000..649ef80d --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/MapFileTileSetIDBroker.java @@ -0,0 +1,224 @@ +// +// $Id: MapFileTileSetIDBroker.java 4145 2006-05-24 01:24:24Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import java.util.HashMap; +import java.util.Iterator; + +import com.samskivert.io.PersistenceException; +import com.samskivert.util.QuickSort; + +import com.threerings.media.tile.TileSetIDBroker; + +/** + * Stores a set of tileset name to id mappings in a map file. + */ +public class MapFileTileSetIDBroker implements TileSetIDBroker +{ + /** + * Creates a broker that will use the specified file as its persistent + * store. The persistent store will be created if it does not yet + * exist. + */ + public MapFileTileSetIDBroker (File mapfile) + throws PersistenceException + { + // keep this for later + _mapfile = mapfile; + + // load up our map data + try { + BufferedReader bin = new BufferedReader(new FileReader(mapfile)); + // read in our metadata + _nextTileSetID = readInt(bin); + _storedTileSetID = _nextTileSetID; + // read in our mappings + _map = new HashMap(); + readMapFile(bin, _map); + + bin.close(); + + } catch (FileNotFoundException fnfe) { + // create a blank map if our map file doesn't exist + _map = new HashMap(); + + } catch (Exception e) { + // other errors are more fatal + String errmsg = "Failure reading map file."; + throw new PersistenceException(errmsg, e); + } + } + + protected int readInt (BufferedReader bin) + throws IOException + { + String line = bin.readLine(); + try { + return Integer.parseInt(line); + } catch (NumberFormatException nfe) { + throw new IOException("Expected number, got '" + line + "'"); + } + } + + // documentation inherited + public int getTileSetID (String tileSetName) + throws PersistenceException + { + Integer tsid = (Integer)_map.get(tileSetName); + if (tsid == null) { + tsid = Integer.valueOf(++_nextTileSetID); + _map.put(tileSetName, tsid); + } + return tsid.intValue(); + } + + // documentation inherited from interface + public boolean tileSetMapped (String tileSetName) + throws PersistenceException + { + return _map.containsKey(tileSetName); + } + + // documentation inherited + public void commit () + throws PersistenceException + { + // only write ourselves out if we've changed + if (_storedTileSetID == _nextTileSetID) { + return; + } + + try { + BufferedWriter bout = new BufferedWriter(new FileWriter(_mapfile)); + // write out our metadata + String tline = "" + _nextTileSetID; + bout.write(tline, 0, tline.length()); + bout.newLine(); + // write out our mappings + writeMapFile(bout, _map); + bout.close(); + + } catch (IOException ioe) { + String errmsg = "Failure writing map file."; + throw new PersistenceException(errmsg, ioe); + } + } + + /** + * Reads in a mapping from strings to integers, which should have been + * written via {@link #writeMapFile}. + */ + public static void readMapFile (BufferedReader bin, HashMap map) + throws IOException + { + String line; + while ((line = bin.readLine()) != null) { + int eidx = line.indexOf(SEP_STR); + if (eidx == -1) { + throw new IOException("Malformed line, no '" + SEP_STR + + "': '" + line + "'"); + } + try { + String code = line.substring(eidx+SEP_STR.length()); + map.put(line.substring(0, eidx), Integer.valueOf(code)); + } catch (NumberFormatException nfe) { + String errmsg = "Malformed line, invalid code: '" + line + "'"; + throw new IOException(errmsg); + } + } + } + + /** + * Writes out a mapping from strings to integers in a manner that can + * be read back in via {@link #readMapFile}. + */ + public static void writeMapFile (BufferedWriter bout, HashMap map) + throws IOException + { + String[] lines = new String[map.size()]; + Iterator iter = map.keySet().iterator(); + for (int ii = 0; iter.hasNext(); ii++) { + String key = (String)iter.next(); + Integer value = (Integer)map.get(key); + lines[ii] = key + SEP_STR + value; + } + QuickSort.sort(lines); + for (int ii = 0; ii < lines.length; ii++) { + bout.write(lines[ii], 0, lines[ii].length()); + bout.newLine(); + } + bout.flush(); + } + + /** + * Copies the ID from the old tileset to the new tileset which is + * useful when a tileset is renamed. This is called by the {@link + * RenameTileSet} utility. + */ + protected boolean renameTileSet (String oldName, String newName) + { + Integer tsid = (Integer)_map.get(oldName); + if (tsid != null) { + _map.put(newName, tsid); + // fudge our stored tileset ID so that we flush ourselves when + // the rename tool requests that we commit the changes + _storedTileSetID--; + return true; + + } else { + return false; + } + } + + /** + * Used by {@link DumpTileSetMap} to enumerate our tileset ID + * mappings. + */ + protected Iterator enumerateMappings () + { + return _map.keySet().iterator(); + } + + /** Our persistent map file. */ + protected File _mapfile; + + /** The next tileset id that we'll assign. */ + protected int _nextTileSetID; + + /** The last tileset id assigned when we were unserialized. */ + protected int _storedTileSetID; + + /** Our mapping from tileset names to ids. */ + protected HashMap _map; + + /** The character we use to separate tileset name from code in the map + * file. */ + protected static final String SEP_STR = " := "; +} diff --git a/src/java/com/threerings/media/tile/tools/RenameTileSet.java b/src/java/com/threerings/media/tile/tools/RenameTileSet.java new file mode 100644 index 00000000..ab846e66 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/RenameTileSet.java @@ -0,0 +1,74 @@ +// +// $Id: RenameTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools; + +import java.io.File; + +import com.samskivert.io.PersistenceException; + +/** + * Used to map a tileset name to the same ID as a pre-existing tileset. + * This only works for tileset mappings stored using a {@link + * MapFileTileSetIDBroker}. If a tileset is renamed, this utility must be + * used to map the new name to the old ID, otherwise scenes created with + * the renamed tileset will cease to work as the tileset will live under a + * new ID. + */ +public class RenameTileSet +{ + /** + * Loads up the tileset map file with the specified path and copies + * the tileset ID from the old tileset name to the new tileset name. + * This is necessary when a tileset is renamed so that the new name + * does not cause the tileset to be assigned a new tileset ID. Bear in + * mind that the old name should never again be used as it will + * conflict with a tileset provided under the new name. + */ + public static void renameTileSet ( + String mapPath, String oldName, String newName) + throws PersistenceException + { + MapFileTileSetIDBroker broker = + new MapFileTileSetIDBroker(new File(mapPath)); + if (!broker.renameTileSet(oldName, newName)) { + throw new PersistenceException( + "No such old tileset '" + oldName + "'."); + } + broker.commit(); + } + + public static void main (String[] args) + { + if (args.length < 3) { + System.err.println("Usage: RenameTileSet tileset.map " + + "old_name new_name"); + System.exit(-1); + } + + try { + renameTileSet(args[0], args[1], args[2]); + } catch (PersistenceException pe) { + System.err.println("Unable to rename tileset: " + pe); + System.exit(-1); + } + } +} diff --git a/src/java/com/threerings/media/tile/tools/xml/ObjectTileSetRuleSet.java b/src/java/com/threerings/media/tile/tools/xml/ObjectTileSetRuleSet.java new file mode 100644 index 00000000..c2dacd05 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/xml/ObjectTileSetRuleSet.java @@ -0,0 +1,188 @@ +// +// $Id: ObjectTileSetRuleSet.java 3607 2005-06-20 21:18:55Z andrzej $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.CallMethodSpecialRule; + +import com.threerings.media.tile.ObjectTileSet; + +import com.threerings.util.DirectionUtil; + +/** + * Parses {@link ObjectTileSet} instances from a tileset description. An + * object tileset description looks like so: + * + *
+ * <tileset name="Sample Object Tileset">
+ *   <imagePath>path/to/image.png</imagePath>
+ *   <!-- the widths (per row) of each tile in pixels -->
+ *   <widths>265</widths>
+ *   <!-- the heights (per row) of each tile in pixels -->
+ *   <heights>224</heights>
+ *   <!-- the number of tiles in each row -->
+ *   <tileCounts>4</tileCounts>
+ *   <!-- the offset in pixels to the upper left tile -->
+ *   <offsetPos>0, 0</offsetPos>
+ *   <!-- the gap between tiles in pixels -->
+ *   <gapSize>0, 0</gapSize>
+ *   <!-- the widths (in unit tile count) of the objects -->
+ *   <objectWidths>4, 3, 4, 3</objectWidths>
+ *   <!-- the heights (in unit tile count) of the objects -->
+ *   <objectHeights>3, 4, 3, 4</objectHeights>
+ *   <!-- the default render priorities for these object tiles -->
+ *   <priorities>0, 0, -1, 0</priorities>
+ *   <!-- the constraints for these object tiles -->
+ *   <constraints>ATTACH_N, ATTACH_E, ATTACH_S, ATTACH_W</constraints>
+ * </tileset>
+ * 
+ */ +public class ObjectTileSetRuleSet extends SwissArmyTileSetRuleSet +{ + // documentation inherited + public void addRuleInstances (Digester digester) + { + super.addRuleInstances(digester); + + digester.addRule( + _prefix + TILESET_PATH + "/objectWidths", + new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] widths = StringUtil.parseIntArray(bodyText); + ((ObjectTileSet)target).setObjectWidths(widths); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/objectHeights", + new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] heights = StringUtil.parseIntArray(bodyText); + ((ObjectTileSet)target).setObjectHeights(heights); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/xOrigins", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] xorigins = StringUtil.parseIntArray(bodyText); + ((ObjectTileSet)target).setXOrigins(xorigins); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/yOrigins", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] yorigins = StringUtil.parseIntArray(bodyText); + ((ObjectTileSet)target).setYOrigins(yorigins); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/priorities", + new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + byte[] prios = StringUtil.parseByteArray(bodyText); + ((ObjectTileSet)target).setPriorities(prios); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/zations", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + String[] zations = StringUtil.parseStringArray(bodyText); + ((ObjectTileSet)target).setColorizations(zations); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/xspots", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + short[] xspots = StringUtil.parseShortArray(bodyText); + ((ObjectTileSet)target).setXSpots(xspots); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/yspots", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + short[] yspots = StringUtil.parseShortArray(bodyText); + ((ObjectTileSet)target).setYSpots(yspots); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/sorients", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + ObjectTileSet set = (ObjectTileSet)target; + String[] ostrs = StringUtil.parseStringArray(bodyText); + byte[] sorients = new byte[ostrs.length]; + for (int ii = 0; ii < sorients.length; ii++) { + sorients[ii] = (byte) + DirectionUtil.fromShortString(ostrs[ii]); + if ((sorients[ii] == DirectionUtil.NONE) && + // don't complain if they didn't even try to + // specify a valid direction + (! ostrs[ii].equals("-1"))) { + System.err.println("Invalid spot orientation " + + "[set=" + set.getName() + + ", idx=" + ii + + ", orient=" + ostrs[ii] + "]."); + } + } + set.setSpotOrients(sorients); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/constraints", + new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + String[] constrs = StringUtil.parseStringArray( + bodyText); + String[][] constraints = new String[constrs.length][]; + for (int ii = 0; ii < constrs.length; ii++) { + constraints[ii] = constrs[ii].split("\\s*\\|\\s*"); + } + ((ObjectTileSet)target).setConstraints(constraints); + } + }); + } + + // documentation inherited + protected Class getTileSetClass () + { + return ObjectTileSet.class; + } +} diff --git a/src/java/com/threerings/media/tile/tools/xml/SwissArmyTileSetRuleSet.java b/src/java/com/threerings/media/tile/tools/xml/SwissArmyTileSetRuleSet.java new file mode 100644 index 00000000..83835ce6 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/xml/SwissArmyTileSetRuleSet.java @@ -0,0 +1,156 @@ +// +// $Id: SwissArmyTileSetRuleSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import java.awt.Dimension; +import java.awt.Point; + +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.CallMethodSpecialRule; + +import com.threerings.media.Log; +import com.threerings.media.tile.SwissArmyTileSet; + +/** + * Parses {@link SwissArmyTileSet} instances from a tileset description. A + * swiss army tileset description looks like so: + * + *
+ * <tileset name="Sample Swiss Army Tileset">
+ *   <imagePath>path/to/image.png</imagePath>
+ *   <!-- the widths (per row) of each tile in pixels -->
+ *   <widths>64, 64, 64, 64</widths>
+ *   <!-- the heights (per row) of each tile in pixels -->
+ *   <heights>48, 48, 48, 64</heights>
+ *   <!-- the number of tiles in each row -->
+ *   <tileCounts>16, 5, 3, 10</tileCounts>
+ *   <!-- the offset in pixels to the upper left tile -->
+ *   <offsetPos>8, 8</offsetPos>
+ *   <!-- the gap between tiles in pixels -->
+ *   <gapSize>12, 12</gapSize>
+ * </tileset>
+ * 
+ */ +public class SwissArmyTileSetRuleSet extends TileSetRuleSet +{ + // documentation inherited + public void addRuleInstances (Digester digester) + { + super.addRuleInstances(digester); + + digester.addRule( + _prefix + TILESET_PATH + "/widths", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] widths = StringUtil.parseIntArray(bodyText); + ((SwissArmyTileSet)target).setWidths(widths); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/heights", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] heights = StringUtil.parseIntArray(bodyText); + ((SwissArmyTileSet)target).setHeights(heights); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/tileCounts", + new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] tileCounts = StringUtil.parseIntArray(bodyText); + ((SwissArmyTileSet)target).setTileCounts(tileCounts); + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/offsetPos", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] values = StringUtil.parseIntArray(bodyText); + SwissArmyTileSet starget = (SwissArmyTileSet)target; + if (values.length == 2) { + starget.setOffsetPos(new Point(values[0], values[1])); + } else { + Log.warning("Invalid 'offsetPos' definition '" + + bodyText + "'."); + } + } + }); + + digester.addRule( + _prefix + TILESET_PATH + "/gapSize", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] values = StringUtil.parseIntArray(bodyText); + SwissArmyTileSet starget = (SwissArmyTileSet)target; + if (values.length == 2) { + starget.setGapSize(new Dimension(values[0], values[1])); + } else { + Log.warning("Invalid 'gapSize' definition '" + + bodyText + "'."); + } + } + }); + } + + // documentation inherited + public boolean isValid (Object target) + { + SwissArmyTileSet set = (SwissArmyTileSet)target; + boolean valid = super.isValid(target); + + // check for a element + if (set.getWidths() == null) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + // check for a element + if (set.getHeights() == null) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + // check for a element + if (set.getTileCounts() == null) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + return valid; + } + + // documentation inherited + protected Class getTileSetClass () + { + return SwissArmyTileSet.class; + } +} diff --git a/src/java/com/threerings/media/tile/tools/xml/TileSetRuleSet.java b/src/java/com/threerings/media/tile/tools/xml/TileSetRuleSet.java new file mode 100644 index 00000000..a4756872 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/xml/TileSetRuleSet.java @@ -0,0 +1,128 @@ +// +// $Id: TileSetRuleSet.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.RuleSetBase; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.ValidatedSetNextRule.Validator; +import com.samskivert.xml.ValidatedSetNextRule; + +import com.threerings.media.Log; +import com.threerings.media.tile.TileSet; + +/** + * The tileset rule set is used to parse the base attributes of a tileset + * instance. Derived classes would extend this and add rules for their own + * special tilesets. + */ +public abstract class TileSetRuleSet + extends RuleSetBase implements Validator +{ + /** The component of the digester path that is appended by the tileset + * rule set to match a tileset. This is appended to whatever prefix is + * provided to the tileset rule set to obtain the complete XML path to + * a matched tileset. */ + public static final String TILESET_PATH = "/tileset"; + + /** + * Instructs the tileset rule set to match tilesets with the supplied + * prefix. For example, passing a prefix of + * tilesets.objectsets will match tilesets in the + * following XML file: + * + *
+     * <tilesets>
+     *   <objectsets>
+     *     <tileset>
+     *       // ...
+     *     </tileset>
+     *   </objectsets>
+     * </tilesets>
+     * 
+ * + * This must be called before adding the ruleset to a digester. + */ + public void setPrefix (String prefix) + { + _prefix = prefix; + } + + /** + * Adds the necessary rules to the digester to parse our tilesets. + * Derived classes should override this method, being sure to call the + * superclass method and then adding their own rule instances (which + * should register themselves relative to the _prefix + * member). + */ + public void addRuleInstances (Digester digester) + { + // this creates the appropriate instance when we encounter a + // tag + digester.addObjectCreate(_prefix + TILESET_PATH, + getTileSetClass().getName()); + + // grab the name attribute from the tag + digester.addSetProperties(_prefix + TILESET_PATH); + + // grab the image path from an element + digester.addCallMethod( + _prefix + TILESET_PATH + "/imagePath", "setImagePath", 0); + } + + /** + * The ruleset can be provided to a {@link ValidatedSetNextRule} to + * ensure that the tileset was fully parsed before doing something + * with it. + */ + public boolean isValid (Object target) + { + TileSet set = (TileSet)target; + boolean valid = true; + + // check for the 'name' attribute + if (StringUtil.isBlank(set.getName())) { + Log.warning("Tile set definition missing 'name' attribute " + + "[set=" + set + "]."); + valid = false; + } + + // check for an element + if (StringUtil.isBlank(set.getImagePath())) { + Log.warning("Tile set definition missing element " + + "[set=" + set + "]."); + valid = false; + } + + return valid; + } + + /** + * A tileset rule set will create tilesets of a particular class, + * which must be provided by the derived class via this method. + */ + protected abstract Class getTileSetClass (); + + /** The prefix at which me match our tilesets. */ + protected String _prefix; +} diff --git a/src/java/com/threerings/media/tile/tools/xml/UniformTileSetRuleSet.java b/src/java/com/threerings/media/tile/tools/xml/UniformTileSetRuleSet.java new file mode 100644 index 00000000..3bd6725f --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/xml/UniformTileSetRuleSet.java @@ -0,0 +1,86 @@ +// +// $Id: UniformTileSetRuleSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import org.apache.commons.digester.Digester; + +import com.threerings.media.Log; +import com.threerings.media.tile.UniformTileSet; + +/** + * Parses {@link UniformTileSet} instances from a tileset description. A + * uniform tileset description looks like so: + * + *
+ * <tileset name="Sample Uniform Tileset">
+ *   <imagePath>path/to/image.png</imagePath>
+ *   <!-- the width of each tile in pixels -->
+ *   <width>64</width>
+ *   <!-- the height of each tile in pixels -->
+ *   <height>48</height>
+ * </tileset>
+ * 
+ */ +public class UniformTileSetRuleSet extends TileSetRuleSet +{ + // documentation inherited + public void addRuleInstances (Digester digester) + { + super.addRuleInstances(digester); + + digester.addCallMethod( + _prefix + TILESET_PATH + "/width", "setWidth", 0, + new Class[] { java.lang.Integer.TYPE }); + digester.addCallMethod( + _prefix + TILESET_PATH + "/height", "setHeight", 0, + new Class[] { java.lang.Integer.TYPE }); + } + + // documentation inherited + public boolean isValid (Object target) + { + UniformTileSet set = (UniformTileSet)target; + boolean valid = super.isValid(target); + + // check for a element + if (set.getWidth() == 0) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + // check for a element + if (set.getHeight() == 0) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + return valid; + } + + // documentation inherited + protected Class getTileSetClass () + { + return UniformTileSet.class; + } +} diff --git a/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParser.java b/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParser.java new file mode 100644 index 00000000..a7820820 --- /dev/null +++ b/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParser.java @@ -0,0 +1,172 @@ +// +// $Id: XMLTileSetParser.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +import org.apache.commons.digester.Digester; +import org.xml.sax.SAXException; + +import com.samskivert.util.ConfigUtil; +import com.samskivert.xml.ValidatedSetNextRule; + +import com.threerings.media.Log; +import com.threerings.media.tile.TileSet; + +/** + * Parse an XML tileset description file and construct tileset objects for + * each valid description. Does not currently perform validation on the + * input XML stream, though the parsing code assumes the XML document is + * well-formed. + */ +public class XMLTileSetParser +{ + /** + * Constructs an xml tile set parser. + */ + public XMLTileSetParser () + { + // create our digester + _digester = new Digester(); + } + + /** + * Adds a ruleset to be used when parsing tiles. This should be an + * instance of a class derived from {@link TileSetRuleSet}. The prefix + * will be used to configure the ruleset so that it matches elements + * at a particular point in the XML hierarchy. For example: + * + *
+     * _parser.addRuleSet("tilesets", new UniformTileSetRuleSet());
+     * 
+ */ + public void addRuleSet (String prefix, TileSetRuleSet ruleset) + { + // configure the ruleset with the appropriate prefix + ruleset.setPrefix(prefix); + + // and have it set itself up with the digester + _digester.addRuleSet(ruleset); + + // add a set next rule which will put tilesets with this prefix + // into the array list that'll be on the top of the stack + _digester.addRule(prefix + TileSetRuleSet.TILESET_PATH, + new ValidatedSetNextRule("add", Object.class, + ruleset)); + } + + /** + * Loads all of the tilesets specified in the supplied XML tileset + * description file and places them into the supplied hashmap indexed + * by tileset name. This method is not reentrant, so don't go calling + * it from multiple threads. + * + * @param path a path, relative to the classpath, at which the tileset + * definition file can be found. + * @param tilesets the hashmap into which the tilesets will be placed, + * indexed by tileset name. + */ + public void loadTileSets (String path, HashMap tilesets) + throws IOException + { + // get an input stream for this XML file + InputStream is = ConfigUtil.getStream(path); + if (is == null) { + String errmsg = "Can't load tileset description file from " + + "classpath [path=" + path + "]."; + throw new FileNotFoundException(errmsg); + } + + // load up the tilesets + loadTileSets(is, tilesets); + } + + /** + * Loads all of the tilesets specified in the supplied XML tileset + * description file and places them into the supplied hashmap indexed + * by tileset name. This method is not reentrant, so don't go calling + * it from multiple threads. + * + * @param file the file in which the tileset definition file can be + * found. + * @param tilesets the hashmap into which the tilesets will be placed, + * indexed by tileset name. + */ + public void loadTileSets (File file, HashMap tilesets) + throws IOException + { + // load up the tilesets + loadTileSets(new FileInputStream(file), tilesets); + } + + /** + * Loads all of the tilesets specified in the supplied XML tileset + * description file and places them into the supplied hashmap indexed + * by tileset name. This method is not reentrant, so don't go calling + * it from multiple threads. + * + * @param source an input stream from which the tileset definition + * file can be read. + * @param tilesets the hashmap into which the tilesets will be placed, + * indexed by tileset name. + */ + public void loadTileSets (InputStream source, HashMap tilesets) + throws IOException + { + // stick an array list on the top of the stack for collecting + // parsed tilesets + ArrayList setlist = new ArrayList(); + _digester.push(setlist); + + // now fire up the digester to parse the stream + try { + _digester.parse(source); + } catch (SAXException saxe) { + Log.warning("Exception parsing tile set descriptions " + + "[error=" + saxe + "]."); + Log.logStackTrace(saxe); + } + + // stick the tilesets from the list into the hashtable + for (int i = 0; i < setlist.size(); i++) { + TileSet set = (TileSet)setlist.get(i); + if (set.getName() == null) { + Log.warning("Tileset did not receive name during " + + "parsing process [set=" + set + "]."); + } else { + tilesets.put(set.getName(), set); + } + } + + // and clear out the list for next time + setlist.clear(); + } + + /** Our XML digester. */ + protected Digester _digester; +} diff --git a/src/java/com/threerings/media/tile/util/TileSetTrimmer.java b/src/java/com/threerings/media/tile/util/TileSetTrimmer.java new file mode 100644 index 00000000..51a3c819 --- /dev/null +++ b/src/java/com/threerings/media/tile/util/TileSetTrimmer.java @@ -0,0 +1,146 @@ +// +// $Id: TileSetTrimmer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.util; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.awt.image.RasterFormatException; +import java.awt.image.WritableRaster; +import java.io.IOException; +import java.io.OutputStream; + +import com.threerings.media.image.FastImageIO; +import com.threerings.media.image.ImageUtil; +import com.threerings.media.tile.TileSet; + +/** + * Contains routines for trimming the images from an existing tileset + * which means that each tile is converted to an image that contains the + * smallest rectangular region of the original image that contains all + * non-transparent pixels. These trimmed images are then written out to a + * single image, packed together left to right. + */ +public class TileSetTrimmer +{ + /** + * Used to communicate the metrics of the trimmed tiles back to the + * caller so that they can do what they like with them. + */ + public static interface TrimMetricsReceiver + { + /** + * Called for each trimmed tile. + * + * @param tileIndex the index of the tile in the original tileset. + * @param imageX the x offset into the newly created tileset image + * of the trimmed image data. + * @param imageY the y offset into the newly created tileset image + * of the trimmed image data. + * @param trimX the x offset into the untrimmed tile image where + * the trimmed data begins. + * @param trimY the y offset into the untrimmed tile image where + * the trimmed data begins. + * @param trimWidth the width of the trimmed tile image. + * @param trimHeight the height of the trimmed tile image. + */ + public void trimmedTile (int tileIndex, int imageX, int imageY, + int trimX, int trimY, + int trimWidth, int trimHeight); + } + + /** + * Generates a trimmed tileset image from the supplied source + * tileset. The source tileset must be configured with an image + * provider so that the tile images can be obtained. The tile images + * will be trimmed and a new tileset image generated and written to + * the destImage output stream argument. + * + * @param source the source tileset. + * @param destImage an output stream to which the new trimmed image + * will be written. + * @param tmr a callback object that will be used to inform the caller + * of the trimmed tile metrics. + */ + public static void trimTileSet ( + TileSet source, OutputStream destImage, TrimMetricsReceiver tmr) + throws IOException + { + int tcount = source.getTileCount(); + BufferedImage[] timgs = new BufferedImage[tcount]; + + // these will contain the bounds of the trimmed image in the + // coordinate system defined by the untrimmed image + Rectangle[] tbounds = new Rectangle[tcount]; + + // compute some tile metrics + int nextx = 0, maxy = 0; + for (int ii = 0; ii < tcount; ii++) { + // extract the image from the original tileset + try { + timgs[ii] = source.getRawTileImage(ii); + } catch (RasterFormatException rfe) { + throw new IOException("Failed to get tile image " + + "[tidx=" + ii + ", tset=" + source + + ", rfe=" + rfe + "]."); + } + + // figure out how tightly we can trim it + tbounds[ii] = new Rectangle(); + ImageUtil.computeTrimmedBounds(timgs[ii], tbounds[ii]); + + // let our caller know what we did + tmr.trimmedTile(ii, nextx, 0, tbounds[ii].x, tbounds[ii].y, + tbounds[ii].width, tbounds[ii].height); + + // adjust the new tileset image dimensions + maxy = Math.max(maxy, tbounds[ii].height); + nextx += tbounds[ii].width; + } + + // create the new tileset image + BufferedImage image = null; + try { + image = ImageUtil.createCompatibleImage( + (BufferedImage)source.getRawTileSetImage(), nextx, maxy); + + } catch (RasterFormatException rfe) { + throw new IOException("Failed to create trimmed tileset image " + + "[wid=" + nextx + ", hei=" + maxy + + ", tset=" + source + ", rfe=" + rfe + "]."); + } + + // copy the tile data + WritableRaster drast = image.getRaster(); + int xoff = 0; + for (int ii = 0; ii < tcount; ii++) { + Rectangle tb = tbounds[ii]; + Raster srast = timgs[ii].getRaster().createChild( + tb.x, tb.y, tb.width, tb.height, 0, 0, null); + drast.setRect(xoff, 0, srast); + xoff += tb.width; + } + + // write out trimmed image + FastImageIO.write(image, destImage); + } +} diff --git a/src/java/com/threerings/media/timer/MediaTimer.java b/src/java/com/threerings/media/timer/MediaTimer.java new file mode 100644 index 00000000..25925993 --- /dev/null +++ b/src/java/com/threerings/media/timer/MediaTimer.java @@ -0,0 +1,52 @@ +// +// $Id: MediaTimer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.timer; + +/** + * Provides a pluggable mechanism for delivering high resolution timing + * information. The timers are not intended to be used by different + * threads and thus must be protected by synchronization in such + * circumstances. + */ +public interface MediaTimer +{ + /** + * Resets the timer's monotonically increasing value. + */ + public void reset (); + + /** + * Returns the number of milliseconds that have elapsed since the + * timer was created or last {@link #reset}. Note: the + * accuracy of this method is highly dependent on the timer + * implementation used. + */ + public long getElapsedMillis (); + + /** + * Returns the number of microseconds that have elapsed since the + * timer was created or last {@link #reset}. Note: the + * accuracy of this method is highly dependent on the timer + * implementation used. + */ + public long getElapsedMicros (); +} diff --git a/src/java/com/threerings/media/timer/PerfTimer.java b/src/java/com/threerings/media/timer/PerfTimer.java new file mode 100644 index 00000000..1d5f21c1 --- /dev/null +++ b/src/java/com/threerings/media/timer/PerfTimer.java @@ -0,0 +1,69 @@ +// +// $Id: PerfTimer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.timer; + +import sun.misc.Perf; + +import com.threerings.media.Log; + +/** + * A timer that uses the performance clock exposed by Sun in JDK 1.4.2. + */ +public class PerfTimer implements MediaTimer +{ + public PerfTimer () + { + _timer = Perf.getPerf(); + _mfrequency = _timer.highResFrequency() / 1000; + _ufrequency = _timer.highResFrequency() / 1000000; + _startStamp = _timer.highResCounter(); + Log.info("Using high performance timer [mfreq=" + _mfrequency + + ", ufreq=" + _ufrequency + ", start=" + _startStamp + "]."); + } + + // documentation inherited from interface + public void reset () + { + _startStamp = _timer.highResCounter(); + } + + // documentation inherited from interface + public long getElapsedMillis () + { + return (_timer.highResCounter() - _startStamp) / _mfrequency; + } + + // documentation inherited from interface + public long getElapsedMicros () + { + return (_timer.highResCounter() - _startStamp) / _ufrequency; + } + + /** A performance timer object. */ + protected Perf _timer; + + /** The time at which this timer was last reset. */ + protected long _startStamp; + + /** The timer frequencies. */ + protected long _mfrequency, _ufrequency; +} diff --git a/src/java/com/threerings/media/timer/SystemMediaTimer.java b/src/java/com/threerings/media/timer/SystemMediaTimer.java new file mode 100644 index 00000000..3ebed746 --- /dev/null +++ b/src/java/com/threerings/media/timer/SystemMediaTimer.java @@ -0,0 +1,60 @@ +// +// $Id: SystemMediaTimer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.timer; + +/** + * Implements the {@link MediaTimer} interface using {@link + * System#currentTimeMillis} to obtain timing information. + * + *

Note: {@link System#currentTimeMillis} is notoriously + * inaccurate on different platforms. See + * bug report 4486109 for more information. + * + *

Also note: clock drift on Windows XP is especially + * pronounced and is exacerbated by the fact that WinXP periodically + * resyncs the system clock with the hardware clock, causing discontinuous + * jumps in the progression of time (usually backwards in time). + */ +public class SystemMediaTimer implements MediaTimer +{ + // documentation inherited from interface + public void reset () + { + _resetStamp = System.currentTimeMillis(); + } + + // documentation inherited from interface + public long getElapsedMillis () + { + return System.currentTimeMillis() - _resetStamp; + } + + // documentation inherited from interface + public long getElapsedMicros () + { + return getElapsedMillis() * 10; + } + + /** The time at which this timer was last reset. */ + protected long _resetStamp = System.currentTimeMillis(); +} diff --git a/src/java/com/threerings/media/tools/RecolorImage.java b/src/java/com/threerings/media/tools/RecolorImage.java new file mode 100644 index 00000000..ce0744e9 --- /dev/null +++ b/src/java/com/threerings/media/tools/RecolorImage.java @@ -0,0 +1,476 @@ +// +// $Id: RecolorImage.java 3887 2006-02-24 01:24:34Z mthomas $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tools; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collections; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSlider; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import com.samskivert.swing.HGroupLayout; +import com.samskivert.swing.IntField; +import com.samskivert.swing.VGroupLayout; +import com.samskivert.swing.event.DocumentAdapter; +import com.samskivert.swing.util.SwingUtil; +import com.samskivert.util.Interator; + +import com.threerings.media.image.ColorPository; +import com.threerings.media.image.Colorization; +import com.threerings.media.image.ImageUtil; +import com.threerings.media.image.tools.xml.ColorPositoryParser; + +/** + * Tests the image recoloring code. + */ +public class RecolorImage extends JPanel + implements ActionListener +{ + public RecolorImage () + { + setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + VGroupLayout vlay = new VGroupLayout(VGroupLayout.STRETCH); + vlay.setOffAxisPolicy(VGroupLayout.STRETCH); + setLayout(vlay); + + JPanel images = new JPanel(new HGroupLayout()); + images.add(_oldImage = new JLabel()); + images.add(_newImage = new JLabel()); + add(new JScrollPane(images)); + + // Image file + JPanel file = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); + file.add(new JLabel("Image file:"), HGroupLayout.FIXED); + file.add(_imagePath = new JTextField()); + _imagePath.setEditable(false); + JButton browse = new JButton("Browse..."); + browse.setActionCommand("browse"); + browse.addActionListener(this); + file.add(browse, HGroupLayout.FIXED); + JButton reload = new JButton("Reload"); + reload.setActionCommand("reload"); + reload.addActionListener(this); + file.add(reload, HGroupLayout.FIXED); + add(file, VGroupLayout.FIXED); + + // Colorization file + JPanel colFile = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); + colFile.add(new JLabel("Colorize file:"), HGroupLayout.FIXED); + colFile.add(_colFilePath = new JTextField()); + _colFilePath.setEditable(false); + browse = new JButton("Browse..."); + browse.setActionCommand("browse_colorize"); + browse.addActionListener(this); + colFile.add(browse, HGroupLayout.FIXED); + add(colFile, VGroupLayout.FIXED); + + JPanel colMode = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); + colMode.add(_mode = new JToggleButton("All Colorizations")); + colMode.add(_classList = new JComboBox()); + ActionListener al = new ActionListener () { + public void actionPerformed (ActionEvent ae) { + convert(); + } + }; + _mode.addActionListener(al); + _classList.addActionListener(al); + + add(colMode, VGroupLayout.FIXED); + + JPanel controls = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); + controls.add(new JLabel("Source color:"), HGroupLayout.FIXED); + controls.add(_source = new JTextField("FF0000")); + _colorLabel = new JPanel(); + _colorLabel.setSize(48, 48); + _colorLabel.setOpaque(true); + controls.add(_colorLabel, HGroupLayout.FIXED); + controls.add(new JLabel("Target color:"), HGroupLayout.FIXED); + controls.add(_target = new JTextField()); + JButton update = new JButton("Update"); + update.setActionCommand("update"); + update.addActionListener(this); + controls.add(update, HGroupLayout.FIXED); + add(controls, VGroupLayout.FIXED); + + HGroupLayout hlay = new HGroupLayout(HGroupLayout.STRETCH); + JPanel dists = new JPanel(hlay); + dists.add(new JLabel("HSV distances:"), HGroupLayout.FIXED); + dists.add(_hueD = new SliderAndLabel(0.0f, 1.0f, 0.05f)); + dists.add(_saturationD = new SliderAndLabel(0.0f, 1.0f, 0.8f)); + dists.add(_valueD = new SliderAndLabel(0.0f, 1.0f, 0.6f)); + add(dists, VGroupLayout.FIXED); + + hlay = new HGroupLayout(HGroupLayout.STRETCH); + JPanel offsets = new JPanel(hlay); + offsets.add(new JLabel("HSV offsets:"), HGroupLayout.FIXED); + offsets.add(_hueO = new SliderAndLabel(-1.0f, 1.0f, 0.1f)); + offsets.add(_saturationO = new SliderAndLabel(-1.0f, 1.0f, 0.0f)); + offsets.add(_valueO = new SliderAndLabel(-1.0f, 1.0f, 0.0f)); + add(offsets, VGroupLayout.FIXED); + + add(_status = new JTextField(), VGroupLayout.FIXED); + _status.setEditable(false); + + hlay = new HGroupLayout(); + hlay.setJustification(HGroupLayout.CENTER); + JPanel buttons = new JPanel(hlay); + JButton convert = new JButton("Convert"); + convert.setActionCommand("convert"); + convert.addActionListener(this); + buttons.add(convert); + add(buttons, VGroupLayout.FIXED); + + // listen for mouse clicks + images.addMouseListener(new MouseAdapter() { + public void mousePressed (MouseEvent event) { + RecolorImage.this.mousePressed(event); + } + }); + + // we'll be using a file chooser + String cwd = System.getProperty("user.dir"); + if (cwd == null) { + _chooser = new JFileChooser(); + _colChooser = new JFileChooser(); + } else { + _chooser = new JFileChooser(cwd); + _colChooser = new JFileChooser(cwd); + } + } + + /** + * Performs colorizations. + */ + protected void convert () + { + if (_image == null) { + return; + } + + // obtain the target color and offset + try { + BufferedImage image; + if (_mode.isSelected()) { + // All recolorings from file. + image = getAllRecolors(); + if (image == null) { + return; + } + } else { + // Normal recoloring + int color = Integer.parseInt(_source.getText(), 16); + + float hueD = _hueD.getValue(); + float satD = _saturationD.getValue(); + float valD = _valueD.getValue(); + float[] dists = new float[] { hueD, satD, valD }; + + float hueO = _hueO.getValue(); + float satO = _saturationO.getValue(); + float valO = _valueO.getValue(); + float[] offsets = new float[] { hueO, satO, valO }; + + image = ImageUtil.recolorImage( + _image, new Color(color), dists, offsets); + } + _newImage.setIcon(new ImageIcon(image)); + _status.setText("Recolored image."); + repaint(); + + } catch (NumberFormatException nfe) { + _status.setText("Invalid value: " + nfe.getMessage()); + } + } + + /** + * Gets an image with all recolorings of the selection colorization class. + */ + public BufferedImage getAllRecolors () + { + if (_colRepo == null) { + return null; + } + + ColorPository.ClassRecord colClass = + _colRepo.getClassRecord((String)_classList.getSelectedItem()); + int classId = colClass.classId; + + ArrayList imgs = new ArrayList(); + Interator iter = colClass.colors.keys(); + BufferedImage img = new BufferedImage(_image.getWidth(), + _image.getHeight()*colClass.colors.size(), + BufferedImage.TYPE_INT_ARGB); + Graphics gfx = img.getGraphics(); + int y = 0; + + while (iter.hasNext()) { + Colorization coloriz = + _colRepo.getColorization(classId, iter.nextInt()); + BufferedImage subImg = ImageUtil.recolorImage( + _image, coloriz.rootColor, coloriz.range, coloriz.offsets); + + gfx.drawImage(subImg, 0, y, null, null); + + y += subImg.getHeight(); + } + + return img; + } + + public void actionPerformed (ActionEvent event) + { + String cmd = event.getActionCommand(); + + if (cmd.equals("convert")) { + convert(); + } else if (cmd.equals("update")) { + // obtain the target color and offset + try { + int source = Integer.parseInt(_source.getText(), 16); + int target = Integer.parseInt(_target.getText(), 16); + float[] shsv = rgbToHSV(source); + float[] thsv = rgbToHSV(target); + + // set the offsets based on the differences + _hueO.setValue(thsv[0] - shsv[0]); + _saturationO.setValue(thsv[1] - shsv[1]); + _valueO.setValue(thsv[2] - shsv[2]); + + } catch (NumberFormatException nfe) { + _status.setText("Invalid value: " + nfe.getMessage()); + } + + } else if (cmd.equals("browse")) { + int result = _chooser.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + setImage(_chooser.getSelectedFile()); + } + } else if (cmd.equals("reload")) { + setImage(_chooser.getSelectedFile()); + } else if (cmd.equals("browse_colorize")) { + int result = _colChooser.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + setColorizeFile(_colChooser.getSelectedFile()); + } + } + } + + public void setImage (File path) + { + try { + _image = ImageIO.read(path); + _imagePath.setText(path.getPath()); + _oldImage.setIcon(new ImageIcon(_image)); + + } catch (IOException ioe) { + _status.setText("Error opening image file: " + ioe); + } + } + + /** + * Loads up the colorization classes from the specified file. + */ + public void setColorizeFile (File path) + { + try { + if (path.getName().endsWith("xml")) { + ColorPositoryParser parser = new ColorPositoryParser(); + _colRepo = + (ColorPository)(parser.parseConfig(path)); + } else { + _colRepo = + ColorPository.loadColorPository(new FileInputStream(path)); + } + + _classList.removeAllItems(); + Iterator iter = _colRepo.enumerateClasses(); + ArrayList names = new ArrayList(); + while (iter.hasNext()) { + String str = ((ColorPository.ClassRecord)iter.next()).name; + names.add(str); + } + + Collections.sort(names); + + iter = names.iterator(); + while (iter.hasNext()) { + _classList.addItem((String)iter.next()); + } + + _classList.setSelectedIndex(0); + _colFilePath.setText(path.getPath()); + } catch (Exception ex) { + _status.setText("Error opening colorization file: " + ex); + } + } + + protected static float[] rgbToHSV (int rgb) + { + float[] hsv = new float[3]; + Color color = new Color(rgb); + Color.RGBtoHSB(color.getRed(), color.getGreen(), + color.getBlue(), hsv); + return hsv; + } + + public void mousePressed (MouseEvent event) + { + // if the click was in the bounds of the source image, grab the + // pixel color and use that to set the "source" color + int x = event.getX(), y = event.getY(); + Rectangle ibounds = _oldImage.getBounds(); + if (ibounds.contains(x, y)) { + int argb = _image.getRGB(x - ibounds.x, y - ibounds.y); + String cstr = Integer.toString(argb & 0xFFFFFF, 16); + _source.setText(cstr.toUpperCase()); + _colorLabel.setBackground(new Color(argb)); + _colorLabel.repaint(); + } + } + + /** + * Class with linked slider and label arranged vertically. + */ + protected class SliderAndLabel extends JPanel + { + public SliderAndLabel (float minf, float maxf, float valuef) + { + int min = (int)(minf*CONVERSION); + int max = (int)(maxf*CONVERSION); + int value = (int)(valuef*CONVERSION); + setLayout(new VGroupLayout(VGroupLayout.STRETCH)); + _intField = new JLabel(String.valueOf(value/CONVERSION)); + _slider = new JSlider(min, max, value); + + _slider.addChangeListener(new ChangeListener() { + public void stateChanged (ChangeEvent ce) { + _intField.setText(String.valueOf( + ((float)_slider.getValue())/CONVERSION)); + + convert(); + } + }); + add(_intField); + add(_slider); + } + + public float getValue () + { + return _slider.getValue()/CONVERSION; + } + + public void setValue (float val) + { + _slider.setValue((int)(val*CONVERSION)); + } + + protected JSlider _slider; + protected JLabel _intField; + + protected final static float CONVERSION = 1000.0f; + } + + public static void main (String[] args) + { + try { + JFrame frame = new JFrame("Image recoloring test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + RecolorImage panel = new RecolorImage(); + + // load up the image from the command line if one was + // specified + if (args.length > 0) { + panel.setImage(new File(args[0])); + } + + frame.getContentPane().add(panel, BorderLayout.CENTER); + frame.setSize(600, 600); + SwingUtil.centerWindow(frame); + frame.setVisible(true); + + } catch (Exception e) { + e.printStackTrace(System.err); + } + } + + protected BufferedImage _image; + protected JFileChooser _chooser; + protected JFileChooser _colChooser; + protected JTextField _imagePath; + protected JTextField _colFilePath; + + protected JLabel _oldImage; + protected JLabel _newImage; + protected JPanel _colorLabel; + + protected JTextField _source; + protected JTextField _target; + + protected SliderAndLabel _hueO; + protected SliderAndLabel _saturationO; + protected SliderAndLabel _valueO; + + protected SliderAndLabel _hueD; + protected SliderAndLabel _saturationD; + protected SliderAndLabel _valueD; + + protected JTextField _status; + + protected JComboBox _classList; + protected JToggleButton _mode; + + protected ColorPository _colRepo; + + protected static final String IMAGE_PATH = + // "bundles/components/pirate/torso/regular/standing.png"; + "bundles/components/pirate/head/regular/standing.png"; +} diff --git a/src/java/com/threerings/media/util/AStarPathUtil.java b/src/java/com/threerings/media/util/AStarPathUtil.java new file mode 100644 index 00000000..4583fda0 --- /dev/null +++ b/src/java/com/threerings/media/util/AStarPathUtil.java @@ -0,0 +1,437 @@ +// +// $Id: AStarPathUtil.java 3413 2005-03-18 01:13:09Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Point; +import java.util.*; + +import com.samskivert.util.HashIntMap; + +import com.threerings.media.util.MathUtil; + +/** + * The AStarPathUtil class provides a facility for + * finding a reasonable path between two points in a scene using the + * A* search algorithm. + * + *

See the path-finding article on + * + * Gamasutra for more detailed information. + */ +public class AStarPathUtil +{ + /** + * Provides traversibility information when computing paths. + */ + public static interface TraversalPred + { + /** + * Requests to know if the specified traverser (which was provided + * in the call to {@link #getPath}) can traverse the specified + * tile coordinate. + */ + public boolean canTraverse (Object traverser, int x, int y); + } + + /** + * Considers all the possible steps the piece in question can take. + */ + public static class Stepper + { + public void init (Info info, Node n) + { + _info = info; + _node = n; + } + + /** + * Should call {@link #considerStep} in turn on all possible steps + * from the specified coordinates. No checking must be done as to + * whether the step is legal, that will be handled later. Just + * enumerate all possible steps. + */ + public void considerSteps (int x, int y) + { + considerStep(x - 1, y - 1, DIAGONAL_COST); + considerStep(x, y - 1, ADJACENT_COST); + considerStep(x + 1, y - 1, DIAGONAL_COST); + considerStep(x - 1, y, ADJACENT_COST); + considerStep(x + 1, y, ADJACENT_COST); + considerStep(x - 1, y + 1, DIAGONAL_COST); + considerStep(x, y + 1, ADJACENT_COST); + considerStep(x + 1, y + 1, DIAGONAL_COST); + } + + protected void considerStep (int x, int y, int cost) + { + AStarPathUtil.considerStep(_info, _node, x, y, cost); + } + + protected Info _info; + protected Node _node; + } + + /** The standard cost to move between nodes. */ + public static final int ADJACENT_COST = 10; + + /** The cost to move diagonally. */ + public static final int DIAGONAL_COST = (int)Math.sqrt( + (ADJACENT_COST * ADJACENT_COST) * 2); + + /** + * Return a list of Point objects representing a path + * from coordinates (ax, by) to (bx, by), + * inclusive, determined by performing an A* search in the given + * scene's base tile layer. Assumes the starting and destination nodes + * are traversable by the specified traverser. + * + * @param tpred lets us know what tiles are traversible. + * @param stepper enumerates the possible steps. + * @param trav the traverser to follow the path. + * @param longest the longest allowable path in tile traversals. + * @param ax the starting x-position in tile coordinates. + * @param ay the starting y-position in tile coordinates. + * @param bx the ending x-position in tile coordinates. + * @param by the ending y-position in tile coordinates. + * @param partial if true, a partial path will be returned that gets + * us as close as we can to the goal in the event that a complete path + * cannot be located. + * + * @return the list of points in the path. + */ + public static List getPath (TraversalPred tpred, Stepper stepper, + Object trav, int longest, int ax, int ay, + int bx, int by, boolean partial) + { + Info info = new Info(tpred, trav, longest, bx, by); + + // set up the starting node + Node s = info.getNode(ax, ay); + s.g = 0; + s.h = getDistanceEstimate(ax, ay, bx, by); + s.f = s.g + s.h; + + // push starting node on the open list + info.open.add(s); + _considered = 1; + + // track the best path + float bestdist = Float.MAX_VALUE; + Node bestpath = null; + + // while there are more nodes on the open list + while (info.open.size() > 0) { + + // pop the best node so far from open + Node n = (Node)info.open.first(); + info.open.remove(n); + + // if node is a goal node + if (n.x == bx && n.y == by) { + // construct and return the acceptable path + return getNodePath(n); + } else if (partial) { + float pathdist = MathUtil.distance(n.x, n.y, bx, by); + if (pathdist < bestdist) { + bestdist = pathdist; + bestpath = n; + } + } + + // consider each successor of the node + stepper.init(info, n); + stepper.considerSteps(n.x, n.y); + + // push the node on the closed list + info.closed.add(n); + } + + // return the best path we could find if we were asked to do so + if (bestpath != null) { + return getNodePath(bestpath); + } + + // no path found + return null; + } + + /** + * Gets a path with the default stepper which assumes the piece can + * move one in any of the eight cardinal directions. + */ + public static List getPath (TraversalPred tpred, Object trav, int longest, + int ax, int ay, int bx, int by, boolean partial) + { + return getPath( + tpred, new Stepper(), trav, longest, ax, ay, bx, by, partial); + } + + /** + * Returns the number of nodes considered in computing the most recent + * path. + */ + public static int getConsidered () + { + return _considered; + } + + /** + * Consider the step (n.x, n.y) to (x, y) + * for possible inclusion in the path. + * + * @param info the info object. + * @param n the originating node for the step. + * @param x the x-coordinate for the destination step. + * @param y the y-coordinate for the destination step. + */ + protected static void considerStep ( + Info info, Node n, int x, int y, int cost) + { + // skip node if it's outside the map bounds or otherwise impassable + if (!info.isStepValid(n.x, n.y, x, y)) { + return; + } + + // calculate the new cost for this node + int newg = n.g + cost; + + // make sure the cost is reasonable + if (newg > info.maxcost) { +// Log.info("Rejected costly step."); + return; + } + + // retrieve the node corresponding to this location + Node np = info.getNode(x, y); + + // skip if it's already in the open or closed list or if its + // actual cost is less than the just-calculated cost + if ((info.open.contains(np) || info.closed.contains(np)) && + np.g <= newg) { + return; + } + + // remove the node from the open list since we're about to + // modify its score which determines its placement in the list + info.open.remove(np); + + // update the node's information + np.parent = n; + np.g = newg; + np.h = getDistanceEstimate(np.x, np.y, info.destx, info.desty); + np.f = np.g + np.h; + + // remove it from the closed list if it's present + info.closed.remove(np); + + // add it to the open list for further consideration + info.open.add(np); + _considered++; + } + + /** + * Return a list of Point objects detailing the path + * from the first node (the given node's ultimate parent) to the + * ending node (the given node itself.) + * + * @param n the ending node in the path. + * + * @return the list detailing the path. + */ + protected static List getNodePath (Node n) + { + Node cur = n; + ArrayList path = new ArrayList(); + + while (cur != null) { + // add to the head of the list since we're traversing from + // the end to the beginning + path.add(0, new Point(cur.x, cur.y)); + + // advance to the next node in the path + cur = cur.parent; + } + + return path; + } + + /** + * Return a heuristic estimate of the cost to get from (ax, + * ay) to (bx, by). + */ + protected static int getDistanceEstimate (int ax, int ay, int bx, int by) + { + // we're doing all of our cost calculations based on geometric + // distance times ten + int xsq = bx - ax; + int ysq = by - ay; + return (int) (ADJACENT_COST * Math.sqrt(xsq * xsq + ysq * ysq)); + } + + /** + * A holding class to contain the wealth of information referenced + * while performing an A* search for a path through a tile array. + */ + protected static class Info + { + /** Knows whether or not tiles are traversable. */ + public TraversalPred tpred; + + /** The tile array dimensions. */ + public int tilewid, tilehei; + + /** The traverser moving along the path. */ + public Object trav; + + /** The set of open nodes being searched. */ + public SortedSet open; + + /** The set of closed nodes being searched. */ + public ArrayList closed; + + /** The destination coordinates in the tile array. */ + public int destx, desty; + + /** The maximum cost of any path that we'll consider. */ + public int maxcost; + + public Info (TraversalPred tpred, Object trav, + int longest, int destx, int desty) + { + // save off references + this.tpred = tpred; + this.trav = trav; + this.destx = destx; + this.desty = desty; + + // compute our maximum path cost + this.maxcost = longest * ADJACENT_COST; + + // construct the open and closed lists + open = new TreeSet(); + closed = new ArrayList(); + } + + /** + * Returns whether moving from the given source to destination + * coordinates is a valid move. + */ + protected boolean isStepValid (int sx, int sy, int dx, int dy) + { + // not traversable if the destination itself fails test + if (!isTraversable(dx, dy)) { + return false; + } + + // if the step is diagonal, make sure the corners don't impede + // our progress + if ((Math.abs(dx - sx) == 1) && (Math.abs(dy - sy) == 1)) { + return isTraversable(dx, sy) && isTraversable(sx, dy); + } + + // non-diagonals are always traversable + return true; + } + + /** + * Returns whether the given coordinate is valid and traversable. + */ + protected boolean isTraversable (int x, int y) + { + return tpred.canTraverse(trav, x, y); + } + + /** + * Get or create the node for the specified point. + */ + public Node getNode (int x, int y) + { + // note: this _could_ break for unusual values of x and y. + // perhaps use a IntTuple as a key? Bleah. + int key = (x << 16) | (y & 0xffff); + Node node = (Node) _nodes.get(key); + if (node == null) { + node = new Node(x, y); + _nodes.put(key, node); + } + return node; + } + + /** The nodes being considered in the path. */ + protected HashIntMap _nodes = new HashIntMap(); + } + + /** + * A class that represents a single traversable node in the tile array + * along with its current A*-specific search information. + */ + protected static class Node implements Comparable + { + /** The node coordinates. */ + public int x, y; + + /** The actual cheapest cost of arriving here from the start. */ + public int g; + + /** The heuristic estimate of the cost to the goal from here. */ + public int h; + + /** The score assigned to this node. */ + public int f; + + /** The node from which we reached this node. */ + public Node parent; + + /** The node's monotonically-increasing unique identifier. */ + public int id; + + public Node (int x, int y) + { + this.x = x; + this.y = y; + id = _nextid++; + } + + public int compareTo (Object o) + { + int bf = ((Node)o).f; + + // since the set contract is fulfilled using the equality results + // returned here, and we'd like to allow multiple nodes with + // equivalent scores in our set, we explicitly define object + // equivalence as the result of object.equals(), else we use the + // unique node id since it will return a consistent ordering for + // the objects. + if (f == bf) { + return (this == o) ? 0 : (id - ((Node)o).id); + } + + return f - bf; + } + + /** The next unique node id. */ + protected static int _nextid = 0; + } + + /** The number of nodes considered in computing our path. */ + protected static int _considered = 0; +} diff --git a/src/java/com/threerings/media/util/ArcPath.java b/src/java/com/threerings/media/util/ArcPath.java new file mode 100644 index 00000000..d8a2562b --- /dev/null +++ b/src/java/com/threerings/media/util/ArcPath.java @@ -0,0 +1,238 @@ +// +// $Id: ArcPath.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; + +import com.samskivert.util.StringUtil; + +import com.threerings.util.DirectionUtil; + +/** + * The line path is used to cause a pathable to go from point A to point B + * along the arc of an ellipse in a certain number of milliseconds. + */ +public class ArcPath extends TimedPath +{ + /** An orientation constant indicating that the normal (eight) + * directions should be used to orient the pathable being made to + * follow this path. */ + public static final int NORMAL = 0; + + /** An orientation constant indicating that the fine (sixteen) + * directions should be used to orient the pathable being made to + * follow this path. */ + public static final int FINE = 1; + + /** An orientation indicating that the pathable should not be oriented + * as it moves along the path. + */ + public static final int NONE = 2; + + /** + * Creates an arc path that will animate a pathable from the specified + * starting position along an ellipse defined by the supplied + * parameters. The pathable will travel the specified number of + * radians along the arc of that ellipse. A positive number of radians + * indicates counter-clockwise travel along the circle, a negative + * number, clockwise rotation. + * + * @param start the starting point for the pathable. + * @param xradius the length of the x radius. + * @param yradius the length of the y radius. + * @param sangle the starting angle. + * @param delta the angle through which the pathable should be moved. + * @param duration the number of milliseconds during which to effect + * the animation. + * @param orient an orientation code indicating how the pathable + * should be oriented when following the path, either {@link #NORMAL}, + * or {@link #FINE}. + */ + public ArcPath (Point start, double xradius, double yradius, + double sangle, double delta, long duration, + int orient) + { + super(duration); + _xradius = xradius; + _yradius = yradius; + _sangle = sangle; + _delta = delta; + _orient = orient; + + // compute the center of the ellipse + _center = new Point( + (int)(start.x - Math.round(Math.cos(sangle) * xradius)), + (int)(start.y - Math.round(Math.sin(sangle) * yradius))); + } + + /** + * Return a copy of the path, translated by the specified amounts. + */ + public Path getTranslatedInstance (int x, int y) + { + int startx = + (int)(_center.x + Math.round(Math.cos(_sangle) * _xradius)); + int starty = + (int)(_center.y + Math.round(Math.sin(_sangle) * _yradius)); + + return new ArcPath(new Point (startx + x, starty + y), + _xradius, _yradius, _sangle, _delta, _duration, _orient); + } + + /** + * Sets the offset that is applied to the pathable whenever it is + * oriented. This offset is in clockwise units whose granularity is + * specified by the {@link #NORMAL} or {@link #FINE} setting supplied + * to the path at construct time. The intent here is to allow arc + * paths to be applied that don't orient the pathable in the direction + * they are traveling but instead in some fixed offset from that + * direction. + */ + public void setOrientOffset (int offset) + { + _orientOffset = offset; + } + + // documentation inherited + public boolean tick (Pathable pable, long timestamp) + { + double angle; + boolean modified = false; + + // if we've blown past our arrival time... + if (timestamp >= _startStamp + _duration) { + // ...force the angle to the destination angle + angle = _sangle + _delta; + + } else { + // otherwise, compute the angle at which we should place the + // pathable based on the elapsed time + long elapsed = timestamp - _startStamp; + angle = _sangle + _delta * elapsed / _duration; + } + + // determine where we should be along the path + computePosition(_center, _xradius, _yradius, angle, _tpos); + + // Skip this if we are not reorienting as we follow the path. + if (_orient != NONE) { + // compute the pathable's new orientation + double theta = angle + ((_delta > 0) ? Math.PI/2 : -Math.PI/2); + int orient; + switch (_orient) { + default: + case NORMAL: + orient = DirectionUtil.getDirection(theta); + // adjust it appropriately + orient = DirectionUtil.rotateCW(orient, 2*_orientOffset); + break; + + case FINE: + orient = DirectionUtil.getFineDirection(theta); + // adjust it appropriately + orient = DirectionUtil.rotateCW(orient, _orientOffset); + break; + } + + // update the pathable's orientation if it changed + if (pable.getOrientation() != orient) { + pable.setOrientation(orient); + modified = true; + } + } + + // update the pathable's location if it moved + if (pable.getX() != _tpos.x || pable.getY() != _tpos.y) { + pable.setLocation(_tpos.x, _tpos.y); + modified = true; + } + + // if we completed our path, let the sprite know + if (angle == _sangle + _delta) { + pable.pathCompleted(timestamp); + } + + return modified; + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + int x = (int)(_center.x - _xradius), y = (int)(_center.y - _yradius); + int width = (int)(2*_xradius), height = (int)(2*_yradius); + int sangle = (int)(Math.round(180 * _sangle / Math.PI)), + delta = (int)(Math.round(180 * _delta / Math.PI)); + + gfx.setColor(Color.blue); + gfx.drawRect(x, y, width-1, height-1); + + gfx.setColor(Color.yellow); + gfx.drawArc(x, y, width-1, height-1, 0, 360); + + gfx.setColor(Color.red); + gfx.drawArc(x, y, width-1, height-1, 360-sangle, -delta); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", center=").append(StringUtil.toString(_center)); + buf.append(", sangle=").append(_sangle); + buf.append(", delta=").append(_delta); + buf.append(", radii=").append(_xradius).append("/").append(_yradius); + } + + /** + * Computes the position of an entity along the path defined by the + * supplied parameters assuming that it must finish the path in the + * specified duration (in millis) and has been traveling the path for + * the specified number of elapsed milliseconds. + */ + public static void computePosition ( + Point center, double xradius, double yradius, double angle, Point pos) + { + pos.x = (int)Math.round(center.x + xradius * Math.cos(angle)); + pos.y = (int)Math.round(center.y + yradius * Math.sin(angle)); + } + + /** The center of our ellipse. */ + protected Point _center; + + /** Our ellipse radii. */ + protected double _xradius, _yradius; + + /** Our starting and delta angles. */ + protected double _sangle, _delta; + + /** The method to be used to orient the pathable. */ + protected int _orient; + + /** An orientation offset used when orienting our pathable. */ + protected int _orientOffset = 0; + + /** A temporary point used when computing our position along the + * path. */ + protected Point _tpos = new Point(); +} diff --git a/src/java/com/threerings/media/util/BackgroundTiler.java b/src/java/com/threerings/media/util/BackgroundTiler.java new file mode 100644 index 00000000..200cdd8a --- /dev/null +++ b/src/java/com/threerings/media/util/BackgroundTiler.java @@ -0,0 +1,208 @@ +// +// $Id: BackgroundTiler.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics; +import java.awt.image.BufferedImage; + +import com.threerings.media.Log; + +/** + * Used to tile a background image into regions of various sizes. The + * source image is divided into nine quadrants (of mostly equal size) + * which are tiled accordingly to fill whatever size background image is + * desired. + */ +public class BackgroundTiler +{ + /** + * Creates a background tiler with the specified source image. + */ + public BackgroundTiler (BufferedImage src) + { + // make sure we were given the goods + if (src == null) { + Log.info("Backgrounder given null source image. Coping."); + return; + } + + // compute some values + int width = src.getWidth(null); + int height = src.getHeight(null); + + _w3 = width/3; + _cw3 = width-2*_w3; + _h3 = height/3; + _ch3 = height-2*_h3; + + // make sure the image suits our minimum useful dimensions + if (_w3 <= 0 || _cw3 <= 0 || _h3 <= 0 || _ch3 <= 0) { + Log.warning("Backgrounder given source image of insufficient " + + "size for tiling " + + "[width=" + width + ", height=" + height + "]."); + return; + } + + // create our sub-divided images + _tiles = new BufferedImage[9]; + int[] sy = { 0, _h3, _h3+_ch3 }; + int[] thei = { _h3, _ch3, _h3 }; + for (int i = 0; i < 3; i++) { + _tiles[3*i] = src.getSubimage(0, sy[i], _w3, thei[i]); + _tiles[3*i+1] = src.getSubimage(_w3, sy[i], _cw3, thei[i]); + _tiles[3*i+2] = + src.getSubimage(width-_w3, sy[i], _w3, thei[i]); + } + } + + /** + * Returns the "natural" width of the image being used to tile the + * background. + */ + public int getNaturalWidth () + { + return _w3*2+_cw3; + } + + /** + * Returns the "natural" height of the image being used to tile the + * background. + */ + public int getNaturalHeight () + { + return _h3*2+_ch3; + } + + /** + * Fills the requested region with the background defined by our + * source image. + */ + public void paint (Graphics g, int x, int y, int width, int height) + { + // bail out now if we were passed a bogus source image at + // construct time + if (_tiles == null) { + return; + } + + int rwid = width-2*_w3, rhei = height-2*_h3; + + g.drawImage(_tiles[0], x, y, _w3, _h3, null); + g.drawImage(_tiles[1], x + _w3, y, rwid, _h3, null); + g.drawImage(_tiles[2], x + _w3 + rwid, y, _w3, _h3, null); + + y += _h3; + g.drawImage(_tiles[3], x, y, _w3, rhei, null); + g.drawImage(_tiles[4], x + _w3, y, rwid, rhei, null); + g.drawImage(_tiles[5], x + _w3 + rwid, y, _w3, rhei, null); + + y += rhei; + g.drawImage(_tiles[6], x, y, _w3, _h3, null); + g.drawImage(_tiles[7], x + _w3, y, rwid, _h3, null); + g.drawImage(_tiles[8], x + _w3 + rwid, y, _w3, _h3, null); + } + + /** Our nine sub-divided images. */ + protected BufferedImage[] _tiles; + + /** One third of width/height of our source image. */ + protected int _w3, _h3; + + /** The size of the center chunk of our subdivided images. */ + protected int _cw3, _ch3; +} + + +// Below is an alternate implementation that uses only the source image +// without chopping it up. It ends up running very slightly slower, that +// may be because the documentation for the version of drawImage used below +// states that scaled instances will not be cached, that the scaling will +// happen each time on the fly. On the other hand, maybe that's a good thing. +// I like it better because it doesn't have to have 9 separate images and +// because it does the render in a loop, which is good fun. + +//public class BackgroundTiler +//{ +// /** +// * Creates a background tiler with the specified source image. +// */ +// public BackgroundTiler (BufferedImage src) +// { +// // make sure we were given the goods +// if (src == null) { +// Log.info("Backgrounder given null source image. Coping."); +// return; +// } +// +// _src = src; +// +// // compute some values +// int width = src.getWidth(null); +// int height = src.getHeight(null); +// +// _w3 = width/3; +// _cw3 = width-2*_w3; +// _h3 = height/3; +// _ch3 = height-2*_h3; +// +// _sx = new int[] { 0, _w3, width - _w3, width }; +// _sy = new int[] { 0, _h3, height - _h3, height }; +// _dx = new int[4]; +// _dy = new int[4]; +// } +// +// /** +// * Fills the requested region with the background defined by our +// * source image. +// */ +// public void paint (Graphics g, int x, int y, int width, int height) +// { +// _dx[0] = x; +// _dx[1] = x + _w3; +// _dx[2] = x + width - _w3; +// _dx[3] = x + width; +// +// _dy[0] = y; +// _dy[1] = y + _h3; +// _dy[2] = y + height - _h3; +// _dy[3] = y + height; +// +// for (int jj=0; jj < 3; jj++) { +// for (int ii=0; ii < 3; ii++) { +// g.drawImage(_src, _dx[ii], _dy[jj], _dx[ii + 1], _dy[jj + 1], +// _sx[ii], _sy[jj], _sx[ii + 1], _sy[jj + 1], null); +// } +// } +// } +// +// /** Our source image. */ +// protected BufferedImage _src; +// +// /** Coordinates. */ +// protected int[] _sx, _sy, _dx, _dy; +// +// /** One third of width/height of our source image. */ +// protected int _w3, _h3; +// +// /** The size of the center chunk of our subdivided images. */ +// protected int _cw3, _ch3; +//} diff --git a/src/java/com/threerings/media/util/BobblePath.java b/src/java/com/threerings/media/util/BobblePath.java new file mode 100644 index 00000000..c6d8db79 --- /dev/null +++ b/src/java/com/threerings/media/util/BobblePath.java @@ -0,0 +1,191 @@ +// +// $Id: BobblePath.java 4188 2006-06-13 18:03:48Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Graphics2D; + +import com.samskivert.util.RandomUtil; + +import com.threerings.media.Log; + +/** + * Bobble a Pathable. + */ +public class BobblePath implements Path +{ + /** + * Construct a bobble path that updates as often as possible. + * + * @param dx the variance in the x direction. + * @param dy the variance in the y direction. + * @param duration the duration to bobble, or -1 to bobble until + * stop() is called. + */ + public BobblePath (int dx, int dy, long duration) + { + this(dx, dy, duration, 1L); + } + + /** + * Construct a bobble path. + * + * @param dx the variance in the x direction. + * @param dy the variance in the y direction. + * @param duration the duration to bobble, or -1 to bobble until + * stop() is called. + * @param updateFreq how often to update the Pathable's location. + */ + public BobblePath (int dx, int dy, long duration, long updateFreq) + { + _updateFreq = updateFreq; + _duration = duration; + setVariance(dx, dy); + } + + /** + * Set the variance of bobblin' in each direction. + */ + public void setVariance (int dx, int dy) + { + if ((dx < 0) || (dy < 0) || ((dx == 0) && (dy == 0))) { + throw new IllegalArgumentException( + "Variance values must be positive, " + + "and at least one must be non-zero."); + } else { + _dx = dx; + _dy = dy; + } + } + + /** + * Set a new update frequency. + */ + public void setUpdateFrequency (long freq) + { + _updateFreq = freq; + } + + /** + * Have the Pathable stop bobbling asap. + */ + public void stop () + { + // it will stop on the next tick.. + _stopTime = 0L; + } + + // documentation inherited from interface Path + public void init (Pathable pable, long tickstamp) + { + _sx = pable.getX(); + _sy = pable.getY(); + // change the duration to a real stop time + if (_duration == -1L) { + _stopTime = Long.MAX_VALUE; + } else { + _stopTime = tickstamp + _duration; + } + _nextMove = tickstamp; + } + + // documentation inherited from interface Path + public boolean tick (Pathable pable, long tickStamp) + { + // see if we need to stop + if (_stopTime <= tickStamp) { + boolean updated = updatePositionTo(pable, _sx, _sy); + pable.pathCompleted(tickStamp); + return updated; + } + + // see if it's time to move.. + if (_nextMove > tickStamp) { + return false; + } + + // when bobbling, it's bad form to bobble into the same position + int newx, newy; + do { + newx = _sx + RandomUtil.getInt(_dx * 2 + 1) - _dx; + newy = _sy + RandomUtil.getInt(_dy * 2 + 1) - _dy; + } while (! updatePositionTo(pable, newx, newy)); + + // and update the next time to move + _nextMove = tickStamp + _updateFreq; + return true; + } + + // documentation inherited from interface Path + public void fastForward (long timeDelta) + { + _stopTime += timeDelta; + _nextMove += timeDelta; + } + + // documentation inherited from interface Path + public void paint (Graphics2D gfx) + { + // for debugging, show the bobble bounds + gfx.setColor(Color.RED); + gfx.drawRect(_sx - _dx, _sy - _dy, _dx * 2, _dy * 2); + } + + // documentation inherited from interface + public void wasRemoved (Pathable pable) + { + // reset the pathable to its initial location + pable.setLocation(_sx, _sy); + } + + /** + * Update the position of the pathable or return false + * if it's already there. + */ + protected boolean updatePositionTo (Pathable pable, int x, int y) + { + if ((pable.getX() == x) && (pable.getY() == y)) { + return false; + } else { + pable.setLocation(x, y); + return true; + } + } + + /** The initial position of the pathable. */ + protected int _sx, _sy; + + /** The variance we will bobble around that initial position. */ + protected int _dx, _dy; + + /** How long we'll bobble. */ + protected long _duration; + + /** How often we update the locations. */ + protected long _updateFreq; + + /** The time at which we'll stop pathin'. */ + protected long _stopTime; + + /** The time at which we'll next update the position of the pathable. */ + protected long _nextMove = 0L; +} diff --git a/src/java/com/threerings/media/util/DelayPath.java b/src/java/com/threerings/media/util/DelayPath.java new file mode 100644 index 00000000..ef83b482 --- /dev/null +++ b/src/java/com/threerings/media/util/DelayPath.java @@ -0,0 +1,91 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; +import java.awt.Point; + +/** + * A convenience path that waits a specified amount of time. + */ +public class DelayPath extends TimedPath +{ + /** + * Cause the current path to remain unchanged for the duration. + */ + public DelayPath (long duration) + { + this(null, duration); + } + + /** + * Move to the sprite to the supplied location then wait for the duration. + */ + public DelayPath (int x, int y, long duration) + { + this(new Point(x, y), duration); + } + + /** + * Move to the sprite to the supplied location then wait for the duration. + */ + public DelayPath (Point source, long duration) + { + super(duration); + _source = source; + } + + // documentation inherited + public void init (Pathable pable, long timestamp) + { + super.init(pable, timestamp); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + } + + // documentation inherited + public boolean tick (Pathable pable, long tickstamp) + { + if (tickstamp >= _startStamp + _duration) { + if (_source != null) { + pable.setLocation(_source.x, _source.y); + } + pable.pathCompleted(tickstamp); + return (_source != null); + } + + // If necessary, move the sprite to the supplied location + if (_source != null && (pable.getX() != _source.x || + pable.getY() != _source.y)) { + pable.setLocation(_source.x, _source.y); + return true; + } + + return false; + } + + /** Source point. */ + protected Point _source; +} diff --git a/src/java/com/threerings/media/util/DelegatingPathable.java b/src/java/com/threerings/media/util/DelegatingPathable.java new file mode 100644 index 00000000..46eb58fc --- /dev/null +++ b/src/java/com/threerings/media/util/DelegatingPathable.java @@ -0,0 +1,87 @@ +// +// $Id: DelegatingPathable.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Rectangle; + +/** + * Delegates all calls to a delegate pathable. One would derive from this + * class and override just the methods in which that one desired to + * intervene. + */ +public class DelegatingPathable implements Pathable +{ + public DelegatingPathable (Pathable delegate) + { + _delegate = delegate; + } + + // documentation inherited from interface + public int getX () + { + return _delegate.getX(); + } + + // documentation inherited from interface + public int getY () + { + return _delegate.getY(); + } + + // documentation inherited from interface + public Rectangle getBounds () + { + return _delegate.getBounds(); + } + + // documentation inherited from interface + public void setLocation (int x, int y) + { + _delegate.setLocation(x, y); + } + + // documentation inherited from interface + public void setOrientation (int orient) + { + _delegate.setOrientation(orient); + } + + // documentation inherited from interface + public int getOrientation () + { + return _delegate.getOrientation(); + } + + // documentation inherited from interface + public void pathBeginning () + { + _delegate.pathBeginning(); + } + + // documentation inherited from interface + public void pathCompleted (long timestamp) + { + _delegate.pathCompleted(timestamp); + } + + protected Pathable _delegate; +} diff --git a/src/java/com/threerings/media/util/FrameSequencer.java b/src/java/com/threerings/media/util/FrameSequencer.java new file mode 100644 index 00000000..c5b47bbe --- /dev/null +++ b/src/java/com/threerings/media/util/FrameSequencer.java @@ -0,0 +1,113 @@ +// +// $Id: FrameSequencer.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +/** + * Used to control animation timing when displaying a {@link + * MultiFrameImage}. This interface allows for constant framerates, or + * more sophisticated animation timing. + */ +public interface FrameSequencer +{ + /** + * Called prior to the execution of an animation sequence (not + * necessarily immediately, so time stamps should be obtained in the + * first call to tick). + * + * @param source the multie-frame image that is providing the + * animation frames. + */ + public void init (MultiFrameImage source); + + /** + * Called every display frame, the frame sequencer should return the + * index of the animation frame that should be displayed during this + * tick. If the sequencer returns -1, it is taken as an indication + * that the animation is finished and should be stopped. + */ + public int tick (long tickStamp); + + /** + * Called if the display is paused for some length of time and then + * unpaused. Sequencers should adjust any time stamps they are + * maintaining internally by the delta so that time maintains the + * illusion of flowing smoothly forward. + */ + public void fastForward (long timeDelta); + + /** + * A frame sequencer that delivers a constant frame rate in either one + * shot or looping mode. + */ + public static class ConstantRate implements FrameSequencer + { + /** + * Creates a constant rate frame sequencer with the desired target + * frames per second. + * + * @param framesPerSecond the target frames per second. + * @param loop if false, the sequencer will report the end of + * the animation after progressing through all of the frames once, + * otherwise it will loop indefinitely. + */ + public ConstantRate (double framesPerSecond, boolean loop) + { + _millisPerFrame = (long)(1000d / framesPerSecond); + _loop = loop; + } + + // documentation inherited from interface + public void init (MultiFrameImage source) + { + _frameCount = source.getFrameCount(); + _startStamp = 0l; + } + + // documentation inherited from interface + public int tick (long tickStamp) + { + // obtain our starting timestamp if we don't already have one + if (_startStamp == 0) { + _startStamp = tickStamp; + } + + // compute our current frame index + int frameIdx = (int)((tickStamp - _startStamp) / _millisPerFrame); + + // if we're not looping and we've exhausted our frames, we + // return -1 to indicate that the animation should stop + return (_loop || frameIdx < _frameCount) ? (frameIdx % _frameCount) + : -1; + } + + // documentation inherited from interface + public void fastForward (long timeDelta) + { + _startStamp += timeDelta; + } + + protected long _millisPerFrame; + protected boolean _loop; + protected int _frameCount; + protected long _startStamp; + } +} diff --git a/src/java/com/threerings/media/util/LinePath.java b/src/java/com/threerings/media/util/LinePath.java new file mode 100644 index 00000000..4e0ad4bc --- /dev/null +++ b/src/java/com/threerings/media/util/LinePath.java @@ -0,0 +1,151 @@ +// +// $Id: LinePath.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; + +import com.samskivert.util.StringUtil; + +/** + * The line path is used to cause a pathable to go from point A to point B + * in a certain number of milliseconds. + */ +public class LinePath extends TimedPath +{ + /** + * Constructs a line path between the two specified points that will + * be followed in the specified number of milliseconds. + */ + public LinePath (int x1, int y1, int x2, int y2, long duration) + { + this(new Point(x1, y1), new Point(x2, y2), duration); + } + + /** + * Constructs a line path between the two specified points that will + * be followed in the specified number of milliseconds. + */ + public LinePath (Point source, Point dest, long duration) + { + super(duration); + _source = source; + _dest = dest; + } + + /** + * Constructs a line path that moves a pathable from + * whatever its location is at init time to the dest point over + * the specified number of milliseconds. + */ + public LinePath (Point dest, long duration) + { + this(null, dest, duration); + } + + /** + * Return a copy of the path, translated by the specified amounts. + */ + public Path getTranslatedInstance (int x, int y) + { + if (_source == null) { + return new LinePath(null, new Point(_dest.x + x, _dest.y + y), + _duration); + } else { + return new LinePath(_source.x + x, _source.y + y, _dest.x + x, + _dest.y + y, _duration); + } + } + + // documentation inherited + public void init (Pathable pable, long timestamp) + { + super.init(pable, timestamp); + + // fill in the source if necessary. + if (_source == null) { + _source = new Point(pable.getX(), pable.getY()); + } + } + + // documentation inherited + public boolean tick (Pathable pable, long timestamp) + { + // if we've blown past our arrival time, we need to get our bootay + // to the prearranged spot and get the hell out + if (timestamp >= _startStamp + _duration) { + pable.setLocation(_dest.x, _dest.y); + pable.pathCompleted(timestamp); + return true; + } + + // determine where we should be along the path + long elapsed = timestamp - _startStamp; + computePosition(_source, _dest, elapsed, _duration, _tpos); + + // only update the pathable's location if it actually moved + if (pable.getX() != _tpos.x || pable.getY() != _tpos.y) { + pable.setLocation(_tpos.x, _tpos.y); + return true; + } + + return false; + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + gfx.setColor(Color.red); + gfx.drawLine(_source.x, _source.y, _dest.x, _dest.y); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", src=").append(StringUtil.toString(_source)); + buf.append(", dest=").append(StringUtil.toString(_dest)); + } + + /** + * Computes the position of an entity along the path defined by the + * supplied start and end points assuming that it must finish the path + * in the specified duration (in millis) and has been traveling the + * path for the specified number of elapsed milliseconds. + */ + public static void computePosition (Point start, Point end, long elapsed, + long duration, Point pos) + { + float pct = (float)elapsed / duration; + int travx = (int)((end.x - start.x) * pct); + int travy = (int)((end.y - start.y) * pct); + pos.setLocation(start.x + travx, start.y + travy); + } + + /** Our source and destination points. */ + protected Point _source, _dest; + + /** A temporary point used when computing our position along the + * path. */ + protected Point _tpos = new Point(); +} diff --git a/src/java/com/threerings/media/util/LineSegmentPath.java b/src/java/com/threerings/media/util/LineSegmentPath.java new file mode 100644 index 00000000..0b512608 --- /dev/null +++ b/src/java/com/threerings/media/util/LineSegmentPath.java @@ -0,0 +1,388 @@ +// +// $Id: LineSegmentPath.java 3880 2006-02-22 18:29:05Z mjohnson $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Point; +import java.awt.Graphics2D; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.samskivert.util.StringUtil; + +import com.threerings.util.DirectionCodes; +import com.threerings.util.DirectionUtil; + +import com.threerings.media.Log; +import com.threerings.media.util.MathUtil; + +/** + * The line segment path is used to cause a pathable to follow a path that + * is made up of a sequence of line segments. There must be at least two + * nodes in any worthwhile path. The direction of the first node in the + * path is meaningless since the pathable begins at that node and will + * therefore never be heading towards it. + */ +public class LineSegmentPath + implements DirectionCodes, Path +{ + /** + * Constructs an empty line segment path. + */ + public LineSegmentPath () + { + } + + /** + * Constructs a line segment path that consists of a single segment + * connecting the point (x1, y1) with (x2, + * y2). The orientation for the first node is set arbitrarily + * and the second node is oriented based on the vector between the two + * nodes (in top-down coordinates). + */ + public LineSegmentPath (int x1, int y1, int x2, int y2) + { + addNode(x1, y1, NORTH); + Point p1 = new Point(x1, y1), p2 = new Point(x2, y2); + int dir = DirectionUtil.getDirection(p1, p2); + addNode(x2, y2, dir); + } + + /** + * Construct a line segment path between the two nodes with the + * specified direction. + */ + public LineSegmentPath (Point p1, Point p2, int dir) + { + addNode(p1.x, p1.y, NORTH); + addNode(p2.x, p2.y, dir); + } + + /** + * Constructs a line segment path with the specified list of points. + * An arbitrary direction will be assigned to the starting node. + */ + public LineSegmentPath (List points) + { + createPath(points); + } + + /** + * Returns the orientation the sprite will face at the end of the + * path. + */ + public int getFinalOrientation () + { + return (_nodes.size() == 0) ? NORTH : + ((PathNode)_nodes.get(_nodes.size()-1)).dir; + } + + /** + * Add a node to the path with the specified destination point and + * facing direction. + * + * @param x the x-position. + * @param y the y-position. + * @param dir the facing direction. + */ + public void addNode (int x, int y, int dir) + { + _nodes.add(new PathNode(x, y, dir)); + } + + /** + * Return the requested node index in the path, or null if no such + * index exists. + * + * @param idx the node index. + * + * @return the path node. + */ + public PathNode getNode (int idx) + { + return (PathNode)_nodes.get(idx); + } + + /** + * Return the number of nodes in the path. + */ + public int size () + { + return _nodes.size(); + } + + /** + * Sets the velocity of this pathable in pixels per millisecond. The + * velocity is measured as pixels traversed along the path that the + * pathable is traveling rather than in the x or y directions + * individually. Note that the pathable velocity should not be + * changed while a path is being traversed; doing so may result in the + * pathable position changing unexpectedly. + * + * @param velocity the pathable velocity in pixels per millisecond. + */ + public void setVelocity (float velocity) + { + _vel = velocity; + } + + /** + * Computes the velocity at which the pathable will need to travel + * along this path such that it will arrive at the destination in + * approximately the specified number of milliseconds. Efforts are + * taken to get the pathable there as close to the desired time as + * possible, but framerate variation may prevent it from arriving + * exactly on time. + */ + public void setDuration (long millis) + { + // if we have only zero or one nodes, we don't have enough + // information to compute our velocity + int ncount = _nodes.size(); + if (ncount < 2) { + Log.warning("Requested to set duration of bogus path " + + "[path=" + this + ", duration=" + millis + "]."); + return; + } + + // compute the total distance along our path + float distance = 0; + PathNode start = (PathNode)_nodes.get(0); + for (int ii = 1; ii < ncount; ii++) { + PathNode end = (PathNode)_nodes.get(ii); + distance += MathUtil.distance( + start.loc.x, start.loc.y, end.loc.x, end.loc.y); + start = end; + } + + // set the velocity accordingly + setVelocity(distance/millis); + } + + // documentation inherited + public void init (Pathable pable, long timestamp) + { + // give the pathable a chance to perform any starting antics + pable.pathBeginning(); + + // if we have only one node then let the pathable know that we're + // done straight away + if (size() < 2) { + // move the pathable to the location specified by the first + // node (assuming we have a first node) + if (size() == 1) { + PathNode node = (PathNode)_nodes.get(0); + pable.setLocation(node.loc.x, node.loc.y); + } + // and let the pathable know that we're done + pable.pathCompleted(timestamp); + return; + } + + // and an enumeration of the path nodes + _niter = _nodes.iterator(); + + // pretend like we were previously heading to our starting position + _dest = getNextNode(); + + // begin traversing the path + headToNextNode(pable, timestamp, timestamp); + } + + // documentation inherited + public boolean tick (Pathable pable, long timestamp) + { + // figure out how far along this segment we should be + long msecs = timestamp - _nodestamp; + float travpix = msecs * _vel; + float pctdone = travpix / _seglength; + + // if we've moved beyond the end of the path, we need to adjust + // the timestamp to determine how much time we used getting to the + // end of this node, then move to the next one + if (pctdone >= 1.0) { + long used = (long)(_seglength / _vel); + return headToNextNode(pable, _nodestamp + used, timestamp); + } + + // otherwise we position the pathable along the path + int ox = pable.getX(); + int oy = pable.getY(); + int nx = _src.loc.x + (int)((_dest.loc.x - _src.loc.x) * pctdone); + int ny = _src.loc.y + (int)((_dest.loc.y - _src.loc.y) * pctdone); + +// Log.info("Moving pathable [msecs=" + msecs + ", pctdone=" + pctdone + +// ", travpix=" + travpix + ", seglength=" + _seglength + +// ", dx=" + (nx-ox) + ", dy=" + (ny-oy) + "]."); + + // only update the pathable's location if it actually moved + if (ox != nx || oy != ny) { + pable.setLocation(nx, ny); + return true; + } + + return false; + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _nodestamp += timeDelta; + } + + // documentation inherited from interface + public void wasRemoved (Pathable pable) + { + // nothing doing + } + + /** + * Place the pathable moving along the path at the end of the previous + * path node, face it appropriately for the next node, and start it on + * its way. Returns whether the pathable position moved. + */ + protected boolean headToNextNode ( + Pathable pable, long startstamp, long now) + { + if (_niter == null) { + throw new IllegalStateException( + "headToNextNode() called before init()"); + } + + // check to see if we've completed our path + if (!_niter.hasNext()) { + // move the pathable to the location of our last destination + pable.setLocation(_dest.loc.x, _dest.loc.y); + pable.pathCompleted(now); + return true; + } + + // our previous destination is now our source + _src = _dest; + + // pop the next node off the path + _dest = getNextNode(); + + // adjust the pathable's orientation + if (_dest.dir != NONE) { + pable.setOrientation(_dest.dir); + } + + // make a note of when we started traversing this node + _nodestamp = startstamp; + + // figure out the distance from source to destination + _seglength = MathUtil.distance( + _src.loc.x, _src.loc.y, _dest.loc.x, _dest.loc.y); + + // if we're already there (the segment length is zero), we skip to + // the next segment + if (_seglength == 0) { + return headToNextNode(pable, startstamp, now); + } + + // now update the pathable's position based on our progress thus far + return tick(pable, now); + } + + // documentation inherited + public void paint (Graphics2D gfx) + { + gfx.setColor(Color.red); + Point prev = null; + int size = size(); + for (int ii = 0; ii < size; ii++) { + PathNode n = (PathNode)getNode(ii); + if (prev != null) { + gfx.drawLine(prev.x, prev.y, n.loc.x, n.loc.y); + } + prev = n.loc; + } + } + + // documentation inherited + public String toString () + { + return StringUtil.toString(_nodes.iterator()); + } + + /** + * Populate the path with the path nodes that lead the pathable from + * its starting position to the given destination coordinates + * following the given list of screen coordinates. + */ + protected void createPath (List points) + { + Point last = null; + int size = points.size(); + for (int ii = 0; ii < size; ii++) { + Point p = (Point)points.get(ii); + + int dir = (ii == 0) ? NORTH : DirectionUtil.getDirection(last, p); + addNode(p.x, p.y, dir); + last = p; + } + } + + /** + * Gets the next node in the path. + */ + protected PathNode getNextNode () + { + return (PathNode)_niter.next(); + } + + /** The nodes that make up the path. */ + protected ArrayList _nodes = new ArrayList(); + + /** We use this when moving along this path. */ + protected Iterator _niter; + + /** When moving, the pathable's source path node. */ + protected PathNode _src; + + /** When moving, the pathable's destination path node. */ + protected PathNode _dest; + + /** The time at which we started traversing the current node. */ + protected long _nodestamp; + + /** The length in pixels of the current path segment. */ + protected float _seglength; + + /** The path velocity in pixels per millisecond. */ + protected float _vel = DEFAULT_VELOCITY; + + /** When moving, the pathable position including fractional pixels. */ + protected float _movex, _movey; + + /** When moving, the distance to move on each axis per tick. */ + protected float _incx, _incy; + + /** The distance to move on the straight path line per tick. */ + protected float _fracx, _fracy; + + /** Default pathable velocity. */ + protected static final float DEFAULT_VELOCITY = 200f/1000f; +} diff --git a/src/java/com/threerings/media/util/LinearTimeFunction.java b/src/java/com/threerings/media/util/LinearTimeFunction.java new file mode 100644 index 00000000..8cbc1976 --- /dev/null +++ b/src/java/com/threerings/media/util/LinearTimeFunction.java @@ -0,0 +1,22 @@ +// +// $Id: LinearTimeFunction.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media.util; + +/** + * Varies a value linearly with time. + */ +public class LinearTimeFunction extends TimeFunction +{ + public LinearTimeFunction (int start, int end, int duration) + { + super(start, end, duration); + } + + // documentation inherited + protected int computeValue (int dt) + { + int dv = (_end - _start); + return (dt * dv / _duration) + _start; + } +} diff --git a/src/java/com/threerings/media/util/MathUtil.java b/src/java/com/threerings/media/util/MathUtil.java new file mode 100644 index 00000000..68ededf7 --- /dev/null +++ b/src/java/com/threerings/media/util/MathUtil.java @@ -0,0 +1,162 @@ +// +// $Id: MathUtil.java 3580 2005-05-27 23:04:42Z tedv $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Point; + +/** + * Provides miscellaneous useful utility routines for mathematical + * calculations. + */ +public class MathUtil +{ + /** + * Bounds the supplied value within the specified range. + * + * @return low if value < low, high if value > high and value + * otherwise. + */ + public static int bound (int low, int value, int high) + { + return Math.min(high, Math.max(low, value)); + } + + /** + * Return the squared distance between the given points. + */ + public static int distanceSq (int x0, int y0, int x1, int y1) + { + return ((x1 - x0) * (x1 - x0)) + ((y1 - y0) * (y1 - y0)); + } + + /** + * Return the distance between the given points. + */ + public static float distance (int x0, int y0, int x1, int y1) + { + return (float)Math.sqrt(((x1 - x0) * (x1 - x0)) + + ((y1 - y0) * (y1 - y0))); + } + + /** + * Return the distance between the given points. + */ + public static float distance (Point source, Point dest) + { + return MathUtil.distance(source.x, source.y, dest.x, dest.y); + } + + /** + * Return a string representation of the given line. + */ + public static String lineToString (int x0, int y0, int x1, int y1) + { + return "(" + x0 + ", " + y0 + ") -> (" + x1 + ", " + y1 + ")"; + } + + /** + * Return a string representation of the given line. + */ + public static String lineToString (Point p1, Point p2) + { + return lineToString(p1.x, p1.y, p2.x, p2.y); + } + + /** + * Returns the approximate circumference of the ellipse defined by the + * specified minor and major axes. The formula used (due to Ramanujan, + * via a paper of his entitled "Modular Equations and Approximations + * to Pi"), is Pi(3a + 3b - sqrt[(a+3b)(b+3a)]). + */ + public static double ellipseCircum (double a, double b) + { + return Math.PI * (3*a + 3*b - Math.sqrt((a + 3*b) * (b + 3*a))); + } + + /** + * Returns positive 1 if the sign of the argument is positive, or -1 + * if the sign of the argument is negative. + */ + public static int sign (int value) + { + return (value < 0) ? -1 : 1; + } + + /** + * Computes the floored division dividend/divisor which + * is useful when dividing potentially negative numbers into bins. For + * positive numbers, it is the same as normal division, for negative + * numbers it returns (dividend - divisor + 1) / divisor. + * + *

For example, the following numbers floorDiv 10 are: + *

+     * -15 -10 -8 -2 0 2 8 10 15
+     *  -2  -1 -1 -1 0 0 0  1  1
+     * 
+ */ + public static int floorDiv (int dividend, int divisor) + { + return ((dividend >= 0) ? dividend : (dividend - divisor + 1))/divisor; + } + + /** + * Computes the standard deviation of the supplied values. + * + * @return an array of three values: the mean, variance and standard + * deviation, in that order. + */ + public static float[] stddev (int[] values, int start, int length) + { + // first we need the mean + float mean = 0f; + for (int ii = start, end = start + length; ii < end; ii++) { + mean += values[ii]; + } + mean /= length; + + // next we compute the variance + float variance = 0f; + for (int ii = start, end = start + length; ii < end; ii++) { + float value = values[ii] - mean; + variance += value * value; + } + variance /= (length - 1); + + // the standard deviation is the square root of the variance + return new float[] { mean, variance, (float)Math.sqrt(variance) }; + } + + /** + * Computes (N choose K), the number of ways to select K different + * elements from a set of size N. + */ + public static int choose (int n, int k) + { + // Base case: One way to select or not select the whole set + if (k <= 0 || k >= n) { + return 1; + } + + // Recurse using pascal's triangle + return (choose(n-1, k-1) + choose(n-1, k)); + } +} diff --git a/src/java/com/threerings/media/util/ModeUtil.java b/src/java/com/threerings/media/util/ModeUtil.java new file mode 100644 index 00000000..d4ac9193 --- /dev/null +++ b/src/java/com/threerings/media/util/ModeUtil.java @@ -0,0 +1,99 @@ +// +// $Id: ModeUtil.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.DisplayMode; +import java.awt.GraphicsDevice; + +import java.util.Comparator; +import java.util.TreeSet; + +/** + * Display mode related utilities. + */ +public class ModeUtil +{ + /** + * Gets a display mode that matches the specified parameters. The + * screen resolution must match the specified resolution exactly, the + * specified desired depth will be used if it is available, and if + * not, the highest depth greater than or equal to the specified + * minimum depth is used. The highest refresh rate available for the + * desired mode is also used. + */ + public static DisplayMode getDisplayMode ( + GraphicsDevice gd, int width, int height, + int desiredDepth, int minimumDepth) + { + DisplayMode[] modes = gd.getDisplayModes(); + final int ddepth = desiredDepth; + + // we sort modes in order of desirability + Comparator mcomp = new Comparator () { + public int compare (Object o1, Object o2) { + DisplayMode m1 = (DisplayMode)o1; + DisplayMode m2 = (DisplayMode)o2; + int bd1 = m1.getBitDepth(), bd2 = m2.getBitDepth(); + int rr1 = m1.getRefreshRate(), rr2 = m2.getRefreshRate(); + + // prefer the desired depth + if (bd1 == ddepth && bd2 != ddepth) { + return -1; + } else if (bd2 == ddepth && bd1 != ddepth) { + return 1; + } + + // otherwise prefer higher depths + if (bd1 != bd2) { + return bd2 - bd1; + } + + // for same bitrates, prefer higher refresh rates + return rr2 - rr1; + } + }; + + // but we only add modes that meet our minimum requirements + TreeSet mset = new TreeSet(mcomp); + for (int i = 0; i < modes.length; i++) { + if (modes[i].getWidth() == width && + modes[i].getHeight() == height && + modes[i].getBitDepth() >= minimumDepth && + modes[i].getRefreshRate() <= 75) { + mset.add(modes[i]); + } + } + + return (mset.size() > 0) ? (DisplayMode)mset.first() : null; + } + + /** + * Returns a string representation of the supplied display mode. + */ + public static String toString (DisplayMode mode) + { + return "[width=" + mode.getWidth() + + ", height=" + mode.getHeight() + + ", depth=" + mode.getBitDepth() + + ", refresh=" + mode.getRefreshRate() + "]"; + } +} diff --git a/src/java/com/threerings/media/util/MultiFrameImage.java b/src/java/com/threerings/media/util/MultiFrameImage.java new file mode 100644 index 00000000..8a200d86 --- /dev/null +++ b/src/java/com/threerings/media/util/MultiFrameImage.java @@ -0,0 +1,58 @@ +// +// $Id: MultiFrameImage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +/** + * The multi-frame image interface provides encapsulated access to a set + * of images that are used to create a multi-frame animation. + */ +public interface MultiFrameImage +{ + /** + * Returns the number of frames in this multi-frame image. + */ + public int getFrameCount (); + + /** + * Returns the width of the specified frame image. + */ + public int getWidth (int index); + + /** + * Returns the height of the specified frame image. + */ + public int getHeight (int index); + + /** + * Renders the specified frame into the specified graphics object at + * the specified coordinates. + */ + public void paintFrame (Graphics2D g, int index, int x, int y); + + /** + * Returns true if the specified frame contains a non-transparent + * pixel at the specified coordinates. + */ + public boolean hitTest (int index, int x, int y); +} diff --git a/src/java/com/threerings/media/util/MultiFrameImageImpl.java b/src/java/com/threerings/media/util/MultiFrameImageImpl.java new file mode 100644 index 00000000..8958d4b4 --- /dev/null +++ b/src/java/com/threerings/media/util/MultiFrameImageImpl.java @@ -0,0 +1,75 @@ +// +// $Id: MultiFrameImageImpl.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +import com.threerings.media.image.Mirage; + +/** + * A basic implementation of the {@link MultiFrameImage} interface + * intended to facilitate the creation of MFIs whose display frames + * consist of multiple image objects. + */ +public class MultiFrameImageImpl implements MultiFrameImage +{ + /** + * Constructs a multiple frame image object. + */ + public MultiFrameImageImpl (Mirage[] mirages) + { + _mirages = mirages; + } + + // documentation inherited + public int getFrameCount () + { + return _mirages.length; + } + + // documentation inherited from interface + public int getWidth (int index) + { + return _mirages[index].getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) + { + return _mirages[index].getHeight(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) + { + _mirages[index].paint(g, x, y); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) + { + return _mirages[index].hitTest(x, y); + } + + /** The frame images. */ + protected Mirage[] _mirages; +} diff --git a/src/java/com/threerings/media/util/Path.java b/src/java/com/threerings/media/util/Path.java new file mode 100644 index 00000000..0d7c2fa6 --- /dev/null +++ b/src/java/com/threerings/media/util/Path.java @@ -0,0 +1,82 @@ +// +// $Id: Path.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +/** + * A path is used to cause a {@link Pathable} to follow a particular path + * along the screen. The {@link Pathable} is responsible for calling + * {@link #tick} on the path with reasonable frequency (generally as a + * part of the frame tick. The path is responsible for updating the + * position of the {@link Pathable} based on the time that has elapsed + * since the {@link Pathable} started down the path. + * + *

The path should call the appropriate callbacks on the {@link + * Pathable} when appropriate (e.g. {@link Pathable#pathBeginning}, {@link + * Pathable#pathCompleted}). + */ +public interface Path +{ + /** + * Called once to let the path prepare itself for the process of + * animating the supplied pathable. Path users should also call {@link + * #tick} after {@link #init} with the same initialization timestamp. + */ + public void init (Pathable pable, long tickStamp); + + /** + * Called to request that this path update the position of the + * specified pathable based on the supplied timestamp information. A + * path should record its initial timestamp and determine the progress + * of the pathable along the path based on the time elapsed since the + * pathable began down the path. + * + * @param pable the pathable whose position should be updated. + * @param tickStamp the timestamp associated with this frame. + * + * @return true if the pathable's position was updated, false if the + * path determined that the pathable should not move at this time. + */ + public boolean tick (Pathable pable, long tickStamp); + + /** + * This is called if the pathable is paused for some length of time + * and then unpaused. Paths should adjust any time stamps they are + * maintaining internally by the delta so that time maintains the + * illusion of flowing smoothly forward. + */ + public void fastForward (long timeDelta); + + /** + * Paint this path on the screen (used for debugging purposes only). + */ + public void paint (Graphics2D gfx); + + /** + * When a path is removed from a pathable, whether that is because the + * path was completed or because it was replaced by another path, this + * method will be called to let the path know that it is no longer + * associated with this pathable. + */ + public void wasRemoved (Pathable pable); +} diff --git a/src/java/com/threerings/media/util/PathNode.java b/src/java/com/threerings/media/util/PathNode.java new file mode 100644 index 00000000..cef316da --- /dev/null +++ b/src/java/com/threerings/media/util/PathNode.java @@ -0,0 +1,72 @@ +// +// $Id: PathNode.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Point; + +/** + * A path node is a single destination point in a {@link Path}. + */ +public class PathNode +{ + /** The node coordinates in screen pixels. */ + public Point loc; + + /** The direction to face while heading toward the node. */ + public int dir; + + /** + * Construct a path node object. + * + * @param x the node x-position. + * @param y the node y-position. + * @param dir the facing direction. + */ + public PathNode (int x, int y, int dir) + { + loc = new Point(x, y); + this.dir = dir; + } + + /** + * Return a string representation of this path node. + */ + public String toString () + { + StringBuilder buf = new StringBuilder(); + buf.append("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * This should be overridden by derived classes (which should be sure + * to call super.toString()) to append the derived class + * specific path node information to the string buffer. + */ + public void toString (StringBuilder buf) + { + buf.append("x=").append(loc.x); + buf.append(", y=").append(loc.y); + buf.append(", dir=").append(dir); + } +} diff --git a/src/java/com/threerings/media/util/PathSequence.java b/src/java/com/threerings/media/util/PathSequence.java new file mode 100644 index 00000000..d8d981d9 --- /dev/null +++ b/src/java/com/threerings/media/util/PathSequence.java @@ -0,0 +1,143 @@ +// +// $Id: PathSequence.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +import java.util.ArrayList; +import java.util.List; + +import com.threerings.media.Log; + +/** + * Used to create a path that is a sequence of several other paths. + */ +public class PathSequence + implements Path +{ + /** + * Conveniently construct a path sequence with the two specified + * paths. + */ + public PathSequence (Path first, Path second) + { + this(new ArrayList()); + _paths.add(first); + _paths.add(second); + } + + /** + * Construct a path sequence with the list of paths. + * Note: Paths may be added to the end of the list while + * the pathable is still traversing earlier paths! + */ + public PathSequence (List paths) + { + _paths = paths; + } + + // documentation inherited from interface Path + public void init (Pathable pable, long tickStamp) + { + _pable = pable; + _pableRep = new DelegatingPathable(_pable) { + public void pathCompleted (long timeStamp) { + long initStamp; + // if we just finished a timed path, we can figure out how + // long ago it really finished and init the next path at + // that time in the past. + if (_curPath instanceof TimedPath) { + initStamp = _lastInit + ((TimedPath) _curPath)._duration; + } else { + // we don't know + initStamp = timeStamp; + } + initNextPath(initStamp, timeStamp); + } + }; + initNextPath(tickStamp, tickStamp); + } + + // documentation inherited from interface Path + public boolean tick (Pathable pable, long tickStamp) + { + if (pable != _pable) { + Log.warning("PathSequence ticked with different path than " + + "it was inited with."); + } + return _curPath.tick(_pableRep, tickStamp); + } + + // documentation inherited from interface Path + public void fastForward (long timeDelta) + { + _lastInit += timeDelta; + _curPath.fastForward(timeDelta); + } + + // documentation inherited from interface Path + public void paint (Graphics2D gfx) + { + // for now.. + _curPath.paint(gfx); + } + + // documentation inherited from interface Path + public void wasRemoved (Pathable pable) + { + if (_curPath != null) { + _curPath.wasRemoved(_pableRep); + } + } + + /** + * Initialize and start the next path in the sequence. + */ + protected void initNextPath (long initStamp, long tickStamp) + { + if (_paths.size() == 0) { + _pable.pathCompleted(tickStamp); + + } else { + _curPath = (Path) _paths.remove(0); + _lastInit = initStamp; + + _curPath.init(_pableRep, initStamp); + _curPath.tick(_pableRep, tickStamp); + } + } + + /** The list of paths. */ + protected List _paths; + + /** The timestamp at which we last inited a path. */ + protected long _lastInit; + + /** The current path we're pathing. */ + protected Path _curPath; + + /** The pathable we're duping bigtime. */ + protected Pathable _pable; + + /** A fake pathable that we pass to the subpaths. */ + protected Pathable _pableRep; +} diff --git a/src/java/com/threerings/media/util/Pathable.java b/src/java/com/threerings/media/util/Pathable.java new file mode 100644 index 00000000..be571e11 --- /dev/null +++ b/src/java/com/threerings/media/util/Pathable.java @@ -0,0 +1,77 @@ +// +// $Id: Pathable.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Rectangle; + +import com.threerings.util.DirectionCodes; + +/** + * Used in conjunction with a {@link Path}. + */ +public interface Pathable +{ + /** + * Returns the pathable's current x coordinate. + */ + public int getX (); + + /** + * Returns the pathable's current y coordinate. + */ + public int getY (); + + /** + * Returns the rectangle that bounds the pathable. + */ + public Rectangle getBounds (); + + /** + * Updates the pathable's current coordinates. + */ + public void setLocation (int x, int y); + + /** + * Will be called by a path when it moves the pathable in the + * specified direction. Pathables that wish to face in the direction + * they are moving can take advantage of this callback. + * + * @see DirectionCodes + */ + public void setOrientation (int orient); + + /** + * Should return the orientation of the pathable, or {@link + * DirectionCodes#NONE} if the pathable does not support orientation. + */ + public int getOrientation (); + + /** + * Called by a path when this pathable is made to start along a path. + */ + public void pathBeginning (); + + /** + * Called by a path when this pathable finishes moving along its path. + */ + public void pathCompleted (long timestamp); +} diff --git a/src/java/com/threerings/media/util/PerformanceMonitor.java b/src/java/com/threerings/media/util/PerformanceMonitor.java new file mode 100644 index 00000000..306e5cd6 --- /dev/null +++ b/src/java/com/threerings/media/util/PerformanceMonitor.java @@ -0,0 +1,215 @@ +// +// $Id: PerformanceMonitor.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.util.HashMap; + +import com.threerings.media.Log; +import com.threerings.media.timer.MediaTimer; +import com.threerings.media.timer.SystemMediaTimer; + +/** + * Provides a simple mechanism for monitoring the number of times an + * action takes place within a certain time period. + * + *

The action being tracked should be registered with a suitable name + * via {@link #register}, and {@link #tick} should be called each time the + * action is performed. + * + *

Whenever {@link #tick} is called and the checkpoint time interval + * has elapsed since the last checkpoint (if any), the observer will be + * notified to that effect by a call to {@link + * PerformanceObserver#checkpoint}. + * + *

Note that this is not intended to be used as an + * industrial-strength profiling or performance monitoring tool. The + * checkpoint time interval granularity is in milliseconds, not + * microseconds, and the observer's checkpoint() method will + * never be called until/unless a subsequent call to {@link #tick} is made + * after the requested number of milliseconds have passed since the last + * checkpoint. + */ +public class PerformanceMonitor +{ + /** + * Register a new action with an observer, the action name, and + * the milliseconds to wait between checkpointing the action's + * performance. + * + * @param obs the action observer. + * @param name the action name. + * @param delta the milliseconds between checkpoints. + */ + public static void register (PerformanceObserver obs, String name, + long delta) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + // create it if it didn't exist + _observers.put(obs, actions = new HashMap()); + } + + // add the action to the set we're tracking + actions.put(name, new PerformanceAction(obs, name, delta)); + } + + /** + * Un-register the named action associated with the given observer. + * + * @param obs the action observer. + * @param name the action name. + */ + public static void unregister (PerformanceObserver obs, String name) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + Log.warning("Attempt to unregister by unknown observer " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // attempt to remove the specified action + PerformanceAction action = (PerformanceAction)actions.remove(name); + if (action == null) { + Log.warning("Attempt to unregister unknown action " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // if the observer has no actions left, remove the observer's action + // hash in its entirety + if (actions.size() == 0) { + _observers.remove(obs); + } + } + + /** + * Tick the named action associated with the given observer. + * + * @param obs the action observer. + * @param name the action name. + */ + public static void tick (PerformanceObserver obs, String name) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + Log.warning("Attempt to tick by unknown observer " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // get the specified action + PerformanceAction action = (PerformanceAction)actions.get(name); + if (action == null) { + Log.warning("Attempt to tick unknown value " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // tick the action + action.tick(); + } + + /** + * Used to configure the performance monitor with a particular {@link + * MediaTimer} implementation. By default it uses a pure-Java + * implementation which isn't extremely accurate across platforms. + */ + public static void setMediaTimer (MediaTimer timer) + { + _timer = timer; + } + + /** Used by the performance actions. */ + protected synchronized static long getTimeStamp () + { + return _timer.getElapsedMillis(); + } + + /** The observers monitoring some set of actions. */ + protected static HashMap _observers = new HashMap(); + + /** Used to obtain high resolution time stamps. */ + protected static MediaTimer _timer = new SystemMediaTimer(); +} + +/** + * This class represents the individual actions being tracked by the + * PerformanceMonitor class. + */ +class PerformanceAction +{ + public PerformanceAction (PerformanceObserver obs, String name, long delta) + { + _obs = obs; + _name = name; + _delta = delta; + _lastDelta = PerformanceMonitor.getTimeStamp(); + } + + public void tick () + { + _numTicks++; + + long now = PerformanceMonitor.getTimeStamp(); + long passed = now - _lastDelta; + if (passed >= _delta) { + // update the last checkpoint time + _lastDelta = now + (passed - _delta); + + // notify our observer of the checkpoint + _obs.checkpoint(_name, _numTicks); + + // reset the tick count + _numTicks = 0; + } + } + + public String toString () + { + StringBuilder buf = new StringBuilder(); + buf.append("[obs=").append(_obs); + buf.append(", name=").append(_name); + buf.append(", delta=").append(_delta); + buf.append(", lastDelta=").append(_lastDelta); + buf.append(", numTicks=").append(_numTicks); + return buf.append("]").toString(); + } + + /** The performance observer. */ + protected PerformanceObserver _obs; + + /** The action name. */ + protected String _name; + + /** The number of milliseconds between each checkpoint. */ + protected long _delta; + + /** The time the last time a checkpoint was made. */ + protected long _lastDelta; + + /** The number of ticks since the last checkpoint. */ + protected int _numTicks; +} diff --git a/src/java/com/threerings/media/util/PerformanceObserver.java b/src/java/com/threerings/media/util/PerformanceObserver.java new file mode 100644 index 00000000..8b22f6b5 --- /dev/null +++ b/src/java/com/threerings/media/util/PerformanceObserver.java @@ -0,0 +1,39 @@ +// +// $Id: PerformanceObserver.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +/** + * This interface should be implemented by classes that wish to register + * actions to be monitored by the {@link PerformanceMonitor} class. + */ +public interface PerformanceObserver +{ + /** + * This method is called by the {@link PerformanceMonitor} class + * whenever an action's requested time interval between checkpoints + * has expired. + * + * @param name the action name. + * @param ticks the ticks since the last checkpoint. + */ + public void checkpoint (String name, int ticks); +} diff --git a/src/java/com/threerings/media/util/SingleFrameImageImpl.java b/src/java/com/threerings/media/util/SingleFrameImageImpl.java new file mode 100644 index 00000000..69f59454 --- /dev/null +++ b/src/java/com/threerings/media/util/SingleFrameImageImpl.java @@ -0,0 +1,75 @@ +// +// $Id: SingleFrameImageImpl.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +import com.threerings.media.image.Mirage; + +/** + * The single frame image class is a basic implementation of the {@link + * MultiFrameImage} interface intended to facilitate the creation of MFIs + * whose display frames consist of only a single image. + */ +public class SingleFrameImageImpl implements MultiFrameImage +{ + /** + * Constructs a single frame image object. + */ + public SingleFrameImageImpl (Mirage mirage) + { + _mirage = mirage; + } + + // documentation inherited + public int getFrameCount () + { + return 1; + } + + // documentation inherited from interface + public int getWidth (int index) + { + return _mirage.getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) + { + return _mirage.getHeight(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) + { + _mirage.paint(g, x, y); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) + { + return _mirage.hitTest(x, y); + } + + /** The frame image. */ + protected Mirage _mirage; +} diff --git a/src/java/com/threerings/media/util/SingleTileImageImpl.java b/src/java/com/threerings/media/util/SingleTileImageImpl.java new file mode 100644 index 00000000..fa9a1510 --- /dev/null +++ b/src/java/com/threerings/media/util/SingleTileImageImpl.java @@ -0,0 +1,75 @@ +// +// $Id: SingleTileImageImpl.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Graphics2D; + +import com.threerings.media.tile.Tile; + +/** + * The single frame image class is a basic implementation of the {@link + * MultiFrameImage} interface intended to facilitate the creation of MFIs + * whose display frames consist of only a single tile image. + */ +public class SingleTileImageImpl implements MultiFrameImage +{ + /** + * Constructs a single frame image object. + */ + public SingleTileImageImpl (Tile tile) + { + _tile = tile; + } + + // documentation inherited + public int getFrameCount () + { + return 1; + } + + // documentation inherited from interface + public int getWidth (int index) + { + return _tile.getWidth(); + } + + // documentation inherited from interface + public int getHeight (int index) + { + return _tile.getHeight(); + } + + // documentation inherited from interface + public void paintFrame (Graphics2D g, int index, int x, int y) + { + _tile.paint(g, x, y); + } + + // documentation inherited from interface + public boolean hitTest (int index, int x, int y) + { + return _tile.hitTest(x, y); + } + + /** The frame image. */ + protected Tile _tile; +} diff --git a/src/java/com/threerings/media/util/SmoothBobblePath.java b/src/java/com/threerings/media/util/SmoothBobblePath.java new file mode 100644 index 00000000..2ba20b56 --- /dev/null +++ b/src/java/com/threerings/media/util/SmoothBobblePath.java @@ -0,0 +1,86 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import com.samskivert.util.RandomUtil; + +/** + * Bobble a Pathable smoothly. + */ +public class SmoothBobblePath extends BobblePath +{ + public SmoothBobblePath (int dx, int dy, long duration) + { + this(dx, dy, duration, 1L); + } + + public SmoothBobblePath (int dx, int dy, long duration, long updateFreq) + { + super(dx, dy, duration, updateFreq); + } + + // documentation inherited + public void init (Pathable pable, long tickstamp) + { + super.init(pable, tickstamp); + + _newx = _sx; + _newy = _sy; + _oldx = _sx; + _oldy = _sy; + } + + // documentation inherited + public boolean tick (Pathable pable, long tickStamp) + { + // see if we need to stop + if (_stopTime <= tickStamp) { + boolean updated = updatePositionTo(pable, _sy, _sy); + pable.pathCompleted(tickStamp); + return updated; + } + + // see if it's time to update the position + if (_nextMove < tickStamp) { + _oldx = _newx; + _oldy = _newy; + do { + _newx = _sx + RandomUtil.getInt(_dx * 2 + 1) - _dx; + _newy = _sy + RandomUtil.getInt(_dy * 2 + 1) - _dy; + } while (_newx == _oldx && _newy == _oldy); + + _nextMove = tickStamp + _updateFreq; + } + + float movePerc = (float)(_nextMove - tickStamp) / (float)_updateFreq; + int x = _oldx + (int)((_newx - _oldx) * movePerc); + int y = _oldy + (int)((_newy - _oldy) * movePerc); + // update the position + return updatePositionTo(pable, x, y); + } + + /** The previous position. */ + protected int _oldx, _oldy; + + /** The next position. */ + protected int _newx, _newy; +} diff --git a/src/java/com/threerings/media/util/TiledArea.java b/src/java/com/threerings/media/util/TiledArea.java new file mode 100644 index 00000000..e53af78c --- /dev/null +++ b/src/java/com/threerings/media/util/TiledArea.java @@ -0,0 +1,61 @@ +// +// $Id: TiledArea.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +/** + * A component that can be inserted into a user interface to fill a + * particular area using a {@link BackgroundTiler}. + */ +public class TiledArea extends JComponent +{ + public TiledArea (BufferedImage imgsrc) + { + this(new BackgroundTiler(imgsrc)); + } + + public TiledArea (BackgroundTiler tiler) + { + _tiler = tiler; + setOpaque(true); + } + + // documentation inherited + public void paintComponent (Graphics g) + { + super.paintComponent(g); + _tiler.paint(g, 0, 0, getWidth(), getHeight()); + } + + // documentation inherited + public Dimension getPreferredSize () + { + return new Dimension(_tiler.getNaturalWidth(), + _tiler.getNaturalHeight()); + } + + protected BackgroundTiler _tiler; +} diff --git a/src/java/com/threerings/media/util/TimeFunction.java b/src/java/com/threerings/media/util/TimeFunction.java new file mode 100644 index 00000000..3e4f75d7 --- /dev/null +++ b/src/java/com/threerings/media/util/TimeFunction.java @@ -0,0 +1,83 @@ +// +// $Id: TimeFunction.java 4191 2006-06-13 22:42:20Z ray $ + +package com.threerings.media.util; + +/** + * Used to vary a value over time where time is provided at discrete + * increments (on the frame tick) and the value is computed appropriately. + */ +public abstract class TimeFunction +{ + /** + * Every time function varies a value from some starting value to some + * ending value over some duration. The way in which it varies + * (linearly, for example) is up to the derived class. + * + *

Note: it is assumed that we will operate with + * relatively short durations such that integer arithmetic may be used + * rather than long arithmetic. + */ + public TimeFunction (int start, int end, int duration) + { + _start = start; + _end = end; + _duration = duration; + } + + /** + * Configures this function with a starting time. This method need not + * be called, and instead the first vall to {@link #getValue} will be + * used to obtain a starting time stamp. + */ + public void init (long tickStamp) + { + _startStamp = tickStamp; + } + + /** + * Called to fast forward our time stamps if we are ever paused and + * need to resume where we left off. + */ + public void fastForward (long timeDelta) + { + _startStamp += timeDelta; + } + + /** + * Returns the current value given the supplied time stamp. The value + * will be bounded to the originally supplied starting and ending + * values at times 0 (and below) and {@link #_duration} (and above) + * respectively. + */ + public int getValue (long tickStamp) + { + if (_startStamp == 0L) { + _startStamp = tickStamp; + } + + int dt = (int)(tickStamp - _startStamp); + if (dt <= 0) { + return _start; + } else if (dt >= _duration) { + return _end; + } else { + return computeValue(dt); + } + } + + /** + * This must be implemented by our derived class to compute our value + * given the specified elapsed time (in millis). + */ + protected abstract int computeValue (int dt); + + /** Our starting and ending values. */ + protected int _start, _end; + + /** The number of milliseconds over which we vary our value. */ + protected int _duration; + + /** The timestamp at which we began varying our value. */ + protected long _startStamp; +} diff --git a/src/java/com/threerings/media/util/TimedPath.java b/src/java/com/threerings/media/util/TimedPath.java new file mode 100644 index 00000000..944b0dd3 --- /dev/null +++ b/src/java/com/threerings/media/util/TimedPath.java @@ -0,0 +1,98 @@ +// +// $Id: TimedPath.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import com.threerings.media.Log; + +/** + * A base class for path implementations that endeavor to move their + * pathables along a path in a specified number of milliseconds. + */ +public abstract class TimedPath implements Path +{ + /** + * Configures the timed path with the duration in which it must + * traverse its path. + */ + public TimedPath (long duration) + { + // sanity check some things + if (duration <= 0) { + Log.warning("Requested path with illegal duration (<=0) " + + "[duration=" + duration + "]"); + Thread.dumpStack(); + duration = 1; // assume something short but non-zero + } + + _duration = duration; + } + + // documentation inherited + public void init (Pathable pable, long timestamp) + { + // give the pable a chance to perform any starting antics + pable.pathBeginning(); + + // make a note of when we started + _startStamp = timestamp; + + // we'll be ticked immediately following init() which will update + // our position to the start of our path + } + + // documentation inherited + public void fastForward (long timeDelta) + { + _startStamp += timeDelta; + } + + // documentation inherited from interface + public void wasRemoved (Pathable pable) + { + // nothing doing + } + + /** + * Generates a string representation of this instance. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + toString(buf); + return buf.append("]").toString(); + } + + /** + * An extensible method for generating a string representation of this + * instance. + */ + protected void toString (StringBuilder buf) + { + buf.append("duration=").append(_duration).append("ms"); + } + + /** The duration that we're to spend following the path. */ + protected long _duration; + + /** The time at which we started along the path. */ + protected long _startStamp; +} diff --git a/src/java/com/threerings/media/util/TrailingAverage.java b/src/java/com/threerings/media/util/TrailingAverage.java new file mode 100644 index 00000000..7e0d440b --- /dev/null +++ b/src/java/com/threerings/media/util/TrailingAverage.java @@ -0,0 +1,81 @@ +// +// $Id: TrailingAverage.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +/** + * Used to compute a trailing average of a value. + */ +public class TrailingAverage +{ + /** + * Creates a trailing average instance with the default number of + * values used to compute the average (10). + */ + public TrailingAverage () + { + this(10); + } + + /** + * Creates a trailing average instance with the specified number of + * values used to compute the average. + */ + public TrailingAverage (int history) + { + _history = new int[history]; + } + + /** + * Records a new value. + */ + public void record (int value) + { + _history[_index++%_history.length] = value; + } + + /** + * Returns the current averaged value. + */ + public int value () + { + int end = Math.min(_history.length, _index); + int value = 0; + for (int ii = 0; ii < end; ii++) { + value += _history[ii]; + } + return (end > 0) ? (value/end) : 0; + } + + /** + * Returns the current trailing average value as a string. + */ + public String toString () + { + return Integer.toString(value()); + } + + /** The history of values. */ + protected int[] _history; + + /** The index where we will next record a value. */ + protected int _index; +} diff --git a/src/java/com/threerings/miso/Log.java b/src/java/com/threerings/miso/Log.java new file mode 100644 index 00000000..c0bcce5f --- /dev/null +++ b/src/java/com/threerings/miso/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso; + +/** + * A placeholder class that contains a reference to the log object used by + * the miso package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("miso"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/miso/MisoConfig.java b/src/java/com/threerings/miso/MisoConfig.java new file mode 100644 index 00000000..f724f11f --- /dev/null +++ b/src/java/com/threerings/miso/MisoConfig.java @@ -0,0 +1,61 @@ +// +// $Id: MisoConfig.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso; + +import com.samskivert.util.Config; + +import com.threerings.miso.util.MisoSceneMetrics; + +/** + * Provides access to the Miso configuration. + */ +public class MisoConfig +{ + /** Provides access to configuration data for this package. */ + public static Config config = new Config("rsrc/config/miso/miso"); + + /** + * Creates scene metrics with information obtained from the deployed + * config file. + */ + public static MisoSceneMetrics getSceneMetrics () + { + return new MisoSceneMetrics( + config.getValue(TILE_WIDTH_KEY, DEF_TILE_WIDTH), + config.getValue(TILE_HEIGHT_KEY, DEF_TILE_HEIGHT), + config.getValue(FINE_GRAN_KEY, DEF_FINE_GRAN)); + } + + /** The config key for tile width in pixels. */ + protected static final String TILE_WIDTH_KEY = "tile_width"; + + /** The config key for tile height in pixels. */ + protected static final String TILE_HEIGHT_KEY = "tile_height"; + + /** The config key for tile fine coordinate granularity. */ + protected static final String FINE_GRAN_KEY = "fine_granularity"; + + /** Default scene view parameters. */ + protected static final int DEF_TILE_WIDTH = 64; + protected static final int DEF_TILE_HEIGHT = 48; + protected static final int DEF_FINE_GRAN = 4; +} diff --git a/src/java/com/threerings/miso/MisoPrefs.java b/src/java/com/threerings/miso/MisoPrefs.java new file mode 100644 index 00000000..0ba85f64 --- /dev/null +++ b/src/java/com/threerings/miso/MisoPrefs.java @@ -0,0 +1,35 @@ +// +// $Id: MisoPrefs.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso; + +import com.samskivert.util.Config; + +/** + * Provides access to runtime configuration parameters for the miso + * package and its subpackages. + */ +public class MisoPrefs +{ + /** Used to load our preferences from a properties file and map them + * to the persistent Java preferences repository. */ + public static Config config = new Config("rsrc/config/miso"); +} diff --git a/src/java/com/threerings/miso/client/DirtyItemList.java b/src/java/com/threerings/miso/client/DirtyItemList.java new file mode 100644 index 00000000..f58b01e0 --- /dev/null +++ b/src/java/com/threerings/miso/client/DirtyItemList.java @@ -0,0 +1,680 @@ +// +// $Id: DirtyItemList.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Comparator; + +import com.samskivert.util.SortableArrayList; + +import com.threerings.media.Log; +import com.threerings.media.sprite.Sprite; +import com.threerings.media.tile.ObjectTile; + +/** + * The dirty item list keeps track of dirty sprites and object tiles + * in a scene. + */ +public class DirtyItemList +{ + /** + * Creates a dirt item list that will handle dirty items for the + * specified view. + */ + public DirtyItemList () + { + } + + /** + * Appends the dirty sprite at the given coordinates to the dirty item + * list. + * + * @param sprite the dirty sprite itself. + * @param tx the sprite's x tile position. + * @param ty the sprite's y tile position. + */ + public void appendDirtySprite (Sprite sprite, int tx, int ty) + { + DirtyItem item = getDirtyItem(); + item.init(sprite, tx, ty); + _items.add(item); + } + + /** + * Appends the dirty object tile at the given coordinates to the dirty + * item list. + * + * @param scobj the scene object that is dirty. + */ + public void appendDirtyObject (SceneObject scobj) + { + DirtyItem item = getDirtyItem(); + item.init(scobj, scobj.info.x, scobj.info.y); + _items.add(item); + } + + /** + * Returns the dirty item at the given index in the list. + */ + public DirtyItem get (int idx) + { + return (DirtyItem)_items.get(idx); + } + + /** + * Returns an array of the {@link DirtyItem} objects in the list + * sorted in proper rendering order. + */ + public void sort () + { + int size = size(); + + if (DEBUG_SORT) { + Log.info("Sorting dirty item list [size=" + size + "]."); + } + + // if we've only got one item, we need to do no sorting + if (size > 1) { + // get items sorted by increasing origin x-coordinate + _xitems.addAll(_items); + _xitems.sort(ORIGIN_X_COMP); + if (DEBUG_SORT) { + Log.info("Sorted by x-origin " + + "[items=" + toString(_xitems) + "]."); + } + + // get items sorted by increasing origin y-coordinate + _yitems.addAll(_items); + _yitems.sort(ORIGIN_Y_COMP); + if (DEBUG_SORT) { + Log.info("Sorted by y-origin " + + "[items=" + toString(_yitems) + "]."); + } + + // sort the items according to the depth of the rear-most tile + _ditems.addAll(_items); + _ditems.sort(REAR_DEPTH_COMP); + + // now insertion sort the items from back to front into the + // render-sorted array + _items.clear(); + POS_LOOP: + for (int ii = 0; ii < size; ii++) { + DirtyItem item = (DirtyItem)_ditems.get(ii); + for (int rr = _items.size()-1; rr >= 0; rr--) { + DirtyItem pitem = (DirtyItem)_items.get(rr); + // if we render in front of this item, insert + // ourselves immediately following it + if (_rcomp.compare(item, pitem) > 0) { + _items.add(rr+1, item); + continue POS_LOOP; + } + } + // we don't render in front of anyone, so we go at the + // front of the list + _items.add(0, item); + } + + // clear out our temporary arrays + _xitems.clear(); + _yitems.clear(); + _ditems.clear(); + } + + if (DEBUG_SORT) { + Log.info("Sorted for render [items=" + toString(_items) + "]."); + for (int ii = 0, ll = _items.size()-1; ii < ll; ii++) { + DirtyItem a = (DirtyItem)_items.get(ii); + DirtyItem b = (DirtyItem)_items.get(ii+1); + if (_rcomp.compare(a, b) > 0) { + Log.warning("Invalid ordering [a=" + a + ", b=" + b + "]."); + } + } + } + } + + /** + * Paints all the dirty items in this list using the supplied graphics + * context. The items are removed from the dirty list after being + * painted and the dirty list ends up empty. + */ + public void paintAndClear (Graphics2D gfx) + { + int icount = _items.size(); + for (int ii = 0; ii < icount; ii++) { + DirtyItem item = (DirtyItem)_items.get(ii); + item.paint(gfx); + item.clear(); + _freelist.add(item); + } + _items.clear(); + } + + /** + * Clears out any items that were in this list. + */ + public void clear () + { + for (int icount = _items.size(); icount > 0; icount--) { + DirtyItem item = (DirtyItem)_items.remove(0); + item.clear(); + _freelist.add(item); + } + } + + /** + * Returns the number of items in the dirty item list. + */ + public int size () + { + return _items.size(); + } + + /** + * Obtains a new dirty item instance, reusing an old one if possible + * or creating a new one otherwise. + */ + protected DirtyItem getDirtyItem () + { + if (_freelist.size() > 0) { + return (DirtyItem)_freelist.remove(0); + } else { + return new DirtyItem(); + } + } + + /** + * Returns an abbreviated string representation of the given dirty + * item describing only its origin coordinates and render priority. + * Intended for debugging purposes. + */ + protected static String toString (DirtyItem a) + { + StringBuilder buf = new StringBuilder("["); + toString(buf, a); + return buf.append("]").toString(); + } + + /** + * Returns an abbreviated string representation of the two given dirty + * items. See {@link #toString(DirtyItem)}. + */ + protected static String toString (DirtyItem a, DirtyItem b) + { + StringBuilder buf = new StringBuilder("["); + toString(buf, a); + toString(buf, b); + return buf.append("]").toString(); + } + + /** + * Returns an abbreviated string representation of the given dirty + * items. See {@link #toString(DirtyItem)}. + */ + protected static String toString (SortableArrayList items) + { + StringBuilder buf = new StringBuilder(); + buf.append("["); + for (int ii = 0; ii < items.size(); ii++) { + DirtyItem item = (DirtyItem)items.get(ii); + toString(buf, item); + if (ii < (items.size() - 1)) { + buf.append(", "); + } + } + return buf.append("]").toString(); + } + + /** Helper function for {@link #toString(DirtyItem)}. */ + protected static void toString (StringBuilder buf, DirtyItem item) + { + buf.append("(o:+").append(item.ox).append("+").append(item.oy); + buf.append(" p:").append(item.getRenderPriority()).append(")"); + } + + /** + * A class to hold the items inserted in the dirty list along with + * all of the information necessary to render their dirty regions + * to the target graphics context when the time comes to do so. + */ + public class DirtyItem + { + /** The dirtied object; one of either a sprite or an object tile. */ + public Object obj; + + /** The origin tile coordinates. */ + public int ox, oy; + + /** The leftmost tile coordinates. */ + public int lx, ly; + + /** The rightmost tile coordinates. */ + public int rx, ry; + + /** + * Initializes a dirty item. + */ + public void init (Object obj, int x, int y) + { + this.obj = obj; + this.ox = x; + this.oy = y; + + // calculate the item's leftmost and rightmost tiles; note + // that sprites occupy only a single tile, so leftmost and + // rightmost tiles are equivalent + lx = rx = ox; + ly = ry = oy; + if (obj instanceof SceneObject) { + ObjectTile tile = ((SceneObject)obj).tile; + lx -= (tile.getBaseWidth() - 1); + ry -= (tile.getBaseHeight() - 1); + } + } + + /** + * Paints the dirty item to the given graphics context. Only + * the portion of the item that falls within the given dirty + * rectangle is actually drawn. + */ + public void paint (Graphics2D gfx) + { + if (obj instanceof Sprite) { + ((Sprite)obj).paint(gfx); + } else { + ((SceneObject)obj).paint(gfx); + } + } + + /** + * Returns the "depth" of our rear-most tile. + */ + public int getRearDepth () + { + return ry + lx; + } + + /** + * Returns the render priority for this dirty item. It will be + * zero unless this is a display object which may have a custom + * render priority. + */ + public int getRenderPriority () + { + if (obj instanceof SceneObject) { + return ((SceneObject)obj).getPriority(); + } else { + return 0; + } + } + + /** + * Releases all references held by this dirty item so that it + * doesn't inadvertently hold on to any objects while waiting to + * be reused. + */ + public void clear () + { + obj = null; + } + + // documentation inherited + public boolean equals (Object other) + { + // we're never equal to something that's not our kind + if (!(other instanceof DirtyItem)) { + return false; + } + + // sprites are equivalent if they're the same sprite + DirtyItem b = (DirtyItem)other; + return obj.equals(b.obj); + } + + // documentation inherited + public int hashCode () + { + return obj.hashCode(); + } + + /** + * Returns a string representation of the dirty item. + */ + public String toString () + { + StringBuilder buf = new StringBuilder(); + buf.append("[obj=").append(obj); + buf.append(", ox=").append(ox); + buf.append(", oy=").append(oy); + buf.append(", lx=").append(lx); + buf.append(", ly=").append(ly); + buf.append(", rx=").append(rx); + buf.append(", ry=").append(ry); + return buf.append("]").toString(); + } + } + + /** + * A comparator class for use in sorting dirty items in ascending + * origin x- or y-axis coordinate order. + */ + protected static class OriginComparator implements Comparator + { + /** + * Constructs an origin comparator that sorts dirty items in + * ascending order based on their origin coordinate on the given + * axis. + */ + public OriginComparator (int axis) + { + _axis = axis; + } + + // documentation inherited + public int compare (Object a, Object b) + { + DirtyItem da = (DirtyItem)a; + DirtyItem db = (DirtyItem)b; + + // if they don't overlap, sort them normally + if (_axis == X_AXIS) { + if (da.ox != db.ox) { + return da.ox - db.ox; + } + } else { + if (da.oy != db.oy) { + return da.oy - db.oy; + } + } + + // if they do overlap, incorporate render priority; assume + // non-display objects have a render priority of zero + return da.getRenderPriority() - db.getRenderPriority(); + } + + /** The axis this comparator sorts on. */ + protected int _axis; + } + + /** + * A comparator class for use in sorting the dirty sprites and + * objects in a scene in ascending x- and y-coordinate order + * suitable for rendering in the isometric view with proper visual + * results. + */ + protected class RenderComparator implements Comparator + { + // documentation inherited + public int compare (Object a, Object b) + { + DirtyItem da = (DirtyItem)a; + DirtyItem db = (DirtyItem)b; + + // if the two objects are scene objects and they overlap, we + // compare them solely based on their human assigned priority + if ((da.obj instanceof SceneObject) && + (db.obj instanceof SceneObject)) { + SceneObject soa = (SceneObject)da.obj; + SceneObject sob = (SceneObject)db.obj; + if (soa.objectFootprintOverlaps(sob)) { + int result = soa.getPriority() - sob.getPriority(); + if (DEBUG_COMPARE) { + String items = DirtyItemList.toString(da, db); + Log.info("compare: overlapping [result=" + result + + ", items=" + items + "]."); + } + return result; + } + } + + // check for partitioning objects on the y-axis + int result = comparePartitioned(Y_AXIS, da, db); + if (result != 0) { + if (DEBUG_COMPARE) { + String items = DirtyItemList.toString(da, db); + Log.info("compare: Y-partitioned " + + "[result=" + result + ", items=" + items + "]."); + } + return result; + } + + // check for partitioning objects on the x-axis + result = comparePartitioned(X_AXIS, da, db); + if (result != 0) { + if (DEBUG_COMPARE) { + String items = DirtyItemList.toString(da, db); + Log.info("compare: X-partitioned " + + "[result=" + result + ", items=" + items + "]."); + } + return result; + } + + // use normal iso-ordering check + result = compareNonPartitioned(da, db); + if (DEBUG_COMPARE) { + String items = DirtyItemList.toString(da, db); + Log.info("compare: non-partitioned " + + "[result=" + result + ", items=" + items + "]."); + } + + return result; + } + + /** + * Returns whether two dirty items have a partitioning object + * between them on the given axis. + */ + protected int comparePartitioned ( + int axis, DirtyItem da, DirtyItem db) + { + // prepare for the partitioning check + SortableArrayList sitems; + Comparator comp; + boolean swapped = false; + switch (axis) { + case X_AXIS: + if (da.ox == db.ox) { + // can't be partitioned if there's no space between + return 0; + } + + // order items for proper comparison + if (da.ox > db.ox) { + DirtyItem temp = da; + da = db; + db = temp; + swapped = true; + } + + // use the axis-specific sorted array + sitems = _xitems; + comp = ORIGIN_X_COMP; + break; + + case Y_AXIS: + default: + if (da.oy == db.oy) { + // can't be partitioned if there's no space between + return 0; + } + + // order items for proper comparison + if (da.oy > db.oy) { + DirtyItem temp = da; + da = db; + db = temp; + swapped = true; + } + + // use the axis-specific sorted array + sitems = _yitems; + comp = ORIGIN_Y_COMP; + break; + } + + // get the bounding item indices and the number of + // potentially-partitioning dirty items + int aidx = sitems.binarySearch(da, comp); + int bidx = sitems.binarySearch(db, comp); + int size = bidx - aidx - 1; + + // check each potentially partitioning item + int startidx = aidx + 1, endidx = startidx + size; + for (int pidx = startidx; pidx < endidx; pidx++) { + DirtyItem dp = (DirtyItem)sitems.get(pidx); + if (dp.obj instanceof Sprite) { + // sprites can't partition things + continue; + } else if ((dp.obj == da.obj) || + (dp.obj == db.obj)) { + // can't be partitioned by ourselves + continue; + } + + // perform the actual partition check for this object + switch (axis) { + case X_AXIS: + if (dp.ly >= da.ry && + dp.ry <= db.ly && + dp.lx >= da.rx && + dp.rx <= db.lx) { + return (swapped) ? 1 : -1; + } + + case Y_AXIS: + default: + if (dp.lx <= db.ox && + dp.rx >= da.lx && + dp.ry >= da.oy && + dp.oy <= db.ry) { + return (swapped) ? 1 : -1; + } + } + } + + // no partitioning object found + return 0; + } + + /** + * Compares the two dirty items assuming there are no partitioning + * objects between them. + */ + protected int compareNonPartitioned (DirtyItem da, DirtyItem db) + { + if (da.ox == db.ox && + da.oy == db.oy) { + if (da.equals(db)) { + // render level is equal if we're the same sprite + // or an object at the same location + return 0; + } + + boolean aIsSprite = (da.obj instanceof Sprite); + boolean bIsSprite = (db.obj instanceof Sprite); + + if (aIsSprite && bIsSprite) { + Sprite as = (Sprite)da.obj, bs = (Sprite)db.obj; + // we're comparing two sprites co-existing on the same + // tile, first check their render order + int rocomp = as.getRenderOrder() - bs.getRenderOrder(); + if (rocomp != 0) { + return rocomp; + } + // next sort them by y-position + int ydiff = as.getY() - bs.getY(); + if (ydiff != 0) { + return ydiff; + } + // if they're at the same height, just use hashCode() + // to establish a consistent arbitrary ordering + return (as.hashCode() - bs.hashCode()); + + // otherwise, always put a sprite on top of a non-sprite + } else if (aIsSprite) { + return 1; + + } else if (bIsSprite) { + return -1; + } + } + + // otherwise use a consistent ordering for non-overlappers; + // see narya/docs/miso/render_sort_diagram.png for more info + if (db.lx <= da.ox && db.ry <= da.oy) { + return 1; + } else if (db.rx >= da.lx && db.ly >= da.ry) { + return -1; + } else { + return da.oy - db.oy; + } + } + } + + /** The list of dirty items. */ + protected SortableArrayList _items = new SortableArrayList(); + + /** The list of dirty items sorted by x-position. */ + protected SortableArrayList _xitems = new SortableArrayList(); + + /** The list of dirty items sorted by y-position. */ + protected SortableArrayList _yitems = new SortableArrayList(); + + /** The list of dirty items sorted by rear-depth. */ + protected SortableArrayList _ditems = new SortableArrayList(); + + /** The render comparator we'll use for our final, magical sort. */ + protected Comparator _rcomp = new RenderComparator(); + + /** Unused dirty items. */ + protected ArrayList _freelist = new ArrayList(); + + /** Whether to log debug info when comparing pairs of dirty items. */ + protected static final boolean DEBUG_COMPARE = false; + + /** Whether to log debug info for the main dirty item sorting algorithm. */ + protected static final boolean DEBUG_SORT = false; + + /** Constants used to denote axis sorting constraints. */ + protected static final int X_AXIS = 0; + protected static final int Y_AXIS = 1; + + /** The comparator used to sort dirty items in ascending origin + * x-coordinate order. */ + protected static final Comparator ORIGIN_X_COMP = + new OriginComparator(X_AXIS); + + /** The comparator used to sort dirty items in ascending origin + * y-coordinate order. */ + protected static final Comparator ORIGIN_Y_COMP = + new OriginComparator(Y_AXIS); + + /** The comparator used to sort dirty items in ascending "rear-depth" + * order. */ + protected static final Comparator REAR_DEPTH_COMP = new Comparator() { + public int compare (Object o1, Object o2) { + return (((DirtyItem)o1).getRearDepth() - + ((DirtyItem)o2).getRearDepth()); + } + }; +} diff --git a/src/java/com/threerings/miso/client/MisoScenePanel.java b/src/java/com/threerings/miso/client/MisoScenePanel.java new file mode 100644 index 00000000..193e6dda --- /dev/null +++ b/src/java/com/threerings/miso/client/MisoScenePanel.java @@ -0,0 +1,1735 @@ +// +// $Id: MisoScenePanel.java 4007 2006-04-10 08:59:30Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Stroke; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.Icon; +import javax.swing.JFrame; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import com.samskivert.swing.Controller; +import com.samskivert.swing.RadialMenu; +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.swing.event.CommandEvent; +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +import com.threerings.media.VirtualMediaPanel; +import com.threerings.media.sprite.Sprite; +import com.threerings.media.tile.Tile; +import com.threerings.media.tile.TileManager; +import com.threerings.media.tile.TileSet; +import com.threerings.media.util.AStarPathUtil; +import com.threerings.media.util.MathUtil; +import com.threerings.media.util.Path; + +import com.threerings.miso.Log; +import com.threerings.miso.MisoPrefs; +import com.threerings.miso.client.DirtyItemList.DirtyItem; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.tile.BaseTile; +import com.threerings.miso.util.MisoContext; +import com.threerings.miso.util.MisoSceneMetrics; +import com.threerings.miso.util.MisoUtil; + +/** + * Renders a Miso scene for all to see. + */ +public class MisoScenePanel extends VirtualMediaPanel + implements MouseListener, MouseMotionListener, AStarPathUtil.TraversalPred, + RadialMenu.Host +{ + /** Show flag that indicates we should show all tips. */ + public static final int SHOW_TIPS = (1 << 0); + + /** + * Creates a blank miso scene display. Configure it with a scene model + * via {@link #setSceneModel} to cause it to display something. + */ + public MisoScenePanel (MisoContext ctx, MisoSceneMetrics metrics) + { + super(ctx.getFrameManager()); + _ctx = ctx; + _metrics = metrics; + + // set ourselves up + setOpaque(true); + addMouseListener(this); + addMouseMotionListener(this); + + // handy rectangle + _tbounds = new Rectangle(0, 0, _metrics.tilewid, _metrics.tilehei); + + // create the resolver if it's not already around + if (_resolver == null) { + _resolver = new SceneBlockResolver(); + _resolver.setDaemon(true); + _resolver.setPriority(Thread.MIN_PRIORITY); + _resolver.start(); + } + } + + /** + * Configures this display with a scene model which will immediately + * be resolved and displayed. + */ + public void setSceneModel (MisoSceneModel model) + { + _model = model; + + // clear out old blocks and objects + clearScene(); + + centerOnTile(0, 0); + if (isShowing()) { + rethink(); + _remgr.invalidateRegion(_vbounds); + } + } + + /** + * Clears out our old scene business. + */ + protected void clearScene () + { + _blocks.clear(); + _vizobjs.clear(); + _masks.clear(); + if (_dpanel != null) { + _dpanel.newScene(); + } + } + + /** + * Completely invalidates our current resolved scene and re-resolves + * it from the ground up. + */ + public void refreshScene () + { + clearScene(); + rethink(); + _delayRepaint = true; + _remgr.invalidateRegion(_vbounds); + } + + /** + * Moves the scene such that the specified tile is in the center. + */ + public void centerOnTile (int tx, int ty) + { + Rectangle trect = MisoUtil.getTilePolygon(_metrics, tx, ty).getBounds(); + int nx = trect.x + trect.width/2 - _vbounds.width/2; + int ny = trect.y + trect.height/2 - _vbounds.height/2; +// Log.info("Centering on t:" + StringUtil.coordsToString(tx, ty) + +// " b:" + StringUtil.toString(trect) + +// " vb: " + StringUtil.toString(_vbounds) + +// ", n:" + StringUtil.coordsToString(nx, ny) + "."); + setViewLocation(nx, ny); + } + + /** + * Returns the scene model being displayed by this panel. Do + * not modify! + */ + public MisoSceneModel getSceneModel () + { + return _model; + } + + /** + * Returns the scene metrics in use by this panel. Do not + * modify! + */ + public MisoSceneMetrics getSceneMetrics () + { + return _metrics; + } + + /** + * Set whether or not to highlight object tooltips (and potentially + * other scene entities). + */ + public void setShowFlags (int flags, boolean on) + { + int oldshow = _showFlags; + + if (on) { + _showFlags |= flags; + } else { + _showFlags &= ~flags; + } + + if (oldshow != _showFlags) { + showFlagsDidChange(oldshow); + } + } + + /** + * Check to see if the specified show flag is on. + */ + public boolean checkShowFlag (int flag) + { + return (0 != (flag & _showFlags)); + } + + /** + * Called when our show flags have changed. + */ + protected void showFlagsDidChange (int oldflags) + { + if ((oldflags & SHOW_TIPS) != (_showFlags & SHOW_TIPS)) { + for (Iterator iter = _tips.values().iterator(); iter.hasNext(); ) { + dirtyTip((SceneObjectTip)iter.next()); + } + } + } + + /** + * Returns the top-most object over which the mouse is hovering; this + * may be a sprite or a {@link SceneObject}. + */ + public Object getHoverObject () + { + return _hobject; + } + + /** + * Returns the tile coordinates of the tile over which the mouse is + * hovering. + */ + public Point getHoverCoords () + { + return _hcoords; + } + + /** + * Returns an iterator over all resolved {@link SceneBlock} instances. + */ + public Iterator enumerateResolvedBlocks () + { + return _blocks.values().iterator(); + } + + /** + * Returns the resolved block that contains the specified tile + * coordinate or null if no block is resolved for that coordinate. + */ + public SceneBlock getBlock (int tx, int ty) + { + int bx = MathUtil.floorDiv(tx, _metrics.blockwid); + int by = MathUtil.floorDiv(ty, _metrics.blockhei); + return (SceneBlock)_blocks.get(compose(bx, by)); + } + + /** + * Computes a path for the specified sprite to the specified tile + * coordinates. + * + * @param loose if true, an approximate path will be returned if a + * complete path cannot be located. This path will navigate the sprite + * "legally" as far as possible and then walk the sprite in a straight + * line to its final destination. This is generally only useful if the + * the path goes "off screen". + */ + public Path getPath (Sprite sprite, int x, int y, boolean loose) + { + // sanity check + if (sprite == null) { + throw new IllegalArgumentException( + "Can't get path for null sprite [x=" + x + ", y=" + y + "."); + } + + // get the destination tile coordinates + Point src = MisoUtil.screenToTile( + _metrics, sprite.getX(), sprite.getY(), new Point()); + Point dest = MisoUtil.screenToTile(_metrics, x, y, new Point()); + + // compute our longest path from the screen size + int longestPath = 3 * (getWidth() / _metrics.tilewid); + + // get a reasonable tile path through the scene + long start = System.currentTimeMillis(); + List points = AStarPathUtil.getPath( + this, sprite, longestPath, src.x, src.y, dest.x, dest.y, loose); + long duration = System.currentTimeMillis() - start; + + // sanity check the number of nodes searched so that we can keep + // an eye out for bogosity + if (duration > 500L) { + int considered = AStarPathUtil.getConsidered(); + Log.warning("Considered " + considered + " nodes for path from " + + StringUtil.toString(src) + " to " + + StringUtil.toString(dest) + + " [duration=" + duration + "]."); + } + + // construct a path object to guide the sprite on its merry way + return (points == null) ? null : + new TilePath(_metrics, sprite, points, x, y); + } + + /** + * Converts the supplied full coordinates to screen coordinates. + */ + public Point getScreenCoords (int x, int y) + { + return MisoUtil.fullToScreen(_metrics, x, y, new Point()); + } + + /** + * Coverts the supplied screen coordinates to full coordinates. + */ + public Point getFullCoords (int x, int y) + { + return MisoUtil.screenToFull(_metrics, x, y, new Point()); + } + + /** + * Coverts the supplied screen coordinates to tile coordinates. + */ + public Point getTileCoords (int x, int y) + { + return MisoUtil.screenToTile(_metrics, x, y, new Point()); + } + + /** + * Clears any radial menu being displayed. + */ + public void clearRadialMenu () + { + if (_activeMenu != null) { + _activeMenu.deactivate(); + } + } + + /** + * Reports the memory usage of the resolved tiles in the current scene + * block. + */ + public void reportMemoryUsage () + { + HashMap base = new HashMap(); + HashSet fringe = new HashSet(); + HashMap object = new HashMap(); + long[] usage = new long[3]; + for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) { + SceneBlock block = (SceneBlock)iter.next(); + block.computeMemoryUsage(base, fringe, object, usage); + } + Log.info("Scene tile memory usage " + + "[scene=" + StringUtil.shortClassName(this) + + ", base=" + base.size() + "->" + (usage[0] / 1024) + "k" + + ", fringe=" + fringe.size() + "->" + (usage[1] / 1024) + "k" + + ", fmasks=" + _masks.size() + ", obj=" + object.size() + + "->" + (usage[2] / 1024) + "k" + "]."); + } + + // documentation inherited + public void addNotify () + { + super.addNotify(); + + if (_resolveDebug.getValue()) { + _dpanel = new ResolutionView(this); + _dframe = new JFrame("Scene block resolver"); + _dframe.setContentPane(_dpanel); + _dframe.pack(); + _dframe.setVisible(true); + } + } + + // documentation inherited + public void removeNotify () + { + super.removeNotify(); + + if (_dpanel != null) { + _dframe.dispose(); + _dpanel = null; + _dframe = null; + } + } + + // documentation inherited from interface + public void mouseClicked (MouseEvent e) + { + // nothing doing + } + + // documentation inherited from interface + public void mousePressed (MouseEvent e) + { + // ignore mouse presses if we're not responsive + if (!isResponsive()) { + return; + } + + if (e.getButton() == MouseEvent.BUTTON1) { + if (_hobject instanceof Sprite) { + handleSpritePressed((Sprite)_hobject, e.getX(), e.getY()); + return; + } else if (_hobject instanceof SceneObject) { + handleObjectPressed((SceneObject)_hobject, e.getX(), e.getY()); + return; + } + } + // if not button1, or _hobject not Sprite or SceneObject... + handleMousePressed(_hobject, e); + } + + /** + * Programmatically "click" a scene object. This results in a call to + * {@link #handleObjectPressed} with click coordinates in the center + * of the object. + */ + public void pressObject (SceneObject scobj) + { + int px = scobj.bounds.x + scobj.bounds.width/2; + int py = scobj.bounds.y + scobj.bounds.height/2; + handleObjectPressed(scobj, px, py); + } + + /** + * Called when the user presses the mouse button over a sprite. + */ + protected void handleSpritePressed (Sprite sprite, int mx, int my) + { + } + + /** + * Called when the user presses the mouse button over an object. + */ + protected void handleObjectPressed (final SceneObject scobj, int mx, int my) + { + String action = scobj.info.action; + final ObjectActionHandler handler = ObjectActionHandler.lookup(action); + + // if there's no handler, just fire the action immediately + if (handler == null) { + fireObjectAction(null, scobj, new SceneObjectActionEvent( + this, 0, action, 0, scobj)); + return; + } + + // if the action's not allowed, pretend like we handled it + if (!handler.actionAllowed(action)) { + return; + } + + // if there's no menu for this object, fire the action immediately + RadialMenu menu = handler.handlePressed(scobj); + if (menu == null) { + fireObjectAction(handler, scobj, new SceneObjectActionEvent( + this, 0, action, 0, scobj)); + return; + } + + // make the menu surround the clicked object, but with consistent size + Rectangle mbounds = getRadialMenuBounds(scobj); + + _activeMenu = menu; + _activeMenu.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent e) { + if (e instanceof CommandEvent) { + fireObjectAction(handler, scobj, e); + } else { + SceneObjectActionEvent event = new SceneObjectActionEvent( + e.getSource(), e.getID(), e.getActionCommand(), + e.getModifiers(), scobj); + fireObjectAction(handler, scobj, event); + } + } + }); + _activeMenu.activate(this, mbounds, scobj); + } + + /** + * Returns an appropriate set of menu bounds for the specified object. + * Returns a rectangle of the size specified by + * {@link #getObjectRadialSize} centered around the object. + */ + protected Rectangle getRadialMenuBounds (SceneObject scobj) + { + Rectangle mbounds = new Rectangle(scobj.bounds); + Dimension radbox = getObjectRadialSize(); + if (mbounds.width != radbox.width) { + mbounds.x += (mbounds.width-radbox.width)/2; + mbounds.width = radbox.width; + } + if (mbounds.height != radbox.height) { + mbounds.y += (mbounds.height-radbox.height)/2; + mbounds.height = radbox.height; + } + return mbounds; + } + + /** + * Returns the size of the rectangle around which we create an + * object's radial menu. The default is a sensible size, but derived + * classes may wish to tune the value to make their menus lay out in a + * more aestetically pleasing manner. + */ + protected Dimension getObjectRadialSize () + { + return DEF_RADIAL_RECT; + } + + /** + * Called when an object or object menu item has been clicked. + */ + protected void fireObjectAction ( + ObjectActionHandler handler, SceneObject scobj, ActionEvent event) + { + if (handler == null) { + Controller.postAction(event); + } else { + handler.handleAction(scobj, event); + } + } + + /** + * Called when the mouse is pressed over an unknown or non-existent + * hover object. + * + * @param hobject the hover object at the time of the mouse press or + * null if no hover object is active. + * + * @return true if the mouse press was handled, false if not. + */ + protected boolean handleMousePressed (Object hobject, MouseEvent event) + { + return false; + } + + // documentation inherited from interface + public void mouseReleased (MouseEvent e) + { + // nothing doing; everything is handled on pressed + } + + // documentation inherited from interface + public void mouseEntered (MouseEvent e) + { + // nothing doing + } + + // documentation inherited from interface + public void mouseExited (MouseEvent e) + { + // clear the highlight tracking data + _hcoords.setLocation(-1, -1); + changeHoverObject(null); + _remgr.invalidateRegion(_vbounds); + } + + // documentation inherited from interface + public void mouseDragged (MouseEvent e) + { + // nothing doing + } + + // documentation inherited from interface + public void mouseMoved (MouseEvent e) + { + int x = e.getX(), y = e.getY(); + + // update the mouse's tile coordinates + updateTileCoords(x, y, _hcoords); + + // stop now if we're not responsive + if (!isResponsive()) { + return; + } + + // give derived classes a chance to start with a hover object + Object hobject = computeOverHover(x, y); + + // if they came up with nothing, compute the list of objects over + // which the mouse is hovering + if (hobject == null) { + // start with the sprites that contain the point + _spritemgr.getHitSprites(_hitSprites, x, y); + int hslen = _hitSprites.size(); + for (int i = 0; i < hslen; i++) { + Sprite sprite = (Sprite)_hitSprites.get(i); + appendDirtySprite(_hitList, sprite); + } + + // add the object tiles that contain the point + getHitObjects(_hitList, x, y); + + // sort the list of hit items by rendering order + _hitList.sort(); + + // the last element in the array is what we want (assuming + // there are any items in the array) + int icount = _hitList.size(); + if (icount > 0) { + DirtyItem item = (DirtyItem)_hitList.get(icount-1); + hobject = item.obj; + } + + // clear out the hitlists + _hitList.clear(); + _hitSprites.clear(); + } + + // if the user isn't hovering over a sprite or object with an + // action, allow derived classes to provide some other hover + if (hobject == null) { + hobject = computeUnderHover(x, y); + } + + changeHoverObject(hobject); + } + + /** + * Gives derived classes a chance to compute a hover object that takes + * precedence over sprites and actionable objects. If this method + * returns non-null, no sprite or object hover calculations will be + * performed and the object returned will become the new hover object. + */ + protected Object computeOverHover (int mx, int my) + { + return null; + } + + /** + * Gives derived classes a chance to compute a hover object that is + * used if the mouse is not hovering over a sprite or actionable + * object. If this method is called, it means that there are no + * sprites or objects under the mouse. Thus if it returns non-null, + * the object returned will become the new hover object. + */ + protected Object computeUnderHover (int mx, int my) + { + return null; + } + + // documentation inherited + public boolean canTraverse (Object traverser, int tx, int ty) + { + SceneBlock block = getBlock(tx, ty); + return (block == null) ? canTraverseUnresolved(traverser, tx, ty) : + block.canTraverse(traverser, tx, ty); + } + + /** + * Derived classes can control whether or not we consider unresolved + * tiles to be traversable or not. + */ + protected boolean canTraverseUnresolved (Object traverser, int tx, int ty) + { + return false; + } + + // documentation inherited from interface + public Rectangle getViewBounds () + { + return _vbounds; + } + + // documentation inherited from interface + public Component getComponent () + { + return this; + } + + // documentation inherited from interface + public void repaintRect (int x, int y, int width, int height) + { + // translate back into view coordinates + x -= _vbounds.x; + y -= _vbounds.y; + repaint(x, y, width, height); + } + + // documentation inherited from interface + public void menuDeactivated (RadialMenu menu) + { + _activeMenu = null; + } + + // documentation inherited + public void setBounds (int x, int y, int width, int height) + { + super.setBounds(x, y, width, height); + + // if we change size... + if (width != _rsize.width || height != _rsize.height) { + // ...adjust our view location to preserve the center of the + // screen... + int dx = (_rsize.width-width)/2, dy = (_rsize.height-height)/2; +// Log.info("Adjusting offset " + +// "rsize:" + StringUtil.toString(_rsize) + +// " nsize:" + width + "x" + height + +// " vb:" + StringUtil.toString(_vbounds) + +// " d:" + StringUtil.coordsToString(dx, dy) + "."); + setViewLocation(_nx+dx, _ny+dy); + _rsize.setSize(width, height); + + // ...and force a rethink on the next tick + _ulpos = null; + } + } + + // documentation inherited + protected void viewLocationDidChange (int dx, int dy) + { + super.viewLocationDidChange(dx, dy); + + // compute the tile coordinates of our upper left screen + // coordinate and request a rethink if they've changed + MisoUtil.screenToTile(_metrics, _vbounds.x, _vbounds.y, _tcoords); + if (_ulpos == null || !_tcoords.equals(_ulpos)) { + // if this is a forced rethink (_ulpos is null), we might + // delay paint as a result of it, but only if we queue up + // blocks for resolution in our rethink + boolean mightDelayPaint = false; + if (_ulpos == null) { + _ulpos = new Point(); + mightDelayPaint = true; + } + _ulpos.setLocation(_tcoords); + if (rethink() > 0) { + _delayRepaint = mightDelayPaint; + Log.info("Delaying repaint... " + + "[need=" + _visiBlocks.size() + + ", of=" + _pendingBlocks + + ", view=" + StringUtil.toString(_vbounds) + "]."); + } + } + } + + /** + * Derived classes can override this method and provide a colorizer + * that will be used to colorize the supplied scene object when + * rendering. + */ + protected TileSet.Colorizer getColorizer (ObjectInfo oinfo) + { + return null; + } + + /** + * Computes the tile coordinates of the supplied sprite and appends it + * to the supplied dirty item list. + */ + protected void appendDirtySprite (DirtyItemList list, Sprite sprite) + { + MisoUtil.screenToTile(_metrics, sprite.getX(), sprite.getY(), _tcoords); + list.appendDirtySprite(sprite, _tcoords.x, _tcoords.y); + } + + /** + * Returns the tile manager from which we load our tiles. + */ + protected TileManager getTileManager () + { + return _ctx.getTileManager(); + } + + /** + * This is called when our view position has changed by more than one + * tile in any direction. Herein we do a whole crapload of stuff: + * + *

  • Queue up loads for any new influential blocks. + *
  • Flush any blocks that are no longer influential. + *
  • Recompute the list of potentially visible scene objects. + *
+ * + * @return the count of blocks pending after this rethink. + */ + protected int rethink () + { + // recompute our "area of influence" + computeInfluentialBounds(); + +// Log.info("Rethinking vb:" + StringUtil.toString(_vbounds) + +// " ul:" + StringUtil.toString(_ulpos) + +// " ibounds: " + StringUtil.toString(_ibounds)); + + // not to worry if we presently have no scene model + if (_model == null) { + return 0; + } + + // compute the intersecting set of blocks + applyToTiles(_ibounds, _rethinkOp); +// Log.info("Influential blocks " + +// StringUtil.toString(_rethinkOp.blocks) + "."); + + // prune any blocks that are no longer influential + Point key = new Point(); + for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) { + SceneBlock block = (SceneBlock)iter.next(); + key.x = block.getBounds().x; + key.y = block.getBounds().y; + if (!_rethinkOp.blocks.contains(key)) { + Log.debug("Flushing block " + block + "."); + if (_dpanel != null) { + _dpanel.blockCleared(block); + } + iter.remove(); + } + } + + for (Iterator iter = _rethinkOp.blocks.iterator(); iter.hasNext(); ) { + Point origin = (Point)iter.next(); + int bx = MathUtil.floorDiv(origin.x, _metrics.blockwid); + int by = MathUtil.floorDiv(origin.y, _metrics.blockhei); + int bkey = compose(bx, by); + if (!_blocks.containsKey(bkey)) { + SceneBlock block = new SceneBlock( + this, origin.x, origin.y, + _metrics.blockwid, _metrics.blockhei); + boolean visible = + block.getFootprint().getBounds().intersects(_vibounds); + block.setVisiBlock(visible); + _blocks.put(bkey, block); + + // queue the block up to be resolved + _pendingBlocks++; + if (visible) { + _visiBlocks.add(block); + } + _resolver.resolveBlock(block, visible); + if (_dpanel != null) { + _dpanel.queuedBlock(block); + } + } + } + _rethinkOp.blocks.clear(); + + // recompute our visible object set + recomputeVisible(); + + Log.debug("Rethunk [pending=" + _pendingBlocks + + ", visible=" + _visiBlocks.size() + "]."); + return _visiBlocks.size(); + } + + /** + * Called during the {@link #rethink} process, configures {@link + * #_ibounds} to contain the bounds of the potentially "influential" + * world and {@link #_vibounds} to contain bounds that are used to + * determine which blocks should be resolved before making the view + * visible. + * + *

Everything that intersects the influential area will be + * resolved on the expectation that it could be scrolled into view at + * any time. The influential bounds should be large enough that the + * time between a block becoming influential and the time at which it + * is resolved is longer than the expected time by which it will be + * scrolled into view, otherwise the users will see the man behind the + * curtain. + */ + protected void computeInfluentialBounds () + { + int infborx = 3*_vbounds.width/4; + int infbory = _vbounds.height/2; + _ibounds.setBounds(_vbounds.x-infborx, _vbounds.y-infbory, + _vbounds.width+2*infborx, + // we go extra on the height because objects + // below can influence fairly high up + _vbounds.height+3*infbory); + _vibounds.setBounds(_vbounds.x-_vbounds.width/4, _vbounds.y, + _vbounds.width+_vbounds.width/2, + _vbounds.height+infbory); + } + + /** + * Returns the bounds for which all intersecting scene blocks are kept + * resolved. Do not modify the rectangle returned by this method. + */ + protected Rectangle getInfluentialBounds () + { + return _ibounds; + } + + /** + * Called by the scene block when it has started its resolution. + */ + protected void blockResolving (SceneBlock block) + { + if (_dpanel != null) { + _dpanel.resolvingBlock(block); + } + } + + /** + * Called by the scene block if it has come up for resolution but is + * no longer influential. + */ + protected void blockAbandoned (SceneBlock block) + { + if (_dpanel != null) { + _dpanel.blockCleared(block); + } + } + + /** + * Called by a scene block when it has completed its resolution + * process. + */ + protected void blockResolved (SceneBlock block) + { + if (_dpanel != null) { + _dpanel.resolvedBlock(block); + } + + Rectangle sbounds = block.getScreenBounds(); + if (!_delayRepaint && sbounds != null && sbounds.intersects(_vbounds)) { +// warnVisible(block, sbounds); + // if we have yet further blocks to resolve, queue up a + // repaint now so that we get this data onscreen as quickly as + // possible + if (_pendingBlocks > 1) { + recomputeVisible(); + _remgr.invalidateRegion(sbounds); + } + } + --_pendingBlocks; +// if (_pendingBlocks == 0) { +// Log.info("Finished resolving pending blocks " + +// "[view=" + StringUtil.toString(_vbounds) + "]."); +// reportMemoryUsage(); +// } + + // once all the visible pending blocks have completed their + // resolution, recompute our visible object set and show ourselves + if (_visiBlocks.remove(block) && _visiBlocks.size() == 0) { + recomputeVisible(); + Log.info("Restoring repaint... [left=" + _pendingBlocks + + ", view=" + StringUtil.toString(_vbounds) + "]."); + _delayRepaint = false; + _remgr.invalidateRegion(_vbounds); + } + } + + /** + * Issues a warning to the error log that the specified block became + * visible prior to being resolved. Derived classes may wish to + * augment or inhibit this warning. + */ + protected void warnVisible (SceneBlock block, Rectangle sbounds) + { + Log.warning("Block visible during resolution " + block + + " sbounds:" + StringUtil.toString(sbounds) + + " vbounds:" + StringUtil.toString(_vbounds) + "."); + } + + /** + * Recomputes our set of visible objects and their tips. + */ + protected void recomputeVisible () + { + // flush our visible object set which we'll recreate later + _vizobjs.clear(); + + Rectangle vbounds = new Rectangle( + _vbounds.x-_metrics.tilewid, _vbounds.y-_metrics.tilehei, + _vbounds.width+2*_metrics.tilewid, + _vbounds.height+2*_metrics.tilehei); + + for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) { + SceneBlock block = (SceneBlock)iter.next(); + if (!block.isResolved()) { + continue; + } + + // links this block to its neighbors; computes coverage + block.update(_blocks); + + // see which of this block's objects are visible + SceneObject[] objs = block.getObjects(); + for (int ii = 0; ii < objs.length; ii++) { + if (objs[ii].bounds != null && + vbounds.intersects(objs[ii].bounds)) { + _vizobjs.add(objs[ii]); + } + } + } + + // recompute our object tips + computeTips(); + +// Log.info("Computed " + _vizobjs.size() + " visible objects from " + +// _blocks.size() + " blocks."); + +// Log.info(StringUtil.listToString(_vizobjs, new StringUtil.Formatter() { +// public String toString (Object object) { +// SceneObject scobj = (SceneObject)object; +// return (TileUtil.getTileSetId(scobj.info.tileId) + ":" + +// TileUtil.getTileIndex(scobj.info.tileId)); +// } +// })); + } + + /** + * Masks off the lower 16 bits of the supplied integers and composes + * them into a single int. + */ + protected static int compose (int x, int y) + { + return (x << 16) | (y & 0xFFFF); + } + + /** + * Compute the tips for any objects in the scene. + */ + public void computeTips () + { + // clear any old tips + _tips.clear(); + + for (int ii = 0, nn = _vizobjs.size(); ii < nn; ii++) { + SceneObject scobj = (SceneObject)_vizobjs.get(ii); + String action = scobj.info.action; + + // if the object has no action, skip it + if (StringUtil.isBlank(action)) { + continue; + } + + // if we have an object action handler, possibly let them veto + // the display of this tooltip and action + ObjectActionHandler oah = ObjectActionHandler.lookup(action); + if (oah != null && !oah.isVisible(action)) { + continue; + } + + String tiptext = getTipText(scobj, action); + if (tiptext != null) { + Icon icon = getTipIcon(scobj, action); + SceneObjectTip tip = new SceneObjectTip(tiptext, icon); + _tips.put(scobj, tip); + } + } + + _tipsLaidOut = false; + } + + /** + * Derived classes can provide human readable object tips via this + * method. + */ + protected String getTipText (SceneObject scobj, String action) + { + ObjectActionHandler oah = ObjectActionHandler.lookup(action); + return (oah == null) ? action : oah.getTipText(action); + } + + /** + * Provides an icon for this tooltip, the default looks up an object + * action handler for the action and requests the icon from it. + */ + protected Icon getTipIcon (SceneObject scobj, String action) + { + ObjectActionHandler oah = ObjectActionHandler.lookup(action); + return (oah == null) ? null : oah.getTipIcon(action); + } + + /** + * Dirties the specified tip. + */ + protected void dirtyTip (SceneObjectTip tip) + { + if (tip != null) { + Rectangle r = tip.bounds; + if (r != null) { + _remgr.invalidateRegion(r); + } + } + } + + /** + * Change the hover object to the new object. + */ + protected void changeHoverObject (Object newHover) + { + if (newHover == _hobject) { + return; + } + Object oldHover = _hobject; + _hobject = newHover; + hoverObjectChanged(oldHover, newHover); + } + + /** + * A place for subclasses to react to the hover object changing. + * One of the supplied arguments may be null. + */ + protected void hoverObjectChanged (Object oldHover, Object newHover) + { + // deal with objects that care about being hovered over + if (oldHover instanceof SceneObject) { + SceneObject oldhov = (SceneObject)oldHover; + if (oldhov.setHovered(false)) { + _remgr.invalidateRegion(oldhov.bounds); + } + } + if (newHover instanceof SceneObject) { + SceneObject newhov = (SceneObject)newHover; + if (newhov.setHovered(true)) { + _remgr.invalidateRegion(newhov.bounds); + } + } + + // dirty the tips associated with the hover objects + dirtyTip((SceneObjectTip)_tips.get(oldHover)); + dirtyTip((SceneObjectTip)_tips.get(newHover)); + } + + /** + * Adds to the supplied dirty item list, all of the object tiles that + * are hit by the specified point (meaning the point is contained + * within their bounds and intersects a non-transparent pixel in the + * actual object image. + */ + protected void getHitObjects (DirtyItemList list, int x, int y) + { + for (int ii = 0, ll = _vizobjs.size(); ii < ll; ii++) { + SceneObject scobj = (SceneObject)_vizobjs.get(ii); + Rectangle pbounds = scobj.bounds; + if (!pbounds.contains(x, y)) { + continue; + } + + // see if we should skip it + if (skipHitObject(scobj)) { + continue; + } + + // now check that the pixel in the tile image is + // non-transparent at that point + if (!scobj.tile.hitTest(x - pbounds.x, y - pbounds.y)) { + continue; + } + + // we've passed the test, add the object to the list + list.appendDirtyObject(scobj); + } + } + + /** + * Determines whether we should skip the specified object when compiling + * the list of objects under a specified point using + * {@link #getHitObjects}. The default implementation returns + * true iff the object has no action. + */ + protected boolean skipHitObject (SceneObject scobj) + { + return StringUtil.isBlank(scobj.info.action); + } + + /** + * Converts the supplied screen coordinates into tile coordinates, + * writing the values into the supplied {@link Point} instance and + * returning true if the screen coordinates translated into a + * different set of tile coordinates than were already contained in + * the point (so that the caller can know to update a highlight, for + * example). + * + * @return true if the tile coordinates have changed. + */ + protected boolean updateTileCoords (int sx, int sy, Point tpos) + { + Point npos = MisoUtil.screenToTile(_metrics, sx, sy, new Point()); + if (!tpos.equals(npos)) { + tpos.setLocation(npos.x, npos.y); + return true; + } else { + return false; + } + } + + // documentation inherited + public void paint (Graphics g) + { + if (_delayRepaint) { + return; + } + super.paint(g); + } + + // documentation inherited + protected void paintInFront (Graphics2D gfx, Rectangle dirty) + { + super.paintInFront(gfx, dirty); + + // paint any active menu (this should in theory check to see if + // the active menu intersects one or more of the dirty rects) + if (_activeMenu != null) { + _activeMenu.render(gfx); + } + } + + // documentation inherited + protected void paintBetween (Graphics2D gfx, Rectangle dirty) + { + // render any intersecting tiles + paintTiles(gfx, dirty); + + // render anything that goes on top of the tiles + paintBaseDecorations(gfx, dirty); + + // render our dirty sprites and objects + paintDirtyItems(gfx, dirty); + + // draw sprite paths + if (_pathsDebug.getValue()) { + _spritemgr.renderSpritePaths(gfx); + } + + // paint any extra goodies + paintExtras(gfx, dirty); + } + + /** + * We don't want sprites rendered using the standard mechanism because + * we intersperse them with objects in our scene and need to manage + * their z-order. + */ + protected void paintBits (Graphics2D gfx, int layer, Rectangle dirty) + { + _animmgr.paint(gfx, layer, dirty); + } + + /** + * A function where derived classes can paint things after the base + * tiles have been rendered but before anything else has been rendered + * (so that whatever is painted appears to be on the ground). + */ + protected void paintBaseDecorations (Graphics2D gfx, Rectangle clip) + { + // nothing for now + } + + /** + * Renders the dirty sprites and objects in the scene to the given + * graphics context. + */ + protected void paintDirtyItems (Graphics2D gfx, Rectangle clip) + { + // add any sprites impacted by the dirty rectangle + _dirtySprites.clear(); + _spritemgr.getIntersectingSprites(_dirtySprites, clip); + int size = _dirtySprites.size(); + for (int ii = 0; ii < size; ii++) { + Sprite sprite = (Sprite)_dirtySprites.get(ii); + Rectangle bounds = sprite.getBounds(); + if (!bounds.intersects(clip)) { + continue; + } + appendDirtySprite(_dirtyItems, sprite); +// Log.info("Dirtied item: " + sprite); + } + + // add any objects impacted by the dirty rectangle + for (int ii = 0, ll = _vizobjs.size(); ii < ll; ii++) { + SceneObject scobj = (SceneObject)_vizobjs.get(ii); + if (!scobj.bounds.intersects(clip)) { + continue; + } + _dirtyItems.appendDirtyObject(scobj); +// Log.info("Dirtied item: " + scobj); + } + +// Log.info("paintDirtyItems [items=" + _dirtyItems.size() + "]."); + + // sort the dirty items so that we can paint them back-to-front + _dirtyItems.sort(); + _dirtyItems.paintAndClear(gfx); + } + + /** + * A function where derived classes can paint extra stuff while we've + * got the clipping region set up. + */ + protected void paintExtras (Graphics2D gfx, Rectangle clip) + { + if (isResponsive()) { + paintTips(gfx, clip); + } + } + + /** + * Paint all the appropriate tips for our scene objects. + */ + protected void paintTips (Graphics2D gfx, Rectangle clip) + { + // make sure the tips are ready + if (!_tipsLaidOut) { + ArrayList boxlist = new ArrayList(); + for (Iterator iter = _tips.keySet().iterator(); iter.hasNext(); ) { + SceneObject scobj = (SceneObject)iter.next(); + SceneObjectTip tip = (SceneObjectTip)_tips.get(scobj); + tip.layout(gfx, scobj, _vbounds, boxlist); + boxlist.add(tip.bounds); + } + _tipsLaidOut = true; + } + + if (checkShowFlag(SHOW_TIPS)) { + // show all the tips + for (Iterator iter = _tips.values().iterator(); iter.hasNext(); ) { + paintTip(gfx, clip, (SceneObjectTip)iter.next()); + } + + } else { + // show maybe one tip + SceneObjectTip tip = (SceneObjectTip)_tips.get(_hobject); + if (tip != null) { + paintTip(gfx, clip, tip); + } + } + } + + /** + * Paint the specified tip if it intersects the clipping rectangle. + */ + protected void paintTip (Graphics2D gfx, Rectangle clip, SceneObjectTip tip) + { + if (clip.intersects(tip.bounds)) { + tip.paint(gfx); + } + } + + /** + * Applies the supplied tile operation to all tiles that intersect the + * supplied screen rectangle. + */ + protected void applyToTiles (Rectangle bounds, TileOp op) + { + // determine which tiles intersect this region: this is going to + // be nearly incomprehensible without some sort of diagram; i'll + // do what i can to comment it, but you'll want to print out a + // scene diagram (docs/miso/scene.ps) and start making notes if + // you want to follow along + + // obtain our upper left tile + Point tpos = MisoUtil.screenToTile( + _metrics, bounds.x, bounds.y, new Point()); + + // determine which quadrant of the upper left tile we occupy + Point spos = MisoUtil.tileToScreen( + _metrics, tpos.x, tpos.y, new Point()); + boolean left = (bounds.x - spos.x < _metrics.tilehwid); + boolean top = (bounds.y - spos.y < _metrics.tilehhei); + + // set up our tile position counters + int dx, dy; + if (left) { + dx = 0; dy = 1; + } else { + dx = 1; dy = 0; + } + + // if we're in the top-half of the tile we need to move up a row, + // either forward or back depending on whether we're in the left + // or right half of the tile + if (top) { + if (left) { + tpos.x -= 1; + } else { + tpos.y -= 1; + } + // we'll need to start zig-zagging the other way as well + dx = 1 - dx; + dy = 1 - dy; + } + + // these will bound our loops + int rightx = bounds.x + bounds.width, + bottomy = bounds.y + bounds.height; + +// Log.info("Preparing to apply [tpos=" + StringUtil.toString(tpos) + +// ", left=" + left + ", top=" + top + +// ", bounds=" + StringUtil.toString(bounds) + +// ", spos=" + StringUtil.toString(spos) + +// "]."); + + // obtain the coordinates of the tile that starts the first row + // and loop through, applying to the intersecting tiles + MisoUtil.tileToScreen(_metrics, tpos.x, tpos.y, spos); + while (spos.y < bottomy) { + // set up our row counters + int tx = tpos.x, ty = tpos.y; + _tbounds.x = spos.x; + _tbounds.y = spos.y; + +// Log.info("Applying to row [tx=" + tx + ", ty=" + ty + "]."); + + // apply to the tiles in this row + while (_tbounds.x < rightx) { + op.apply(tx, ty, _tbounds); + + // move one tile to the right + tx += 1; ty -= 1; + _tbounds.x += _metrics.tilewid; + } + + // update our tile coordinates + tpos.x += dx; dx = 1-dx; + tpos.y += dy; dy = 1-dy; + + // obtain the screen coordinates of the next starting tile + MisoUtil.tileToScreen(_metrics, tpos.x, tpos.y, spos); + } + } + + /** + * Renders the base and fringe layer tiles that intersect the + * specified clipping rectangle. + */ + protected void paintTiles (Graphics2D gfx, Rectangle clip) + { + // go through rendering our tiles + _paintOp.setGraphics(gfx); + applyToTiles(clip, _paintOp); + _paintOp.setGraphics(null); + } + + /** + * Fills the specified tile with the given color at 50% alpha. + * Intended for debug-only tile highlighting purposes. + */ + protected void fillTile ( + Graphics2D gfx, int tx, int ty, Color color) + { + Composite ocomp = gfx.getComposite(); + gfx.setComposite(ALPHA_FILL_TILE); + Polygon poly = MisoUtil.getTilePolygon(_metrics, tx, ty); + gfx.setColor(color); + gfx.fill(poly); + gfx.setComposite(ocomp); + } + + /** Returns the base tile for the specified tile coordinate. */ + protected BaseTile getBaseTile (int tx, int ty) + { + SceneBlock block = getBlock(tx, ty); + return (block == null) ? null : block.getBaseTile(tx, ty); + } + + /** Returns the fringe tile for the specified tile coordinate. */ + protected BaseTile getFringeTile (int tx, int ty) + { + SceneBlock block = getBlock(tx, ty); + return (block == null) ? null : block.getFringeTile(tx, ty); + } + + /** Computes the fringe tile for the specified coordinate. */ + protected BaseTile computeFringeTile (int tx, int ty) + { + return _ctx.getTileManager().getAutoFringer().getFringeTile( + _model, tx, ty, _masks); + } + + /** + * Returns true if we're responding to user input. This is used to + * control the display of tooltips and other potential user + * interactions. By default we are always responsive. + */ + protected boolean isResponsive () + { + return true; + } + + /** Used with {@link #applyToTiles}. */ + protected static interface TileOp + { + public void apply (int tx, int ty, Rectangle tbounds); + } + + /** Used by {@link #paintTiles}. */ + protected class PaintTileOp implements TileOp + { + public void setGraphics (Graphics2D gfx) { + _gfx = gfx; + _thw = 0; + _thh = 0; + _fhei = 0; + _fm = null; + + // if we're showing coordinates, we need to do some setting up + if (gfx != null && _coordsDebug.getValue()) { + _fm = gfx.getFontMetrics(_font); + _fhei = _fm.getAscent(); + _thw = _metrics.tilehwid; + _thh = _metrics.tilehhei; + gfx.setFont(_font); + } + } + + public void apply (int tx, int ty, Rectangle tbounds) { + // draw the base and fringe tile images + try { + Tile tile; + boolean passable = true; + + if ((tile = getBaseTile(tx, ty)) != null) { + tile.paint(_gfx, tbounds.x, tbounds.y); + passable = ((BaseTile)tile).isPassable(); + + } else { + // draw black where there are no tiles + Polygon poly = MisoUtil.getTilePolygon(_metrics, tx, ty); + _gfx.setColor(Color.black); + _gfx.fill(poly); + } + + if ((tile = getFringeTile(tx, ty)) != null) { + tile.paint(_gfx, tbounds.x, tbounds.y); + passable = passable && ((BaseTile)tile).isPassable(); + } + + // highlight impassable tiles + if (_traverseDebug.getValue()) { + if (!passable) { + // highlight tiles blocked by base or fringe in yellow + fillTile(_gfx, tx, ty, Color.yellow); + + } else if (!canTraverse(null, tx, ty)) { + // highlight passable non-traversable tiles in green + fillTile(_gfx, tx, ty, Color.green); + } + } + + } catch (ArrayIndexOutOfBoundsException e) { + Log.warning("Whoops, booched it [tx=" + tx + + ", ty=" + ty + ", tb.x=" + tbounds.x + "]."); + e.printStackTrace(System.err); + } + + // if we're showing coordinates, do that + if (_coordsDebug.getValue()) { + // set the color according to the scene block + int bx = MathUtil.floorDiv(tx, _metrics.blockwid); + int by = MathUtil.floorDiv(ty, _metrics.blockhei); + if (((bx % 2) ^ (by % 2)) == 0) { + _gfx.setColor(Color.white); + } else { + _gfx.setColor(Color.yellow); + } + + // get the top-left screen coordinates of the tile + int sx = tbounds.x, sy = tbounds.y; + + // draw x-coordinate + String str = String.valueOf(tx); + int xpos = sx + _thw - (_fm.stringWidth(str) / 2); + _gfx.drawString(str, xpos, sy + _thh); + + // draw y-coordinate + str = String.valueOf(ty); + xpos = sx + _thw - (_fm.stringWidth(str) / 2); + _gfx.drawString(str, xpos, sy + _thh + _fhei); + + // draw the tile polygon as well + _gfx.draw(MisoUtil.getTilePolygon(_metrics, tx, ty)); + } + } + + protected Graphics2D _gfx; + protected FontMetrics _fm; + protected int _thw, _thh, _fhei; + protected Font _font = new Font("Arial", Font.PLAIN, 7); + } + + /** Used by {@link #rethink}. */ + protected class RethinkOp implements TileOp + { + public HashSet blocks = new HashSet(); + + public void apply (int tx, int ty, Rectangle tbounds) { + _key.x = MathUtil.floorDiv(tx, _metrics.blockwid) * + _metrics.blockwid; + _key.y = MathUtil.floorDiv(ty, _metrics.blockhei) * + _metrics.blockhei; + if (!blocks.contains(_key)) { + blocks.add(new Point(_key.x, _key.y)); + } + } + + protected Point _key = new Point(); + } + + /** Provides access to a few things. */ + protected MisoContext _ctx; + + /** Contains basic scene metrics like tile width and height. */ + protected MisoSceneMetrics _metrics; + + /** The scene model to be displayed. */ + protected MisoSceneModel _model; + + /** Tracks the size at which we were last "rethunk". */ + protected Dimension _rsize = new Dimension(); + + /** Contains the tile coords of our upper-left view coord. */ + protected Point _ulpos; + + /** Contains the bounds of our "area of influence" in screen coords. */ + protected Rectangle _ibounds = new Rectangle(); + + /** Contains the bounds of our visible "area of influence" in screen + * coords. */ + protected Rectangle _vibounds = new Rectangle(); + + /** Used by {@link #rethink}. */ + protected RethinkOp _rethinkOp = new RethinkOp(); + + /** Contains our scene blocks. See {@link #getBlock} for details. */ + protected HashIntMap _blocks = new HashIntMap(); + + /** A count of blocks in the process of being resolved. */ + protected int _pendingBlocks; + + /** Used to track visible blocks that are waiting to be resolved. */ + protected HashSet _visiBlocks = new HashSet(); + + /** Used to avoid repaints while we don't yet have resolved all the + * blocks needed to render the visible view. */ + protected boolean _delayRepaint = false; + + /** A list of the potentially visible objects in the scene. */ + protected ArrayList _vizobjs = new ArrayList(); + + /** For computing fringe tiles. */ + protected HashMap _masks = new HashMap(); + + /** The dirty sprites and objects that need to be re-painted. */ + protected DirtyItemList _dirtyItems = new DirtyItemList(); + + /** The working sprites list used when calculating dirty regions. */ + protected ArrayList _dirtySprites = new ArrayList(); + + /** Used when rendering tiles. */ + protected Rectangle _tbounds; + + /** Used to paint tiles. */ + protected PaintTileOp _paintOp = new PaintTileOp(); + + /** Temporary point used for intermediate calculations. */ + protected Point _tcoords = new Point(); + + /** Used to collect the list of sprites "hit" by a particular mouse + * location. */ + protected List _hitSprites = new ArrayList(); + + /** The list that we use to track and sort the items over which the + * mouse is hovering. */ + protected DirtyItemList _hitList = new DirtyItemList(); + + /** Info on the object that the mouse is currently hovering over. */ + protected Object _hobject; + + /** The item that the user has clicked on with the mouse. */ + protected Object _armedItem = null; + + /** The active radial menu (or null). */ + protected RadialMenu _activeMenu; + + /** Used to track the tile coordinates over which the mouse is hovering. */ + protected Point _hcoords = new Point(); + + /** Our object tips, indexed by the object that they tip for. */ + protected HashMap _tips = new HashMap(); + + /** Have the tips been laid out? */ + protected boolean _tipsLaidOut = false; + + /** Flags indicating which features we should show in the scene. */ + protected int _showFlags = 0; + + /** A scene block resolver shared by all scene panels. */ + protected static SceneBlockResolver _resolver; + + // used to display debugging information on scene block resolution + protected JFrame _dframe; + protected ResolutionView _dpanel; + + /** A debug hook that toggles debug rendering of traversable tiles. */ + protected static RuntimeAdjust.BooleanAdjust _traverseDebug = + new RuntimeAdjust.BooleanAdjust( + "Toggles debug rendering of traversable and impassable tiles in " + + "the iso scene view.", "narya.miso.iso_traverse_debug_render", + MisoPrefs.config, false); + + /** A debug hook that toggles debug rendering of tile coordinates. */ + protected static RuntimeAdjust.BooleanAdjust _coordsDebug = + new RuntimeAdjust.BooleanAdjust( + "Toggles debug rendering of tile coordinates in the iso scene " + + "view.", "narya.miso.iso_coords_debug_render", + MisoPrefs.config, false); + + /** A debug hook that toggles debug rendering of sprite paths. */ + protected static RuntimeAdjust.BooleanAdjust _pathsDebug = + new RuntimeAdjust.BooleanAdjust( + "Toggles debug rendering of sprite paths in the iso scene view.", + "narya.miso.iso_paths_debug_render", MisoPrefs.config, false); + + /** A debug hook that toggles the block resolution display. */ + protected static RuntimeAdjust.BooleanAdjust _resolveDebug = + new RuntimeAdjust.BooleanAdjust( + "Enables a view displaying the status of scene block resolution.", + "narya.miso.iso_paths_debug_resolve", MisoPrefs.config, false); + + /** The stroke used to draw dirty rectangles. */ + protected static final Stroke DIRTY_RECT_STROKE = new BasicStroke(2); + + /** The alpha used to fill tiles for debugging purposes. */ + protected static final Composite ALPHA_FILL_TILE = + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + + /** The default size of the "box" that defines the size of our radial + * menu circles. */ + protected static final Dimension DEF_RADIAL_RECT = new Dimension(80, 80); +} diff --git a/src/java/com/threerings/miso/client/ObjectActionHandler.java b/src/java/com/threerings/miso/client/ObjectActionHandler.java new file mode 100644 index 00000000..e8fea6df --- /dev/null +++ b/src/java/com/threerings/miso/client/ObjectActionHandler.java @@ -0,0 +1,151 @@ +// +// $Id: ObjectActionHandler.java 3917 2006-03-06 23:45:12Z mthomas $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.event.ActionEvent; +import java.util.HashMap; +import javax.swing.Icon; + +import com.samskivert.swing.RadialMenu; +import com.samskivert.util.StringUtil; + +import com.threerings.miso.Log; +import com.threerings.miso.client.SceneObject; + +/** + * Objects in scenes can be configured to generate action events. Those + * events are grouped into types and an object action handler can be + * registered to handle all actions of a particular type. + */ +public class ObjectActionHandler +{ + /** + * Returns true if we should allow this object action, false if we + * should not. + */ + public boolean actionAllowed (String action) + { + return true; + } + + /** + * Returns true if we should display the text for the action. By default + * this returns whether the action is allowed or not, but can be + * overridden by subclasses. This is used to completely hide actions that + * should not be visible without the proper privileges. + */ + public boolean isVisible (String action) + { + return actionAllowed(action); + } + + /** + * Get the human readable object tip for the specified action. + */ + public String getTipText (String action) + { + return action; + } + + /** + * Returns the tooltip icon for the specified action or null if the + * action has no tooltip icon. + */ + public Icon getTipIcon (String action) + { + return null; + } + + /** + * Return a {@link RadialMenu} or null if no menu needed. + */ + public RadialMenu handlePressed (SceneObject sourceObject) + { + return null; + } + + /** + * Called when an action is generated for an object. + */ + public void handleAction (SceneObject scobj, ActionEvent event) + { + Log.warning("Unknown object action [scobj=" + scobj + + ", action=" + event + "]."); + } + + /** + * Returns the type associated with this action command (which is + * mapped to a registered object action handler) or the empty string + * if it has no type. + */ + public static String getType (String command) + { + int cidx = StringUtil.isBlank(command) ? -1 : command.indexOf(':'); + return (cidx == -1) ? "" : command.substring(0, cidx); + } + + /** + * Returns the unqualified object action (minus the type, see {@link + * #getType}). + */ + public static String getAction (String command) + { + int cidx = StringUtil.isBlank(command) ? -1 : command.indexOf(':'); + return (cidx == -1) ? command : command.substring(cidx+1); + } + + /** + * Looks up the object action handler associated with the specified + * command. + */ + public static ObjectActionHandler lookup (String command) + { + return (ObjectActionHandler)_oahandlers.get(getType(command)); + } + + /** + * Registers an object action handler which will be called when a user + * clicks on an object in a scene that has an associated action. + */ + public static void register (String prefix, ObjectActionHandler handler) + { + // make sure we know about potential funny business + if (_oahandlers.containsKey(prefix)) { + Log.warning("Warning! Overwriting previous object action " + + "handler registration, all hell could shortly " + + "break loose [prefix=" + prefix + + ", handler=" + handler + "]."); + } + _oahandlers.put(prefix, handler); + } + + /** + * Removes an object action handler registration. + */ + public static void unregister (String prefix) + { + _oahandlers.remove(prefix); + } + + /** Our registered object action handlers. */ + protected static HashMap _oahandlers = new HashMap(); +} diff --git a/src/java/com/threerings/miso/client/ResolutionView.java b/src/java/com/threerings/miso/client/ResolutionView.java new file mode 100644 index 00000000..775b64af --- /dev/null +++ b/src/java/com/threerings/miso/client/ResolutionView.java @@ -0,0 +1,164 @@ +// +// $Id: ResolutionView.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import javax.swing.JPanel; + +import java.util.HashMap; +import java.util.Iterator; + +import com.samskivert.util.IntTuple; + +import com.threerings.media.util.MathUtil; +import com.threerings.miso.util.MisoSceneMetrics; +import com.threerings.miso.util.MisoUtil; + +/** + * Used to debug scene block resolution visually. + */ +public class ResolutionView extends JPanel +{ + public ResolutionView (MisoScenePanel panel) + { + _panel = panel; + _metrics = panel.getSceneMetrics(); + } + + public Dimension getPreferredSize () + { + return new Dimension(TILE_SIZE*MAX_WIDTH, TILE_SIZE*MAX_HEIGHT); + } + + public synchronized void queuedBlock (SceneBlock block) + { + assignColor(block, Color.yellow); + repaint(); + } + + public synchronized void resolvingBlock (SceneBlock block) + { + IntTuple key = blockKey(block); + if (_blocks.containsKey(key)) { + assignColor(block, Color.red); + repaint(); + } + } + + public synchronized void resolvedBlock (SceneBlock block) + { + IntTuple key = blockKey(block); + if (_blocks.containsKey(key)) { + assignColor(block, Color.green); + repaint(); + } + } + + public synchronized void blockCleared (SceneBlock block) + { + _blocks.remove(blockKey(block)); + repaint(); + } + + public synchronized void newScene () + { + _blocks.clear(); + repaint(); + } + + protected void assignColor (SceneBlock block, Color color) + { + IntTuple key = blockKey(block); + BlockGlyph glyph = (BlockGlyph)_blocks.get(key); + if (glyph == null) { + glyph = new BlockGlyph(_metrics, key.left, key.right); + _blocks.put(key, glyph); + } + glyph.color = color; + } + + public synchronized void paintComponent (Graphics g) + { + super.paintComponent(g); + Graphics2D gfx = (Graphics2D)g; + + Rectangle vbounds = _panel.getViewBounds(); + gfx.translate((getWidth()-vbounds.width/16)/2 - vbounds.x/16, + (getHeight()-vbounds.height/16)/2 - vbounds.y/16); + + AffineTransform xform = gfx.getTransform(); + gfx.scale(0.25, 0.25); + + // draw our block glyphs + for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) { + ((BlockGlyph)iter.next()).paint(gfx); + } + + // draw the view bounds + gfx.scale(0.25, 0.25); + gfx.draw(vbounds); + gfx.setColor(Color.red); + gfx.draw(_panel.getInfluentialBounds()); + gfx.setTransform(xform); + } + + protected final IntTuple blockKey (SceneBlock block) + { + Rectangle bounds = block.getBounds(); + return new IntTuple(MathUtil.floorDiv(bounds.x, bounds.width), + MathUtil.floorDiv(bounds.y, bounds.height)); + } + + protected static class BlockGlyph + { + public Color color; + + public BlockGlyph (MisoSceneMetrics metrics, int bx, int by) + { + _bpoly = MisoUtil.getTilePolygon(metrics, bx, by); + } + + public void paint (Graphics2D gfx) + { + gfx.setColor(color); + gfx.fill(_bpoly); + gfx.setColor(Color.black); + gfx.draw(_bpoly); + } + + protected Polygon _bpoly; + } + + protected MisoScenePanel _panel; + protected MisoSceneMetrics _metrics; + protected HashMap _blocks = new HashMap(); + + protected static final int TILE_SIZE = 10; + protected static final int MAX_WIDTH = 30; + protected static final int MAX_HEIGHT = 30; +} diff --git a/src/java/com/threerings/miso/client/SceneBlock.java b/src/java/com/threerings/miso/client/SceneBlock.java new file mode 100644 index 00000000..97bcb906 --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneBlock.java @@ -0,0 +1,596 @@ +// +// $Id: SceneBlock.java 3628 2005-06-28 17:42:55Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Polygon; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; + +import com.samskivert.util.ArrayUtil; +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +import com.threerings.geom.GeomUtil; +import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.ObjectTile; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TileUtil; +import com.threerings.media.util.MathUtil; + +import com.threerings.miso.Log; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.tile.BaseTile; +import com.threerings.miso.util.MisoUtil; +import com.threerings.miso.util.ObjectSet; + +/** + * Contains the base and object tile information on a particular + * rectangular region of a scene. + */ +public class SceneBlock +{ + /** + * Creates a scene block and resolves the base and object tiles that + * reside therein. + */ + public SceneBlock ( + MisoScenePanel panel, int tx, int ty, int width, int height) + { + _panel = panel; + _bounds = new Rectangle(tx, ty, width, height); + _base = new BaseTile[width*height]; + _fringe = new BaseTile[width*height]; + _covered = new boolean[width*height]; + + // compute our screen-coordinate footprint polygon + _footprint = MisoUtil.getFootprintPolygon( + panel.getSceneMetrics(), tx, ty, width, height); + + // the rest of our resolution will happen in resolve() + } + + /** + * Makes a note that this block was considered to be visible at the + * time it was created. This is purely for debugging purposes. + */ + public void setVisiBlock (boolean visi) + { + _visi = visi; + } + + /** + * This method is called by the {@link SceneBlockResolver} on the + * block resolution thread to allow us to load up our image data + * without blocking the AWT thread. + */ + protected boolean resolve () + { + // if we got canned before we were resolved, go ahead and bail now + if (_panel.getBlock(_bounds.x, _bounds.y) != this) { + // Log.info("Not resolving abandoned block " + this + "."); + _panel.blockAbandoned(this); + return false; + } + _panel.blockResolving(this); + + // start with the bounds of the footprint polygon + Rectangle sbounds = new Rectangle(_footprint.getBounds()); + Rectangle obounds = null; + + // resolve our base tiles + long now = System.currentTimeMillis(); + int baseCount = 0, fringeCount = 0; + MisoSceneModel model = _panel.getSceneModel(); + for (int yy = 0; yy < _bounds.height; yy++) { + for (int xx = 0; xx < _bounds.width; xx++) { + int x = _bounds.x + xx, y = _bounds.y + yy; + int fqTileId = model.getBaseTileId(x, y); + if (fqTileId <= 0) { + continue; + } + + // load up this base tile + updateBaseTile(fqTileId, x, y); + baseCount++; + + // if there's no tile here, we don't need no fringe + int tidx = index(x, y); + if (_base[tidx] == null) { + continue; + } + + // compute the fringe for this tile + _fringe[tidx] = _panel.computeFringeTile(x, y); + fringeCount++; + } + } + + // DEBUG: check for long resolution times + long stamp = System.currentTimeMillis(); + long elapsed = stamp - now; + if (elapsed > 500L) { + Log.warning("Base and fringe resolution took long time " + + "[block=" + this + ", baseCount=" + baseCount + + ", fringeCount=" + fringeCount + + ", elapsed=" + elapsed + "]."); + } + + // resolve our objects + ObjectSet set = new ObjectSet(); + model.getObjects(_bounds, set); + ArrayList scobjs = new ArrayList(); + now = System.currentTimeMillis(); + for (int ii = 0, ll = set.size(); ii < ll; ii++) { + SceneObject scobj = new SceneObject(_panel, set.get(ii)); + // ignore this object if it failed to resolve + if (scobj.bounds == null) { + continue; + } + sbounds.add(scobj.bounds); + obounds = GeomUtil.grow(obounds, scobj.bounds); + scobjs.add(scobj); + + // DEBUG: check for long resolution times + stamp = System.currentTimeMillis(); + elapsed = stamp - now; + now = stamp; + if (elapsed > 250L) { + Log.warning("Scene object took look time to resolve " + + "[block=" + this + ", scobj=" + scobj + + ", elapsed=" + elapsed + "]."); + } + } + _objects = (SceneObject[])scobjs.toArray( + new SceneObject[scobjs.size()]); + + // resolve our default tileset + int bsetid = model.getDefaultBaseTileSet(); + try { + if (bsetid > 0) { + _defset = _panel.getTileManager().getTileSet(bsetid); + } + } catch (Exception e) { + Log.warning("Unable to fetch default base tileset [tsid=" + bsetid + + ", error=" + e + "]."); + } + + // this both marks us as resolved and makes all our other updated + // fields visible + synchronized (this) { + _obounds = obounds; + _sbounds = sbounds; + } + + return true; + } + + /** + * This is called by the {@link SceneBlockResolver} on the AWT thread + * when our resolution has completed. We inform our containing panel. + */ + protected void wasResolved () + { + _panel.blockResolved(this); + } + + /** + * Returns true if this block has been resolved, false if not. + */ + protected synchronized boolean isResolved () + { + return _sbounds != null; + } + + /** + * Returns the bounds of this block, in tile coordinates. + */ + public Rectangle getBounds () + { + return _bounds; + } + + /** + * Returns the bounds of the screen coordinate rectangle that contains + * all pixels that are drawn on by all tiles and objects in this + * block. + */ + public Rectangle getScreenBounds () + { + return _sbounds; + } + + /** + * Returns the bounds of the screen coordinate rectangle that contains + * all pixels that are drawn on by all objects (but not base tiles) in + * this block. Note: this will return null if + * the block has no objects. + */ + public Rectangle getObjectBounds () + { + return _obounds; + } + + /** + * Returns the screen-coordinate polygon bounding the footprint of + * this block. + */ + public Polygon getFootprint () + { + return _footprint; + } + + /** + * Returns an array of all resolved scene objects in this block. + */ + public SceneObject[] getObjects () + { + return _objects; + } + + /** + * Returns the base tile at the specified coordinates or null if + * there's no tile at said coordinates. + */ + public BaseTile getBaseTile (int tx, int ty) + { + BaseTile tile = _base[index(tx, ty)]; + if (tile == null && _defset != null) { + tile = (BaseTile)_defset.getTile( + TileUtil.getTileHash(tx, ty) % _defset.getTileCount()); + } + return tile; + } + + /** + * Returns the fringe tile at the specified coordinates or null if + * there's no tile at said coordinates. + */ + public BaseTile getFringeTile (int tx, int ty) + { + return _fringe[index(tx, ty)]; + } + + /** + * Informs this scene block that the specified base tile has been + * changed. + */ + public void updateBaseTile (int fqTileId, int tx, int ty) + { + String errmsg = null; + int tidx = index(tx, ty); + + // this is a bit magical: we pass the fully qualified tile id to + // the tile manager which loads up from the configured tileset + // repository the appropriate tileset (which should be a + // BaseTileSet) and then extracts the appropriate base tile (the + // index of which is also in the fqTileId) + try { + if (fqTileId <= 0) { + _base[tidx] = null; + } else { + _base[tidx] = (BaseTile) + _panel.getTileManager().getTile(fqTileId); + } + // clear out the fringe (it must be recomputed by the caller) + _fringe[tidx] = null; + + } catch (ClassCastException cce) { + errmsg = "Scene contains non-base tile in base layer"; + } catch (NoSuchTileSetException nste) { + errmsg = "Scene contains non-existent tileset"; + } + + if (errmsg != null) { + Log.warning(errmsg + " [fqtid=" + fqTileId + + ", x=" + tx + ", y=" + ty + "]."); + } + } + + /** + * Instructs this block to recompute its fringe at the specified + * location. + */ + public void updateFringe (int tx, int ty) + { + int tidx = index(tx, ty); + if (_base[tidx] != null) { + _fringe[tidx] = _panel.computeFringeTile(tx, ty); + } + } + + /** + * Adds the supplied object to this block. Coverage is not computed + * for the added object, a subsequent call to {@link #update} will be + * needed. + * + * @return true if the object was added, false if it was not because + * another object of the same type already occupies that location. + */ + public boolean addObject (ObjectInfo info) + { + // make sure we don't already have this same object at these + // coordinates + for (int ii = 0; ii < _objects.length; ii++) { + if (_objects[ii].info.equals(info)) { + return false; + } + } + + _objects = (SceneObject[]) + ArrayUtil.append(_objects, new SceneObject(_panel, info)); + + // clear out our neighbors array so that the subsequent update + // causes us to recompute our coverage + Arrays.fill(_neighbors, null); + return true; + } + + /** + * Removes the specified object from this block. Coverage is not + * recomputed, so a subsequent call to {@link #update} will be needed. + * + * @return true if the object was deleted, false if it was not found + * in our object list. + */ + public boolean deleteObject (ObjectInfo info) + { + int oidx = -1; + for (int ii = 0; ii < _objects.length; ii++) { + if (_objects[ii].info.equals(info)) { + oidx = ii; + break; + } + } + if (oidx == -1) { + return false; + } + _objects = (SceneObject[])ArrayUtil.splice(_objects, oidx, 1); + + // clear out our neighbors array so that the subsequent update + // causes us to recompute our coverage + Arrays.fill(_neighbors, null); + return true; + } + + /** + * Returns true if the specified traverser can traverse the specified + * tile (which is assumed to be in the bounds of this scene block). + */ + public boolean canTraverse (Object traverser, int tx, int ty) + { + if (_covered[index(tx, ty)]) { + return false; + } + + // null base or impassable base kills traversal + BaseTile base = getBaseTile(tx, ty); + if ((base == null) || !base.isPassable()) { + return false; + } + + // fringe can only kill traversal if it is present + BaseTile fringe = getFringeTile(tx, ty); + return (fringe == null) || fringe.isPassable(); + } + + /** + * Computes the memory usage of the base and object tiles in this + * scene block; registering counted tiles in the hash map so that + * other blocks can be sure not to double count them. Base tile usage + * is placed into the zeroth array element, fringe tile usage into the + * first and object tile usage into the second. + */ + public void computeMemoryUsage ( + HashMap bases, HashSet fringes, HashMap objects, long[] usage) + { + // account for our base tiles + MisoSceneModel model = _panel.getSceneModel(); + for (int yy = 0; yy < _bounds.height; yy++) { + for (int xx = 0; xx < _bounds.width; xx++) { + int x = _bounds.x + xx, y = _bounds.y + yy; + int tidx = index(x, y); + BaseTile base = _base[tidx]; + if (base == null) { + continue; + } + + BaseTile sbase = (BaseTile)bases.get(base.key); + if (sbase == null) { + bases.put(base.key, base); + usage[0] += base.getEstimatedMemoryUsage(); + } else if (base != _base[tidx]) { + Log.warning("Multiple instances of same base tile " + + "[base=" + base + + ", x=" + xx + ", y=" + yy + "]."); + usage[0] += base.getEstimatedMemoryUsage(); + } + + // now account for the fringe + if (_fringe[tidx] == null) { + continue; + } else if (!fringes.contains(_fringe[tidx])) { + fringes.add(_fringe[tidx]); + usage[1] += _fringe[tidx].getEstimatedMemoryUsage(); + } + } + } + + // now get the object tiles + int ocount = (_objects == null) ? 0 : _objects.length; + for (int ii = 0; ii < ocount; ii++) { + SceneObject scobj = _objects[ii]; + ObjectTile tile = (ObjectTile)objects.get(scobj.tile.key); + if (tile == null) { + objects.put(scobj.tile.key, scobj.tile); + usage[2] += scobj.tile.getEstimatedMemoryUsage(); + } else if (tile != scobj.tile) { + Log.warning("Multiple instances of same object tile: " + + scobj.info + "."); + usage[2] += scobj.tile.getEstimatedMemoryUsage(); + } + } + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + int bx = MathUtil.floorDiv(_bounds.x, _bounds.width); + int by = MathUtil.floorDiv(_bounds.y, _bounds.height); + return StringUtil.coordsToString(bx, by) + ":" + + StringUtil.toString(_bounds) + ":" + + ((_objects == null) ? 0 : _objects.length) + + (_visi ? ":v" : ":i"); + } + + /** + * Returns the index into our arrays of the specified tile. + */ + protected final int index (int tx, int ty) + { +// if (!_bounds.contains(tx, ty)) { +// String errmsg = "Coordinates out of bounds: +" + tx + "+" + ty + +// " not in " + StringUtil.toString(_bounds); +// throw new IllegalArgumentException(errmsg); +// } + return (ty-_bounds.y)*_bounds.width + (tx-_bounds.x); + } + + /** + * Links this block to its neighbors; informs neighboring blocks of + * object coverage. + */ + protected void update (HashIntMap blocks) + { + boolean recover = false; + + // link up to our neighbors + for (int ii = 0; ii < DX.length; ii++) { + SceneBlock neigh = (SceneBlock) + blocks.get(neighborKey(DX[ii], DY[ii])); + if (neigh != _neighbors[ii]) { + _neighbors[ii] = neigh; + // if we're linking up to a neighbor for the first time; + // we need to recalculate our coverage + recover = recover || (neigh != null); +// Log.info(this + " was introduced to " + neigh + "."); + } + } + + // if we need to regenerate the set of tiles covered by our + // objects, do so + if (recover) { + for (int ii = 0; ii < _objects.length; ii++) { + setCovered(blocks, _objects[ii]); + } + } + } + + /** Computes the key of our neighbor. */ + protected final int neighborKey (int dx, int dy) + { + int nx = MathUtil.floorDiv(_bounds.x, _bounds.width)+dx; + int ny = MathUtil.floorDiv(_bounds.y, _bounds.height)+dy; + return MisoScenePanel.compose(nx, ny); + } + + /** Computes the key for the block that holds the specified tile. */ + protected final int blockKey (int tx, int ty) + { + int bx = MathUtil.floorDiv(tx, _bounds.width); + int by = MathUtil.floorDiv(ty, _bounds.height); + return MisoScenePanel.compose(bx, by); + } + + /** + * Sets the footprint of this object tile + */ + protected void setCovered (HashIntMap blocks, SceneObject scobj) + { + int endx = scobj.info.x - scobj.tile.getBaseWidth() + 1; + int endy = scobj.info.y - scobj.tile.getBaseHeight() + 1; + + for (int xx = scobj.info.x; xx >= endx; xx--) { + for (int yy = scobj.info.y; yy >= endy; yy--) { + SceneBlock block = (SceneBlock)blocks.get(blockKey(xx, yy)); + if (block != null) { + block.setCovered(xx, yy); + } + } + } + +// Log.info("Updated coverage " + scobj.info + "."); + } + + /** + * Indicates that this tile is covered by an object footprint. + */ + protected void setCovered (int tx, int ty) + { + _covered[index(tx, ty)] = true; + } + + /** The panel for which we contain a block. */ + protected MisoScenePanel _panel; + + /** The bounds of (in tile coordinates) of this block. */ + protected Rectangle _bounds; + + /** The bounds (in screen coords) of all images rendered by this block. */ + protected Rectangle _sbounds; + + /** The bounds (in screen coords) of all objects rendered by this block. */ + protected Rectangle _obounds; + + /** A polygon bounding the footprint of this block. */ + protected Polygon _footprint; + + /** Used to return a tile where we have none. */ + protected TileSet _defset; + + /** Our base tiles. */ + protected BaseTile[] _base; + + /** Our fringe tiles. */ + protected BaseTile[] _fringe; + + /** Indicates whether our tiles are covered by an object. */ + protected boolean[] _covered; + + /** Info on our objects. */ + protected SceneObject[] _objects; + + /** Our neighbors in the eight cardinal directions. */ + protected SceneBlock[] _neighbors = new SceneBlock[DX.length]; + + /** A debug flag indicating whether we were visible at creation. */ + protected boolean _visi; + + // used to link up to our neighbors + protected static final int[] DX = { -1, -1, 0, 1, 1, 1, 0, -1 }; + protected static final int[] DY = { 0, -1, -1, -1, 0, 1, 1, 1 }; +} diff --git a/src/java/com/threerings/miso/client/SceneBlockResolver.java b/src/java/com/threerings/miso/client/SceneBlockResolver.java new file mode 100644 index 00000000..cb1aee0e --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneBlockResolver.java @@ -0,0 +1,138 @@ +// +// $Id: SceneBlockResolver.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.EventQueue; + +import com.samskivert.util.Histogram; +import com.samskivert.util.LoopingThread; +import com.samskivert.util.Queue; + +import com.threerings.miso.Log; + +/** + * A separate thread for resolving miso scene blocks. + */ +public class SceneBlockResolver extends LoopingThread +{ + /** + * Queues up a scene block for resolution. + */ + public void resolveBlock (SceneBlock block, boolean hipri) + { + Log.debug("Queueing block for resolution " + block + + " (" + hipri + ")."); + if (hipri) { + _queue.prepend(block); + } else { + _queue.append(block); + } + } + + /** + * Temporarily suspends the scene block resolution thread. + */ + public synchronized void suspendResolution () + { + _resolving = false; + } + + /** + * Restores the operation of the scene block resolution thread after a + * previous call to {@link #suspendResolution}. + */ + public synchronized void restoreResolution () + { + _resolving = true; + notify(); + } + + /** + * Returns the number of scene blocks on the resolution queue. + */ + public int queueSize () + { + return _queue.size(); + } + + // documentation inherited + public void iterate () + { + final SceneBlock block = (SceneBlock)_queue.get(); + + while (!_resolving) { + synchronized (this) { + try { + wait(); + } catch (InterruptedException ie) { + Log.info("Resolver interrupted."); + } + } + } + + try { + long start = System.currentTimeMillis(); + Log.debug("Resolving block " + block + "."); + if (block.resolve()) { + Log.debug("Resolved block " + block + "."); + } + long elapsed = System.currentTimeMillis() - start; + _histo.addValue((int)elapsed); + + // warn if a block takes a long time to resolve + if (elapsed > LONG_RESOLVE_TIME) { + Log.warning("Block took long time to resolve [block=" + block + + ", elapsed=" + elapsed + "ms]."); + } + + // queue it up on the AWT thread to complete its resolution + final boolean report = (_queue.size() == 0); + EventQueue.invokeLater(new Runnable() { + public void run () { + // let the block's panel know that it is resolved + block.wasResolved(); + // report statistics +// if (report) { +// Log.info("Resolution histogram " + +// _histo.summarize() + "."); +// } + } + }); + + } catch (Exception e) { + Log.warning("Block failed during resolution " + block + "."); + Log.logStackTrace(e); + } + } + + /** The invoker's queue of units to be executed. */ + protected Queue _queue = new Queue(); + + /** Indicates whether or not we are resolving or suspended. */ + protected boolean _resolving = true; + + /** Used to time block loading. */ + protected Histogram _histo = new Histogram(0, 25, 100); + + /** Blocks shouldn't take too long to resolve. */ + protected static final long LONG_RESOLVE_TIME = 500L; +} diff --git a/src/java/com/threerings/miso/client/SceneObject.java b/src/java/com/threerings/miso/client/SceneObject.java new file mode 100644 index 00000000..b17df38e --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneObject.java @@ -0,0 +1,358 @@ +// +// $Id: SceneObject.java 4007 2006-04-10 08:59:30Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; + +import com.samskivert.swing.RuntimeAdjust; +import com.samskivert.util.StringUtil; + +import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.ObjectTile; +import com.threerings.media.tile.TileUtil; + +import com.threerings.miso.Log; +import com.threerings.miso.MisoPrefs; +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.util.MisoSceneMetrics; +import com.threerings.miso.util.MisoUtil; + +/** + * Contains resolved information on an object in a scene. + */ +public class SceneObject +{ + /** The object's info record. */ + public ObjectInfo info; + + /** The object tile used to display this object. */ + public ObjectTile tile; + + /** The screen coordinate bounds of our object tile given its position + * in the scene. */ + public Rectangle bounds; + + /** + * Creates a scene object for display by the specified panel. The + * appropriate object tile is resolved and the object's in-situ bounds + * are computed. + */ + public SceneObject (MisoScenePanel panel, ObjectInfo info) + { + this.info = info; + + // resolve our object tile + refreshObjectTile(panel); + } + + /** + * Creates a scene object for display by the specified panel. + */ + public SceneObject (MisoScenePanel panel, ObjectInfo info, ObjectTile tile) + { + this(panel.getSceneMetrics(), info, tile); + } + + /** + * Creates a scene object for display according to the supplied metrics. + */ + public SceneObject ( + MisoSceneMetrics metrics, ObjectInfo info, ObjectTile tile) + { + this.info = info; + this.tile = tile; + computeInfo(metrics); + } + + /** + * Used to flag overlapping scene objects that have no resolving + * object priorities. + */ + public void setWarning (boolean warning) + { + _warning = warning; + } + + /** + * Requests that this scene object render itself. + */ + public void paint (Graphics2D gfx) + { + if (_hideObjects.getValue()) { + return; + } + + // if we're rendering footprints, paint that + boolean footpaint = _fprintDebug.getValue(); + if (footpaint) { + gfx.setColor(Color.black); + gfx.draw(_footprint); + } + + // if we have a warning, render an alpha'd red rectangle over our + // bounds + if (_warning) { + Composite ocomp = gfx.getComposite(); + gfx.setComposite(ALPHA_WARN); + gfx.fill(bounds); + gfx.setComposite(ocomp); + } + + // paint our tile + tile.paint(gfx, bounds.x, bounds.y); + + // and possibly paint the object's spot + if (footpaint && _sspot != null) { + // translate the origin to center on the portal + gfx.translate(_sspot.x, _sspot.y); + + // rotate to reflect the spot orientation + double rot = (Math.PI / 4.0f) * tile.getSpotOrient(); + gfx.rotate(rot); + + // draw the spot triangle + gfx.setColor(Color.green); + gfx.fill(_spotTri); + + // outline the triangle in black + gfx.setColor(Color.black); + gfx.draw(_spotTri); + + // restore the original transform + gfx.rotate(-rot); + gfx.translate(-_sspot.x, -_sspot.y); + } + } + + /** + * Returns the location associated with this object's "spot" in fine + * coordinates or null if it has no spot. + */ + public Point getObjectSpot () + { + return _fspot; + } + + /** + * Returns the location associated with this object's "spot" in screen + * coordinates or null if it has no spot. + */ + public Point getObjectScreenSpot () + { + return _sspot; + } + + /** + * Returns true if this object's footprint overlaps that of the + * specified other object. + */ + public boolean objectFootprintOverlaps (SceneObject so) + { + return _frect.intersects(so._frect); + } + + /** + * Returns true if this object's footprint overlaps the supplied tile + * coordinate rectangle. + */ + public boolean objectFootprintOverlaps (Rectangle rect) + { + return _frect.intersects(rect); + } + + /** + * Returns a polygon bounding all footprint tiles of this scene + * object. + * + * @return the bounding polygon. + */ + public Polygon getObjectFootprint () + { + return _footprint; + } + + /** + * Returns the render priority of this scene object. + */ + public int getPriority () + { + // if we have no overridden priority, return our object tile's + // default priority + return (info.priority == 0 && tile != null) ? + tile.getPriority() : info.priority; + } + + /** + * Overrides the render priority of this object. + */ + public void setPriority (byte priority) + { + info.priority = (byte)Math.max( + Byte.MIN_VALUE, Math.min(Byte.MAX_VALUE, priority)); + } + + /** + * Informs this scene object that the mouse is now hovering over it. + * Custom objects may wish to adjust some internal state and return + * true from this method indicating that they should be repainted. + */ + public boolean setHovered (boolean hovered) + { + return false; + } + + /** + * Updates this object's origin tile coordinate. It's bounds and other + * cached screen coordinate information are updated. + */ + public void relocateObject (MisoSceneMetrics metrics, int tx, int ty) + { +// Log.info("Relocating object " + this + " to " + +// StringUtil.coordsToString(tx, ty)); + info.x = tx; + info.y = ty; + computeInfo(metrics); + } + + /** + * Reloads and recolorizes our object tile. It is not intended for the + * actual object tile used by a scene object to change in its + * lifetime, only attributes of that object like its colorizations. So + * don't do anything crazy like change our {@link ObjectInfo}'s + * tileId and call this method or things might break. + */ + public void refreshObjectTile (MisoScenePanel panel) + { + int tsid = TileUtil.getTileSetId(info.tileId); + int tidx = TileUtil.getTileIndex(info.tileId); + try { + tile = (ObjectTile)panel.getTileManager().getTile( + tsid, tidx, panel.getColorizer(info)); + computeInfo(panel.getSceneMetrics()); + + } catch (NoSuchTileSetException te) { + Log.warning("Scene contains non-existent object tileset " + + "[info=" + info + "]."); + } + } + + /** + * Computes our screen bounds, tile footprint and other useful cached + * metrics. + */ + protected void computeInfo (MisoSceneMetrics metrics) + { + // start with the screen coordinates of our origin tile + Point tpos = MisoUtil.tileToScreen( + metrics, info.x, info.y, new Point()); + + // if the tile has an origin coordinate, use that, otherwise + // compute it from the tile footprint + int tox = tile.getOriginX(), toy = tile.getOriginY(); + if (tox == Integer.MIN_VALUE) { + tox = tile.getBaseWidth() * metrics.tilehwid; + } + if (toy == Integer.MIN_VALUE) { + toy = tile.getHeight(); + } + + bounds = new Rectangle(tpos.x + metrics.tilehwid - tox, + tpos.y + metrics.tilehei - toy, + tile.getWidth(), tile.getHeight()); + + // compute our object footprint as well + _frect = new Rectangle(info.x - tile.getBaseWidth() + 1, + info.y - tile.getBaseHeight() + 1, + tile.getBaseWidth(), tile.getBaseHeight()); + _footprint = MisoUtil.getFootprintPolygon( + metrics, _frect.x, _frect.y, _frect.width, _frect.height); + + // compute our object spot if we've got one + if (tile.hasSpot()) { + _fspot = MisoUtil.tilePlusFineToFull( + metrics, info.x, info.y, tile.getSpotX(), tile.getSpotY(), + new Point()); + _sspot = MisoUtil.fullToScreen( + metrics, _fspot.x, _fspot.y, new Point()); + } + +// Log.info("Computed object metrics " + +// "[tpos=" + StringUtil.coordsToString(tx, ty) + +// ", info=" + info + +// ", sbounds=" + StringUtil.toString(bounds) + "]."); + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + return info + "[" + StringUtil.toString(bounds) + "]"; + } + + /** Our object as a tile coordinate rectangle. */ + protected Rectangle _frect; + + /** Our object footprint as a polygon. */ + protected Polygon _footprint; + + /** The full-coordinates of our object spot; or null if we have none. */ + protected Point _fspot; + + /** The screen-coordinates of our object spot; or null if we have none. */ + protected Point _sspot; + + /** Used to mark objects with errors. */ + protected boolean _warning; + + /** A debug hook that toggles rendering of objects. */ + protected static RuntimeAdjust.BooleanAdjust _hideObjects = + new RuntimeAdjust.BooleanAdjust( + "Toggles rendering of objects in the scene view.", + "narya.miso.hide_objects", MisoPrefs.config, false); + + /** A debug hook that toggles rendering of object footprints. */ + protected static RuntimeAdjust.BooleanAdjust _fprintDebug = + new RuntimeAdjust.BooleanAdjust( + "Toggles rendering of object footprints in the scene view.", + "narya.miso.iso_fprint_debug_render", MisoPrefs.config, false); + + /** The triangle used to render an object's spot. */ + protected static Polygon _spotTri; + + static { + _spotTri = new Polygon(); + _spotTri.addPoint(-3, -3); + _spotTri.addPoint(3, -3); + _spotTri.addPoint(0, 3); + }; + + /** The alpha used to fill our bounds for warning purposes. */ + protected static final Composite ALPHA_WARN = + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); +} diff --git a/src/java/com/threerings/miso/client/SceneObjectActionEvent.java b/src/java/com/threerings/miso/client/SceneObjectActionEvent.java new file mode 100644 index 00000000..bd759a52 --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneObjectActionEvent.java @@ -0,0 +1,48 @@ +// +// $Id: SceneObjectActionEvent.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.event.ActionEvent; + +/** + * An {@link ActionEvent} derivation that is fired when a scene object is + * clicked or menu item selected. + */ +public class SceneObjectActionEvent extends ActionEvent +{ + public SceneObjectActionEvent (Object source, int id, String action, + int modifiers, SceneObject scobj) + { + super(source, id, action, modifiers); + _scobj = scobj; + } + + /** + * Returns the scene object that was the source of this action. + */ + public SceneObject getSceneObject () + { + return _scobj; + } + + protected SceneObject _scobj; +} diff --git a/src/java/com/threerings/miso/client/SceneObjectTip.java b/src/java/com/threerings/miso/client/SceneObjectTip.java new file mode 100644 index 00000000..c394e895 --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneObjectTip.java @@ -0,0 +1,206 @@ +// +// $Id: SceneObjectTip.java 4007 2006-04-10 08:59:30Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import java.util.Collection; + +import javax.swing.Icon; +import javax.swing.UIManager; + +import com.samskivert.swing.Label; +import com.samskivert.swing.LabelSausage; +import com.samskivert.util.ComparableArrayList; +import com.samskivert.util.StringUtil; + +/** + * A lightweight tooltip used by the {@link MisoScenePanel}. The tip + * foreground and background are controlled by the following {@link + * UIManager} properties: + * + *

+ * SceneObjectTip.background
+ * SceneObjectTip.foreground
+ * SceneObjectTip.font (falls back to Label.font)
+ * 
+ */ +public class SceneObjectTip extends LabelSausage +{ + /** + * Used to position a scene tip in relation to the object with which + * it is associated. + */ + public static interface TipLayout + { + /** + * Position the supplied tip relative to the supplied scene object. + */ + public void layout (Graphics2D gfx, Rectangle boundary, + SceneObject tipFor, SceneObjectTip tip); + } + + /** The bounding box of this tip, or null prior to layout(). */ + public Rectangle bounds; + + /** + * Construct a SceneObjectTip. + */ + public SceneObjectTip (String text, Icon icon) + { + super(new Label(text, _foreground, _font), icon); + } + + /** + * Called to initialize the tip so that it can be painted. + * + * @param tipFor the scene object that we're a tip for. + * @param boundary the boundary of all displayable space. + * @param othertips other tip boundaries that we should avoid. + */ + public void layout (Graphics2D gfx, SceneObject tipFor, Rectangle boundary, + Collection othertips) + { + layout(gfx, ICON_PAD, EXTRA_PAD); + bounds = new Rectangle(_size); + + // locate the most appropriate tip layout + for (int ii = 0, ll = _layouts.size(); ii < ll; ii++) { + LayoutReg reg = (LayoutReg)_layouts.get(ii); + String act = tipFor.info.action == null ? "" : tipFor.info.action; + if (act.startsWith(reg.prefix)) { + reg.layout.layout(gfx, boundary, tipFor, this); + break; + } + } + } + + /** + * Paint this tip at it's location. + */ + public void paint (Graphics2D gfx) + { + paint(gfx, bounds.x, bounds.y, _background, null); + } + + /** + * Generates a string representation of this instance. + */ + public String toString () + { + return _label.getText() + "[" + StringUtil.toString(bounds) + "]"; + } + + /** + * It may be desirable to layout object tips specially depending on + * what sort of actions they represent, so we allow different tip + * layout algorithms to be registered for particular object prefixes. + * The registration is simply a list searched from longest string to + * shortest string for the first match to an object's action. + */ + public static void registerTipLayout (String prefix, TipLayout layout) + { + LayoutReg reg = new LayoutReg(); + reg.prefix = prefix; + reg.layout = layout; + _layouts.insertSorted(reg); + } + + // documentation inherited + protected void drawBase (Graphics2D gfx, int x, int y) + { + Composite ocomp = gfx.getComposite(); + gfx.setComposite(ALPHA); + super.drawBase(gfx, x, y); + gfx.setComposite(ocomp); + } + + /** The alpha we use for our base. */ + protected static final Composite ALPHA = AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, .75f); + + /** Colors to use when rendering the tip. */ + protected static Color _background, _foreground; + + /** The font to use when rendering the tip. */ + protected static Font _font; + + // initialize resources shared by all tips + static { + _background = UIManager.getColor("SceneObjectTip.background"); + _foreground = UIManager.getColor("SceneObjectTip.foreground"); + _font = UIManager.getFont("SceneObjectTip.font"); + if (_font == null) { + _font = UIManager.getFont("Label.font"); + } + } + + /** Used to store {@link TipLayout} registrations. */ + protected static class LayoutReg implements Comparable + { + /** The prefix that defines our applicability. */ + public String prefix; + + /** The layout to use for objects matching our prefix. */ + public TipLayout layout; + + // documentation inherited from interface + public int compareTo (Object o) { + LayoutReg or = (LayoutReg)o; + if (or.prefix.length() == prefix.length()) { + return or.prefix.compareTo(prefix); + } else { + return or.prefix.length() - prefix.length(); + } + } + } + + /** Our default tip layout algorithm which centers the tip in the + * bounds of the object in question. */ + protected static class DefaultLayout implements TipLayout + { + public void layout (Graphics2D gfx, Rectangle boundary, + SceneObject tipFor, SceneObjectTip tip) { + tip.bounds.setLocation( + tipFor.bounds.x + (tipFor.bounds.width-tip.bounds.width) / 2, + tipFor.bounds.y + (tipFor.bounds.height-tip.bounds.height) / 2); + } + } + + /** Contains a sorted list of layout registrations. */ + protected static ComparableArrayList _layouts = new ComparableArrayList(); + + /** The number of pixels to pad around the icon. */ + protected static final int ICON_PAD = 4; + + /** The number of pixels to pad between the icon and text. */ + protected static final int EXTRA_PAD = 2; + + static { + registerTipLayout("", new DefaultLayout()); + } +} diff --git a/src/java/com/threerings/miso/client/TilePath.java b/src/java/com/threerings/miso/client/TilePath.java new file mode 100644 index 00000000..78cced6e --- /dev/null +++ b/src/java/com/threerings/miso/client/TilePath.java @@ -0,0 +1,144 @@ +// +// $Id: TilePath.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Point; +import java.util.List; + +import com.threerings.util.DirectionCodes; + +import com.threerings.media.sprite.Sprite; +import com.threerings.media.util.LineSegmentPath; +import com.threerings.media.util.MathUtil; + +import com.threerings.miso.util.MisoSceneMetrics; +import com.threerings.miso.util.MisoUtil; + +/** + * The tile path represents a path of tiles through a scene. The path is + * traversed by treating each pair of connected tiles as a line segment. + * Only ambulatory sprites can follow a tile path, and their tile + * coordinates are updated as the path is traversed. + */ +public class TilePath extends LineSegmentPath + implements DirectionCodes +{ + /** + * Constructs a tile path. + * + * @param metrics the metrics for the scene the with which the path is + * associated. + * @param sprite the sprite to follow the path. + * @param tiles the tiles to be traversed during the path. + * @param destx the destination x-position in screen pixel + * coordinates. + * @param desty the destination y-position in screen pixel + * coordinates. + */ + public TilePath (MisoSceneMetrics metrics, Sprite sprite, + List tiles, int destx, int desty) + { + // constrain destination pixels to fine coordinates + Point fpos = new Point(); + MisoUtil.screenToFull(metrics, destx, desty, fpos); + + // add the starting path node + int sx = sprite.getX(), sy = sprite.getY(); + Point ipos = MisoUtil.screenToTile(metrics, sx, sy, new Point()); + addNode(sx, sy, NORTH); + + // TODO: make more visually appealing path segments from start to + // second tile, and penultimate to ultimate tile + + // add all remaining path nodes excepting the last one + Point prev = new Point(ipos.x, ipos.y); + Point spos = new Point(); + int size = tiles.size(); + for (int ii = 1; ii < size - 1; ii++) { + Point next = (Point)tiles.get(ii); + + // determine the direction from previous to next node + int dir = MisoUtil.getIsoDirection(prev.x, prev.y, next.x, next.y); + + // determine the node's position in screen pixel coordinates + MisoUtil.tileToScreen(metrics, next.x, next.y, spos); + + // add the node to the path, wandering through the middle + // of each tile in the path for now + int dsx = spos.x + metrics.tilehwid; + int dsy = spos.y + metrics.tilehhei; + addNode(dsx, dsy, dir); + + prev = next; + } + + // get the final destination point's screen coordinates + // constrained to the closest full coordinate + MisoUtil.fullToScreen(metrics, fpos.x, fpos.y, spos); + + // get the tile coordinates for the final destination tile + int tdestx = MisoUtil.fullToTile(fpos.x); + int tdesty = MisoUtil.fullToTile(fpos.y); + + // get the facing direction for the final node + int dir; + if (prev.x == ipos.x && prev.y == ipos.y) { + // if destination is within starting tile, direction is + // determined by studying the fine coordinates + dir = MisoUtil.getDirection(metrics, sx, sy, spos.x, spos.y); + + } else { + // else it's based on the last tile we traversed + dir = MisoUtil.getIsoDirection(prev.x, prev.y, tdestx, tdesty); + } + + // add the final destination path node + addNode(spos.x, spos.y, dir); + } + + /** + * Returns the estimated number of millis that we'll be traveling + * along this path. + */ + public long getEstimTravelTime () + { + return (long)(_estimPixels / _vel); + } + + // documentation inherited + public void addNode (int x, int y, int dir) + { + super.addNode(x, y, dir); + if (_last == null) { + _last = new Point(); + } else { + _estimPixels += MathUtil.distance(_last.x, _last.y, x, y); + } + _last.setLocation(x, y); + } + + /** Used to compute estimated travel time. */ + protected Point _last; + + /** Estimated pixels traveled. */ + protected int _estimPixels; +} diff --git a/src/java/com/threerings/miso/data/MisoSceneModel.java b/src/java/com/threerings/miso/data/MisoSceneModel.java new file mode 100644 index 00000000..2a6422ff --- /dev/null +++ b/src/java/com/threerings/miso/data/MisoSceneModel.java @@ -0,0 +1,129 @@ +// +// $Id: MisoSceneModel.java 3726 2005-10-11 19:17:43Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.data; + +import java.awt.Rectangle; +import java.util.Random; + +import com.threerings.io.SimpleStreamableObject; + +import com.threerings.miso.util.ObjectSet; + +/** + * Contains basic information for a miso scene model that is shared among + * the specialized model implementations. + */ +public abstract class MisoSceneModel extends SimpleStreamableObject + implements Cloneable +{ + /** + * Creates a completely uninitialized model suitable for little more + * than unserialization. + */ + public MisoSceneModel () + { + } + + /** + * Returns the fully qualified tile id of the base tile at the + * specified coordinates. -1 will be returned if there is + * no tile at the specified coordinate. + */ + public abstract int getBaseTileId (int x, int y); + + /** + * Updates the tile at the specified location in the base layer. + * + *

Note that if there are fringe tiles associated with this scene, + * calling this method may result in the surrounding fringe tiles + * being cleared and subsequently recalculated. This should not be + * called on a displaying scene unless you know what you are doing. + * + * @param fqTileId the fully-qualified tile id (@see + * TileUtil#getFQTileId}) of the tile to set. + * @param x the x-coordinate of the tile to set. + * @param y the y-coordinate of the tile to set. + * + * @return false if the specified tile coordinates are outside of the + * scene and the tile was not saved, true otherwise. + */ + public abstract boolean setBaseTile (int fqTileId, int x, int y); + + /** + * Updates the default base tileset id for this scene. + */ + public void setDefaultBaseTileSet (int tileSetId) + { + // nothing doing + } + + /** + * Scene models can return a default tileset to be used when no base + * tile data exists for a particular tile. + */ + public int getDefaultBaseTileSet () + { + return 0; + } + + /** + * Populates the supplied object set with info on all objects whose + * origin falls in the requested region. + */ + public abstract void getObjects (Rectangle region, ObjectSet set); + + /** + * Adds an object to this scene. + * + * @return true if the object was added, false if the add was rejected + * due to being a duplicate. + */ + public abstract boolean addObject (ObjectInfo info); + + /** + * Updates an object in this scene. + */ + public abstract void updateObject (ObjectInfo info); + + /** + * Removes the specified object from the scene. + * + * @return true if it was removed, false if the object was not in the + * scene. + */ + public abstract boolean removeObject (ObjectInfo info); + + /** + * Creates a copy of this scene model. + */ + public Object clone () + { + try { + return (MisoSceneModel)super.clone(); + } catch (CloneNotSupportedException cnse) { + throw new RuntimeException("MisoSceneModel.clone: " + cnse); + } + } + + /** A random number generator for filling random base tiles. */ + protected transient Random _rando = new Random(); +} diff --git a/src/java/com/threerings/miso/data/ObjectInfo.java b/src/java/com/threerings/miso/data/ObjectInfo.java new file mode 100644 index 00000000..70c5ccb8 --- /dev/null +++ b/src/java/com/threerings/miso/data/ObjectInfo.java @@ -0,0 +1,168 @@ +// +// $Id: ObjectInfo.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.data; + +import com.samskivert.util.StringUtil; + +import com.threerings.io.SimpleStreamableObject; +import com.threerings.media.tile.TileUtil; + +/** + * Contains information about an object in a Miso scene. + */ +public class ObjectInfo extends SimpleStreamableObject + implements Cloneable +{ + /** The fully qualified object tile id. */ + public int tileId; + + /** The x and y tile coordinates of the object. */ + public int x, y; + + /** Don't access this directly unless you are serializing this + * instance. Use {@link #getPriority} instead. */ + public byte priority = 0; + + /** The action associated with this object or null if it has no + * action. */ + public String action; + + /** A "spot" associated with this object (specified as an offset from + * the fine coordinates of the object's origin tile). */ + public byte sx, sy; + + /** The orientation of the "spot" associated with this object. */ + public byte sorient; + + /** Up to two colorization assignments for this object. */ + public int zations; + + /** + * Convenience constructor. + */ + public ObjectInfo (int tileId, int x, int y) + { + this.tileId = tileId; + this.x = x; + this.y = y; + } + + /** + * Creates an object info that is a copy of the supplied info. + */ + public ObjectInfo (ObjectInfo other) + { + this.tileId = other.tileId; + this.x = other.x; + this.y = other.y; + this.priority = other.priority; + this.action = other.action; + this.sx = other.sx; + this.sy = other.sy; + this.sorient = other.sorient; + this.zations = other.zations; + } + + /** + * Zero argument constructor needed for unserialization. + */ + public ObjectInfo () + { + } + + /** + * Returns the render priority of this object tile. + */ + public int getPriority () + { + return priority; + } + + /** + * Returns the primary colorization assignment. + */ + public int getPrimaryZation () + { + return (zations & 0xFFFF); + } + + /** + * Returns the secondary colorization assignment. + */ + public int getSecondaryZation () + { + return ((zations >> 16) & 0xFFFF); + } + + /** + * Sets the primary and secondary colorization assignments. + */ + public void setZations (short primary, short secondary) + { + zations = ((secondary << 16) | primary); + } + + /** + * Returns true if this object info contains non-default data for + * anything other than the tile id and coordinates. + */ + public boolean isInteresting () + { + return (!StringUtil.isBlank(action) || priority != 0 || + sx != 0 || sy != 0 || zations != 0); + } + + // documentation inherited + public boolean equals (Object other) + { + if (other instanceof ObjectInfo) { + ObjectInfo ooi = (ObjectInfo)other; + return (x == ooi.x && y == ooi.y && tileId == ooi.tileId); + } else { + return false; + } + } + + // documentation inherited + public int hashCode () + { + return x ^ y ^ tileId; + } + + // documentation inherited + public Object clone () + { + try { + return super.clone(); + } catch (CloneNotSupportedException cnse) { + // notgunnahappen. + return null; + } + } + + /** Enhances our {@link SimpleStreamableObject#toString} output. */ + public String tileIdToString () + { + return (TileUtil.getTileSetId(tileId) + ":" + + TileUtil.getTileIndex(tileId)); + } +} diff --git a/src/java/com/threerings/miso/data/SimpleMisoSceneModel.java b/src/java/com/threerings/miso/data/SimpleMisoSceneModel.java new file mode 100644 index 00000000..79256f8b --- /dev/null +++ b/src/java/com/threerings/miso/data/SimpleMisoSceneModel.java @@ -0,0 +1,282 @@ +// +// $Id: SimpleMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.data; + +import java.awt.Rectangle; +import java.util.ArrayList; + +import com.samskivert.util.ArrayUtil; +import com.samskivert.util.IntListUtil; +import com.samskivert.util.ListUtil; + +import com.threerings.media.util.MathUtil; +import com.threerings.miso.util.ObjectSet; + +/** + * Contains miso scene data for a scene that is assumed to be reasonably + * simple and small, such that all base tile data for the entire scene can + * be stored in a single contiguous array. + * + *

Additionally, it makes the assumption that the single model will be + * used to display a scene on a rectangular screen (dimensions defined by + * {@link #vwidth} and {@link #vheight}) and further optimizes the base + * tile array to obviate the need to store tile data for things that fall + * outside the bounds of the screen. + */ +public class SimpleMisoSceneModel extends MisoSceneModel +{ + /** The width of this scene in tiles. */ + public short width; + + /** The height of this scene in tiles. */ + public short height; + + /** The viewport width in tiles. */ + public int vwidth; + + /** The viewport height in tiles. */ + public int vheight; + + /** The combined tile ids (tile set id and tile id) in compressed + * format. Don't go poking around in here, use the accessor + * methods. */ + public int[] baseTileIds; + + /** The combined tile ids (tile set id and tile id) of the + * "uninteresting" tiles in the object layer. */ + public int[] objectTileIds; + + /** The x coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectXs; + + /** The y coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectYs; + + /** Information records for the "interesting" objects in the object + * layer. */ + public ObjectInfo[] objectInfo; + + /** + * Creates a completely uninitialized model suitable for little more + * than unserialization. + */ + public SimpleMisoSceneModel () + { + } + + /** + * Creates a blank scene model with the specified dimensions. + */ + public SimpleMisoSceneModel (int width, int height, int vwidth, int vheight) + { + this.width = (short)MathUtil.bound( + Short.MIN_VALUE, width, Short.MAX_VALUE); + this.height = (short)MathUtil.bound( + Short.MIN_VALUE, height, Short.MAX_VALUE); + this.vwidth = vwidth; + this.vheight = vheight; + allocateBaseTileArray(); + + // start with zero-length object arrays + objectTileIds = new int[0]; + objectXs = new short[0]; + objectYs = new short[0]; + objectInfo = new ObjectInfo[0]; + } + + // documentation inherited + public int getBaseTileId (int col, int row) + { + int index = getIndex(col, row); + return (index == -1) ? 0 : baseTileIds[index]; + } + + // documentation inherited + public boolean setBaseTile (int fqBaseTileId, int col, int row) + { + int index = getIndex(col, row); + if (index == -1) { + return false; + } + baseTileIds[index] = fqBaseTileId; + return true; + } + + // documentation inherited + public void getObjects (Rectangle region, ObjectSet set) + { + // first look for intersecting interesting objects + for (int ii = 0; ii < objectInfo.length; ii++) { + ObjectInfo info = objectInfo[ii]; + if (region.contains(info.x, info.y)) { + set.insert(info); + } + } + + // now look for intersecting non-interesting objects + for (int ii = 0; ii < objectTileIds.length; ii++) { + int x = objectXs[ii], y = objectYs[ii]; + if (region.contains(x, y)) { + set.insert(new ObjectInfo(objectTileIds[ii], x, y)); + } + } + } + + // documentation inherited + public boolean addObject (ObjectInfo info) + { + if (info.isInteresting()) { + objectInfo = (ObjectInfo[])ArrayUtil.append(objectInfo, info); + } else { + objectTileIds = ArrayUtil.append(objectTileIds, info.tileId); + objectXs = ArrayUtil.append(objectXs, (short)info.x); + objectYs = ArrayUtil.append(objectYs, (short)info.y); + } + return true; + } + + // documentation inherited + public void updateObject (ObjectInfo info) + { + // not efficient, but this is only done in editing situations + removeObject(info); + addObject(info); + } + + // documentation inherited + public boolean removeObject (ObjectInfo info) + { + // look for it in the interesting info array + int oidx = ListUtil.indexOf(objectInfo, info); + if (oidx != -1) { + objectInfo = (ObjectInfo[])ArrayUtil.splice(objectInfo, oidx, 1); + return true; + } + + // look for it in the uninteresting arrays + oidx = IntListUtil.indexOf(objectTileIds, info.tileId); + if (oidx != -1) { + objectTileIds = ArrayUtil.splice(objectTileIds, oidx, 1); + objectXs = ArrayUtil.splice(objectXs, oidx, 1); + objectYs = ArrayUtil.splice(objectYs, oidx, 1); + return true; + } + + return false; + } + + // documentation inherited + public Object clone () + { + SimpleMisoSceneModel model = (SimpleMisoSceneModel)super.clone(); + model.baseTileIds = (int[])baseTileIds.clone(); + model.objectTileIds = (int[])objectTileIds.clone(); + model.objectXs = (short[])objectXs.clone(); + model.objectYs = (short[])objectYs.clone(); + model.objectInfo = (ObjectInfo[])objectInfo.clone(); + return model; + } + + /** + * Get the index into the baseTileIds[] for the specified + * x and y coordinates, or return -1 if the specified coordinates + * are outside of the viewable area. + * + * Assumption: The viewable area is centered and aligned as far + * to the top of the isometric scene as possible, such that + * the upper-left corner is at the point where the tiles + * (0, vwid) and (0, vwid-1) touch. The upper-right corner + * is at the point where the tiles (vwid-1, 0) and (vwid, 0) + * touch. + * + * The viewable area is made up of "fat" rows and "thin" rows. The + * fat rows display one more tile than the thin rows because their + * first and last tiles are halfway off the viewable area. The thin + * rows are fully contained within the viewable area except for the + * first and last thin rows, which display only their bottom and top + * halves, respectively. Note that #fatrows == #thinrows - 1; + */ + protected int getIndex (int x, int y) + { + // check to see if the index lies in one of the "fat" rows + if (((x + y) & 1) == (vwidth & 1)) { + + int col = (vwidth + x - y) >> 1; + int row = x - col; + if ((col < 0) || (col > vwidth) || + (row < 0) || (row >= vheight)) { + return -1; // out of view + } + + return (vwidth + 1) * row + col; + + } else { + // the index must be in a "thin" row + int col = (vwidth + x - y - 1) >> 1; + int row = x - col; + if ((col < 0) || (col >= vwidth) || + (row < 0) || (row > vheight)) { + return -1; // out of view + } + + // we store the all the fat rows first, then all the thin + // rows, the '(vwidth + 1) * vheight' is the size of all + // the fat rows. + return row * vwidth + col + (vwidth + 1) * vheight; + } + } + + /** + * Allocate the base tile array. + */ + protected void allocateBaseTileArray () + { + baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)]; + } + + /** + * Populates the interesting and uninteresting parts of a miso scene + * model given lists of {@link ObjectInfo} records for each. + */ + public static void populateObjects (SimpleMisoSceneModel model, + ArrayList ilist, ArrayList ulist) + { + // set up the uninteresting arrays + int ucount = ulist.size(); + model.objectTileIds = new int[ucount]; + model.objectXs = new short[ucount]; + model.objectYs = new short[ucount]; + for (int ii = 0; ii < ucount; ii++) { + ObjectInfo info = (ObjectInfo)ulist.get(ii); + model.objectTileIds[ii] = info.tileId; + model.objectXs[ii] = (short)info.x; + model.objectYs[ii] = (short)info.y; + } + + // set up the interesting array + int icount = ilist.size(); + model.objectInfo = new ObjectInfo[icount]; + ilist.toArray(model.objectInfo); + } +} diff --git a/src/java/com/threerings/miso/data/SparseMisoSceneModel.java b/src/java/com/threerings/miso/data/SparseMisoSceneModel.java new file mode 100644 index 00000000..8617f8c8 --- /dev/null +++ b/src/java/com/threerings/miso/data/SparseMisoSceneModel.java @@ -0,0 +1,445 @@ +// +// $Id: SparseMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.data; + +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Iterator; + +import com.samskivert.util.ArrayUtil; +import com.samskivert.util.ListUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.io.SimpleStreamableObject; + +import com.threerings.media.util.MathUtil; +import com.threerings.util.StreamableHashIntMap; + +import com.threerings.miso.Log; +import com.threerings.miso.util.ObjectSet; + +/** + * Contains miso scene data that is broken up into NxN tile sections. + */ +public class SparseMisoSceneModel extends MisoSceneModel +{ + /** An interface that allows external entities to "visit" and inspect + * every object in this scene. */ + public static interface ObjectVisitor + { + /** Called for each object in the scene, interesting and not. */ + public void visit (ObjectInfo info); + } + + /** Contains information on a section of this scene. This is only + * public so that the scene model parser can do its job, so don't go + * poking around in here. */ + public static class Section extends SimpleStreamableObject + implements Cloneable + { + /** The tile coordinate of our upper leftmost tile. */ + public short x, y; + + /** The width of this section in tiles. */ + public int width; + + /** The combined tile ids (tile set id and tile id) for our + * section (in row major order). */ + public int[] baseTileIds; + + /** The combined tile ids (tile set id and tile id) of the + * "uninteresting" tiles in the object layer. */ + public int[] objectTileIds = new int[0]; + + /** The x coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectXs = new short[0]; + + /** The y coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectYs = new short[0]; + + /** Information records for the "interesting" objects in the + * object layer. */ + public ObjectInfo[] objectInfo = new ObjectInfo[0]; + + /** + * Creates a blank section instance, suitable for unserialization + * or configuration by the XML scene parser. + */ + public Section () + { + } + + /** + * Creates a new scene section with the specified dimensions. + */ + public Section (short x, short y, short width, short height) + { + this.x = x; + this.y = y; + this.width = width; + baseTileIds = new int[width*height]; + } + + public int getBaseTileId (int col, int row) { + if (col < x || col >= (x+width) || row < y || row >= (y+width)) { + Log.warning("Requested bogus tile +" + col + "+" + row + + " from " + this + "."); + return -1; + } else { + return baseTileIds[(row-y)*width+(col-x)]; + } + } + + public void setBaseTile (int col, int row, int fqBaseTileId) { + baseTileIds[(row-y)*width+(col-x)] = fqBaseTileId; + } + + public boolean addObject (ObjectInfo info) { + // sanity check: see if there is already an object of this + // type at these coordinates + int dupidx; + if ((dupidx = ListUtil.indexOf(objectInfo, info)) != -1) { + Log.warning("Refusing to add duplicate object [ninfo=" + info + + ", oinfo=" + objectInfo[dupidx] + "]."); + return false; + } + if ((dupidx = indexOfUn(info)) != -1) { + Log.warning("Refusing to add duplicate object " + + "[info=" + info + "]."); + return false; + } + + if (info.isInteresting()) { + objectInfo = (ObjectInfo[])ArrayUtil.append(objectInfo, info); + } else { + objectTileIds = ArrayUtil.append(objectTileIds, info.tileId); + objectXs = ArrayUtil.append(objectXs, (short)info.x); + objectYs = ArrayUtil.append(objectYs, (short)info.y); + } + return true; + } + + public boolean removeObject (ObjectInfo info) { + // look for it in the interesting info array + int oidx = ListUtil.indexOf(objectInfo, info); + if (oidx != -1) { + objectInfo = (ObjectInfo[]) + ArrayUtil.splice(objectInfo, oidx, 1); + return true; + } + + // look for it in the uninteresting arrays + oidx = indexOfUn(info); + if (oidx != -1) { + objectTileIds = ArrayUtil.splice(objectTileIds, oidx, 1); + objectXs = ArrayUtil.splice(objectXs, oidx, 1); + objectYs = ArrayUtil.splice(objectYs, oidx, 1); + return true; + } + + return false; + } + + /** + * Returns the index of the specified object in the uninteresting + * arrays or -1 if it is not in this section as an uninteresting + * object. + */ + protected int indexOfUn (ObjectInfo info) + { + for (int ii = 0; ii < objectTileIds.length; ii++) { + if (objectTileIds[ii] == info.tileId && + objectXs[ii] == info.x && objectYs[ii] == info.y) { + return ii; + } + } + return -1; + } + + public void getObjects (Rectangle region, ObjectSet set) { + // first look for intersecting interesting objects + for (int ii = 0; ii < objectInfo.length; ii++) { + ObjectInfo info = objectInfo[ii]; + if (region.contains(info.x, info.y)) { + set.insert(info); + } + } + + // now look for intersecting non-interesting objects + for (int ii = 0; ii < objectTileIds.length; ii++) { + int x = objectXs[ii], y = objectYs[ii]; + if (region.contains(x, y)) { + set.insert(new ObjectInfo(objectTileIds[ii], x, y)); + } + } + } + + /** + * Returns true if this section contains no data beyond the default. + * Used when saving a sparse scene: we omit blank sections. + */ + public boolean isBlank () + { + if ((objectTileIds.length != 0) || (objectInfo.length != 0)) { + return false; + } + for (int ii=0, nn=baseTileIds.length; ii < nn; ii++) { + if (baseTileIds[ii] != 0) { + return false; + } + } + + return true; + } + + public Object clone () { + try { + Section section = (Section)super.clone(); + section.baseTileIds = (int[])baseTileIds.clone(); + section.objectTileIds = (int[])objectTileIds.clone(); + section.objectXs = (short[])objectXs.clone(); + section.objectYs = (short[])objectYs.clone(); + section.objectInfo = (ObjectInfo[])objectInfo.clone(); + return section; + } catch (CloneNotSupportedException cnse) { + throw new RuntimeException( + "SparseMisoSceneModel.Section.clone: " + cnse); + } + } + + public String toString () { + return ((width == 0) ? "" : + (width + "x" + (baseTileIds.length/width))) + + "+" + x + "+" + y + + ":" + objectInfo.length + ":" + objectTileIds.length; + } + } + + /** The dimensions of a section of our scene. */ + public short swidth, sheight; + + /** The tileset to use when we have no tile data. */ + public int defTileSet = 0; + + /** + * Creates a scene model with the specified bounds. + * + * @param swidth the width of a single section (in tiles). + * @param sheight the height of a single section (in tiles). + */ + public SparseMisoSceneModel (int swidth, int sheight) + { + this.swidth = (short)swidth; + this.sheight = (short)sheight; + } + + /** + * Creates a blank model suitable for unserialization. + */ + public SparseMisoSceneModel () + { + } + + /** + * Adds all interesting {@link ObjectInfo} records in this scene to + * the supplied list. + */ + public void getInterestingObjects (ArrayList list) + { + for (Iterator iter = getSections(); iter.hasNext(); ) { + Section sect = (Section)iter.next(); + for (int oo = 0; oo < sect.objectInfo.length; oo++) { + list.add(sect.objectInfo[oo]); + } + } + } + + /** + * Informs the supplied visitor of each object in this scene. + */ + public void visitObjects (ObjectVisitor visitor) + { + visitObjects(visitor, false); + } + + /** + * Informs the supplied visitor of each object in this scene. + * + * @param interestingOnly if true, only the interesting objects will + * be visited. + */ + public void visitObjects (ObjectVisitor visitor, boolean interestingOnly) + { + for (Iterator iter = getSections(); iter.hasNext(); ) { + Section sect = (Section)iter.next(); + for (int oo = 0; oo < sect.objectInfo.length; oo++) { + ObjectInfo oinfo = sect.objectInfo[oo]; + visitor.visit(oinfo); + } + if (!interestingOnly) { + ObjectInfo info = new ObjectInfo(); + for (int oo = 0; oo < sect.objectTileIds.length; oo++) { + info.tileId = sect.objectTileIds[oo]; + info.x = sect.objectXs[oo]; + info.y = sect.objectYs[oo]; + visitor.visit(info); + } + } + } + } + + // documentation inherited + public int getBaseTileId (int col, int row) + { + Section sec = getSection(col, row, false); + return (sec == null) ? -1 : sec.getBaseTileId(col, row); + } + + // documentation inherited + public boolean setBaseTile (int fqBaseTileId, int col, int row) + { + getSection(col, row, true).setBaseTile(col, row, fqBaseTileId); + return true; + } + + // documentation inherited + public void setDefaultBaseTileSet (int tileSetId) + { + defTileSet = tileSetId; + } + + // documentation inherited + public int getDefaultBaseTileSet () + { + return defTileSet; + } + + // documentation inherited + public void getObjects (Rectangle region, ObjectSet set) + { + int minx = MathUtil.floorDiv(region.x, swidth)*swidth; + int maxx = MathUtil.floorDiv(region.x+region.width-1, swidth)*swidth; + int miny = MathUtil.floorDiv(region.y, sheight)*sheight; + int maxy = MathUtil.floorDiv(region.y+region.height-1, sheight)*sheight; + for (int yy = miny; yy <= maxy; yy += sheight) { + for (int xx = minx; xx <= maxx; xx += swidth) { + Section sec = getSection(xx, yy, false); + if (sec != null) { + sec.getObjects(region, set); + } + } + } + } + + // documentation inherited + public boolean addObject (ObjectInfo info) + { + return getSection(info.x, info.y, true).addObject(info); + } + + // documentation inherited + public void updateObject (ObjectInfo info) + { + // not efficient, but this is only done in editing situations + removeObject(info); + addObject(info); + } + + // documentation inherited + public boolean removeObject (ObjectInfo info) + { + Section sec = getSection(info.x, info.y, false); + if (sec != null) { + return sec.removeObject(info); + } else { + return false; + } + } + + /** + * Don't call this method! This is only public so that the scene + * parser can construct a scene from raw data. If only Java supported + * class friendship. + */ + public void setSection (Section section) + { + _sections.put(key(section.x, section.y), section); + } + + /** + * Don't call this method! This is only public so that the scene + * writer can generate XML from the raw scene data. + */ + public Iterator getSections () + { + return _sections.values().iterator(); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", sections=" + + StringUtil.toString(_sections.values().iterator())); + } + + /** + * Returns the key for the specified section. + */ + protected final int key (int x, int y) + { + int sx = MathUtil.floorDiv(x, swidth); + int sy = MathUtil.floorDiv(y, sheight); + return (sx << 16) | (sy & 0xFFFF); + } + + /** Returns the section for the specified tile coordinate. */ + protected final Section getSection (int x, int y, boolean create) + { + int key = key(x, y); + Section sect = (Section)_sections.get(key); + if (sect == null && create) { + short sx = (short)(MathUtil.floorDiv(x, swidth)*swidth); + short sy = (short)(MathUtil.floorDiv(y, sheight)*sheight); + _sections.put(key, sect = new Section(sx, sy, swidth, sheight)); +// Log.info("Created new section " + sect + "."); + } + return sect; + } + + // documentation inherited + public Object clone () + { + SparseMisoSceneModel model = (SparseMisoSceneModel)super.clone(); + model._sections = new StreamableHashIntMap(); + for (Iterator iter = getSections(); iter.hasNext(); ) { + Section sect = (Section)iter.next(); + model.setSection((Section)sect.clone()); + } + return model; + } + + /** Contains our sections in row major order. */ + protected StreamableHashIntMap _sections = new StreamableHashIntMap(); +} diff --git a/src/java/com/threerings/miso/data/VirtualMisoSceneModel.java b/src/java/com/threerings/miso/data/VirtualMisoSceneModel.java new file mode 100644 index 00000000..299fdd65 --- /dev/null +++ b/src/java/com/threerings/miso/data/VirtualMisoSceneModel.java @@ -0,0 +1,58 @@ +// +// $Id: VirtualMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.data; + +/** + * A convenient base class for "virtual" scenes which do not allow editing + * and compute the base and object tiles rather than obtain them from some + * data structure. + */ +public abstract class VirtualMisoSceneModel extends MisoSceneModel +{ + public VirtualMisoSceneModel () + { + } + + // documentation inherited from interface + public boolean setBaseTile (int fqTileId, int x, int y) + { + throw new UnsupportedOperationException(); + } + + // documentation inherited from interface + public boolean addObject (ObjectInfo info) + { + throw new UnsupportedOperationException(); + } + + // documentation inherited from interface + public void updateObject (ObjectInfo info) + { + throw new UnsupportedOperationException(); + } + + // documentation inherited from interface + public boolean removeObject (ObjectInfo info) + { + throw new UnsupportedOperationException(); + } +} diff --git a/src/java/com/threerings/miso/tile/AutoFringer.java b/src/java/com/threerings/miso/tile/AutoFringer.java new file mode 100644 index 00000000..be302f13 --- /dev/null +++ b/src/java/com/threerings/miso/tile/AutoFringer.java @@ -0,0 +1,390 @@ +// +// $Id: AutoFringer.java 4145 2006-05-24 01:24:24Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile; + +import java.awt.Graphics2D; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; + +import com.samskivert.util.CheapIntMap; +import com.samskivert.util.QuickSort; + +import com.threerings.media.image.BufferedMirage; +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.ImageUtil; + +import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.Tile; +import com.threerings.media.tile.TileManager; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TileUtil; + +import com.threerings.miso.Log; +import com.threerings.miso.data.MisoSceneModel; + +/** + * Automatically fringes a scene according to the rules in the supplied + * fringe configuration. + */ +public class AutoFringer +{ + /** + * Constructs an instance that will fringe according to the rules in + * the supplied fringe configuration. + */ + public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr, + TileManager tmgr) + { + _fringeconf = fringeconf; + _imgr = imgr; + _tmgr = tmgr; + } + + /** + * Compute and return the fringe tile to be inserted at the specified + * location. + */ + public BaseTile getFringeTile (MisoSceneModel scene, int col, int row, + HashMap masks) + { + // get the tileset id of the base tile we are considering + int underset = scene.getBaseTileId(col, row) >> 16; + + // start with a clean temporary fringer map + _fringers.clear(); + boolean passable = true; + + // walk through our influence tiles + for (int y = row - 1, maxy = row + 2; y < maxy; y++) { + for (int x = col - 1, maxx = col + 2; x < maxx; x++) { + // we sensibly do not consider ourselves + if ((x == col) && (y == row)) { + continue; + } + + // determine the tileset for this tile + int btid = scene.getBaseTileId(x, y); + int baseset = (btid <= 0) ? + scene.getDefaultBaseTileSet() : (btid >> 16); + + // determine if it fringes on our tile + int pri = _fringeconf.fringesOn(baseset, underset); + if (pri == -1) { + continue; + } + + FringerRec fringer = (FringerRec)_fringers.get(baseset); + if (fringer == null) { + fringer = new FringerRec(baseset, pri); + _fringers.put(baseset, fringer); + } + + // now turn on the appropriate fringebits + fringer.bits |= FLAGMATRIX[y - row + 1][x - col + 1]; + + // See if a tile that fringes on us kills our passability, + // but don't count the default base tile against us, as + // we allow users to splash in the water. + if (passable && (btid > 0)) { + try { + BaseTile bt = (BaseTile) _tmgr.getTile(btid); + passable = bt.isPassable(); + } catch (NoSuchTileSetException nstse) { + Log.warning("Autofringer couldn't find a base " + + "set while attempting to figure passability " + + "[error=" + nstse + "]."); + } + } + } + } + + // if nothing fringed, we're done + int numfringers = _fringers.size(); + if (numfringers == 0) { + return null; + } + + // otherwise compose a FringeTile from the specified fringes + FringerRec[] frecs = new FringerRec[numfringers]; + for (int ii = 0, pp = 0; ii < 16; ii++) { + FringerRec rec = (FringerRec)_fringers.getValue(ii); + if (rec != null) { + frecs[pp++] = rec; + } + } + + BaseTile frTile = new BaseTile(); + frTile.setPassable(passable); + composeFringeTile(frTile, frecs, masks, TileUtil.getTileHash(col, row)); + return frTile; + } + + /** + * Compose a FringeTile out of the various fringe images needed. + */ + protected void composeFringeTile ( + Tile frTile, FringerRec[] fringers, HashMap masks, int hashValue) + { + // sort the array so that higher priority fringers get drawn first + QuickSort.sort(fringers); + + BufferedImage ftimg = null; + for (int ii = 0; ii < fringers.length; ii++) { + int[] indexes = getFringeIndexes(fringers[ii].bits); + for (int jj = 0; jj < indexes.length; jj++) { + try { + ftimg = getTileImage(ftimg, fringers[ii].baseset, + indexes[jj], masks, hashValue); + } catch (NoSuchTileSetException nstse) { + Log.warning("Autofringer couldn't find a needed tileset " + + "[error=" + nstse + "]."); + } + } + } + + frTile.setImage(new BufferedMirage(ftimg)); + } + + /** + * Retrieve or compose an image for the specified fringe. + */ + protected BufferedImage getTileImage ( + BufferedImage ftimg, int baseset, int index, + HashMap masks, int hashValue) + throws NoSuchTileSetException + { + FringeConfiguration.FringeTileSetRecord tsr = + _fringeconf.getFringe(baseset, hashValue); + int fringeset = tsr.fringe_tsid; + TileSet fset = _tmgr.getTileSet(fringeset); + + if (!tsr.mask) { + // oh good, this is easy + Tile stamp = fset.getTile(index); + return stampTileImage(stamp, ftimg, stamp.getWidth(), + stamp.getHeight()); + } + + // otherwise, it's a mask.. look for it in the cache.. + Long maskkey = Long.valueOf((((long) baseset) << 32) + + (fringeset << 16) + index); + BufferedImage img = (BufferedImage)masks.get(maskkey); + if (img == null) { + BufferedImage fsrc = fset.getRawTileImage(index); + BufferedImage bsrc = _tmgr.getTileSet(baseset).getRawTileImage(0); + img = ImageUtil.composeMaskedImage(_imgr, fsrc, bsrc); + masks.put(maskkey, img); + } + ftimg = stampTileImage(img, ftimg, img.getWidth(null), + img.getHeight(null)); + + return ftimg; + } + + /** Helper function for {@link #getTileImage}. */ + protected BufferedImage stampTileImage (Object stamp, BufferedImage ftimg, + int width, int height) + { + // create the target image if necessary + if (ftimg == null) { + ftimg = _imgr.createImage(width, height, Transparency.BITMASK); + } + Graphics2D gfx = (Graphics2D)ftimg.getGraphics(); + try { + if (stamp instanceof Tile) { + ((Tile)stamp).paint(gfx, 0, 0); + } else { + gfx.drawImage((BufferedImage)stamp, 0, 0, null); + } + } finally { + gfx.dispose(); + } + return ftimg; + } + + /** + * Get the fringe index specified by the fringebits. If no index + * is available, try breaking down the bits into contiguous regions of + * bits and look for indexes for those. + */ + protected int[] getFringeIndexes (int bits) + { + int index = BITS_TO_INDEX[bits]; + if (index != -1) { + int[] ret = new int[1]; + ret[0] = index; + return ret; + } + + // otherwise, split the bits into contiguous components + + // look for a zero and start our first split + int start = 0; + while ((((1 << start) & bits) != 0) && (start < NUM_FRINGEBITS)) { + start++; + } + + if (start == NUM_FRINGEBITS) { + // we never found an empty fringebit, and since index (above) + // was already -1, we have no fringe tile for these bits.. sad. + return new int[0]; + } + + ArrayList indexes = new ArrayList(); + int weebits = 0; + for (int ii=(start + 1) % NUM_FRINGEBITS; ii != start; + ii = (ii + 1) % NUM_FRINGEBITS) { + + if (((1 << ii) & bits) != 0) { + weebits |= (1 << ii); + } else if (weebits != 0) { + index = BITS_TO_INDEX[weebits]; + if (index != -1) { + indexes.add(Integer.valueOf(index)); + } + weebits = 0; + } + } + if (weebits != 0) { + index = BITS_TO_INDEX[weebits]; + if (index != -1) { + indexes.add(Integer.valueOf(index)); + } + } + + int[] ret = new int[indexes.size()]; + for (int ii=0; ii < ret.length; ii++) { + ret[ii] = ((Integer) indexes.get(ii)).intValue(); + } + return ret; + } + + /** + * A record for holding information about a particular fringe as we're + * computing what it will look like. + */ + static protected class FringerRec implements Comparable + { + int baseset; + int priority; + int bits; + + public FringerRec (int base, int pri) + { + baseset = base; + priority = pri; + } + + public int compareTo (Object o) + { + return priority - ((FringerRec) o).priority; + } + + public String toString () + { + return "[base=" + baseset + ", pri=" + priority + + ", bits=" + Integer.toString(bits, 16) + "]"; + } + } + + // fringe bits + // see docs/miso/fringebits.png + // + protected static final int NORTH = 1 << 0; + protected static final int NORTHEAST = 1 << 1; + protected static final int EAST = 1 << 2; + protected static final int SOUTHEAST = 1 << 3; + protected static final int SOUTH = 1 << 4; + protected static final int SOUTHWEST = 1 << 5; + protected static final int WEST = 1 << 6; + protected static final int NORTHWEST = 1 << 7; + + protected static final int NUM_FRINGEBITS = 8; + + // A matrix mapping adjacent tiles to which fringe bits + // they affect. + // (x and y are offset by +1, since we can't have -1 as an array index) + // again, see docs/miso/fringebits.png + // + protected static final int[][] FLAGMATRIX = { + { NORTHEAST, (NORTHEAST | EAST | SOUTHEAST), SOUTHEAST }, + { (NORTHWEST | NORTH | NORTHEAST), 0, (SOUTHEAST | SOUTH | SOUTHWEST) }, + { NORTHWEST, (NORTHWEST | WEST | SOUTHWEST), SOUTHWEST } + }; + + /** + * The fringe tiles we use. These are the 17 possible tiles made + * up of continuous fringebits sections. + * Huh? see docs/miso/fringebits.png + */ + protected static final int[] FRINGETILES = { + SOUTHEAST, + SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHWEST, + NORTHEAST | EAST | SOUTHEAST, + NORTHWEST | WEST | SOUTHWEST, + NORTHEAST, + NORTHWEST | NORTH | NORTHEAST, + NORTHWEST, + + SOUTHWEST | WEST | NORTHWEST | NORTH | NORTHEAST, + NORTHWEST | NORTH | NORTHEAST | EAST | SOUTHEAST, + NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, + + NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, + SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST, + SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST, + NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, + + // all the directions! + NORTH | NORTHEAST | EAST | SOUTHEAST | + SOUTH | SOUTHWEST | WEST | NORTHWEST + }; + + // A reverse map of the above array, for quickly looking up which tile + // we want. + protected static final int[] BITS_TO_INDEX; + + // Construct the BITS_TO_INDEX array. + static { + int num = (1 << NUM_FRINGEBITS); + BITS_TO_INDEX = new int[num]; + + // first clear everything to -1 (meaning there is no tile defined) + for (int ii=0; ii < num; ii++) { + BITS_TO_INDEX[ii] = -1; + } + + // then fill in with the defined tiles. + for (int ii=0; ii < FRINGETILES.length; ii++) { + BITS_TO_INDEX[FRINGETILES[ii]] = ii; + } + } + + protected ImageManager _imgr; + protected TileManager _tmgr; + protected FringeConfiguration _fringeconf; + protected CheapIntMap _fringers = new CheapIntMap(16); +} diff --git a/src/java/com/threerings/miso/tile/BaseTile.java b/src/java/com/threerings/miso/tile/BaseTile.java new file mode 100644 index 00000000..b39107a5 --- /dev/null +++ b/src/java/com/threerings/miso/tile/BaseTile.java @@ -0,0 +1,52 @@ +// +// $Id: BaseTile.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile; + +import com.threerings.media.tile.Tile; + +/** + * Extends the tile class to add support for tile passability. + * + * @see BaseTileSet + */ +public class BaseTile extends Tile +{ + /** + * Returns whether or not this tile can be walked upon by character + * sprites. + */ + public boolean isPassable () + { + return _passable; + } + + /** + * Configures this base tile as passable or impassable. + */ + public void setPassable (boolean passable) + { + _passable = passable; + } + + /** Whether the tile is passable. */ + protected boolean _passable = true; +} diff --git a/src/java/com/threerings/miso/tile/BaseTileSet.java b/src/java/com/threerings/miso/tile/BaseTileSet.java new file mode 100644 index 00000000..81ba4b97 --- /dev/null +++ b/src/java/com/threerings/miso/tile/BaseTileSet.java @@ -0,0 +1,81 @@ +// +// $Id: BaseTileSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile; + +import com.samskivert.util.StringUtil; + +import com.threerings.media.image.Colorization; +import com.threerings.media.tile.SwissArmyTileSet; +import com.threerings.media.tile.Tile; + +/** + * The base tileset extends the swiss army tileset to add support for tile + * passability. Passability is used to determine whether traverser objects + * (generally sprites made to "walk" around the scene) can traverse a + * particular tile in a scene. + */ +public class BaseTileSet extends SwissArmyTileSet +{ + /** + * Sets the passability information for the tiles in this tileset. + * Each entry in the array corresponds to the tile at that tile index. + */ + public void setPassability (boolean[] passable) + { + _passable = passable; + } + + /** + * Returns the passability information for the tiles in this tileset. + */ + public boolean[] getPassability () + { + return _passable; + } + + // documentation inherited + protected Tile createTile () + { + return new BaseTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + ((BaseTile)tile).setPassable(_passable[tileIndex]); + } + + // documentation inherited + protected void toString (StringBuilder buf) + { + super.toString(buf); + buf.append(", passable=").append(StringUtil.toString(_passable)); + } + + /** Whether each tile is passable. */ + protected boolean[] _passable; + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/miso/tile/FringeConfiguration.java b/src/java/com/threerings/miso/tile/FringeConfiguration.java new file mode 100644 index 00000000..33747aaa --- /dev/null +++ b/src/java/com/threerings/miso/tile/FringeConfiguration.java @@ -0,0 +1,158 @@ +// +// $Id: FringeConfiguration.java 3403 2005-03-14 23:58:02Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile; + +import java.io.Serializable; +import java.util.ArrayList; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +/** + * Used to manage data about which base tilesets fringe on which others + * and how they fringe. + */ +public class FringeConfiguration implements Serializable +{ + /** + * The path (relative to the resource directory) at which the fringe + * configuration should be loaded and stored. + */ + public static final String CONFIG_PATH = "config/miso/tile/fringeconf.dat"; + + public static class FringeRecord implements Serializable + { + /** The tileset id of the base tileset to which this applies. */ + public int base_tsid; + + /** The fringe priority of this base tileset. */ + public int priority; + + /** A list of the possible tilesets that can be used for fringing. */ + public ArrayList tilesets = new ArrayList(); + + /** Used when parsing the tilesets definitions. */ + public void addTileset (FringeTileSetRecord record) + { + tilesets.add(record); + } + + /** Did everything parse well? */ + public boolean isValid () + { + return ((base_tsid != 0) && (priority > 0)); + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return "[base_tsid=" + base_tsid + ", priority=" + priority + + ", tilesets=" + StringUtil.toString(tilesets) + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + } + + /** + * Used to parse the tileset fringe definitions. + */ + public static class FringeTileSetRecord implements Serializable + { + /** The tileset id of the fringe tileset. */ + public int fringe_tsid; + + /** Is this a mask? */ + public boolean mask; + + /** Did everything parse well? */ + public boolean isValid () + { + return (fringe_tsid != 0); + } + + /** Generates a string representation of this instance. */ + public String toString () + { + return "[fringe_tsid=" + fringe_tsid + ", mask=" + mask + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + } + + /** + * Adds a parsed FringeRecord to this instance. This is used when parsing + * the fringerecords from xml. + */ + public void addFringeRecord (FringeRecord frec) + { + _frecs.put(frec.base_tsid, frec); + } + + /** + * If the first base tileset fringes upon the second, return the + * fringe priority of the first base tileset, otherwise return -1. + */ + public int fringesOn (int first, int second) + { + FringeRecord f1 = (FringeRecord) _frecs.get(first); + + // we better have a fringe record for the first + if (null != f1) { + + // it had better have some tilesets defined + if (f1.tilesets.size() > 0) { + + FringeRecord f2 = (FringeRecord) _frecs.get(second); + + // and we only fringe if second doesn't exist or has a lower + // priority + if ((null == f2) || (f1.priority > f2.priority)) { + return f1.priority; + } + } + } + + return -1; + } + + /** + * Get a random FringeTileSetRecord from amongst the ones + * listed for the specified base tileset. + */ + public FringeTileSetRecord getFringe (int baseset, int hashValue) + { + FringeRecord f = (FringeRecord) _frecs.get(baseset); + return (FringeTileSetRecord) f.tilesets.get( + hashValue % f.tilesets.size()); + } + + /** The mapping from base tileset id to fringerecord. */ + protected HashIntMap _frecs = new HashIntMap(); + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; +} diff --git a/src/java/com/threerings/miso/tile/MisoTileManager.java b/src/java/com/threerings/miso/tile/MisoTileManager.java new file mode 100644 index 00000000..13bdd006 --- /dev/null +++ b/src/java/com/threerings/miso/tile/MisoTileManager.java @@ -0,0 +1,92 @@ +// +// $Id: MisoTileManager.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile; + +import java.io.IOException; +import java.io.InputStream; + +import com.samskivert.io.StreamUtil; + +import com.threerings.resource.ResourceManager; +import com.threerings.util.CompiledConfig; + +import com.threerings.media.image.ImageManager; +import com.threerings.media.tile.TileManager; + +import com.threerings.miso.Log; + +/** + * Extends the basic tile manager and provides support for automatically + * generating fringes in between different types of base tiles in a scene. + */ +public class MisoTileManager extends TileManager +{ + /** + * Creates a tile manager and provides it with a reference to the + * image manager from which it will load tileset images. + * + * @param imgr the image manager via which the tile manager will + * decode and cache images. + */ + public MisoTileManager (ResourceManager rmgr, ImageManager imgr) + { + super(imgr); + + // look for a fringe configuration in the appropriate place + InputStream in = null; + try { + in = rmgr.getResource(FRINGE_CONFIG_PATH); + FringeConfiguration config = (FringeConfiguration) + CompiledConfig.loadConfig(in); + + // if we've found it, create our auto fringer with it + _fringer = new AutoFringer(config, imgr, this); + + } catch (IOException ioe) { + Log.warning("Unable to load fringe configuration " + + "[path=" + FRINGE_CONFIG_PATH + + ", error=" + ioe + "]."); + + } finally { + StreamUtil.close(in); + } + } + + /** + * Returns the auto fringer that has been configured for use by this + * tile manager. This will only be valid if this tile manager has been + * provided with a miso tileset repository via {@link + * #setTileSetRepository}. + */ + public AutoFringer getAutoFringer () + { + return _fringer; + } + + /** The entity that performs the automatic fringe layer generation. */ + protected AutoFringer _fringer; + + /** The path (in the classpath) to the serialized fringe + * configuration. */ + protected static final String FRINGE_CONFIG_PATH = + "config/miso/tile/fringeconf.dat"; +} diff --git a/src/java/com/threerings/miso/tile/tools/CompileFringeConfigurationTask.java b/src/java/com/threerings/miso/tile/tools/CompileFringeConfigurationTask.java new file mode 100644 index 00000000..8784efd2 --- /dev/null +++ b/src/java/com/threerings/miso/tile/tools/CompileFringeConfigurationTask.java @@ -0,0 +1,96 @@ +// +// $Id: CompileFringeConfigurationTask.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile.tools; + +import java.io.File; +import java.io.Serializable; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import com.samskivert.io.PersistenceException; + +import com.threerings.util.CompiledConfig; + +import com.threerings.media.tile.tools.MapFileTileSetIDBroker; + +import com.threerings.miso.tile.tools.xml.FringeConfigurationParser; + +/** + * Compile fringe configuration. + */ +public class CompileFringeConfigurationTask extends Task +{ + public void setTileSetMap (File tsetmap) + { + _tsetmap = tsetmap; + } + + public void setFringeDef (File fringedef) + { + _fringedef = fringedef; + } + + public void setTarget (File target) + { + _target = target; + } + + public void execute () throws BuildException + { + // make sure the source file exists + if (!_fringedef.exists()) { + throw new BuildException("Fringe definition file not found " + + "[path=" + _fringedef.getPath() + "]."); + } + + // set up the tileid broker + MapFileTileSetIDBroker broker; + try { + broker = new MapFileTileSetIDBroker(_tsetmap); + } catch (PersistenceException pe) { + throw new BuildException("Couldn't set up tileset mapping " + + "[path=" + _tsetmap.getPath() + + ", error=" + pe.getCause() + "]."); + } + + FringeConfigurationParser parser = new FringeConfigurationParser( + broker); + Serializable config; + try { + config = parser.parseConfig(_fringedef); + } catch (Exception e) { + throw new BuildException("Failure parsing config definition", e); + } + + try { + // and write it on out + CompiledConfig.saveConfig(_target, config); + } catch (Exception e) { + throw new BuildException("Failure writing serialized config", e); + } + } + + protected File _tsetmap; + protected File _fringedef; + protected File _target; +} diff --git a/src/java/com/threerings/miso/tile/tools/xml/BaseTileSetRuleSet.java b/src/java/com/threerings/miso/tile/tools/xml/BaseTileSetRuleSet.java new file mode 100644 index 00000000..f34bb431 --- /dev/null +++ b/src/java/com/threerings/miso/tile/tools/xml/BaseTileSetRuleSet.java @@ -0,0 +1,84 @@ +// +// $Id: BaseTileSetRuleSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile.tools.xml; + +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.CallMethodSpecialRule; + +import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet; + +import com.threerings.miso.Log; +import com.threerings.miso.tile.BaseTileSet; + +/** + * Parses {@link BaseTileSet} instances from a tileset description. Base + * tilesets extend swiss army tilesets with the addition of a passability + * flag for each tile. + * + * @see SwissArmyTileSetRuleSet + */ +public class BaseTileSetRuleSet extends SwissArmyTileSetRuleSet +{ + // documentation inherited + public void addRuleInstances (Digester digester) + { + super.addRuleInstances(digester); + + digester.addRule( + _prefix + TILESET_PATH + "/passable", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + { + int[] values = StringUtil.parseIntArray(bodyText); + boolean[] passable = new boolean[values.length]; + for (int i = 0; i < values.length; i++) { + passable[i] = (values[i] != 0); + } + BaseTileSet starget = (BaseTileSet)target; + starget.setPassability(passable); + } + }); + } + + // documentation inherited + public boolean isValid (Object target) + { + BaseTileSet set = (BaseTileSet)target; + boolean valid = super.isValid(target); + + // check for a element + if (set.getPassability() == null) { + Log.warning("Tile set definition missing valid " + + "element [set=" + set + "]."); + valid = false; + } + + return valid; + } + + // documentation inherited + protected Class getTileSetClass () + { + return BaseTileSet.class; + } +} diff --git a/src/java/com/threerings/miso/tile/tools/xml/FringeConfigurationParser.java b/src/java/com/threerings/miso/tile/tools/xml/FringeConfigurationParser.java new file mode 100644 index 00000000..8450b037 --- /dev/null +++ b/src/java/com/threerings/miso/tile/tools/xml/FringeConfigurationParser.java @@ -0,0 +1,168 @@ +// +// $Id: FringeConfigurationParser.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tile.tools.xml; + +import java.io.Serializable; + +import org.xml.sax.Attributes; +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; +import com.samskivert.xml.SetPropertyFieldsRule; +import com.samskivert.xml.ValidatedSetNextRule; + +import com.threerings.tools.xml.CompiledConfigParser; + +import com.threerings.media.tile.TileSetIDBroker; + +import com.threerings.miso.Log; +import com.threerings.miso.tile.FringeConfiguration.FringeRecord; +import com.threerings.miso.tile.FringeConfiguration.FringeTileSetRecord; +import com.threerings.miso.tile.FringeConfiguration; + +/** + * Parses fringe config definitions. + */ +public class FringeConfigurationParser extends CompiledConfigParser +{ + public FringeConfigurationParser (TileSetIDBroker broker) + { + _idBroker = broker; + } + + + // documentation inherited + protected Serializable createConfigObject () + { + return new FringeConfiguration(); + } + + // documentation inherited + protected void addRules (Digester digest) + { + // configure top-level constraints + String prefix = "fringe"; + digest.addRule(prefix, new SetPropertyFieldsRule()); + + // create and configure fringe config instances + prefix += "/base"; + digest.addObjectCreate(prefix, FringeRecord.class.getName()); + + ValidatedSetNextRule.Validator val; + val = new ValidatedSetNextRule.Validator() { + public boolean isValid (Object target) { + if (((FringeRecord) target).isValid()) { + return true; + } else { + Log.warning("A FringeRecord was not added because it was " + + "improperly specified [rec=" + target + "]."); + return false; + } + } + }; + ValidatedSetNextRule vrule; + vrule = new ValidatedSetNextRule("addFringeRecord", val) { + // parse the fringe record, converting tileset names to + // tileset ids + public void begin (String namespace, String lname, Attributes attrs) + throws Exception + { + FringeRecord frec = (FringeRecord) digester.peek(); + + for (int ii=0; ii < attrs.getLength(); ii++) { + String name = attrs.getLocalName(ii); + if (StringUtil.isBlank(name)) { + name = attrs.getQName(ii); + } + String value = attrs.getValue(ii); + + if ("name".equals(name)) { + if (_idBroker.tileSetMapped(value)) { + frec.base_tsid = _idBroker.getTileSetID(value); + } else { + Log.warning("Skipping unknown base " + + "tileset [name=" + value + "]."); + } + + } else if ("priority".equals(name)) { + frec.priority = Integer.parseInt(value); + } else { + Log.warning("Skipping unknown attribute " + + "[name=" + name + "]."); + } + } + } + }; + digest.addRule(prefix, vrule); + + // create the tileset records in each fringe record + prefix += "/tileset"; + digest.addObjectCreate(prefix, FringeTileSetRecord.class.getName()); + + val = new ValidatedSetNextRule.Validator() { + public boolean isValid (Object target) { + if (((FringeTileSetRecord) target).isValid()) { + return true; + } else { + Log.warning("A FringeTileSetRecord was not added because " + + "it was improperly specified " + + "[rec=" + target + "]."); + return false; + } + } + }; + vrule = new ValidatedSetNextRule("addTileset", val) { + // parse the fringe tilesetrecord, converting tileset names to ids + public void begin (String namespace, String lname, Attributes attrs) + throws Exception + { + FringeTileSetRecord f = (FringeTileSetRecord) digester.peek(); + + for (int ii=0; ii < attrs.getLength(); ii++) { + String name = attrs.getLocalName(ii); + if (StringUtil.isBlank(name)) { + name = attrs.getQName(ii); + } + String value = attrs.getValue(ii); + + if ("name".equals(name)) { + if (_idBroker.tileSetMapped(value)) { + f.fringe_tsid = _idBroker.getTileSetID(value); + } else { + Log.warning("Skipping unknown fringe " + + "tileset [name=" + value + "]."); + } + + } else if ("mask".equals(name)) { + f.mask = Boolean.valueOf(value).booleanValue(); + } else { + Log.warning("Skipping unknown attribute " + + "[name=" + name + "]."); + } + } + } + }; + digest.addRule(prefix, vrule); + } + + protected TileSetIDBroker _idBroker; +} diff --git a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneParser.java b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneParser.java new file mode 100644 index 00000000..5b005dd6 --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneParser.java @@ -0,0 +1,90 @@ +// +// $Id: SimpleMisoSceneParser.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import java.io.IOException; +import java.io.FileInputStream; + +import org.xml.sax.SAXException; +import org.apache.commons.digester.Digester; + +import com.samskivert.util.StringUtil; + +import com.threerings.miso.data.SimpleMisoSceneModel; + +/** + * A simple class for parsing simple miso scene models. + */ +public class SimpleMisoSceneParser +{ + /** + * Constructs a scene parser that parses scenes with the specified XML + * path prefix. + */ + public SimpleMisoSceneParser (String prefix) + { + // create and configure our digester + _digester = new Digester(); + + // create our scene rule set + SimpleMisoSceneRuleSet set = new SimpleMisoSceneRuleSet(); + + // configure our top-level path prefix + if (StringUtil.isBlank(prefix)) { + _prefix = set.getOuterElement(); + } else { + _prefix = prefix + "/" + set.getOuterElement(); + } + + // add the scene rules + set.addRuleInstances(_prefix, _digester); + + // add a rule to grab the finished scene model + _digester.addSetNext( + _prefix, "setScene", SimpleMisoSceneModel.class.getName()); + } + + /** + * Parses the XML file at the specified path into a scene model + * instance. + */ + public SimpleMisoSceneModel parseScene (String path) + throws IOException, SAXException + { + _model = null; + _digester.push(this); + _digester.parse(new FileInputStream(path)); + return _model; + } + + /** + * Called by the parser once the scene is parsed. + */ + public void setScene (SimpleMisoSceneModel model) + { + _model = model; + } + + protected String _prefix; + protected Digester _digester; + protected SimpleMisoSceneModel _model; +} diff --git a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneRuleSet.java b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneRuleSet.java new file mode 100644 index 00000000..9210441e --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneRuleSet.java @@ -0,0 +1,108 @@ +// +// $Id: SimpleMisoSceneRuleSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import java.util.ArrayList; +import org.xml.sax.Attributes; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.Rule; + +import com.samskivert.xml.CallMethodSpecialRule; +import com.samskivert.xml.SetFieldRule; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.tools.xml.NestableRuleSet; + +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.data.SimpleMisoSceneModel; + +/** + * Used to parse a {@link SimpleMisoSceneModel} from XML. + */ +public class SimpleMisoSceneRuleSet implements NestableRuleSet +{ + // documentation inherited from interface + public String getOuterElement () + { + return SimpleMisoSceneWriter.OUTER_ELEMENT; + } + + // documentation inherited from interface + public void addRuleInstances (String prefix, Digester dig) + { + // this creates the appropriate instance when we encounter our + // prefix tag + dig.addRule(prefix, new Rule() { + public void begin (String namespace, String name, + Attributes attributes) throws Exception { + digester.push(createMisoSceneModel()); + } + public void end (String namespace, String name) throws Exception { + digester.pop(); + } + }); + + // set up rules to parse and set our fields + dig.addRule(prefix + "/width", new SetFieldRule("width")); + dig.addRule(prefix + "/height", new SetFieldRule("height")); + dig.addRule(prefix + "/viewwidth", new SetFieldRule("vwidth")); + dig.addRule(prefix + "/viewheight", new SetFieldRule("vheight")); + dig.addRule(prefix + "/base", new SetFieldRule("baseTileIds")); + + dig.addObjectCreate(prefix + "/objects", ArrayList.class.getName()); + dig.addObjectCreate(prefix + "/objects/object", + ObjectInfo.class.getName()); + dig.addSetNext(prefix + "/objects/object", "add", + Object.class.getName()); + + dig.addRule(prefix + "/objects/object", new SetPropertyFieldsRule()); + + dig.addRule(prefix + "/objects", new CallMethodSpecialRule() { + public void parseAndSet (String bodyText, Object target) + throws Exception + { + ArrayList ilist = (ArrayList)target; + ArrayList ulist = new ArrayList(); + SimpleMisoSceneModel model = (SimpleMisoSceneModel) + digester.peek(1); + + // filter interesting and uninteresting into two lists + for (int ii = 0; ii < ilist.size(); ii++) { + ObjectInfo info = (ObjectInfo)ilist.get(ii); + if (!info.isInteresting()) { + ilist.remove(ii--); + ulist.add(info); + } + } + + // now populate the model + SimpleMisoSceneModel.populateObjects(model, ilist, ulist); + } + }); + } + + protected SimpleMisoSceneModel createMisoSceneModel () + { + return new SimpleMisoSceneModel(0, 0, 0, 0); + } +} diff --git a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneWriter.java b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneWriter.java new file mode 100644 index 00000000..1af46bba --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneWriter.java @@ -0,0 +1,116 @@ +// +// $Id: SimpleMisoSceneWriter.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import com.megginson.sax.DataWriter; +import com.samskivert.util.StringUtil; +import com.threerings.tools.xml.NestableWriter; + +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.data.SimpleMisoSceneModel; + +/** + * Generates an XML representation of a {@link SimpleMisoSceneModel}. + */ +public class SimpleMisoSceneWriter implements NestableWriter +{ + /** The element used to enclose scene models written with this + * writer. */ + public static final String OUTER_ELEMENT = "miso"; + + // documentation inherited from interface + public void write (Object object, DataWriter writer) + throws SAXException + { + SimpleMisoSceneModel model = (SimpleMisoSceneModel)object; + writer.startElement(OUTER_ELEMENT); + writeSceneData(model, writer); + writer.endElement(OUTER_ELEMENT); + } + + /** + * Writes just the scene data which is handy for derived classes which + * may wish to add their own scene data to the scene output. + */ + protected void writeSceneData (SimpleMisoSceneModel model, + DataWriter writer) + throws SAXException + { + writer.dataElement("width", Integer.toString(model.width)); + writer.dataElement("height", Integer.toString(model.height)); + writer.dataElement("viewwidth", Integer.toString(model.vwidth)); + writer.dataElement("viewheight", Integer.toString(model.vheight)); + writer.dataElement("base", + StringUtil.toString(model.baseTileIds, "", "")); + + // write our uninteresting object tile information + writer.startElement("objects"); + for (int ii = 0; ii < model.objectTileIds.length; ii++) { + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(model.objectTileIds[ii])); + attrs.addAttribute("", "x", "", "", + String.valueOf(model.objectXs[ii])); + attrs.addAttribute("", "y", "", "", + String.valueOf(model.objectYs[ii])); + writer.emptyElement("", "object", "", attrs); + } + + // write our uninteresting object tile information + for (int ii = 0; ii < model.objectInfo.length; ii++) { + ObjectInfo info = model.objectInfo[ii]; + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(info.tileId)); + attrs.addAttribute("", "x", "", "", String.valueOf(info.x)); + attrs.addAttribute("", "y", "", "", String.valueOf(info.y)); + + if (!StringUtil.isBlank(info.action)) { + attrs.addAttribute("", "action", "", "", info.action); + } + + if (info.priority != 0) { + attrs.addAttribute("", "priority", "", "", + String.valueOf(info.priority)); + } + + if (info.sx != 0 || info.sy != 0) { + attrs.addAttribute("", "sx", "", "", + String.valueOf(info.sx)); + attrs.addAttribute("", "sy", "", "", + String.valueOf(info.sy)); + attrs.addAttribute("", "sorient", "", "", + String.valueOf(info.sorient)); + } + + if (info.zations != 0) { + attrs.addAttribute("", "zations", "", "", + String.valueOf(info.zations)); + } + writer.emptyElement("", "object", "", attrs); + } + writer.endElement("objects"); + } +} diff --git a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneParser.java b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneParser.java new file mode 100644 index 00000000..4151feb3 --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneParser.java @@ -0,0 +1,97 @@ +// +// $Id: SparseMisoSceneParser.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import java.io.IOException; +import java.io.FileInputStream; + +import org.xml.sax.SAXException; +import org.apache.commons.digester.Digester; + +import com.samskivert.io.StreamUtil; +import com.samskivert.util.StringUtil; + +import com.threerings.miso.data.SparseMisoSceneModel; + +/** + * A simple class for parsing simple miso scene models. + */ +public class SparseMisoSceneParser +{ + /** + * Constructs a scene parser that parses scenes with the specified XML + * path prefix. + */ + public SparseMisoSceneParser (String prefix) + { + // create and configure our digester + _digester = new Digester(); + + // create our scene rule set + SparseMisoSceneRuleSet set = new SparseMisoSceneRuleSet(); + + // configure our top-level path prefix + if (StringUtil.isBlank(prefix)) { + _prefix = set.getOuterElement(); + } else { + _prefix = prefix + "/" + set.getOuterElement(); + } + + // add the scene rules + set.addRuleInstances(_prefix, _digester); + + // add a rule to grab the finished scene model + _digester.addSetNext( + _prefix, "setScene", SparseMisoSceneModel.class.getName()); + } + + /** + * Parses the XML file at the specified path into a scene model + * instance. + */ + public SparseMisoSceneModel parseScene (String path) + throws IOException, SAXException + { + _model = null; + _digester.push(this); + FileInputStream stream = null; + try { + stream = new FileInputStream(path); + _digester.parse(stream); + } finally { + StreamUtil.close(stream); + } + return _model; + } + + /** + * Called by the parser once the scene is parsed. + */ + public void setScene (SparseMisoSceneModel model) + { + _model = model; + } + + protected String _prefix; + protected Digester _digester; + protected SparseMisoSceneModel _model; +} diff --git a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneRuleSet.java b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneRuleSet.java new file mode 100644 index 00000000..f3a1ba0f --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneRuleSet.java @@ -0,0 +1,85 @@ +// +// $Id: SparseMisoSceneRuleSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import org.xml.sax.Attributes; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.Rule; + +import com.samskivert.xml.SetFieldRule; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.tools.xml.NestableRuleSet; + +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.data.SparseMisoSceneModel.Section; +import com.threerings.miso.data.SparseMisoSceneModel; + +/** + * Used to parse a {@link SparseMisoSceneModel} from XML. + */ +public class SparseMisoSceneRuleSet implements NestableRuleSet +{ + // documentation inherited from interface + public String getOuterElement () + { + return SparseMisoSceneWriter.OUTER_ELEMENT; + } + + // documentation inherited from interface + public void addRuleInstances (String prefix, Digester dig) + { + // this creates the appropriate instance when we encounter our + // prefix tag + dig.addRule(prefix, new Rule() { + public void begin (String namespace, String name, + Attributes attributes) throws Exception { + digester.push(createMisoSceneModel()); + } + public void end (String namespace, String name) throws Exception { + digester.pop(); + } + }); + + // set up rules to parse and set our fields + dig.addRule(prefix + "/swidth", new SetFieldRule("swidth")); + dig.addRule(prefix + "/sheight", new SetFieldRule("sheight")); + dig.addRule(prefix + "/defTileSet", new SetFieldRule("defTileSet")); + + String sprefix = prefix + "/sections/section"; + dig.addObjectCreate(sprefix, Section.class.getName()); + dig.addRule(sprefix, new SetPropertyFieldsRule()); + dig.addRule(sprefix + "/base", new SetFieldRule("baseTileIds")); + dig.addObjectCreate(sprefix + "/objects/object", + ObjectInfo.class.getName()); + dig.addRule(sprefix + "/objects/object", new SetPropertyFieldsRule()); + dig.addSetNext(sprefix + "/objects/object", "addObject", + ObjectInfo.class.getName()); + dig.addSetNext(sprefix, "setSection", Section.class.getName()); + } + + protected SparseMisoSceneModel createMisoSceneModel () + { + return new SparseMisoSceneModel(); + } +} diff --git a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneWriter.java b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneWriter.java new file mode 100644 index 00000000..686de7a9 --- /dev/null +++ b/src/java/com/threerings/miso/tools/xml/SparseMisoSceneWriter.java @@ -0,0 +1,131 @@ +// +// $Id: SparseMisoSceneWriter.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.tools.xml; + +import java.util.Iterator; + +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import com.megginson.sax.DataWriter; +import com.samskivert.util.StringUtil; +import com.threerings.tools.xml.NestableWriter; + +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.data.SparseMisoSceneModel.Section; +import com.threerings.miso.data.SparseMisoSceneModel; + +/** + * Generates an XML representation of a {@link SparseMisoSceneModel}. + */ +public class SparseMisoSceneWriter implements NestableWriter +{ + /** The element used to enclose scene models written with this + * writer. */ + public static final String OUTER_ELEMENT = "miso"; + + // documentation inherited from interface + public void write (Object object, DataWriter writer) + throws SAXException + { + SparseMisoSceneModel model = (SparseMisoSceneModel)object; + writer.startElement(OUTER_ELEMENT); + writeSceneData(model, writer); + writer.endElement(OUTER_ELEMENT); + } + + /** + * Writes just the scene data which is handy for derived classes which + * may wish to add their own scene data to the scene output. + */ + protected void writeSceneData (SparseMisoSceneModel model, + DataWriter writer) + throws SAXException + { + writer.dataElement("swidth", Integer.toString(model.swidth)); + writer.dataElement("sheight", Integer.toString(model.sheight)); + writer.dataElement("defTileSet", Integer.toString(model.defTileSet)); + + writer.startElement("sections"); + for (Iterator iter = model.getSections(); iter.hasNext(); ) { + Section sect = (Section)iter.next(); + if (sect.isBlank()) { + continue; + } + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "x", "", "", String.valueOf(sect.x)); + attrs.addAttribute("", "y", "", "", String.valueOf(sect.y)); + attrs.addAttribute("", "width", "", "", String.valueOf(sect.width)); + writer.startElement("", "section", "", attrs); + + writer.dataElement( + "base", StringUtil.toString(sect.baseTileIds, "", "")); + + // write our uninteresting object tile information + writer.startElement("objects"); + for (int ii = 0; ii < sect.objectTileIds.length; ii++) { + attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(sect.objectTileIds[ii])); + attrs.addAttribute("", "x", "", "", + String.valueOf(sect.objectXs[ii])); + attrs.addAttribute("", "y", "", "", + String.valueOf(sect.objectYs[ii])); + writer.emptyElement("", "object", "", attrs); + } + + // write our interesting object tile information + for (int ii = 0; ii < sect.objectInfo.length; ii++) { + ObjectInfo info = sect.objectInfo[ii]; + attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(info.tileId)); + attrs.addAttribute("", "x", "", "", String.valueOf(info.x)); + attrs.addAttribute("", "y", "", "", String.valueOf(info.y)); + + if (!StringUtil.isBlank(info.action)) { + attrs.addAttribute("", "action", "", "", info.action); + } + if (info.priority != 0) { + attrs.addAttribute("", "priority", "", "", + String.valueOf(info.priority)); + } + if (info.sx != 0 || info.sy != 0) { + attrs.addAttribute("", "sx", "", "", + String.valueOf(info.sx)); + attrs.addAttribute("", "sy", "", "", + String.valueOf(info.sy)); + attrs.addAttribute("", "sorient", "", "", + String.valueOf(info.sorient)); + } + if (info.zations != 0) { + attrs.addAttribute("", "zations", "", "", + String.valueOf(info.zations)); + } + writer.emptyElement("", "object", "", attrs); + } + writer.endElement("objects"); + writer.endElement("section"); + } + writer.endElement("sections"); + } +} diff --git a/src/java/com/threerings/miso/util/MisoContext.java b/src/java/com/threerings/miso/util/MisoContext.java new file mode 100644 index 00000000..267dfdc6 --- /dev/null +++ b/src/java/com/threerings/miso/util/MisoContext.java @@ -0,0 +1,43 @@ +// +// $Id: MisoContext.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.util; + +import com.threerings.media.FrameManager; +import com.threerings.miso.tile.MisoTileManager; + +/** + * Provides Miso code with access to the managers that it needs to do its + * thing. + */ +public interface MisoContext +{ + /** + * Returns the frame manager that our scene panel will interact with. + */ + public FrameManager getFrameManager (); + + /** + * Returns a reference to the tile manager. This reference is valid + * for the lifetime of the application. + */ + public MisoTileManager getTileManager (); +} diff --git a/src/java/com/threerings/miso/util/MisoSceneMetrics.java b/src/java/com/threerings/miso/util/MisoSceneMetrics.java new file mode 100644 index 00000000..b2f3facb --- /dev/null +++ b/src/java/com/threerings/miso/util/MisoSceneMetrics.java @@ -0,0 +1,101 @@ +// +// $Id: MisoSceneMetrics.java 3310 2005-01-24 23:08:21Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.util; + +import com.threerings.miso.client.MisoScenePanel; + +/** + * Contains information on the configuration of a particular isometric + * view. The member data are public to facilitate convenient referencing + * by the {@link MisoScenePanel} class, the values should not be modified + * once the metrics are constructed. + */ +public class MisoSceneMetrics +{ + /** Tile dimensions and half-dimensions in the view. */ + public int tilewid, tilehei, tilehwid, tilehhei; + + /** Fine coordinate dimensions. */ + public int finehwid, finehhei; + + /** Number of fine coordinates on each axis within a tile. */ + public int finegran; + + /** Dimensions of our scene blocks in tile count. */ + public short blockwid = 4, blockhei = 4; + + /** The length of a tile edge in pixels. */ + public float tilelen; + + /** The slope of the x- and y-axis lines. */ + public float slopeX, slopeY; + + /** The length between fine coordinates in pixels. */ + public float finelen; + + /** The y-intercept of the x-axis line within a tile. */ + public float fineBX; + + /** The slope of the x- and y-axis lines within a tile. */ + public float fineSlopeX, fineSlopeY; + + /** + * Constructs scene metrics by directly specifying the desired config + * parameters. + * + * @param tilewid the width in pixels of the tiles. + * @param tilehei the height in pixels of the tiles. + * @param finegran the number of sub-tile divisions to use for fine + * coordinates. + */ + public MisoSceneMetrics (int tilewid, int tilehei, int finegran) + { + // keep track of this stuff + this.tilewid = tilewid; + this.tilehei = tilehei; + this.finegran = finegran; + + // halve the dimensions + tilehwid = (tilewid / 2); + tilehhei = (tilehei / 2); + + // calculate the length of a tile edge in pixels + tilelen = (float) Math.sqrt( + (tilehwid * tilehwid) + (tilehhei * tilehhei)); + + // calculate the slope of the x- and y-axis lines + slopeX = (float)tilehei / (float)tilewid; + slopeY = -slopeX; + + // calculate the edge length separating each fine coordinate + finelen = tilelen / (float)finegran; + + // calculate the fine-coordinate x-axis line + fineSlopeX = (float)tilehei / (float)tilewid; + fineBX = -(fineSlopeX * (float)tilehwid); + fineSlopeY = -fineSlopeX; + + // calculate the fine coordinate dimensions + finehwid = (int)((float)tilehwid / (float)finegran); + finehhei = (int)((float)tilehhei / (float)finegran); + } +} diff --git a/src/java/com/threerings/miso/util/MisoUtil.java b/src/java/com/threerings/miso/util/MisoUtil.java new file mode 100644 index 00000000..64108264 --- /dev/null +++ b/src/java/com/threerings/miso/util/MisoUtil.java @@ -0,0 +1,518 @@ +// +// $Id: MisoUtil.java 3628 2005-06-28 17:42:55Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.util; + +import java.awt.Point; +import java.awt.Polygon; + +import com.samskivert.swing.SmartPolygon; + +import com.threerings.util.DirectionCodes; +import com.threerings.util.DirectionUtil; + +import com.threerings.media.util.MathUtil; + +/** + * Miscellaneous isometric-display-related utility routines. + */ +public class MisoUtil + implements DirectionCodes +{ + /** + * Given two points in screen pixel coordinates, return the + * compass direction that point B lies in from point A from an + * isometric perspective. + * + * @param ax the x-position of point A. + * @param ay the y-position of point A. + * @param bx the x-position of point B. + * @param by the y-position of point B. + * + * @return the direction specified as one of the Sprite + * class's direction constants. + */ + public static int getDirection ( + MisoSceneMetrics metrics, int ax, int ay, int bx, int by) + { + Point afpos = new Point(), bfpos = new Point(); + + // convert screen coordinates to full coordinates to get both + // tile coordinates and fine coordinates + screenToFull(metrics, ax, ay, afpos); + screenToFull(metrics, bx, by, bfpos); + + // pull out the tile coordinates for each point + int tax = fullToTile(afpos.x); + int tay = fullToTile(afpos.y); + + int tbx = fullToTile(bfpos.x); + int tby = fullToTile(bfpos.y); + + // compare tile coordinates to determine direction + int dir = getIsoDirection(tax, tay, tbx, tby); + if (dir != DirectionCodes.NONE) { + return dir; + } + + // destination point is in the same tile as the + // origination point, so consider fine coordinates + + // pull out the fine coordinates for each point + int fax = afpos.x - (tax * FULL_TILE_FACTOR); + int fay = afpos.y - (tay * FULL_TILE_FACTOR); + + int fbx = bfpos.x - (tbx * FULL_TILE_FACTOR); + int fby = bfpos.y - (tby * FULL_TILE_FACTOR); + + // compare fine coordinates to determine direction + dir = getIsoDirection(fax, fay, fbx, fby); + + // arbitrarily return southwest if fine coords were also equivalent + return (dir == -1) ? SOUTHWEST : dir; + } + + /** + * Given two points in an isometric coordinate system (in which {@link + * #NORTH} is in the direction of the negative x-axis and {@link + * #WEST} in the direction of the negative y-axis), return the compass + * direction that point B lies in from point A. This method is used + * to determine direction for both tile coordinates and fine + * coordinates within a tile, since the coordinate systems are the + * same. + * + * @param ax the x-position of point A. + * @param ay the y-position of point A. + * @param bx the x-position of point B. + * @param by the y-position of point B. + * + * @return the direction specified as one of the Sprite + * class's direction constants, or DirectionCodes.NONE if + * point B is equivalent to point A. + */ + public static int getIsoDirection (int ax, int ay, int bx, int by) + { + // head off a div by 0 at the pass.. + if (bx == ax) { + if (by == ay) { + return DirectionCodes.NONE; + } + return (by < ay) ? EAST : WEST; + } + + // figure direction base on the slope of the line + float slope = ((float) (ay - by)) / ((float) Math.abs(ax - bx)); + if (slope > 2f) { + return EAST; + } + if (slope > .5f) { + return (bx < ax) ? NORTHEAST : SOUTHEAST; + } + if (slope > -.5f) { + return (bx < ax) ? NORTH : SOUTH; + } + if (slope > -2f) { + return (bx < ax) ? NORTHWEST : SOUTHWEST; + } + return WEST; + } + + /** + * Given two points in screen coordinates, return the isometrically + * projected compass direction that point B lies in from point A. + * + * @param ax the x-position of point A. + * @param ay the y-position of point A. + * @param bx the x-position of point B. + * @param by the y-position of point B. + * + * @return the direction specified as one of the Sprite + * class's direction constants, or DirectionCodes.NONE if + * point B is equivalent to point A. + */ + public static int getProjectedIsoDirection (int ax, int ay, int bx, int by) + { + return toIsoDirection(DirectionUtil.getDirection(ax, ay, bx, by)); + } + + /** + * Converts a non-isometric orientation (where north points toward the + * top of the screen) to an isometric orientation where north points + * toward the upper-left corner of the screen. + */ + public static int toIsoDirection (int dir) + { + if (dir != DirectionCodes.NONE) { + // rotate the direction clockwise (ie. change SOUTHEAST to + // SOUTH) + dir = DirectionUtil.rotateCW(dir, 2); + } + return dir; + } + + /** + * Returns the tile coordinate of the given full coordinate. + */ + public static int fullToTile (int val) + { + return MathUtil.floorDiv(val, FULL_TILE_FACTOR); + } + + /** + * Returns the fine coordinate of the given full coordinate. + */ + public static int fullToFine (int val) + { + return (val - (fullToTile(val) * FULL_TILE_FACTOR)); + } + + /** + * Convert the given screen-based pixel coordinates to their + * corresponding tile-based coordinates. Converted coordinates + * are placed in the given point object. + * + * @param sx the screen x-position pixel coordinate. + * @param sy the screen y-position pixel coordinate. + * @param tpos the point object to place coordinates in. + * + * @return the point instance supplied via the tpos + * parameter. + */ + public static Point screenToTile ( + MisoSceneMetrics metrics, int sx, int sy, Point tpos) + { + // determine the upper-left of the quadrant that contains our + // point + int zx = (int)Math.floor((float)sx / metrics.tilewid); + int zy = (int)Math.floor((float)sy / metrics.tilehei); + + // these are the screen coordinates of the tile's top + int ox = (zx * metrics.tilewid), oy = (zy * metrics.tilehei); + + // these are the tile coordinates + tpos.x = zy + zx; tpos.y = zy - zx; + + // now determine which of the four tiles our point occupies + int dx = sx - ox, dy = sy - oy; + + if (Math.round(metrics.slopeY * dx + metrics.tilehei) <= dy) { + tpos.x += 1; + } + + if (Math.round(metrics.slopeX * dx) > dy) { + tpos.y -= 1; + } + +// Log.info("Converted [sx=" + sx + ", sy=" + sy + +// ", zx=" + zx + ", zy=" + zy + +// ", ox=" + ox + ", oy=" + oy + +// ", dx=" + dx + ", dy=" + dy + +// ", tpos.x=" + tpos.x + ", tpos.y=" + tpos.y + "]."); + return tpos; + } + + /** + * Convert the given tile-based coordinates to their corresponding + * screen-based pixel coordinates. The screen coordinate for a tile is + * the upper-left coordinate of the rectangle that bounds the tile + * polygon. Converted coordinates are placed in the given point + * object. + * + * @param x the tile x-position coordinate. + * @param y the tile y-position coordinate. + * @param spos the point object to place coordinates in. + * + * @return the point instance supplied via the spos + * parameter. + */ + public static Point tileToScreen ( + MisoSceneMetrics metrics, int x, int y, Point spos) + { + spos.x = (x - y - 1) * metrics.tilehwid; + spos.y = (x + y) * metrics.tilehhei; + return spos; + } + + /** + * Convert the given fine coordinates to pixel coordinates within + * the containing tile. Converted coordinates are placed in the + * given point object. + * + * @param x the x-position fine coordinate. + * @param y the y-position fine coordinate. + * @param ppos the point object to place coordinates in. + */ + public static void fineToPixel ( + MisoSceneMetrics metrics, int x, int y, Point ppos) + { + ppos.x = metrics.tilehwid + ((x - y) * metrics.finehwid); + ppos.y = (x + y) * metrics.finehhei; + } + + /** + * Convert the given pixel coordinates, whose origin is at the + * top-left of a tile's containing rectangle, to fine coordinates + * within that tile. Converted coordinates are placed in the + * given point object. + * + * @param x the x-position pixel coordinate. + * @param y the y-position pixel coordinate. + * @param fpos the point object to place coordinates in. + */ + public static void pixelToFine ( + MisoSceneMetrics metrics, int x, int y, Point fpos) + { + // calculate line parallel to the y-axis (from the given + // x/y-pos to the x-axis) + float bY = y - (metrics.fineSlopeY * x); + + // determine intersection of x- and y-axis lines + int crossx = (int)((bY - metrics.fineBX) / + (metrics.fineSlopeX - metrics.fineSlopeY)); + int crossy = (int)((metrics.fineSlopeY * crossx) + bY); + + // TODO: final position should check distance between our + // position and the surrounding fine coords and return the + // actual closest fine coord, rather than just dividing. + + // determine distance along the x-axis + float xdist = MathUtil.distance(metrics.tilehwid, 0, crossx, crossy); + fpos.x = (int)(xdist / metrics.finelen); + + // determine distance along the y-axis + float ydist = MathUtil.distance(x, y, crossx, crossy); + fpos.y = (int)(ydist / metrics.finelen); + +// Log.info("Pixel to fine " + StringUtil.coordsToString(x, y) + +// " -> " + StringUtil.toString(fpos) + "."); + } + + /** + * Convert the given screen-based pixel coordinates to full + * scene-based coordinates that include both the tile coordinates + * and the fine coordinates in each dimension. Converted + * coordinates are placed in the given point object. + * + * @param sx the screen x-position pixel coordinate. + * @param sy the screen y-position pixel coordinate. + * @param fpos the point object to place coordinates in. + * + * @return the point passed in to receive the coordinates. + */ + public static Point screenToFull ( + MisoSceneMetrics metrics, int sx, int sy, Point fpos) + { + // get the tile coordinates + Point tpos = new Point(); + screenToTile(metrics, sx, sy, tpos); + + // get the screen coordinates for the containing tile + Point spos = tileToScreen(metrics, tpos.x, tpos.y, new Point()); + +// Log.info("Screen to full " + +// "[screen=" + StringUtil.coordsToString(sx, sy) + +// ", tpos=" + StringUtil.toString(tpos) + +// ", spos=" + StringUtil.toString(spos) + +// ", fpix=" + StringUtil.coordsToString( +// sx-spos.x, sy-spos.y) + "]."); + + // get the fine coordinates within the containing tile + pixelToFine(metrics, sx - spos.x, sy - spos.y, fpos); + + // toss in the tile coordinates for good measure + fpos.x += (tpos.x * FULL_TILE_FACTOR); + fpos.y += (tpos.y * FULL_TILE_FACTOR); + + return fpos; + } + + /** + * Convert the given full coordinates to screen-based pixel + * coordinates. Converted coordinates are placed in the given + * point object. + * + * @param x the x-position full coordinate. + * @param y the y-position full coordinate. + * @param spos the point object to place coordinates in. + * + * @return the point passed in to receive the coordinates. + */ + public static Point fullToScreen ( + MisoSceneMetrics metrics, int x, int y, Point spos) + { + // get the tile screen position + int tx = fullToTile(x), ty = fullToTile(y); + Point tspos = tileToScreen(metrics, tx, ty, new Point()); + + // get the pixel position of the fine coords within the tile + Point ppos = new Point(); + int fx = x - (tx * FULL_TILE_FACTOR), fy = y - (ty * FULL_TILE_FACTOR); + fineToPixel(metrics, fx, fy, ppos); + + // final position is tile position offset by fine position + spos.x = tspos.x + ppos.x; + spos.y = tspos.y + ppos.y; + + return spos; + } + + /** + * Converts the given fine coordinate to a full coordinate (a tile + * coordinate plus a fine coordinate remainder). The fine coordinate + * is assumed to be relative to tile (0, 0). + */ + public static int fineToFull (MisoSceneMetrics metrics, int fine) + { + return toFull(fine / metrics.finegran, fine % metrics.finegran); + } + + /** + * Composes the supplied tile coordinate and fine coordinate offset + * into a full coordinate. + */ + public static int toFull (int tile, int fine) + { + return tile * FULL_TILE_FACTOR + fine; + } + + /** + * Return a polygon framing the specified tile. + * + * @param x the tile x-position coordinate. + * @param y the tile y-position coordinate. + */ + public static Polygon getTilePolygon ( + MisoSceneMetrics metrics, int x, int y) + { + return getFootprintPolygon(metrics, x, y, 1, 1); + } + + /** + * Return a screen-coordinates polygon framing the two specified + * tile-coordinate points. + */ + public static Polygon getMultiTilePolygon (MisoSceneMetrics metrics, + Point sp1, Point sp2) + { + int x = Math.min(sp1.x, sp2.x), y = Math.min(sp1.y, sp2.y); + int width = Math.abs(sp1.x-sp2.x)+1, height = Math.abs(sp1.y-sp2.y)+1; + return getFootprintPolygon(metrics, x, y, width, height); + } + + /** + * Returns a polygon framing the specified scene footprint. + * + * @param x the x tile coordinate of the "upper-left" of the footprint. + * @param y the y tile coordinate of the "upper-left" of the footprint. + * @param width the width in tiles of the footprint. + * @param height the height in tiles of the footprint. + */ + public static Polygon getFootprintPolygon ( + MisoSceneMetrics metrics, int x, int y, int width, int height) + { + SmartPolygon footprint = new SmartPolygon(); + Point tpos = MisoUtil.tileToScreen(metrics, x, y, new Point()); + + // start with top-center point + int rx = tpos.x + metrics.tilehwid, ry = tpos.y; + footprint.addPoint(rx, ry); + // right point + rx += width * metrics.tilehwid; + ry += width * metrics.tilehhei; + footprint.addPoint(rx, ry); + // bottom-center point + rx -= height * metrics.tilehwid; + ry += height * metrics.tilehhei; + footprint.addPoint(rx, ry); + // left point + rx -= width * metrics.tilehwid; + ry -= width * metrics.tilehhei; + footprint.addPoint(rx, ry); + // end with top-center point + rx += height * metrics.tilehwid; + ry -= height * metrics.tilehhei; + footprint.addPoint(rx, ry); + + return footprint; + } + + /** + * Adds the supplied fine coordinates to the supplied tile coordinates + * to compute full coordinates. + * + * @return the point object supplied as full. + */ + public static Point tilePlusFineToFull (MisoSceneMetrics metrics, + int tileX, int tileY, + int fineX, int fineY, + Point full) + { + int dtx = fineX / metrics.finegran; + int dty = fineY / metrics.finegran; + int fx = fineX - dtx * metrics.finegran; + if (fx < 0) { + dtx--; + fx += metrics.finegran; + } + int fy = fineY - dty * metrics.finegran; + if (fy < 0) { + dty--; + fy += metrics.finegran; + } + + full.x = toFull(tileX + dtx, fx); + full.y = toFull(tileY + dty, fy); + return full; + } + + /** + * Turns x and y scene coordinates into an integer key. + * + * @return the hash key, given x and y. + */ + public static final int coordsToKey (int x, int y) + { + return ((y << 16) & (0xFFFF0000)) | (x & 0xFFFF); + } + + /** + * Gets the x coordinate from an integer hash key. + * + * @return the x coordinate. + */ + public static final int xCoordFromKey (int key) + { + return (key & 0xFFFF); + } + + /** + * Gets the y coordinate from an integer hash key. + * + * @return the y coordinate from the hash key. + */ + public static final int yCoordFromKey (int key) + { + return ((key >> 16) & 0xFFFF); + } + + /** Multiplication factor to embed tile coords in full coords. */ + protected static final int FULL_TILE_FACTOR = 100; +} diff --git a/src/java/com/threerings/miso/util/ObjectSet.java b/src/java/com/threerings/miso/util/ObjectSet.java new file mode 100644 index 00000000..4734b259 --- /dev/null +++ b/src/java/com/threerings/miso/util/ObjectSet.java @@ -0,0 +1,182 @@ +// +// $Id: ObjectSet.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.util; + +import java.util.Arrays; +import java.util.Comparator; + +import com.samskivert.util.ArrayUtil; +import com.samskivert.util.ListUtil; + +import com.threerings.miso.Log; +import com.threerings.miso.data.ObjectInfo; + +/** + * Used to store an (arbitrarily) ordered, low-impact iteratable (doesn't + * require object creation), set of {@link ObjectInfo} instances. + */ +public class ObjectSet +{ + /** + * Inserts the supplied object into the set. + * + * @return true if it was inserted, false if the object was already in + * the set. + */ + public boolean insert (ObjectInfo info) + { + // bail if it's already in the set + int ipos = indexOf(info); + if (ipos >= 0) { + // log a warning because the caller shouldn't be doing this + Log.warning("Requested to add an object to a set that already " + + "contains such an object [ninfo=" + info + + ", oinfo=" + _objs[ipos] + "]."); + Thread.dumpStack(); + return false; + } + + // otherwise insert it + ipos = -(ipos+1); + _objs = ListUtil.insert(_objs, ipos, info); + _size++; + return true; + } + + /** + * Returns true if the specified object is in the set, false if it is + * not. + */ + public boolean contains (ObjectInfo info) + { + return (indexOf(info) >= 0); + } + + /** + * Returns the number of objects in this set. + */ + public int size () + { + return _size; + } + + /** + * Returns the object with the specified index. The index must & be + * between 0 and {@link #size}-1. + */ + public ObjectInfo get (int index) + { + return (ObjectInfo)_objs[index]; + } + + /** + * Removes the object at the specified index. + */ + public void remove (int index) + { + ListUtil.remove(_objs, index); + _size--; + } + + /** + * Removes the specified object from the set. + * + * @return true if it was removed, false if it was not in the set. + */ + public boolean remove (ObjectInfo info) + { + int opos = indexOf(info); + if (opos >= 0) { + remove(opos); + return true; + } else { + return false; + } + } + + /** + * Clears out the contents of this set. + */ + public void clear () + { + _size = 0; + Arrays.fill(_objs, null); + } + + /** + * Converts the contents of this object set to an array. + */ + public ObjectInfo[] toArray () + { + ObjectInfo[] info = new ObjectInfo[_size]; + System.arraycopy(_objs, 0, info, 0, _size); + return info; + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + StringBuilder buf = new StringBuilder("["); + for (int ii = 0; ii < _size; ii++) { + if (ii > 0) { + buf.append(", "); + } + buf.append(_objs[ii]); + } + return buf.append("]").toString(); + } + + /** + * Returns the index of the object or it's insertion index if it is + * not in the set. + */ + protected final int indexOf (ObjectInfo info) + { + return ArrayUtil.binarySearch(_objs, 0, _size, info, INFO_COMP); + } + + /** Our sorted array of objects. */ + protected Object[] _objs = new Object[DEFAULT_SIZE]; + + /** The number of objects in the set. */ + protected int _size; + + /** We simply sort the objects in order of their hash code. We don't + * care about their order, it exists only to support binary search. */ + protected static final Comparator INFO_COMP = new Comparator() { + public int compare (Object o1, Object o2) { + ObjectInfo do1 = (ObjectInfo)o1; + ObjectInfo do2 = (ObjectInfo)o2; + if (do1.tileId == do2.tileId) { + return ((do1.x << 16) + do1.y) - ((do2.x << 16) + do2.y); + } else { + return do1.tileId - do2.tileId; + } + } + }; + + /** We start big because we know these will in general contain at + * least in the tens of objects. */ + protected static final int DEFAULT_SIZE = 16; +} diff --git a/src/java/com/threerings/openal/BlankSound.java b/src/java/com/threerings/openal/BlankSound.java new file mode 100644 index 00000000..97774428 --- /dev/null +++ b/src/java/com/threerings/openal/BlankSound.java @@ -0,0 +1,38 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +/** + * A blank sound used when we cannot initialize the sound system. + */ +public class BlankSound extends Sound +{ + protected BlankSound () + { + super(null, null); + } + + protected boolean play (boolean allowDefer, boolean loop) + { + return false; // nothing doing + } +} diff --git a/src/java/com/threerings/openal/Clip.java b/src/java/com/threerings/openal/Clip.java new file mode 100644 index 00000000..bda9d8af --- /dev/null +++ b/src/java/com/threerings/openal/Clip.java @@ -0,0 +1,41 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.nio.ByteBuffer; + +import org.lwjgl.openal.AL10; + +/** + * Contains data for a single sampled sound. + */ +public class Clip +{ + /** The OpenAL format of this clip: {@link AL10#AL_FORMAT_MONO8}, etc. */ + public int format; + + /** The frequency of this clip in samples per second. */ + public int frequency; + + /** The audio data. */ + public ByteBuffer data; +} diff --git a/src/java/com/threerings/openal/ClipBuffer.java b/src/java/com/threerings/openal/ClipBuffer.java new file mode 100644 index 00000000..f78cebe7 --- /dev/null +++ b/src/java/com/threerings/openal/ClipBuffer.java @@ -0,0 +1,287 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.IOException; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +import com.samskivert.util.ObserverList; + +/** + * Represents a sound that has been loaded into the OpenAL system. + */ +public class ClipBuffer +{ + /** Used to notify parties interested in when a clip is loaded. */ + public static interface Observer + { + /** Called when a clip has completed loading and is ready to be + * played. */ + public void clipLoaded (ClipBuffer buffer); + + /** Called when a clip has failed to prepare itself for one reason + * or other. */ + public void clipFailed (ClipBuffer buffer); + } + + /** + * Create a key that uniquely identifies this combination of clip + * provider and path. + */ + public static Comparable makeKey (ClipProvider provider, String path) + { + // we'll just use a string, amazing! + return provider + path; + } + + /** + * Creates a new clip buffer with the specified path that will obtain + * its clip data from the specified source. The clip will + * automatically queue itself up to be loaded into memory. + */ + public ClipBuffer (SoundManager manager, ClipProvider provider, String path) + { + _manager = manager; + _provider = provider; + _path = path; + } + + /** + * Returns the unique key for this clip buffer. + */ + public Comparable getKey () + { + return makeKey(_provider, _path); + } + + /** + * Returns the provider used to load this clip. + */ + public ClipProvider getClipProvider () + { + return _provider; + } + + /** + * Returns the path that identifies this sound clip. + */ + public String getPath () + { + return _path; + } + + /** + * Returns true if this buffer is loaded and ready to go. + */ + public boolean isPlayable () + { + return (_state == LOADED); + } + + /** + * Returns the identifier for this clip's buffer or -1 if it is not + * loaded. + */ + public int getBufferId () + { + return (_bufferId == null) ? -1 : _bufferId.get(0); + } + + /** + * Returns the size (in bytes) of this clip as reported by OpenAL. + * This value will not be valid until the clip is bound. + */ + public int getSize () + { + return _size; + } + + /** + * Instructs this buffer to resolve its underlying clip and be ready + * to be played ASAP. + */ + public void resolve (Observer observer) + { + // if we were waiting to unload, cancel that + if (_state == UNLOADING) { + _state = LOADED; + _manager.restoreClip(this); + } + + // if we're already loaded, this is easy + if (_state == LOADED) { + if (observer != null) { + observer.clipLoaded(this); + } + return; + } + + // queue up the observer + if (observer != null) { + _observers.add(observer); + } + + // if we're already loading, we can stop here + if (_state == LOADING) { + return; + } + + // create our OpenAL buffer and then queue ourselves up to have + // our clip data loaded + _bufferId = BufferUtils.createIntBuffer(1); + AL10.alGenBuffers(_bufferId); + int errno = AL10.alGetError(); + if (errno != AL10.AL_NO_ERROR) { + Log.warning("Failed to create buffer [key=" + getKey() + + ", errno=" + errno + "]."); + _bufferId = null; + // queue up a failure notification so that we properly return + // from this method and our sound has a chance to register + // itself as an observer before we jump up and declare failure + _manager.queueClipFailure(this); + + } else { + _state = LOADING; + _manager.queueClipLoad(this); + } + } + + /** + * Frees up the internal audio buffers associated with this clip. + */ + public void dispose () + { + if (_bufferId != null) { + // if there are sources bound to this buffer, we must wait + // for them to be unbound + if (_bound > 0) { + _state = UNLOADING; + return; + } + + // free up our buffer + AL10.alDeleteBuffers(_bufferId); + _bufferId = null; + _state = UNLOADED; + } + } + + /** + * This method is called by the background sound loading thread and + * actually loads the sound data from wherever it cometh. + */ + protected Clip load () + throws IOException + { + return _provider.loadClip(_path); + } + + /** + * This method is called back on the main thread and instructs this + * buffer to bind the clip data to this buffer's OpenAL buffer. + * + * @return true if the binding succeeded, false if we were unable to + * load the sound data into OpenAL. + */ + protected boolean bind (Clip clip) + { + AL10.alBufferData( + _bufferId.get(0), clip.format, clip.data, clip.frequency); + int errno = AL10.alGetError(); + if (errno != AL10.AL_NO_ERROR) { + Log.warning("Failed to bind clip [key=" + getKey() + + ", errno=" + errno + "]."); + failed(); + return false; + } + + _state = LOADED; + _size = AL10.alGetBufferi(_bufferId.get(0), AL10.AL_SIZE); + _observers.apply(new ObserverList.ObserverOp() { + public boolean apply (Object observer) { + ((Observer)observer).clipLoaded(ClipBuffer.this); + return true; + } + }); + _observers.clear(); + return true; + } + + /** + * Called when we fail in some part of the process in resolving our + * clip data. Notifies our observers and resets the clip to the + * UNLOADED state. + */ + protected void failed () + { + if (_bufferId != null) { + AL10.alDeleteBuffers(_bufferId); + _bufferId = null; + } + _state = UNLOADED; + + _observers.apply(new ObserverList.ObserverOp() { + public boolean apply (Object observer) { + ((Observer)observer).clipFailed(ClipBuffer.this); + return true; + } + }); + _observers.clear(); + } + + /** + * Notifies the buffer that a source has been bound to it. + */ + protected void sourceBound () + { + _bound++; + } + + /** + * Notifies the buffer that a source has been unbound from it. + */ + protected void sourceUnbound () + { + // dispose of the buffer when the last source is unbound + if (--_bound == 0 && _state == UNLOADING) { + dispose(); + } + } + + protected SoundManager _manager; + protected ClipProvider _provider; + protected String _path; + protected int _state; + protected IntBuffer _bufferId; + protected int _size; + protected ObserverList _observers = + new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); + protected int _bound; + + protected static final int UNLOADED = 0; + protected static final int LOADING = 1; + protected static final int LOADED = 2; + protected static final int UNLOADING = 3; +} diff --git a/src/java/com/threerings/openal/ClipProvider.java b/src/java/com/threerings/openal/ClipProvider.java new file mode 100644 index 00000000..855be786 --- /dev/null +++ b/src/java/com/threerings/openal/ClipProvider.java @@ -0,0 +1,33 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.IOException; + +/** + * Provides a generic mechanism for loading sound data. + */ +public interface ClipProvider +{ + /** Loads the specified clip from the appropriate source. */ + public Clip loadClip (String path) throws IOException; +} diff --git a/src/java/com/threerings/openal/Log.java b/src/java/com/threerings/openal/Log.java new file mode 100644 index 00000000..ff125d44 --- /dev/null +++ b/src/java/com/threerings/openal/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +/** + * A placeholder class that contains a reference to the log object used by + * this package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("narya.openal"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/openal/OggFileStream.java b/src/java/com/threerings/openal/OggFileStream.java new file mode 100644 index 00000000..562f4980 --- /dev/null +++ b/src/java/com/threerings/openal/OggFileStream.java @@ -0,0 +1,121 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.nio.ByteBuffer; + +import java.util.ArrayList; + +import org.lwjgl.openal.AL10; + +import com.jmex.sound.openAL.objects.util.OggInputStream; + +/** + * An audio stream read from one or more Ogg Vorbis files. + */ +public class OggFileStream extends Stream +{ + /** + * Creates a new Ogg stream for the specified file. + * + * @param loop whether or not to play the file in a continuous loop + * if there's nothing on the queue + */ + public OggFileStream (SoundManager soundmgr, File file, boolean loop) + throws IOException + { + super(soundmgr); + _file = new OggFile(file, loop); + _istream = new OggInputStream(new FileInputStream(file)); + } + + /** + * Adds a file to the queue of files to play. + * + * @param loop if true, play this file in a loop if there's nothing else + * on the queue + */ + public void queueFile (File file, boolean loop) + { + _queue.add(new OggFile(file, loop)); + } + + // documentation inherited + protected int getFormat () + { + return (_istream.getFormat() == OggInputStream.FORMAT_MONO16) ? + AL10.AL_FORMAT_MONO16 : AL10.AL_FORMAT_STEREO16; + } + + // documentation inherited + protected int getFrequency () + { + return _istream.getRate(); + } + + // documentation inherited + protected int populateBuffer (ByteBuffer buf) + throws IOException + { + int read = _istream.read(buf, buf.position(), buf.remaining()); + while (buf.hasRemaining() && (!_queue.isEmpty() || _file.loop)) { + if (!_queue.isEmpty()) { + _file = _queue.remove(0); + } + _istream = new OggInputStream(new FileInputStream(_file.file)); + read = Math.max(0, read); + read += _istream.read(buf, buf.position(), buf.remaining()); + } + return read; + } + + /** The file currently being played. */ + protected OggFile _file; + + /** The underlying Ogg input stream for the current file. */ + protected OggInputStream _istream; + + /** The queue of files to play after the current one. */ + protected ArrayList _queue = new ArrayList(); + + /** A file queued for play. */ + protected class OggFile + { + /** The file to play. */ + public File file; + + /** Whether or not to play the file in a loop when there's nothing + * in the queue. */ + public boolean loop; + + public OggFile (File file, boolean loop) + { + this.file = file; + this.loop = loop; + } + } +} diff --git a/src/java/com/threerings/openal/Sound.java b/src/java/com/threerings/openal/Sound.java new file mode 100644 index 00000000..fbe67ca7 --- /dev/null +++ b/src/java/com/threerings/openal/Sound.java @@ -0,0 +1,298 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.nio.FloatBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +/** + * Represents an instance of a sound clip which can be positioned in 3D + * space, gain and pitch adjusted and played or looped. + */ +public class Sound +{ + /** Used to await notification of the starting of a sound which may be + * delayed in loading. */ + public interface StartObserver + { + /** Called when the specified sound has started playing. If + * sound is null then the sound failed to play but soundStarted + * was called anyway to perform whatever actions were waiting + * on the sound. */ + public void soundStarted (Sound sound); + } + + /** + * Returns the buffer of audio data associated with this sound. + */ + public ClipBuffer getBuffer () + { + return _buffer; + } + + /** + * Configures the location of this sound in 3D space. This will not + * affect an already playing sound but will take effect the next time + * it is played. + */ + public void setLocation (float x, float y, float z) + { + if (_position == null) { + _position = BufferUtils.createFloatBuffer(3); + } + _position.put(x).put(y).put(z); + _position.flip(); + } + + /** + * Configures the velocity of this sound in 3D space, in delta + * location per second (see {@link #setLocation}). This will not + * affect an already playing sound but will take effect the next time + * it is played. + */ + public void setVelocity (float dx, float dy, float dz) + { + if (_velocity == null) { + _velocity = BufferUtils.createFloatBuffer(3); + } + _velocity.put(dx).put(dy).put(dz); + _velocity.flip(); + } + + /** + * Configures the sounds's pitch. This value can range from 0.5 to + * 2.0. This will not affect an already playing sound but will take + * effect the next time it is played. + */ + public void setPitch (float pitch) + { + _pitch = pitch; + } + + /** + * Configures the sound's gain (volume). This value can range from 0.0 + * to 1.0 with 1.0 meaning no attenuation, each division by two + * corresponding to a -6db attentuation and each multiplication by two + * corresponding to +6db amplification. This will not affect an + * already playing sound but will take effect the next time it is + * played. + * + *

Note: this value is multiplied by the base gain configured + * in the sound manager. + */ + public void setGain (float gain) + { + _gain = gain; + } + + /** + * Plays this sound from the beginning. While the sound is playing, an + * audio channel will be locked and then freed when the sound + * completes. + * + * @param allowDefer if false, the sound will be played immediately or + * not at all. If true, the sound will be queued up for loading if it + * is currently flushed from the cache and played once loaded. + * + * @return true if the sound could be played and was started (or + * queued up to be loaded and played ASAP if it was specified as + * deferrable) or false if the sound could not be played either + * because it was not ready and deferral was not allowed or because + * too many other sounds were playing concurrently. + */ + public boolean play (boolean allowDefer) + { + return play(allowDefer, false, null); + } + + /** + * Loops this sound, starting from the beginning of the audio data. It + * will continue to loop until {@link #pause}d or {@link #stop}ped. + * While the sound is playing an audio channel will be locked. + * + * @return true if a channel could be obtained to play the sound (and + * the sound was thus started) or false if no channels were available. + */ + public boolean loop (boolean allowDefer) + { + return play(allowDefer, true, null); + } + + /** + * Plays this sound from the beginning, notifying the supplied observer + * when the audio starts. + * + * @param loop whether or not to loop the sampe until {@link #stop}ped. + */ + public void play (StartObserver obs, boolean loop) + { + play(true, loop, obs); + } + + /** + * Pauses this sound. A subsequent call to {@link #play} will resume + * the sound from the precise position that it left off. While the + * sound is paused, its audio channel will remain locked. + */ + public void pause () + { + if (_sourceId != -1) { + AL10.alSourcePause(_sourceId); + } + } + + /** + * Stops this sound and rewinds to its beginning. The audio channel + * being used to play the sound will be released. + */ + public void stop () + { + if (_sourceId != -1) { + AL10.alSourceStop(_sourceId); + } + } + + protected Sound (SoundGroup group, ClipBuffer buffer) + { + _group = group; + _buffer = buffer; + } + + protected boolean play ( + boolean allowDefer, final boolean loop, final StartObserver obs) + { + // if we were unable to get our buffer, fail immediately + if (_buffer == null) { + if (obs != null) { + obs.soundStarted(null); + } + return false; + } + + // if we're not ready to go... + if (!_buffer.isPlayable()) { + if (allowDefer) { + // resolve the buffer and instruct it to play once it is + // resolved + _buffer.resolve(new ClipBuffer.Observer() { + public void clipLoaded (ClipBuffer buffer) { + play(false, loop, obs); + } + public void clipFailed (ClipBuffer buffer) { + // well, let's pretend like the sound started so that + // the observer isn't left hanging + if (obs != null) { + obs.soundStarted(Sound.this); + } + } + }); + return true; + } else { + // sorry charlie... + if (obs != null) { + obs.soundStarted(null); + } + return false; + } + } + + // let the observer know that (as far as they're concerned), we're + // started + if (obs != null) { + obs.soundStarted(this); + } + + // if we do not already have a source, obtain one + if (_sourceId == -1) { + _sourceId = _group.acquireSource(this); + if (_sourceId == -1) { + return false; + } + + // bind our clip buffer to the source and notify it + AL10.alSourcei(_sourceId, AL10.AL_BUFFER, _buffer.getBufferId()); + _buffer.sourceBound(); + } + + // configure the source with our ephemera + AL10.alSourcef(_sourceId, AL10.AL_PITCH, _pitch); + AL10.alSourcef(_sourceId, AL10.AL_GAIN, _gain * _group.getBaseGain()); + if (_position != null) { + AL10.alSource(_sourceId, AL10.AL_POSITION, _position); + } + if (_velocity != null) { + AL10.alSource(_sourceId, AL10.AL_VELOCITY, _velocity); + } + + // configure whether or not we should loop + AL10.alSourcei(_sourceId, AL10.AL_LOOPING, + loop ? AL10.AL_TRUE : AL10.AL_FALSE); + + // and start that damned thing up! + AL10.alSourcePlay(_sourceId); + + return true; + } + + /** + * Called by the {@link SoundGroup} when it wants to reclaim our + * source. + * + * @return false if we have no source to reclaim or if we're still busy + * playing our sound, true if we gave up our source. + */ + protected boolean reclaim () + { + if (_sourceId != -1 && + AL10.alGetSourcei(_sourceId, AL10.AL_SOURCE_STATE) == + AL10.AL_STOPPED) { + AL10.alSourcei(_sourceId, AL10.AL_BUFFER, 0); + _buffer.sourceUnbound(); + _sourceId = -1; + return true; + } + return false; + } + + /** The sound group with which we are associated. */ + protected SoundGroup _group; + + /** The OpenAL buffer from which we get our sound data. */ + protected ClipBuffer _buffer; + + /** The source via which we are playing our sound currently. */ + protected int _sourceId = -1; + + /** The pitch adjustment. */ + protected float _pitch = 1; + + /** The gain adjustment. */ + protected float _gain = 1; + + /** The starting position in 3D space. */ + protected FloatBuffer _position; + + /** The velocity vector. */ + protected FloatBuffer _velocity; +} diff --git a/src/java/com/threerings/openal/SoundGroup.java b/src/java/com/threerings/openal/SoundGroup.java new file mode 100644 index 00000000..efd2ec21 --- /dev/null +++ b/src/java/com/threerings/openal/SoundGroup.java @@ -0,0 +1,155 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.nio.IntBuffer; +import java.util.ArrayList; + +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +/** + * Manages a group of sounds, binding them to OpenAL sources as they are + * played and freeing up those sources for use by other sounds when the + * sounds are finished. + */ +public class SoundGroup +{ + /** + * Queues up the specified sound clip for pre-loading into the cache. + */ + public void preloadClip (String path) + { + if (_manager.isInitialized()) { + _manager.getClip(_provider, path); + } + } + + /** + * Obtains an "instance" of the specified sound which can be + * positioned, played, looped and otherwise used to make noise. + */ + public Sound getSound (String path) + { + ClipBuffer buffer = null; + if (_manager.isInitialized()) { + buffer = _manager.getClip(_provider, path); + } + return (buffer == null) ? new BlankSound() : new Sound(this, buffer); + } + + /** + * Disposes this sound group, freeing up the OpenAL sources with which + * it is associated. All sounds obtained from this group will no + * longer be usable and should be discarded. + */ + public void dispose () + { + if (_sourceIds != null) { + // make sure any bound sources are released + for (Source source : _sources) { + if (source.holder != null) { + source.holder.stop(); + source.holder.reclaim(); + } + } + _sources.clear(); + AL10.alDeleteSources(_sourceIds); + _sourceIds = null; + } + } + + protected SoundGroup ( + SoundManager manager, ClipProvider provider, int sources) + { + _manager = manager; + _provider = provider; + + // if we were unable to initialize the sound system at all, just + // stop here and we'll behave as if we have no available sources + if (!_manager.isInitialized()) { + return; + } + + // create our sources + _sourceIds = BufferUtils.createIntBuffer(sources); + AL10.alGenSources(_sourceIds); + int errno = AL10.alGetError(); + if (errno != AL10.AL_NO_ERROR) { + Log.warning("Failed to create sources [cprov=" + provider + + ", sources=" + sources + ", errno=" + errno + "]."); + _sourceIds = null; + // we'll have no sources which means all requests to play + // sounds will silently fail as if all sources were in use + + } else { + for (int ii = 0; ii < sources; ii++) { + Source source = new Source(); + source.sourceId = _sourceIds.get(ii); + _sources.add(source); + } + } + } + + /** + * Called by a {@link Sound} when it wants to obtain a source on which + * to play its clip. + */ + protected int acquireSource (Sound acquirer) + { + // start at the beginning of the list looking for an available + // source + for (int ii = 0, ll = _sources.size(); ii < ll; ii++) { + Source source = _sources.get(ii); + if (source.holder == null || source.holder.reclaim()) { + // note this source's new holder + source.holder = acquirer; + // move this source to the end of the list + _sources.remove(ii); + _sources.add(source); + return source.sourceId; + } + } + return -1; + } + + /** + * Used to pass the base gain through to sound effects. + */ + protected float getBaseGain () + { + return _manager.getBaseGain(); + } + + /** Used to track which sources are in use. */ + protected static class Source + { + public int sourceId; + public Sound holder; + } + + protected SoundManager _manager; + protected ClipProvider _provider; + + protected IntBuffer _sourceIds; + protected ArrayList _sources = new ArrayList(); +} diff --git a/src/java/com/threerings/openal/SoundManager.java b/src/java/com/threerings/openal/SoundManager.java new file mode 100644 index 00000000..d7841264 --- /dev/null +++ b/src/java/com/threerings/openal/SoundManager.java @@ -0,0 +1,347 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.WeakHashMap; + +import org.lwjgl.openal.AL; +import org.lwjgl.openal.AL10; + +import com.samskivert.util.LRUHashMap; +import com.samskivert.util.Queue; +import com.samskivert.util.RunQueue; + +/** + * An interface to the OpenAL library that provides a number of additional + * services: + * + *

    + *
  • an object oriented interface to the OpenAL system + *
  • a mechanism for loading a group of sounds and freeing their + * resources all at once + *
  • a mechanism for loading sounds in a background thread and + * preloading sounds that are likely to be needed soon + *
+ * + *

Note: the sound manager is not thread safe (other than + * during its interactions with its internal background loading + * thread). It assumes that all sound loading and play requests will be + * made from a single thread. + */ +public class SoundManager +{ + /** + * Creates, initializes and returns the singleton sound manager + * instance. + * + * @param rqueue a queue that the sound manager can use to post short + * runnables that must be executed on the same thread from which all + * other sound methods will be called. + */ + public static SoundManager createSoundManager (RunQueue rqueue) + { + if (_soundmgr != null) { + throw new IllegalStateException( + "A sound manager has already been created."); + } + _soundmgr = new SoundManager(rqueue); + return _soundmgr; + } + + /** + * Returns true if we were able to initialize the sound system. + */ + public boolean isInitialized () + { + return (_toLoad != null); + } + + /** + * Configures the size of our sound cache. If this value is larger + * than memory available to the underlying sound system, it will be + * reduced when OpenAL first tells us we're out of memory. + */ + public void setCacheSize (int bytes) + { + _clips.setMaxSize(bytes); + } + + /** + * Configures the base gain (which must be a value between 0 and 1.0) which + * is multiplied to the individual gain assigned to sound effects (but not + * music). + */ + public void setBaseGain (float gain) + { + _baseGain = gain; + } + + /** + * Returns the base gain used for sound effects (not music). + */ + public float getBaseGain () + { + return _baseGain; + } + + /** + * Creates an object that can be used to manage and play a group of + * sounds. Note: the sound group must be disposed + * when it is no longer needed via a call to {@link + * SoundGroup#dispose}. + * + * @param provider indicates from where the sound group will load its + * sounds. + * @param sources indicates the maximum number of simultaneous sounds + * that can play in this group. + */ + public SoundGroup createGroup (ClipProvider provider, int sources) + { + return new SoundGroup(this, provider, sources); + } + + /** + * Returns a reference to the list of active streams. + */ + public ArrayList getStreams () + { + return _streams; + } + + /** + * Updates all of the streams controlled by the manager. This should be + * called once per frame by the application. + * + * @param time the number of seconds elapsed since the last update + */ + public void updateStreams (float time) + { + // iterate backwards through the list so that streams can dispose of + // themselves during their update + for (int ii = _streams.size() - 1; ii >= 0; ii--) { + _streams.get(ii).update(time); + } + } + + /** + * Creates a sound manager and initializes the OpenAL sound subsystem. + */ + protected SoundManager (RunQueue rqueue) + { + _rqueue = rqueue; + + // initialize the OpenAL sound system + try { + AL.create("", 44100, 15, false); + } catch (Exception e) { + Log.warning("Failed to initialize sound system."); + Log.logStackTrace(e); + // don't start the background loading thread + return; + } + + int errno = AL10.alGetError(); + if (errno != AL10.AL_NO_ERROR) { + Log.warning("Failed to initialize sound system " + + "[errno=" + errno + "]."); + // don't start the background loading thread + return; + } + + // configure our LRU map with a removal observer + _clips.setRemovalObserver( + new LRUHashMap.RemovalObserver() { + public void removedFromMap (LRUHashMap map, + final ClipBuffer item) { + _rqueue.postRunnable(new Runnable() { + public void run () { + Log.debug("Flushing " + item.getKey()); + item.dispose(); + } + }); + } + }); + + // create our loading queue + _toLoad = new Queue(); + + // start up the background loader thread + _loader.setDaemon(true); + _loader.start(); + } + + /** + * Creates a clip buffer for the sound clip loaded via the specified + * provider with the specified path. The clip buffer may come from teh + * cache, and it will immediately be queued for loading if it is not + * already loaded. + */ + protected ClipBuffer getClip (ClipProvider provider, String path) + { + Comparable ckey = ClipBuffer.makeKey(provider, path); + ClipBuffer buffer = _clips.get(ckey); + try { + if (buffer == null) { + // check to see if this clip is currently loading + buffer = _loading.get(ckey); + if (buffer == null) { + buffer = new ClipBuffer(this, provider, path); + _loading.put(ckey, buffer); + } + } + buffer.resolve(null); + return buffer; + + } catch (Throwable t) { + Log.warning("Failure resolving buffer [key=" + ckey + "]."); + Log.logStackTrace(t); + return null; + } + } + + /** + * Queues the supplied clip buffer up for resolution. The {@link Clip} + * will be loaded into memory and then bound into OpenAL on the + * background thread. + */ + protected void queueClipLoad (ClipBuffer buffer) + { + if (_toLoad != null) { + _toLoad.append(buffer); + } + } + + /** + * Queues the supplied clip buffer up using our {@link RunQueue} to + * notify its observers that it failed to load. + */ + protected void queueClipFailure (final ClipBuffer buffer) + { + _rqueue.postRunnable(new Runnable() { + public void run () { + _loading.remove(buffer.getKey()); + buffer.failed(); + } + }); + } + + /** + * Adds the supplied clip buffer back to the cache after it has been marked + * for disposal and subsequently re-requested. + */ + protected void restoreClip (ClipBuffer buffer) + { + _clips.put(buffer.getKey(), buffer); + } + + /** + * Adds a stream to the list maintained by the manager. Called by streams + * when they are created. + */ + protected void addStream (Stream stream) + { + _streams.add(stream); + } + + /** + * Removes a stream from the list maintained by the manager. Called by + * streams when they are disposed. + */ + protected void removeStream (Stream stream) + { + _streams.remove(stream); + } + + /** The thread that loads up sound clips in the background. */ + protected Thread _loader = new Thread("SoundManager.Loader") { + public void run () { + while (true) { + final ClipBuffer buffer = (ClipBuffer)_toLoad.get(); + try { + Log.info("Loading " + buffer.getKey() + "."); + final Clip clip = buffer.load(); + _rqueue.postRunnable(new Runnable() { + public void run () { + Comparable ckey = buffer.getKey(); + Log.debug("Loaded " + ckey + "."); + _loading.remove(ckey); + if (buffer.bind(clip)) { + _clips.put(ckey, buffer); + } else { + // TODO: shrink the cache size if the bind + // failed due to OUT_OF_MEMORY + } + } + }); + + } catch (Throwable t) { + Log.warning("Failed to load clip " + + "[key=" + buffer.getKey() + "]."); + Log.logStackTrace(t); + + // let the clip and its observers know that we are a + // miserable failure + queueClipFailure(buffer); + } + } + } + }; + + /** Used to get back from the background thread to our "main" thread. */ + protected RunQueue _rqueue; + + /** A base gain that is multiplied by the individual gain assigned to + * sounds. */ + protected float _baseGain = 1; + + /** Contains a mapping of all currently-loading clips. */ + protected HashMap _loading = + new HashMap(); + + /** Contains a mapping of all loaded clips. */ + protected LRUHashMap _clips = + new LRUHashMap(DEFAULT_CACHE_SIZE, _sizer); + + /** Contains a queue of clip buffers waiting to be loaded. */ + protected Queue _toLoad; + + /** The list of active streams. */ + protected ArrayList _streams = new ArrayList(); + + /** The one and only sound manager, here for an exclusive performance + * by special request. Available for all your sound playing needs. */ + protected static SoundManager _soundmgr; + + /** Used to compute the in-memory size of sound samples. */ + protected static LRUHashMap.ItemSizer _sizer = + new LRUHashMap.ItemSizer() { + public int computeSize (ClipBuffer item) { + return item.getSize(); + } + }; + + /** Default to a cache size of one megabyte. */ + protected static final int DEFAULT_CACHE_SIZE = 8 * 1024 * 1024; +} diff --git a/src/java/com/threerings/openal/Stream.java b/src/java/com/threerings/openal/Stream.java new file mode 100644 index 00000000..92a06155 --- /dev/null +++ b/src/java/com/threerings/openal/Stream.java @@ -0,0 +1,350 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.IOException; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +/** + * Represents a streaming source of sound data. + */ +public abstract class Stream +{ + /** + * Creates a new stream. Call {@link #dispose} when finished with the + * stream. + * + * @param soundmgr a reference to the sound manager that will update the + * stream + */ + public Stream (SoundManager soundmgr) + { + _soundmgr = soundmgr; + + // create the source and buffers + _nbuf = BufferUtils.createIntBuffer(NUM_BUFFERS); + _nbuf.limit(1); + AL10.alGenSources(_nbuf); + _sourceId = _nbuf.get(); + _nbuf.clear(); + AL10.alGenBuffers(_nbuf); + _nbuf.get(_bufferIds); + + // register with sound manager + _soundmgr.addStream(this); + } + + /** + * Sets the base gain of the stream. + */ + public void setGain (float gain) + { + _gain = gain; + if (_fadeMode == FadeMode.NONE) { + AL10.alSourcef(_sourceId, AL10.AL_GAIN, _gain); + } + } + + /** + * Sets the pitch of the stream. + */ + public void setPitch (float pitch) + { + _pitch = pitch; + AL10.alSourcef(_sourceId, AL10.AL_PITCH, _pitch); + } + + /** + * Determines whether this stream is currently playing. + */ + public boolean isPlaying () + { + return _state == AL10.AL_PLAYING; + } + + /** + * Starts playing this stream. + */ + public void play () + { + if (_state == AL10.AL_PLAYING) { + Log.warning("Tried to play stream already playing."); + return; + } + if (_state == AL10.AL_INITIAL) { + _qidx = _qlen = 0; + queueBuffers(NUM_BUFFERS); + } + AL10.alSourcePlay(_sourceId); + _state = AL10.AL_PLAYING; + } + + /** + * Pauses this stream. + */ + public void pause () + { + if (_state != AL10.AL_PLAYING) { + Log.warning("Tried to pause stream that wasn't playing."); + return; + } + AL10.alSourcePause(_sourceId); + _state = AL10.AL_PAUSED; + } + + /** + * Stops this stream. + */ + public void stop () + { + if (_state == AL10.AL_STOPPED) { + Log.warning("Tried to stop stream that was already stopped."); + return; + } + AL10.alSourceStop(_sourceId); + _state = AL10.AL_STOPPED; + } + + /** + * Fades this stream in over the specified interval. If the stream isn't + * playing, it will be started. + */ + public void fadeIn (float interval) + { + if (_state != AL10.AL_PLAYING) { + play(); + } + AL10.alSourcef(_sourceId, AL10.AL_GAIN, 0f); + _fadeMode = FadeMode.IN; + _fadeInterval = interval; + _fadeElapsed = 0f; + } + + /** + * Fades this stream out over the specified interval. + * + * @param dispose if true, dispose of the stream when done fading out + */ + public void fadeOut (float interval, boolean dispose) + { + _fadeMode = dispose ? FadeMode.OUT_DISPOSE : FadeMode.OUT; + _fadeInterval = interval; + _fadeElapsed = 0f; + } + + /** + * Releases the resources held by this stream and removes it from + * the manager. + */ + public void dispose () + { + // make sure the stream is stopped + if (_state != AL10.AL_STOPPED) { + stop(); + } + + // delete the source and buffers + _nbuf.clear(); + _nbuf.put(_sourceId).flip(); + AL10.alDeleteSources(_nbuf); + _nbuf.clear(); + _nbuf.put(_bufferIds).flip(); + AL10.alDeleteBuffers(_nbuf); + + // remove from manager + _soundmgr.removeStream(this); + } + + /** + * Updates the state of this stream, loading data into buffers and + * adjusting gain as necessary. Called periodically by the + * {@link SoundManager}. + * + * @param time the amount of time elapsed since the last update + */ + protected void update (float time) + { + // update fade, which may stop playing + updateFade(time); + if (_state != AL10.AL_PLAYING) { + return; + } + + // find out how many buffers have been played and unqueue them + int played = AL10.alGetSourcei(_sourceId, AL10.AL_BUFFERS_PROCESSED); + if (played == 0) { + return; + } + _nbuf.clear(); + for (int ii = 0; ii < played; ii++) { + _nbuf.put(_bufferIds[_qidx]); + _qidx = (_qidx + 1) % NUM_BUFFERS; + _qlen--; + } + _nbuf.flip(); + AL10.alSourceUnqueueBuffers(_sourceId, _nbuf); + + // enqueue up to the number of buffers played + queueBuffers(played); + + // find out if we're still playing; if not and we have buffers queued, + // we must restart + _state = AL10.alGetSourcei(_sourceId, AL10.AL_SOURCE_STATE); + if (_qlen > 0 && _state != AL10.AL_PLAYING) { + play(); + } + } + + /** + * Updates the gain of the stream according to the fade state. + */ + protected void updateFade (float time) + { + if (_fadeMode == FadeMode.NONE) { + return; + } + float alpha = Math.min((_fadeElapsed += time) / _fadeInterval, 1f); + AL10.alSourcef(_sourceId, AL10.AL_GAIN, _gain * + (_fadeMode == FadeMode.IN ? alpha : (1f - alpha))); + if (alpha == 1f) { + if (_fadeMode == FadeMode.OUT) { + stop(); + } else if (_fadeMode == FadeMode.OUT_DISPOSE) { + dispose(); + } + _fadeMode = FadeMode.NONE; + } + } + + /** + * Queues (up to) the specified number of buffers. + */ + protected void queueBuffers (int buffers) + { + _nbuf.clear(); + for (int ii = 0; ii < buffers; ii++) { + int bufferId = _bufferIds[(_qidx + _qlen) % NUM_BUFFERS]; + if (populateBuffer(bufferId)) { + _nbuf.put(bufferId); + _qlen++; + } else { + break; + } + } + _nbuf.flip(); + AL10.alSourceQueueBuffers(_sourceId, _nbuf); + } + + /** + * Populates the identified buffer with as much data as it can hold. + * + * @return true if data was read into the buffer and it should be enqueued, + * false if the end of the stream has been reached and no data was read + * into the buffer + */ + protected boolean populateBuffer (int bufferId) + { + if (_abuf == null) { + _abuf = ByteBuffer.allocateDirect(BUFFER_SIZE); + } + _abuf.clear(); + int read = 0; + try { + read = Math.max(populateBuffer(_abuf), 0); + } catch (IOException e) { + Log.warning("Error reading audio stream [error=" + e + "]."); + } + if (read <= 0) { + return false; + } + _abuf.rewind().limit(read); + AL10.alBufferData(bufferId, getFormat(), _abuf, getFrequency()); + return true; + } + + /** + * Returns the OpenAL audio format of the stream. + */ + protected abstract int getFormat (); + + /** + * Returns the stream's playback frequency in samples per second. + */ + protected abstract int getFrequency (); + + /** + * Populates the given buffer with audio data. + * + * @return the total number of bytes read into the buffer, or -1 if the + * end of the stream has been reached + */ + protected abstract int populateBuffer (ByteBuffer buf) + throws IOException; + + /** The manager to which the stream was added. */ + protected SoundManager _soundmgr; + + /** The source through which the stream plays. */ + protected int _sourceId; + + /** The buffers through which we cycle. */ + protected int[] _bufferIds = new int[NUM_BUFFERS]; + + /** The starting index and length of the current queue in + * {@link #_bufferIds}. */ + protected int _qidx, _qlen; + + /** The pitch of the stream. */ + protected float _pitch = 1f; + + /** The gain of the stream. */ + protected float _gain = 1f; + + /** The interval and elapsed time for fading. */ + protected float _fadeInterval, _fadeElapsed; + + /** The type of fading being performed. */ + protected FadeMode _fadeMode = FadeMode.NONE; + + /** The buffer used to store names. */ + protected IntBuffer _nbuf; + + /** The buffer used to store audio data temporarily. */ + protected ByteBuffer _abuf; + + /** The OpenAL state of the stream. */ + protected int _state = AL10.AL_INITIAL; + + /** The size of the buffers in bytes. */ + protected static final int BUFFER_SIZE = 131072; + + /** The number of buffers to use. */ + protected static final int NUM_BUFFERS = 4; + + /** Fading modes. */ + protected enum FadeMode { NONE, IN, OUT, OUT_DISPOSE }; +} diff --git a/src/java/com/threerings/openal/WaveDataClipProvider.java b/src/java/com/threerings/openal/WaveDataClipProvider.java new file mode 100644 index 00000000..9630e1a6 --- /dev/null +++ b/src/java/com/threerings/openal/WaveDataClipProvider.java @@ -0,0 +1,46 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.openal; + +import java.io.IOException; + +import org.lwjgl.util.WaveData; + +/** + * Loads clips via the class loader using LWJGL's {@link WaveData} utility + * class. + */ +public class WaveDataClipProvider implements ClipProvider +{ + public Clip loadClip (String path) throws IOException + { + Clip clip = new Clip(); + WaveData file = WaveData.create(path); + if (file == null) { + throw new IOException("Error loading " + path); + } + clip.format = file.format; + clip.frequency = file.samplerate; + clip.data = file.data; + return clip; + } +} diff --git a/src/java/com/threerings/resource/Handler.java b/src/java/com/threerings/resource/Handler.java new file mode 100644 index 00000000..a30aec2b --- /dev/null +++ b/src/java/com/threerings/resource/Handler.java @@ -0,0 +1,194 @@ +// +// $Id: Handler.java 3749 2005-11-09 04:00:16Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.resource; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +import java.security.Permission; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageInputStream; + +import com.samskivert.io.ByteArrayOutInputStream; +import com.samskivert.net.AttachableURLFactory; +import com.samskivert.util.StringUtil; + +import com.threerings.geom.GeomUtil; + +/** + * This class is not used directly, except by a registering ResourceManager + * so that we can load data from the resource manager using URLs of the form + * resource://<resourceSet>/<path>. ResourceSet may + * be the empty string to load from the default resource sets. + */ +public class Handler extends URLStreamHandler +{ + /** + * Register this class to handle "resource" urls + * ("resource://resourceSet/path") with the specified + * ResourceManager. + */ + public static void registerHandler (ResourceManager rmgr) + { + // if we already have a resource manager registered; don't + // register another one + if (_rmgr != null) { + Log.warning("Refusing duplicate resource handler registration."); + return; + } + _rmgr = rmgr; + + // wire up our handler with the handy dandy attachable URL factory + AttachableURLFactory.attachHandler("resource", Handler.class); + } + + // documentation inherited + protected int hashCode (URL url) + { + return String.valueOf(url).hashCode(); + } + + // documentation inherited + protected boolean equals (URL u1, URL u2) + { + return String.valueOf(u1).equals(String.valueOf(u2)); + } + + // documentation inherited + protected URLConnection openConnection (URL url) + throws IOException + { + return new URLConnection(url) { + // documentation inherited + public void connect () + throws IOException + { + // the host is the bundle name + String bundle = this.url.getHost(); + // and we need to remove the leading '/' from path; + String path = this.url.getPath().substring(1); + try { + // if there are query parameters, we need special magic + String query = url.getQuery(); + if (!StringUtil.isBlank(query)) { + _stream = getStream(bundle, path, query); + } else if (StringUtil.isBlank(bundle)) { + _stream = _rmgr.getResource(path); + } else { + _stream = _rmgr.getResource(bundle, path); + } + this.connected = true; + + } catch (IOException ioe) { + Log.warning("Could not find resource [url=" + this.url + + ", error=" + ioe.getMessage() + "]."); + throw ioe; // rethrow + } + } + + // documentation inherited + public InputStream getInputStream () + throws IOException + { + if (!this.connected) { + connect(); + } + return _stream; + } + + // documentation inherited + public Permission getPermission () + throws IOException + { + // We allow anything in the resource bundle to be loaded + // without any permission restrictions. + return null; + } + + protected InputStream _stream; + }; + } + + /** + * Does some magic to allow a subset of an image to be extracted, + * reencoded as a PNG and then spat back out to the Java content + * handler system for inclusion in internal documentation. + */ + protected InputStream getStream (String bundle, String path, String query) + throws IOException + { + // we can only do this with PNGs + if (!path.endsWith(".png")) { + Log.warning("Requested sub-tile of non-PNG resource " + + "[bundle=" + bundle + ", path=" + path + + ", dims=" + query + "]."); + return _rmgr.getResource(bundle, path); + } + + // parse the query string + String[] bits = StringUtil.split(query, "&"); + int width = -1, height = -1, tidx = -1; + try { + for (int ii = 0; ii < bits.length; ii++) { + if (bits[ii].startsWith("width=")) { + width = Integer.parseInt(bits[ii].substring(6)); + } else if (bits[ii].startsWith("height=")) { + height = Integer.parseInt(bits[ii].substring(7)); + } else if (bits[ii].startsWith("tile=")) { + tidx = Integer.parseInt(bits[ii].substring(5)); + } + } + } catch (NumberFormatException nfe) { + } + if (width <= 0 || height <= 0 || tidx < 0) { + Log.warning("Bogus sub-image dimensions [bundle=" + bundle + + ", path=" + path + ", dims=" + query + "]."); + throw new FileNotFoundException(path); + } + + // locate the tile image, then write that subimage back out in PNG + // format into memory and return an input stream for that + ImageInputStream stream = + StringUtil.isBlank(bundle) ? _rmgr.getImageResource(path) + : _rmgr.getImageResource(bundle, path); + BufferedImage src = ImageIO.read(stream); + Rectangle trect = GeomUtil.getTile( + src.getWidth(), src.getHeight(), width, height, tidx); + BufferedImage tile = src.getSubimage( + trect.x, trect.y, trect.width, trect.height); + ByteArrayOutInputStream data = new ByteArrayOutInputStream(); + ImageIO.write(tile, "PNG", data); + return data.getInputStream(); + } + + /** Our singleton resource manager. */ + protected static ResourceManager _rmgr; +} diff --git a/src/java/com/threerings/resource/Log.java b/src/java/com/threerings/resource/Log.java new file mode 100644 index 00000000..926f844d --- /dev/null +++ b/src/java/com/threerings/resource/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.resource; + +/** + * A placeholder class that contains a reference to the log object used by + * the resource management package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("resource"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/resource/ResourceBundle.java b/src/java/com/threerings/resource/ResourceBundle.java new file mode 100644 index 00000000..1df76039 --- /dev/null +++ b/src/java/com/threerings/resource/ResourceBundle.java @@ -0,0 +1,418 @@ +// +// $Id: ResourceBundle.java 3998 2006-04-04 18:46:42Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.resource; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import com.samskivert.util.FileUtil; +import com.samskivert.util.StringUtil; + +import org.apache.commons.io.CopyUtils; + +/** + * A resource bundle provides access to the resources in a jar file. + */ +public class ResourceBundle +{ + /** + * Constructs a resource bundle with the supplied jar file. + * + * @param source a file object that references our source jar file. + */ + public ResourceBundle (File source) + { + this(source, false, false); + } + + /** + * Constructs a resource bundle with the supplied jar file. + * + * @param source a file object that references our source jar file. + * @param delay if true, the bundle will wait until someone calls + * {@link #sourceIsReady} before allowing access to its resources. + * @param unpack if true the bundle will unpack itself into a + * temporary directory + */ + public ResourceBundle (File source, boolean delay, boolean unpack) + { + _source = source; + if (unpack) { + String root = stripSuffix(source.getPath()); + _unpacked = new File(root + ".stamp"); + _cache = new File(root); + } + + if (!delay) { + sourceIsReady(); + } + } + + /** + * Returns the {@link File} from which resources are fetched for this + * bundle. + */ + public File getSource () + { + return _source; + } + + /** + * @return true if the bundle is fully downloaded and successfully + * unpacked. + */ + public boolean isUnpacked () + { + return (_source.exists() && _unpacked != null && + _unpacked.lastModified() == _source.lastModified()); + } + + /** + * Called by the resource manager once it has ensured that our + * resource jar file is up to date and ready for reading. + * + * @return true if we successfully unpacked our resources, false if we + * encountered errors in doing so. + */ + public boolean sourceIsReady () + { + // make a note of our source's last modification time + _sourceLastMod = _source.lastModified(); + + // if we are unpacking files, the time to do so is now + if (_unpacked != null && _unpacked.lastModified() != _sourceLastMod) { + try { + resolveJarFile(); + } catch (IOException ioe) { + Log.warning("Failure resolving jar file '" + _source + + "': " + ioe + "."); + wipeBundle(true); + return false; + } + + Log.info("Unpacking into " + _cache + "..."); + if (!_cache.exists()) { + if (!_cache.mkdir()) { + Log.warning("Failed to create bundle cache directory '" + + _cache + "'."); + closeJar(); + // we are hopelessly fucked + return false; + } + } else { + FileUtil.recursiveClean(_cache); + } + + // unpack the jar file (this will close the jar when it's done) + if (!FileUtil.unpackJar(_jarSource, _cache)) { + // if something went awry, delete everything in the hopes + // that next time things will work + wipeBundle(true); + return false; + } + + // if everything unpacked smoothly, create our unpack stamp + try { + _unpacked.createNewFile(); + if (!_unpacked.setLastModified(_sourceLastMod)) { + Log.warning("Failed to set last mod on stamp file '" + + _unpacked + "'."); + } + } catch (IOException ioe) { + Log.warning("Failure creating stamp file '" + _unpacked + + "': " + ioe + "."); + // no need to stick a fork in things at this point + } + } + + return true; + } + + /** + * Clears out everything associated with this resource bundle in the + * hopes that we can download it afresh and everything will work the + * next time around. + */ + public void wipeBundle (boolean deleteJar) + { + // clear out our cache directory + if (_cache != null) { + FileUtil.recursiveClean(_cache); + } + + // delete our unpack stamp file + if (_unpacked != null) { + _unpacked.delete(); + } + + // clear out any .jarv file that Getdown might be maintaining so + // that we ensure that it is revalidated + File vfile = new File(FileUtil.resuffix(_source, ".jar", ".jarv")); + if (vfile.exists() && !vfile.delete()) { + Log.warning("Failed to delete " + vfile + "."); + } + + // close and delete our source jar file + if (deleteJar && _source != null) { + closeJar(); + if (!_source.delete()) { + Log.warning("Failed to delete " + _source + + " [exists=" + _source.exists() + "]."); + } + } + } + + /** + * Fetches the named resource from this bundle. The path should be + * specified as a relative, platform independent path (forward + * slashes). For example sounds/scream.au. + * + * @param path the path to the resource in this jar file. + * + * @return an input stream from which the resource can be loaded or + * null if no such resource exists. + * + * @exception IOException thrown if an error occurs locating the + * resource in the jar file. + */ + public InputStream getResource (String path) + throws IOException + { + // unpack our resources into a temp directory so that we can load + // them quickly and the file system can cache them sensibly + File rfile = getResourceFile(path); + return (rfile == null) ? null : new FileInputStream(rfile); + } + + /** + * Returns a file from which the specified resource can be loaded. + * This method will unpack the resource into a temporary directory and + * return a reference to that file. + * + * @param path the path to the resource in this jar file. + * + * @return a file from which the resource can be loaded or null if no + * such resource exists. + */ + public File getResourceFile (String path) + throws IOException + { + if (resolveJarFile()) { + return null; + } + + // if we have been unpacked, return our unpacked file + if (_cache != null) { + File cfile = new File(_cache, path); + if (cfile.exists()) { + return cfile; + } else { + return null; + } + } + + // otherwise, we unpack resources as needed into a temp directory + String tpath = StringUtil.md5hex(_source.getPath() + "%" + path); + File tfile = new File(getCacheDir(), tpath); + if (tfile.exists() && (tfile.lastModified() > _sourceLastMod)) { + return tfile; + } + + JarEntry entry = _jarSource.getJarEntry(path); + if (entry == null) { +// Log.info("Couldn't locate " + path + " in " + _jarSource + "."); + return null; + } + + // copy the resource into the temporary file + BufferedOutputStream fout = + new BufferedOutputStream(new FileOutputStream(tfile)); + InputStream jin = _jarSource.getInputStream(entry); + CopyUtils.copy(jin, fout); + jin.close(); + fout.close(); + + return tfile; + } + + /** + * Returns true if this resource bundle contains the resource with the + * specified path. This avoids actually loading the resource, in the + * event that the caller only cares to know that the resource exists. + */ + public boolean containsResource (String path) + { + try { + if (resolveJarFile()) { + return false; + } + return (_jarSource.getJarEntry(path) != null); + } catch (IOException ioe) { + return false; + } + } + + /** + * Returns a string representation of this resource bundle. + */ + public String toString () + { + try { + resolveJarFile(); + return (_jarSource == null) ? "[file=" + _source + "]" : + "[path=" + _jarSource.getName() + "]"; + + } catch (IOException ioe) { + return "[file=" + _source + ", ioe=" + ioe + "]"; + } + } + + /** + * Creates the internal jar file reference if we've not already got + * it; we do this lazily so as to avoid any jar- or zip-file-related + * antics until and unless doing so is required, and because the + * resource manager would like to be able to create bundles before the + * associated files have been fully downloaded. + * + * @return true if the jar file could not yet be resolved because we + * haven't yet heard from the resource manager that it is ready for us + * to access, false if all is cool. + */ + protected boolean resolveJarFile () + throws IOException + { + // if we don't yet have our resource bundle's last mod time, we + // have not yet been notified that it is ready + if (_sourceLastMod == -1) { + return true; + } + + if (!_source.exists()) { + throw new IOException("Missing jar file for resource bundle: " + + _source + "."); + } + + try { + if (_jarSource == null) { + _jarSource = new JarFile(_source); + } + return false; + + } catch (IOException ioe) { + String msg = "Failed to resolve resource bundle jar file '" + + _source + "'"; + Log.warning(msg + "."); + Log.logStackTrace(ioe); + throw (IOException) new IOException(msg).initCause(ioe); + } + } + + /** + * Closes our (possibly opened) jar file. + */ + protected void closeJar () + { + try { + if (_jarSource != null) { + _jarSource.close(); + } + } catch (Exception ioe) { + Log.warning("Failed to close jar file [path=" + _source + + ", error=" + ioe + "]."); + } + } + + /** + * Returns the cache directory used for unpacked resources. + */ + public static File getCacheDir () + { + if (_tmpdir == null) { + String tmpdir = System.getProperty("java.io.tmpdir"); + if (tmpdir == null) { + Log.info("No system defined temp directory. Faking it."); + tmpdir = System.getProperty("user.home"); + } + setCacheDir(new File(tmpdir, ".narcache")); + } + return _tmpdir; + } + + /** + * Specifies the directory in which our temporary resource files + * should be stored. + */ + public static void setCacheDir (File tmpdir) + { + String rando = Long.toHexString((long)(Math.random() * Long.MAX_VALUE)); + _tmpdir = new File(tmpdir, rando); + if (!_tmpdir.exists()) { + Log.info("Creating narya temp cache directory '" + _tmpdir + "'."); + _tmpdir.mkdirs(); + } + + // add a hook to blow away the temp directory when we exit + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run () { + Log.info("Clearing narya temp cache '" + _tmpdir + "'."); + FileUtil.recursiveDelete(_tmpdir); + } + }); + } + + /** Strips the .jar off of jar file paths. */ + protected static String stripSuffix (String path) + { + if (path.endsWith(".jar")) { + return path.substring(0, path.length()-4); + } else { + // we have to change the path somehow + return path + "-cache"; + } + } + + /** The file from which we construct our jar file. */ + protected File _source; + + /** The last modified time of our source jar file. */ + protected long _sourceLastMod = -1; + + /** A file whose timestamp indicates whether or not our existing jar + * file has been unpacked. */ + protected File _unpacked; + + /** A directory into which we unpack files from our bundle. */ + protected File _cache; + + /** The jar file from which we load resources. */ + protected JarFile _jarSource; + + /** A directory in which we temporarily unpack our resource files. */ + protected static File _tmpdir; +} diff --git a/src/java/com/threerings/resource/ResourceManager.java b/src/java/com/threerings/resource/ResourceManager.java new file mode 100644 index 00000000..afa61d16 --- /dev/null +++ b/src/java/com/threerings/resource/ResourceManager.java @@ -0,0 +1,691 @@ +// +// $Id: ResourceManager.java 4000 2006-04-05 19:40:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.resource; + +import java.awt.EventQueue; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.imageio.stream.FileImageInputStream; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.MemoryCacheImageInputStream; + +import com.samskivert.net.PathUtil; +import com.samskivert.util.ResultListener; +import com.samskivert.util.StringUtil; + +/** + * The resource manager is responsible for maintaining a repository of + * resources that are synchronized with a remote source. This is + * accomplished in the form of sets of jar files (resource bundles) that + * contain resources and that are updated from a remote resource + * repository via HTTP. These resource bundles are organized into + * resource sets. A resource set contains one or more resource bundles and + * is defined much like a classpath. + * + *

The resource manager can load resources from the default resource + * set, and can make available named resource sets to entities that wish + * to do their own resource loading. If the resource manager fails to + * locate a resource in the default resource set, it falls back to loading + * the resource via the classloader (which will search the classpath). + * + *

Applications that wish to make use of resource sets and their + * associated bundles must call {@link #initBundles} after constructing + * the resource manager, providing the path to a resource definition file + * which describes these resource sets. The definition file will be loaded + * and the resource bundles defined within will be loaded relative to the + * resource directory. The bundles will be cached in the user's home + * directory and only reloaded when the source resources have been + * updated. The resource definition file looks something like the + * following: + * + *

+ * resource.set.default = sets/misc/config.jar: \
+ *                        sets/misc/icons.jar
+ * resource.set.tiles = sets/tiles/ground.jar: \
+ *                      sets/tiles/objects.jar: \
+ *                      /global/resources/tiles/ground.jar: \
+ *                      /global/resources/tiles/objects.jar
+ * resource.set.sounds = sets/sounds/sfx.jar: \
+ *                       sets/sounds/music.jar: \
+ *                       /global/resources/sounds/sfx.jar: \
+ *                       /global/resources/sounds/music.jar
+ * 
+ * + *

All resource set definitions are prefixed with + * resource.set. and all text following that string is + * considered to be the name of the resource set. The resource set named + * default is the default resource set and is the one that is + * searched for resources is a call to {@link #getResource}. + * + *

When a resource is loaded from a resource set, the set is searched + * in the order that entries are specified in the definition. + */ +public class ResourceManager +{ + /** + * Provides facilities for notifying an observer of the resource + * unpacking process. + */ + public interface InitObserver + { + /** + * Indicates a percent completion along with an estimated time + * remaining in seconds. + */ + public void progress (int percent, long remaining); + + /** + * Indicates that there was a failure unpacking our resource + * bundles. + */ + public void initializationFailed (Exception e); + } + + /** + * An adapter that wraps an {@link InitObserver} and routes all method + * invocations to the AWT thread. + */ + public static class AWTInitObserver implements InitObserver + { + public AWTInitObserver (InitObserver obs) { + _obs = obs; + } + + public void progress (final int percent, final long remaining) { + EventQueue.invokeLater(new Runnable() { + public void run () { + _obs.progress(percent, remaining); + } + }); + } + + public void initializationFailed (final Exception e) { + EventQueue.invokeLater(new Runnable() { + public void run () { + _obs.initializationFailed(e); + } + }); + } + + protected InitObserver _obs; + } + + /** + * Constructs a resource manager which will load resources via the + * classloader, prepending resourceRoot to their path. + * + * @param resourceRoot the path to prepend to resource paths prior to + * attempting to load them via the classloader. When resources are + * bundled into the default resource bundle, they don't need this + * prefix, but if they're to be loaded from the classpath, it's likely + * that they'll live in some sort of resources directory + * to isolate them from the rest of the files in the classpath. This + * is not a platform dependent path (forward slash is always used to + * separate path elements). + */ + public ResourceManager (String resourceRoot) + { + this(resourceRoot, ResourceManager.class.getClassLoader()); + } + + /** + * Creates a resource manager with the specified class loader via + * which to load classes. See {@link #ResourceManager(String)} for + * further documentation. + */ + public ResourceManager (String resourceRoot, ClassLoader loader) + { + _rootPath = resourceRoot; + _loader = loader; + + // get our resource directory from resource_dir if possible + initResourceDir(null); + + // set up a URL handler so that things can be loaded via urls + // with the 'resource' protocol + AccessController.doPrivileged(new PrivilegedAction() { + public Object run () { + Handler.registerHandler(ResourceManager.this); + return null; + } + }); + } + + /** + * Initializes the bundle sets to be made available by this resource + * manager. Applications that wish to make use of resource bundles + * should call this method after constructing the resource manager. + * + * @param resourceDir the base directory to which the paths in the + * supplied configuration file are relative. If this is null, the + * system property resource_dir will be used, if + * available. + * @param configPath the path (relative to the resource dir) of the + * resource definition file. + * @param initObs a bundle initialization observer to notify of + * unpacking progress and success or failure, or null if + * the caller doesn't care to be informed; note that in the latter + * case, the calling thread will block until bundle unpacking is + * complete. + * + * @exception IOException thrown if we are unable to read our resource + * manager configuration. + */ + public void initBundles ( + String resourceDir, String configPath, InitObserver initObs) + throws IOException + { + // reinitialize our resource dir if it was specified + if (resourceDir != null) { + initResourceDir(resourceDir); + } + + // check to see if we're in developer mode in which case we won't + // unpack our resources + _unpack = !"true".equalsIgnoreCase( + System.getProperty("no_unpack_resources")); + + // load up our configuration + Properties config = new Properties(); + try { + config.load(new FileInputStream(new File(_rdir, configPath))); + } catch (Exception e) { + String errmsg = "Unable to load resource manager config " + + "[rdir=" + _rdir + ", cpath=" + configPath + "]"; + Log.warning(errmsg + "."); + Log.logStackTrace(e); + throw new IOException(errmsg); + } + + // resolve the configured resource sets + ArrayList dlist = new ArrayList(); + Enumeration names = config.propertyNames(); + while (names.hasMoreElements()) { + String key = (String)names.nextElement(); + if (!key.startsWith(RESOURCE_SET_PREFIX)) { + continue; + } + String setName = key.substring(RESOURCE_SET_PREFIX.length()); + resolveResourceSet(setName, config.getProperty(key), dlist); + } + + // if an observer was passed in, then we do not need to block + // the caller + final boolean[] shouldWait = new boolean[] { false }; + if (initObs == null) { + // if there's no observer, we'll need to block the caller + shouldWait[0] = true; + initObs = new InitObserver() { + public void progress (int percent, long remaining) { + if (percent >= 100) { + synchronized (this) { + // turn off shouldWait, in case we reached + // 100% progress before the calling thread even + // gets a chance to get to the blocking code, below + shouldWait[0] = false; + notify(); + } + } + } + public void initializationFailed (Exception e) { + synchronized (this) { + shouldWait[0] = false; + notify(); + } + } + }; + } + + // start a thread to unpack our bundles + Unpacker unpack = new Unpacker(dlist, initObs); + unpack.start(); + + if (shouldWait[0]) { + synchronized (initObs) { + if (shouldWait[0]) { + try { + initObs.wait(); + } catch (InterruptedException ie) { + Log.warning("Interrupted while waiting for bundles " + + "to unpack."); + } + } + } + } + } + + /** + * Given a path relative to the resource directory, the path is + * properly jimmied (assuming we always use /) and combined with the + * resource directory to yield a {@link File} object that can be used + * to access the resource. + * + * @return a file referencing the specified resource or null if the + * resource manager was never configured with a resource directory. + */ + public File getResourceFile (String path) + { + if (_rdir == null) { + return null; + } + if (!"/".equals(File.separator)) { + path = StringUtil.replace(path, "/", File.separator); + } + return new File(_rdir, path); + } + + /** + * Checks to see if the specified bundle exists, is unpacked and is + * ready to be used. + */ + public boolean checkBundle (String path) + { + File bfile = getResourceFile(path); + return (bfile == null) ? false : + new ResourceBundle(bfile, true, _unpack).isUnpacked(); + } + + /** + * Resolve the specified bundle (the bundle file must already exist in + * the appropriate place on the file system) and return it on the + * specified result listener. Note that the result listener may be + * notified before this method returns on the caller's thread if the + * bundle is already resolved, or it may be notified on a brand new + * thread if the bundle requires unpacking. + */ + public void resolveBundle (String path, final ResultListener listener) + { + File bfile = getResourceFile(path); + if (bfile == null) { + String errmsg = "ResourceManager not configured with " + + "resource directory."; + listener.requestFailed(new IOException(errmsg)); + return; + } + + final ResourceBundle bundle = new ResourceBundle(bfile, true, _unpack); + if (bundle.isUnpacked()) { + if (bundle.sourceIsReady()) { + listener.requestCompleted(bundle); + } else { + String errmsg = "Bundle initialization failed."; + listener.requestFailed(new IOException(errmsg)); + } + return; + } + + // start a thread to unpack our bundles + ArrayList list = new ArrayList(); + list.add(bundle); + Unpacker unpack = new Unpacker(list, new InitObserver() { + public void progress (int percent, long remaining) { + if (percent == 100) { + listener.requestCompleted(bundle); + } + } + public void initializationFailed (Exception e) { + listener.requestFailed(e); + } + }); + unpack.start(); + } + + /** + * Returns the class loader being used to load resources if/when there + * are no resource bundles from which to load them. + */ + public ClassLoader getClassLoader () + { + return _loader; + } + + /** + * Configures the class loader this manager should use to load + * resources if/when there are no bundles from which to load them. + */ + public void setClassLoader (ClassLoader loader) + { + _loader = loader; + } + + /** + * Fetches a resource from the local repository. + * + * @param path the path to the resource + * (ie. "config/miso.properties"). This should not begin with a slash. + * + * @exception IOException thrown if a problem occurs locating or + * reading the resource. + */ + public InputStream getResource (String path) + throws IOException + { + InputStream in = null; + + // first look for this resource in our default resource bundle + for (int i = 0; i < _default.length; i++) { + in = _default[i].getResource(path); + if (in != null) { + return in; + } + } + + // fallback next to an unpacked resource file + File file = getResourceFile(path); + if (file != null && file.exists()) { + return new FileInputStream(file); + } + + // if we still didn't find anything, try the classloader + final String rpath = PathUtil.appendPath(_rootPath, path); + in = (InputStream)AccessController.doPrivileged(new PrivilegedAction() { + public Object run () { + return _loader.getResourceAsStream(rpath); + } + }); + if (in != null) { + return in; + } + + // if we still haven't found it, we throw an exception + String errmsg = "Unable to locate resource [path=" + path + "]"; + throw new FileNotFoundException(errmsg); + } + + /** + * Fetches the specified resource as an {@link ImageInputStream} and + * one that takes advantage, if possible, of caching of unpacked + * resources on the local filesystem. + * + * @exception FileNotFoundException thrown if the resource could not + * be located in any of the bundles in the specified set, or if the + * specified set does not exist. + * @exception IOException thrown if a problem occurs locating or + * reading the resource. + */ + public ImageInputStream getImageResource (String path) + throws IOException + { + // first look for this resource in our default resource bundle + for (int i = 0; i < _default.length; i++) { + File file = _default[i].getResourceFile(path); + if (file != null) { + return new FileImageInputStream(file); + } + } + + // fallback next to an unpacked resource file + File file = getResourceFile(path); + if (file != null && file.exists()) { + return new FileImageInputStream(file); + } + + // if we still didn't find anything, try the classloader + final String rpath = PathUtil.appendPath(_rootPath, path); + InputStream in = (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run () { + return _loader.getResourceAsStream(rpath); + } + }); + if (in != null) { + return new MemoryCacheImageInputStream(new BufferedInputStream(in)); + } + + // if we still haven't found it, we throw an exception + String errmsg = "Unable to locate image resource [path=" + path + "]"; + throw new FileNotFoundException(errmsg); + } + + /** + * Returns an input stream from which the requested resource can be + * loaded. Note: this performs a linear search of all of the + * bundles in the set and returns the first resource found with the + * specified path, thus it is not extremely efficient and will behave + * unexpectedly if you use the same paths in different resource + * bundles. + * + * @exception FileNotFoundException thrown if the resource could not + * be located in any of the bundles in the specified set, or if the + * specified set does not exist. + * @exception IOException thrown if a problem occurs locating or + * reading the resource. + */ + public InputStream getResource (String rset, String path) + throws IOException + { + // grab the resource bundles in the specified resource set + ResourceBundle[] bundles = getResourceSet(rset); + if (bundles == null) { + throw new FileNotFoundException( + "Unable to locate resource [set=" + rset + + ", path=" + path + "]"); + } + + // look for the resource in any of the bundles + int size = bundles.length; + for (int ii = 0; ii < size; ii++) { + InputStream instr = bundles[ii].getResource(path); + if (instr != null) { +// Log.info("Found resource [rset=" + rset + +// ", bundle=" + bundles[ii].getSource().getPath() + +// ", path=" + path + ", in=" + instr + "]."); + return instr; + } + } + + throw new FileNotFoundException( + "Unable to locate resource [set=" + rset + ", path=" + path + "]"); + } + + /** + * Fetches the specified resource as an {@link ImageInputStream} and + * one that takes advantage, if possible, of caching of unpacked + * resources on the local filesystem. + * + * @exception FileNotFoundException thrown if the resource could not + * be located in any of the bundles in the specified set, or if the + * specified set does not exist. + * @exception IOException thrown if a problem occurs locating or + * reading the resource. + */ + public ImageInputStream getImageResource (String rset, String path) + throws IOException + { + // grab the resource bundles in the specified resource set + ResourceBundle[] bundles = getResourceSet(rset); + if (bundles == null) { + throw new FileNotFoundException( + "Unable to locate image resource [set=" + rset + + ", path=" + path + "]"); + } + + // look for the resource in any of the bundles + int size = bundles.length; + for (int ii = 0; ii < size; ii++) { + File file = bundles[ii].getResourceFile(path); + if (file != null) { +// Log.info("Found image resource [rset=" + rset + +// ", bundle=" + bundles[ii].getSource() + +// ", path=" + path + ", file=" + file + "]."); + return new FileImageInputStream(file); + } + } + + String errmsg = "Unable to locate image resource [set=" + rset + + ", path=" + path + "]"; + throw new FileNotFoundException(errmsg); + } + + /** + * Returns a reference to the resource set with the specified name, or + * null if no set exists with that name. Services that wish to load + * their own resources can allow the resource manager to load up a + * resource set for them, from which they can easily load their + * resources. + */ + public ResourceBundle[] getResourceSet (String name) + { + return (ResourceBundle[])_sets.get(name); + } + + protected void initResourceDir (String resourceDir) + { + // if none was specified, check the resource_dir system property + if (resourceDir == null) { + try { + resourceDir = System.getProperty("resource_dir"); + } catch (SecurityException se) { + } + } + + // if we found no resource directory, don't use one + if (resourceDir == null) { + return; + } + + // make sure there's a trailing slash + if (!resourceDir.endsWith(File.separator)) { + resourceDir += File.separator; + } + _rdir = new File(resourceDir); + } + + /** + * Loads up a resource set based on the supplied definition + * information. + */ + protected void resolveResourceSet ( + String setName, String definition, List dlist) + { + StringTokenizer tok = new StringTokenizer(definition, ":"); + ArrayList set = new ArrayList(); + + while (tok.hasMoreTokens()) { + String path = tok.nextToken().trim(); + ResourceBundle bundle = + new ResourceBundle(getResourceFile(path), true, _unpack); + set.add(bundle); + if (bundle.isUnpacked() && bundle.sourceIsReady()) { + continue; + } + dlist.add(bundle); + } + + // convert our array list into an array and stick it in the table + ResourceBundle[] setvec = new ResourceBundle[set.size()]; + set.toArray(setvec); + _sets.put(setName, setvec); + + // if this is our default resource bundle, keep a reference to it + if (DEFAULT_RESOURCE_SET.equals(setName)) { + _default = setvec; + } + } + + /** Used to unpack bundles on a separate thread. */ + protected static class Unpacker extends Thread + { + public Unpacker (List bundles, InitObserver obs) + { + _bundles = bundles; + _obs = obs; + } + + public void run () + { + try { + int count = 0; + for (Iterator iter = _bundles.iterator(); iter.hasNext(); ) { + ResourceBundle bundle = (ResourceBundle)iter.next(); + if (!bundle.sourceIsReady()) { + Log.warning("Bundle failed to initialize " + + bundle + "."); + } + if (_obs != null) { + int pct = count*100/_bundles.size(); + if (pct < 100) { + _obs.progress(pct, 1); + } + } + count++; + } + if (_obs != null) { + _obs.progress(100, 0); + } + + } catch (Exception e) { + if (_obs != null) { + _obs.initializationFailed(e); + } + } + } + + protected List _bundles; + protected InitObserver _obs; + } + + /** The classloader we use for classpath-based resource loading. */ + protected ClassLoader _loader; + + /** The directory that contains our resource bundles. */ + protected File _rdir; + + /** The prefix we prepend to resource paths before attempting to load + * them from the classpath. */ + protected String _rootPath; + + /** Whether or not to unpack our resource bundles. */ + protected boolean _unpack; + + /** Our default resource set. */ + protected ResourceBundle[] _default = new ResourceBundle[0]; + + /** A table of our resource sets. */ + protected HashMap _sets = new HashMap(); + + /** The prefix of configuration entries that describe a resource + * set. */ + protected static final String RESOURCE_SET_PREFIX = "resource.set."; + + /** The name of the default resource set. */ + protected static final String DEFAULT_RESOURCE_SET = "default"; +} diff --git a/src/java/com/threerings/util/BrowserUtil.java b/src/java/com/threerings/util/BrowserUtil.java new file mode 100644 index 00000000..315cc51c --- /dev/null +++ b/src/java/com/threerings/util/BrowserUtil.java @@ -0,0 +1,141 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.net.URL; + +import com.samskivert.util.ResultListener; +import com.samskivert.util.RunAnywhere; +import com.samskivert.util.StringUtil; + +/** + * Encapsulates a bunch of hackery needed to invoke an external web browser + * from within a Java application. + */ +public class BrowserUtil +{ + /** + * Opens the user's web browser with the specified URL. + * + * @param url the URL to display in an external browser. + * @param listener a listener to be notified if we failed to launch the + * browser. Note: it will not be notified of success. + */ + public static void browseURL (URL url, ResultListener listener) + { + browseURL(url, listener, "firefox"); + } + + /** + * Opens the user's web browser with the specified URL. + * + * @param url the URL to display in an external browser. + * @param listener a listener to be notified if we failed to launch the + * browser. Note: it will not be notified of success. + * @param genagent the path to the browser to execute on non-Windows, + * non-MacOS. + */ + public static void browseURL ( + URL url, ResultListener listener, String genagent) + { + String[] cmd; + if (RunAnywhere.isWindows()) { + // TODO: test this on Vinders 98 +// cmd = new String[] { "rundll32", "url.dll,FileProtocolHandler", +// url.toString() }; + String osName = System.getProperty("os.name"); + if (osName.indexOf("9") != -1 || osName.indexOf("Me") != -1) { + cmd = new String[] { "command.com", "/c", "start", + "\"" + url.toString() + "\"" }; + } else { + cmd = new String[] { "cmd.exe", "/c", "start", "\"\"", + "\"" + url.toString() + "\"" }; + } + + } else if (RunAnywhere.isMacOS()) { + cmd = new String[] { "open", url.toString() }; + + } else { // Linux, Solaris, etc + cmd = new String[] { genagent, url.toString() }; + } + + Log.info("Browsing URL [cmd=" + StringUtil.join(cmd, " ") + "]."); + try { + Process process = Runtime.getRuntime().exec(cmd); + BrowserTracker tracker = new BrowserTracker(process, url, listener); + tracker.start(); + } catch (Exception e) { + Log.warning("Failed to launch browser [url=" + url + + ", error=" + e + "]."); + listener.requestFailed(e); + } + } + + protected static class BrowserTracker extends Thread + { + public BrowserTracker (Process process, URL url, ResultListener rl) { + super("BrowserLaunchWaiter"); + setDaemon(true); + _process = process; + _url = url; + _listener = rl; + } + + public void run () { + try { + _process.waitFor(); + int rv = _process.exitValue(); + if (rv == 0) { + return; + } + + String errmsg = "Launched browser failed [rv=" + rv + "]."; + Log.warning(errmsg); + if (!RunAnywhere.isWindows()) { + _listener.requestFailed(new Exception(errmsg)); + return; + } + + // if we're on windows, make a last ditch effort + String[] cmd = new String[] { + "C:\\Program Files\\Internet Explorer\\" + + "IEXPLORE.EXE", "\"" + _url.toString() + "\""}; + Process process = Runtime.getRuntime().exec(cmd); + process.waitFor(); + rv = process.exitValue(); + if (rv != 0) { + errmsg = "Failed to launch iexplore.exe [rv=" + rv + "]."; + Log.warning(errmsg); + _listener.requestFailed(new Exception(errmsg)); + } + + } catch (Exception e) { + Log.logStackTrace(e); + _listener.requestFailed(e); + } + } + + protected Process _process; + protected URL _url; + protected ResultListener _listener; + }; +} diff --git a/src/java/com/threerings/util/DirectionCodes.java b/src/java/com/threerings/util/DirectionCodes.java new file mode 100644 index 00000000..3021e214 --- /dev/null +++ b/src/java/com/threerings/util/DirectionCodes.java @@ -0,0 +1,104 @@ +// +// $Id: DirectionCodes.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +/** + * A single, top-level location for the definition of compass direction + * constants, which are used by a variety of Narya services. + */ +public interface DirectionCodes +{ + /** A direction code indicating no direction. */ + public static final int NONE = -1; + + /** A direction code indicating moving left. */ + public static final int LEFT = 0; + + /** A direction code indicating moving right. */ + public static final int RIGHT = 1; + + /** A direction code indicating a counter-clockwise rotation. */ + public static final int CCW = 0; + + /** A direction code indicating a clockwise rotation. */ + public static final int CW = 1; + + /** A direction code indicating horizontal movement. */ + public static final int HORIZONTAL = 0; + + /** A direction code indicating vertical movement. */ + public static final int VERTICAL = 1; + + /** A direction code indicating southwest. */ + public static final int SOUTHWEST = 0; + + /** A direction code indicating west. */ + public static final int WEST = 1; + + /** A direction code indicating northwest. */ + public static final int NORTHWEST = 2; + + /** A direction code indicating north. */ + public static final int NORTH = 3; + + /** A direction code indicating northeast. */ + public static final int NORTHEAST = 4; + + /** A direction code indicating east. */ + public static final int EAST = 5; + + /** A direction code indicating southeast. */ + public static final int SOUTHEAST = 6; + + /** A direction code indicating south. */ + public static final int SOUTH = 7; + + /** The number of basic compass directions. */ + public static final int DIRECTION_COUNT = 8; + + /** A direction code indicating west by southwest. */ + public static final int WESTSOUTHWEST = 8; + + /** A direction code indicating west by northwest. */ + public static final int WESTNORTHWEST = 9; + + /** A direction code indicating north by northwest. */ + public static final int NORTHNORTHWEST = 10; + + /** A direction code indicating north by northeast. */ + public static final int NORTHNORTHEAST = 11; + + /** A direction code indicating east by northeast. */ + public static final int EASTNORTHEAST = 12; + + /** A direction code indicating east by southeast. */ + public static final int EASTSOUTHEAST = 13; + + /** A direction code indicating south by southeast. */ + public static final int SOUTHSOUTHEAST = 14; + + /** A direction code indicating south by southwest. */ + public static final int SOUTHSOUTHWEST = 15; + + /** The number of fine compass directions. */ + public static final int FINE_DIRECTION_COUNT = 16; +} diff --git a/src/java/com/threerings/util/DirectionUtil.java b/src/java/com/threerings/util/DirectionUtil.java new file mode 100644 index 00000000..ca83df8a --- /dev/null +++ b/src/java/com/threerings/util/DirectionUtil.java @@ -0,0 +1,338 @@ +// +// $Id: DirectionUtil.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.Point; + +import com.samskivert.util.IntListUtil; + +/** + * Direction related utility functions. + */ +public class DirectionUtil implements DirectionCodes +{ + /** + * Returns an array of names corresponding to each direction constant. + */ + public static String[] getDirectionNames () + { + return DIR_STRINGS; + } + + /** + * Returns a string representation of the supplied direction code. + */ + public static String toString (int direction) + { + return ((direction >= 0) && (direction < FINE_DIRECTION_COUNT)) ? + DIR_STRINGS[direction] : "INVALID"; + } + + /** + * Returns an abbreviated string representation of the supplied + * direction code. + */ + public static String toShortString (int direction) + { + return ((direction >= 0) && (direction < FINE_DIRECTION_COUNT)) ? + SHORT_DIR_STRINGS[direction] : "?"; + } + + /** + * Returns the direction code that corresponds to the supplied string + * or {@link #NONE} if the string does not correspond to a known + * direction code. + */ + public static int fromString (String dirstr) + { + for (int ii = 0; ii < FINE_DIRECTION_COUNT; ii++) { + if (DIR_STRINGS[ii].equals(dirstr)) { + return ii; + } + } + return NONE; + } + + /** + * Returns the direction code that corresponds to the supplied short + * string or {@link #NONE} if the string does not correspond to a + * known direction code. + */ + public static int fromShortString (String dirstr) + { + for (int ii = 0; ii < FINE_DIRECTION_COUNT; ii++) { + if (SHORT_DIR_STRINGS[ii].equals(dirstr)) { + return ii; + } + } + return NONE; + } + + /** + * Returns a string representation of an array of direction codes. The + * directions are represented by the abbreviated names. + */ + public static String toString (int[] directions) + { + StringBuilder buf = new StringBuilder("{"); + for (int i = 0; i < directions.length; i++) { + if (i > 0) { + buf.append(", "); + } + buf.append(toShortString(directions[i])); + } + return buf.append("}").toString(); + } + + /** + * Rotates the requested fine direction constant clockwise by + * the requested number of ticks. + */ + public static int rotateCW (int direction, int ticks) + { + for (int ii = 0; ii < ticks; ii++) { + direction = FINE_CW_ROTATE[direction]; + } + return direction; + } + + /** + * Rotates the requested fine direction constant + * counter-clockwise by the requested number of ticks. + */ + public static int rotateCCW (int direction, int ticks) + { + for (int ii = 0; ii < ticks; ii++) { + direction = FINE_CCW_ROTATE[direction]; + } + return direction; + } + + /** + * Returns the opposite of the specified direction. + */ + public static int getOpposite (int direction) + { + return rotateCW(direction, FINE_CW_ROTATE.length/2); + } + + /** + * Get the direction closest to the specified direction, out of + * the directions in the possible list (preferring a clockwise match). + */ + public static int getClosest (int direction, int[] possible) + { + return getClosest(direction, possible, true); + } + + /** + * Get the direction closest to the specified direction, out of + * the directions in the possible list. + * + * @param preferCW whether to prefer a clockwise match or a + * counter-clockwise match. + */ + public static int getClosest (int direction, int[] possible, + boolean preferCW) + { + // rotate a tick at a time, looking for matches + int first = direction; + int second = direction; + for (int ii = 0; ii <= FINE_DIRECTION_COUNT / 2; ii++) { + if (IntListUtil.contains(possible, first)) { + return first; + } + + if (ii != 0 && IntListUtil.contains(possible, second)) { + return second; + } + + first = preferCW ? rotateCW(first, 1) : rotateCCW(first, 1); + second = preferCW ? rotateCCW(second, 1) : rotateCW(second, 1); + } + + return NONE; + } + + /** + * Returns which of the eight compass directions that point + * b lies in from point a as one of the + * {@link DirectionCodes} direction constants. Note: that the + * coordinates supplied are assumed to be logical (screen) rather than + * cartesian coordinates and NORTH is considered to point + * toward the top of the screen. + */ + public static int getDirection (Point a, Point b) + { + return getDirection(a.getX(), a.getY(), b.getX(), b.getY()); + } + + /** + * Returns which of the eight compass directions that point + * b lies in from point a as one of the + * {@link DirectionCodes} direction constants. Note: that the + * coordinates supplied are assumed to be logical (screen) rather than + * cartesian coordinates and NORTH is considered to point + * toward the top of the screen. + */ + public static int getDirection (int ax, int ay, int bx, int by) + { + return getDirection(Math.atan2(by-ay, bx-ax)); + } + + /** + * Returns which of the eight compass directions that point + * b lies in from point a as one of the + * {@link DirectionCodes} direction constants. Note: that the + * coordinates supplied are assumed to be logical (screen) rather than + * cartesian coordinates and NORTH is considered to point + * toward the top of the screen. + */ + public static int getDirection (double ax, double ay, double bx, double by) + { + return getDirection(Math.atan2(by-ay, bx-ax)); + } + + /** + * Returns which of the eight compass directions is associated with + * the specified angle theta. Note: that the angle supplied + * is assumed to increase clockwise around the origin (which screen + * angles do) rather than counter-clockwise around the origin (which + * cartesian angles do) and NORTH is considered to point + * toward the top of the screen. + */ + public static int getDirection (double theta) + { + theta = ((theta + Math.PI) * 4) / Math.PI; + return (int)(Math.round(theta) + WEST) % 8; + } + + /** + * Returns which of the sixteen compass directions that point + * b lies in from point a as one of the + * {@link DirectionCodes} direction constants. Note: that the + * coordinates supplied are assumed to be logical (screen) rather than + * cartesian coordinates and NORTH is considered to point + * toward the top of the screen. + */ + public static int getFineDirection (Point a, Point b) + { + return getFineDirection(a.x, a.y, b.x, b.y); + } + + /** + * Returns which of the sixteen compass directions that point + * b lies in from point a as one of the + * {@link DirectionCodes} direction constants. Note: that the + * coordinates supplied are assumed to be logical (screen) rather than + * cartesian coordinates and NORTH is considered to point + * toward the top of the screen. + */ + public static int getFineDirection (int ax, int ay, int bx, int by) + { + return getFineDirection(Math.atan2(by-ay, bx-ax)); + } + + /** + * Returns which of the sixteen compass directions is associated with + * the specified angle theta. Note: that the angle supplied + * is assumed to increase clockwise around the origin (which screen + * angles do) rather than counter-clockwise around the origin (which + * cartesian angles do) and NORTH is considered to point + * toward the top of the screen. + */ + public static int getFineDirection (double theta) + { + theta = ((theta + Math.PI) * 8) / Math.PI; + return ANGLE_MAP[(int)Math.round(theta) % FINE_DIRECTION_COUNT]; + } + + /** + * Move the specified point in the specified screen direction, + * adjusting by the specified adjustments. Fine directions are + * not supported. + */ + public static void moveDirection (Point p, int direction, int dx, int dy) + { + if (direction >= DIRECTION_COUNT) { + throw new IllegalArgumentException( + "Fine coordinates not supported."); + } + + switch (direction) { + case NORTH: case NORTHWEST: case NORTHEAST: p.y -= dy; + } + switch (direction) { + case SOUTH: case SOUTHWEST: case SOUTHEAST: p.y += dy; + } + switch (direction) { + case WEST: case SOUTHWEST: case NORTHWEST: p.x -= dx; + } + switch (direction) { + case EAST: case SOUTHEAST: case NORTHEAST: p.x += dx; + } + } + + /** Direction constant string names. */ + protected static final String[] DIR_STRINGS = { + "SOUTHWEST", "WEST", "NORTHWEST", "NORTH", + "NORTHEAST", "EAST", "SOUTHEAST", "SOUTH", + "WESTSOUTHWEST", "WESTNORTHWEST", "NORTHNORTHWEST", "NORTHNORTHEAST", + "EASTNORTHEAST", "EASTSOUTHEAST", "SOUTHSOUTHEAST", "SOUTHSOUTHWEST", + }; + + /** Abbreviated direction constant string names. */ + protected static final String[] SHORT_DIR_STRINGS = { + "SW", "W", "NW", "N", "NE", "E", "SE", "S", + "WSW", "WNW", "NNW", "NNE", "ENE", "ESE", "SSE", "SSW", + }; + + /** Used to rotate a fine compass direction clockwise. */ + protected static final int[] FINE_CW_ROTATE = { + /* SW -> */ WESTSOUTHWEST, /* W -> */ WESTNORTHWEST, + /* NW -> */ NORTHNORTHWEST, /* N -> */ NORTHNORTHEAST, + /* NE -> */ EASTNORTHEAST, /* E -> */ EASTSOUTHEAST, + /* SE -> */ SOUTHSOUTHEAST, /* S -> */ SOUTHSOUTHWEST, + /* WSW -> */ WEST, /* WNW -> */ NORTHWEST, + /* NNW -> */ NORTH, /* NNE -> */ NORTHEAST, + /* ENE -> */ EAST, /* ESE -> */ SOUTHEAST, + /* SSE -> */ SOUTH, /* SSW -> */ SOUTHWEST + }; + + /** Used to rotate a fine compass direction counter-clockwise. */ + protected static final int[] FINE_CCW_ROTATE = { + /* SW -> */ SOUTHSOUTHWEST, /* W -> */ WESTSOUTHWEST, + /* NW -> */ WESTNORTHWEST, /* N -> */ NORTHNORTHWEST, + /* NE -> */ NORTHNORTHEAST, /* E -> */ EASTNORTHEAST, + /* SE -> */ EASTSOUTHEAST, /* S -> */ SOUTHSOUTHEAST, + /* WSW -> */ SOUTHWEST, /* WNW -> */ WEST, + /* NNW -> */ NORTHWEST, /* NNE -> */ NORTH, + /* ENE -> */ NORTHEAST, /* ESE -> */ EAST, + /* SSE -> */ SOUTHEAST, /* SSW -> */ SOUTH + }; + + /** Used to map an angle to a fine compass direction. */ + protected static final int[] ANGLE_MAP = { + WEST, WESTNORTHWEST, NORTHWEST, NORTHNORTHWEST, NORTH, NORTHNORTHEAST, + NORTHEAST, EASTNORTHEAST, EAST, EASTSOUTHEAST, SOUTHEAST, + SOUTHSOUTHEAST, SOUTH, SOUTHSOUTHWEST, SOUTHWEST, WESTSOUTHWEST }; +} diff --git a/src/java/com/threerings/util/IdleTracker.java b/src/java/com/threerings/util/IdleTracker.java new file mode 100644 index 00000000..2d30c724 --- /dev/null +++ b/src/java/com/threerings/util/IdleTracker.java @@ -0,0 +1,177 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.AWTEvent; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; + +import com.samskivert.util.Interval; +import com.samskivert.util.RunQueue; + +/** + * Used to track user idleness in an AWT application. + */ +public abstract class IdleTracker +{ + /** + * Creates an idle tracker that will report idleness (via {@link + * #idledOut}) after toIdleTime milliseconds have elapsed. + * After an additional toAbandonTime milliseconds have + * elapsed, we will report that the user has {@link #abandonedShip}. + */ + public IdleTracker (long toIdleTime, long toAbandonTime) + { + _toIdleTime = toIdleTime; + _toAbandonTime = toAbandonTime; + + // initialize our last event time + _lastEvent = getTimeStamp(); + } + + public void start (KeyboardManager keymgr, RunQueue rqueue) + { + // we want to observe all mouse and keyboard events + long eventMask = + AWTEvent.MOUSE_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK | + AWTEvent.MOUSE_WHEEL_EVENT_MASK | + AWTEvent.KEY_EVENT_MASK; + + // add the global event listener + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched (AWTEvent event) { + handleUserActivity(); + } + }, eventMask); + + // and tie into the keyboard manager if one is provided + if (keymgr != null) { + keymgr.registerKeyObserver(new KeyboardManager.KeyObserver() { + public void handleKeyEvent ( + int id, int keyCode, long timestamp) { + handleUserActivity(); + } + }); + } + + // register an interval to periodically check our last activity time + new Interval(rqueue) { + public void expired () { + checkIdle(); + } + }.schedule(_toIdleTime/3, true); + } + + /** + * Called when the client has been idle for {@link #_toIdleTime} + * milliseconds. + */ + protected abstract void idledOut (); + + /** + * Called when the client becomes non-idle after we have previously + * reported their idleness. + */ + protected abstract void idledIn (); + + /** + * Called when the client has been idle for {@link #_toIdleTime} plus + * {@link #_toAbandonTime} milliseconds. + */ + protected abstract void abandonedShip (); + + /** + * This should return a timestamp. We would use {@link + * System#currentTimeMillis} except that on Windows that sometimes does + * strange things like leap forward in time causing immediate idleness. + */ + protected abstract long getTimeStamp (); + + /** + * Called with any keyboard or mouse events performed on the frame so + * as to note user activity as it pertains to tracking the client idle + * state. + */ + protected void handleUserActivity () + { + // note the time of the last user action + _lastEvent = getTimeStamp(); + + // idle-in if appropriate + if (_state != ACTIVE) { + _state = ACTIVE; + idledIn(); + } + } + + /** + * Checks the last user event time and posts a command to idle them + * out if they've been inactive for too long, or log them out if + * they've been idle for too long. + */ + protected void checkIdle () + { + long now = getTimeStamp(); + + switch (_state) { + case ACTIVE: + // check whether they've idled out + if (now >= (_lastEvent + _toIdleTime)) { + Log.info("User idle for " + (now-_lastEvent) + "ms."); + _state = IDLE; + idledOut(); + } + break; + + case IDLE: + // check whether they've been idle for too long + if (now >= (_lastEvent + _toIdleTime + _toAbandonTime)) { + Log.info("User idle for " + (now-_lastEvent) + "ms. " + + "Abandoning ship."); + _state = ABANDONED; + abandonedShip(); + } + break; + } + } + +// /** The user's current state. */ +// protected static enum State { ACTIVE, IDLE, ABANDONED }; + + /** The duration after which we declare the user to be idle. */ + protected long _toIdleTime; + + /** The duration after which we declare the user to have abandoned ship. */ + protected long _toAbandonTime; + + /** The time of the last mouse or keyboard event; used to track + * whether the user is idle. */ + protected long _lastEvent; + + /** Whether the user is currently active, idle or abandoned. */ + protected int _state = ACTIVE; + + protected static final int ACTIVE = 0; + protected static final int IDLE = 1; + protected static final int ABANDONED = 2; +} diff --git a/src/java/com/threerings/util/KeyDispatcher.java b/src/java/com/threerings/util/KeyDispatcher.java new file mode 100644 index 00000000..1300261a --- /dev/null +++ b/src/java/com/threerings/util/KeyDispatcher.java @@ -0,0 +1,275 @@ +// +// $Id: KeyDispatcher.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.Component; +import java.awt.Window; +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; + +import javax.swing.JRootPane; +import javax.swing.JTable; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import javax.swing.text.JTextComponent; + +import com.samskivert.util.HashIntMap; + +/** + * Handles dispatching special global key pressed and released events to + * those that care to monitor and process such things. + * + *

A {@link JTextComponent} may registered as a "chat grabber" via + * {@link #pushChatGrabber} so as to capture typed chat characters + * regardless of which component currently has the focus. + * + *

Components may also register as global {@link KeyListener}s via + * {@link #addGlobalKeyListener} to always be notified of key press and + * release events for all keys. + */ +public class KeyDispatcher + implements KeyEventDispatcher, AncestorListener, WindowFocusListener +{ + /** + * Constructs a key dispatcher. + */ + public KeyDispatcher (Window window) + { + // save things off + _window = window; + + // listen to window events on our main window so that we can release + // keys when the mouse leaves the window + _window.addWindowFocusListener(this); + + // monitor key events from the central dispatch mechanism + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addKeyEventDispatcher(this); + } + + /** + * Shuts down the key dispatcher. + */ + public void shutdown () + { + // cease monitoring key events + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + removeKeyEventDispatcher(this); + + // cease observing our window + _window.removeWindowFocusListener(this); + } + + /** + * Makes the specified component the new grabber of key typed events + * that look like they're chat-related per {@link #isChatCharacter}. + */ + public void pushChatGrabber (JTextComponent comp) + { + // note this component as the new chat grabber + _curChatGrabber = comp; + + // add the component to the list of grabbers + _chatGrabbers.addLast(comp); + comp.addAncestorListener(this); + + // and request to give the new component the focus since that's a + // sensible thing to do as it's aiming to nab all key events + // henceforth + comp.requestFocusInWindow(); + } + + /** + * Removes the specified component from the list of chat grabbers so + * that it will no longer be notified of chat-like key events. + */ + public void removeChatGrabber (JTextComponent comp) + { + // remove the component from the list of grabbers + comp.removeAncestorListener(this); + _chatGrabbers.remove(comp); + + // update the current chat grabbing component + _curChatGrabber = _chatGrabbers.isEmpty() ? null : + _chatGrabbers.getLast(); + } + + /** + * Adds the key listener to receive all key events at all times. + */ + public void addGlobalKeyListener (KeyListener listener) + { + _listeners.add(listener); + } + + /** + * Removes the specified global key listener. + */ + public void removeGlobalKeyListener (KeyListener listener) + { + _listeners.remove(listener); + } + + // documentation inherited from interface KeyEventDispatcher + public boolean dispatchKeyEvent (KeyEvent e) + { + int lsize = _listeners.size(); + + switch (e.getID()) { + case KeyEvent.KEY_TYPED: + // dispatch to all the global listeners + for (int ii = 0; ii < lsize; ii++) { + _listeners.get(ii).keyTyped(e); + } + + // see if a chat grabber needs to grab it + if (_curChatGrabber != null) { + Component target = e.getComponent(); + // if the key was typed on a non-text component or one + // that wasn't editable... + if (isChatCharacter(e.getKeyChar()) && + !isTypableTarget(target)) { + // focus our grabby component, and redirect this + // key event there + _curChatGrabber.requestFocusInWindow(); + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + redispatchEvent(_curChatGrabber, e); + return true; + } + } + break; + + case KeyEvent.KEY_PRESSED: + if (lsize > 0) { + for (int ii = 0; ii < lsize; ii++) { + _listeners.get(ii).keyPressed(e); + } + // remember the key event.. + _downKeys.put(e.getKeyCode(), e); + } + break; + + case KeyEvent.KEY_RELEASED: + if (lsize > 0) { + for (int ii = 0; ii < lsize; ii++) { + ((KeyListener) _listeners.get(ii)).keyReleased(e); + } + // forget the key event + _downKeys.remove(e.getKeyCode()); + } + break; + } + + return false; + } + + /** + * Returns true if the specified target component supports being typed + * into, and thus we shouldn't steal focus away from it if the user + * starts typing. + */ + protected boolean isTypableTarget (Component target) + { + return target.isShowing() && + (((target instanceof JTextComponent) && + ((JTextComponent) target).isEditable()) || + (target instanceof JTable) || + (target instanceof JRootPane)); + } + + /** + * Returns whether the specified character is a chat character. + */ + protected boolean isChatCharacter (char c) + { + return (Character.isLetterOrDigit(c) || ('/' == c)); + } + + // documentation inherited from interface WindowFocusListener + public void windowGainedFocus (WindowEvent e) + { + // nothing + } + + // documentation inherited from interface WindowFocusListener + public void windowLostFocus (WindowEvent e) + { + // un-press any keys that were left down + if (!_downKeys.isEmpty()) { + long now = System.currentTimeMillis(); + for (KeyEvent down : _downKeys.values()) { + KeyEvent up = new KeyEvent( + down.getComponent(), KeyEvent.KEY_RELEASED, now, + down.getModifiers(), down.getKeyCode(), down.getKeyChar(), + down.getKeyLocation()); + for (int ii = 0, nn = _listeners.size(); ii < nn; ii++) { + _listeners.get(ii).keyReleased(up); + } + } + _downKeys.clear(); + } + } + + // documentation inherited from interface AncestorListener + public void ancestorAdded (AncestorEvent ae) + { + // nothing + } + + // documentation inherited from interface AncestorListener + public void ancestorMoved (AncestorEvent ae) + { + // nothing + } + + // documentation inherited from interface AncestorListener + public void ancestorRemoved (AncestorEvent ae) + { + removeChatGrabber((JTextComponent) ae.getComponent()); + } + + /** The main window for which we're observing key events. */ + protected Window _window; + + /** The current most-recently pushed component that wants to grab + * alphanumeric key presses. */ + protected JTextComponent _curChatGrabber; + + /** The stack of grabbers. */ + protected LinkedList _chatGrabbers = + new LinkedList(); + + /** Global key listeners. */ + protected ArrayList _listeners = new ArrayList(); + + /** Keys that are currently held down. */ + protected HashIntMap _downKeys = new HashIntMap(); +} diff --git a/src/java/com/threerings/util/KeyTranslator.java b/src/java/com/threerings/util/KeyTranslator.java new file mode 100644 index 00000000..208905aa --- /dev/null +++ b/src/java/com/threerings/util/KeyTranslator.java @@ -0,0 +1,79 @@ +// +// $Id: KeyTranslator.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.util.Iterator; + +/** + * The key translator interface provides a means whereby the keyboard + * manager can map a key code to the logical {@link + * com.samskivert.swing.Controller} action command that it represents. + */ +public interface KeyTranslator +{ + /** + * Returns whether there is an action command for the key + * corresponding to the given keycode. The translator may have an + * action command for either a key press or a key release of the key, + * or both. + */ + public boolean hasCommand (int keyCode); + + /** + * Returns the action command string associated with a key press of + * the key corresponding to the given key code, or null + * if there is no associated command. + */ + public String getPressCommand (int keyCode); + + /** + * Returns the action command string associated with a key release of + * the key corresponding to the given key code, or null + * if there is no associated command. + */ + public String getReleaseCommand (int keyCode); + + /** + * Returns the number of times each second that key presses are to be + * automatically repeated while the key is held down, or + * 0 to disable auto-repeat for the key. + */ + public int getRepeatRate (int keyCode); + + /** + * Returns the delay in milliseconds before generating auto-repeated + * key press events for the specified key. + */ + public long getRepeatDelay (int keyCode); + + /** + * Returns an iterator that iterates over the available press + * commands. + */ + public Iterator enumeratePressCommands (); + + /** + * Returns an iterator that iterates over the available release + * commands. + */ + public Iterator enumerateReleaseCommands (); +} diff --git a/src/java/com/threerings/util/KeyTranslatorImpl.java b/src/java/com/threerings/util/KeyTranslatorImpl.java new file mode 100644 index 00000000..47a5de24 --- /dev/null +++ b/src/java/com/threerings/util/KeyTranslatorImpl.java @@ -0,0 +1,190 @@ +// +// $Id: KeyTranslatorImpl.java 3272 2004-12-13 07:52:09Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.samskivert.util.HashIntMap; + +/** + * A basic implementation of the {@link KeyTranslator} interface that + * provides facilities for mapping key codes to action command strings for + * use by the {@link KeyboardManager}. + */ +public class KeyTranslatorImpl implements KeyTranslator +{ + /** + * Adds a mapping from a key press to an action command string that + * will auto-repeat at a default repeat rate. + */ + public void addPressCommand (int keyCode, String command) + { + addPressCommand(keyCode, command, DEFAULT_REPEAT_RATE); + } + + /** + * Adds a mapping from a key press to an action command string that + * will auto-repeat at the specified repeat rate. Overwrites any + * existing mapping and repeat rate that may have already been + * registered. + * + * @param rate the number of times each second that the key press + * should be repeated while the key is down, or 0 to + * disable auto-repeat for the key. + */ + public void addPressCommand (int keyCode, String command, int rate) + { + addPressCommand(keyCode, command, rate, DEFAULT_REPEAT_DELAY); + } + + /** + * Adds a mapping from a key press to an action command string that + * will auto-repeat at the specified repeat rate after the specified + * auto-repeat delay has expired. Overwrites any existing mapping for + * the specified key code that may have already been registered. + * + * @param rate the number of times each second that the key press + * should be repeated while the key is down; passing 0 + * will result in no repeating. + * @param repeatDelay the delay in milliseconds before auto-repeating + * key press events will be generated for the key. + */ + public void addPressCommand ( + int keyCode, String command, int rate, long repeatDelay) + { + KeyRecord krec = getKeyRecord(keyCode); + krec.pressCommand = command; + krec.repeatRate = rate; + krec.repeatDelay = repeatDelay; + } + + /** + * Adds a mapping from a key release to an action command string. + * Overwrites any existing mapping that may already have been + * registered. + */ + public void addReleaseCommand (int keyCode, String command) + { + KeyRecord krec = getKeyRecord(keyCode); + krec.releaseCommand = command; + } + + /** + * Returns the key record for the specified key, creating it and + * inserting it in the key table if necessary. + */ + protected KeyRecord getKeyRecord (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + if (krec == null) { + krec = new KeyRecord(); + _keys.put(keyCode, krec); + } + return krec; + } + + // documentation inherited + public boolean hasCommand (int keyCode) + { + return (_keys.get(keyCode) != null); + } + + // documentation inherited + public String getPressCommand (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? null : krec.pressCommand; + } + + // documentation inherited + public String getReleaseCommand (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? null : krec.releaseCommand; + } + + // documentation inherited + public int getRepeatRate (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? DEFAULT_REPEAT_RATE : krec.repeatRate; + } + + // documentation inherited + public long getRepeatDelay (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? DEFAULT_REPEAT_DELAY : krec.repeatDelay; + } + + // documentation inherited + public Iterator enumeratePressCommands () + { + ArrayList commands = new ArrayList(); + Iterator iter = _keys.values().iterator(); + while (iter.hasNext()) { + KeyRecord krec = (KeyRecord)iter.next(); + commands.add(krec.pressCommand); + } + return commands.iterator(); + } + + // documentation inherited + public Iterator enumerateReleaseCommands () + { + ArrayList commands = new ArrayList(); + Iterator iter = _keys.values().iterator(); + while (iter.hasNext()) { + KeyRecord krec = (KeyRecord)iter.next(); + commands.add(krec.releaseCommand); + } + return commands.iterator(); + } + + protected static class KeyRecord + { + /** The command to be posted when the key is pressed. */ + public String pressCommand; + + /** The command to be posted when the key is released. */ + public String releaseCommand; + + /** The rate in presses per second at which the key is to be + * auto-repeated. */ + public int repeatRate; + + /** The delay in milliseconds that must expire with the key still + * pressed before auto-repeated key presses will begin. */ + public long repeatDelay; + } + + /** The keys for which commands are registered. */ + protected HashIntMap _keys = new HashIntMap(); + + /** The default key press repeat rate. */ + protected static final int DEFAULT_REPEAT_RATE = 5; + + /** The default delay in milliseconds before auto-repeated key presses + * will begin. */ + protected static final long DEFAULT_REPEAT_DELAY = 500L; +} diff --git a/src/java/com/threerings/util/KeyboardManager.java b/src/java/com/threerings/util/KeyboardManager.java new file mode 100644 index 00000000..feb4995a --- /dev/null +++ b/src/java/com/threerings/util/KeyboardManager.java @@ -0,0 +1,720 @@ +// +// $Id: KeyboardManager.java 4145 2006-05-24 01:24:24Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; +import java.awt.Window; + +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; + +import java.util.Iterator; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; + +import com.samskivert.swing.Controller; +import com.samskivert.util.HashIntMap; +import com.samskivert.util.Interval; +import com.samskivert.util.ObserverList; +import com.samskivert.util.RunAnywhere; + +import com.threerings.util.keybd.Keyboard; + +/** + * The keyboard manager observes keyboard actions on a particular + * component and posts commands associated with the key presses to the + * {@link Controller} hierarchy. It allows specifying the key repeat + * rate, and will begin repeating a key immediately after it is held down + * rather than depending on the system-specific key repeat delay/rate. + */ +public class KeyboardManager + implements KeyEventDispatcher, AncestorListener, WindowFocusListener +{ + /** + * An interface to be implemented by those that care to be notified + * whenever an event (either a key press or a key release) occurs for + * any key while the keyboard manager is active. We use this custom + * interface rather than the more standard {@link + * java.awt.event.KeyListener} interface so that we needn't create key + * pressed and released event objects each time a (potentially + * artificially-generated) event occurs. + */ + public interface KeyObserver + { + /** + * Called whenever a key event occurs for a particular key. + */ + public void handleKeyEvent (int id, int keyCode, long timestamp); + } + + /** + * Constructs a keyboard manager that is initially disabled. The + * keyboard manager should not be enabled until it has been supplied + * with a target component and translator via {@link #setTarget}. + */ + public KeyboardManager () + { + // capture low-level keyboard events via the keyboard focus manager + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addKeyEventDispatcher(this); + } + + /** + * Resets the keyboard manager, clearing any target and key translator + * in use and disabling the keyboard manager if it is currently + * active. + */ + public void reset () + { + setEnabled(false); + _target = null; + _xlate = null; + _focus = false; + } + + /** + * Initializes the keyboard manager with the supplied target component + * and key translator and disables the keyboard manager if it is + * currently active. + * + * @param target the component whose keyboard events are to be observed. + * @param xlate the key translator used to map keyboard events to + * controller action commands. + */ + public void setTarget (JComponent target, KeyTranslator xlate) + { + setEnabled(false); + + // save off references + _target = target; + _xlate = xlate; + } + + /** + * Registers a key observer that will be notified of all key events + * while the keyboard manager is active. + */ + public void registerKeyObserver (KeyObserver obs) + { + _observers.add(obs); + } + + /** + * Removes the supplied key observer from the list of observers to be + * notified of all key events while the keyboard manager is active. + */ + public void removeKeyObserver (KeyObserver obs) + { + _observers.remove(obs); + } + + /** + * Sets whether the keyboard manager processes keyboard input. + */ + public void setEnabled (boolean enabled) + { + // report incorrect usage + if (enabled && _target == null) { + Log.warning("Attempt to enable uninitialized keyboard manager!"); + Thread.dumpStack(); + return; + } + + // ignore NOOPs + if (enabled == _enabled) { + return; + } + + if (!enabled) { + if (Keyboard.isAvailable()) { + // restore the original key auto-repeat settings + Keyboard.setKeyRepeat(_nativeRepeat); + } + + // clear out all of our key states + releaseAllKeys(); + _keys.clear(); + + // cease listening to all of our business + if (_window != null) { + _window.removeWindowFocusListener(this); + _window = null; + } + _target.removeAncestorListener(this); + + // note that we no longer have the focus + _focus = false; + + } else { + // listen to ancestor events so that we can cease our business + // if we lose the focus + _target.addAncestorListener(this); + + // if we're already showing, listen to window focus events, + // else we have to wait until the target is added since it + // doesn't currently have a window + if (_target.isShowing() && _window == null) { + _window = SwingUtilities.getWindowAncestor(_target); + if (_window != null) { + _window.addWindowFocusListener(this); + } + } + + // assume the keyboard focus since we were just enabled + _focus = true; + + if (Keyboard.isAvailable()) { + // note whether key auto-repeating was enabled + _nativeRepeat = Keyboard.isKeyRepeatEnabled(); + + // disable native key auto-repeating so that we can + // definitively ascertain key pressed/released events + Keyboard.setKeyRepeat(false); + } + } + + // save off our new enabled state + _enabled = enabled; + } + + /** + * Sets the expected delay in milliseconds between each key + * press/release event the keyboard manager should expect to receive + * while a key is repeating. + */ + public void setRepeatDelay (long delay) + { + _repeatDelay = delay; + } + + /** + * Releases all keys and ceases any hot repeating action that may be + * going on. + */ + public void releaseAllKeys () + { + long now = System.currentTimeMillis(); + Iterator iter = _keys.elements(); + while (iter.hasNext()) { + ((KeyInfo)iter.next()).release(now); + } + } + + /** + * Called when the keyboard manager gains focus and should begin + * handling keys again if it was previously enabled. + */ + protected void gainedFocus () + { + if (Keyboard.isAvailable()) { + // disable key auto-repeating + Keyboard.setKeyRepeat(false); + } + + // note that we've regained the focus + _focus = true; + } + + /** + * Called when the keyboard manager loses focus and should cease + * handling keys. + */ + protected void lostFocus () + { + if (Keyboard.isAvailable()) { + // restore key auto-repeating + Keyboard.setKeyRepeat(_nativeRepeat); + } + + // clear out all of our keyboard state + releaseAllKeys(); + // note that we no longer have the focus + _focus = false; + } + + // documentation inherited from interface KeyEventDispatcher + public boolean dispatchKeyEvent (KeyEvent e) + { + // bail if we're not enabled, we haven't the focus, or we're not + // showing on-screen + if (!_enabled || !_focus || !_target.isShowing()) { +// Log.info("dispatchKeyEvent [enabled=" + _enabled + +// ", focus=" + _focus + +// ", showing=" + ((_target == null) ? "N/A" : +// "" + _target.isShowing()) + "]."); + return false; + } + + // handle key press and release events + switch (e.getID()) { + case KeyEvent.KEY_PRESSED: + return keyPressed(e); + + case KeyEvent.KEY_RELEASED: + return keyReleased(e); + + default: + return false; + } + } + + /** + * Called when Swing notifies us that a key has been pressed while the + * keyboard manager is active. + * + * @return true to swallow the key event + */ + protected boolean keyPressed (KeyEvent e) + { + logKey("keyPressed", e); + + // get the action command associated with this key + int keyCode = e.getKeyCode(); + boolean hasCommand = _xlate.hasCommand(keyCode); + if (hasCommand) { + // get the info object for this key, creating one if necessary + KeyInfo info = (KeyInfo)_keys.get(keyCode); + if (info == null) { + info = new KeyInfo(keyCode); + _keys.put(keyCode, info); + } + + // remember the last time this key was pressed + info.setPressTime(RunAnywhere.getWhen(e)); + } + + // notify any key observers of the key press + notifyObservers(KeyEvent.KEY_PRESSED, e.getKeyCode(), + RunAnywhere.getWhen(e)); + + return hasCommand; + } + + /** + * Called when Swing notifies us that a key has been released while + * the keyboard manager is active. + * + * @return true to swallow the key event + */ + protected boolean keyReleased (KeyEvent e) + { + logKey("keyReleased", e); + + // get the info object for this key + KeyInfo info = (KeyInfo)_keys.get(e.getKeyCode()); + if (info != null) { + // remember the last time we received a key release + info.setReleaseTime(RunAnywhere.getWhen(e)); + } + + // notify any key observers of the key release + notifyObservers(KeyEvent.KEY_RELEASED, e.getKeyCode(), + RunAnywhere.getWhen(e)); + + return (info != null); + } + + /** + * Notifies all registered key observers of the supplied key event. + * This method provides a thread-safe manner in which to notify the + * observers, which is necessary since the {@link KeyInfo} objects do + * various antics from the interval manager thread whilst we may do + * other notification from the AWT thread when normal key events are + * handled. + */ + protected synchronized void notifyObservers ( + int id, int keyCode, long timestamp) + { + _keyOp.init(id, keyCode, timestamp); + _observers.apply(_keyOp); + } + + /** + * Logs the given message and key. + */ + protected void logKey (String msg, KeyEvent e) + { + if (DEBUG_EVENTS) { + int keyCode = e.getKeyCode(); + Log.info(msg + " [key=" + KeyEvent.getKeyText(keyCode) + "]."); + } + } + + // documentation inherited from interface AncestorListener + public void ancestorAdded (AncestorEvent e) + { + gainedFocus(); + + if (_window == null) { + _window = SwingUtilities.getWindowAncestor(_target); + _window.addWindowFocusListener(this); + } + } + + // documentation inherited from interface AncestorListener + public void ancestorMoved (AncestorEvent e) + { + // nothing for now + } + + // documentation inherited from interface AncestorListener + public void ancestorRemoved (AncestorEvent e) + { + lostFocus(); + + if (_window != null) { + _window.removeWindowFocusListener(this); + _window = null; + } + } + + // documentation inherited from interface WindowFocusListener + public void windowGainedFocus (WindowEvent e) + { + gainedFocus(); + } + + // documentation inherited from interface WindowFocusListener + public void windowLostFocus (WindowEvent e) + { + lostFocus(); + } + + protected class KeyInfo extends Interval + { + /** + * Constructs a key info object for the given key code. + */ + public KeyInfo (int keyCode) + { + _keyCode = keyCode; + _keyText = KeyEvent.getKeyText(_keyCode); + _pressCommand = _xlate.getPressCommand(_keyCode); + _releaseCommand = _xlate.getReleaseCommand(_keyCode); + int rate = _xlate.getRepeatRate(_keyCode); + _pressDelay = (rate == 0) ? 0 : (1000L / rate); + _repeatDelay = _xlate.getRepeatDelay(_keyCode); + } + + /** + * Sets the last time the key was pressed. + */ + public synchronized void setPressTime (long time) + { + if (_lastPress == 0 && _pressCommand != null) { + // post the initial key press command + postPress(time); + } + + if (!_scheduled && _pressDelay > 0) { + // register an interval to post the key press command + // until the key is decidedly released + if (_repeatDelay > 0) { + schedule(_repeatDelay, _pressDelay); + + } else { + schedule(_pressDelay, true); + } + _scheduled = true; + + if (DEBUG_EVENTS) { + Log.info("Pressing key [key=" + _keyText + "]."); + } + } + + _lastPress = time; + _lastRelease = time; + } + + /** + * Sets the last time the key was released. + */ + public synchronized void setReleaseTime (long time) + { + release(time); + _lastRelease = time; + + // handle key release events received so quickly after the key + // press event that the press/release times are exactly equal + // and, in intervalExpired(), we would therefore be unable to + // distinguish between the key being initially pressed and the + // actual true key release that's taken place. + + // the only case I can think of that might result in this + // happening is if the event manager class queues up a key + // press and release event succession while other code is + // executing, and when it comes time for it to dispatch the + // events in its queue it manages to dispatch both of them to + // us really-lickety-split. one would still think at least a + // few milliseconds should pass between the press and release, + // but in any case, we arguably ought to be watching for and + // handling this case for posterity even though it would seem + // unlikely or impossible, and so, now we do, which is a good + // thing since it appears this does in fact happen, and not so + // infrequently. + if (_lastPress == _lastRelease) { + if (DEBUG_EVENTS) { + Log.warning("Insta-releasing key due to equal key " + + "press/release times [key=" + _keyText + "]."); + } + release(time); + } + } + + /** + * Releases the key if pressed and cancels any active key repeat + * interval. + */ + public synchronized void release (long timestamp) + { + // bail if we're not currently pressed + if (_lastPress == 0) { + return; + } + + if (DEBUG_EVENTS) { + Log.info("Releasing key [key=" + _keyText + "]."); + } + + // remove the repeat interval + if (_scheduled) { + cancel(); + _scheduled = false; + } + + if (_releaseCommand != null) { + // post the key release command + postRelease(timestamp); + } + + // clear out the last press and release timestamps + _lastPress = _lastRelease = 0; + } + + // documentation inherited + public synchronized void expired () + { + long now = System.currentTimeMillis(); + long deltaPress = now - _lastPress; + long deltaRelease = now - _lastRelease; + + if (KeyboardManager.DEBUG_INTERVAL) { + Log.info("Interval [key=" + _keyText + + ", deltaPress=" + deltaPress + + ", deltaRelease=" + deltaRelease + "]."); + } + + // handle a normal interval where we either (a) create a + // sub-interval if we can't yet determine definitively + // whether the key is still down, (b) cease repeating if + // we're certain the key is now up, or (c) repeat the key + // command if we're certain the key is still down + if (_lastRelease != _lastPress) { +// if (deltaRelease < _repeatDelay) { +// // register a one-shot sub-interval to +// // definitively check whether the key was released +// long delay = _repeatDelay - deltaRelease; +// _siid = IntervalManager.register( +// this, delay, Long.valueOf(_lastPress), false); +// if (KeyboardManager.DEBUG_INTERVAL) { +// Log.info("Registered sub-interval " + +// "[id=" + _siid + "]."); +// } + +// } else { + // we know the key was released, so cease repeating + release(now); +// } + + } else if (_lastPress != 0 && _pressCommand != null) { + // post the key press command again + postPress(now); + } + } + +/* + * Old stuff- sub interval stuff was commented out prior to my + * reworking of Interval, I'll be damned if I'm going to convert this + * code that wasn't even being used. + } else if (id == _siid) { + // handle the sub-interval that checks whether the key has + // really been released since the normal interval expired + // at an inopportune time for a definitive check + + // clear out the non-recurring sub-interval identifier + _siid = -1; + + // make sure the key hasn't been pressed again since the + // sub-interval was registered + if (_lastPress != ((Long)arg).longValue()) { + if (KeyboardManager.DEBUG_INTERVAL) { + Log.warning("Key pressed since sub-interval was " + + "registered, aborting release check " + + "[key=" + _keyText + "]."); + } + return; + } + + // provide the last word on whether the key was released + if ((_lastRelease != _lastPress) && + deltaRelease >= _repeatDelay) { + release(now); + + } else if (_pressCommand != null) { + // post the key command again + postPress(now); + } + } + } + **/ + + /** + * Posts the press command for this key and notifies all key + * observers of the key press. + */ + protected void postPress (long timestamp) + { + notifyObservers(KeyEvent.KEY_PRESSED, _keyCode, timestamp); + Controller.postAction(_target, _pressCommand); + } + + /** + * Posts the release command for this key and notifies all key + * observers of the key release. + */ + protected void postRelease (long timestamp) + { + notifyObservers(KeyEvent.KEY_RELEASED, _keyCode, timestamp); + Controller.postAction(_target, _releaseCommand); + } + + /** Returns a string representation of the key info object. */ + public String toString () + { + return "[key=" + _keyText + "]"; + } + + /** True if we are a scheduled interval. */ + protected boolean _scheduled = false; + + /** The last time a key released event was received for this key. */ + protected long _lastRelease; + + /** The last time a key pressed event was received for this key. */ + protected long _lastPress; + + /** The press action command associated with this key. */ + protected String _pressCommand; + + /** The release action command associated with this key. */ + protected String _releaseCommand; + + /** A text representation of this key. */ + protected String _keyText; + + /** The key code associated with this key info object. */ + protected int _keyCode; + + /** The milliseconds to sleep between sending repeat key commands. */ + protected long _pressDelay; + + /** The delay in milliseconds before auto-repeating the key press. */ + protected long _repeatDelay; + } + + /** An observer operation to notify observers of a key event. */ + protected static class KeyObserverOp implements ObserverList.ObserverOp + { + /** Initialized the operation with its parameters. */ + public void init (int id, int keyCode, long timestamp) + { + _id = id; + _keyCode = keyCode; + _timestamp = timestamp; + } + + // documentation inherited from interface ObserverList.ObserverOp + public boolean apply (Object observer) + { + ((KeyObserver)observer).handleKeyEvent(_id, _keyCode, _timestamp); + return true; + } + + /** The key event id. */ + protected int _id; + + /** The key code. */ + protected int _keyCode; + + /** The key event timestamp. */ + protected long _timestamp; + } + + /** Whether to output debugging info for individual key events. */ + protected static final boolean DEBUG_EVENTS = false; + + /** Whether to output debugging info for interval callbacks. */ + protected static final boolean DEBUG_INTERVAL = false; + + /** The default repeat delay. */ + protected static final long DEFAULT_REPEAT_DELAY = 50L; + + /** The expected approximate milliseconds between each key + * release/press event while the key is being auto-repeated. */ + protected long _repeatDelay = DEFAULT_REPEAT_DELAY; + + /** A hashtable mapping key codes to {@link KeyInfo} objects. */ + protected HashIntMap _keys = new HashIntMap(); + + /** Whether the keyboard manager currently has the keyboard focus. */ + protected boolean _focus; + + /** Whether the keyboard manager is accepting keyboard input. */ + protected boolean _enabled; + + /** The window containing our target component whose focus events we + * care to observe, or null if we're not observing a window. */ + protected Window _window; + + /** The component that receives keyboard events and that we associate + * with posted controller commands. */ + protected JComponent _target; + + /** The translator that maps keyboard events to controller commands. */ + protected KeyTranslator _xlate; + + /** The list of key observers. */ + protected ObserverList _observers = + new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); + + /** The operation used to notify observers of actual key events. */ + protected KeyObserverOp _keyOp = new KeyObserverOp(); + + /** Whether native key auto-repeating was enabled when the keyboard + * manager was last enabled. */ + protected boolean _nativeRepeat; +} diff --git a/src/java/com/threerings/util/Log.java b/src/java/com/threerings/util/Log.java new file mode 100644 index 00000000..9a376628 --- /dev/null +++ b/src/java/com/threerings/util/Log.java @@ -0,0 +1,56 @@ +// +// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +/** + * A placeholder class that contains a reference to the log object used by + * the media services package. + */ +public class Log +{ + public static com.samskivert.util.Log log = + new com.samskivert.util.Log("util"); + + /** Convenience function. */ + public static void debug (String message) + { + log.debug(message); + } + + /** Convenience function. */ + public static void info (String message) + { + log.info(message); + } + + /** Convenience function. */ + public static void warning (String message) + { + log.warning(message); + } + + /** Convenience function. */ + public static void logStackTrace (Throwable t) + { + log.logStackTrace(com.samskivert.util.Log.WARNING, t); + } +} diff --git a/src/java/com/threerings/util/keybd/Keyboard.java b/src/java/com/threerings/util/keybd/Keyboard.java new file mode 100644 index 00000000..509d140a --- /dev/null +++ b/src/java/com/threerings/util/keybd/Keyboard.java @@ -0,0 +1,83 @@ +// +// $Id: Keyboard.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util.keybd; + +import com.threerings.util.Log; + +/** + * Provides access to the native operating system's auto-repeat keyboard + * settings. + */ +public class Keyboard +{ + /** + * Sets whether key auto-repeating is enabled. + */ + public static native void setKeyRepeat (boolean enabled); + + /** + * Returns whether key auto-repeating is enabled. + */ + public static native boolean isKeyRepeatEnabled (); + + /** + * Tests keyboard functionality. + */ + public static void main (String[] args) + { + boolean enabled = (args.length > 0 && args[0].equals("on")); + Keyboard.setKeyRepeat(enabled); + } + + /** + * Returns whether the native keyboard interface is available. + */ + public static boolean isAvailable () + { + return _haveLib; + } + + /** + * Initializes the library and returns true if it successfully did so. + */ + protected static native boolean init (); + + /** Whether the keyboard native library was successfully loaded. */ + protected static boolean _haveLib; + + static { + try { + System.loadLibrary("keybd"); + _haveLib = init(); + if (_haveLib) { + Log.info("Loaded native keyboard library."); + } else { + Log.info("Native keyboard library initialization failed."); + } + + } catch (UnsatisfiedLinkError e) { + Log.warning("Failed to load native keyboard library " + + "[e=" + e + "]."); + _haveLib = false; + } + } +} diff --git a/src/java/com/threerings/util/keybd/Linux/Makefile b/src/java/com/threerings/util/keybd/Linux/Makefile new file mode 100644 index 00000000..e71ee11b --- /dev/null +++ b/src/java/com/threerings/util/keybd/Linux/Makefile @@ -0,0 +1,44 @@ +# +# $Id: Makefile 3330 2005-02-03 01:24:57Z mdb $ + +# +# Executable definitions + +CC=gcc +RM=rm +CP=cp +MKDIR=mkdir + +# +# Directory definitions + +ROOT=../../../../../../.. +LIBRARIES_PATH=-L/usr/X11R6/lib +INSTALL_PATH=${ROOT}/dist/lib/i686-Linux + +# +# Parameter and file definitions + +INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux +LIBRARIES=-lX11 +TARGET=libkeybd.so + +# +# Target definitions + +all: ${TARGET} + +install: ${TARGET} + @${MKDIR} -p ${INSTALL_PATH} + cp ${TARGET} ${INSTALL_PATH} + +${TARGET}: com_threerings_util_keybd_Keyboard.c + @echo Compiling Keyboard.c + @${CC} ${INCLUDES} -c com_threerings_util_keybd_Keyboard.c \ + -o com_threerings_util_keybd_Keyboard.o + @echo Creating libkeybd.so + @${CC} -o ${TARGET} com_threerings_util_keybd_Keyboard.o \ + ${LIBRARIES} ${LIBRARIES_PATH} -shared + +clean: + -${RM} -f *.o ${TARGET} diff --git a/src/java/com/threerings/util/keybd/Linux/com_threerings_util_keybd_Keyboard.c b/src/java/com/threerings/util/keybd/Linux/com_threerings_util_keybd_Keyboard.c new file mode 100644 index 00000000..1def0e6f --- /dev/null +++ b/src/java/com/threerings/util/keybd/Linux/com_threerings_util_keybd_Keyboard.c @@ -0,0 +1,87 @@ +/* + * $Id: com_threerings_util_keybd_Keyboard.c 3330 2005-02-03 01:24:57Z mdb $ + */ + +#include +#include +#include +#include "com_threerings_util_keybd_Keyboard.h" + +/* defines */ +#define MESSAGE_LENGTH (256) + +/* prototype definitions */ +Display* getXDisplay (JNIEnv* env); + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_keybd_Keyboard_init ( + JNIEnv* env, jclass class, jboolean enabled) +{ + Display* display = getXDisplay(env); + if (display == NULL) { + /* If we are unable to open a display, we can't function. */ + return JNI_FALSE; + } else { + XCloseDisplay(display); + return JNI_TRUE; + } +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_keybd_Keyboard_setKeyRepeat ( + JNIEnv* env, jclass class, jboolean enabled) +{ + Display* display = getXDisplay(env); + if (display == NULL) { + return; + } + + /* set the desired key auto-repeat state. */ + if (enabled) { + XAutoRepeatOn(display); + } else { + XAutoRepeatOff(display); + } + + /* close the display to save our changes */ + XCloseDisplay(display); +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_keybd_Keyboard_isKeyRepeatEnabled ( + JNIEnv* env, jclass class) +{ + XKeyboardState values; + Display* display = getXDisplay(env); + if (display == NULL) { + /* for now, assume auto-repeat is enabled */ + return JNI_TRUE; + } + + /* get the current keyboard control information */ + XGetKeyboardControl(display, &values); + + /* close the display */ + XCloseDisplay(display); + + return (values.global_auto_repeat) ? JNI_TRUE : JNI_FALSE; +} + +/* + * Returns a pointer to the X display, or null if an error occurred. + */ +Display* +getXDisplay (JNIEnv* env) +{ + char* disp = NULL; + Display* dpy = XOpenDisplay(disp); + if (dpy == NULL) { + char message[MESSAGE_LENGTH]; + snprintf(message, MESSAGE_LENGTH, + "Unable to open display [display=%s].\n", XDisplayName(disp)); + return NULL; + } + + /* printf("Opened display [disp=%s].\n", XDisplayName(disp)); */ + return dpy; +} diff --git a/src/java/com/threerings/util/keybd/Linux/libkeybd.so b/src/java/com/threerings/util/keybd/Linux/libkeybd.so new file mode 100755 index 0000000000000000000000000000000000000000..e43ea176c1cfdd3d02e0977ba0fe38208b2389a5 GIT binary patch literal 8129 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 +#include +#include +#include "com_threerings_util_keybd_Keyboard.h" + +/* prototype definitions */ +LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK LowLevelKeyboardProc (int nCode, WPARAM wParam, LPARAM lParam); + +/* static global variables */ +static HHOOK gKeyHook; +static HINSTANCE gHInst; + +BOOL WINAPI +DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) +{ + /* save off our instance handle */ + fprintf(stderr, "In DllMain.\n"); + gHInst = (HINSTANCE)hinstDLL; +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_keybd_Keyboard_setKeyRepeat ( + JNIEnv* env, jclass class, jboolean enabled) +{ + if (enabled) { + if (gKeyHook != NULL) { + fprintf(stderr, "Removing windows keyboard hook.\n"); + /* remove the keyboard hook */ + UnhookWindowsHookEx(gKeyHook); + gKeyHook = NULL; + } + + } else { + /* install the hook with which we usurp all keyboard events */ +/* gKeyHook = SetWindowsHookEx( */ +/* WH_KEYBOARD_LL, LowLevelKeyboardProc, hinstExe, 0); */ + + fprintf(stderr, "Setting windows keyboard hook.\n"); + gKeyHook = SetWindowsHookEx( + WH_KEYBOARD, KeyboardProc, gHInst, 0); + } +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_keybd_Keyboard_isKeyRepeatEnabled ( + JNIEnv* env, jclass class) +{ + /* since windows has no global key repeat enable/disable facility, we + * simply always return true here so that we'll be sure to "re-enable" + * key repeat, which will result in our properly removing the keyboard + * hook with which we trap key events. */ + fprintf(stderr, "isKeyRepeatEnabled stderr.\n"); + printf("isKeyRepeatEnabled stdout.\n"); + return JNI_TRUE; +} + +/* + * The keyboard event hook that eats all repeated keystrokes. + */ +LRESULT CALLBACK +KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam) +{ + int repeatCount = (lParam & KF_REPEAT); + fprintf(stderr, "Key down [key=%d, repeatCount=%d].\n", + wParam, repeatCount); + return (repeatCount > 1) ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam); +} + +#if 0 + +/* + * The low-level keyboard event hook that eats all keystrokes. + */ +LRESULT CALLBACK +LowLevelKeyboardProc (int nCode, WPARAM wParam, LPARAM lParam) +{ + BOOL fEatKeystroke = FALSE; + + if (nCode == HC_ACTION) { + switch (wParam) { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; + fEatKeystroke = + ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) || + ((p->vkCode == VK_ESCAPE) && + ((p->flags & LLKHF_ALTDOWN) != 0)) || + ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & + 0x8000) != 0)); + break; + } + } + + return (fEatKeystroke) ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam); +} + +#endif diff --git a/src/java/com/threerings/util/keybd/com_threerings_util_keybd_Keyboard.h b/src/java/com/threerings/util/keybd/com_threerings_util_keybd_Keyboard.h new file mode 100644 index 00000000..04f524d0 --- /dev/null +++ b/src/java/com/threerings/util/keybd/com_threerings_util_keybd_Keyboard.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_threerings_util_keybd_Keyboard */ + +#ifndef _Included_com_threerings_util_keybd_Keyboard +#define _Included_com_threerings_util_keybd_Keyboard +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_threerings_util_keybd_Keyboard + * Method: setKeyRepeat + * Signature: (Z)V + */ +JNIEXPORT void JNICALL Java_com_threerings_util_keybd_Keyboard_setKeyRepeat + (JNIEnv *, jclass, jboolean); + +/* + * Class: com_threerings_util_keybd_Keyboard + * Method: isKeyRepeatEnabled + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_threerings_util_keybd_Keyboard_isKeyRepeatEnabled + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/java/com/threerings/util/unsafe/FreeBSD/Makefile b/src/java/com/threerings/util/unsafe/FreeBSD/Makefile new file mode 100644 index 00000000..39a78063 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/FreeBSD/Makefile @@ -0,0 +1,45 @@ +# +# $Id: Makefile 3332 2005-02-03 01:30:33Z mdb $ + +# +# Executable definitions + +CC=gcc +RM=rm +CP=cp +MKDIR=mkdir + +# +# Directory definitions + +ROOT=../../../../../../.. +LIBRARIES_PATH= +OSINCDIR!=uname -s | tr 'A-Z' 'a-z' +INSTALL_PATH=${ROOT}/dist/lib/i386-FreeBSD + +# +# Parameter and file definitions + +INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/${OSINCDIR} +LIBRARIES= +TARGET=libunsafe.so + +# +# Target definitions + +all: ${TARGET} + +install: ${TARGET} + @${MKDIR} -p ${INSTALL_PATH} + cp ${TARGET} ${INSTALL_PATH} + +${TARGET}: com_threerings_util_unsafe_Unsafe.c + @echo "Compiling Unsafe.c" + @${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \ + -o com_threerings_util_unsafe_Unsafe.o + @echo "Creating libunsafe.so" + @${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \ + ${LIBRARIES} ${LIBRARIES_PATH} -shared + +clean: + -${RM} -f *.o ${TARGET} diff --git a/src/java/com/threerings/util/unsafe/FreeBSD/com_threerings_util_unsafe_Unsafe.c b/src/java/com/threerings/util/unsafe/FreeBSD/com_threerings_util_unsafe_Unsafe.c new file mode 100644 index 00000000..04ac0526 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/FreeBSD/com_threerings_util_unsafe_Unsafe.c @@ -0,0 +1,97 @@ +/* + * $Id: com_threerings_util_unsafe_Unsafe.c 3653 2005-07-21 19:10:08Z mdb $ + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "com_threerings_util_unsafe_Unsafe.h" + +/* global jvmpi interface pointer */ +static JVMPI_Interface* jvmpi; + +/** A sleep method that uses select(). This seems to have about 10ms + * granularity where nanosleep() has about 20ms. Sigh. */ +static int select_sleep (int millisecs) +{ + fd_set dummy; + struct timeval toWait; + FD_ZERO(&dummy); + toWait.tv_sec = millisecs / 1000; + toWait.tv_usec = (millisecs % 1000) * 1000; + return select(0, &dummy, NULL, NULL, &toWait); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz) +{ + jvmpi->EnableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz) +{ + jvmpi->DisableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSleep ( + JNIEnv* env, jclass clazz, jint millis) +{ +/* struct timespec tmspec; */ +/* tmspec.tv_sec = millis/1000; */ +/* tmspec.tv_nsec = (millis%1000)*1000000; */ +/* if (nanosleep(&tmspec, NULL) < 0) { */ +/* fprintf(stderr, "nanosleep() failed: %s\n", strerror(errno)); */ +/* } */ + if (select_sleep(millis) < 0) { + fprintf(stderr, "select_sleep() failed: %s\n", strerror(errno)); + } +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSetuid ( + JNIEnv* env, jclass clazz, jint uid) +{ + if (setuid((uid_t)uid) != 0) { + fprintf(stderr, "setuid(%d) failed: %s\n", uid, strerror(errno)); + return JNI_FALSE; + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSetgid ( + JNIEnv* env, jclass clazz, jint gid) +{ + if (setgid((gid_t)gid) != 0) { + fprintf(stderr, "setgid(%d) failed: %s\n", gid, strerror(errno)); + return JNI_FALSE; + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz) +{ + JavaVM* jvm; + + if ((*env)->GetJavaVM(env, &jvm) > 0) { + fprintf(stderr, "Failed to get JavaVM from env.\n"); + return JNI_FALSE; + } + + /* get jvmpi interface pointer */ + if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) { + fprintf(stderr, "Failed to get JVMPI from JavaVM.\n"); + return JNI_FALSE; + } + + return JNI_TRUE; +} diff --git a/src/java/com/threerings/util/unsafe/FreeBSD/libunsafe.so b/src/java/com/threerings/util/unsafe/FreeBSD/libunsafe.so new file mode 100755 index 0000000000000000000000000000000000000000..2a6a9e53686bc79615cf738bf7bd508f7d432f8d GIT binary patch literal 6809 zcmeHLeQZ=&6~EJ|(Cy-G>6V2>cX`W#wtUQ#Qr6NC0<_awY@t#hD&pJe%$v?M^ObpT zYHQ+tINNA5R-3pc{9()*NMz$`h`WCf>jzjO+toj6)Ua7M+88wLLIlkQ8&VyAzx&>u zz8wkwF&O7JabMCoc=iQIK$`QZmbf5_yI~aLh5fqzWHGr-$QX7oUU;66`+gIFG5c|3zSP$F?ME4|o6yL`k{(nu@ zEYm>UGG(PjPnH(kMSjUCw^v$-S*#7gE4VU3yv#)aFct_Ca^Wc3ic>3PF=V;o;(SrI z4KEdCn_(;wyuxOF{GgKUu)9>0tEGZ*L+}b)u~3u|Gyuj7!7Dx}=^1BXyuuFFSBvt) zQvZ5UMsNbo7vO(y~N)xm%RqQwnTrXMBW9t-PPV7Agl4#puf+; z$Bb)ye}udMxr@HhKMho^SFLzJd=K>(;qU8?{z{2IuArJ<&d0mZSMrAhu)UDY%CClR z40;6|e~%JCHS&71q>tXZPU)`@8kS9UXmvqx#YP2f72g&?B*AOz3)OI7l`a zkA1;_7&bD-K+Lp^j2_7Z6NVm3Mp7tWw)EhTe#EhEiw8~9FokKvjgTb{28V)rD3#Ey zXvQ!yvE+cMXRTOV&nC@a#L$n~#7GAF<3?v&x%T0hd4Cm>K`S<7^u-M$jX@ZhOe!Nx zD`PXdZdw>`CM_aqbkT~G+YQI7VP#`sj98K~M_jBrU{@t6vntlh61ou%T0xAZ-!#$v zV1`A>un<=ed)y_iIdnS$it>mgrt-)aTs#w z&m6jm6dP{Bq0Ue}WR&duYyohZe^!+0`57tmG>Nis{(_Ww;zjwHKL`2P*q{4y*DL2BixV$Qox=1y zKPeC7te%_1poFki=dQ0Ryw(Eixp91Qmum94Jz(-;^n$f^>{d=nm4%t5;_S8Dq$VrZ zqVjldAIy8_bi4L1a%{kpKe;$PRnq=Cw4a--mo*>DU9TF?HG=O|4))p(a+8Z-g!M#j za+5S&BO761?_9NQGd?6_0}~SyXyb+Jr(iffIt=C5XdK_mqfvY{l;(ayPFRoUrDFV> z6bsdPNiSDUu!U=H=Xbslv?k)YvVIb*b#A zyNrvNt(m*=FS&xF7e@S8ci3|EZI_jWMu%I~8?8fJ732xzl+{d6VNPxTjxW1f4Wgh0 zCCfRg=|!7S{~f+A2NvbDt^~tVAs?_~LH0-Xvs~XD_vgDRAE?ULj0YCcv8w!+;`pfw zGl=NX3(syqV+MuiJXU!Sk;9`bAPSO?JZ<)o%kHgC+7MvAyYzZ>cHW2ps&4E zGczH7Jl5|InOT2qXUo&ujd;W#%2+X9-?kxbhwo{vsj;!i-?+=aW0%(0+`40TYx8a` z)t`wONi8s(*5t2aAAY*YXv2dRN4G4a9b=2gm{OqF9Voz+Mfzh5 z5g9}7cDcl@E<45?QFH2nmF?254M^XNWxgwj?5_g$kFXc0?D&2o_DYTYp&hXcsO!bLsoYDw}|Y60%dm$1+?S%_zom)Wq||A?j&RuvniQZz|YI^DNuGH6exdu zH!i?V>1eC?1bFs`{`fC3A92=^L5lM?1YWhvcjg&v7R$B!MVB4lpReA>%n*#zuapG6^Qs(K67P|p07+BcNc z?}5C4{<9zS{~79Wo#cPS@jU}s<;6S|4~hh2cV6n-w0D62-FG3YI|B1C=SuWHa>*L( zry;xZQvY=6>8}z$JI@XR^HSBWpP%|#m#jhF;*zOvDv@_XcITxMkh$Ij=7~liyYo`7 zKz8S)-hu4SOZ^G5J1_MR_87OnHIUtTsjZORd8tOo3N$e7E}8xRgiEGg__Jole~a4}~O@0~rvEVv&WVsI#tW=1b; zrt~Q0FK(2ZSz1b~E#=0F*~4OztRz=hX4a}C;U%+!NGc+grIK!UPdYmJI>Wk;ELpKV r=H}dKvNHR7zbQ$lJv+lFZ`@@z^uBc7@+n#-_Vi_wtTN@ed{*|~ZVjB% literal 0 HcmV?d00001 diff --git a/src/java/com/threerings/util/unsafe/Linux/Makefile b/src/java/com/threerings/util/unsafe/Linux/Makefile new file mode 100644 index 00000000..c692c906 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Linux/Makefile @@ -0,0 +1,44 @@ +# +# $Id: Makefile 3331 2005-02-03 01:25:21Z mdb $ + +# +# Executable definitions + +CC=gcc +RM=rm +CP=cp +MKDIR=mkdir + +# +# Directory definitions + +ROOT=../../../../../../.. +LIBRARIES_PATH=-L/usr/X11R6/lib +INSTALL_PATH=${ROOT}/dist/lib/i686-Linux + +# +# Parameter and file definitions + +INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux +LIBRARIES=-lX11 +TARGET=libunsafe.so + +# +# Target definitions + +all: ${TARGET} + +install: ${TARGET} + @${MKDIR} -p ${INSTALL_PATH} + cp ${TARGET} ${INSTALL_PATH} + +${TARGET}: com_threerings_util_unsafe_Unsafe.c + @echo Compiling Unsafe.c + @${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \ + -o com_threerings_util_unsafe_Unsafe.o + @echo Creating ${TARGET} + @${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \ + ${LIBRARIES} ${LIBRARIES_PATH} -shared + +clean: + -${RM} -f *.o ${TARGET} diff --git a/src/java/com/threerings/util/unsafe/Linux/com_threerings_util_unsafe_Unsafe.c b/src/java/com/threerings/util/unsafe/Linux/com_threerings_util_unsafe_Unsafe.c new file mode 100644 index 00000000..04ac0526 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Linux/com_threerings_util_unsafe_Unsafe.c @@ -0,0 +1,97 @@ +/* + * $Id: com_threerings_util_unsafe_Unsafe.c 3653 2005-07-21 19:10:08Z mdb $ + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "com_threerings_util_unsafe_Unsafe.h" + +/* global jvmpi interface pointer */ +static JVMPI_Interface* jvmpi; + +/** A sleep method that uses select(). This seems to have about 10ms + * granularity where nanosleep() has about 20ms. Sigh. */ +static int select_sleep (int millisecs) +{ + fd_set dummy; + struct timeval toWait; + FD_ZERO(&dummy); + toWait.tv_sec = millisecs / 1000; + toWait.tv_usec = (millisecs % 1000) * 1000; + return select(0, &dummy, NULL, NULL, &toWait); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz) +{ + jvmpi->EnableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz) +{ + jvmpi->DisableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSleep ( + JNIEnv* env, jclass clazz, jint millis) +{ +/* struct timespec tmspec; */ +/* tmspec.tv_sec = millis/1000; */ +/* tmspec.tv_nsec = (millis%1000)*1000000; */ +/* if (nanosleep(&tmspec, NULL) < 0) { */ +/* fprintf(stderr, "nanosleep() failed: %s\n", strerror(errno)); */ +/* } */ + if (select_sleep(millis) < 0) { + fprintf(stderr, "select_sleep() failed: %s\n", strerror(errno)); + } +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSetuid ( + JNIEnv* env, jclass clazz, jint uid) +{ + if (setuid((uid_t)uid) != 0) { + fprintf(stderr, "setuid(%d) failed: %s\n", uid, strerror(errno)); + return JNI_FALSE; + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSetgid ( + JNIEnv* env, jclass clazz, jint gid) +{ + if (setgid((gid_t)gid) != 0) { + fprintf(stderr, "setgid(%d) failed: %s\n", gid, strerror(errno)); + return JNI_FALSE; + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz) +{ + JavaVM* jvm; + + if ((*env)->GetJavaVM(env, &jvm) > 0) { + fprintf(stderr, "Failed to get JavaVM from env.\n"); + return JNI_FALSE; + } + + /* get jvmpi interface pointer */ + if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) { + fprintf(stderr, "Failed to get JVMPI from JavaVM.\n"); + return JNI_FALSE; + } + + return JNI_TRUE; +} diff --git a/src/java/com/threerings/util/unsafe/Linux/libunsafe.so b/src/java/com/threerings/util/unsafe/Linux/libunsafe.so new file mode 100755 index 0000000000000000000000000000000000000000..59305842f9e3d2d14326b815e4292e7bc59064be GIT binary patch literal 8251 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 literal 0 HcmV?d00001 diff --git a/src/java/com/threerings/util/unsafe/Mac OS X/Makefile b/src/java/com/threerings/util/unsafe/Mac OS X/Makefile new file mode 100644 index 00000000..0fe6ecb0 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Mac OS X/Makefile @@ -0,0 +1,7 @@ +# +# $Id: Makefile 3331 2005-02-03 01:25:21Z mdb $ +# +# Placeholder Makefile + +install: + @echo Nothing to see here. Move it along. diff --git a/src/java/com/threerings/util/unsafe/Unsafe.java b/src/java/com/threerings/util/unsafe/Unsafe.java new file mode 100644 index 00000000..7514362d --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Unsafe.java @@ -0,0 +1,144 @@ +// +// $Id: Unsafe.java 3653 2005-07-21 19:10:08Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util.unsafe; + +import com.threerings.util.Log; +import com.samskivert.util.RunAnywhere; + +/** + * A native library for doing unsafe things. Don't use this library. If + * you must ignore that warning, then be sure you use it sparingly and + * only in very well considered cases. + */ +public class Unsafe +{ + /** + * Enables or disables garbage collection. Warning: you will + * be fucked if you leave it disabled for too long. Do not do this + * unless you are dang sure about what you're doing and are prepared + * to test your code on every platform this side of Nantucket. + * + *

Calls to this method do not nest. Regardless of how many times + * you disable GC, only one call is required to reenable it. + */ + public static void setGCEnabled (boolean enabled) + { + // we don't support nesting, NOOP if the state doesn't change + if (_loaded && enabled != _gcEnabled) { + if (_gcEnabled = enabled) { + enableGC(); + } else { + disableGC(); + } + } + } + + /** + * Causes the current thread to block for the specified number of + * milliseconds. This exists primarily to work around the fact that on + * Linux, {@link Thread#sleep} is only accurate to around 12ms which + * is wholly unacceptable. + */ + public static void sleep (int millis) + { + if (_loaded && RunAnywhere.isLinux()) { + nativeSleep(millis); + } else { + try { + Thread.sleep(millis); + } catch (InterruptedException ie) { + Log.info("Thread.sleep(" + millis + ") interrupted."); + } + } + } + + /** + * Sets the processes uid to the specified value. + * + * @return true if the uid was changed, false if we were unable to do so. + */ + public static boolean setuid (int uid) + { + if (_loaded && !RunAnywhere.isWindows()) { + return nativeSetuid(uid); + } + return false; + } + + /** + * Sets the processes uid to the specified value. + * + * @return true if the uid was changed, false if we were unable to do so. + */ + public static boolean setgid (int gid) + { + if (_loaded && !RunAnywhere.isWindows()) { + return nativeSetgid(gid); + } + return false; + } + + /** + * Reenable garbage collection after a call to {@link #disableGC}. + */ + protected static native void enableGC (); + + /** + * Disables garbage collection. + */ + protected static native void disableGC (); + + /** + * Sleeps the current thread for the specified number of milliseconds. + */ + protected static native void nativeSleep (int millis); + + /** + * Calls through to the native OS system call to change our uid. + */ + protected static native boolean nativeSetuid (int uid); + + /** + * Calls through to the native OS system call to change our gid. + */ + protected static native boolean nativeSetgid (int gid); + + /** + * Called to initialize our library. + */ + protected static native boolean init (); + + /** The current state of GC enablement. */ + protected static boolean _gcEnabled = true; + + /** Whether or not we were able to load and initialize our library. */ + protected static boolean _loaded; + + static { + try { + System.loadLibrary("unsafe"); + _loaded = init(); + } catch (UnsatisfiedLinkError e) { + Log.warning("Failed to load 'unsafe' library: " + e + "."); + } + } +} diff --git a/src/java/com/threerings/util/unsafe/Windows/.cvsignore b/src/java/com/threerings/util/unsafe/Windows/.cvsignore new file mode 100644 index 00000000..c253038a --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Windows/.cvsignore @@ -0,0 +1 @@ +*.def diff --git a/src/java/com/threerings/util/unsafe/Windows/Makefile b/src/java/com/threerings/util/unsafe/Windows/Makefile new file mode 100644 index 00000000..92c204ee --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Windows/Makefile @@ -0,0 +1,49 @@ +# +# $Id: Makefile 3331 2005-02-03 01:25:21Z mdb $ + +NAME=unsafe + +# +# Executable definitions + +CC=i586-mingw32msvc-gcc +RM=rm +CP=cp +MKDIR=mkdir +DLLWRAP=i586-mingw32msvc-dllwrap +# +# Directory definitions + +ROOT=../../../../../../.. +INSTALL_PATH=${ROOT}/dist/lib/i686-Windows + +# +# Source files + +SRCS = com_threerings_util_unsafe_Unsafe.c +OBJS = ${SRCS:.c=.o} + +# +# Parameter and file definitions + +INCLUDES= +CFLAGS=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux + +LDFLAGS=-L/usr/X11R6/lib +LIBS= +TARGET=${NAME}.dll +INSTALL_TARGET=${INSTALL_PATH}/${TARGET} + +# +# Target definitions + +all: ${INSTALL_TARGET} + +${INSTALL_TARGET}: ${OBJS} + @${MKDIR} -p ${INSTALL_PATH} + ${DLLWRAP} --output-def ${NAME}.def --add-stdcall-alias \ + -o ${INSTALL_TARGET} -s ${OBJS} + +clean: + -${RM} ${OBJS} + -${RM} ${INSTALL_TARGET} diff --git a/src/java/com/threerings/util/unsafe/Windows/com_threerings_util_unsafe_Unsafe.c b/src/java/com/threerings/util/unsafe/Windows/com_threerings_util_unsafe_Unsafe.c new file mode 100644 index 00000000..dcb2e950 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/Windows/com_threerings_util_unsafe_Unsafe.c @@ -0,0 +1,52 @@ +/* + * $Id: com_threerings_util_unsafe_Unsafe.c 3331 2005-02-03 01:25:21Z mdb $ + */ + +#include +#include +#include + +#include "com_threerings_util_unsafe_Unsafe.h" + +/* global jvmpi interface pointer */ +static JVMPI_Interface* jvmpi; + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz) +{ + fprintf(stderr, "Reenabling GC.\n"); + jvmpi->EnableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz) +{ + fprintf(stderr, "Disabling GC.\n"); + jvmpi->DisableGC(); +} + +JNIEXPORT void JNICALL +Java_com_threerings_util_unsafe_Unsafe_nativeSleep ( + JNIEnv* env, jclass clazz, jint millis) +{ + /* not supported */ +} + +JNIEXPORT jboolean JNICALL +Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz) +{ + JavaVM* jvm; + + if ((*env)->GetJavaVM(env, &jvm) > 0) { + fprintf(stderr, "Failed to get JavaVM from env.\n"); + return JNI_FALSE; + } + + /* get jvmpi interface pointer */ + if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) { + fprintf(stderr, "Failed to get JVMPI from JavaVM.\n"); + return JNI_FALSE; + } + + return JNI_TRUE; +} diff --git a/src/java/com/threerings/util/unsafe/com_threerings_util_unsafe_Unsafe.h b/src/java/com/threerings/util/unsafe/com_threerings_util_unsafe_Unsafe.h new file mode 100644 index 00000000..f439fed8 --- /dev/null +++ b/src/java/com/threerings/util/unsafe/com_threerings_util_unsafe_Unsafe.h @@ -0,0 +1,47 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_threerings_util_unsafe_Unsafe */ + +#ifndef _Included_com_threerings_util_unsafe_Unsafe +#define _Included_com_threerings_util_unsafe_Unsafe +#ifdef __cplusplus +extern "C" { +#endif +/* Inaccessible static: _gcEnabled */ +/* Inaccessible static: _loaded */ +/* + * Class: com_threerings_util_unsafe_Unsafe + * Method: enableGC + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_enableGC + (JNIEnv *, jclass); + +/* + * Class: com_threerings_util_unsafe_Unsafe + * Method: disableGC + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_disableGC + (JNIEnv *, jclass); + +/* + * Class: com_threerings_util_unsafe_Unsafe + * Method: nativeSleep + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSleep + (JNIEnv *, jclass, jint); + +/* + * Class: com_threerings_util_unsafe_Unsafe + * Method: init + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_init + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tests/bin/miso-viewer b/tests/bin/miso-viewer new file mode 100755 index 00000000..1ec88363 --- /dev/null +++ b/tests/bin/miso-viewer @@ -0,0 +1,3 @@ +#!/bin/sh + +`dirname $0`/runjava com.threerings.miso.viewer.ViewerApp $* diff --git a/tests/bin/runjava b/tests/bin/runjava new file mode 100755 index 00000000..356074ae --- /dev/null +++ b/tests/bin/runjava @@ -0,0 +1,108 @@ +#!/usr/bin/perl -w + +use Getopt::Std; + +my $usage = "Usage: $0 [-p pid_file] args\n"; + +# locations of stuff +chomp($location = `dirname $0`); + +# get the server root by popping the /bin off of our parent directory +@parts = split(/\//, $location); +pop(@parts); +my $root = join("/", @parts); + +# but we're in the test directory, so we want up one +$realroot = $root; +$root = "$root/.."; + +# make sure JAVA_HOME is set +my $jhome = $ENV{"JAVA_HOME"}; +if (!defined $jhome) { + warn "$0: Error: No JAVA_HOME specified!\n"; + warn "\n"; + warn "You must set your JAVA_HOME environment variable to the\n"; + warn "the absolute path of your JDK installation. For example:\n"; + warn "\n"; + warn " % JAVA_HOME=/usr/local/jdk1.2\n"; + warn " % export JAVA_HOME\n"; + die "\n"; +} + +# make sure it's set to a directory +if (! -d $jhome) { + die "$0: Can't find a java interpreter in '$jhome'.\n"; +} + +my $java = "$jhome/bin/java"; +my $jlib = "$jhome/lib/classes.zip"; + +# determine our machine architecture +my $ostype = `uname -s`; +my $machtype = `uname -m`; +chomp($ostype); +chomp($machtype); +my $arch = "$machtype-$ostype"; + +# add our native libraries to the runtime library path +my $libs = "$root/lib/$arch"; +my $libpath = $ENV{"LD_LIBRARY_PATH"}; + +if (defined $libpath) { + $ENV{"LD_LIBRARY_PATH"} = "$libs:$libpath"; +} else { + $ENV{"LD_LIBRARY_PATH"} = $libs; +} + +# put everything in our class path +my $classpath = "-classpath $root/tests/dist/classes:$root/dist/classes"; + +# add zip and jar files from our lib/ directory and the global Java +# libraries directory +my @dirs = ( "$root/lib" ); +foreach $dir (@dirs) { + next unless (defined $dir); + if (opendir(DIR, $dir)) { + foreach $lib (grep { /.(zip|jar)/ && -f "$dir/$_" } readdir(DIR)) { + # skip nenya-*.jar because we have the nenya build directory + # in our classpath + $classpath .= ":$dir/$lib" unless $lib =~ /nenya/; + } + closedir DIR; + } +} + +# finally add the standard classes +$classpath = "$classpath:$jlib"; + +# specify our server root (this is for server code) +my $rootarg = "-Dresource_dir=$realroot/rsrc -Dtest_dir=$realroot"; + +my $pid_file = undef; +my $i = 0; + +# strip out the -p args (we'd use getopt() but the damned thing provides +# no way of escaping arguments so that we can pass args to runjava that +# get passed down to the JVM) +for ($i = 0; $i < @ARGV; $i++) { + my $arg = $ARGV[$i]; + + # stop when we see -- (and strip it out because Java don't dig --) + if ($arg eq "--") { + splice(@ARGV, $i, 1); + last; + } + + if ($arg eq "-p") { + $pid_file = $ARGV[$i+1]; + splice(@ARGV, $i, 2); + $i -= 1; # decrement i so that things stay in sync + } +} + +# log the pid file if requested to do so +print `echo $$ > $pid_file` if (defined $pid_file); + +my $cmd = "$java -mx256M $classpath $rootarg " . join(" ", @ARGV); +# print "$cmd\n"; +exec($cmd); diff --git a/tests/build.xml b/tests/build.xml new file mode 100644 index 00000000..f346119f --- /dev/null +++ b/tests/build.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/rsrc/bundles/components/.cvsignore b/tests/rsrc/bundles/components/.cvsignore new file mode 100644 index 00000000..1a4f5c01 --- /dev/null +++ b/tests/rsrc/bundles/components/.cvsignore @@ -0,0 +1,2 @@ +*.jar +*.map diff --git a/tests/rsrc/bundles/components/actions.xml b/tests/rsrc/bundles/components/actions.xml new file mode 100644 index 00000000..4ee164b4 --- /dev/null +++ b/tests/rsrc/bundles/components/actions.xml @@ -0,0 +1,76 @@ + + + + + + + + 5 + 50,112 + SW, W, NW, N, NE, E, SE, S + + 160, 160, 160, 160, 160, 160, 160, 160 + 100, 100, 100, 100, 100, 100, 100, 100 + 1, 1, 1, 1, 1, 1, 1, 1 + 0, 0 + 0, 0 + + + + + 7.3 + 50,112 + SW, W, NW, N, NE, E, SE, S + + 160, 160, 160, 160, 160, 160, 160, 160 + 100, 100, 100, 100, 100, 100, 100, 100 + 6, 6, 6, 6, 6, 6, 6, 6 + 0, 0 + 0, 0 + + + + + 5 + 50,112 + SW, W, NW, N, NE, E, SE, S + + 160, 160, 160, 160, 160, 160, 160, 160 + 100, 100, 100, 100, 100, 100, 100, 100 + 1, 1, 1, 1, 1, 1, 1, 1 + 0, 0 + 0, 0 + + + + + + 8 + 87,80 + + S, SSW, SW, WSW, W, WNW, NW, NNW, N, NNE, NE, ENE, E, ESE, SE, SSE + + + 168, 168, 168, 168, 168, 168, 168, 168 + 128, 128, 128, 128, 128, 128, 128, 128 + 12, 12, 12, 12, 12, 12, 12, 12 + 0, 0 + 0, 0 + + + + + 8 + 42,34 + + S, SSW, SW, WSW, W, WNW, NW, NNW, N, NNE, NE, ENE, E, ESE, SE, SSE + + + 84, 84, 84, 84, 84, 84, 84, 84 + 64, 64, 64, 64, 64, 64, 64, 64 + 2, 2, 2, 2, 2, 2, 2, 2 + 0, 0 + 0, 0 + + + diff --git a/tests/rsrc/bundles/components/classes.xml b/tests/rsrc/bundles/components/classes.xml new file mode 100644 index 00000000..4ccce56b --- /dev/null +++ b/tests/rsrc/bundles/components/classes.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/rsrc/bundles/components/pirate/.cvsignore b/tests/rsrc/bundles/components/pirate/.cvsignore new file mode 100644 index 00000000..d392f0e8 --- /dev/null +++ b/tests/rsrc/bundles/components/pirate/.cvsignore @@ -0,0 +1 @@ +*.jar diff --git a/tests/rsrc/bundles/components/pirate/female/feet/barefoot/behind_back.png b/tests/rsrc/bundles/components/pirate/female/feet/barefoot/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..fa249decf33b2ad471684deec58e805417a127d3 GIT binary patch literal 11300 zcmeHN`6JZb_a9Q|sVK5MDw09jmu$(FG)y7e*!Sf@+1HFERHVqzjD2JaW673c$YZGn zS(0p_7)yyVb|&x7eS7|h@8|h^^UHX@@4e@qd+t52^E&6g;|=w%96tExK?DMESQn*j z1b&?ni2Vqbec->l4$Ke150jhbHBAJfDiOPLJq0`qIH8QLArQBa2t-s202Lxgt!tkoeWep9DT{mdMc@uJnNLNT{>S>TCME9UCIWLV^ zjX*b`gbN8#3Q>?ZwCb@+_omkv)I3su1o=XAANr=(<_+l^EoLo#a(<9MH0?TlTje$s z0QKAVH<&f#=;l1W{1^&`=)rU-6xs~hyrpsrx&^HUu9h2@EAc7O!{|^rl%SmeML^LS z(IYoTpeV>$)|nnjr$^B@BQ~KJ2#SR~6g_AWG;bAe=pM8gv)Sg>R%2JAbw&${gYq%? z33>_UQs(q~bXp9J8b*ER{SJQ}4<$hKc=}lISg2NL3@QeC2+c>&(-Z0X;`&fBw3)c+ zE#Z4lG2UM)Fk6FoOBP#+s>-{Z-)lVh^irAYS@#WR=%>SGyFq8X;sdN~WS~@thuF<+ z7pUo4Yld3(1La5dB923tF9W8Z`bS>vb2eLFtXAHePIno7s?}{HU49v-m=Y-$ z?$OSCpJNt_qvl^fV&;c2bA2YCdrT&}jmJBUMqe8a zwi>)|(eG`(_O9`2X9N0ey_;wL!MUU6U}m>W?80sak^Sz@`dc=3t119)9x!h zj#WsyB^w(e6CEraw=C133>)~?Ujs>;?NrK=SYE*9V~=BKJYiIPtU zkc#jS^LIJxWiR6X=KAn6)T<)xx`Ip9k1yuoREbF!vJzD?5|jzi=O1F_?zx@wu@iB# zL^_%a*_)oRd8m@^CxyKs5#%Wzpsud2s;a7@qN1#H8P$V)&X7__<32*x-`Jc5bcMx22~puwDxT_d3CcgKIFd3^EM9o=MjTT_ul zm$Gqkvp@oUTkk&n<^j@9ICFI5<$~aM)e5ijxt~cP@YeI7dwTopYqhJXADD6r)r8uG zH4sPhSEsd+;T*=Nlp?paIC6Wx$Jc`s5%-MxX6by*9nRQeUl=Q;SkuidEjfrhKnM%E z`TO{GuB)cbu?Nr&HN}Nox_ztt%|#%}fl|35Vyia7v&Jjgw@afqy2gu6Ih_L1;#2kw z{8*asMf^<+^qcH@v!FKpG3v;kN=KH|>lA-+M^9#kHG~VZ2GN;W1RTYcYoN7L&VkGZ zy(;;d(I+7W#yC+Tc{}8o^4WLW0nOS;sakA6u3?wYLR;dL-CM??M8B_NknjXJ?1DEa zuP(Bkl3>47MWt!mN*Mc2Nr2k%R zGEqlnZduRt1`d8PU_?V?8=Y0=Sn1bdM{ZuzMJze~IWP>1Wi>%L9b?LN9)q=bQ|wXd zy+SaDjr#~0$?wbhHLW;5zPZzQQ08>=Pev92Ej(S+k$S%F!)1;pX{**Af06!lU=S7y znrYCC7DsTvG!NI+K=f&~Kn5oEzm-b3hDD|yRDAoPzwc#DyA|-y*Z~J`Y^910XRlGo znI{bU*fq3;*8Q2IrQ0J?j94JpSbm(Wg`7da>jT_18GrlsZ$$g=0{kjG-Tsl_Q0*?B3`TIG8tLb5h3H68MJpYYN3(@#A@J9h^Jt$R*_)OG{3kHSc#Hxxvqw zv6Ibe*E3FD%h>}E6guJ*Hf+O;(`4Dr=+a>TAEtI2>w_O0jzrt~A1zY{7^u#hOT=~w%P$ub{X<&O?r7*zU6KEbYanwgam_rD@!KHAx z$&tRXus2=YRo6fyJ5c5Zf88LLS{k)4AXo%s#a}9BqBV8x&J#jTg57RFzA9QyK#iqW z=ZYw+A_SsP_0(w_23{@+eIt1QR200lc}=lsGna6Q3@f{akkzryd{rA-`&Ha3P=$gw zA)-~sH)2f#uiCsr)q%r_s-|{% zoHh+d2m2c-M(kr^*9CNgAYShD)$1IZo}Fb6@T_1zW@j|?0l8FIMd-B&7+~ zfAyV1WxzaQEeF4eL4b8}E@u*Y9A+Ika0;ho zSYcyyhSjT@H|M%4oZ(}&D$s=Wsiw~T&5hwNd)xW_v%ou;ab*F6(m5>=f&T zgxhd03A62q#R&yuMbzVGdP2a6LIfM4!H<#W71g+TvGzSl-oY{_hU;8zGU(o91xwHO z-Iy6zX1+63Fb~Y~USca~VU$|LV{uG!bC(Uq8Jf!|?T$Y#eM`5W1?-9?ZL7bdaE;P! zZCzlJ2=uU=UJ7%hec$3v*NozP2wp^6-sMn!($P&`3+?WHK;bPAk^=Mmjf>$YWH&@o zVhQOoMfqC-|BzQBZ1u|8RPYMTbx6`nP1n){K;7BW$PXt+RYT`)s~s@1S_2|I-nD47 zUf=Hn)3&cYfc*VWdCKp_{7d6i1#*%HH9QQ+ma`?zLPs}gvuP8Y)*K{J`FL$WR^0Rb z0#R>kVjU`Q&GGRfRberJtz0FR5zC$O^7GLJe!wl{^d~CHhpw9n1SQD;EO4jXDQ62Q zEIc0f;V>+<_1Vg|6Yi|Gf_o^Lj>m>IImvQk4kg3&sdEdiCJW1C?Q6eMfUrn7ALKrCB9g^ z1r|z1x>b~0U9WU;bY%HJ^WVlPFH9^+s_I#LF#*adu|@OfYMbd67FNk6HSw;OH9z;q zU~E;cTLP{WD}?=P^qp8rNMNdY%l47x;i~)`v1rk3AXU#*Rqp1_;2GpKmh_0(q+d zCfr?yUUIxq6he2kt(p;$ODw#=6z_09m~GYUB(<%z1sK3{6{oAxOaFs>%q3QSK(kH9 z{YFg0(5>1S!iQ}JfbeFMJ!fnS1;(UYFme_z9jp696new{`sY2KJ+^=xIBpWyo%{i!e(Y!d;U>%i z93cc9anq=;zdqm+%O~T$q51&9*N8n3lUfK_3tUasw|=Si$%>7(xv>A>N z<2blxjCw|0S)$bJ%n67)3@`ueFLicQs02W8R(W@|s3+r3p-cXiHkrrx^kQ{@^bVX{ z(p^Td*TW%#a8{@5GL+bHe&vz4!;8Qboh#929AKN=N2=SEr(wk6gnV{qQ|L_I z`=bBcQ=<81Mqq6a18r$$qP+KDjCC1njsRTbvZDRC@U;65DdEp#2?wR-GYQ7y;~9qM z_Tb$Cg@4<)3!3hpbKOWnp;JcMtUW})Y`ma8VE%jhL-2`J( z7TKn8omO(YHT3Jp^6P`ZO5ex zs~9e~rSp*-#aQ_m0Cg1l(y%df>ZGKWvMhDw!P7$RG?!;VE z`ysgeE{|@mO3Scpz>zUfEQ5qvvR)CXi*@lZku0#F`S`hsQx!H|EpHd$gL>NCK`q=! zT>00}FP(`f)Tqj2FUk9>R|z^52C9Bs;mOnXv#)GYX7xzl=GpyQ+8~&-+(#~APD#vf z9+_z9d={~0q;UGQp!ZvVGC1*(&EnkQuGxCtJ{%NhFNSME6tng%pAk>9Z_od@Qu zmKY&dq@cS#h_u)${t`Le0W9_$nQ7KNYt-k<_Hz(L3pP9TgO>f~vW-0Qh2{;eV zR(?)?#@A%!`22Nt*rM-)<716(Hkf=76gm+7UB&Sb*!1egBSg3F8P8uOzA)keNyQH$ zeUmmLm8=IkOJ)oFzO(#|kN-9I)5%U0%mKlT?!V#UmKSRbIVa^QpYAq@Vb16tsZ{AY z{|#Rx`6(*{cw>TgElcb5bevoAx_tj1=;`(3HYjsTF*IZsnDK*C*M8he7eUg-aG5gGwOO6a&| zX1zDICV;WBxiFg~(Z)Y@9iB~ObEA72> zw7#$~?oEh!TJ{|y9at|?Xt?#y25D`mAwO}R(lkqG~8V{m>~&=S@yW0v>Zdeg9KXwKSd5wU$P3@pBhV|7vP z(%PM{r+c+X=XG9PJ!?4JN}e?S4S~NQ@c$SBsTQAiuATjg4a*uYAG10l3}UshIhr?)#_laB|#702>8Xei5`73U}zWaf!uv_zkGN z?@;gF!y9UE^@&wy(_S!#aJ+Ko0u{F!>d>my zfbCMoEkyfLrtgkyC9e5t#r}Q@U_)`no4=@CHub^8= zYl6_YzNA&`5>ll_`{0mAlGxKTTq^jLwpu~dmzE+{*QWLfVZf8yEn0m%N0+#Z^>~kX ziKx5)5lRWIKly2kd?H*B}$=W)zt44D=cb%DIk$JW&~5|* zu@`TkXAXW{5eQBM7d!Yb(RtT(@WbJuW2}QfRHl*F&C)?z(WL zs*I|#b+f6ORLBq7AZ^5}#*aIXZ}@L~_xcW9hJN|~f&!sH#Xu+sdT98Nc#@c^oeG6O zZMJQnd_F;8Py?}{)VwrSBX&7>`L@ArC<5|P^noIw4e|zAgA7GMPzDA2EjUm52! z(u~roE>;C<20|&&24!O@erYIph$u&du0sV51rQZlPFbEym{S*150nXNHvT(D`+k%{ zj4#&jiGJyj%?E}>cen!it#$vh%esez_nIrja)s&*n=&=B6O}2B;?Dlk0e0e!H&ip` z99Jf6XNRpPd&~zq&%b$~QylP|svhRA|9+ zWSN7fq7)NQ`^C>5)lXBsGi|>*WIfw!G2UZ7)@J&y#pG=bzOCY1b1|+VN4uDICg+CQ z-K5j$iOSTgN@=l*DPgCsT8i3f3hFLg+?sP*pK)Y;vS0bfZfV^1`-si_2jbj-_2+K$ zk(cKO{x*5tWc=#65u<_7Rd%kiRR39_UTuMH<-@ZTceNhVHS*Hcb8nu>PFBf?kWcW% z2D?d+E@C{b#2ilXDUI07cA5=5I9rykelJZeD^NDV7VT^yYC||~rhHh<8ykQ>W+HI_ zo1$|2(n(+aqegv}lXZq2kM-&cbgQ#8AKg-aK!r8Wj#8lbONV(&1&-N%>$hTdntiCk zx7^Vx%+xHnt(l*$e*e1KomACKib_Vj^36D<>#<6yWQA)Xaxo<7D;|=6IiK`)!gxAi zJWNC`=p8jY%q?(TEz4fq)f(lbCZL7n+^eOfrLL~7rlzK=ynz|V>*-jAX1n|{-G$)MMlM%y zh{Swx;nqgHeaRbx$V)*ZcIfdF5Nt^@bOZ;F19k_O$TK1vk9JVypN{`0-NT}joiB=5 zDQF|8Bu0c6iR2*~%+A5{HjQToA!-t$(r5S!Iq>#*s2j4E`D%wvtRaMX{m>9 zc1R3D)MOwc*vH4m)V0=0SwXVMN8n(gut-dj`ATptt+Mu^Qq@SGskQv>;*+d{ZeSZ7 zaO2i>%1^G#QA-}NxIOgBgCg=81NPLdCl)>tnH)CN=ieWT4i5f2@sz)BYZ}YIMz`1{lv%W|Q4h97l+eKpZwYEFo zZj&uj%)_7(6;e1aEGPBv2Wm)!N6jv^9}OaC<~nfIw9^DO!ECAMGuF$p*O6PXG8=z2 z-%rdLFcn22xI{#;tj4L1SygP5z|=q>$I8*BBuY5&l`muFE};x3SDARppfOjh=s}sW z(RlzPXQf7?z)TLDg`5M~H!U^)8S)g2E*&N0gVeY@d0XQ9Q*wsg0-l;{<`~!Q=)BXcoKx73P868KF+Ig8BVBAC=gMb0vYxxK8e`xMMk=$$0 z?TfChJHaM3APDf)+GC>+T3r(ch`CHBTfM0Z33`Vf0;iQ|H%*J5Q)#(G*rDsAAty{G zOPh;qI%v{fv}#^`^aHl-KGEMW*3NMc|A8nQo zc5w6K%VG!sY74R(ZFy)nh%10j^ue?A)4o+}&1YtPzWT=91Aq3-4i275!%_F9=sQk` zPm$-}C@Y^5^IntZ0;Qbl~rjmW6ACrUk10lfD`6Na9mGv2$!H*CM;DFaG5Km1iVS^a?9=!CqSNFh4WVss5REzau& zld9#ahKI@Ys!QtM5P9y)xTU+OG$7Tu?&ka9JDhta2OE!aPr)=>b%fU`O}Nyh{aK{Y zLEwX7y4-w|u!O|bU`TN%Aj>Lg)u&T6k5iFH%)9|#*%O*e7H0XZMEhai4$;z6X54l^ z>AE<2`UW>x@Uh*s5&I4n=hMKtfZj#~83pccgC_Jad}oP|z)ksQGDd zrnxcpIL@-SH0QC}t!#lsY3N**i%Ndz@I#8q8V8AJK=U1>9lXGVB=0-Y9==uJa zc5;cBW5Yxrmw7CB8qYs6yc^wHU z9)3oZ4~%&Wm~X{CHFA-5#yZE?O;qVL0N>j=t&+L2d-YGhZM<7BW#M~Ig4t@&$b=() ztM?>4>D5(NxLAZca9|hLCpcoVu#{o>_OBpIu~X*2Gd2H2zLtEFPg?LadOtnM1=1Ci z&C*&6+hH9u!Qe{=`(K9xYx>Dcldq8!E&PgQ9F$BNjoi-(+KFf<4~?7}(NDX$)qvJWg1|l_ zho)OpzU$!SGc*!oCH-9U8ZL)J8ngp={T9E@I?7?#$9@jTwKt<66-l`>Rr7YYg`Qu|^IPFKz}l9|p-@!P=fb zIo+R>_uri8Q#}|HxhM&c-Bn?oxo%aV+$MGcyj|kHT0=|BIm7*Y1_0iCQ4jGOWg=kfchY37e>dPbIVp|T_~AsS7Z)c;g=vd;ZqdO6Fed+* zmi7AW-cQPdgYi!w^%XBa+I@8@9FkV1WodY=BsWM33DupCT5nqvI_z@A70%i6JFyna?scP5(ZedPp!aY{y?UHzB?qubC#m4ipS{VPlJ z>*Qx{BUd<4M}6^XAV)i(Y+wbs!FuIh`plcR@IeT$H+fs-4u( z${`)1TCZ9M4gn{}a zHa4(KDuguS`Nc)M2JhB*Kfh>sIL;Im+v@r_uz4C&vgp*R*H7U(4@T?pYnAtvYt=_h z_3H(Q9s{Zj{wxgrdMjmS=vR8ECsF`bcHjC~2(wqFf3-w+2h4qaTz|Ol5BL3>x$l4C z@RJox3_CmZ*)~A89_%60Eryg&_?=M(IR1KA#^#J-ft{tI;?V`l$UF>Co23Zav$~uE z$s>KQLJxlLXCupsGB-ZCJM%k)M^$;YLoq~yHHh!(OA zTJXOgA9YkZXHMjuzR8w&=(L}!VKQ$4pvI(X=7)F_KPxK<<{2Ns-}LcJ%t?b=QGgd; z(^e@zZ8C}Z)U}#ZM#M_8rqtylNGQTpn57gEd+u19$>ULH~k z{2XxKHF-b3@~X$dD{SoGu?J(OXC_2;Soo^w>W`_HwZqMN!i|7yfMJ`g{H4WycguTs zWy|_jH*u+O^yFG8?_<8!|M9W+3;*XqQk7fP(^pzg?1X8yzu9@VAEj99KTeXNSk)+^ z$?9xi2EiZa{G>moUkmwrcN={jtwT?fp-)u!oQ31W4%!PRSKQ+A>Z1o4t4ND)ZhM3T zBQkl$v_WXpPHYuvi}HQ9H2uXrGOYfDg*k52HukuCw~kG*=(;ue=&?EIa%KkG{eVp138v+ zYARlvS@O$#8&EW%^U1Ry7r3^VhgEG3YwKO&7LZt(7!}J+QqzTt1XaxSl9Y(`R*D$~ zE`(6Ce!LmXUv^7{ zHWMQwIaoWeZ$k-n#YgPyo>LDsg03~nh4?z)I z)aqbcuN&bEj`M0WuT?T!IU*85R%PszZ)8X$Rv2R8sHB#;@}$`<)hLzeCIt@}Dh@2Z zJrF-l4Zc1b4IcEx#BHPPgxE>dB8l)e`iKKgqyYcjPpqLd9Ia?E`U@-%kThSKDo? zeyrZPrMq)N+IcQ_O@?_m!;A__f!kAC@GF-kSFKcCskqMmQ!7`aT9KA;_b&UV`$*qy z-CaL*bZblPKdrIPAlc<?q6HsLlBNiXw1WY=|3o*qEMuR4cW{Ix-ppktwr~;Y+46d&CD@6qYO6TUs z6ffg;S8@V|r;ei3l){YNI42j@c!23lTlw{=JKgp!N`L|z=#9gTY8jsJSbKt_6S4L# zo;vxp{2LO<(bob(y8!8|+Ip-7v2FNe_ba33n>XPs9h3%rO#3G3H6cGM2i=Qfb-P#^u?T)I$9pLqP3fbqu290kDxo=$$zxH{jfAZ2ZW zIwcOs4K?+n6igRnPLd55D6;;&xyMQC>^1qJ_Q#N}-Jks+H zz-`yT4t&JW>KdBo%Hf?Hz-J8leB+fLt%1>4VvyMy)G*iTsy9<`N=63nK+KD>UHUdK zzEzMXH0X$$g^R&geTF(H#T-gCAJu~mxa5Iv2WYw1{7o~<^E^n?W%JrWg5VfH@!!lH zEi}sZAx#Hp&pi>U37$*; zXYOR)=Rc9#Vi@la0&2<Y5W+i1S+T# z(wak|*m&s)0Mj&d^?rMehCqJqfA!2!kIWG%FlyWhT_sfkIhs7;7oAC zGcEYeBimE^F|_I)H}4#lw+wD`xasN|e=X0RLQ!Ajs-cp4B!MA~XuDj^(K_K3`)hrA zbAUCbq{I3f7Z8*)x1HfIwvPEe{j(HDxpn6bU<8p6^_r|0sL*g-5oq@8myL#3ByYoZ z#q+o0TKN|~BkGcQ%cE#}j$Zg3*1STrMutd#r R6nrg=z~fBx%FbSl`!D;i)I9(I literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/barefoot/walking.png b/tests/rsrc/bundles/components/pirate/female/feet/barefoot/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..529c9289bee532e023290bb812c0815ed0f6ca1f GIT binary patch literal 32989 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 WnrnC)mcbYGFuV!TxYW=+?tcKv)#a=J literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/boots/standing.png b/tests/rsrc/bundles/components/pirate/female/feet/boots/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..796d9ad391a3582981e489de97326948993a9258 GIT binary patch literal 12294 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/boots/walking.png b/tests/rsrc/bundles/components/pirate/female/feet/boots/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..69b109ac27e624462e6b25c9827465d2927bd089 GIT binary patch literal 37845 zcmeFZ5-O@;xN;gO&A_zkX3=Q*c zpXdAq=i52&&6i^-{))k|p^@89r^;u zT90Sc4wMw)PY7lN1*Qb}#|8LD`1!u^@ec6vbn$SvadS0uan^Hk)Nrtuv9lGkvF5X~ zq%kukFfzn5G6X)Sb)urQA}2Q^C(|P#(Ih73di?lWTJo=?_=bpZ4=>LbZteyy&T@A4 zLN?ZH7M4^drVosa?->{(>F7e9KM$a#^`)V4qo#&YQ8`dj+EP#$l9K9>kjOrLijtK^ zL8R|wq%Wi-4<*EZ2!rRqLX{jGxvZ=?tgKnAELki-GnkW^nBo~3V;LCU(gU*7h0)Ok zK7Z~_=PGdFiNCubEWX9+ud9vfR0 zD{DH?HfH8T7N$fdrZ`5%XeNee28P!(H15xy!KtbBNJ-U*iIs_nq=AOXLr`*%2RXT6|R)zHz88X(h}XmLgjos+1#8VOpGWMrMnl3r%LkG0(|M59MP;Sk*v(9 z7s@DAaC39Bu&~h3(4bH#Ntc^u z5C{$ArKhD2y#2rV52SyI1MC|gR8$q^4BlkhT|pizqY;2)K?3+q7|MMom>@K8X1y|+ zCh$=_YqhQ{35Za(2p3K|g$cr(g7#Bmfzkf^$$$Ow|A)zN5Q+S?(i-N|Z-Wy;y-oFy zSn!lSRQYxPP0b${Afd*5L3qxoU84;h1TnAnFG z{AO&_Jfz;8hpGaTJ`~%%|3=jaR|DN9I(?)4*TWa@r3g{{lL!btK7J3(IRe&qx4z(c z*`cYr_?S>OLRg1tAB>0hK4f|(mU|7$QVx;Vib=4*PY>#D-^Mw%(im0Vsw-Ba7Dv?e zSbfv@VigLaE)L5i6ArllEg8oJHHA8;@nyrBA8x$m_^8d~C42K*XPl0|Q5*5=`pDh#+Yd8Ddeza z)4$`Ebr8NcYY1d+F#_vRejio&1~J8@X$|DkNGCTcjsJ=i>FabX1!${*P|($3ip)SI za&v{8fVzbu(`X_qspH811J<4y8anh9HfMyBZU_|7x5y|6ZrV03o$XvtK%R|3S3spi zSJQ2;eV|i)tzkD{7haRn$>Xf<2YPGrf0st5Mk4Wk;Dyx(Pqm4juCY0~XM$;2D2P#J2fdR*bIs$vd*YJL(bN3tdPs`u zKq`{0H)LyUqC&nJoZ~UvaAjXv*A|V3sZECJede@^fq= zjXoY!nf2cOosy$%TRICK)wmdNe+k>5D($^Y|BHt+*(gxgwK!t3Ydu-@i>qRUHd;5H zfAu^p<5^fqtcHc!NJ&ohoanW=r}c}`_Etnjk2>FN5?G}FH0N> z9;6F68kLi>-s0DQ&=i{*DXGbSW7YJaET%@ATx{JC?Tezr&}pJ$ZY6c!@kfx%CyD5{ zxxLVy?gZ@k)asih%P^dcT4RaL1`fVgyZ5`#Pv=^<10q_~GFzoINz%-9RZGerQDGdT zfZ@A}{M`fp{X{xlEWJt7D}gEEbpy9m*#gkNE1jr$`J58 z3-{?JC%yjtT!0Ds4Y^1Ru8(ARSySkcDaJ#xaC{T(SHP&et%xBDBFd|uVLgA>Vg>oW z=d>>X^Evr~Ae#UmPzesE&AWCj$^Yt0w2pPCRBMXP09|SdDJ-l}klkmIOG51Tk%(+? z{b1m9a`FqrP`CbuJ*Ej_yHI%@BnaHMW=}f>(cgU#;i6_r4jaZhTd3Rp%koWzvF~!Q zupI%R^D2tp0~T`P%tc3u?= z=(5FCqmeGra@dV(CItxSlsV|$GvPXO6U+O6&`-wwQn)MxnWSv^R!8)nA%03@@Sxj3 z86NpVb4z!`gyz)djb;k|q|LtmDw|_j^~1NZVn^E#(JfR22PR;R&JaU|9lPtfQO1zl0Tvsxv6CGajh{-Au8D33)EiVb^e}FIpyg zqRwp1n5~Yx6KF4wKTY-8W7e-aIkFd3Ox%RH-gMuHQN5(b&jQ27(r@nk;?Vi$DkT&#s(3it_53a|29GpouX%=#Sjc^E7grfm+S)@GI1&h~xyo6wU=%DHmq=NT6ig0Y* zddNl|$Tm`q#O`8s1)D1bNpc6WO&-hq7%9-0JtB>O&9eFFE}$}!hR*8h%rzoRAJ1N| zxh_V~gu#CB1lzgC*u8d5oDQMZUM)BZ#77#-=QQAF-l9a5w1&Gi5-o=@9}i}iRl4Ys{TP`vw$*YNO^-E=ho`*zqhE+Rl}Jd$5m(_w1>pFT9&c&Y7`(dHQw}&pjXx8& z+te9!q=6y%z%Sd9l|H1bX+T5<2o(#7GC-Ro#c(CC+NuFPqTf$M$bL7eOA~-DP9nBb(g> zbz4M?vXDVKz4=RvH+P3x@f*DfZgX21i1itM+j|HhMN!Sj(6IWf zM|CxJNF%pitR_RIjpa;ufMNpCavUROY?(Y+vjVIuMQoouKSh~Xq*G*%2@)qtt4QTsuJa>ta9a|5@ z<8~UJeOm|nJpI$yQ9q?8f!LLVT%qBX)RoALwL0{zUyZwOOSt2skn6UwL$|WuZt$p7 zFa&K6f7uj-iRLj;8P0r|fetJ>|F;({g=UGAq907fx_*m`!rYji*tdUM@~E8kirx!x zbZPHOCnO+G=$AX&%AN2G7wRn-N@S=Z{;HrbN;yOP@&IZE!ieB@)|;I0E+%CGR#s;~ zw?hWDtfA1GPvZx;g~JV0*iVf$wWODGmp6;d=eS4}M2c36H}{-quHmU zbB4w_tRxJN5~E1E-vp15sW@Af?vif~@ zwVsmi_I2sgH$PbycE^&siuwx_ka4W1Qt7$%Pc@v1hqiZy=`@>;I1 zZ^yHtPZZ6U7FS@||6O1ED>uYSD_*pAH{h842>;Z_W0j(woaS0h_xnuVr+ZCxrFrWd z6JIz+!mht*m5_j&OgfIjYZax@pUDSUlrFec)51m{6>`!LZB$?QB^4JFxWFD4@#6Jdp$>zVSsE)oR%1h*_0wY5N=|JkgU?L1 zw`2fR^5PR2nSj&2Iq_FNzzj@e;f{(PYBXDz1=|W!oI60QA%V+B`3@S5PrI#Nm_H3t zkIu>J$c=2)0|fZqzgTT!HGxD{HdQ~)qL@5b=b#jE$uvRr%xh$?++24P#k*GIk-8Nr z1r7rJv#DkRvD@{n30Nb-5E&8*!dAfuyG(bg0hI z&*N0TcAUJ{=-IYr{?*r|D z|H}_bjP}3Z_ITKawAL?gzMdrng)}4|%!6@^-~ID3jF|g#I!A6)R;*vdRCmqV0N*+YTBReX|JjEdJ*sf}q~sM9!1=7Lnp{ zL}xGxc|QOz#G-tEP4z&yfc`%$FFN9wmCW4isa4*Ql7b{<%lH_9#MRy5eZ-8=LS092 zkR`RP^#3rv(9LhYj18NcnE0b#B7CGEmv=XA%R}3FO<0Ym;fvBeJ>9}}^8C=)923{$y(c+=y97ojXXe9Waar92bBM`fI*V^F8dHbrp>iSa-zJc9 z;qnq@0HN)72@k{+2Ckp3y*_-_x@#~rMAlR@CIA}$b-R+h5P*{h>9P8o6Bd@Kivd2w zA&VbC8zY~{fvx!;ZQd-<^P-uRa6@eRGp8B28Cf}%uHoF^Y-9b+A=Db*^v8T1|Qf1t`%bKd7Pb42g-ZyDJd>%nyf>=s6aQ|%!4SECcR zb#;00zr|A-gBY{x$i+p=jpq2YL)knmp$;=^y1?Kdr!eQyiL@vCKaj3|mvi2W*47(P z4YFUa(4*{Z`bS7eJ`qxoASuXfOX7JPQ^+eS;0QHmxC8C?*Nd|T`fP=-0MCRGBiT0i zgW=}HZk;bScEwadBo0R0L+wIN-QpTVH0jj?Jq5pp1%HR=t^ej1WDTdkoLqSLoT>@3 z@k{tZUO>Pr%X)Ofu>mYfH3~i*z1GDBef=cQd7a;dny#ljeZ#$C0)0bE+I?f+q}5gy zQXgpoMwGp*$k_4t`1%s(cV6c5^EgK1E%cD7S+0R?albyEI`gMT7Vh%G=G`dS8WSOM zo^+uiOC22@6%{S@_X>*XoVaney4J=gH=c-wW>V_kuw^f3Y>H2Xz|^Ov#a5f0g~WW_ z`O#OKp(S=v8(|tj1Bz5ZJTNZ_LxU3HDk4Nh&w(ar z(8CGv4#3UeIm5Q5CmI$ZM-PoDRTaynZU+)??jP=@Rca=!4e@ryve&T>mLESh(wT3%URdE>9TR2B1AZ-_A}=FBlx6)Nm=&=!muNkNRlmhP|q z4mS*QHxAFrDHzI!n~4*0U45h>(#?0MQ?B{cBuC^ zr-HPNi1x1fk&G|u@GOU0!T6b zl2E*hhDGJAMP%)4a*pb#D3Gfz9^$r|%GRHHhVNJv(YoVVc5_U)SY@QJgf zFUlJ+fy`{;ZV1ktKp+r}L{C$6c8XvD2@FaUCh%cGDn(#AdZ`FjYhG$0#ZF*b_=wFk z&l;C7Ik)XEgcyNU9K1SPq`wK3-2%+!f81o5ty#9xteJHoofs^i79o*3ALse9^AsTGj z?EE?4I&BRlb#zKdx=7s|;#oM@;SJBahEqFaaX7Fo{0Xb9o)D&vJB!+pV8Kbv& z&?Kp-?8&X`pqz!mxzSVnH26!3^2)tR4pkNC)l4Bf?4a$*K}>e~%=~(8N){WhLY(u- zZK{H-WbQi4%T63X_{-DQWYb2c%c1Le%91~@$}0B1x~}M91!KBG8XAg7WGfACljjgg@m)PtA3$1K|1el7?UFLWCa=?k!iSlwW7qs*6Mhb0ev-aC`(#7`wh)p-rSNnj&BQQj6U1yg8wr~*ow3L zvMqBp-SeSF#ls3pNyyma9bOIVtfeXFQgOwI>ch#7gn@=I;BbSX3ghlN%@4Z7y9NW$ zSn&9$X$Z<9j{c*WX9zdqS59VTaWnr}oryfwsxU zY7r}}ysD}~1!O)4el`Z>&Z1yttsPzEGEk_22GM>4v+KE)k|_R!{UO84#kA=5SYW7&d<19wN4UlFEIqntVlsoQC?_H1kRb! zxZSRY6S!tQGLi-w%`iE4b@fDgoM!U{{Ldu<68U{TTA8fX+#5Ic7}Bni!kROZ&cLk7 z?r7NZYWmn;U^wqPzGTTD-_N+mY#xON9(>^pgB4D?a`JwMOZx_u)w9eWT%#ZZOyj2N zA4@;~-LSK@UYR>cBqYL(E6nJ_S!{l+=gv;`m~!i75i7KuLp>Tk^_qwz;%!FE=cJ~W z4UBte*Z`&#S#Lx~&sPg!9-CNdm(kIQa2_Clz;nEXg|Da7&4;iW&3$Sqh6~e#Wv#(q z6_={G)K#XywhkJZE6=Do8Mp3MS|Rpp$cUP`Om=y69I0aDf$*Hc$BYU$aICOqaH*9{ zo`&$Y>H-jID!y&EwVL>XkThT7$By`pjXx~tznn=a)NDF*))Afx(H+mE>&DyV%dX?> zV=2%cc+1^eIi;=rLJ3^(*XbpL@di;bAMUMsEu&GpX#8D+y69HSC_pxk9~r35vT!(#*kiL(Vb|K>Omeuepv<$NG-Hy<1v$ zcb3@OXW&`7JN>4;yam)e)h|`NekIiwM7-!G8%N-h?GQ2qH4p+V(=Z9y-`%O*Xium~ zvX6VUbS&fh5J<-2!Rr8Vrivjb<^zq>n7oUvuzR02jStq!U1X_NPtki@@O4V{LwU(= zY8b@o?Db+Z=Hp}mB%tJ(_pfpqpgT84M9v?L@pFYy=vYD z5$S5u3eVSyVx{qEPK_zTii!zX(W2t)5xvBf@_fy_N+?6~n3kcuMw&<|Q*UefdVa*^ zQ|u(6225b~_}?2hc8Y%tM@(jB6fi9DEVUPIjZ}kq7eY)jaUa>^e@bBsjN9RgiPH@# zd_;TqH^Zs<=;2;=%sWXD01k}O@)aT}6ZNp?_0nre&qgX1HExr)FFzFc9pI3k1Wg~* z5^~uJn#~oX4Pgm|Vl8N$DsuzW2=qa~nKMHa8{XqqN&Jx3Hd?*u9K^ zcAVqb87gyM4*)n3$c>1iRLP^00Oq+j4Sdg*3Tqy?Es!ZufE64tF}c$2DgACsRx*<4Q$)dbH91df9{+aEBc($){l^7?1K9HV1V>(J7zsPaQ=n?4$h$XZ|Bn z|B<@?@Z`UM7Rdr%l>gJ0%OwMOJut^}c1jSCh^1JT>h55v?`skA=5Y5Zb=y|!@j}rj znyqT$r#aoJDImpUe?mb9$MhG zQ;_qbE~u!2<wTaoI- zrZJCY0VN=kN>)TZo;N=`?SKD(xJ7Ia`#vW>`DV<=`P%0jfHLx4=+4_1OtqEs6(cwA zTPN#g3I$(a^rCkQLGRml`Ska6WCaH=e6^*o-slQr5CmPQ2R~#V<>yQuLwX=N>53SD zLB(3_zBl}F2=6RF(roe2;`l`jo`CGY_HaVd47F{0Sk0J$FeMr0pjLXyV)xng%C0Ar zZfPCQG3@ab!hLbPx~$m}|LxiCIc95T@WaiG?y~7l}RDBHqKG1eAAw zbK71WRd-%^A3=?KC&zCr9Za6KyH z26}CoA*5knf6bEi(7?6YFBOaZHFG9jAq|`4ALt4kR$e(H_@rSKjz3D{!lD?CJ^;0% zsvUP};OD_ZJYMyCm4okEb7Lh8lkdATwdBE>?CK7wPf~8-A0(yFHu(Wz0+)I3%4I}M zVCs_tg3*24phoDW{5n4{VD7>isxYw^Xj3GoSOy*hb7q}-%^k-eT)}CiZEk518Bfw~ ztsa5abX=Me;A0i?MtEG^Lag2}?y8nlH`G>5N$|D$+6)gv?V!~>E4a*I7wpIRdwc^D zoF6&LhbP(^X@a9Uf09ec(B~=1MyLj46e@;GQjTq71quq1W(`GRRhZh>c>BzK<^!>E z^Mr6_#-dSnuEMjC-Uq4TN^?XkYVr z-Y$6z2?-J>U}#vF;}Y)E)qguHq4KRIlsabs;)us5(;et6thayNEwWa&AU)BiC9GlG z=CIZ`imCSmu$_{77aiyM_QeA3O?g`DMUd!-EYq|+-g3^loflN}w?jITKYgf?oZmL6 zzQ%YYC1*Ns*`e`&K3+d_YQp%n_tVI^g?g4^Yzz-(>3hG4SQOQpPt`16Hio{>AoDtT zK(x9OmOeC`*PLm1H5lXl0=vR~mxZ&GO6LoVF1qvG(hr@LDO>YRVzRkvn?6GTI3i*3 zCz1ka7qJKVS%5_N0>(rS=x@}Aw z%ksn7@<(LXxotKN8dctxd61CqtXP7Z^Km@KOP`hle5uR3hbUIhC+_=H_hk&MZl_}h z5tG)Cjab6__JvknVF6|HNoyr`_Q+GvOZJRKvbKlSmDW0I_ZMoW_@<@n&2BrIx)Pjr zg>skH))sHsU;xAYTYL34$Pa~YqqTY+xO>m!Xhqug3@cFGTU{$j)79b@L)elG6d)mo z$OXoyF~KZ8UmM;?%EN>4=3{07dN&px#TZ(Pf7tl??zi&Ad~3w>#y7#~@s#xvQmqr( z;SsSlmt*OtCX19)`5WGv#q1~t*kkU-u`Hy)(2t00j+Wn9yTuQ+MpNI%Ru)wZk5F_t zf@9oI({CSr{{wxCMHl#RM||Y=Zy9IRKY)2F^4g&5)$0>T$+t(=c|@`>%PRmg|HPR} z9J7CVIY%n0ZSam?!>Y|@eQed6r?=W~Dn-7Ea8qBQOW;ESHP|?iE2|!A+Y=8B7@a^& zIu+}?mhNk(eP}H!Ffy@n+q^-NH)J~-JR?EwZum6QaXema zMk)pG!ExhHOdprUGW~^DR}MzWS!?UYiHX1Wa?^H9;f2whlRBODv*An9jB=8b(mmaw z&O~QSvy0{n!{nLu!Ecm@K;~yZMJx|_c6Z>;IyEy6(DE~W%!@o%`I@%#HSkdRq8oqQ zhqx;451L-ysmin_S3@ViR@l@-+@A*++K#--;OXjGpmeUPYN|G;h#vpDA=nkq)SRk> z88PEQ1-LPTH{vh1N;Tm@L7mAj=Z65CX>Q7nS6%v5Q|L_M%#nv(L_7^04dXGAUiXaXs*~ozp2NtBHtT)QPCBPy zno{hs)qm}|J7!)FCFYlM-a6-3!;8YV4vVzw2z-XvBwy!OQ>gU#{l50%sQcQ31Bt9q zrrzQ|>&A#ni=@<{Sf2irA`M;3zV-bdE2YQb)1oGQp;9R z^H#_a$SL^4-st6#y_#zEDU-0Igp=2K9bs&#u-(-9oHU;YtY}xEwJP%O{aYlzC&TtXkmvC)O#oU)sv)>*KoO zA4g!wG~)&G@K84{IL-r3xu+jor-s-4R9xrSXpb4@{*KfJe>iIg&2z7R=!t_zZEb?Y z$SLW{+3d_Bm+*6wtg2hvmRDKcjH^<5$(A`KU9Z^a0L9kLZKLBdAz@>7jC-(9i4dvC zO!{pjRu9hJCe$@Kpyc4Obfm8teNT0cLmld)iuh4^g^2U~u4lj0`W?6TVIw>|W=P=k zgoppKbM(YmYx5qfH+pO=`q7M;Gb0a9-bS9b--w>qYLkuXeC3VyIQhEAg&jBb9QE*x z5uZ(E+rj{g9=Im`pPw3=ni$htXDC6+lFJjPPs)-Bs=}q$> zjh~F;!{pwqGO${SEuXzP&d-_BUHd`zJdm3ENV~1&RMnJNR?-(rLtn)uzlp2qmNcHk z|C~h|Ej4iS_L>d89i;lgT>3`zS2OlMW-`DRb)45g9pvma&+dDlcZ`n@=iwp4$XvAZ zT`6nEkufz(r$)eD>xsM@wAuM1)-G1rxoXPFo4__hsz21K9V>J6`JytLQEn^sgJhr( zSAtqyo{8O`H2Rv7YM)R$jDoM3%q0uAB4E2>{V43P$a29V#mi#mO9Q`=TM5GYg~9^4 zby>sb3acx^3>8VTMmUe?XHvd>2#vy~^L2e(L``*f9abjlSn=l=<6uwchsO0lZ(>RL z51J|H5d!WUHb2`#t)XWZC;V~HvO=eu{|=cg1h2i{7G$&JF|^#T)^RM)F(9{2(IF{{ zW%&~lW+ac%hen^THFUeiEx<88p!q?axXA4$_2ZCiIR*g$F<7fNHcG|VN}0dHJpU$^ zr*NN0cX3a9KK_uv`Ee)l;qC#AoAt9=(AlYmR`m4e5_zT5+194A4yUixcYc{f%NH%3 zq|Y9WQFfDcHSSP+l=ueXaxoeqV8-mua9cAV{$%rr`&ILI>d1eogDWQZqr2Q*UOpZR zt@@?a(wd}Kj%H0ZdKqzXO)Zs}HO7@fSA#=C`-ne(^l~?POviGTQWj^0inLXgEJw9+ zwtmNjjM)V&OUeg0{jQ?ehr*|%xPt}e#t$>ZogTJSzCGeGG;SCJ41K-T?>asCRRLeC zg9&g{X?YAewQB6JHYoKRy^-jyaqJ0Gx{HNCh?Mk%t!q%AviePUOB2iQDAV-uOyS0| zGAGCMzWF3Wa5X(6Xw_#Y6S#cAnV zAOIBkGwR&buibLZPiWwD{_s%P)nkHK7sn*kXLl!ZXFQ#(wzS06y-Z<6DGwe;&T9r( z#ypyD&u@ji_wF7{g$4}g=Y&(TD(bP`7xA)d83c#4#0l(m)qr7+#0*P-r9NVA90#A4HXm` zVn#;!b^DH+@hDtp-Y0sMsHM`XOfSxVUcAIN8I}F`I<3Iv@9L6}Q)E?nxwA?c*UX!| z#ix0(OO1}($gxK$Afs);J^1h_74SG9#AM)_DFj!ZeE*8YL0Gd$8JqgpOZ5ZB%@Y%; zsCQN6h)0-&2a!71-J%+qHtu!mKfTatLIa>1_~^>Sdi~JpTo|1V zIHX?>d8$#l(LKB8g%<^)d&zgEF^WO@76-5er@r3IWqWV-qUp7m>VqEm?S&m`EIZP) z7Vc3GK_{i0Um_p|KWzR*{J&BDm-+Kwy3>DYVE^IO{}*`m6-%`>KK=&IGC@%&CxEcA z4f}75ntwg~n%#i9j2^r9KwSpduTXTrH@f{dzl|HFoOjO_wPA?TD9zaqb<~RM&r5;J zR0w`TLZDmtiNi7px+zYY(w8?#4>O~88?D}lKn{clH9-v}mMnm{idm{RN{22!;y0<9 z<0t9P{Ea(ZunxJG`p8NyTf>q2tm)_m@u{iy)e8wg|IHAmg@o+hH12BYN$bgKUa;;7 z?p`%u&H8o+=W4i~CDl}BOi{c!K_Z;MO%Y#1!)zaIKL(6A9$R7V0|Im-X5(^m$Dl?F zF{ZzZ%cnoYKE3(&kPsn>Rqias3Dt^Sn`?YPBH|QUur{We&;B}RHml@^{&NqNumNWb zh6{K78$MMbdE8T5_Fcn1p;---X-!8`YP#)@0J(>Lwr1ishA$pl_`W1#@hQaU>BsUz_;Q&o z3@$Q%8QO7^N;MC=qto<^It(;yaxXQ#;dPx3YdypH;mUYO(O`!C(ksV0rn-bnBN!NV?@mjLJ-WJn+IaCDu zyH}L}cjG90t=;OAvdGa=r|umk?d-9>m@S1l>d6PXM5;j( z^C{z%g=d^J-K7KUk#*KFcuwf%#dV+bXHPcPg^yC4ysLXqBC(lY3o%Anf);9eMV?+4 z2?9#luD{{@6-UO#?CYZ&30OnTAP5qeLlgI_v$HFU2eFUI4V8Q|oR~>Dsc*-|&|jdC zwR2k+=_f7To4mjD;d~g+Ka_S#%h~@=tG1?He}89M&aO*{{!M(X?7}_yQ}R_I#j0lj0H+n;h#OG zX%P8HoV+}p_jzDG_xpBlp^Ef|hpTqYzu9&xS#XwkYMq{PYBzjzheio=^NB7iS+^q$ z0P^174Y2XbZGJFL)|k7?D4@wU;4$vbU}k0xSjZR&(4RHn-dr?$H-xhw;-^$%YBJ>< z7*caqDpR$9l-zI=h_jTE1nPhgaTPiuKvZiV_wgCVu>R`oJ~0h}R3dXv7V9#+Oz$)1 z!_TbLa!3*U9ubkNQiv}rTa60{8F-_TB^fzgC6CRiVaD<1;>OnZ_4R$pM#e+^ z$#@U%rt}CY;Hr0SkW%uI7XP&N?Y*BkA`hainP58A_3(i7PJKESB*e2nyl2AOYqNKF zl)Gg`QjwF8c&97w?s%JUOJ;!I8Jd|MzO?2lX-+uA6VZEjRKd4M2m?}}iSp1XCilio zLr#V&o4avq_Zh=knLEgO{_enXIs7?qnq0&{VRaXG>){$`zOVpqYqO=lD^fD0Hbzz# z$lF=6QSUR)#X9(OzSsyAIp4wY;a-k@VqmY(5Yy5S2O7r?B_sL8@9Li5gjjvsw4={M zEkd3V5p6aXfpHm-s+Zr+_7wlc`lA0tA_rd19<1ggC#~6T7yfL=J=SlG$3ovAMIcts z%UwCCuk?@GpnZ23@R|2b^U%c?-_^LeG9itgyY0xaBLQk5g>ZBv`vf0;EeZKVmS~8+ zNBqX}ve_?1Yx`YPd7KG9)1Mo}vta|SM#@0qktRb|MKN?6WkE&W%ng#OyX*VkiYz?9 z8kKp|$S68K;wruPdVOY1H76zFEzRy02IT40bx0BNby`&V7A}cY&^~eVN0<|tLXNs> zU-nT8IZ(`H65t>JH|J~$UN9o#Gi!U*uc&Yt)r`|1Q;@*m^iexKtK;Z;1;JsUZi=I4 zaW0%HOl@fU^L%s;Hk`e>5HXo|Ns`h4bVOvN;jy5tTOAU)`z_O%^;Jw;@^6d4&8JdL z!TfVX8*0qB{NG7OBDVRksj1>;hP&10 zBoa2w1a&WMkNG(TO<8;n0j!`LNoxpXH%38pZ&Uw^ab?moib8>|1)kTl2S*Etx??(q zeh4rtJ3mqB!M6@>C4AO5G7f%Mvoflt!DG*x#{L7YnI2=wAH!r4C zVUHW(kZEh7Y1dgxeN%00^crwKj#?scDw3k87I+VIwMlKRvS3@K3{iikYmw}}*^r_j zOL~Eq|57f)B^#1Q<6LiFN1%&i=-IWEORa|j{mQK_T9KaU;hz)RiBIj_YP?5AF4C&vX+%p!ptEYXU@+S{CMsQUmiK)^grwRI-gY_~f}Wl?VGc+iGjzTpM}NIp80WU@mmus`wTl1$2vI4o38Nsf8JjB zrx2Vr?(Ub0>JyD&ec-eZcnPjw6SPOZu5pb)4xpu~MY1+t;EkE6Gj-_xnYkL!( z65#BdL9HkKFkWXxuM1bcn0Vgb0w{M5tB3Z5F$JryNpUse!b*Bd9~>jL@tZ%UP>k)H zg`oT)@%t;I5DfgLf~(ar37l`ZU0g z8YVgGmMA5};5^)!3&WXg*6|CZd(w>&;P#Ov?xw?h;j@G8ynR#yZr0AEbv;ZkJoHmm z0%fbaWjHolO=p;WjYCdrRZv?ry`dTV#$xH9(#OHJFDze|Rr8sXFsuYKMV2IS`ObkF zPCJr?%W9~0lzR_VW*15GP!q=f>|OaYI`&?{A-~gp)AkyKFsu!%PV|G*l%L5URr=GH zp+dWZVwN~^&2-97$(hwW44HdLP`+Ai!)NuO)-j#|Pu{3h#o>bK`y?ZbE=VQwg?8QfRY>0IC?lI@=7B|uMNt_idE(Ylezn}_&;osLe#fhcyJ|&g z58F!3Um=qDe{xbSir@*X!Sp3AM>o5tkxdwwgh{wnu)n3(jZTxM`MYlW`fx7gpHH5I z+qhQR#*}8#mf46A@JQsR&%2a9dp<*~?4V9bN|N)kuo#|9{1QATh$WRH+zbn1#EN)X z5OqjBi%IZ=h%>DRAE$wOdZ?TSqnKWAq=D#EvYMX^V@)#>kJ76`cczgKR>XrGsVCebgwmeau>p1_l=+vtTn-~ds9-4aM1w?)p& zm+)lgb641x@GIl911o91C^|S|jaexYmc7)I)h_w=Fi>+oDEW~r;(p|Nub}Yo+S;02 zj2TIaSl=c0hsf^_2RUbd6DIx@9MoP7B^u_Lr2Ki#rK;YF(#VEXl@)ck%PIJ~782v| zw5~+-hJ9)CqupJfpZ!5C5sJZDk^9_(nz%{JWT)b}>Srtw`70-U0BX%yO5ikTz~O=% z9u#t1&g6XAlD-f9s<_QoG0S!atBz4*cg||O8M7YuJN#k-aee(054U!wqs>WSi-R$a|iQ3$9fO z#4Ws-22%%&mX!?IOhgv_tIdj}LQaMamJgG#k$+ogW81Ho5wi_)`hKbwYx!e#Mt;rh zrZ;pW@5xlK+3T7R1?3bw@~{ggAg!rC5^KL|=$mp{>O3=>8oYdF?(K%xxO1{TapBI+ zBj?$N^9)<`;GkQ%He-MYMF`s7qmUdz(=5EUu>sjn=y(E*@Dt*a?JS9jN00`Gu;o`Y ze*b(ur+)Mr@dg)_oUPpaDiw8eQsm>fl3x}nYs6hRa9Mmqz+a0HlM3Olc6D8IRJI4Pc zRsDD1%zvls{CBj_|7AxmMFVEX2F77{-;;;HXHbgGe`Tytk_Eb1ssL<{HUjKk9q|1` zU6>Ch@4tOU*fz*~W##ofW4z^M(S`j!-LjdS!ig(PWhDsDi~(uhe*2DURaV0Y3q!S{#@h*($)QPtlS z7=uf{K_Tf0(84#roys73Juk&!%T_k&i}U^`JmPXdDy%&=LYw+iZ-&R)AX?y5o|gO) zmUz!l*rl**Z1pjIlU6-`oZ~JQZRaGfthzc7xvUOw)rk6+96fp)(s@QPmsFGlO|;UN zD(m>Y8e~c>qJ?@h(Fl~#-28b;oqq4?aWUc0=Hl0v!?7QFgOz1d-%f)ug%$b)(tjO zFW>BUte{!*@JLujeK5<|;V7QWo5c4f06Tllc=T;Mn|3kJy41n-M|S4sk30%a2DyRA z`R%rRu7KSj5o(h@em>v*zFW2mcYgH1l*^dx4LA=cP;0MFIkPi1*7&76<^4W6P#Ew0 zX`H~S=j;K)OoXvv-&r5Oncx5nbsBa*P9GLpHm||zDtGt!)j9Q#PleK=cG-~QIN@}q z-lZH`na;$uV1ei8lr%YP=jSvQb=qHyfd1mxqNMEoShIAHzu8@XyDgJaulk>~<9yE?4jP3K>4i{t?QcsLH_r*eY{c;G_jxi! ziwo`8zS>seoaQ zRZ`)0ehl6VU(ZKghN)hx^jA1d(%x%%bA`&;?;rl&+b>rdy~`mIwtX18=%tsN;rZt^ zc@lXwODU1X)S0XID%1qp;Iq^3@64P9vpS0ZK zG5r2|LyY7{Y=~CG@&)QcH8(_PmRlV-IbqD?o6>z3L%2Qjzhp40Z*?QN0B_u|znUa$ zuK*7DL3mz+X&zs>CF`Y>v&zqY&Ud78k~YT`AkweQ8sqo-+esz9`y@8#Hf0$Pzo~V! z+zpEm^9?4=_tT^@n7(l-x4fl%YEH&EIgr8(9QzX$PSw{NK5`b~IF~Fw3ltNkYbx;F z!>Xr^i9QwX@gIb7&$c}>S9RZC)E{S2!n=`Jtb1x_!=6dj`EUcbtTac%#E(&}sP(aH z(lCKEI1?bf?Z+`x{vCD2%v_!9=NE=!&G)cjAn4KeKHIz3hG|WrFw7yRpoP;Fr;bdY zo4c_=#!@f;%W#G+3B?4q$VLQZX6)|dcPqAXjX1d!q++Erf+wWHLHdlssba&F`&a;-3vv%XJo!7-V@`8;{ovrfePLeE!K@gzfS zYGk7_SfcxSdu3DFq1d+ujrOX-xPp(pfhI413kf_YpG3e+DcDb>YrYzqX$!`AjYfku z0=G?}QbD7MM*KbKP@IUefX?nEf5ETNN8uZ3G5*xVG`RRNEO<^$#}*WSRD&c#H*d?V zLuALDH*zZwPNmbm=-6FDro+iCTlo2=-hRoiC4ix&t%R(qr;TMzuTu}+@d%fyXokb- zc(zdH9=@X!YhX=N$cX;}U1!MMH&in$MtAup%nVE!f&5$@qeI+GZu5%QRH{spo&S5p zjSqcq>jTp17_y;;kwRthxKZz1Se)uXNaMR{PveKkXkZBxeiUR@)H36*8s${U>SJs9 zk*2=8Ku$dvechSheQ8yf-`)49ce6epet*Avih>MxsBp$Tp0ROw64CV`pqjd@oFYP3 zXwGBkmC&fN$C(Pxz2xkg@o;WHCI-3 z2H)2{R@CTZ`wyf3vuS^7Qf|jMC#>T@>73Fv^lycJev)Cf#p&DC<18a`apHf%E6>%u zJ%~0?@E|U40~VKJ=w5;Q|7q{6-lBTLcP}m7jUpW~NP{3CDc#)-1Jd2yAss^sIMUq> zf=D+bjWi6Qbh8(~{SWMeeeIL|<#4XyTC>)A-?g5&@6V%(Y2{gkTP&6K7-*m6TNj&t z8|;{}d(~uU{9Ww+8uxjdKpdgyNsAQYR%?%M(}jM^UFX8T29Vqw5jWas4Ze3t2jgK= zkW8Fl3tsvBd#c#d5whgeQ&8ZPB(i8-WR2yx*KV+}z5F-6sEj0!*Q5wk=N@m)+#6o< zL?B=F3kX&DL=4o2dUOS>igmmKa!B#M;a@tNRy|A@SfJPT?%(W$G)qNK$MNdDj2z() zp*#k}HzTijR$Pv~uazU(EDYTtacP_aiofKVw2@FX>+LG4(j#uzA>-{tW4QLMPd-eF zI}Y6HDY?81qY%v9@Ix=9nCHWEe0iYCwgaFvL0{7}ODo6I=EXyat*{1qbR0XoQ}S=6 ze^fdd@Hk43_ugq?iBc#gAB}-c2XU`9tUQI?r>LKZ?KaLo^HxnYymW8@DxP<@XSp2> z967yj8N^`eUs=oo9M>;kXe&|kK&PYs?zeTYrCeMka!sUDkIE;-xVOxqRFNBKiUU0a zc8jg<$pGdC6_F8?Ct7a~7uqYJ-#3ZZ8bYKH9+o$P&>Rw1TU(b8_oYIVjr%OQNIeX5Q3H z$BIc%z~|*Bt(>V|@(8hKiE=l8V^DeBUo_?NE}|v1Uk6*M`Uxw#*2lvN4b1Zq19dGW zmh@t`@zCI%QVPO0wXPjG&OH~x;?#=AvB}G+%^Kh`_N6MRimQjDLl9~VN~hEbNmFP> za=m&TtB0h{?gT^iD#6X)qkEO1zm+sYQlNxMqW(dOgdlX4zT^ZIeuqB=+pjBk!gTEC zI8;>;7PknTvR2m#D8E+qv+O7|d;-dn*XxFGos_J-0-TB=;+5RPkD9a>!DfD`owk{o z%-q-+yneV&b6OdR1*Y6MFL8(XKcjDLAy`l3 zTwHMmVD*%H8P6tl0{p`LpDY8zA*(rWy!G@D;?M(QD=OBW0A~|#YrjpqNm8$O-A@Hh zE68!wV>*X(fN}ye`s4GL#mRQ<6XVfO!J5pf%~?gc~bSgN=d(+%-|I-gFyAGV$1S>UzDdhKG3Lnpgore z10K_NlJ;a~nxZEVsjti|DHmV6{ab2iVTy!4@E~8W?xj>HZX%fm%qvbO*0lR5rKhJO z6OA31(OK#Oa_gkjEH=BDPH?O9PPefb#IqRE!fyYC3Y|GC%Uoini5-!HgX&k|KYW93 zf5uXI4r4v0PxA5*rqN$C;0b}}f3NBCzkN)Be)`2LMGqOYm6>#bT?bCC-&K(4v2l^V z`MWeI7B6q&^X39}Ocx9d_g1fzk!1to;})ezJ$UA#NlB&TW>}i;Y;#@{lj9UIN2X+% zD_7)9(_Ch&$*o|roHtO8F!(d_Mm>Fp;_ImL(nc}3uOfYy=halfTa&+u^LX0Ca|M=$ zr=J3h2Hz8qjNL!s0#W)~(+6c`8ChnnuSX_p&Cuxj`iUuzt=zmI8qRqo@wj+s=rGpy znag+*&*n2~ht0H7QK>Xq<2$&|Oolsmc5Oj?1PO5ulT6K^QS&|6d!5imegA$RjtEOG z00>N|x_!4`2&-MeH{}tv65h&!cVB%CxG1h24*nF=h|NgwKJkBYIMAi;2Pt>p z0OtVUik|qrCyL1+2{G1;^O9qPq&u(q(Ba*M)sZ-F?LXNNnPXTtVMN;yQriHR=QqLp zQ)44`qGDzPA{G?!m@|phs-YpYYn|{1LZIHsfPz~sDPf8eqYc}?!VguEH))dUbO@N5~CMZJtIsp+9Y%JQ9#DfX=KL4ZX{)Z6$53T(F zBTw2Zh#Ctk5Oooo87P4Q_${Xwq6fRm!rk5~0}Q~^gmo|u@$|)yQ}WhIG~>uAJ}&YD zrguh)ZnZ$rRD>RzzRr(?^urOdbV?VX~ux>sPxPqkVTmX+RNR7?Q zQAWiTZ>K3wJ^jsYCkID|5hcFfH`PVIG67yaG4&w|DV+^Sr$~sc2#K(+pLR(>71yf*fyZ$5GrEopG`dN zbDSdxTDcjtzFpXDE?v>LE*U*~3AEI@1md|-CZR3jn&?WL_@;dBsP$0;cBT0Zk6uz9 z7u${1q#J+fwEzrb5}7F$G=-^siktKC_befSn?r8F>!Zbl536)V6gdb z8M+^7Y!mjU}Xw+$qHOQ-RTsPohw9h z@qJ2(&PXQ3Hd~qX8KwcG3!lZZ&y|(I2D8e;`3mMo!RYb|3PF3QK!+n~J<5@gj~KM) zfW2W74KaU3)bP0Mu4?P)6%hETJdw>mIrqGEu0;|%fQw_+(C6`zi%zQda?letPCk+p zXToem^)0u$f`MIjrNz-9?#nMUD`#hvtCij3wKeH8@{R7XfS;EJ;vpesJbU4+d{$Wp z1HW|dX;vwLpx%$iKi0SdY-HTr7!`39l6QQQt1cnQP`do*2FhvvbA!i1f_&P4Ecw+@ z>Hv~}XSe^|<=JlYRVQ<8Z*}0{*)GiU2NPpJRw|oOBDEDA<4=X?+RQfv%OFF&6{R}x z<83|6xLZUasXQ7XYxP2n6;LJ-G?49C%gFr2;n=oj5!jIbT=!g#Ak-={nu4}+i%SVm z(gE5QD`h0BPppyi&F|q=qTSuD+%8LJL8Z;L!3hxv+`c1rCc{4d<1rxw@QnRFsTH&} z5o5HIQh#}n=j=;DLPBEhZ#{o>K3XZ%R=HB01uL!u!*RO;6z?1obj=D$YRpTNQqbum z=zqw7^p}EmtE(yTOHrPIFE!p4|2Di$&1mcDaAJ4d8XJ+(V^#SZ$dXA>5jNKi*kfwZ zC^}Zm2}cKh&m-8Sy28Vwj!(=&99bUxh5e6Uo*1+~wswSObhBxn1xkexv&rE)1yxpR zd|)U*{<%YI4OD@7DNG75NPm)u&*m$t#d1KeP4=j2Hd-@gk}7`Qs9#wX;^H!?*%_gW z1|41w$__P&Q9PR23|QNkBohw)0ae8Ic`1Kpf|d8n%)~1}@X+53IEiaIrcuTm-}(8i zZ3_z6`~KL~+nP1Zrlv+8AK{^onggT~w=oP7fw80UT9Tq0zdwNkKAzTw?yFs3Tj<`X-gV*;yRkA~lr*G&`U2-a3=z*O;tUbnS!0sBDyO z%@1^ozOgZ~Sy+OkhY}CpO@xHIT6;7$V#MCiNfLL$_}UNtRiHp&YZ_FKH=Bg|pQ~2{ zyr(*J&t~Ts1WFC2Xb(+GvOYM!W7g>6WcIP1DmJjdOXRheOPHKD)o-q1kO`78d|sUj z{#WNVN=h8HzhdMR5>#vPw^NI)F0a#dYH9+dwG(QhP<_C8X?umGeJr%YET0zGbZ)1C zU!s7EPcrw>rNu1QPr`Nn1b8ty_&QJ*=uO`y=~Wf6Bw~F2FnWkXjGtDZDtkIskIj?Q zV#gbGc1H+m%UeqhUU_o;q-NKU`a2Xc)GI0;5x6g_gWdi)x#xt~TU_6YZ133))E-JH zbh7YcNiVNZh$<*_;s>bonjYQ54ud z(~(@1ctJEGO7fut^%fiVU3n@vs@98fe15UUzuO;|;V{?|xY@vJ;gB3Hzq_k@MkhBV zH$FFVuL~ewCMDMRZRWato`cN`4W`SstMcn2$S0K0nncfmXjvT+Xgmw5ehS69+>H)z zUud>T^`|Dq-OjA*X0U>2yk2EiiHM3?%U9Bt5AkZL|8THh*b1+=53;luOpB93=~mkb z8_!;Fd3Y4m)B`czH+AqcTl~D;oq+wbb&84c!8f*iP7Kk@<@B^;tt;bPKc@x=mvr6A z4zT9-f}kesHpLYBmH(nCN;7FZLd?YrD`Nzx)&BLaCv8B#GctM|-<-iFa8Xq&S+=x^ zi@x@MPA2Zw;T@GW$mTWex8>JKlSDxA zO|48^`{CuQ>QR9V9q?{978ZCU?}NU4qcpliys>3)dxIkci-c$ zXL$DBlLI^!>d(Y~IOo$f=%wC0?~7vUE_58d#T;zsi0NBDTi9Aik760GT%FvoE!TzH z%?Fs;h@{)30QlbrOUrmG4LickSF^2>VIj!jQl$c@=PNK_Eqz0pTGk;L7o3SXU%fl& zqTHdc@BPXVDEP3y+LC52W)c0&+5>no8L7;^8;WdLf3CSlP$Cn!9j1CM8=AQvF(6L_ z|Lo1Do@JV=YzZ=3pcfi@36^JV_*N4t3XUZ$D=pUlWeFIX=eJ%$FD5I7V1P~bWULi1kdIE zjWm8H3fppLRQi56_-!o85%QPNdR6<{Bq?&6;>Dx6B5fYq$N>E|St%)`BF^MAg3{8$ z!tC*nEAMS0l=t0Zx}uL|(RUt)n2b9f?k~7%kv>Z5|6!!&#r^$d2T#4AZpdj}n@C;# zHz8F&yOmhovzAxHl(+St4XZ0F<4<^rd=zqHQv-&ctWNT0YMj4=&7-PIN?-QR&O#f8 z0=lP3#&Ff$f5(X=@G;jnu4!xW)k3B%CqH$8 z^0GZwhG~h@JFNiraeb-MR}YGusy=N#oFrI0OSpITH(`oRO?t^OYeUfl zz!?}#d~e+MGg^DJ_$CN0-S<*$O3-8%2BAt|}lSC`&ID04hf z`0{01Ws?YtKm#fpY$;+I;8?=E3-Qq-OTg4=gYA{X#yUAgm1U}T;t%4f@07f=Jbifb zL|yRbA!iyf=&LcX;n~)*p;RPain8qY|;+j z@x4!c5&9)NuPwPH*@zpPOWr)IzUy`UK0JN(MLvMD?O!29^2>=h4sZv2?YM_ z;XKF)=sj^IfI+kFYl$6F4NI{@1{&_tyNSqaGbtBGsSLB;#9)G8EJaQTK~CXeNG05Ehz9`d z0g2iqGMd7&#RCz!4X@v+Jg1hrp@I%a%>ZPS=-FR|Zf6rB+K{~&7UW1Wu9rhg71Cz` z#RJY3AT7TT0<6<4KQz^1mXm-U-v4~WfBl$yXa;bt{v$B|N2dM{$6fFrgZ%%9%|1nS ze{*47kPD1?e13G0#3M*7Zgio%-6J0D4xAaH4SD|9sPA^@qp0YU+2130j?dra2eh|) zc$=$OUc7}sXs}q2>7)hL^a~^j|IPb5{^n_xzcc36ON~3om7-n`H)lMM zrOWcJ?&f;;L3eY=VxP)MFYQOkbD(Q7BsQwTd$fLmnbDoJ$=nB^8h*T6%)~;*dVS{O zyK~a=bbE8-1JMonY&_fNU4JU>S`Pyn%L$P?^So?(`BV0Dw;d9}9v&PD`v9c!a@neH z=-I2Tpwm5?zN@t24a{F5b+-`2#=ZWr&cFHiFmlSniW4};mdWq>Gh{uq+IUU$vpA)Y z%Ey!+h2dwU=NBHk(NRu((~C{U=$N|`S#vX{piCf+$)d3f2vqikC%9HC<7;37_Nvxk z8fP)FYEAe!yxLe4>XCIZ#_#aBOj0le}>cLfNOpKm@ZvSqcs3?CvPFm~sRx}|d z$zo|a*hYvz-B$%Q;Jczhhe=*p9kXx2Ph80FzxG)YYZX~5Gz;+Y=s>1oGT=<)bh?u< z_=v~yIXnFy+T43J#z_!-Fn2(i)OCOh0|qN9vExDZ<5o1N1NU}#-*8J*h9Cl?MmGCi zNEG=xJDUb~HZ?UR5WUiKM;KQkJhV^iuRzi7v@r`lfriKKj2~oAy&WzU<1hu$%|MUk2N?(m8L;ut|DssX6eXW7;rRI1e|XDm zfGamD>Sbr94va?wi99Iipb-q1Z@JI6{Ve8rpxbSpGIvSO5J?pGZWe z%pk43uOha-JFja<86e9oX4co&BG@mFR)767*zAdINN+~r$3;tG9Udozg{gB!g*c!eG`lV?WO*+FVXA9 z^P>+qW+G$(Q=%gDdzH}DJ@3U&tF8fyv=`;rxi1Zcg_(*E{|W~jkA8p`)X$`_$m(HP z@rI|2MeX43(+mj|GrZ7kbUrq_$bg9vy-F z`VA&i#X2ySV?-;oI@@I~mFcv>5TN8M5u!K#im0FmDHCYh74VpOI85HUUKw{6c;Mbn zTwQnF0J^E}u2u||9}l()ia8sUi9;ai8xy&n;`b{wt}YXu0sevH4Q6UQwdd}$fc<`U zmVuW2Ib_}&u8@_PVAcBoJg~NIxX;9;=u6TExi^P%ks#kLf_l)u<(;zVOp2B>DaRRd zsKk!0_VL3)P%r^}#&<|2Z>8mR#5`m;lf$&PqbqOx5O3V)bma>Qk7YVBo6$1qblchE z8BE`=bO~M2`1cxrpu>7A%rSpW9HYun6vyHlrF4nBle%p$zo>}^X0CAe1%LqCWqo5t z9vvNTSC359;7%OP@!SiSr6hN7$kI)T;Ty|$gl|Dq=#D-mq|^qBilk|xtKZM_$qJDd z7q-aMTJ#}my1P^20QL3LWX{moydP%1_MeJoKE- zZIxu8WfMTX=I?l3T@St}D@)AY@22Qf|K`r4LEkTV{i{L|al@SMg0_L@0?~rgaMVPD zWV>W{{l%fwNQ(6boWGs5T^4l`re8z5^74v@a^^{_%E%uS-xSzPg?OLskbWwQ#>6bt z@)e!#R5v?H3-jy_z(n-bP7?h4H?+5+xQ70x=jr|XKXR-GNgo6c?$?1r;Gyd7zLDc) zyjWg-TJSm-GLSdYxFajbW_VtG{&kv|;KH@8Xjh;IIGl6$@~l4ZOnIJN=$m+bFc-(b zlCMtn5(c>wqrVp6I;yWwc6Xkg(%7{S@}errx?JKPZ3+aMeg{uN-1Lq3-rk@T91#>v*7{>;jVo@`tx@BB zs7Kyl1vW1I&%p!u`@Q$KYTjWy|ay68FCCp@vD=)KfKElKz zrl&2T;I!-Nr0X?@8JGpQi2Io;M6p)`jvH64uocm&^4ffycYDcaZBseCpaOu_Dk_MC zeWg3VVb_#|e#mjPlvn9P`l%l4#+KDBHJZW-{oFtpa;O^zqWO{D3+(k{ zwfwo%Jt{lA-Nox%rvb4KCNc_c%DiJ`Nz-3a6XZXOR)(X@8`-7fgRaIR|LBQ!@+!YO0xmFs#rVOO*;ue;? z?M&ajq4e($H1%}Db)tPzHmo`v{{E|QuG8Kmz$d}Lz-Zb~5p$kpirs09Ib}~smaDT^ z`g;@<*;c|FDQLy<_LfBt5y72FBsi#dq`!ISv?mzJj=Ut>;sII=^}f5UwudBtKD3X< zZxv-bShhSrvY$)sALyUW5lyma+US=}VI-DsN6&;>`n@G}&v=m<|)LoQTDJ>qb8kl|U>Hjtx#(H-L zt8Ux}S1l6Ig14;i9qq71%xQNy2;{Gh9p<82gYmJD~Pfd6ld3sAxVeEk;_k3*dErYbY?)fseGHY`f zSG;;>@;Bc8lFp?+?LoeVmF=;wE*1|}60?}Ilec!DO;pxG$iM3uJ@xTIJ#$jj;~G>E z=kX_zvU=$4tV~ytk;4X`ZLh^FuL!T?KKahAjyJhhi*~mv4salW-kDrK!ub0aF)rD$T!QaNJC$hpPOYT*lCpHgV1ypR|s;W1l)Wq9)!a&Wf}4q}%# z<4-}GuwC~CDr67Y*DK$Q3=mS-YP>RD+Iv6VY`1gTQ z>9ZE@M)(yFx;)&c`5+)5rAO<@_2jMnl$5)x1-3xp2-!TUm-POkUD(ymPJ;sM z`=m=@uU;^uBnr_zO}EqVl|8&_&7~;47t2UJCzf}vPb{3HhUdN|SB?d)9ONq=*W~j! zdYmv1a7()j^)Rk2AXM501td71zr3)E_f#k^wP2^xXiUZfj66=T<`P-_1ZQaJc&$>( zjv_!1Iy%!h(C5M^c`Cdo(Zw;Iimh6XRwR_l_fVo;_s=P@^c5N z@$}-tD7x&cnBZ&^B9foHK}$`&|KP%%<3TC-5O-$#AUux;9K}juOZuDmcAhN<#!t7q zeD-}y4|s>sGvP*1+@Y*g0_dVuiHA((F$IMZ*|;wdSitd(*a6cr+opvlLOoLcJmmTs za(lBUJKd#ERzS*Wx*E5Bv71NzwJ?xucz5Ce-2GUR?jzkN1~j_OixoD*fKgZPFjj$x zL6*zT8AzcP+E)_>2zPda1vO#6>hbws{yiU)^SJse6Q93SE0TSS4sey_7uVN4Qs9lVCK$2*_0EOa!if9Mg>EC?w~?7AAM zFqh*COs>u6qpz1HfW`iOKyTSRED-o%!` zE8T>LNmD%d#FJx|vvY)VQY=6n^6iSW#lCJF2#+Oo#Lx{qJ|b+`ySvFXlP4os z5k~f_Gb>_LX3b6MJiCFXY-It&ae4q&g{?ZGcFV^?F9kXT#_oJb8zDlS5bTCFUYxqG zia^P;c=oGUDFzQpFjl*3BS<2OLX1W0812iAvvs%`hCm`N4%)G=8x3^o znpAwJk>@BLAJLZqN8Ernj`!`G_y#85H$iKx2U~ZUr|yr0kbZa;jspGXLyon=?L8iW+;C}IiWqXFjV(Xu-+zraGr=Kh}N zAK+tO=Nl6lnGxA#Mc5eUFkBV~dK;U))(9vpibU}@9x?A+U?&~2;DpaSauvMl4d_I`;z@JyY?}7DKK`^(xUsrkx@*LZS`3Av&w6{`sFwfvyHvqRH`O>y zXLZ?-d*w+NuJKTa!tF9IT3s-CU*Ywd6xWzr>K(#F0}-$4TT?Hc2br|Im8GuD)r)OO zteI!=1&u*9zwv%i ztwboLZfvrvtEY>=ZmvpI3l>ubv`bgfHP7R?oCX}LGk+zYhS!TDdUmCg%8bzdn7Zx_ zZtHhBy5ARC3+Pg4hh8+Zse9i@%cS3p_sC@vUH%Y;j{2YFEcduiI0g!u*v{L?c2@MQ zCmmc2HFs5wj~XhDl27S8eZYxlgpWC@ z8LMk@?-$3(8ruX&masoB2%^8HKD3@|9Q*(eSAkn}-;yMmr@oxZ)jlfGp{ zYPUp}a}g~GBLGYJbUgMg2p<8;H14dWnJJg7bj|riVpm_+`FtU<(CL55>Sl^&b+X$b zc~tf*>7Ik7U=#@#MT0DVsv3q{bW4oWW^lZ`u7y~p6W-f!5--7X&&DeL0lX`BcSV^J z*@PMCve(Yf!X%m)|od-j-wXX64qo4<+FTjJm;K&fg$JrsthKy1d&jD1T z{1rRj%-$Nc8ET^A_k!nLa%Se6N{KK>Ah$%u<%ix<+5G*7(6pxjDitZkKwI+zC`mh) z+3ZFFj#gJ~kqvgAEd>VHjV3d!8_)2u4^<4{+DyjU-9P0EREyquuE3i~ORb0aegV)USxX zR5T*QE9%-A1q5`*XsJHZy&W3Y;(j|1Rtt_%T*rc>#mkPruKETv7JlIu1{24xrl)sx zL9M!Ch7u_1+w`jg15%`QNS)U`B^0JYR&(>e6gJ}EdeQgGl9nwvy;QM93N3AFf$&4t zsa;Q?qZXcDQnx6~3ZI82;?AyhMMqaD4XdVOv)4nbeeZ6Zg;^XJQ2gwaTqi2z-DBsp z8XZ^)##C5pv|kygsJ+c+t1LQ{a{m!{<5SH0TA(1a@lroUzSa;J724bESejl(M(~Ps z+}8h*#J~R_(oD{>HX@yTo90rHbBc6@2=$$@y3`0yum*17tv&E|meb56Bi)>I^-p@o zgWHuYUjGNWwiZ~-0F<;wPq6ij#j>SbL=}QwC8ZL1YC8xWFjY7rsxRA_X~ek+fQ zc85~m4qN%Yx_q$MQrNlz7ZLqvXZ&O{T4zAHE>C>oH&}9nIDPPN4-sY2d;MnkdCbu_ zZ8Bpm1CGsg*L>v8@Q2P^w6y>csSYc(Ufg_1Sc@4p!=Ijy2ZKUnR3&FJvKI=9T(f*d zZ408Ec4ay45}w1M0$7RzC?2fu;Tom$Ue|MEjZPketrIsk-{iCmo!_yea}CW9L^0B?T${@AorU|rc0Xx&j7%3 zMLD-ALbx4m)jA+RRYOdpF+JUAeFa;qx&?o2Z!rlt?k$i$U6#R8QBZP=cb`iGR*OCXsDek*g3%wJ(TfZsQ-a?Zt3&NrYN9?Q4F z8sW1rOa}TFT789=_KYKdCzP{m=FG;$mt)giIoz4Wy?_ zu%7+8W?n6cZ)(zDrv~gXq8|gJSV!z8QlEYAKP5%%e_+vQ!-IcY{+{=11rS=I1}Klp zc>y9UH*~K(XH|jI1WXQ|)^?(a{Dsyt0Gbx&`m9qXvBP?uLNfZf z^9iz%L{Qk%j7q4?gsmE|nE5#PSe1D8!V-e|b&bOi*!8)ofsj=9p}Q}x3P!fNBtA^}f~cSLI4M#utO)Ujxa zZ`;@|m()Gi?wfV=z+@r;wdE4O|1P|_0YYYKXP%igxu}#Q9E%11dBUXAN z)#+I!l)Dmy8gNU`s3jdWX-j+CuDrG3y&@z^{Z04H{nxvx;6R+r79zXLiM_>tw`V|+ zw(n#A&U+vSnMH?Zfa7D`Okw_djn&-@g6xNO{*O%n_hv!t1qUk`6^&N+fE@FL+^SdG0$a7 z>&b8A#I!zM))lAQM8o0Wu)sc)%>=&qi*R1Ko7u#&aT9d=LFA$bL89FNKQ11rC`j#@ zl<~pz!CEGEnMY`MeK(88m06-bgZc>9gwpvr_3`aPyj+eUIY(Iul<(K#bLq9ID?|W> zm5JroJO;|;HM}{wbnlI&{{h18U# zsDw~R*%{es-gEmtf5ZDc&-><=ai4SUbFS;0bA7JQbzOJL33Fqv{Q~=8Fc_B!iC_tS zyLi9}_I1ZA-p1bUl`$Fj5I|{ECSDbkOf~&!aX8t zk2)$pJFZxF3}0p}|Bxt^qAs1UDc~!8*h-AYOjx<=IJVLdQ>ribP*1j44}Dt`m7y+~ zqAZ!LB9WjZeo0X@QeHSjPUwuRpr4F@H=5rA#qS}-=O}r|T!iPC5V!6T&2hVTLJ ztTcwK)d#H9KAcp2Z=uv-s?b8hKQWfCGs0C9vE>A8nSpGfj!eFebgmXET@9J4Dsfp! z{32dFPC+b6UMvbPdLAco4l5Fh6$+FQ3XnbGf;@au6hRa`pn8}~k;jnkWw`61M|07c zaYEnH5b#9vyP^(i@EUBm8LYbNExKxdca+J|=GNjP(oYlVUW82#%^_QCu>t0uzFfX8 zGC{?N?qjs;N!;;1+Ha%YWobkkts@|;h6oX1I{ku1S0>1C|m|vePF!-I-;t8aL7^x} zM%?@JR39PdC(mr=s#o zS?Pup%9;PjO*A@OT$DyMXi`;*MM~HoIYK8HJ(R~~V`Q&MqkFYAtCSUQVr1Qf1b>^E ze9_lE%)&B9A_{YI!dY2S+}s@d_UY>CYH4X{YHDg|XsD^FDJv^0Dk|dfcpMIg!C+)% zWzlFfole)|G(8A|F~H7Qnp=U#|IdFgt94d@8!`(f1byp>JdX_vRv5P)=dVg;v5P-F z*!5uVUm`BT3R6)q1_GZcj4>HUfiZKtU>MlMp4u~V>z%9mGw{E1dqODDzs)nCW4(zw zY2&?5zku2RjxxC_K_7=}YHVTaq4U6z<=nq=BcNkHVp`~L>FGJE1&<#5JU4eiavTe; zfCOeU2$OY#;<(7fcYB;PEah4ZP{LBMQ$}EveGD-hno|2$L{C zT~2{z0$N^d0; zB``Ch*XSz5Y?m8Ebds;;Zzg7LIA!OmZIzdgu~%lCf~|~$LtV%4vMA7k9Vf?e*xMY* zkaF{OkmcOQL2kVch7 zwFZt)E~OZSZ%hugbMRuFO`=aTvx&u1@N+tGQ(cBP-?`g|d%bMi*Oa`zUk?Va_v)_l z{9%VPte;#TE>1<8&o~+HZNfY9Yz$Aj$Y8w?>IZhQss4gDeZHc@5h$C0**x#o*IBn4 zgFeCBD)iH7`E;L6VLOM|MK+n8=9b{$wifMz6U=czIm#j99jt^ad|;jGgm2968h@|) zJ{fmg?C!1*4Ho+Zj8npkO8q-aRd-=5S!yftRhePB>mur39jlTxBCR@!LDYc&ry!l! zXQ}qkVctL$q>V=GUXV?CMAb|WjNQrjSF>oE$OY|yb=`B{Tm|i1TmCu9*N9F}zTn5t z3zNTf46PE-?qJE=PbpZ3Un0332N6S2;JDwZjPXkcQyBp?47L4%ia!APpWqhY0aQEv zSlS2^z>t|843C{NaZThjxV=4yB-*bJpP%}l-37MTG3{AFC0TU)*=!r-L)evvdSj{5 zXXB@u=052F4RC1Vzgs*tH#44Rwl}~luQGRO*4HoM2EPn6zCJE51HLnq^P3QyN!SNk z0ugD|$=vT0(7kDN@K}Tz^C(oeX5#nb&RP0yRj6kkxzj zl|xKCX$u9lAroC#xvcnbBc&x1jgm)4n~cbA!12RtCx^bL@?6-e7s;>k@60)P_srdq zz^&2z{Hyaw$n_^+1|!^8?)C2u^By0opVB7GFFJ~^ywf}5y(bwX<#B7o#B$<3O+M^M zck&6D7cz&Y`t=P?0jYN=_`KGLkkR;;sXmH@AFgILbsy)lKm>zjzcozGR-;TQ=3}c2 z#E%UX2#2}y45t(eSFk~P-+emQ7x`lguL`TzPu$BMYvBk;sRv%`^+R#h`Oo#9Z(9U& z2e`|aKucv&@c7z%>8H`pT0EYvN;rV_MNYH^x)(h`J4>zC(WsUe+=LNCQp-rxw&>{R zYfm_Y&|s?-G1>SKJ9>Aw)#)7xM-Dw$hC8*)kY`IZIN!)13L$op)Zj&*7F5Ia<{bOg z5+(*-A!9eA*E%O&)l8L36tl2E4esi@8_QFhr6m7o;HIb)=cd}onYQ&J;Us2mJ*3mw zn9jC#`}5x?7=TtrGdX6}B7kI>oLs0pwSQvVCwog2J% zM4Ao+lvHwWVkEm?)$tH1Bt%<~4sBw#p27!f3AZ|q&w;y3M#Whpyx$a0SeZ0V@N)uG zQT{#>xN~&0T$TNP5d@w^4z$Gfgj<8dFQwv@A=n|L59II*ZbX(kk?%t*)=sMVRFkAD z&1+SWm`j>W`Mobq2hF3`K!k`xt>#L*&-6R{XDDfsNr7 z#6e_L?%up4)0V~7vnzcWCai1u&Agr^T~hi(X-Z&xADPJ*cjxKOBQ>M05+m`q7fZLr zOrTxP0F2HtZ1OJ)YX<|z@XWFd+B5#5IcGXxiv&m7<&d#uVZpU=hd`zoU&QBFUXQ_T7X^jGCdM|pTHay$rER&%?)%Zq2M2HISG2V%~Cfr zD;?DVE?HuyokA;AvvuFkBW1qr1Cu!RDfz8lroQ>oHIr)co((#kzW#=g?k5xHMYlxq ziNC%t>j9udI?!qsKi?mjO*hL8^;~&e+?q1L3YzU{6DyzkcVnW0^7A!)dOm2#k&+Jq zSw|5`D{86*Gn%oRec78UQ}Xr-nF$0=u!~M-zb=)eX7%JXHG8~lOO&(444NK;vqL@A z)33|gv-q$_qa&utw@lZSZdexpJ>FBIha00_t(7^Q4;t$x(X^p!*1WaI>9+J;K1CJA z07BB@ULg9P$n#HN{%=i3IGeWIsAk^>xJGS9^?g~%+doH?!ClQqaVqjp`@IzJkY!~P zJBu|TnI1nQWvc|t+|T56WOR^cj%vmm2F7G9)0SK`MNP`yiKj#m%yMnRH&#?r&`Hp6 z+!~OEY|38(D@TWiGz54a2tbP@yf7oYJ^3;5^)JYj?P*u^Qy89_%)Z^a?FA3Bt2;4% z4uoIJ6nwI&-7Q|dwcqo)tJfqQ?2bRX-ng3t84(Kp(Pp}2Q04CR$T&6UmIyJ$u8-{n zjd$*Y&RSF}G2n5($E;&>+%BCSIRHhBGBOnv?#=Gw&%+@ zPQ_S*|F^c0j-O0yVtsGQgF-!nSe+!)H+efzs#9pO zeLd|PbSPm_GpRO_KVMp(ryKtJ=eKEbC*HCx;~Xd&2^5NTYzm$IRQAK?u~u}z@|Txm zq#7twV=m1pxIRBvH}QG%ma%P@i$NhYJlcQf)$_*ly$iyn4Q8$cYgJ=L&}vEc**NDx zA9Wc%aKrZ%!JUpU)#0-)F7|#a##skj&P`STWGuNML0?^7NBbGW zJ#j5baq)Vc8*F93JmOK#)%<;ZsKCE2P10zzT5Ai5w8wx!Au#WID{ykAKjS$nO^+R$ zLaD<;Q1ZaUgQ){WUDegqoMDY`vC1kccgpUhKq+$)$;DvkyZ86V^2(@KdI?*={-&X) z-0lDsGThkF6{VS}HE69!Vn9?tiKahyRfQ0Er841?N!QD6E_ZfA5_ds;&D#04E0TZ- zu~VWOylhwA{UR>i+BD>JK5C&O=F0+R;$G&=(=T6Gh-HJDGr%R)E(=%m@;qfc0`#k& z{828r?cg%<;n$5{ELV~n69Y%+7vIHn0VQiuu0bvu?h6YGX*b(jYd8`fq84-`^D-`; z0&p-ywh%m+UrRd|x@?@#?Rvn)g|EG?0mnV0&9O)0{uG zmjuNYqiCgu`JbvwG=ot=dZfjt%az?VyzpZ#V9Mx@#i8&t?LNy*Wc5@`)cx)pl~qac ze-5)l)THma!nMoalS=AkddZ$z+yOSn6pn%k(UBv0dJ5|U0q)m zaQQa^X(L*$M!BRBXd2Y}uC7@Bpf_%7YKdR^=AND&uLa;OLn&Iq&pz@C9O4+73J}lC zqPPqYx&}GubkJ!+!7HUc$!?B}S*6n}UL;n3n!aArk`TrKg1`)ql*2UzNkb{;)7LNe zM7_gFzpbf~>_LO2;!$y3F<~Rl2Y!jf9;{7IH8nM|u~EscRE3gtmeCSLz4M68aWP+| z5aoke4W%`iJRw5>L6}XCU<@O)u>{9=LI5J($kEf-Zk{VRvhF-%clRFHf+qEewWcaI#UjFC)V%Fa8UvH8{3?m2=L_cNxery=nyR z{YSD_g#q>K^rHkqn_ZCPUZRto$ zGW~Y*CQC50{e$-gT%4TogCyz|w|~-m8kPm=Sk#AWmpd-2?TtXH$2V&DpG}<&Xi>yR zOX+ArEQzv{|2R;n%;t`Z^O*I<)T(CuKxg|N_EKro$IZNL)sZEG$8F?YTU+$q8sr)O zA+0X;x(1 zs&P6L%T^sqQ}yuXV#kXqC;_=kD3t>IDL;)f?oaE2SA5yg@6a!ri#`nk-%xl#oI&!F zn58xiMBOAV;Lo+^Z}&!-^g}rnTStY!K#8e=b*y+Y04gDr$g zc{!+DYceqcD;1pIH)eblyVo?ZR#aKm`ZR9ki%U!l(ih4%_;;2%+1=3%-F~n9p6>TD9_68@mi`s24SBHR^nsL+IMvRjVuLk%*m*RV#^H zXnK#Cq1vFug|Z)6n5W9Yzo)IP1U*KXL&*zggJ{QAUf;jy3o%L zMg*Dg))eTZ+Z{Jz3~7kks~iPV4~8?GYH?$VDI<(SaUPX|Pf%j7tP~LB4@Fe4LJ5FL zK12M8Wl?d@Oymo;HEGMWYA~*fvg0m|!Iq!i=zU&r2+mK18(OjfG^@Ib{oZ$xT0b?+ z$Kx6P{b3Lbd9UbxSm`G(<>ldlI>ir0l^l+Li9~B$IphSai&S@V%Xy#olhrWJ0(G;` z*lP2xe1kXlO@Owa5IQj~6*SHVi)g7_4x@8p1&U#e>uzFs1eKu=;xT-a-Z+4&|c@-3};SUx<31_P#3CM^0Hx)LAI=#2;p5;VLbk6=D zbVB_;>`c;`90u2SdMf=UM(=3$I%|bZaP4v8*IyM)(zppjk-e3Eg9{&((ws-lzT6K4 z>hzEo*x;d(H~%&{q7!J}5TpX<3x*B>{$QpoMI%7j(PNAHeB;vV+fe%Wrb6De@fD>f zD>pv$o47%VnCi))1?~6Si@n*#zu-rFp{AH3Wm5C=;xGJwex)#k@yTh`xA3~ayN%b#*yw1}z~)()FkWg_=}W?%wiRB!6e4PN*@ zetlq)2z@_MI=lFwPBYCVHaZ;xMNSDv&(W99JZON&IC3h2l@UAi#1Q({?Br+Yt25Gm ruR^&nWgz9b>D%B|{l|VK$pRZTOw6FuwkyEb<1iDVIicLZE&hK1IV)ld literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/buckleshoes/standing.png b/tests/rsrc/bundles/components/pirate/female/feet/buckleshoes/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..3e58c5eaf03b8e01b874be0b56d6064b157df269 GIT binary patch literal 12001 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

_mi1(PUU$3!P20lt9#M$Y^G$w$X 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 WazOOab;bkWPeEQ)u0qB*=>GwMeP)vY literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/behind_back.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..e97c5124a3c85c093e35d381ede5ba1dfd98b47c GIT binary patch literal 10916 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/standing.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_barefoot/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..d05f58e8177767c16a3a8675d0d0a819f6dfcbe8 GIT binary patch literal 11005 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

x>R#AcgKP~Iy{i8MC=3|YpHWb|+k2N2#mSb) z$#wp!2~GsaOZrp0&&4th-_p}ZNImN_^k*~aykcxawD^U{8J#HS1AI+FdV9*DtSk zR)7|GwLh zI2Te+qfj6F$i~CaAQnVVy&oF7G%ntJlRLn{ocAE)R9h=_hs?Cc)!ULY$4`M{52Ah8 z(beg}f_jGj7^p+sye#H{Ay(zK$T@zHM4UI@-b$~NR0jgEvVi}$qxbs&1lqL!wJ{I) z1ocZmcoZj)YZ&IC==r6bx948n-~=r6oQh12noeUP3f-U{Ajr}}D;-S6Op&Dv26E8Q z{pKypZ+;~h9U-+q@}-dx^K{|^{!2$O>9{|5K~z7bq%Cyvm6%cdlU%j~eBEz7J*=&& z^j5a&H~1_&K9;yk@UzyP5`0TJR;74sGYs;9S83q|t)U<8yYBGg%S3EKQs{L<#QfLs z^>kPM-Yn&0`)-{+oh|rv9td!W!C!SZs_Oe3rdK5ZP|v(>i(2wI zNToJ@mZPlCxY*d(d5vUflz^fvWZ3+C#0+(FQAJ~}dvQ6~c)12AS_!$24d?uPY(s2* zQF)$Po=8nLHmSku*@>}>ngV7nRL#BKP%)XkaF%@fvR4-6CTg1ngsls@;BI7G%%>g& zCfU-=CQNHjd~`4VnH41S8Y%*Z+UMs^@iAX)cJ4AcSHYyb6ar-DwRShbG3ZFB6=^H5 z+A&Nk#%HdX-Tjo(mnM1`q#1fcdso*SK;FX%}J zvS{JCX4t-qd-5&?MjB2Ni?d+d?EIu`$pd){sWzkh&GcdoC?42>yc~8p{^ym>yDk%&LyZut6K_6}ge!%?|3>h>vf$QwtllP++83Y_WW?95|g(Z>eUKy-&r9agkHMEnTG=b5P$ zF&+*9!5s4+i~Ic6S^sLC^{)tl=0x^KW$X};Ax-&$lRJdh8guP7exuAR--hn+>KM>~ z6`s8f?-)aJPCi}98x(E_u*%Dkz6VO)mUXYs4@P{Qlf-b`7_0 z6|bcKx%6(u&>*!jvN>~2Gut66Wz~xs zIW(z%Lb6+{4X>S>kk27I6I5+o>d=YFiV$dmG0dL6Tes`?78pu>l9qdp zZ1@sX{m3A0ofByn^=RTG9%#SyRPzxCQ~_i{TdU85_Ncjw*S@TXcH(#eTv`|lKV|d| z)SD&40?5e5Lhzm&SsH~hH4StKGdnr=q(s`^06GAq#l{a6!~{g{b+uO+fueEXJaPQ! z(C4M4LVSYvj*(~xtDd9XNdp~8>+{29Mt{OD2SYsDffVHD7i4WmdE^~@a5#0m<9>{! zX!o)pFZN+Hj1;Jmevz& zm(-tLjmBtdZ-)((CrMOl#zhfQQ%;-<4g>vNd?$LvnZ^+N`71GGqqw!)bs(~X%hM*D z1{9A!hUp(RjDF1P_KUfACa%)e>5j2b^ZcW@Im1+-@ngAEZ@F|N@k z-BX2~AqP2_ToIA@Bgg;UdaLd85|6!^1JKEAGtw|+-**jox3n|`(+OG}O#YEXJV$ZM z=J+R(Pwb1l2_~sg*5NURo|ePD9u&fNwx)|KGl*9i;^a|L>`?`zO4C{BGR##B&gF0)`N+=Fql|=(NB;zYq=pduZ&(GLZMbckAsT a>|Jca{hO86;^3Mv%+A)4c-#8$ng0Wwn=`Zk literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/standing.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..087f8d08a07432e5c6dcff89fe30939ec6d7bf9f GIT binary patch literal 11466 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/walking.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_boots/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..fd6086abcdd16da2f733a8506c8d12d5b0154072 GIT binary patch literal 33138 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

    EDsf_&0CJCZk!Gkfq@B<1% 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
    K*|tbo2#_C3 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/behind_back.png b/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..0c631d033e5952b575dd3064640dc7cc63c16513 GIT binary patch literal 8572 zcmeI2do+|=AIBe;GNO#>G72?@C%Ggzu#NTJPn|{Ij3E_HX}Yt-a^-yL_L? zW_oQ|xM0Ns1VI+kX;d~Gc?dEO!KlEeL&0jt;Gi1e?CFdkRmTO>tb8~pgwoia2$F^( zi0~kSOaeHLAjn=z1R3Qb2&o7`@Nq@wPxc~+3c~d8b)!%yWHQ;((vnGFf(RgwkXLT5 zOtDG2Mt0*B#+3?M1&9T*-LhiWVz3814t^}K z6HM%$00}@IFPG3I0(${S1VWN)U?_Shlbk7Z z6oP#qg_HsWU?6&+KeE3&yj$!cE_N?=H*%My$)q9D0J8x3etBnDXJb%f8LJGW10Vzg zu>+NUl@-1fS=20^HE(3^NONd2$N;hfvH|`;e{4VBfzP$#4kZlr?(WTS&7c}mK_;m1 zuZXgXnn<7MjOx73yRc4lzwzVIC0kZte7n>W)=&a1u5hd{ziVTM=sBnmqJO2 zUCVzM&`-i|lJUS79%yBD{zSW;Y?-zOYdXCBw`=Z=@fOK6ea7+yD?WvSU%9eA|Dl^6 z%?H*W{KNzL8mqALwLMm{sJgW0oUu9&DF+Sy5CZNn@0XCv!c3yM#$hZ2KNsE2ZS3Aa zG)P+ww@JtOuFtb(@7{XPdq22d6>U6|OA_ahO17h+zC_M%T<|VPKC*Lic*o~wfn!g$ zy_2%~o4g-1dfjjE>bk*@R@0lxsWlbUtEVX!O2`$3j*|RMrH3};?z8?|glQbxAi#Yk z(@oFaYKiT8?$>5!kHqCt{-)EhYm+wWkT)zNt;U+@Ypzb~W9uhygEXZMz?^ybT3>Myw6IOkH8LlO&Z zjzpOy>@wXGvL>2?hWZ)q^dWM*34ZGquO}=t?DiXOWl>}~M6U*mq~$IZ3p-L989 zUpz%F&);-5+x|p`?Xh&5?*;1*C#>5aX%-)0%IBHv4qg+rMc;G%QhVYebeX!&G15tY zqo7p_iKaLUL#@>~wI!&QiIbC)qoX54u`!CG zdU|>QfZEi=7z9y564_opaQavNAURf2FNM4f^> zxPucSk|QXhM8z`@0TkTnR&{4N%5X5~~!3f7iDz^N-V)_3PZyFe<88I?1Uau0BDM{4%0Ni%k0o-UBURnd@|6&OA;~ z-Y6d48e>#haZQR}v4Y)yi&)a?%;#G4b|vL3bB0cBy&QOCqzMsXhp4Od^DPa~G*%Sw z2}Zn~{EOE+#-{x-DphJ4Fz%%m3R1rS-NijY>BJL|!IS6Tb$AoT+X`q8p>-@SoI537 ze{<>Xi8Rx^{#Mz>Q$2bs~_N}RmYV)_+ zQ*9se<<4yc_L$-7DhID%>>8p7*mkzt?UYl4g0x$P;>v4(6n!PeO?9pCaK9N5M5A$(geHoccPS{%v6+_e^h4vFNjzoG@bSf z>!>P3cNasa)N$u~$`1`Ny9MkXoYG42uI@4Ff}$Mp5$=$#{~JBug@%!(c6yM92ZeeL zeA(DA_d^qeCF^0$i;>FPTP{^FL}5@+(%#)B-q!bKz*NJyV{W_XNVS$;U2WobYF2hP zLXlaIqK}TPIrngb=e+&Opu?(D_iCP%Ob5=~oX_&VaZY8<eoHuGc4j{{A zXgc1qsDIPdDVIY1*&Iw`95^o*nM&^)bj=yW@W0M<&d>`hF-pqN0a_y`_RK95O)0d) zKTSJS$Xx$nnX3}*YJ0qW!Mr&nG&S(nGe%ElG3yrX*rMf$dqIo?AHXayV)W>>oRv#h zuMECnAV%@WSHAVNB_xNwPKO)XaV<}taujVy?z}l8EEVL))i4C2`Q*)+ zwsF^+58J*-XYFI!`VPmG-#gQ8E2q}a9zwqeue)sNx+iFlOZ^;?SJ0pp*2$0hUi)xc zXLk_2bnw+1n10PL_gZOpHBw^z4ns603=>$oD-?aj3y=S^*E~iH>0WJExk_^K2EO(~ zLNd@&@BDX*AqqQJ`Luq@=f!@73eyYo$>|g0t!K=9%D?2{xpSzNB&Cb(9WKT?opgfY zki`6#!oDhd$Ng!GZ|s5XXY0iG@> literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/standing.png b/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..e50ac6d634b483fc57ae6943b67fe98fb67cf01d GIT binary patch literal 8456 zcmeHMX;f257Jh63X;DB~M34Zc2_zswBneA+V1Ph`KnP1jkRY-sinfRbSt25aMS+M3 zXmSul1Q#>{t$<==&;|uXQPEag#VAbcQ5GFG;Z23^fAeR4&6#eKKUMeDd$)3K)mPtl zZ{-IC`s$!eP!I&^_|d3L(8fWK2Bf71dU+hp!=O=5@C@*TAnB2enc${^Le$wvF{Mq$A-5QJ5^c9uP{iqu znXX2ZG0xl?1LAlr@;pLbND}az4sus#$J=aWT7(6mL&jrghoVM)jd=Tj^-LDneaZJq z5m~U#oZ)NcZ=qxLH2nPo)~iame*Mar6${a$oVm|2v(F-io`lOEg$>>g>c2|wJnP*o zaz9z@Qof(S--6ruVdKOL_Hd(LdxLMw8S14H*NRwd;#U05BwR|I%@z(eA;e;RrsE+u zW6%Cj`CaCV8ZT+J=fx_|29f)zLXvQY9hYOB6mAvGvW%pe1$vtJyj=h3Is0RO*xQGp zgAYUB+++QAFXZJv7!Nxb584BITIgL@>Ay7lbu{_il+tco@M*o^(^5}uK0|G;^gJ(t z>nkWVrLK|!(y@F}*&(9fpmWJS$Af!U=cGAg|74%O-EPk|{BHjhL1ZI$f&s}^&knN~ z`#N%@i#c#T;O-e}qli+?CmlUREX{R3!gV~b%`R;#eisLu6l%4>Zw13z*LIB|*+vh) z)|BSBlz5nYoN2)hFlUjCD7Jd`R*Qb@3VtS~-8}2va(Zp!DKDu6K6kT4E2HTCx}@pd(aEf-<32>GcFSt<5hrX|~4 z$C7B|hSOhVj54uUw9-J^$m9nzeXXV1>L?0@;_mM5>gq}+lZiwkfk1F{bhNj($K&y~ zwzk&R)))+C*|KGZhK2}&lvj@f*r-6M%)k&}e$PKBWI_|18>ajGsGh97;@C-sCZr25 z{BlVh%^Qx@hM@^TLQDFUYFjxNNT;3S@CPYOS zE{hzS@!^!W>CL-9QP|=C5E-`Eu=9YMcK@OfgHe)#Qz zB?L7z4|_ScN*+WHLbolj*bTr|ia9oG^jt)J>YrtGauFDp%0D!!F08>_B` z_Q!LEDXpzn&*1Kff~Hj!4_b)Fr18@&&9Bt7Z06r!caCKDpRH`u#sL%M^wv739Z~^v z)1}HIT*+`sUjI)uQ<|*3_r&z#hhKo&=@z=ZkWC_u>PhK&UAhsIwxIf&K+~l$0$e(th@lXm*(%0pC+?fYik_Y!t+J0&xiswf! zV-|iePq`}TpbJ)jL3gM2v`BgSliV6HKxW*#y?MnoNoqiAEyXDXm{N9rA7a~>ZWz1; zq#k;kx;6dn05&c0Q{%kS{WpvC6&Z*Yy*+G0;?G01oj`b4cIelRjTb)C!75_Im&$wE zUBU{O7U1hsE%DhkqYQsVt`dvqx?aCkqVGDVrmh=&bEKAk*izvOOQ%RitFVEfOX@9> z{#vHUX{fCw92Lxbo`a$RmQ*G`%9QV~o#<*^#JuwCw7#PN(>0-kTio>hy0tAJr_UV_ ze4TlpH|!L$9RTi4qkQJ*r$xVH&y__298BUl;vMaei%`L1=4jpsyJN@I`;nFTCbvq>zW*edyh)-#yWVgSstMR+%Fz8+QPC) z17PD>Jfg`E1b{J02{8~4WmV;`nTS{>cc;&zDo6Nj??OwP=f5q`h1Kmi;@gnAuxOr5 za`98{Lo#`O$Q`#PY>S-%ny1Ac`{!h7_h?A`Y1bfu7g+w1=sW`_f6>?NQ(u@xstRH{ z$*5%%Xh+vhAWj$xK&@B$vc;2jYb0peejON8=z!OZ$U1wc8LMJbh|QaS$Zm18yL6|CMpLr_uW6X?c!9Oe*&p371|378G{ zGi9&Of00oCus_`=XMRW$xYX-u>%ukl9(%q{_Y~*{>*y=^@gcrN;xshfJCRwiGF=1B zqcP{clKQ*PN7mmEc9p~ffR)B|CoIooSS^xEdEgtpS?TTgdA5kXg|?qq*~S)4tv-Peb#AG{KFA#=slz zfH4oPbKv_s%z?JHD^oZ0!W1L#CSTl5=+Dv%1H@d$?&y-iMJixs(d8eM7hL}rne9TT YRo&@SVV|fQ+{r?I-htExub7;F1H)pr<^TWy literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/walking.png b/tests/rsrc/bundles/components/pirate/female/hand_left/barehand/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..e55edf3b278c7f1cc7bd98c7ff199138d6a69881 GIT binary patch literal 16925 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 Oh?bh3YUNeyi2nj-DH{d= literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hand_left/hook/behind_back.png b/tests/rsrc/bundles/components/pirate/female/hand_left/hook/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..4b02ee9e9ca69004400e4a08caf40157c2a59a98 GIT binary patch literal 8619 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hand_left/hook/walking.png b/tests/rsrc/bundles/components/pirate/female/hand_left/hook/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..abfa19304010c2da22ae27fe807d92e9a963b233 GIT binary patch literal 17338 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 JvAWH}{{#4Tx3B;J literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hat/captains/standing.png b/tests/rsrc/bundles/components/pirate/female/hat/captains/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..8f91ec1bbea7c4c8c83a1ed6adad8050a817e6e4 GIT binary patch literal 14904 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hat/small_feathered/walking.png b/tests/rsrc/bundles/components/pirate/female/hat/small_feathered/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..77a67592e02e78b7a47f78b6f3d6cc0582aeb5fc GIT binary patch literal 56551 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ⅈzjHF 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hat/tricorne/walking.png b/tests/rsrc/bundles/components/pirate/female/hat/tricorne/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb3e2b8d053f3c30af007cebfb55f53986e54ce GIT binary patch literal 62437 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 B?xg?# literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/behind_back.png b/tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..b040e81904ddcf119323bab52da4c47853e340d1 GIT binary patch literal 16552 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�cvDOL z@#7l0`x}(kHA9Hk!jpkg#g?hK`^uv%q_BLe?^hLcM1((tpuo{=T!gV@n#FhpVZMfc z_!NB>+_D0+w{4m1pnci<k7~0N~`;O z@M@+T2X-5k^)%#Xsu%Dyz3(6WF)jql{Zwq%rPrVxsLI?-yJIY!lNrT?0>)Rvn#!w@ z=0oB^O9h6LIrnZ(Koo*<@c6ZCo)#4z2%&t@`1b8#?PPI>9n+S-XPqW+VkyYffinBC zvgCa4b(`7wxr@vUzZRI7XKH6TA=Fw8o zpt`T$n;VCR9*^8K52^}lh{D7XZN!Ou^o-~QR zzwf%-9UB|cNv5vgU8M0?R|0k^scz^drKz~XK*fr%Pk0f+ou*g%`>@ZW=Y^?d&O#R| zn9R`-=!Hi7NVWgDk}&a{`&~a>w4Y&rF>dB^E`7g6U-7oI6ty8TAnysBG{}TuzH$eD zBnuPtD2>(e@bWnS!XRv6w4(L5#t4B1*a(^qOi(~*)lKrs%UDDIN7{%E;~!z8@T{mr zoG@UMA9RDCtXqDE?%&k*dX(t4miSQ%ci)_WQOC@a8K9Gc&qLT^=!;$M+-5bmbLDX3 zG{?A&MnAXJAD;#+N%h(++|J4)*!^jF;fre)K|VUr6>U=HyDINb%&XF337&?;S7}#) z9^HW)dEl7kf9YAzf80D!CHr?CuKiCgcqka8cqb!+?VDB_@KXaIO*I|WA{FcK{{y2K Bljr~d literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/standing.png b/tests/rsrc/bundles/components/pirate/female/hat/wide_brimmed/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..83029db1fc7e5bd3968b53a07a420bd055335573 GIT binary patch literal 16346 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

    (Y?Tf8-KtFmAWUU4gSmL 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/head/eyepatch/behind_back.png b/tests/rsrc/bundles/components/pirate/female/head/eyepatch/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..8f56599cca71680b1700101b1bc0a62dcf58b08b GIT binary patch literal 12098 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 JtyDrq{14z-yf6R& literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/head/normal/behind_back.png b/tests/rsrc/bundles/components/pirate/female/head/normal/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..377c50762986502038aa07809e12e97278c87480 GIT binary patch literal 11976 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 F{{i>8TloM0 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/head/normal/standing.png b/tests/rsrc/bundles/components/pirate/female/head/normal/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..9a38d412ae7c36da405f98a6b2d6e02b6b801fbf GIT binary patch literal 11946 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 G_5T3pi^zWf literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/behind_back.png b/tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..d082a11c7235ce9510d49d72f4f779f0dc83d003 GIT binary patch literal 19063 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

    ebKcGO*S)V3H^y$Qwt7SDYi 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 J#B+<#{{y@qVfz38 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/behind_back.png b/tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..27f03b3ca711127ca43733670dbd720ac2762493 GIT binary patch literal 13730 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/standing.png b/tests/rsrc/bundles/components/pirate/female/legs/stripey_knickers/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d572fe96a44b3ab4a88cc844dabe430c3cac91 GIT binary patch literal 13843 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 Qe{~^nsyZqK%2xOO4t4P` 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 z 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/torso/dresstop/behind_back.png b/tests/rsrc/bundles/components/pirate/female/torso/dresstop/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..71f771a1ca0c523ef35842e0c098845055be9ea5 GIT binary patch literal 14872 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/torso/dresstop/standing.png b/tests/rsrc/bundles/components/pirate/female/torso/dresstop/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..814ff9ee38c386bd3bf6759f38d08a570881fcba GIT binary patch literal 15314 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 Y$1FG)eewzXD3?e}U01DC#X9W&0BKp*Hvj+t literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/torso/dresstop/walking.png b/tests/rsrc/bundles/components/pirate/female/torso/dresstop/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..7cdda709310ebf9c84af55da15561f4daa43b154 GIT binary patch literal 54343 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

    l##uj# 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/behind_back.png b/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..b3b1ba3ae8188916415dbcdea8c04e1d536cea5a GIT binary patch literal 8120 zcmeI1drVVT7{E_UDJ=qPi-XpJxwOOZRh^C~HOoerIy8`oMzci?`z~2x;*uHTUn{-;oSxHj z?&k1hvR%@ID2z2C5)JeC)5KPhsfX9EwG!v-60}iBD#Sd|bR;C->7WqD zo~!%QmuS<{#Y_w0UAf85+T74+gmI;gt<^QcBG-on%QxVzcwZcdPo3syVBY0yl}D|( z{w0G6!ZJUJs3J7Pk3fJr+d|#(v zs7n)hF_sGeeQo3X__2Abc^e9%Fx*WYiA8RkwwnjDD$6TAYS~}TIJKMr?LB;St?90y zFaa>!L=S1t(~pcZ09KZa|1f;S+BVh`4ZVY#l?gMr1<~u0o8WbhzR(24#SW=Z@zy#I z5muB$Pn%dH0Am2g|A?mNcG}L5PXc8vg5Gr@fRU)@WMj%W3|IwL!yxOM3o)2QOP6?0 z-SF9era{2i=aAm2n31bK>I9VAG)lhu0w&}K1?`q{`xB`t;2!InJyp%s)zv<>{V{na z5y8v&0p9#NqX}4qJ^q%&v*oJCtWzA!GO!qT;$sk+hADg70cOwb$mx(y2bAwk zl+RCVEH9Ko+hH3RzhodBlaVezVO8IwO!>L4-LCq%p8{z61coPgWElvto;6V{gc1}_ z!*6=P(<@-a>_Az=9g&~Mf*TAaQ}s#d^&S%0-dSFn?PFc-&uo*!^h6nFD0n!EwZ7U; zgEcNQ+jqVS9*)hS>o$U)ERNS@Q8DcPGa7p;1+0T@{kg*RLi*FGt`|7g zS=3tyh0NYUo?X)-onL<#02>`<^)pQT?Fu<0dK>AVArCG38c`0OU>>M&+B&3eVwP=C z;H_!TH#84@bqA1I%qlgiB4iS(`S&%DENU+acZ9`k5P6S}PdLYhYEOS34B6ke-hu4H zn~92NE#V{msjwV4%xf#4|KB#eq!i3Ddd{}&A~LwGE3DAxGZ-o;iCX)B9#@`Me23Sz z`nzyoaiz87Y05isknyS8`-TP&Z2TibPt#>?;hUQT|6N95zl3HidqCwqvyd6c8kt4}X9TK@)mG$H>0 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/standing.png b/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..a57168116674e73aaf2579fbeea810aca01240f7 GIT binary patch literal 8107 zcmeI1ZA?>F7{^abDfd>W_fnz7F}W0OE39@E8OnQGOIJiuiXj!0ltN$*U)X{SS!Gv1 z*A9k&1Qc;(OikDfYbWt#Y7{K!HYBN0<4be{oim0k;IcU~7x!GIpZ3Yj4_bP^oO4f4 zdwQSy{Lb@#o?~B?`F4O{t^gqvkZ#Z!p)Eql7hyio+gafEDKxwi%?b@d&PMBBS-at$ zDl`~ZAXG&o#MB}*^#t1c2yIaz^uUZzLOVj@&FwvVFC*lGRxMwhrdF#{Q&Uq?Qj(LC zlai7W6B82>65`|I7cX8M7Z(>B8ygc7qf)7qN~J=fh>nhy%jGmpi$o$0hXd<9c>*hV zFRuk&RSVqO+N6g69$aqB%m!!v?}a#*&fY~R6ie4>R#$dfh=V=|qxe-OE}<@W@+juM z1y>{YU?79K>uJQ%i8Bz_rffqzVx5A6QQvyfM1g{&a%nXp*W+RGLy}o;_A#9){T6A& zzuh)-$At{5!3Rd87hbUw8$X_}M$H>>k$94wy0?Gu&4HDtUhf7w9j2`p1R>WA8B=i6 z_pW{($qx>eRb&a{is!W)CW3r1YHWWb#pRE?N@gzsn+HC=D3wYTT5X3GF-S_6g>0V} z{*{D_Q7y5!b2x7FMW>-5Zwrj&660?7XpF@a^py{ zn&elGn2QVPeqk1Td{y(){@aS-&<1~he`!PH_(MMqY;zgTnYj0PJ@>_U?yGIbKH5KW zgG}$o#w=QU_hz_&P`h#m8q&huCntbIQ^pdd%_d?87h3(aF=qd}3HFwl}T z4no%RRQyZ!<~%=b@)U!++c2zYGspmPBR;z=?}6PHXtS2tr^lKJ`JST_M30DK4ED<6 z@^aAS`O7*qyQ*?3q;G+6Ovkf%TTdpO z!Q787LwH-?(?vQ@bZx(OgvTKG;zi5waFY7$;P6O#jSOUKa@Y~oA{Fsb3zD!UErG$S zIz6?z=SA*$GF*s(!8?X^o1(>#opmqh|Hikg)^rhI>!U+MC0ed4-#8m`!}IvPU@K`^ z02GfcD9|6NQH6bJ!L1`Z=t-##EE{DU$pnWzhYAzc9 z_mVTK%2Ish4cAG7*+>lEOmTDDH zNO6y7empc{C~vTR0s(KbT7O#kSyyYKo6Q2P12xB!@>}o!{m6_6^?@S2-ZZ|bzNr{~ zzPa_zRGNC!u*rRnf&nY*y3n+1_z&kM?f>2 a&9ey4`6F;>=@vLaM<_ilQ`f6C*ZczmDj0D9 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/walking.png b/tests/rsrc/bundles/components/pirate/male/eyepatch/blackpatch/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..afc22015043f2d8e3fa4d2f3b1cc40b66c5366a6 GIT binary patch literal 15536 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 Dxr%DM literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/barefoot/standing.png b/tests/rsrc/bundles/components/pirate/male/feet/barefoot/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..9ed34de9ae9ab77ebe93245b8af730ccbaedc08a GIT binary patch literal 12443 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/barefoot/walking.png b/tests/rsrc/bundles/components/pirate/male/feet/barefoot/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..01bc8ef35bf5c3fbb0bc9186a518abfb69964e5c GIT binary patch literal 40260 zcmeFZ^%1A2f3 z94YHwyam3nt==lV1%aw#{qEEff#1)~-l;2rKt4<$P+$lMbb|)I|A0X5oFLGiF$g4- z0s>Jwr4*-4fci3nbbKjkZQ3t&j){1lksjv_S^)1|sc{BibWq2Q<^59@U9Q}(zA1k55%NKLBj>E=(7xz8?K)i+ zU8FCv)36imk4E|-kKB*YP;`()5IPWz3_z;CR_CVXM))J5WTVi*Xk;ML9Bh8!f1$vv z;418D%WsPgLnA|wIhr}>a5N$qaU5{G;kkhfL;Ak;MTR3s9Y=etdy4gnlT?!86yuDz zjnJRavma;EHPVrhNJKaS9gV&SyVwcXsWYt$mJ3EkA<;2tbS(Nf>=+q?ypFm?$Dfg!*v@-dLa; z6k5z)S-{@rMhnIny)-^DzFpTpSk~M9rS`jBv9INQ_oW&70CM@q=yYCZy+>uRT(*8( zYi?d=`-jTdnJIeH;ABW+re2|o`w8Eg{>75+(bR|SVU6WM^~FBb=^mAdHpRh4g}yrZ zo|<=EMbZs9Z!1zn^WuauBKZ@8c%l!D(R&c&AETRX!|M%$%T@ieWxbPGoxORTy=m<~ z6CXCmwbn;9S4TCM2h`_(s?GMQPIak_cPfu{Dvxw14K=_2*`V;F`dvqrTziFFTe)n@ zcd42@$*SzPWmys>8RA7>MRO8Gvg3ubVgyq|`Qp5|f;~9{?OEMzSzN>U=XDR;m4;gs2MVO?f_Y>7z!5&&VODRPOrxn4nOU!nY0_7>-Z%X9gY}RLNfi~9 z76KeyH=W?h{q(KN&xTTYKb7hKo+O*TlNsJ(@Tq1Ld#VcR$*8wKD=G1@q%)5o1iT9Y zYM*C(-Ca&eerNXWndDq zyj-AF8c0#&m3BJy=*ixRkRz$QareNB1)@L@%_4sEnre^?$RW$iKP)n#tU>z3p|xZZU(C>o+v@L-;^>Jv>{mbS|99bZ8u?jYU!O-#5Y*ZlzbES>DXF}? zC`rT%aJsvHaefJ`I;^ym$6=_0)9h$GT3dxq?7jSphmRySnaenceh;kGDSho2EhFQ? z{mv?`H-CPIB;Ye1P_IcW_<%z9ksc{deDSV+hds;6(~vm&E#`)v{y^m8EvlMO{52Q$ z^T0^_ph~JJIK6hGn|lnwH=EYY>)yHOt;>sx&xSUdn^K^j13%;LgqcCY+*oh%BkI<0 z*;X?b@Ykpx^m24TE%rV>Y&;5ZNPyyspxJ1+K@<_jgXav3R|?}lcl#kva_m?x4GaxM zbJt(hWIRGRf27H1D}lknD3r>Z1#2_YVjz+-SweH0Ns&0OCS+Q^5rF-WMGg{KLie`? zGDC}JXKXV?rZg1Jr%d!I?=UQWQ9KWPurF2#vS+@H_?8r1$rlO28s+8rTyU5`k`n6( z!u?hP<79KdC@AZ(o1ynqZIk_qxw=m#Z$?NsGp0&zt`^QB=yztBGf6#xI5QrMf+68G zahhDj894OhBl?U=7zujob~k<%lFBDal(~>#volMI6ij?LMBi5tuZdroLgHuyg`c?c9%7;ozuy%+ zNe9*pyFS~h=HvkmGh0&E{a}QX73Tgcuy8uCk}p@3ye^SlL8%aL^Vki#cz5Ns%5h6H>v;TallS%r_mUR0?+n+1b zmkTL{#SQT+;rZ0_I0YtH+4D_FJ7nZaQXI2|5w{fJ~i)*jO0g0 zQeE|x*&&S{_+VPksZ}~ptOw5}>F)2Zc3Uj@NE@c3f1cwJQ5wPhZdQ9)Y-JJJxI>?& zuJH<46DDg3iNC31qS8ydPH+~ae-1}aR)ZeE4Mg0JtmQO#73O}NnBJLM1~6$E4ZOz; zg2~1CG|9|YrAiM5nLk3@hrO5ydPfh!ezewix1V=Mcg?%G$YP3jn_49;b1vl~KHmxAKjgQt*bbtTB+>e8*aPm5+IZ%i6812QSxz2V{P3( z$mPZZyyk$ME~BO;Gb1~OT5GLbs@6yPvnWIH^iQ95o5!?OE_Te3$_s7{P5d{13CS7grA6(A1rNvg>}c zkLof>bAW533vtWy9@LUPMYVj%-gpHM+}&&C!qt&Uv|Yqh6ASxMP-qvY!*IIH;+ev( zHTB8hFD$!srl7Bsy)wesNI_w%>u`(VMTXu#+(dE(x69wnLueD!2(O$V@K=eiv%~Y8 zc0N?-cC&Ge8b-p%;cc+yBwcbU(#{562Pcl={5ZskMbkcy0QQ0eoX18H{^6cldhQc?$+P+D3dKQh1<<+JDlXYq(i+p z(fJZ_fA8DUT4N(%o>gzEUK`nFD`t6pJlOqxNP!}UOOr~dOFaO*C|>2+A1*(fR>u<4 z(dO-P`zHwHFeU8`dLDRENEj|zp~&ax-A+Jc0d*R|y_ykujAdF3_By*=g{NukpK;kf z`odT={pHSe|8lTa?%FUX*_&!rTjqlgxHccA{xF&EBITET2_44K6V~fqtbh)okE=(C zm+fpkdU-fC>wWv@94gPmWiszDFduZ3G_LzGdHDFG&*olDy9R9h?EEIV7dmk%b?2#^ zZLpx6r9gs*aJ$^tikN{+*lTq{aeM7$M76Xwxb2q_HJ)klDYe%u^JP;_^~Q9Z*b95s zI>Q~lUN>i3_>GYoM2{p8OD=~k@d3u4OSwN})h0Lj-jqNXp^SLkO@4?~n8Uu0P0EVI z>g@&@{mVt$+$<(1*UdB2wnOJKA}?O8`;VPDDs^caW?lgoV-wU_OFWtPKG#=!p|rt9 zKbQ;yLEV*m6VW2k8gvx1Gmqhm-vSJ-4cOiNFcoz?8&%2+O#-mO?_=HV3PxVB7G^Q= zFBgT*^)(Tgq}+45#ozoMjgu?+E>xKB+5eomvGFUjl5@S$uvcSV3BrhWCm-@k62VJ4Au8RkKY zbi76c3dY!@{nv)>@9+1EpFGp)in;N8%gFqLO&j~cbIfHVH=C5k@f(lk4w7stQPmuE zbr4foxdTr*KBQc?Hc3f6p*;A*!YL{wS^gERuKC8^s9$sc^%`4w8T{6?s|zKm7yi5_ z4J+|{>rgW9Q*k~BGg1|Ga}tlglY7g-!GG_qlD^;^91-#G=%|m+Oog|z%JFP~F2MT+ zbKqsLONjW+%KNjmE1aGwG*4+s#Z!p0v9Qv@V<^Y7Gy*y^hHVi{;5qc?OEytc$ojrj z!qad(WJ|!G)rxQry^2<$$y!t0g8UK@2TCEdxffVMpO;$sX+~?gOj>fxCk_%i4hxNX z#=XC7(ELODVP!c>*veNQM@D$=1S_0R%yR6DLC>Rk1(nCfUM|p4A4kG;$IM%2>(?0x zhMFK!LK7f|bpEG|16<&=(!wsD5&j{Qn{uKC%*XevVs{T6r-9eFIoNvJ^yq_v7@{p) ziG$~rG2NOu)+31!1{43Kj-&BhI?Doen)%a%w&V`qx-0?Waw_AKqvb10(&#ZNJ=xtx zDV7*y2*C>J@*)Xv)eDn*QMiW^2`xYWtvXprFbR1j8(4A}Hw0>f?f5jSov3a-G-{B8 ztLyu2?oMyT!ehDsya(U99*xbstklKOvz07m+b}-a&n z=u#`MbiF@B`+8BztAmSEva&}DpZ?U1KLx;2=gTq{r+Q>aw*l7`I0louvvt_sDW$Ep zoonm}fu{doKljk{`4i2e)9*nZeN`YLyaF7$sdUb<5zybI$Hw13Zzo_R?CSD=-1P;6 z9;V#p9hr=!`{VzdM2B53dVRqDjG54Rmj}U>(ZR$XGj{%w&2fwy0uINgBI+f7^cS>! zj>Sv|0qrU2fIPSU-4H$$Iq zi}A0MJ_v*mt)rGv>`?g$oPWu=RXn2W-#3T3l2RcZ3HikTdUYou6^!-JM4dQ>z?~S; z4Z{AhhxKm@Cqd%Z^lZA=uWN>eB*`8p4xt|vlK$_aN4P}Zzqff}CBk>(lGz+B)$31A zs=&3;3Xud;&y^Yf#|ge5q*BPgkR(F}%O6$6W5O2=Tc7GsM*V!RaOO4`5$-c16=?j6uwX06K7XSjt zd2)W9A8%)^DOtzysePD~H~`E!R!4<_5&mm<2zl10rj|oDUsty?SgcE1=(JK_Xl5ku zF6Rk6r@YtyULO>CX$Nmh%aXG;l}rL}IX-={Iw;84{|e2))39~B2~*@F)tVU_Qzc}` z5Zw&QrmryaySZBGk4rHcT9}wjeQTZ!umG3o8vTuy_p3Gf@GX`iqh4sQoeu2FM|m2u+2HO}3h43_|03kr3&acG9&aB54- z$n3^8)J9?uO-OHEO57KM=BLAn+zQ!kEGv3(;H-fZa}73@z1=fFEBHtGY$K=ShBJ7jrTyvbJ|;%}%; zm?6Zrjz0EAj}`s-=ETEEgU@M>jf;KzIBItV@|q)w`pCf`{a4>`A6v2X#4^nzzZ<{v zrTvs03Odm-oqnK3!W<@*1RGLs{i)oB*8GGhM$3EfDqAvqoU{orD6u(lG z625gc{m75gDed8C>Fe|9%gLdukT6!UIlkVB0iS0(9_!D1fV^91Ik`XozR#z)0zdwl z(|&&#Q+HU0zCBBneg^a*P|TT`dA-_G$Wl3abj%W1g!{Js#;E54-L%7L)8sTapp{44<{!% z4G4?U`}j)g$7F@d3nFeK%k6F+mosC(-?#!KJ*mAJer0N%&*5a+=+W@p{9FdcB~e*PpCv_3PQ~P( z3%}+L=rJtDu)TixFxC5r2;31F35$qG%l|uu{t3K>igLTxRwJW*UwrSZPuFD@`#da5 z80^{X75e%HlIAYM*2bcEkJ&o}1HQF}g}bk%#H|@w4wVX3aB_}$>4b;?^f00wwN;-i zG`i08KG|Wu+RWDsN9UB5&s$WKP@9C%##RTqxr!3hpPrtnH|2Ybda7u(u{~2;JF!8L zP$^|8{)uC(9&y3I(?WtSnqOjL`s;6P&-pjTUxq@RR%?bpba&M0?4FN~oO zjw*KZCPXyfuYGe8x0@2H5Dy`M4m}Y%=uc}9Ay?YoW?FJP9u_{K$-O${cJ$UV6DHJp zXsaWR9&7inZMnOR;u5Zf#$wvN3(z7Im1njTC1Cl=L8iXH%_;c16%qfY0}Lf1RhOcinoP$31On^t`TkXn*7dwvZRA zEh+g&|9uNx{NSK-FnxAKwt<(IlUWXD3sDbh*N)P~4LoD$BW$(tnAzJ5pFr>9vD=R{ zdQr?PPri?yp8V$EHqeK1OFDc~jF6fZhKFBfl5rnAZ^PeT2vOWd!eUa?B*WHDwwZ<) z7VUL=HB)80JU4$LrSPsi4EpyPLTFQxYh89c8=|T9)dhG)op0x-W?m{>@zt40pQc!~ z@_9^Yarp_>UZ0*RI*PiSIixuoK@3Z*PS?NFT8(6m&mwSU>9nS>8swx7KU=F=`I~*K z>rkZPjKsT5*zov^sCSm)duGIPS(co&f`WFI*9Rdoi&rfmp0P(bnBFc+E82KyH!l0y-s^lhxaXi9|#it{H(g` zqlI>r6dynGG^j6gK;3;%$eZ)+qaN}^^Y&G`Kt)6BYD;!H)W|MBk8 z)re507^=nd?r>_D;mKz+!vMy7=3m(>t?23D>*EzH(Mt~{a7SBp7+2NW^J2+{YJtuf z2bS|fRS9;)wDn$h%{sHB5Pj-Nig!x+`o-0Y=! zFCbJN0a@;5jj;E1%+xk$^EuqB*RT}Xb^J5bH@AG>;=h%5_G?i`*7g$)1oj=w&#?!` z8GWg3S!VQuqcZ=WUwuPtGKV!=x9aVxV~-W}M%=-Q@p$EZgv7iI?)gN|1Am?$7LxGO zO_nMk8Qy~@*W0{Vv{j%!e}1;NEA5;V-EmuOFpzqK!8LgNR3kfY&c)N~{C?jKgBv{f z4Stk6Pps{+uCa=p>AOK4vqbMsMAg3p`1*U^KDOkuEJ(&=mbWDueI7!laef(Cee~AB zEgqw%u9u;&qN0LA+A&80KwS(RCWb3;Pb_h!d)M&H>F+ErD>L})Mk-L{S%?zB@C905 zgjUS(Pr5~~%I}UWzZYwZ?D|Hs?v-|2@WyB_CvJtwRZ_m#kv>354%$H+*)kjJE6Q_n zsU%T|*6^AEAJ zQM`6Dic1&RI-=z3N;(q-?CaXxU|+ccElPfoD&DVFN4j9V*-T+itkKR<{3WxN!srgw z#`ydFo?-nR2&|ITM1!fBuZx80q1Y0J{o{dXbJZyw&6BN76!l>0>})E5ywWSc=00@a zig`K|w86q&&$&3?yTcqu)4#@jP+n+p*Z0H{lQYn7~s?9tH@?sUWSX|y77M6cR z{MWP$dO0naXsc?at{#D;aI@n{7uI_R`L2%loa}$JZfKMOw&Ufeox zl4|ZW_2MBFK`Emiadmn^4<-D=QHJy2xvS}cX`tGd#xQD`{p3g- z2$f^|9d~Fn%X6=u9~=yowpMb7L#HQm!8g9v5Hb{$*P=SIB#inK1@K^}KDsTj-nVeH zEQzQFSv)buf{sM%H|f8c!&h&;_Sm|(_dTpr(SdHO?2?W%dWX^g&h0#dQ%huQcWXMW zS^@j>0Gln}0Fhd@vR=u+y`d=q4v)<9imQypM`TI}f zSIc&FkIh`&u!~@r><6u_Fi2c7nUJxw|1bfwyr{5xsU$GJg>R7ECzm9>zW1^O2zBj$ z)W#=KXP8q;Vq*S}Yhl#GwEv8z6u1rUHz)YOF#)_ZZN-DTqI|z_dniO4D|+K%Y}k^| zRV^2sKnx#w#L36Y_mG@Hjs7pNV$}>%#50M&#J)_Ir_;y$AF|Wz8sv>eXt7ymRRNfV#rE_yWx`@1 z&i~FycQt0QoXKb&idY+vb8oIZY1X?wCHNJx2C!o3RpGCUb^0pvtte;|CPL%_9j;X% z%YH9j#{b)E?rL5|M|_H5(aS@|FKvf;|L2mThu3`9RbY*R(O)I`SpOrHq{ujDt$p9= zR~4&67r!d}OE8UL&unq*wr`*pIju)S|K*x^y7~w7r&c&Lyx)`Z0=Xn0HpwBV$_n6& z{7-rEpWNm@jnV(j+N($7_|Y#^($_fH47mxy$pOB?lx!L+K$Nh*lY_^7@D-IT;P;V= zIz*xX5c9}6?OL(f&s5_y_zPFls$#85X!M(WLc?32--8(8+i7>Pd{^Pv2&J;W@s(SQ zo|SC8*6s4-5%UC4Fccv7db%uWZ z@?}#|SolkM2HWdOt2NU15eSs8tC~<_!pmnhL#OhCDO^Es*r5yun82K5xw)-%9S+{G zi5RdA6&ady9n97IWaWABVlso`kUy2lPC5{u<;{yX!M9B86el%uk7r*2!_Dy*zdihI z$?WLes+z8U>As!6_5Owp5ThJ+KX^$C%n+Z+eY4B<*pk+ek7ZvUN;4Kscy}eTtL9Ej z{1qW@7y_i7Lvjhxu-gGLQTp!gZffKDSk&l^lf8YJQX1BH*C3YL&X69FefO5yjKPzW!<&k! zp|eize|VDUhT{`8g6J@}$+c$$XcjK6|3uO8d22uV=E8tFH@*$$6;GC~h_EpEOKg(Z0KXW5?4M?e`ixoVupfR1k2*O#jiCRdcj!&V*?Op6CA zJ6hw%O=gtkVGZwEoxXa_!u{32FsS^A{`~w8XB1GtWkJNS1>z5~21;}RwWl9)+n(Y0 zl=Q5NhNV{a_R2YgYKG4CU2DF0*(0#&w}(a;CA=IDk5{V0<(H>sBg6f%n;do?4ySQ_ z8lIg}PMpTsOwqpcbg-Uw19+IK9Cr(^tsm7`w3GlLp{w(#gc!)y-Z??75FR(dsBZj1 z*s(3&H2Ax+@jb%(tzP=tVA{?o#ZX71rzNo#Q7^t2y9l?ZthP``361DpcU=F&;U)Oz z6-5=;05P88$=235mcEZ>P;X@QIRCuf<;MM`+vt`1i~^0mj*eIV8sWRY&hTYLJhigO z=*}8lc+TNby{ne@^Y(UqVM>9mVtXqkyF=h1HeuyNUFR(tz4LXWkVO2@@vG){Z%wSO zxcB`JNB!H9^yQ6Gw>|s?p+3ur-x>NQolvIL`#t6SFOS^8ySlT@K3;e0%0Gc@&!D@d zsX|Gu89AP0;|qa{fHl4nl$VL~uZ(D4kESE6hod)Mj=+Sy&mIq3y?`1B-mIhGVth<* zb9b0tfru(0tO9j;M$$&{R}-ZWc9_7`M>g@Qc**ZA*z}056V&=IUt$IiI=Y;krhO^k z&RqQhMmA#XK2$96*r82~ql>h(zM5V`(m#~G8o9MToLuN1fr(zPZn@9%kp!TGMx6&& z&x*;;J!b|dzOy6I=fllA5sh4fgA-j19Q32vS&i}ZI_5Uxj1zu0Cnu9ZbYNpSo+nl+ zPXO1xxQxK_v^s1P_FT@9IzJxm7-W_|{R!$>JEYYv)2Us%%JjC16&JYN!&K78BRa2f zsK23D>Tusf#5?kN(_F(OD7gLn?shMm!EQ6}6n^JzTOj<_y6%U+CCOx`;e>ly#fkjV zCmB2atW zs;sSdalCF&>g8;o0O;`(W+p8I86p7TJ^BHKqsV9Kqd)lyL$!IyyZ8DdJYT}Z#T!=t zjNcU=PkkEWuApvE(M?Vxv1b?&IX&yzJv{TNdp6+no$bCe(&1)c?id0~ZIm?%YUv3e zA|kS$T1rtNdD1*{1V!I^{l)j}yz0~097KrpaH4CKEb*K5i+0`j1TJ&9k0kQFZh0$9 zstq+Y55lxH2go7RR249PkAvB2@BIvG!KRCyf#qit{K`u;=bdeLRqu5WakA8ShCxvRYzTZw3~6fCoR3!A$#R1pkw>9IQVCM1+H36 zeY@Y&dw+NIOwi{eY8=mjbtsNCoOQ#O^xaQ3%+P@#F`jYLF=@!c}NmtJPz;rTp3 zJYJb?1lK_vpxV@n{Ke@%23tm9WflwZ`Rb{Yq~7P|G8l|3c66+wf?Cu|sP8R~HTgEi zib7x26(2ffi!b{@x3-#V`$wO$w#gQ=5$$uwyp{PN`Kp3}FjWPg=_%mbFH8(G8`?5s zAkykaanoi2kPn=0(M93Rt8`2+C^;3qysr?#)}QX~XLDWUjc>m@{x3i>+C1po_Dax$`!f&8K9R!>Bw54I28q;XIJ!1P>$`)PB{;kaMuS%Dc3 zE~MUeg0zm{!ev~Kakg=9D)wGrll8~al1T?w68g2#P!Q+Zi~>x*4d@ePgN7Q=)&mP{PaE}Xc|O@ zQ6*1Ga~CG0^dkIaqVH^A-=40H&L8y6MNm4OaTC;ev`_1O#)Q6gdcFAaLbHjwgAka% zLtxGlU{dAf&o+R1#Vzdup}ww-P&Z;@d46lR)BZIHwoeOB?cV&JJXuDNyo3??tRprB zXHK=|?h#6?!|gD^&+^ONWl_6il*!t-Z)>BX;Y6~Oq1$-p_51T{hn1!RI9w+1U<~iU z^WQuHKJI=fl;P6laNRQ#zb60Tgl$DjfiBc;;ht9&rmd8wYdXP9Wuc^Kit!^2rE>5ZFyj+9t>!LjPv*3!&_n^%B2jE4cw zgSL*2j>@lb1v01Co_KtfhShZq4QZeBLoHwL53Z%rYP0DtCT2gh=L;5QqM#$~(oC&I zI$w3h+U&Rb_y)d?ZmE?c;(&E{d0dPI&~O-Hg%5{nzl=RPKDIynhhGGc>u5s3i(bwj zM;d$z47d*&A0qvrrcO{#h?TY-7~CkL#r(Po6rSQ{r2^@|owcK{!v(?-w@YuJ{_hChBiuVn6z&+;(}= z+dlGv51*z|%iIg?(bX2~;BUxwv#1coGp}=gznyV|cYV0KGCig}s|6YSL1OEw!8nM# zIXk&&%UZJ28=Olj68zJDg6xgPi6BuGQI{b?IIs1#8~Tghn#=M4!92YRUbf`zti%SU z6(0rTJQ)A}8k0Dgb#)zTUP zQJ2q}_Qimr;kSPGe~B`0Cfh?t+&D&0d{1YCuLh&2hit%{$l>ll zZ|CFCp#U17)nqZFO2cM97v`$QKG`sG-O#R;9hECKQ`{KgvE_!wJ3dy6?c}7CC;7jV zPUCQVvq%37o0AoP`@ph)7jIMBSXR8Bb7)M0&ADjQ?ut{j^lMmldmfOqGxWxYkBI8s zTXR))uUeXw%|zM>V7}~=`~w>QbQ&~>xHH9X-!jtMbjWADl}SGyKie7} z>ePdS%)DRMvy}>Xn-BDTjrI|8QthhaH<0}8`gk}xV`45f&DMpT;3b{kpxTVb4Ed_n z`ZjJs>CnS;4+19#DARK_Hij3u1EU`ne3R{GfWq*&MOXhm$qf5!;@pJyvtw@GH$fbj z)Ggh9iN9}}(|q4BkImLp`a(Fw#nH-cD)hX2RN;b^|6nfm&{PGun=z~WG z<*hSL21*Cq!2JAU4G7fbh6@^h+m>A(wcTBlv6=E5xVHhHG8X#AV;{NfS_&t_SDSh| zh|d|~?Z*Vev`6CNbeWCl$w`Z>#v+sX?9sbvBP)B>wUnXCeYix-s%cYw%`OJC0bcS( z-_4MBI0J`F>;UGLYo&HA9Hra>=o1q%Z!&_6@Y>Ps0*BqXWMpZ{V&4WO4ld)ajfRi% z)MM_p1`3{a0Bq0@kULuzWUmv1ose`(;&mLS=!3{USQp_Q9#G)`F7J z9LvLDVQJNAJYR=pF`+6I@r`cvwazj3O2Y4DMSw)zwWQk}SyG}<;*q0SS)t6?I<(U9 zX+=jXKQm2OP8=;mg>Yrphxq>U&;iKRsqy!BJ`p3&B#a9s9s2!JQR`c~ zH+Qr&mYLtit#PS1pU(5D0q;Wd zF1JwC`-LMzEACYZ1z#sCXM77krSATE|69z2?a?^6!8zvad$Ko#$~tYM2>DJ+Y) z`z_#HgblR7N-w_H7@3g~1Btuc8Yp*j;>Z-gE(zbm%>#wc$XOQFR#%V1fB2lf8yy)L zN);L&r+2%M%*)Mn9;Ws)Tm7aGiWL05RiRWZ56s?j(n$A$VyBnd_keCwFVtE0I7*ME zAJLmZc+7_56Sx;6O>|;=%b+DHsqCaT;wF)1!&3AVcMLzw)d%vDjRXld4n{ZT%RhFL#e19_~HRJ&r(g7nK97U z$7-q^Yl&R_eU9aRvs3-CIe`7ziI52sf z>nGsb(F#wQW=tu3Xed6}GgM}+WM~$on}#v9OC;yXH~2p4A93*yRjw>EAIweK^ z9)1^)B2O}_)%f6h9q+a8S{i8^JOL3@eGV2}MM|!Gzit8!UyOl#o|4`r150$Xc zUT6E|YrjdgB%>MUmx2_?^+)WF43mT42g&sh%Q#QnA(tJfr-^Yr|0QVvi4I;J^hLa2?-3APewHi1)F@$NH{H;eg2r%?wm0) z8&kZJ4i!RKM1MC>vm&><~7HOtQPh6l9wIy{A=fLlY*^bdh!d(+C$ z4_5i%$I&Ktlf4NPY7$?tNs{TW#prw&Cl-4Y!vb&p*EWB-aZnr#cj+nl>2k&>sfX(S zNL{bE?GKB%a@dRKpU~)@H}Vw@p-!sNJUsDS0+v#MBs;Sv6!MFKXR?R<187-KfIllu z7uL7LKaUZ<(O)pbt(N!vEtR+PUAW9*$u|!t0mXykki5!=th>7=xv~TSo@bNADTPL> z&gWkRqnqA_L_Z-Jxo<+QquLG)ktGT`i6bfZEH`g0@~YXFU;ovlu$yxXFJBZz=#TbH zO+EQwo+a4Q7V!!Clez5J$>^!x%7Vgh=;bvsGfjiSZ6AZsL!+sgpI;>vvZ9d@5MrQ# z&Llg-IYc75oKeW;#Fr4*kNTsKwI5d>`7ABvWujX5h@4cO3X8ZEw_kVN zxD9Spegx?BrZ4wiCr4NA(FmZzVS>diJ|ey#Se%Tnj}Co&@-;{*UF^Ipdn9YFwLZNh zD=s5qdnmmna%Hxs=b_Oj&Zh$2rcw?LwLH!8h<)PN#Q7sF6;F|Qf#cq0yh0=MRrQtI-e1ke2oFO`F<>i%^%V=OYU1{q=`wLyGp3sa^Mo)gdH`PV1@C9~CP;E;l!~ z!G+aY;N6kPkG&~j5!c5C861^`*rnYa2I9U@_OB@$qAFHcd<0~w!UsH{6>2IfI2tW` z>Eao#A$PTs1rJ^6?xtM}85||K=GhtC`C_wueLadpE|Xko0JfOeIP|?5vFTd6MYw*X z27?nHlQYi;h=>H(qxHNE+&qpcMKGCJ9nJiPJpmKo^H%W+K%Zn1*Pkgou8N9Un}`^l zG`t)+DT+{1A7$iv^CmsHeb{N|c6L(~nPtOCaJPj(h6oq(?a#fa7pJ0N*U5y*2iRQ< zpxg-4D9a7_Ee7g#8|hU{26~FmMq>d6$lY=By31Tp!==kXpJrg4ueRHl|kyT@|QD8$mW4Vrx9_66G+L!Dd zG?yDsF(V8k9(q42HYWx}Aqz`2T|BVG=oInDb-k_x0e2sFH1={w&bA%apPlh2>iA|W zLfRvBmwDeLdE7mPi|IB{S<5gy3e|w7jAXMAZV%5*=GhiT7g^E6QyUBFDLmgwJunb$ zvf4S^o#1zxJM-%Md_*8Zj)=&pO-)U^`0UJ~_#Cu6Vpv!)C}OjfZUfF9S!(`3ZY8%m z8rr&uM4owV=K@}Vc;JU#y}9?dld-P)fctRyD9hh>_%WZiFv*N_cgZg-A{D+0-$};x z_y=V!uMOQoar|1H(W@g^JPXOyzi3d28Hv07S=@PfucI;tdvkOTex}{BBTKf0MGb<9h=Yj8>yQgaVA3Ct4 z^e_C%C*sV6`CgySTMRK!czF3fO$y|Yvs{^Ls!5}*vy5GRB1#>&hD6@SQSR$LSNg8x z<&FI59;NpY+QHe@;q0@#X6AINy>d*iY=Skd>a*$Cd+!l&*LBrfTBx|tv~{(?w(s-9 z8E-5_1K9jPA*Z1U*B*$4k>BpSL1~|nr&l-kg@$L7klk1iKjq>Azgy2g%<{s*=?ANL zLHc)|PT37UqyiRU8g5SsX%xjFPt(C+bKSIR7WX&Ew4gIsx0A8<6(PoTK!>Y9Vw%3Z zR;t1KWypg5AfL@f-EL=Sy}O1X8Qq=OGAV|~nyB;TUs;xO_pOUxM^iMP+;X%MN$iq% z)7wy7mL*c-ZffI3+j&<@QAxMV&5+6+l99P)i(v*wGvk3=QwuMfm8bfY;cY2yqe~gB z{>8AlK*c<6k?i!*;Yv-J3Y0jB$8n~Z+1=-tDh*is-C}+{@(>Dk3}T`AjaScrZmX`T zVdT`W?bwZ~T@Pd1@wP=QKYZT}zQ}laM4#Dig5Ma1L!4YF3F;Y?>ZGAetzj+Fqc+Nb zeE;5Ly|wvTcxR}&9T)waWVo}j5l%Ir?T0G0m6VQ(DoWx!%r4Rp; zYqe7nEBXNFGcweDTN37l%A4Bf6NB;E-4z(osEBlk`=VFN+(i>S>a0O;K|Nu4csoNn ztyD=hMIJ`KM>U+5H!sEXgxznivT9+9x(W-(2r@qr)JIVZumcdR#0&(X=%3Xo{3jf4 zFlVSwK|U;t`ii#{aC7McrPS&mJJMG__*P(CW>S<;YQYgEIzItVbmtJSVjp(0g(@c8 zP?XQ<_^Lh{VdzqMz`Qi(ol(GQC}=VNIjvK{+?JAm4of?!dHwf!h_KKrM_ect-=7Cc za{*0NP{G7}7~NIS6CkcJm~a`0boI7-4fNT3!(G}YzNvE*@e_219wo{z^03xO6kneh zjD>QMlaL@!Po&kh&x#wZhUU5Ue{IAJ^Nc{7Ks{5m$Ga14cegjQBl7jbGP4?70J*mj zKGR2Mo6FjwogHX|ty>ID1xUCBSpaQfjrzOy=76!mw2)AbHEo`!H(?Hn1* zm_4O=Tc3Cj4-T>ELNdyY7*Yq}4SoBYAG|n%2YL*TUo4IcULVnJ!qS>e20t&*zQt0i zTW<7099_sMQsg{wI+Mm&HO}>RGa38KDrvF>5y~|@V1tQRY+MY}7M2-JOYM_i65&}5 z>$FBL#3tjxVs!xVe8?LUQ9u7&-`xTC2|mS)7RR%a@0v?{fj9=UqUWbcbi z9Ws1rqZ``>J@M&}eF<(<)CJqvxb^;NUep9Mpgc{Fr=j5){3}o&^yze~zBZLL^#bG} zq>bO=ZYV8|Us<=d#N`W4cNMVV6pwn(#l*tRgw^q~=>F9#IcFLFzFgjVhk~NH#@MO+0^k1pF~x=0kr2k>07AiA zSe5ebe)wF#_iCmU`2F{4;z=Cw?E(GSxv=@)i?GTk=C(jQSj68iPlCY=HJ>Y;GfOp8 zw4hcW;_`G>efZto-OZcO5Q~b>DLSgWk1#j{qEV65#UQRXKt9c=5(Dq^e;pi|>S6Rz zjliO568O3>J2W)J8(GlMrdki|sC34pEeyobJ&=D7b7g+M)lQD2l(12Wp3bbdbo0a* zfo;fpeV?Sy0MUoEnM0cElkDHcekMsKC%E$PCocwZPh2=oK4_-bQLb zkYHJngIXyvqpNC_U0_}#!98bbosRrdT(UPeR-5#dT4$>@w6@k1A=a3lNr{EC6J9&MJKoJ&lmePOId%0G)e;4(aI^ir(Z#EB zLwuc>&~RK0V_dP5>nW5WxPbfA&FW8IxYlpxCo9UPrl#xDwPfF9O%ZM%Sz*nCtW)?e@Gi0ob#yJRxy6_yI z2{#y{u9A}tMB`@7U0HmQt6h29Fqz>qpJ4N3#H&D)X+|dFPvl=EYI8%^q8Okmhy8AH zEwmmZrTJgkj58i8T47B$o>BbX+y$!srXhhjNm4Y1he$s@W5S)}FoBT6=x&&s{cFy1-JKzb}HDcrCdzzQ2<18v!2R z(}(zq@Z6f3uafU3(rJ~H20P4t=;k<_eHNn^vkbGu@Hw%tr?F=~q2`z!%=~`vQc^|I z@XlKsqLhPmz(nAWFYofkulmj8)VSQC3Z6N4T+S4sv}%`!98Z!>>H1^jsuKXGkhfXL zD1f&3gM1}jaK{1g5-RDAqjC8pYW}MLte)e1RUsg3b+~Yi!cfw>*Z92v+ujaFu%Wo> zo=2f>*F#Te>9^>bnrP*BTYl2UFC^4I%>EtsnFcH71`?On7l~zJFWfnmJ3L(p$w(}> zH=GkV`4xY#q0M3wA5n|urM80B2CRPfHdOj^W2ao;*WcZ7F;30&@sW{~Vja2JOi3Rs zvVTx5y(H;-Xlq8D(QH@OgfMdx^$9MVyE>Fc=byqDCJ=TGgYY4orl7I@L$v~@-PV4g zvzb`#?~Ip@DX{7y6@BkIc=fJ&8Y^P-a-QyiaYr3wd>O`QsOeW z}`}jQ-N|sVmhf7t)|ivo~|1yC@CWguQ7Z9u8kmBckRmxfvgX} zeo;H61+;U{%0t!l%Bn%u6^%cfwgbfm8o))^pChr>7Dd#8cDDsYz*0>o%a54v+X^g z;}%s%uP&ZKN7mLjoW=;Jf&SyD=_9{$?w6XV+c&d%JP+}9p_&Y-e0#Xb)P9#S(d6{> zuliVP094!i%{4u16Q`A>W#E**^FiGPo&2>JFVas~;2n7ioSjkdFe?J4Pee%Q&fDB- z8Sxs4i~ODkO)gr?5ti*Q-Y?$|bI%2u%Xet+Pw%!sbhW_sTmR^2kLFKQoA=^e=P5s# z+{G(31!9{0lF zJicovaMvAg(XfpwkK8o^7o}uX|2va@dSd4v7VQNKEcJAcpG`MZ+1L(HZOi7%t%c=H zw$@K}b)!(R{?UxxyaKjJ=@1-v&}@MI{Y_h?=jPpWqD~J%uof;8rfd1BIt2VI1`(pK zM=ioJeG#@H0$!A*rll?XWp_s0Z2_aF014zn2M6zemy0RWY>Pkqs(vcn zd83Yl(%&;a?z5t+c-%JZ>7>-%%rubx)}+zw#TRPQ2l%5|c|GDLCOo%V zbviO``u0^|Uh|i)x8p4kDqzh}9|yMN6~c&QgP6VT0npNr_$()DHL)8YU9IJA^Qf%w zhAK!qPk5CCIZ~oF)-4Youi4&>_f#nu3WzBSj{nrwB1@f7{Q~F415|<#4G*`Ni+wpx zv(hV-6_!mw58yR0iL|0eZAcZ*`Hq?CLG8)De45Dz$vc%_W}g+0zm z<`L@i@cYgjbv@bwIasm6kadbKlUNpUw3z?<-p{qemx(?4FV38p z>n;p_Em~D1^;lHYvNdQ55vc%EJAC;h(gu|+uV-dn9z0U(WQ=aNgnKVL%P1-Rxp$B4 z(5rLd$*#knx@(~T<~k2{`zTa5O(i(WY!Cc>+LgE&8}<>Ik9EHPIn19 zbR9o@^d|84X1vB2PF9xp{)NBC3DP%oNSWPM`5pXkUIQi3_4;oE!+guG=51f>O@`*XU=7#|3s4Fj9FG1feFP(AcCj3txFl%?Kvw)KK+fJS4sqj>gCkY78426?O~|bGPP*}G(NegRc8mlR8U9f zdQptpL`NZ;BzKi97U%x;?~9#u`n;E9F*a*o)9z>O3nSx9A}E2Eqf|Gx+!O-EM(`>~ zO1_*n0YeDo_E;Yjx^|$@D*wUxE9Ff zDoMp(nX$6`$zRejf|3r}4vP+DU((2}wH(}L8oeaMljBx`fKJfMCpQESP%ue|ih5V3 z=Y=OE#PW=4tz7#&AOLk!)9jPU1sfKXU4Bit#&K-uC}QDEe(dtRsC(ZSR_tOv~ zGDc>GuUfz}u();63@n7RZu4;iFK#9#i_FT3{p}%9hd?u<=nKIOOqYj)`bf^INrk27 z)d@RCsK!8dGONG)TrPUBhk;c$%gy_RxdSFtku9S-j#U^iySzhogf33+1#v1qD!Y3W zDyp}=R2SGX;AH+v`YvI^ROoc~10CBV$1-o5yP+kN)CroQI8xa(Je`ih}XC4rDB?=yzNz{j5d zS|9Ot>u=jMcrUU+5uH~`(}qGI$ZN}yU4M8}V>BZ=HU_EF1Q52k!1<&wODe1$~eaCz@QmuXxOjFPA4a>Xx3(dexD)9 z1h{g2n3vQ!i8Oy@J(EnxmWe3dw z^S;UTKhFW}XJ>NtdDuhf(pGB-$F!47{dy7Dk0`qpqXqc5CR5hC7>*RiRraW`CsWwHzqpZIxTWJWOea=v)RO}bMz4#M5M6|EW$%vXrBu~)(GlSIIbcc2Z+&7@=IEj}{2CD-5uSP<91U<{pisBeYG zxZJWOn^Um@9d0bQBrVxHN2VtVMlgQ`EGn))Hw7x(?~jiN>0-4CeC~YVS|=XhcYS5w z?)5XSkpSNY;JADZf861DG}G+sAX6WVeL#BeU(@FgfMptlB8JLXWd?aG)$@N2X#aDD z`yU(f|12A_`w9^L5X|K$`}wjBp=0udCwO_pXP?KFfePq03@UvMx9fNTxP{;to-AgZ zp5#dF1N%m1wIey}PC@%ncW%4JB;Rt{`zLiy&I2s=7}ezAYyXP#r@~bPUGwu>SChW8 z3e;@JKU)iYc3SX-AG9pIp_p&^YzQ#*{Yn)tFpnlf43(6WI6k~e*nf+31uT0jpG(!o zf3ZS$p+r+t-;@6L@BG@-908c=jmTz2P?Ni+o-^~PfBfOpsJFb6;tE=8 z%3|+xy&>)_MCvu9!o7CMqm739-lZopOT#tUr<3%jfkTv&@*vd z1%TiCLoPD{4~|FqfrqoC!OJTZ$=d|pGGpP@g|U&v6ZKXB;5gqeg8QR1v$r}N%RLot z!z;-lnblfjCBY?p;&b%lj2FH(?fv?uW*kJnqai2JNYCn56(30L&E2}o>AiQBI=^B>Xr z-kYAw3p)$4B9k0+JqZdR;wL#=pwBgb1NGgHmKd93fReyKZ5;m~*;4)H;qX7-95FR% z+Epe;{AnfP96i?f_<{E-INw2wCz#UYRWUc%1N*h5!u|9T8&;dGlO@0?j*iKHxFnif z+ho_DFe!N+7 zvwyGXzXlrmamLV)siis>!RNo?hk^3YwBHRt;6Ad(-QM-<{Tu8M8fZ(+@yk^iFkkz~ z$`maUaNfGYkTg!lY|8y=Yo-BeP~>U?ukFsZ8tiJIq(`n-q6=Y1G!Wv(7a*2AfI#7WD0=A4i*_zVvR~bM5!u zJ*iN*w_0<-x0+~jA=?2tk!B^o?w+?fDD`$B+4#Gj>sy^?v{J4^XN@g5e8TaDiM_rQ zFwQorNe+r#bc#QmMBSzil^3k2(4iHRn6Uy1&%r8iZ-kJaNB7rDAs2(@?Q6n^AyI=9 zCiEtEV_rMB#S9u4>DhfU9tMEA8L=>K-MMNnOF|v1+5Wi%pe(o5;Bb;&qq|Cg5SkPa z_~x_!j!1G8ghu7SjSlwitjnQ`!MNvX(hf8unN3ZT6R!*<29LKLP^mvxk*XbPk8Jv@ zWkBdI6Li-T7Px9VFtt)Oj!t)y@0g}Smj@zfIf_KY#>S&K_TwMTU@+OA;_2OI8+YOz zio%-ep+rnw$RrcrJ{^Fiq(;@@@Tkf${im&`p)c>3f)~~pmh}R`Yh9cCNLSZ8L9b0X z_m(&CrT0ILj*X4Iye=;`F76e-VmiTwv#ALln-WSKo@|`VD0%U#H3;Cu)Q-8j2QYMf zq%B|gn*X}`Rp%2@aYam%i=Ji9Ri}tc4Ru*4Ff-w6>p2UwIqhH`5qksj`hX{;;+p#o z13%Q_GmmP}?Amh2zFKp~U5}I1S6+0cb7^J3CL7bl1a8=HX;eFIdJIM-WcV}%a(Drq~g2hk>1u!_|!;{c<1P8H8(wHndKnT2qIW< zuJ;N22>>3qj7>;;JD7;+^?M_|C7+nCP>-Hz3{vy33}IW|y~QG`7Vh!6#am@tZ~?CCv}p4;bL&j-S%}&5bUC`9t1t0Hf-fP!f@ulhbcZ zQzWquo7KKtGL%k?+N`DQgUk16JFe zne*-T$(g*5gWGzgr_JH)Qg zsq#%6$wXG}Xm^Dj3p>z3;<$fH@7Fbp$Mb(@nkb2blOta5)Fp@K=-ka(ycr}L;^O$~ zHL34~tDpr{oMm?7-o3l!bjkXN^G7a^5OI6AADrz^!u_wTcZMbl2zWKw9F+Ip7r?SC zZl;AON`_tJ!T|Efj0|y9B>BzO{@&YF*O?hzxr#XmWD0P*(6koe$jn&c358`c_}Zvc zcVxn2uWi2AxH2J|SMTi=DgYdgJ}^H9SttbhNd~N;@=`YdAOEM&!+}38XqWj-w2GL+ zU?z!hb!EzuI_G>BW^;_qsKs7;>_{*_oY*T*^$An!Bv z)cVZyjih^6Yiong@ziXtw!5J%wSoqvv;TC2PWhRS|3SLE{7LIw9CGH| zZYrkEGUcRXNT8FVZ6-(A{tjb%L2Ij`X4xm;jfS)f^&)Ppx~#bzDLsC|Yx@^j=yF$n zZD}E*MNek5Zp0yqaB_wj5!@FapY7W0q9W371S$Ic`OZIh6u;wA+FZRli~%+;-?4ag zwG+x8qzV*iudFgcZLq*Ouh=7V4D+lEMbdrHoAoITIQH(slTwW?M+FRdQ5!mC%o18= z0arL$J0At}xye7F@yx`pCFkpFj zIg5to6-b2Wd4XRobB6Ip3^tU!BA86aj&gB>Gn9OKKdp{5$RP6nJXlcy*Q?}y5AOe) z%gs5$+z9ZVlGt)+Vh=Vm>YJG-glnjEXvQmxg$;v`JooPm#(ZcG3HA$fq3ev&%aRll zooi{a-`ok7VE|gAw=C4&|9Yb10UpdI(Kh}7c9Nz&%Co^8OqZpLSPq+M{B@84_H0Sz z_Ex!8$k^T=EojEF;r^b~HVurPbnC;yh$`1Tr02#wzSlsNi%bcy9Q7bu(_IgqRB^%X z>5Mew6k=|4xlDt#O>2Ce09602J+K`mnZK9`4!!8eW#bTl>>rGcyKyL?NLT^_F1V|~ z-=y86l*D4K3bzXNdE4ZiKwP1sk;JiL6c zTNgCuw{J9Ka0v1A93c;PaGmozp1OK3b|f!aPo~23&-65jOu9hy4lrfI0W0B(Xue_~ z_TtW5RmU~#NNgv>^URt|MLDe1n*o^3=aX;{-W}9X4l^AV-WbRe!=BTG3j}%p1 zm9Bnfi6vgB0JR~rjPDhxhvf-2IAq;GCScH~n2)gyiHt1G>#wRZZSd|-=C3d;pl=5- zC?G$tIecLi={FFRp{6>5>kt)uyGZghd_7S>R1A&oZMecH_#f=Sm!$hVCrdzV5X|@+ zI4Hm0uFr2iDq|6Qjm0`>2_o*CUS$#1I5}wuxX5Luo@t0Uv2G&8cq`tpB;X0+Q~i`{|;yhyR$hJazke(Ux5k z^ztE4KepbIXH5F{qtr?0wwCcXt@BdMpXUBpRK4|YF*|m*gWP@4tU->)gymbnUwJO#d}8r)8bpFf|+yzOnxF`1ZB`el+)1?83sVl>m&s zfZqPUbhyLLSn_prQquGP0(hk15#`H(A;L z9N=1z15ki3O)|-1$Vr(2AF1uV=ca(=(U%mRfdBl4Ju=;GaEG~)`^!rk(5ek4o$`3? z7_?%;NOGCs2y}tJfO12ny#nbQYPiI0qKA1)+I_v_??wlWjD7Qo zeZSQ?54$@$RJ(aNzvAWNCD7VRMH?qPG_w5<{{l&5r09i%5JQlwl4Sb^a@u9!^O_NGNzNp`P z_95~=+>$7djIw_p3A23vJ?RdVxnJQQ~YHQmht zS?L+380DUP_hD-Qtax2gd2Vw6N1|6Or)G^YlQgN-`N92uoXX=!SgXnGCCc{N$@(}f z=Bz9oP-?C6131>+6U5+EOIPE3;~SU%I)iOaFHa zi^dlFsZ>KP7jv`tQmcYfs{rUgkW=qa>?>Ag7>9lciY;zrU1{cwvWqt8cLGizQ-OrbmYy?3dWB@vrx#6Tb0ZM9V{Q z$Xw;RDjSxCiA%GgVao1S1eEBWH#Yt=u-F(NYM^IDD@@R& z_T!aVyi&l5aGLEr zI^NF(7*y7laLUM{9O`hWV>#j#A+}58&VVDTqTkX^ut|)h;6%U1*U^l#pw=gh`Ywyk zOuKatkMc)K@OBhs4+;@UNzl11+om1m*j)C-iQX!4++c83w=|P2M>34#OjOcd=YST)1`D{bg$Dtgqt@ z=nM%TRK$^(B`51Ys3%ERLq)QW0(uU(AVmBc&AZ*gxxL*#BfAIqiK+1h!opzIUTMgq z@P)o6UMRbB)6qV1 zKk_kS2pQR_%Uy4QZ<1KoK*ilv1bIVO_Z!=8?^3XMbwY?T7?s-s_1~BEY{|q8d#Lq~ zLy8H5^4<$$D$T;_5hO9ZVEpDvnMFWEjFl?Ew-?!&RNpRYlG9Kp3{Kb8!OJ!~ zG$<(6WK2Y7a-f9y8KrXO&u^*esSVj$odCu7Gffj3y*!jcW0-M8u8X5%YeQ-7jX&%$ zGT(@QJ+G>%529@#(VpAoVw6DHCa*0oJe-Nhq0|K#d7XZPqg5ewMJz~ai+t07@|EvdAMwme#!hwU;iuS$)5RL!bmr|CVi zFzEWt`*C3yc0@^Uvn%K{KV3TL@Uo__2$Ts40EIz}U0kM*$M(8huIkePRa|N{9nWk# z)WycdWfjkD&GS$y#(B4q28`vAKlC*|sZT)U)DczgfKyZAGYpvf`qh8;QGUEg_j)5VtS0XNyl&l~3Ea^xRC(3QM|xA!K13CU-SQH1WP_M*=*2M)+xh2st=^sZmzG3~}9>$62Fwe9;RiGa> zoP2VUPK|0k@qu=yrp0GOq|hq79kcrqp;ARZm;<+6mq*n{hB_Z#?C1;dJx~c-zgefPGEW&a@OIr~LANQA& z^I+;+5ykrX^V9B8(DAAfS+mevTuuH{WEO>!UGtu&lrHoq?1hNE-^0xr>XB{ zq8mz{grSHKC?Fgi(@nJ5$ZJ4}D28|tk57fCCj4#ASHWPbR=M4cdug<7z84c+EWPL) zMfr$d6p_uilLMY?$Q6?z<=kQ7$El()n1T;3w*><6n3MAJ#!z|p;(@6#3OFhdIuN`X z1hk6x;rwc%-IQkjhjBEQivQ=D=npc}Zva85KlW!6ph3XH#;FsOR6_B~(rdB9>5M0I zNQK~~l_cI+y4KI`{wIT;?h6Sp1qgal0fNs~f)lI+po&14#k2Pnb2#8{z4!LuEMOjs zFXQ?VdSYmVTyt?QOyIy$G5BI~mr)R8fRMAh!hZU9V<3K14BW1qNA@m?oEnrJ0!{hF zHK|k=Uqm`kCVxUV1B|+5eoY&At=zC(A8vzc;CY~-_))`$m8wl%JBRS59Axc^P_Vot z;qH(EO9{^z%fXyN>(&gJ+ZsXUVf(Jo-5XYlja#|DP|DJQ!aO^voXf4XVU2$Ip8ZnT-&%<;i;D}J9}*7^1R@}koP$jmoSaP4>f zir4i&UZm&pC_Kn|o9Qw(FF?qGyY#Tj7=NP&g(gScOgT9F<&pi!o92ei`T zvyh}J2iII>x5b`K2w_lVJ88HJCMXE8NjChtgPH^*;pMS|$*xMo@+riDKq zlhLuzp(dN0-nLpg($wAWUI*T(+4Zkxk-YD=NZ1R)=LE6H+`2&h#9WrT-L5&tX|OA- z-exTZcEY3YE(1(>lh=cDVUPoMcct;6TMvOi*G=CC_3cWkql@{(i;&K1-YBz;dcEZ*f=?x+lDJxl5d$ zE^o9V;KdRH94#?D!yY06-HO&G$~Pp69(g+iczK}8g=TKi7ar=@<(zE}E+7Ivrv1Gju=d!?!S(&STs+1k@AP(`oIt9`)KfH6!!NW*% z>|&8-Liu)BhP)-$n@Jc!PLiQz+Afv-{1r7%}EcSVIppQMD{YZypYt?~=> z#5g4ZWl`?Tz`k5Xn9&%FNLES5Dw>+3vNb>O<1R}%J_(Cf6{2QaPFn;1X!#Mkv^kGL z_HZkBHk)e|=<&~rW_F?vOUxY4jywZ9+hD8bz09SY=KGP&w6A0I!1TIYYScqkIG4NadkxmH_jF0Q1lr!M&0!9kLUvzpdpU?JZR>?fKn0Wq^*7~qB zeSDXQT9Kf8HI9%o%)6Fj^QyzsXCb@)9=Ir^=p04|QqGxc*;>@Om-TCFYj(rFNLnkH z#p3h#PRfS3mB95_>pA4pYd~rD{cqgDSQ0FRKo?xRGo~LrKOJkno2UCJ2wu3gL&84V zPD23Y9X-zqI#UoySUWpen88q{L8}ZfD_SQ;&fAD@Ezi76F41uc@!-~H17APXOb0Hm zl*gFkN@jv$Bl7k*cM3@lch1?re0Z>QC1w{lM`&x!+YzVu=kskpltT9)2WZu|s27M7 zQIQls{rq?qpgG=7t5)wE`d@Is|CfUUE&=fW>6S0EPF|`q0;ts2|0R9=zp!9uqV^+! zLWiiT@cQslH6KB>t{|?)rJ_vGtcc5aIrGn+N(j&_`_LF}FBbw{zINTDXHfVx3;W^; z__L*y;-%HVSk%w0@NSDNiUivXWv9RIm26u`r?PRUN59W4$j! z);CyL12xwM`_0SG(Bf19*{uaesZS3V0G4L2yPGxcL-#BmQ4K^kmlDVKC4pSK0ELB} zenuia%5Phmmw7xNou^}Z4F zXdW>{px-$u*PY`(wIT)p-|S^wH5|Und7J9;%C@n2xI|e|eeyrAxUsJwLy;dSv3bh7 zuIEWdu?HS=CdZL$%%|Xhu+5)ulfZjbx9jx;0*ZUj@A|ysK$F|P-c|yNONzd%5d3yF-umFItO|8n zB^4EuE7_S@)f0_Q04XFhr_wH9z!m8OuC(mR_JfU$g~*Hc6?*7~=HaF%|1k11-njAC ztEimEK5&XAiv7{Q<1~AE;M)+8hVniZp@Ja2v*9;jFuJ`dbm4Dz89`;lm2-X|D@SRE z#Diny!FS(HAcD47mn*D(YhtyVQebGRp2r7vxNP|3tiNB1Mt+!vMx$8IvYU1-iE^G* z{#=4`!oqi7@VY!OlsceA0+ft_yL4Q^&0kk3R-389@1yhbwUib|`>t#c) zT=j6$H?SlrDnFrY27l?MkffDA#7riK5=XaQL z2^oE=ZX;Cy+^q9L&*vXS^H)nHP>mN2mLTb4=mp1QB;)Tkj}H9^W{(u}8QX3lHE$of zvyMJV5o6|7Xx98OAu2O79r1nbY^wFh2kbFlU+v@f^HX&tcatmxbs!|Nx>;a!7hp1E zh7gBfi#Sw{9DIH&p=jMifs!QwlLy(F1#(c?#s10yKw2D;|A|gvMO)<&fdj0|qf}jJ z`UeRlJ4pAX8D!yIz~L^pR#zehqHVHV?QM%3VGE))8v{4LW0(Y@tVbII!i^wLGxL z#_;)pbz=jROi~;x^1|#9$Q^Gf>m*?=r}m@(=P#ys{`$NP23$dxwCgni&aisx+1$3V zJNg=PVgPV}n{VY+3xGf9hA)D7vZ0H16EOV9>Pmglw2ST2H!m&FcxIy zhQVz(4iad)OIfJ(cxKFuwZHvN_a`(%Az+BY?5(D~zZ?DO9n1$jZ**>5G5}43VUo67 zSwJsNP2#lG``{;>oCv8|H4RX>zpfuB#64G0VtQTpBSILA6E4D7-DjJ9x0k=zYrF1{pv+5^L5CN; zFRcOtmEf%GMdf+L%^i!qQl`qs_|eE{YAnwLBw|eflr3$$`%BY8I^cEMLg%)m24uV; zg*`wvSJ&vf34B3o()E<$@Nb1aP;x$77n=onTB8@4?tF6yy3W-e z7Ix(A4fJOQV3s8ydrRmKKKhL;4JQMPom@c60z-8QmOWE7l8Hc53<4B|2UA&8ql5?T zm>T;V@YWh;ZvHUQ+<+QukP_TjoJ@02I0oZ7@L)1^D@MM%2~3S8Sn-yEaSUmk*WZh6 z16ywr)p}>wBJh5P)nve0s3g2jHoIF`pbe=npg(Vl+qjuclTEFD)@$JxU;(>X2stgR zEwJl`z}XJ+TF>!2e~6>9M;8N|9O)AG+13}Scg@96iV80TR~eWXRt8j0r4+iCQ+DBg zk!RbY=8eJFiPI){5Z}JA;tjH{s=se}fM+ji6C&?@y3`-7fkR{D>Fd@GdpcAjL#GRs zBxRQ3OV(h+m7>87VK{6*vg4Q;gcW48$n+shb(^!*PB?^|_pk9IcO1?SNzcZ*Ml^`! z$qk-BN8lN)U>n2H5$@3@8&)ZxJ9}XiHnNKwTzfg}^Wph5lwViH4PeE`Ka45fowI1% zI+%*4@-@9U#CPNh4oDvH^E)|A&$$rkk+7yWuq=_t;~3CPo$Uyprk`2uY$e8Oimdz^ z*ETuw1CBaj#c8HfWj#G*yP<1F^*q0BrgW z;}}MXS`2U-j8wkA2%Kx?+QGkuecc(>h}70H*^1DMp&3(-YgvvT{l)MZ6lT?W@fH#` z>H-|?t!!3sHdIa%AT@N5c_AsyuiG7+diDHh08HwI+*)1h)*5Hl9Yo&Tu2lc zJ8>skEe^ssnWBRpitPF6qi!Fbs&9bO_j4L8i*EMAqtl5uyc&)#%Pj&PG?@;+`E?S1 zE8Hf%HTj#D*H9`i)f;0yf? z4)YoVa&4LYr8Ww`yeUJ|ZRVP#qqX5temg%0WIbkE5xOZP!@K4J#5j{7Yn3bFx@hTj z(;r1WJqreVyKBH(J^|=*WP)-*BWG^BI{6=Lx(2%84)gz}=KxL(@_s@Mxn&}C7Ha>9 zXPbLkuP<>6m@y@R=(s|GOr?sfT8WFnJ&nQBAnuyll@TkkJ=A zXY>H0W9`z}PS4xb)1XQQsZ#31rA?VR`<9dp*aiqBDl!3WfL?@WlL9Z$AA#pPpZ>&8 zq;3SS)C=Ml;Dnlt zY!hcubLo@)-B`|tfwAEm7lO`#1YN(0naEUwM@gR?JP5T_U=PHdgjhFUdq(rQUwG{W zP$NCH7(FxV142_-GH*V!9q;Izi!a8xJG*@~bg<1pcnM|Y-mhr&39O0LwUMe|w%T^(H2&D32ibI_ZI( z^RVP(H)7$GnCSb^_OJ`-6#vvwF4i}&ruAExzU#z4@&=AqE_skQzwfOtTV&MuC&j_; z&k9LAztXLJ6wLefGwXdbQ}IjpaoS?c8kL8@mF7c~>VTZ9||Pi)7J z0_D^Ii`{d*i9IR!J9$mG&G}EibolIV*I~yWm%_3F5@_J!k6?F01(hjzf@F7A7-i^e zv7Hz|a3lNo|ADxXnbYK+FE6EF?vZam7b;;ktcb0s%Wq8q1YgyB1kFy|l@IS?lv3{u zzchL)0F2&Repc>yeF@|ZYIb{eIZ8QIyiLPj-?{#_!6&<{Utewkq(2ImuH!HX+uS3| zU8M;+77p?!R{#dwXB`t2);7h~dwZ)Bsx7uRKT-l$F(e>-{cv~rBCh$Jo809XqX6DO gWBGpidizvIdH6&zv+lm=Ngp!?XF_NuBLP~@} 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/boots/standing.png b/tests/rsrc/bundles/components/pirate/male/feet/boots/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..9736c9cf55faf6c806a0bf671d047e0e90c183c1 GIT binary patch literal 13111 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/boots/walking.png b/tests/rsrc/bundles/components/pirate/male/feet/boots/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..884426b2d2536c322f9bfd9d0ddc63e954365a12 GIT binary patch literal 43494 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/pegleg_barefoot/behind_back.png b/tests/rsrc/bundles/components/pirate/male/feet/pegleg_barefoot/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..64bc01c3284c1487986159a6e183057b183522d0 GIT binary patch literal 11664 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 bLoP&x`Q%`tpV0_-QjIXyr;uuNJx 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/feet/pegleg_boots/walking.png b/tests/rsrc/bundles/components/pirate/male/feet/pegleg_boots/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2251c47e9e7d49d08fd2eac04d5ad01ab6eceb GIT binary patch literal 37251 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 NNr=jd6btG3{U0Z`yITMN literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hair/ponytail/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hair/ponytail/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..18f7959f2a94cfa0509426e3c1f8c4c8990cd637 GIT binary patch literal 12663 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hair/ponytail/standing.png b/tests/rsrc/bundles/components/pirate/male/hair/ponytail/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..bab363ae71344871d19e991a21fff70186ee586e GIT binary patch literal 12644 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hair/ponytail/walking.png b/tests/rsrc/bundles/components/pirate/male/hair/ponytail/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..7481d333a13cb2e4f34d533ba0561325f0317c23 GIT binary patch literal 41819 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 A9{>OV literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hair/princevaliant/standing.png b/tests/rsrc/bundles/components/pirate/male/hair/princevaliant/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..377fe5f7b85a8dcd6699fd93c393823923522ba1 GIT binary patch literal 13007 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 S8}J_~5Ibu}t7?l=zx@x&q+k;O literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hair/princevaliant/walking.png b/tests/rsrc/bundles/components/pirate/male/hair/princevaliant/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..7f92723042e199e8fe2c7fdc6a9f8e5530b14d4f GIT binary patch literal 42438 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 K3gvPZAOAndVqzKq literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..aee02e409e7beae81c956b7c0c6ba58dc2bf2efa GIT binary patch literal 8646 zcmeI2X;4$i7RN6M2r6jUB!CPN6BY?OqJcmHvYN1j&9H%k+=74u5rQC3 z6j5_MecDHMvLf})y|TB>;}NCK_& zR*(#0OkzeOM!^OkO_55HC23Y^AQkj7d!-wt0*U}|z)Z@FC`8m8&{Xx%zJSQH=0$r>w@>255mKh$I7jG30vVnA)RFWlWjcBcB z)JwNZcTsl*n+4MebdUp@!<$oArbb#sN^_)b(QU1))~2u~kOu${Ol3|@q)!ZQ9NtRa zn&FrcZyS%-z++S}Guvm{V%y4SWm2BBIjR}#1k!xzP}q6_Q1FN~N+!A^T-yk>p;$Oi9YX45URKF5KNY-yTB2FD`fb370_S2OXE+VhwE77K=% zuUhGyR6X}Yl)6%ai+Qt5^P#*5ANld85@a?RB(pD^DJuA90aIC?K| zJB?m9&v>*Ht`@rLd75I(Uq{WpWPN@X{@WmP>QU%qU&!;`ka2PF zzs130JwZ=z`H64)^)%BuudMAj?Qylvt?`&!;}O?$hbZ*|r+?+z@weIJb1b%Qvd9X< z$2jY{*=w&REH-@?^PP#0cGLG-xrAhEoH`jpqJYP@{CaQr{&IP3$3>s^x-}P%x}C3aJ$Hb7 zB+q_djvYVKI&Y&zR?>>Jkmal(qi`<+U!z5YCG)XaHaj*DGgdBfT%|*{*0Q(Iv{6^q zG*HE9s%XzcDJ!CsTwGkpWU`Z!6NyA}aB#4<_qau#?nmwP2 zJnYcmA+?1BM8RE$hM@SCLPQb6A}Xlht}#&w zsqutSZps9!T#TRkx)?*nhfQzjZWtISRNn6W$%TrPo|uc9_2qBkV)U3% z#94PPVpe#8U#V3LA6&Kw%!%6CB&B!@XjR}<<riG>o=_2?cq0 zl_wQ>&i!kpp%p%T$TS3kSV;(3_C{oiR>7?$#@2rtT=udnAHeT-5Q@g`IL8+R&WF4y z4VvgI%$YZ@-4n`{gw5^AZ^oyLeFAhLaEaZEvwrS1tWl{_z);J=0+**wjVJl`nnM?i zH`&Z8v)Bai0e$om9;zK9T8~v#xn=B&q(ko1WpJ=oWX)jBDO2%^Z&YssXfw}p=cx2e ziZGUFl|T=2jU-owa^d_R+l3aPL}TzbYYong96VB*U%W~letLCWDs@nMV2?<#@S%(iY;d-1V&NgymtM-%^dy1?)*=5jG zrMg&Be?Z)u)k#*bmF;HI?Iy%uPHt&xr)W5yK%wAYm0tYSWDTbUwR!hK2zoGe&bVhe zkfrG3*79wUJkb5qw!pzOtU;HoEa2U=i!oeP|4vkoK%;ST5LgM?+38VrBd{KTXHI_% zslXUIRUFLhx6-hHWCiAL@UZI@G_h?8tToWOa15g-?I4S9er{`f5j&zU74{JjNmaj? zhuvR=Vo{Nj|tjp}?-UZSAcZx<QkWzuM3-=s(UjwakOTC2{sCLIXyk~Syfu&J=2v3 zW5vov-%#K{)LA%Pw}&$+6Ai&WE}Ka%L*+8`Zzkr-2xC8uMqi`bl%y&vC}J3Tx`~`2 zN~L&bs;m;Qn%1ziIUP5$d`G0rG^Gg*9k)u>UOKARB7>13taiBwdf%emmgRLd!63lD zFgf^Wjq=DM!%Yi};(#+2cCrz2DZ^Jl+XH=;-sD{}6;V&?*w`sU*irRn2}gESOJl(5n7ke-FW3J6R#EtuCiN3!yloZ| zqy0)(!sT8@Q1u!SmRv8;mdR%cWh<-T+QW4lqMwWzZ0L5oX&{rbM+mA52O_V*bC5%VcQtUf zE`jpzW`iHHEC%ZEN&pUV6Ixdn#yLG~J4Veti&lV4t2StlY`OIls_C zZyT9}!?3hDZuX`1nQwQsobP(tw*W&GF{g7zrb&gNH;gG`D3}TzDS5fmI|Rio&_e}V hNq$E6zdo6qhZKkPhVWTuQs9dih>wS#dxKj{{vU8BG?oAW literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/standing.png b/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..854a41027357a827c98900864ed5583eeb65247f GIT binary patch literal 8546 zcmeHNYdBPE8(t$t8MZ?^BxZ~m#~J6G%|WA#VK6Ad7>686p-4I~)gZFljI*?dW;*ys=^rYi&;#X%6~ zGz6`{V4Q-Wcw-2fVMCBj0R$;W7gQDvLC_k=-Nnn1OeT{^B)PS6{y6{7;qV*Q6dVEb znS8DVx7(w;%%Kb;hfznW!~5VG=NdQ)7Dfu+hreIlzdE>kkYmZQ+iV9%!{tupY<)Hy z3-f*X@IiPca;BNt%(dknw>rLhXtjz_MOG)n@o?ex!cO1L3PuITmIEiiSOqMc2rnF3 zfRDml5|@l3$63d*jo8I5#hKePg(rlAdj~s%J44MvIS!nD=3tm!I8l|9V02& zb12o~EK56>ym?!)IoC?r=1std(cN=hj0fqKyaV`nceM8`d-Yx5%4ERO>wu+y`%FIe z9u;^D{b*Adg+DaST7J4~yxo;wy}jut^3_uk zw{EwgZnwwnt`A!1f<{_*1MN@VZe#s?4*ym~NRHqPs6hC(=osVY$h6jt!6d zFOK=m|LQaI%xC)PuBoTHCLemgdgwjY@A;hX@wC@{xW|3C%k5F4b9X(ht7>~o1+}q^ zQe8@^xl`DvCpDHhqM zww^m?ni^-66irCnYj9|f-T_~1&`vFu3(B+2wZFyXZmm;ijZ?>s?JZZSjYXtug~Tfb z#PU4*OF!C{oU({g^QQ=m70K9-2N3v^O2aByDy~GEaBc z+~tb)Ldjwr)#++78j8{zRb{pii9~yQdm9@YYinyuOG|Teb5m1OV`F1OLqj|sudlDK zqoaev;V>8s48v{Cns^98KygflCosR|1M>VR1@gw0VH%a>KS zdj8G zvRjN)7LLg?q(SB8W585k@?2=TZyyouZPdJW+c-du9GL1 z`z{omL_`S6i6*gM=2R*S#I()4oKR%R@yvmbAiu(!t(vx zIAisF6C8CA>|Jj1l3^Iq2_D192}V?m+)ReK&?J zKwTF}0nG$NbZ^{>i!9jP(${c-ET})c=CX5)grq!U8_T;oBveR!)YxtXs?S*6#Nvz7 z-j=5-f_q>XLU8XXre5Ecrkv(30BS>5q~L{Zee+0VZYM$%sXp-8?pCeY-hdKNs$yE= z7crA5lS8%RBoL@!;<3{3z>vNiSo4;3=_TD4SQ!9T?m+F3080i^Mw}iRAyzHKTFw8H zl!fV4%uol2l0*vEVUj#rmVsjP-meQXVWm6xfsNjQiyz?p6vW@N^$NZl*f-};*BGs5 z?mnxraJ|pHbm0d8fKeXqtXsdoQM#q=;uyW ze8P0Gs^24BR}mFO#|Nx5`+xA0xuUujEczBU`?Z+z!ED@UgQ!4CoC^&t>s{u9iQeu6vNH7i8~GLl&IF*JcvmuXS?o0K&A(U4gy>+`#$ zj8uhm(e3p7lB2?y5gVxx#WsMway>Y%ud*p=QHiD)0+8jjM4KP=yL~U`LAHvBgkGA7 zN_9w;(STpk9*dei?c4$Dj)G&^EjLur96moYbCfoW5LL6C;8DaHJb0txUmm{k1oR7z z`utB>k>V*)_fjfI3jo8E-o6Sc7E9)Vt}5mB@@qJGU7HctOJwC6&t=GaX?+1(WH*Tr z=9#5aE)Dd|M()KDSNgfE|46L^;XZNA(t1E>bta57U!nEQ7$F=1K4W9-tA}E={_9aY zUn{SqDY~9myI@{YrV7qd>dw|EfU$t7B9=n`5mG1;>YA6~-^p4+fG)D&YX9xDF FzW{(2{bv9G literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/walking.png b/tests/rsrc/bundles/components/pirate/male/hand_left/barehand/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..72113e81ae9246e3caa1b67df87e6b7c9e3024ce GIT binary patch literal 17512 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/hook/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hand_left/hook/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..1ad1e64eefa485a88aaf3244e0f278ddc66d593e GIT binary patch literal 8850 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 EC(mtr$N&HU literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/hook/standing.png b/tests/rsrc/bundles/components/pirate/male/hand_left/hook/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..82d872939b635d8fbadeb4e1876d23866cffcbd7 GIT binary patch literal 8770 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 IyWms*1VUsw3IG5A literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_left/hook/walking.png b/tests/rsrc/bundles/components/pirate/male/hand_left/hook/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..7ebffa0545445c7581fa4c54fd8abc523da17418 GIT binary patch literal 18799 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 BLTms4 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_right/barehand/standing.png b/tests/rsrc/bundles/components/pirate/male/hand_right/barehand/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..3fbf6547ad485010c06a8ad4878e9075c3f68cc7 GIT binary patch literal 8561 zcmeHNc_5VQ8vkrrE{9O|jAb$y8nV-v8H2IT7~9AeMuf6tt%*5I9i1%MCQhQVq;jNW zNg@|zE5fOqgwR5rW2+?c-FN2PKhGcc&wFn(|9s#3z0do+-@Nbhd!FC(yx(bxtG$Gn zq8J205)LFH60MjL(t6}#)ew~Xd^;MR2K+3hJ+wy1_Z6c z;Q9`N5-(&5BLaNOepq4`8lgO!!a<+f)!&B^XA~2QrptAxU(x!E5*d(WRqk# z9>%HQ;3Sw~!RQa{&mv^8uq>t(b1-=DY1q@vHQcCN6>#bC+NV`cV4AZ_HghNpD>HTl_*2NYZgPJmp{4{|mSS+? zFgnIt!^czIdp&gPwnIypPK5vNz>mT3YVg(|^=XYw-RBT+zd0YU(oY?^>)hSy)Y;_N zUTsr*34bNmqA1%u|FmgNj9&a}|36;P=AU>>5|v0xL0fPAKfd-`9`T&&bNlU~+gKNQ zsLi?ex@}{%O?^48CSW(+L)~YbHaFt=@`>lme9K=FF()F?agn<5Bc8JZ)QQ^;T{Xm} zYMX`&)>m^a&S#nyWEkfhGsp-*MdB6hP*S?D{XWh5t&YN*RX_A|| zH}kmR$z+4{Sp8#B=!77xa4!viXH}}>E(%G-1*d3hw8IQ3iRz||wmSD-BK&&BoSkV_ z@RMm?FzS%QE;2#MUg;ky#yibb#8pKF#MC4-Wkq)8Tb45nfAT}pu?oa%ws$V!!KAep zaMw$))#vtAviDUKT3yPsEX%bh%{DJ#8l5?Acq)ERYP4QTgznLR-3NV4_L-0w(RS zUQ(D&%t4)Ky7u896xhvBn&ts__5E&YG>2Ujf)WWWjmfqs$uP-@+rtReIYL$Up{RLd z6^Rz|)*c$ZRtk8GtdXdo7#54Qva+(Yv@|z2H#IdiGBPqWG{j&q`uh54G+IYTM@vf! zi9{+ZE5k56`pA6)g7~0#s;fI_e$PM1eN7nn4dpopBHkmpH24cy7?Q$?f2 z;-Duz(oE>`86?CICf5rsdiI(L&_=5H^44P^8a^2Biu?@%z zJ-dfQ$|QLWgj1q`NxX9LU(;V4kNw$wO{0oq4wLl<{LJSc0Ve&Qn(fPW~+J_Sd)5Te0#XN+LQn=q<(##b@4FuzvoF_HP6W;aJ=9q zo6>sd2Qi3Wqywp16T*QP9JIZjzDD%g)z1Y5yY~In=8J@{0$`9`+war? zCn4ZaMLM?U`L0%q|AkE7e^RJgNAw+Ta{TT6{Mq$5yD9A^4rYB3%klKwMw_pgPBKO+?{y^SeABgwolP z0G72)(bm>+1@{Ex5lm9d3%R&IzDNQhq>bR?u_GQQ{LUyd-IssTVqk^{(7n^CB9J^yrCJM*C? z$oozqhsspjq~HJ5N=GJrm2|;Ae+w%#i-F#W{PMkNNmZ^N67E-kSF4#Wm`bvMcN~Q8 zSAdtPajSiYnV8>Vk@vZ_x170nv&-zBd0EQeEy+>tC(D7 zFKx)hxD4ZM0S*FbY?bUbUWxH<-7&8M`+e7)QT21Py9HdD#=ScT``!&qJq-06;4pR`|*UCv} zXh%y4O;P5$GJ@ILF!$(jPBBI)*yg=8S9jN~)WD;gS_KFJP`n+;kCr?#xlT$y1{$MU zk)#n}PWF43cQ(K~5&7N@j4Ej>*?yeTtC>^#CSP88Un8e9)xhFwn+nLDs237J%zS)= zHHln*)i-l3u&;sJJC~Y<$9tb|&f-gH0zBG{&FGkXG17`s%kgo{Mf(D6C?{;uCpmP) zp+RTIWp&;CoC(S&UOo#P%PZbo*X>e`@9y41)y0wXTzmhg%gqWLjn8#-cRzjK~cx$g(g}F#o(I>$idc?SVuUJ{x89?6^H-; literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hand_right/barehand/walking.png b/tests/rsrc/bundles/components/pirate/male/hand_right/barehand/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..0ecbe245e7235049a1bc0b0d79dba1cf4dc112cc GIT binary patch literal 17547 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 Zru=1ar*x_V{x=bjx~h)KryEuw{{c1LjWhrN literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/bandana/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hat/bandana/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..8366a5697713c7324f050921dc37ec3140da276d GIT binary patch literal 12896 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/captains/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hat/captains/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..9a77ae347a02905e819b1b424c3fbe284aee9662 GIT binary patch literal 15623 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 R90dV?IyaD-MH&yD{U4iMgN^_I literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/captains/standing.png b/tests/rsrc/bundles/components/pirate/male/hat/captains/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..e930b059e9b5d9d3038afdefd9e4071be22f5372 GIT binary patch literal 15588 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 XcfVlG-;8dDfIsAIEtO)W`yu}i&{8+9 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/captains/walking.png b/tests/rsrc/bundles/components/pirate/male/hat/captains/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..6544eede6083ee5a54cabed07fe7d35cdf06d79c GIT binary patch literal 55074 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 z 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 bFsM;1#Ga=vklEFt06%I<+OKL9Z6f{$+I*7= literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/behind_back.png b/tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..58024fdc934e7558aefadf74c7fe4b2ccdff8355 GIT binary patch literal 13257 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 D=9ALU literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/walking.png b/tests/rsrc/bundles/components/pirate/male/hat/sleepinghat/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba521a2b4e015c81792349b863e60f5115de514 GIT binary patch literal 43562 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�Re%oLtU`A-60vH02)R<#@s?p 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/head/bald/behind_back.png b/tests/rsrc/bundles/components/pirate/male/head/bald/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..f253f5a392f5feb8573265649734193503c5a7f4 GIT binary patch literal 11976 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

    B*uM8o14vGu|05`pWX$m8G9 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 VvF&tea90-+!! literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/head/goatee/walking.png b/tests/rsrc/bundles/components/pirate/male/head/goatee/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..d6f8c761d1f2f361d67898eb03c4ec5948d7293a GIT binary patch literal 35533 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 DCyOAT literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/head/shortbeard/standing.png b/tests/rsrc/bundles/components/pirate/male/head/shortbeard/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..8df2e6930b691ef7db7e7d8c2e81e30748ab42cf GIT binary patch literal 12309 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�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 QIN;}@ik5PPA~NWI0lu>D!2kdN literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/legs/pants/behind_back.png b/tests/rsrc/bundles/components/pirate/male/legs/pants/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f4d7b3df8c954fdca1ed2938c85e5dbbc04a77 GIT binary patch literal 13556 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/standing.png b/tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..29c2b1c856c12a30fbc69272a1ba20ac4813c059 GIT binary patch literal 14829 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 l^bB6rfffDVO<7&!Xp)#yocyF{{d7KyW;== literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/walking.png b/tests/rsrc/bundles/components/pirate/male/legs/stripeyknickers/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..65a7f87e7155c4fb9fabe63b12e2e06574282509 GIT binary patch literal 52122 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

    _E<5NIBURj64~IpJmLaiL7a%XPXpk5VB>( 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 W%~zK`vGN}9lb2C>Q}qfK{C@x_3PMBx literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/behind_back.png b/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..7e66a6a879f01d6659f723b28cae557f2b72551d GIT binary patch literal 16901 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/standing.png b/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..e832b0407ed8fb1ed99d872dda2dd6682ac23f1f GIT binary patch literal 17691 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 H7xTXW9gJ?< literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/walking.png b/tests/rsrc/bundles/components/pirate/male/torso/shirt_sash/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..2606fe00c8ee5c12fa2639afeb475a720313d4d2 GIT binary patch literal 71046 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 I1fMbTFfVsG9!#L}Y8(_3!vckW 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 U*4fNBlYp;BYB~=p@7qTF9}Qw3tN;K2 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/behind_back.png b/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..4e57a6cb62b7b25f5f6d271dc847e2ab6076f02d GIT binary patch literal 16968 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 HrUCy4SMx~# literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/standing.png b/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..202b318c929bfb2781523e7f73b0257acb2543d0 GIT binary patch literal 17510 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/walking.png b/tests/rsrc/bundles/components/pirate/male/torso/vest_stripedshirt_belt/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..74e82679ef28de72a0815e69b0339e02ef723363 GIT binary patch literal 68282 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 A?EnA( literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/vessel/.cvsignore b/tests/rsrc/bundles/components/vessel/.cvsignore new file mode 100644 index 00000000..d392f0e8 --- /dev/null +++ b/tests/rsrc/bundles/components/vessel/.cvsignore @@ -0,0 +1 @@ +*.jar diff --git a/tests/rsrc/bundles/components/vessel/navsail/merchgal/sailing.png b/tests/rsrc/bundles/components/vessel/navsail/merchgal/sailing.png new file mode 100644 index 0000000000000000000000000000000000000000..007f7ca6e3cd55ff501f2c2a90358905a2b126f6 GIT binary patch literal 151934 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%0A|@~45_0vM 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 =6v%lY=6I}4T!7@_|CoGa6*;( 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 ItJ+2W4<{&g^#A|> literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/vessel/navsail/smsloop/sailing.png b/tests/rsrc/bundles/components/vessel/navsail/smsloop/sailing.png new file mode 100644 index 0000000000000000000000000000000000000000..c09b89eae67ee3d450b0048001c105b1f14608ec GIT binary patch literal 52331 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/.cvsignore b/tests/rsrc/bundles/tiles/.cvsignore new file mode 100644 index 00000000..2eac42e1 --- /dev/null +++ b/tests/rsrc/bundles/tiles/.cvsignore @@ -0,0 +1 @@ +tilesets.map diff --git a/tests/rsrc/bundles/tiles/bundler-config.xml b/tests/rsrc/bundles/tiles/bundler-config.xml new file mode 100644 index 00000000..19103b66 --- /dev/null +++ b/tests/rsrc/bundles/tiles/bundler-config.xml @@ -0,0 +1,28 @@ + + + + + + + bundle/base + + com.threerings.miso.tile.tools.xml.BaseTileSetRuleSet + + + + + + bundle/fringe + + com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet + + + + + + bundle/object + + com.threerings.media.tile.tools.xml.ObjectTileSetRuleSet + + + diff --git a/tests/rsrc/bundles/tiles/ground/.cvsignore b/tests/rsrc/bundles/tiles/ground/.cvsignore new file mode 100644 index 00000000..edfd8732 --- /dev/null +++ b/tests/rsrc/bundles/tiles/ground/.cvsignore @@ -0,0 +1 @@ +bundle.jar diff --git a/tests/rsrc/bundles/tiles/ground/bundle.xml b/tests/rsrc/bundles/tiles/ground/bundle.xml new file mode 100644 index 00000000..6f2c55cd --- /dev/null +++ b/tests/rsrc/bundles/tiles/ground/bundle.xml @@ -0,0 +1,70 @@ + + + + + + + + cobble.png + 48 + 64 + 3 + 1, 1, 1 + + + + dirt.png + 48 + 64 + 3 + 1, 1, 1 + + + + sand.png + 48 + 64 + 3 + 1, 1, 1 + + + + woodplanks.png + 48 + 64 + 3 + 1, 1, 1 + + + + seawater.png + 48 + 64 + 5 + 0, 0, 0, 0, 0 + + + + + + fringe.png + 48, 48, 48, 48, 48 + 64, 64, 64, 64, 64 + 8, 8, 8, 8, 8 + + + + seafringe.png + 48 + 64 + 17 + + + + fringemask.png + 48 + 64 + 17 + + + diff --git a/tests/rsrc/bundles/tiles/ground/cobble.png b/tests/rsrc/bundles/tiles/ground/cobble.png new file mode 100644 index 0000000000000000000000000000000000000000..e3a1c82cf6b832a58f763668805682723280ef9b GIT binary patch literal 7230 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 J%-k#He*hfxaCQIy literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/ground/dirt.png b/tests/rsrc/bundles/tiles/ground/dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..12286a6a5dad272bfed884fac383862842e96f60 GIT binary patch literal 6625 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 Mq^;O0Zxi$X0H1?KTmS$7 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/ground/fringemask.png b/tests/rsrc/bundles/tiles/ground/fringemask.png new file mode 100644 index 0000000000000000000000000000000000000000..fb539fc1581373440bf106edc190eb874fd7e13f GIT binary patch literal 4784 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—wY@ zZ=4I;B-`$~zv(KKbzBxW$fweS5@X(j%0^iSV#UADZQKH-2?{);T0in&$EZ1@Cg5;PmVI@qi~KY8PlEBz1D)7SV7)hJnK#GS|W zHVXq?0M>v4Mq*A|FVbBAtK%=&jz^A_uhI)|bA44a9lO>bc=*CA4+Y-Po4lX#Sg}`$ z^}a;@Sy_UV_9D^ex_PHT6?1sUkV42U*G0?rqIZ#C;IQ0=!tDP2Z`1c`15?hhs_y?h zWv4U$A2EPr#7gkjE&;wDfV&2Kh4+SMg^_Ec>r~Uv=l2u07<9C=&{J=`_L)bQOFH9d z;h&5Qmckr6{oS|S8@{<=jQxC~A=leS+*G}Jk%fU?Z7UMkYzld?!1v)!+1@52i7&8^ z5F!*ripoD<-=)kbVnl{5egRNmvoF~cb_(h;klMD8^$FL=I zZf1jYmsGTDNsW;E%3l!=o?_?DIJut zYOq&XlEn35�bfjsmiv$RPWLG_J)Lz<0^u&-abkq-9J4^I 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 ayE{v(Hqzw>UT5$DK>NAgvzjMX@BbG8jtR^F literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/ground/seafringe.png b/tests/rsrc/bundles/tiles/ground/seafringe.png new file mode 100644 index 0000000000000000000000000000000000000000..17d863260a9d8b4073638b48f5e7d4f42703caf9 GIT binary patch literal 26210 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

    5-p_|uZYx5ux{I~oG| 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

      ZSSWm7+~D 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/.cvsignore b/tests/rsrc/bundles/tiles/objects/.cvsignore new file mode 100644 index 00000000..edfd8732 --- /dev/null +++ b/tests/rsrc/bundles/tiles/objects/.cvsignore @@ -0,0 +1 @@ +bundle.jar diff --git a/tests/rsrc/bundles/tiles/objects/bag_cloth.png b/tests/rsrc/bundles/tiles/objects/bag_cloth.png new file mode 100644 index 0000000000000000000000000000000000000000..09eebd9aea7ac6281b0cf717b62f7334f24968bc GIT binary patch literal 4853 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 KZ?iY2^nU=~C%#4i literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/barrel_oak.png b/tests/rsrc/bundles/tiles/objects/barrel_oak.png new file mode 100644 index 0000000000000000000000000000000000000000..e89c18af12f0815761d9efe7919969db97b1b525 GIT binary patch literal 5704 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 VnJ-T?!C%3UtD}cQgB|JkzX0KNoa_Jq literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/bundle.xml b/tests/rsrc/bundles/tiles/objects/bundle.xml new file mode 100644 index 00000000..6d90278c --- /dev/null +++ b/tests/rsrc/bundles/tiles/objects/bundle.xml @@ -0,0 +1,137 @@ + + + + + + + + house.png + 380 + 480 + 4 + 0, 0 + 0, 0 + 4, 5, 4, 5 + 5, 4, 5, 4 + 173, 205, 173, 205 + 466, 466, 466, 466 + + + + tree_palm.png + 300 + 480 + 4 + 0, 0 + 0, 0 + 1, 1, 1, 1 + 1, 1, 1, 1 + 149, 149, 149, 149 + 456, 456, 456, 456 + + + + dockedge.png + 100 + 200 + 4 + 0, 0 + 0, 0 + 1, 1, 1, 1 + 1, 1, 1, 1 + 49, 49, 49, 49 + 176, 176, 176, 176 + + + + bag_cloth.png + 100 + 200 + 1 + 0, 0 + 0, 0 + 1 + 1 + 49 + 176 + + + + barrel_oak.png + 100 + 200 + 1 + 0, 0 + 0, 0 + 1 + 1 + 49 + 176 + + + + crate.png + 100 + 200 + 2 + 0, 0 + 0, 0 + 1, 1 + 1, 1 + 49, 49 + 176, 176 + + + + mooring.png + 100 + 200 + 4 + 0, 0 + 0, 0 + 1, 1, 1, 1 + 1, 1, 1, 1 + 49, 49, 49, 49 + 176, 176, 176, 176 + + + + tree_oak.png + 300 + 480 + 2 + 0, 0 + 0, 0 + 1, 1 + 1, 1 + 149, 149 + 456, 456 + + + + chest_treasure.png + 200 + 280 + 2 + 0, 0 + 0, 0 + 2, 2 + 2, 2 + 99, 99 + 245, 245 + + + + well.png + 200 + 280 + 2 + 0, 0 + 0, 0 + 2, 2 + 2, 2 + 99, 99 + 245, 245 + + + diff --git a/tests/rsrc/bundles/tiles/objects/chest_purse.png b/tests/rsrc/bundles/tiles/objects/chest_purse.png new file mode 100644 index 0000000000000000000000000000000000000000..212ee1726cf6511d5155e53277e060c427b24582 GIT binary patch literal 19129 zcmeFYcTiJp+$J0dgchVjC=!$+y(&dYzyc~Al_D*4MII@l^aP}dfPhF7HHZxnrKwa& z=$)vjAR?i6A@o3!bM`#%{%M*^X?8XiyxbDpFc^&Y z{JAp@Fc?cV^g?mMq5s;+*gwz-wg5A0GZ?J;ek|QS7y2yYbI!pU28))5!QvBPuze7E zUxdMKX~JO3SQzYN0SqP>^y}t(r284?Ui%(9hSYPmxl9V?;b7gTJ+};BHd{R}E^-ml>T~t8U z*R#Bv@*z6%*%g-v!;{u;UjO>^VXl=(4ZiW<`!EfIxd$*-D{T1OlsWs|g@9;@Q9sn|Kavfu5}#beKe&k3I*Y%(gnD5wR$?Ox z#>&-Qk@)B$QROIJYA04~C7O3Zrq!NkwAOXg5;?1f37;%TE|93;Ptq!sdL%Ma@^454$|PhuEA}6 zlp{==$6t-R(NVb8K`2u9kg*g;k-1=up#T^qN53t%aZ}z^^-#tc(SLLWbtSp|w1v*e z9dc9=ICX?K%tRV3$nBsh>85`)$KB|L+gj5&jyWRpq2yWG#P6QBpxdSX)-oLSOTwzMdJz#Qe-@Ys(AQk8zqy zas;Xibo=PMx~S6Rq4myL%gI>F^(eQGJkmo&R8ojvPfNp2oLiQQ4TXT~sVH&7S-nJ% zA!3J4AlO`m1uaE{f)I#%JUr(Rh#UNTpQR)kB_&8wl0+%VPm&UqlH&0~f&_7~2t`F( z1qES#eqJ6P2^7l3$!T|c8w5d3+gCnNIKjdlY%W3{|4;sdUEJeB!YQNu;lF>` zvujHVr=ZK91={QTWS$*twz2kAH-%{(T_{i zoA_`J7iWE3ZI=@4p7%2sFPC#j1QMXo^J$MORZ2B#CwXCe#I@{-9HJa>c9ss4(b58^YMSq5gy(IH_{4!_EHuH!=&nOf9^cjhq5L?AnHAEgS zx%R7U`iPJF7l4jAovG~%lZh|65{~*Qtu)Oed}(V|Kke1r&9SV22(YRryw2<|BvuN@ zU*&0kyRNgg#(InlJcqXsyCZ;>UO}M7tne zA>=mvAD;w3N|g8z8>fuinG|2MY%Z(KlF&HLz}vvP|;my}b^ zK8z))LS9~_Y{gcw@xEandcI@ATo6*GoSOJ%OmHC4>Fh|Dd|;;r{cd;?%oNtj?VPf9 zG1?Hvum`AY?)}C$6iTjV)i>myVu!JEzVaK}gL7oG(3;g3hArNCu79^O{wGl7)6%8} zds#6HE9Y_*vEj~1!o_z_f%?lucLIC;acRNb>q*RF<*A!oMCBgpLe?Hjm>Y-AnGrhHAMzE=ec?U?xxpvR!*gQS_!>oP^tg;ksKTJ9 zD$JnrI&E+ODexbDbboKW-&W~51{Vb=H0B4aujA&cRyGVeIeFdVVRr%rzWdVtlAeZ% zU7t~Yv_a_~tF(Ia5<=;kusU}oWYtz&G5 zIv>C3s9J-zb@r1`4xx6sA#%BIh4WWvKBXwFdLBKzjW_Dss#1a!6qIijfNzUjh6@S( zejQw12aGb@?o#e^sm5XSHsT`pmq8K2J>sjE$|z;XDP(P)5<`8lmwdc|&TZ>&E59hU zDV~wk-=S%V%>K?ysYZ!%atHc_=abLbt#~e#a!BS=TfMWGKCuW*HzwWH{ek7opFI#? zGz8dl+jRO^M8KXi*URw(1KJPnWT4v$QOf9lJiqr;vAXa=0OlMv9iGi9)ZTh$eLPsd z0*C{<+jcgSd)}R}JW1X6y{1n0PsmzmVfy*x^Z*f)zv4Iq5TEoiT~at9Jtqmexm}?b z0@}Zr8jOzW(^C?4J>u%GDH_s$Iu_+hU`6XlJx`Z0o$)xD+Fry;YImzu1`;1oU2{YU zvdY7OvhKr59~PA0K648rsyrShH2IiYLpR?Qr)F+kIa;%Y@hPb5^t2bFdlE5dK7W5k zBV~YME_og@;j^yZ;osFd4JhZsqLl}`H2kmN_X_6o>CF~Y*S4w?Yv}Iomji@`n$g`B z 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 JS?83{1OVgy+fV=i literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/chest_treasure.png b/tests/rsrc/bundles/tiles/objects/chest_treasure.png new file mode 100644 index 0000000000000000000000000000000000000000..9bab9fb6f4de44f0f39da17249aeb0bd1f0ece24 GIT binary patch literal 22001 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 F{{YB1)@%R( literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/crate.png b/tests/rsrc/bundles/tiles/objects/crate.png new file mode 100644 index 0000000000000000000000000000000000000000..f5befa8903daeec9a41926295418d019eb750165 GIT binary patch literal 8348 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/dockedge.png b/tests/rsrc/bundles/tiles/objects/dockedge.png new file mode 100644 index 0000000000000000000000000000000000000000..bf1270908ee5c5e27c4bac6bee9cf71ba8ad2f0e GIT binary patch literal 6365 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 Z?GbMS{$9mr=>G}8+T6~p*~B~JKLB$3khuT= literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/house.png b/tests/rsrc/bundles/tiles/objects/house.png new file mode 100644 index 0000000000000000000000000000000000000000..6b96766c934bfc5a708082c1d4a1c0e8348403d2 GIT binary patch literal 260565 zcmd>l`y z-=-9b%v^KbX4rkN?>_Ip;QRggyB}Vc?e%;)3K6PZ>+D&UA5Xib? zN1e_>APOu9L}ql2ob>o6Cf!T=gM6^#Nk<6e{R6Dn_YM7Vi|yST-A`&~Qf=48A# z?)t3&cdrm{|2u90UhbaO#(R%A9X@9392XwzdE)$z&D%o)u7`)*PKvu59&lS7rXJ!Q zf(^k2cn83>;J$7F;Q`pYQK@&sABTrvvEg?^0wVmqLyB@s?}XgNhNs`fKKA#%b2qLK z8~OO?VfU~b*`&`46>oa5k#DbGA>?P1lM-H>ce`@)`qQ3H;r+BK7)*Wh=I!C(4{dCY zT3FbJhvU7xQ|ui5b{p+Geg^M+JoNZUbR7QvHB7Wu!0n`rqVV_!AyJ9paS5BZ8^YAp zjrZ<>sl%?`yy9~5ILg6BfBR;Uh|^U6c=+erpIt8|hN~AQ>YM5de|D8m4A+m*QoEW; zhkt%rVGee*e6Fv_|I^<-Km49K*_r@Ec1c@xJ)ijb_Eq-Pk1wzb1239u(l5FnpB`>X z2|w|KfbOqPZYqzP>@FyO5;4$JXuWrLQ_bTpY3EHZhNb=gteGFKCw=|+vNlGq|M8(`nqFp2TuH~ zfBh_PlR7Lf^4L@0T#%dXi`3w>JDyGD>0LFChnrr^|E#%(y;glw`_8pXsh)^W5yp?B zy<-AT-o4=#bwup}8d)9Zv}ecWYo5+c<&V2+3WuA@C%S5U_N#Pd`=wktR)V{H{)qM7 zts5G!PBmDU>nAPBv2LA3kr6INHQ`QA0&MHCE^ot6{Cs%1HQ94G|H{|97mr%*ejeiF zXtcQo>-Id{ZJ;FTTewqcfNgomq2{<#HQ_FS2aWOroa(V|c=rP>53YVo4l2i9s!j}O z&I+#&cX@d6z>5%<@^H5&S6pha-ccS-McxN$LY!X&IF*OE)P%cvSnsOGdOrzqdlv3p zF6}4WE!W$rG{lW?;YfM7_lp4OGu~GYA286-Dwke|xJ4Yd*>AMd+1Mc3-6iSL`8zI$ zAEl)R*jimZ;&j2rS{(-SJbHAklG1^F`*s-`f*^Ppq-jdc2@-zx)H&(x|IZ)DIj-Uk zh}_E2V@{54QH6dY8uGD>1H^1yjoeN-h|J!mA{AAKL&N<4>q}k{AmqCqgbsiHq~LU8 zd-tEjl20APA;X&+&qgiv9J^}!10vIu^0Ax4)}V(Ep}qHzD%)& zt48Ox9=wUyq20nCdmxK8_$2L+HoLm$^v+bq}F?#AFYO1Q;% zyz|VjOApA`KIE;1$ga6Q#_!TI5fK^d2Kp*7`6SX8uhh=vzgkSQHA}d$sFrZyw-g@v ztt^~ zNe^p<&PBtHS4I;<2YvTRhM5@-1LQ|>trR`62vjuC6e-E9&m-N&k%cpAxy!C4LX?uZ zsK4dS{9mKPBrR{yYLF=LM;_=h;LXOV5;pzU_Y-3nYQ&z;N1x8a6BibM2VlA9{o2!g zW5QIdu06x8s?IYy6a2^VyVmAz5B z%MC`Egj$PQeGjiMFm(|oX~Uxz(=5PgUmicf@gbuVFwU2t=8lx~;Vx;3g(qjJWtB@9 z`>?S0vu5?!So=-KG^C?jfkS=4wy6i z;5A>50Mo?&<3An=#Qg`o9&>tzYLA1xza%mSAD95RM0$9j$D~nDlyk%_rRW}8fm%tX z=kZlLq-y?~-(?Fchqch1$j8_q$jTrx)-x?PtY0Umdxn78z4UMDc9OGc<;sd7+S5;Ln>=e4^G1h&hTt9O- z&;YtMXrJzbbwdhdGjGRz#o1YB4sS~=%Fjw>5I^f7sL9NbAIuSPFw%cAySC+W{4CaY zEOyB?-SITTk}3>72$+&2VRNmf?=rR>0IkU;huu57+8Rqb!shx^bkzvzX9$?|Va#2= zz3sloQ=@JoYWitKRfo17j}HeVkNB->Eocm#JS`A|om3jAjgx?Wq2oh9(BUm^96Y0y zm2++dp(1A~r&c{O9qGcfzAI6xrsrhi+|z%pz|O){FvCD|6K{^=HN{*@UNnzWTQkLL zD4D90fz#fyO?+7j|;Ft4e(m3@!Fd>h@VIxC%>U2_sXx0r3x z>PkYp4kqFEZ5|JXI#%SCg8DeI2Tg3vSb(}I@5P8~1O4&@_Vam7bRZo>kNA#h#IJks+EamZscKH%q(J!>EBxJA^ToD5;U{_Efb2(gct@LeRkF$H1V)}87TP@!d zU!ph3aTNLvClUc|QirV&;xgg~erBv&7Y{i&NL?DA=0tWeJ?%xRlD5zzyy+uBKCvxl zCBZ*F4XS4ihN9WhsRPvwND|B~pu#IZm0Wb=h-Gl(n- z)6^JUe3XS84z9{DSC;JC;MqYtwC~cBe4*)h7W0IhqzVl7k#w@gTTa|rjda1>C5iiX ziMg)TvTxSw#jD;slBtom!`>u-Au$q+fBY3mIM?M;4mRUfHO0gxR+8iBuNXJwpZGj} z4-pMm15&rIk@wGYJH||;iKBj=(5d=#=9-gAT(iv=AfK0e%N!dpT2C#F%wXJGR?PRX z?MkmdiH?$-`1I_}Dv3kHXU@E`0)-%1BBT6WNaSgpO1mwNYOWhMkTV+a@?26}qvtf{ ztDw<^t-~U;QFi`<){c;?l)VLvA+l`#F^6MC^xgj!eI+!J2iwv{OF1#S&x>G4-%fh7 zYdBi}fbzc>0vYIaw+J<_4-69h6VD{Fs&(owR_coUxt9c+JfCv+nz2N|afzidMo2f% zVlX8xz=!|5GKSL;mqVnla{@$@h0rj&#BDBH93Wd?#`zSCX{!bArOu%Wx1q_^=JO$p z$v|wsyI@iX;0=xcUeUw`^Td-NaA`*=Sp-<`)sE8s6b1&ap1v-3yc^dLszc>dc3Lm3 zAP#LGm?W2@;CJWq3}(fWCQ3~qKTTe!rL7&_Oa??e_JT^r?mmQ%(i@KR=ngG8#j!!G(^mm0N8r25%Km-a)7R|ka2o(YT8U`>iVl?1%5!l&5 z@r{7}#l8bK!ccH~P|{QKJbdL!(^D=Hb=%x5g*G8Z4WTanX+)f?Q_`V&`Pjts5s5QG zT6*&Kw`Jaum+wq|O4XY~JKATu+VtMf9Ss@}fFAxG3Dwoki46vRx5owgMDdat(;j;W zsFXrkRfo{&TA98^gs#sTv9MTtg5_l=r|&PM3o)P$S38oL;3XEyoxg*B&&V5{ai#hKEuo4rx3H+;6UYvs1ZVO!MjD z&4~}B?^mh5JNi}&6`wQ(Kn?CZpoLx7SO}PF?KG0yzOgkH#^5PM`LPx_$oe)Tq9%c8FcfZUJPZ*$_ZBI>RSNub*76tc7ly8YaS{rM)Sga^_IFdc*yM9AI5d|Pc zk`*Sog&yhcjWq`7AIv{5U`>{D9GzkRy-!aru~|@%oy_1GLxTuMeJW<^8kLL{qd^dO zUfFRQ{&!zVd7Fv8JFSN`Zuv@K-=+JB3`BKa`~j-hF+yqyx8TqjcOe+~F!rB*r+AM0 z9ldc!C8=$`PPyF5e(7zD*+^6iWn%jSZ7T#k;4Z>K#Os8F{Ji!WX>RcniA4Kab%Lpm z4XbzdxJkpht=ldX&9pL^+je6BP~1xC__?c7Zx#K3odwAnp4IohR-U&A3Rm^B^A;BpEc7JgD&ZXL_Y{m(v^@)vMdrC?c^c@LcWnkVm5g_bAfa*Bzn*r7TG4+W#C5rTattbPi-Zb_z{d>xyTPw;>R%;sRTA zqrJ#qwRLA6xKw41Jr6XM7R9J|zLf0)$*mNF_h$=tQ*(=3*FS^z@VC-d@)>}1kt2VF zp_4R5mT(hUJ{K$E_`BrBK_(rU+(@c669uYjx?dEoJ4zOIu$T=%{?}lTEP5_TWo*Ts zhWz&`w}j8Fi0xZSsHA!kJB_pOHRIb_W*!KhvTbc*WoNAW8`Y0Vhy6GxTaR$>Le~ce zNhC``%&CUWIX=)8Akqkiergo#lO62N=l&AnH6TViGn?QjSpar?>?F{M`E5>(Z%w4pg%$CHP|RhLH4t4s5)xf_ThXr;FtZYDa9B{ zkYm26!EwyJ{oL$?!u3=`sLX0`P*{&}%N+^XcjM1yHK@1@NxS$OY+|eV0T2=Hm}` zajC|e{Bf$3&lXgLalb0ehdR2IiALD8>!P|q4OGMh}(pH18{}u=Na?mXzdB@LEav7 zF<808-cQBEO?AEjK~5aHWi(W)^uJ{?*bjtm>QWS(n>h8hN#-?bg`S^-92Q0vFy`mh zex3O@1;#G-kLy!4>`53{>tGV2yLJny8!ZM$+`ktcVHVasj|_y! z+-9Ch<_AD9bw&9r#kJn~v(eiH1{~)qKG|YYxb$Qkq5s?&Pw%wEjJUWqATR$@ zt9o~(O*v#{OLnl&Dspb&F%v6)?U%Qo!?jCNtf7(5%qLl}EktW#MF$`H4wM=`Y1}*u zyX8ukC)UPtZXC#I&oVT|3KwI+V9ACvU$5^A4~gwVAMRUkth z8QQwTzC8VR+tsVSG=ef z^?=*w1=aP5UL&sp{AB$x$HwqS5*RwA$rs?|J3x`IY+wgyTf1Yewz@UkSX<+pw%^;( zO|&m~u8pBeA`1h}213I8LSE()?G;v;+VxE8W61x+PP;oXVvaPs5ePky?0EX0J{Yp1 zN61B+u4ppMbzddBkD6ASR^9eh3UTcGjg%PCd5;_?cl7`B6LofU3nk-6q<$RjhJIm& z-RN&6A-+RAZ*!6*#+xjm(V8-9t6L`Nu*$npci|2)A2TXdOJ()qAAVRY3x;9nveZX1 zZj4qERRRCgR7Q;Y<~|7?yiWV!o6@Zix{z3;5N2cO#qYtxJo$lI7;fQoTFs%-qQicX? z4I-4)F9qK&#cgQZxv{rFtLHknUJM#!A+M z#-H=;MY!FKoo`nODOED~BV%Di`S`0(@N+w;Cu(Y7st$1f*JcTTwxrs;p8tM)&#el@ z1SS)tiMv>br;xO5q6)EhKY<8nA_WKK|*Y0fkhdMl> zQuhURq3OwbS(!53_Makqati$8*$lWKykgY&{(D)5muOOi_`Zckfv7sb!1s`2_%!Fi zCbmpF{akm7+isH!Kaag(7j8cH-dafteN|q4nA$XU<{&=RKPKn6-f5+REa^yJIms}{ znv$)gVnw}p!e@?*?3ENl-FV2Rv8Vr!_~?IF>fHf8IC5$G6-qN_bYF|7K^Y4I9@1Ny z?71!PK4N|Uj)p!=s`?Srm;-=GJbq>}(ee?OU$r|Pf8TP@+M~#B7F=kX?v^i-RiwYM zza#`X<94ON)5xjkXDCZwnF^?z(K8@(oNwW&A?>E$V5k;An|4$!eG3NLSxzkCuAAc+ zq&QZen>>A=_naPimv4M8Tzn*=g-pANJ1bbuO1ppV=!V+H>j@tGBzWG<{CeTi@rN=) zvd;g(j%d)#JP-9-@J}fjplb6cf3N6)QlxcG6hSo!?baNHS zEpcn6Kz9ANugyDHiAA|H&6fB`dX#+6#%XL26sJ29dywgjiW?WUG%bOf*54Tju-0~3 zlmIUqn{Eq)kuCJWjcXkszPBXjPU?OlR~DyIGmk` z_23NaxoTo>C3zlLv@pZAcpvJdP`Co+X(lnFZjjg}7Id|*60)DhDwOV)Mo72p>Gznn zvoIH$G}Oq9<)9xjRurGAh+vhU;SwAFSy5w~?DhxMN|K3<;7X!)UNTzpL9$dhZC0_5 zGPuBw1`~1M`@jb>@ z3e6*(NEY)umc=G&^q1s+*Vi*fO%lIH{u(k}1Orw5#)J7huT-XbE205)-1d0h%iDTJ zy+Ap3GuDNC0d)%t>NmG_34P}H0EYR@*i1V9L@(ILo#aG+_aeAdTA`~$kB*!pai~uw z|9C)WA{#MC&6W>lp(Fuoo})6J8-gJnwfEq2na^S4O0T&hq5{G%MpGVV4*K}n(|B1z zleESm=CdwrB|?%F2#W4qnpaXJumOn-RcuQ2Rk&vqMmfmQwi%$&LH-MsB~f6&!Hbyn zQgE;{Q~t6AXGnZnN^4BnsF@0FUe~638>5^Cal;yXQ-b|McNc4NM)3jg>_f=dS(u1^ zS0du=3>VhvT8?Lc3H6?rOuI!H+4nLtk32c&Jf@Yn*QQNK1V>{eI%tKGb$Uk|f|+G>U%&C=yrhKj{43rV0;>Sd`Wgh_~%qI7c4ZPBQ3^}(fVW?64- zr19o?*pJy0Kk9JiC9YZ3xT&g~&xXyE@T@GyEQTDaFAGRd$C9HIqJeJ>B&FHcy2*nB zM^I$5Dv^2sBd(FfL`?xf%4+)zo*JkJ59@*%D7r1FhgGweqP12-I%)e^sYCSj&L~##i zG3hEhMg~w;B$SUok9YQA7XN2#c~7t^k2I~D_>(LwhY{`9zWMuwotnwsQv1s?Es3m< z_wD;n+^BQ{I25?&J5eCxv3U@0o5H4C$r|IA_CSckSt(|F^eQ+_Z^Z=AIUr!nVVF{F z3?$qHw0(>uaLvT}$3oH-qd%+n$o*yc12^4Nu z%O0YX79b?45&=73h%nWn=9&^w9bxZxN(-2O*avs)Y@eWm|0iPPWuO#BU+*E<`a!y|&@w{K)fAd+3%u=Rd|C2c^Qntxm4% z%WVA*D^-r$D$@d#!#cGk-_(I!0cJ^=*3iPe*eZmFvero%Gqt zVhb6s13+fOj8(F!&HsiF~gDwa%oSt={eOEbaSzq6Dyc`2VzYz95 zzTF`n_2Vg*Z^elNCj=d#GfDSG$u^HL#8A;7Zv%Xwv5F_VMlWj2*Vh+nz!-f_x3~BA z$v!`!X(0@55-l1D!C&0%@Ih^4?I*E>rdP6*o1NA0W1XjY`w6r6*Dc5%b#mc$)a^3H z_i1I=E|-x4Fm0_J-?&|`x#4}3BnObiW(3Cxmy(1=U&f>~2`G90%G~Vzt=ny6D@yYn z<`63T2#hQ-1$mix<(fSZS!uAbC?W%JIEePkE8aq|Nb8CvbPH%9^rgdj*HUt{Lw^O!q6*9WLeXaXQ`^9dr*znvl&L&%lQ`0v@DH2^c-+Qm$V*Dj1roZS#4?zU9; zTMOo+z#u+*z>NVOfkJ}~p2iN4sy^5U^DNOz?S`k6c-IW2u5fKB-I!u5;ni3r#`gkj zU>7?+$qj8 zm?9K2OO+Ze^5G-6BW}k3%f{@-iF7jE0(l!}Dr^$6etAQ0oy^|@RnUDf1Oo#_hJNW zD~_wftY^gabm+Z`6q*p&vnnW1YED97B((V@f@qP)CHs%=(yBN;F4;*fx##&$>J~$% zK|%9Ua&|t$&Qea1Dg>DH%cfqBp7W+P6Cdg&K9|)Zuwm)Jd^jKq2;xbKj$K&(?SAAK zv_%cJpQ77*w%;pk=y&hM8~wSzO>;3~Ng`u{OWVfHw%*v+HFRF0!2{7*4AgkGeY*QI zm~n)F2ugSjFyo3RZcNn1z;QmT>;0Wt5-xBw&R8DfE@kH0vIShB;$Vz5euNx}J zHXxI~z-6N950>c%(7$>35m$~lwtMC)zc127m!0@Ve*l2z1|+!5eHPlmuD!#58s zz|T~76%3%_@4Nc!dfmk0)0vYXoCkL90v7#we|=M?oVgfxP;aC`hUHN=K(%O$G? zqeGFw_L6}>^$9Io;YKPCje+Bi*%^!FT~H3i0-eLqApbqk=N_#w#$2r_XlNT1p$5_89yp6NFrAE6rx*D=thT zS($q#y3uU$#vA4;0oTaB`xBe^{%$@)$B4R?keorc2(i1c?qXs$YpINqT~g~8a(Ipy z(&$;!LFrgNK1q!vL?V`PST)FbL8<}PTc}%YYZHEtL0)4qrK$kZO|fJ?T1j&5bsUA# z#S#An@fuK?A6)^_e?h*I^0W+ZV$IqrwD=S37bmMkp0Rv@8 z;19zT4XVvW8p72h`}iYFQnN-{*s8qaitus%7o9|_Kwjj66MCpl83w)nL}o62Yo91?D&QYiuAc3@T_usYtyS6KJ$D8sRjN&CDHPUc`7ctH)BcdA&<<@gXALdn@gWf)9?+m z;BRLbh@`EJl6ToJYtBS1VeP~V%%1Ed;sJO2#X9V&)wtsMh?kf09t1zu@INgv0Si3n z^E1;KricK9Q2l>L zUNb_a5(6L3VqvKRDy|=qh16xSQsTQ2%OH)kG{*HQ_|mGj2poA=)^oa@Dp@wr5)`AL zP$i$Dm11|97w6!E=a3=}r}EWjB=wL_?D;%LS<+Fh|A_?bp~$Brr)Gk+aktw~w6!B1 z<+oH#rq}4rtvf~N^f2pBlF>0GN_IjMuE#dmY+N$ccorD(*UYn}WEuPgTy>d-9Et`f zjYKYF?$H<9tLq;b`K$U|UY!hb66RWBqAvUGv57U{>3+daFlltyVHEFE8^{k7s(L$i zZAegYk>L#Z?%7|RZ}50Nu*?h z<<$>PoJg`TvI`6j22!Kvn}ys{27XL!lGt7RrYE1mDi;hoL+zj|8n7R!u-y0WWN}kH zyV^o0OsPkLq{SQvIL^Qv>Fx8--v@kov#@b){W%3yhmY@rC#BD?6ySvgIgnf3YdTO~UQ& z!?Q?IyCENtzJ+ zLsC8P{bM-X$~t<`=AZtqv~>Jr`-xAnKhpX)oEKa=%HpiORjhk99h6)i6&o(ZdUnW5 zLB0LeJ6RSB)8PkCG<=89$i-iq2!_*r)-OybP}$cru95!jyQPlqj?yY>R^=Ey3nkC+mZlQBd0klB_I)2eU^{OaGsT18o? z4cPa}I+Lm$RQ4|H*t? zl=qIhpQ-$Lx*{&9p%xtt;BtfF0(rvXpB4l!ZIktLWE2BX^N6faXZi*GBIBx%VA*@2<;&QN<||Nw=Q(abM=Y7pV~ZU$QniER3`P zYamE+WN8nz64Bq_i%NgTg87ig&0&XR_Cr+TKUjD=s;)_7G52iy@HH=Q>)`uC;j=5T zgqWn`E(v=tb$M2Ii|1r^FUQ7P!{lyn3M%1uM9tm_b{g8`W_IX{*QWOD*Iz9`jzfXP+RLk>7i2lbp;Ihqh2J<+Et}OBQQzezLB#98(v?=9BLjK^17(Xntmx|t3Xen8uw7R>>;9W$*-he zxZo_2NPvQ(X&c&f@cX;>@pTd#Ln;|v34&VnM!Xf%YGmK_;@X2mUh#W2$^A2UDW2bG z4Gk;|9^Wb#4=H@oy}rRgJqZ)+*4N*5bl27mO53)wW%rLb)FWMeT%RdvZhI=Y?)EQz zS8S7HxcQqkzvsfRX)CcFK+9|99*wf%jv6M8T+!>gbkf?da;|3c>3rCG^|Y~!R}_3q zu5xJ2(W8SG^p8R>UqfD}4{9p6mQJ15dU8F(e3y08X?*~x%`+!#POm=GMX}6zy>Y_v zNKWUWG{LTt7aQ}#M}|(zZn%dPw&rD$$k$Tn%ffODQc3$NZYsOHda=K9uae(8?0%00 z#tB=oXI!x?GAyD_N%o97NiI>O;oNH=@bUktP?Pp=zjyN7%wg|%l|2q>2VwWzRkaC> z*8E+}YvaEu;;=BxVxKjwn|$!eKT2a@e`9h%W%c*(fm5xxIQThXXpEMf`F*XSh%bla zp^GnBKNhDi?Ht*e2g7$!2haRbel`y2HVU8GZ?WZO+V0bD>(b16EHGRf9`5H9zcRHY z{*Hf~XUD7hOo%ySx4n_Wo$KR!19ltO5$bP{5&1t2!Z!WYi+=p!Tbbg?XNRjRQkx2Y z$=47zqs}>*Tun*q7#es)2|?}Z))2AGe~gb^of5l3TDpVw`Rb)MM*cWv(6D#E`HoS< zx>uteivM)N2XYra72I6=G~E4?!nTd-YTJU+^YdH|%${|kscqgf%nTbXzD}j@ZsqO3 zt=WG7fjO~VPN}>9{YY9!N{#WkKbbj?l(1eYeO7lode)vJThv`0>G)+A)JhC|wH_@$ zuccDb8F6#$?!&=Vyxu8YxnSqIIHCMJT+e6F&pT(Qis&LRT#WU#=yR$L z-1g#z=TJklpyGl^&d_kWus|r@K;k!S($j($m)&)YXsYxYnFv^YdalB6hq?MK1go_+ zcJTAkE+@9lV`v4Rh&{kdRZ6%MeY(x=V$<`AT6dD`ZM6%Jb4i<;Y7P*#@4B3{lF;&U zzrQP3a-nnYXO&ne29BB=-b$K+@2Tom5@cOntAA@`X7b5OZ;#5BkA)rX1?<@;AC5tl zl^;)Uc=hLXN%vdOuJxyHF?qDau>6RTf!F0^6Q1hD zAk6BHskscv|M(p0d$n0*=b~s6ssqEa^!}`AdC=tL&$q8VP9FPHGaw9Id$Va<@vo3z ztIa)>!rv(D*p;tPcS>GZNbu{A$zDc2-;clXeVM)h-g2_ z-!C{&HM8b6Y;-C+f3*EW!kuaB%#e%Rp;{BN*^w+6zY6{+WAxf)@AFn`nwa`xMCh+Y znRkZqxQx@^zUw|Iv6OhhZmH8JE5ak z*5*p6-8>9S&zKkyQ$Z9!U-P~%q5@J(eFQJCMEoZlud~7 zc0ig7e_hH*oF4cFf+TxUyF@%-c-{vguKa<1iow*8u>h@QdzTz+6VBkZ`1>6M{BsXh zyc(RHD>KqBX`vJ4K{L4%76bsuPOJMY!3Fu99qeIc;0v-YH63S8kv(iN^3FIru(e{h zP#Tb=sZZOVpwQtAkj9_6X4dVp)ic~??GL%245^rUiP^8loR4NjJ|;O z4h-b;98)tLo!EPgRFtXY&W5g#wGNj+VE6{7NoN&i8pi`>St|o}*%=`S6iKqPY3bD1xieg~kSQtX_~|iiDTBe! zsN9wj{aaTo)TgdqoEKW`Xd$auZC~6?26|e#$qWrGS}?Q$Gn}#68fR8j>Dd+fQJjeq z)*jN*Cb39OfG!Pf5=8h4f?;jw+Q2`RA5XOjMAloNr%vB!TW@^kH+VS!T+Sf!5m~)o z0b_59eV4}`A3*SKncE60^eek}H5Fv=1S!l%ODF<*zOp&K+jBvM{@LD4tR5(8Wsif& z7%<-&R zb*(Bb7(eE3)b%*>>U~hlvaD$b2}Io;d5x^{R!W`qy0x3D^V~tDiod79L67y4_{Kt} zPieeWg$%wSKE&-aTIfP4uye;;ywUh~yH;I8V5n1JODAkKrB%gX{+yOR&4Qugve^Y( z9r1fO$yok#GoydAwB)(#aV3S)0V%(Ne>wDB=nc}}ljR9}Y16=NOmy*U^AucgJtq^i ztNuQYVk%r9ifRtrX5>^$0K(z@x;|~36pK$W3{!+;7Uw&~<0hst{>DO~zmgFSGnx2& z--{dj03T&R`Yaud`h`kti3L+hnz2HUG0jAlSJqjmkET{kN&D&4I#7eUg3`9~bX3mE zz+zjKmfP%ZErRLW04oeG6QZew8X@ubw6X3TS~eUiKqYMU#_oF!=D%3_4S)fo{Kjsi z3YnqV`q5EZN}mG~i!E^HzEG=9P&N+kmf3$=BIb8@g{uvI+2HqR9NQ*h-tW2|v{g#v z5~aHGO(T z&;`Lnj8PYBotUB`&4nZCta@1C_)ad;0k9VJpg8<|bjRl%oRNXL;u$5mCJKq>{Yn>Rq z-NB%|uJRR9FLaChXcJ2;F@)wr_do2!H-N#e>O;z+X-Y#8X2o)M%amzVq-q;043#m+ zC2Pg+8v``Ezdazoj5iTpt@ya(V+EzZ=BKF?#nGV494c-dv#OoYnfFl8mnlVDqv!vQ zxA&Rw69jMV9)VL?xndjB48gin_P<`!weutvZQfdp0G^3n*Ro(pWz{aD&i=z2i5tCJ zk9`l%Tz~k0v>3IE0ycLnDgH|YLk^O8>VVmrmjF@VF|VHnk$cWZ`RoAi-8og^YUJOq z+Y?DKUzwjG+rmt@Uw&;1&?p`6+9(cHM#}|q;ZrhIS66d0iyR$zOpU8I2?$F6R<*Q+ z?i;N?nXf~oxVET$z02pEd3NE$?A7wHPG+{^>mmUd31z1+ z&qc$v^P}?7wprD@9)4=#>j}mkrRaWB0JODy5_j?pdwpWZmTYb-d2M~BFV7Q+f5@hc z@f0oOu3Q^6wee5v$Q=N!FIfH5E==ck+8*E~x(c)tcUHmtz)p((lg4%m>xN`wscRuU ziD|U-_e{g*ZK`_l$bu(@WJkQ*@i-7?XTOr3hPM#XwHO&H+sS64F-Abple%AX3jST2 zzDI(A+?pFfr};}_8#!+5`C~p`qCqsAvv-ra4|}4xKLde+<3vFU%xw}{iT<|Mrf|NX z-~`s?N$OgFaiJcCT@0TldZuAzR;o)SI*Xy1sb}|DeH&q-9qrBu5;9Vi%15FZP zddWNg!r$o2=4Pq&=RS=F{t`-VeQZLobtI9>#vsbuJ8E6tMK`yb%4D$fjXssN>r`>C zDzibwlmz<8ZpoKfmb+4b%1GUabRYR?Md4lO-k*{&U7f<2$#t2hgsq&YLsGw9Xt5yw z4e~o3C7iaG<3y$_ua|}y)mc_GM*?+UAxwMzH^tI${T!&9f)ig%5`EnvB21VLGVA5#Qcoo|s zcuCo%DO1te2$My-!zJd@y|m0kfJMxmo z0(H+rFOzCfWaLKa7Nyw}y?R=`-%*3w+Jh1h$_xX!WAsSqw}FnxMf0}5{!xZf+8i~N zZ+JJGxQYJLU$mS*GpoEZl+cBd2WbZ_q=+w44$VfLPG3=x6W)fFe#Mr{qSW!aM|;(R zc*`BLS-p>#V2uW7<_$z2XOqT&-kVe01eiIU{s!{>*oBr>c{#M&pv7vTQQK+~S5eO9 zUrrghrkdrf!|*oVuqRL=3V5gBrXl zE_e&C@P&{6y}c?_^OJ<8d_ZEeMQ!aYF~!E` z>rB!p6-Cw}k!e>^RI;QPdy5bX88gO~t&ly-XrmpekY$FkZ=;X0WEo?ZWro4*_x;@8 z-(Sz)&++_i%rP9-T=#XI=j;7C@ubA_w=f)v?2_SHB+%nbW@cZvNzY-BHnVKSlHttxtNFnFo_Q)>PtO~q*0j_=2qGkC_74c=y+91BxoNYFGQXez~>wjFzrW3^a z%0o{v5MfA;zR`T*sGy5ANBDNK0&G;EST=RvR}sNb9iJ{+LZR@Is1GZ3hOj(MTvxH6SWii(?~l1Rt~5Nu9yG}1_OMXJt>y!$>gm{u8{JxMx-2}B%Q`*mC zAx7l@pDgmJJ`CB5s@Ze*vo6og{tTz;Q`p?%Yxq`>2H>^UugsblEFm|h+3G-hM;qt# z*ZQY{a=b%r?k%YWjI+wlmL#V8grITtpFV}*MkA@%tjv|4zOXuZb2gcW? zX_Ee}X8a#U7ACWv>%6DCHsMeudHC;vbfx3=#iLDvxF>n_2&Wy<|6DOFt3`?!W;3(X z-Hx+)2`Ds}n*xL2s5l@QygnoEv3)xj{>%RAg$2v_JBSIko6i91>rT1c&<_VKv1Tol2N@b%Pp%LK9o=#)Cx&oqR=K}Nt#m(dtc5IpIMitTTTMFQ zftYHQuD+C`ZS&3jyHs}1(g^VQXAyGw_ioj03i&xRDf-B9s5QJX7;?ANv# zq^)g^N^1v3L@D*c3FLu_D@jzV%^|S0t00@R_?P zoeQ`T=AP=d-2?kbWiv|tbzU9~%!t3IVJ_!jpYORi9BlB!ToHjWU2TQ*N1Ex(G@-hub0 zt~~%VKz2locs~!-gFc#z3~L}oupxMlgog*bMy$wK7e#&}5Ww-8L&0cCuAzWB?Lk^H zO-*834zT@wyG4jd zlL{&8^CWKXPW`;~p4t~&DPt`y7Q2i_sE=nDtyvXGcc{BNl~a$-ryiSqf`V~j!kIXW0{3DCh!UrV9;L@0$%bNvSH zq0vGpnN4Og*FO(BJzF>}C9oi&#bXK=Mgm~lMSc7?13dga!mChGwx{V{VdBSJY;Me& zmrjD_48(8$#N^emn24k$YcT|`)T!;}`*LlLEdp`Y zU-)2#-%fttdMIc)F1CX^Xlt)~9f>fIH4*>6!}#V?dR2Fe%My)?H#XE+`Rx!U1VFiX zc6T)S?}SQB^wF5AJ*?qdRK2yE_xRL6*zYgiM$?74)$u1U*g2|p39IH$L?vbsYPgl# z!}iY5rJj*&h-bhp)&r6aUuLmXW^x{@Rz>mJe`hK=W%utw{vt2_Tq?+sja>O09l zG_r5%%?Pcw1L&DyEfZKnl^R1}P`}C1vfOTB*B_8Ngp9dpd=D3>3r3X- zwb?|v!ieLZQCYv=LHdf8k(;)4AKis zD)6r!FaMJ4>nVB;+pvWrV$mMWhoI}}>aTz=a(n80(2@uM=gt%6pT2o@Xs*TgGNvzh zR6#*WRX`G!R~O9w7B6Kx8fkY5y*w5;0`eHoX-_0Cn=bxN7 zt}W&SRvZrlPj0aFI=&*odP0R@VXzE^LS7CTJIwz~A>&rWD1S=f7LjdVIusO-!BdKH zsm~N+>i)Zb_F<7PF${_8`jRE=B=_*M9haV^yi}nMmccunm*RQFQ_m2cg$SUI2ZG6I zedv$t`Dfw)EzGR9*fzWC#!*SJwV_UufN>z>Mo)PkUsIe#D+9T)Xq>ktGi_?Y3iFZo zUiZmrPi2#8Lqj&%079e6e;bnZKxwF;gvPHy`0}i&j`-l^yaVuYTBa8_Hw$(Dd$?w= z!``WHKwq6KEbuel{GGEY&yDGPO|@1%_G5Du5g8V@tG&)s*@Q#(^QX$*1uewXOLeKO zIr>Kl?*AfA{#Ywh!+JedRt^X_65gZ1yT}92Vj4BJm_fFTi72^`^#>mffdvBr4i3n( zy9a9S`8XPJ>_v1)GXCb^PX4{M8^Dcht@*1#mhmwbi>H7Cw^TfQ!zh9CGjh?bc%Fz~ zNaUoa2Zq<%R&iJ~C*Ign1JW)4OTP)0U)b?rBvV89%*(I}nixM~T#mbc%+nAUZBGrS0Gydrxq!?J= zU$fz~0VWkcWfzHQa+J-r=fi384{6<@uvVef-ZEUcb|Zze-O0k@+G=4>-AbTB*T}rv z@?EqV-p~Rg(57%eW6g5^*^#C&mN-Y`*P;Fg1;^r54pSQv4C;Kt))~u0O{*}_$XHM) zao4p=;Nyj9z_7DdMVFVJ zcZO0MjG4P?n%9|Dr6w$?{qbt>hGOG(gj3N@Z)o!)dWtDhi0ds|;e}65?%Sp>ZcbC% zEDabR9o+XyTsZ$LBA$H*JNb2T57;2eQqs{`ER+J{EDZ#6!r>0`cXsdnMsPnI{)HVi zE2j9T`-Z#bf(yK^KOcI2Y=u!9Y9l8i_Xcz7}s~`xZGq?&uX3k+GZP@LY>xj6TA;mzlRxXr>i0!zJ3aaImQR~Q)j&H4t4 zE0@463ebRoNPf+eJq3>U5BZ7^iR;Tf*Ut8NlU8zCq}lXXrC8d?lKoH4)S%<8_%a(> z)Tw_tK;87htmNm;`I%dkz*M@Xlz2?LkXr25)z=-)zS$9?K-K@tS+4DKEU~h2L0&|h zc%oG%b-fwFr-ferLN5uUA<4Y``)&xl0!79;bv>j*#OyNKXA0+MAppl`0?h@Kv0lgK z?GNuS5yFje^}Z7zKYfl7V8>1-ytHQi8q{heGhH4o?JHLXz(bU;t{zEhAxvSOam;$8 zD~5U#nc4G5v^LHHjz%_A0yqwh&R1`p+YbM65?)7hHPQ~Mx3{D|vQSQ>us!HbnmR^bO;|Lf#-_3@Ia8qVU=hPx}MVZRfL9 z&${}MON89gTGSqlj=`c}X3ke0woRs^K8JIK$=8fYnYv0kLF*wm&3&=ae|DO?CFW4E zE8Q(#4*fY*NaR1ICyFal^v`9xr3Arq^73{8tY^YkTmP=K2%k4@8c1i0WPH<`Lp?*M zkR3jX@J&nDAP$)3fjMj`zE(VHE~}`43tPJPWkRx~Pcc*)Rry5mCWg~gDtLy>^$0^$ z|K25}bDNl#mi4G^7|PNv(D)^FDIiL(hWfU-9G=@#J>Z#-k=&xOlY*on1yr2KA&z?j zryC+w)465Z;(f+&zyDNQz{MYo&9TGvHVf=sL{|*Q%K9m@_AmwI)P^ zbJF4#TTLG=!@pa+g+nPeq!^R-AYN3@SYYhIgQ}F=LopiV^V}{unEjC7aVIg^%%r6%&ZMYZ<4Xd{|r z@5BySi7grho)^@R2tlZ5*O2mfG3)7Y0~61e(p@3+)bnr|rWeJoTnwmQd0w$iHeX8Y z(TZw=|J0)-DMZ!@RG{cR<%}3HtlO?z$9?zWZ2c@}?<~cN_DjN)nI@mu@MvhEi6ZOZ zZVw5ck7EvWZ@9#{^Q6S?g(OIj^^%f)I}W3}m%s+0kI1>higVZOUO#7#n4V?IGx9fF zUOl)2Mcl;9uN^(!RF`j#VrvqHg<;;q1KQT*@a&;K)5(9?_ z!k;0q_&Kz*rIEpsj1t%C%J`%gO#O#0J9Pm?VVFK7H@6pu(S+qjBaODzm-F|@a7K9? zrNeqd13H3mzL1A%uZW+f2*q`B_H=yh znL^~ntzk`Mt#)RSd7iu8ZKI`alzW(W(!gfE?aK-pG8SjZ+-f9xOK#Uksr~0#3UAg9 zmfEd&c!_+f3j?;||x&D zkvQj|AR}Q$s0sU6RY01w#!NL75H8N0YOhoF!sM>>6ufQUxXfUhHjOzM5tPd1C!v@` zUpqN4m9M7CLw<4+IU%yW2rcq?*SouzaMH$=iWPJ`Uum$Sx-lY6$~ACH;QKK?Hzh&y zYNCW~RBHn}JL1Fbiks=bU*sz>QyNb_OLt~w{LSExj-H8AfZnQJ2$I(M-d68iM={ZO zBY67Z1WdBktird>iuMyp^lQg{^+E-%tFjGg`|o<)Qk7c zCPh$;dIgWLo`7xNBoTvEcr4wM*A4ITV7C&_snZ9 z^@TpCCDZhVg(nnbwmnxsU?3M$9o>$eaWk%);%J`e9R4>yq07dfE1`Z`GHn^I#w`E> zKEKVlNXi0!xcZH5-~#)e9}!=^a1jforVINF4U34RA)GKx6Kk{8KM-P|edvyRsFoF5 zD+22(eMGWOxDB~6J(sFlBq0oM{`OiG#t!Tt_cE6(rjie(uGCLXV0Co&=#{XPMzf9ea&5+>q|}1Y6bc$No!bu zKRYP58o_QiF`SszxdK6eDR6YlStRXZ{bTl(6h>E0TPldwe2hE>EzrU>k`b2f!&{w9 zOqq}=l=2G*Lt4s^X1wclgkWv)o^b23)S$W?Zl@6Ze0Zvi)D5};reJ4~Eubw$Bk2oD ze!F%Hmr;vuC3v`;<*G2#v!_A&Vl2z?qT3Y83%NHRh9=?F zglj!Y6)sB6f+=Tc@=!my83qi3DJfu)HM(A(qS3>g>jBG}29+9u4RO98kV@Cr`Gwpj zy_2i8Ig66h5}!)dhvS>`xR);&GD%=Nm06TElUi+pgiVU-f>DxUtW=clAix5IU``@m zMs7|DNDbiPtdD1KUqbXadpuZ(@r}?IFxZ|mwKjfN(KKB4)t~H(Oih-XPZ9M@JcOKX zcV1!|85sd!Cp+IZo!&v4Gp+s-Tz}mQ1NGXwHW@^D2BUVbIRKhTm#Ct1fuM2{ckPKI z!G#$Uz0?)zhBFXAj35OTkZmXBg!Se?O|bl!m@y~5VTMLbpKVDM6^9q-bRQI2a|S_| zy=v{DEFoI-84*>3#L2V+j><~zK6BI8czo+L!U9^RU$s@a87VG*;tUL6;j!dqN)LGt zce(W*>}9|Uo9IskBw}E_yNVZPVj?o~dGq3>vO;!J-&^(*cR{%Pm*NdW`S-FTkMC- zC1#YqW5fBF%g;UJ>)6Yic%S&H0z3^Af^#a1Aed4I;$)2P$PaQPwwxG7PHAj8b8?-s zCcZT~I!(JUE{7@N+N>CU=>GeZIF)lT?ze`wSyx~;B${?&k{mA?hYKev`}T}<7>e4M zN@xaUby+n0_ur8H^%a+$Qi;u*FNmTo3bSloO0OKE@JqYu$bUymo{8V&pZ*7&y=F?d zBOaptYIaloNqW2J;ZlCp^4taPz?|3F! z%bJ#_ZT;jx63Sk z>D{>rU~9skSA=Vx?{1X6DZO^RtM@>*;e8Rp%%lNquq$ZusrxR;d8^#f6*27xr`*4f zgqh1*65+KQJc!@axk-^hBXU7QtmWPk9)S+x0TlWu0w5`4$*mns_Uk@t{vzD%eD&Fl zeKO|#P*}-`m`5l?oupfVd!g3}J^0+|NXjcyLujEVa%X!|8^! z*m-n)Rt_Gnu#<*gtp_(R#BZ2U+)DJD-Tv{j3ujRM*Xhu{3mO7oH+X&i&m6upAQv$n zTpsxw6UN?DrA;k6=}R?1-s3ZV=5AEilnv^tY3H6QNJ|MaDCW=F0-#Dalr~|YD&;Hx zJFuc(hnRaiDM1Vy28|G-UOYh_T|DM_ANsP{7b);)1CAcKISVla;LgWAXnpznh$|=T z?3h!pL*XDA^yKg9Wu|Z$=m&|WG~!mVd%9U9VmQt?vdsc6r8VItWb=tlq38T@F9UW? zE}a5fGLPh*rO5;dIQs$@scP;scOtg9#z2N<(WB-$>d^#)tzgOD53YT8Uxe&#Dr!y+ zJEp&T^{B~Shu?1si z?sGOq!K2F8=hIa+PUwzal2vIFpYwQrBS?&hsq%LXdZ6~I#m%S_Q_aK!2UZ*}7C>^&+i%-Au-_^5+=L_L0nDL9bjt>no7Y^S&_f`s5eM9D@ zrC35W*%x55AdLWV2vKxCa>ADfiCVS#WqR>8C{ViLntM2R#kLR;pBg5)Sp?D0te^(qkTCu9JmdJ4#^6)7-+Ha0B6(T#3~^_3J2|oY+i`PZ zUXZ+Cb@2!JmTSd`ANj7}xTgMy8*BkZ0>Eqzn+_^sI@p)~iBqH`_mrKUix8@X_#CB# z_73{7r=gb|Twi%2KZS?34Of6JuT;H<$w#+^ZkUfvlyjcoRga$#q00&`{8*wPaj^t! zuRuthbNN678ibm_+39Um^A0%_z?7j~uhCp*S026{Mp%s@;}dh5Z*A>l#%)wh);Op7mc0Knr|54~B~`DGI%3fF?2+HJGIxgAc;< zK;i-lVM+IJ2Y?ucF!JmsajEPq+91Jgir>s85C|6-g9NAIzxTH;MZ3`^L!d`SYws;9 zcSOP~Pc_Qp#@1n_+v1WMu98P4O*vw?jJx@V?r1wZC`D~aJHIzJr-{Z zWR&$A`R8+6iZfa#L1BC$;F|h9k9-PZ=k7Vm+gIY%jvtO%$C^c*c`GhQd%P(<6B26j z>V?Itd}EsAMoVVl>)!K``>To(-pIqMehAbU*K)^t-QZ}YRsV(4AA$6yjO*hp{q;e= zt#`Z|Y=>NHvvsamW}kT-Uz(Y1e?NKfe4SO~eIh$n<3ZbVckP>PtrL9*tqgTdG`zL7 z+rEFA5PIE{0Q+BwH!{Pge@biIBv9E;l|zgWQ(gGQVYdc8pV6k14ie3VU8QA$z8WRs zc&sym`aU($eiWM&Il&cMGB%=ddOw9{A?A$Nj0}vv8XA_LFBEisJ?#u3Fr{vvf>Lbp zk$o7faM_%nZ$-9@J2;r7@77>3qlgJ(IXK;1(!L@ZBVmH`_L=@M$?a+ke9ETARle#b zhJ#|B4yQOdCR3;dxh0Y%3p#x9OS;=znT$o#an#r7SEu-ih8!g+Epg2*^ez>chMczrJSe9MXy3PV7nUQ@_$wwFiH9*ZxoC4RgyGUHMp{#=r;4z1{jm#P;|+^u{# z@%2S6V{F68p?z^?PE_h_P+61iPGzmZmR%g5@wvqlJe`>aW}g0Y51MO5v+yXrStVZ z0Ryijx}6H7oQ4{EzVyuOip_Psz~3IVy>j>hw0N2KU!t#;pi4CDP9^MvGD&6hYrMmH zhpYcXsJ5CM5Q-j)>rKgioL}BN5gAokogCa73P4UhNx$ovWEpx!*3FMEy9&oF3rqKD z-{yZS|8QtM;5M)umTq}@@2M)>QqkBun@#akhK^B_Wsha|)@Kxr&tcbxckMSC=%ZQCJA6^< zO7&UBt&g4g&s-NVRqQ40FIPv;AIbT7+CT9@PSxTjD+U(%VPVHVx3YG;BxY$TTrr+t zfHk=zzq^&t{vlK1iqS*8VEk$Dz*SJvCCC4|PQ3gL(d`!!Snh3KYT4FRb(DoS8UA5z zV@!dFrrsd~e}vu{%kcw;-ubic9Z-yp33fhsH`?P?^;kioPfAN`$mE?rN74sKl?l7C zgAO$~JLNZbipeLhPj3_#RZA_M)#WOEyq^$X|8UQv%eLlH!M4weztRCn6)FAbX(pxc zu{ysj(|c;~-Jc$oHWW?6+9Sr`aCN-!vpK=O@tJbfOMY&Xo3J{0|LQmR7b8br#2P(urYCgDQnI*v<-v~lMuTUh#QeXP3*@S{ zp_ZdB?n{c5?`)OGnRs@SkVTNu*dM<~f&lxp|IVpThkwvTvJUDoZSV_7oJ$umim}5h z#@((U@4Wkgir0=c-!`5*>_3M%bkX6;fQCnXSMq?&Z(i6@;Vtxocom^nQ4 z(rU?2_U0==BTF;)n+)*G02NbfRpif@{q1eXFxdGfWsqZdhm0M6vg4$><>9s{r&n0w;>P2_1Kb89p|=2}tWz`O zUMwQ=#sxmxx7WFMGV@{x^urYV+d)4P-Z)THCx}TH*@-3r^6p_|mg35tqcN{%4Z9=i@C<~f(8>~pN`lt*O?oLu#%Gp<%0vr< z?VB;F^vc!KU+@9=_WGj4?-o!^Z0Be7MX-Bk9rQ%OWO@j+y7`-fBpL{Ojm*s83HXD2 zNP0VNU|4Ofnp|1LyX_j2 z2lusaPMDx$5K>a58j9k4wjA02XDjsyF&DC-B$FoT?qRSUhpM(X?`)Z%^y=$rc0H+T z)LhSBMN{#uXt?8g93l+j?fLp(0ezeV@jI0W>x2pr3(0mFcm=Y5{=i5Typt$#7GRCK z^O@lHA-|n%=fxz7r~QI<#1piah(py+PuqcUGbmH zc3V6~u^lu|yy|Kmd*#=_e@9$ciWl-xnr`=|uVk*E*F-|>sZsvLhJRb$xb3={&|lSW z?7HA4iIoMDm0?-8a-4IKg6ithmSQ)VplAN^>Y_{e@V2+C(e;0||? z)OIo8ttAc%E*@tw%J86Z#n!G5ql)jh?ZFi*U8jBhDR+cQtXdHQ96*McTm0YZe5dXwXUG;@4zuh^ z_YD9o6}-Ua##UXu?#;}?xWv@!s~Zeoi@H#}aWH`A#3e5ODN7YIHj}h8?!L9{liHAF zjRlW$=0~97OG(?5P8t&VCFb7@zV(^S^MaC_aL^eEh}PcHwOKl*Yhw{D2n9*7tEpaj zoZPbw!fL*7FhIS?3QpBi+`ghg?&Jw)Q{^sh#g?6w#3xt+T-VLTd{g)moH%Ux?t_K9 zHwKpNPyTC_GUeDAdd~HkC8o3Hd!P13Ei?O4Y|0~g7G@5^*}qOVQKY!3xMa~#E5Up$ zuzwRdFTj(8EgalhJ@}B(V+H$xzIpYgABiR{^z;&jI!rA1UirlO1a(aIF%LOG+&X7o zdJ)}90&zF#*i{}X=C^u<76iaG>|ci>p_^ z)WdNI(@Bg-WIE|nD0qu2@y&UB#v;M8ni=GNH~4638~_Nw%A8~{2uApY;x8P>fq9Oz!_+5rpX$h1es0`?9A&l)UWs%ya;>2^aTccv z)>Re!5ULMe67al9{7&o@+QkZYE5OBE?qs90^+o_jRW7|R2{i3oWexN zpE7Z;@8KnM4N@XN=s5JbuWE2&1VCR%%|PUO^)U`L!|JL4uEq_t1@e;E> zM-#t*nUqk0cXxlXp_w)3;gXC%@t(B`QWl2{yqM8{tuU8QoGa@ZHG2~N6q@4VzVj}$ zM2}Xjp)d0zw3=(chU+}0iy-l^rkru<#PPT69Sr~TGPiu5V|#lyPG&41EZg*fGr&VdWX8v5dkXjv1LA{5-gjkZAK z@d27K>`H|rgF9?_QOKhLnf!iT*yZ>L2h){^?FPalAAeQSmUgh-=T%p@}r-N^JFWkwZ1HuAeKtI8;um z;?P|WQFScH8ACl#F0mrwJLxvMd=_1YP6^k=_%mnT>>vJ zj%GWVx6w{xLo;J=7aRD!9nIu+(0;Yi@pGt0&JY?@6$$#QgIn!EBUC5&%J$1WZ%|5Lm+BSt}rKZ0SXaZ^%?BcXlDOnx)8E7yS?U2AO1 z5tQ@~IWcOiS=mmBA1jvH$NRi6+F*042NZ2N)r%-~*GPC(8RHqz@%Ndh=tZR~B9aPc z4<771U$e!x`0c5iPhKQtKZ{N{e_s0%{9>%1(nzhV@09l?Dao3qK_aB7dd*cdPhG25 z`QhslE1AR6PAvDHhXuiT!#O&)k7J#ASChxCV}Dt2W`ueY>-I7_l^=md%u=%>bai@vI%UO!# zG)zSH(*A!>8-3obZTz&SUiK=%fG6G;W)z|9)z5kc5d(XdC0gv$Xn!eHB2C(?nxUgZ zLs8=pI~e()T7D{(fd>R06Wq24$At7`I-61Y=u;>MEx>T79f8CJHsfvMjTU^7Yk&fb zh^02}xEN^kZ2Qo0@sc7ubUVkdtd*|^!*H`TGTdD6E1^W9y;uaswzO(C`MsowHvw#FEXT`R$H% z=rjb~Ijg9Us`n!0`kW^-a&qFTbF7+fH=^_{ZwznWAX)NdiS9pj_|(uk2JiqM$xDi(lZ=vwKKfpT(o@ahv2nD! zEDL2(?^F91hRLzwKkF`W+E8M~KHv|b*rPwVDAixL?_s(8ZBE4xgp-iZj^2iR8|B{~0a1)`u~b86$Ii;TOpr%r zE~&{4I>wcCgHCUqC7eJb?VS_2R_OLe1O04l=aix^MkMNw!tqYXU1#LCs2Bg*Nyc_= zWD#iaq3gb4lWtAHJ>nU(3s~PUkXJ}HmwiUXZ~L=LBzY+Gl)f)2PU1La3hGIa6lJk} zubdY3i?=&thG!3wH`c%>AU@2pZqD6;IVbn7Vah(dy!*qQWw~<)T8RaCaO{wz^muxj zJg)1*`Qkn=u}9mGVY$PQvy8`QC%=?nrIPUIN{}viNk7mY67@7cnQPqV+845yuP$4{ z=(f3;{DCkgiz{aBTM<9hT0JZCzdxSke8RL>lpjTQK+c($X)!>&0Jxq+NLPKw)-T5a zjm7;Nf@UFF0ZkHsRF3ssDWZe{b(w2%cNxp* zi&OT^8s{<0PzebQxF&LMccUOq9HgaTLTA4-tE#f*8kX4`t}MO#Fw*z zj^j&iQQ6TaqamL^8^6!V8M);Pp9kbCVuzIt`U8!z-!n0j9KKwLw9;$J6@Qo+A>e}r zT+2BRc@#9d-S89iXf!R~?-1XnV%ZeBC2!jUOPTpy8C8yrJ=F{ulk!`bG!O4-k14un zylU4+UjLVbfe)tN7ap_z+bSlSjmyZudw4{T#D@1+Pwzu|R*DKPPdv&mslZy}& z)}^6&`u3L%8bsgX5xFPXhm5eIFm&o4{SxSmm6)6R<`Xo_Pvk~VDU+>rduY0jsCB9Kf*r-2oh)vavjOp@XrMf+k!oXd;JDH=ZWnh z8Fld*lqXf8Kp<2eXg+WLKZ_A&nU9J`;}M(&!#dn!Nd)hy7)i-;&ALOKCi&?bzT1P> z^ljtbUyuaBTRi1#hJY+8vO#aF5t^)r zF%;;cRi7e}ccy?#WC^ClAEzBq$@Qq_G#FU?7PS8ml%Zk-$fkRU5T#}f{$n`-Mp?27 zd2|`gGTfR_*H5phOK_QQNIfim`q2y9bz)Zw5`GZQW>`QK3sHEOYdmNqg_T}D_o5mc zbA;Ii&q*1~#Q0};8+_;Xa^~Lj4eTP_rK$b%2;R)0Rpj7tujdH~dv+Kpt4|+pL>R z9uef9^ffQXNvX81Ho<9TXOxtb#bib6otc+X3L}c-#>0(ZGK+3ycpa?RKmz=ep9R@( z1Dc8R zyhg!+acwT75%UK2|85xX;{K%9mUld~4 z4&NGph&8PI-@OWEDWkm%0u<(s`LKY2ZzyuJCX>6mXzGBrT(t1%69xs78X%9^*W-9) z!h-7+_O|kE8?jl}&H*{=R7$K=Ci3^A{i14ZSm%L){$gy#!$V+*pL2;_~uHTQq+>0j0S6=+P!JrU}YmxxfP5 z5QvMUlcCZ^`JjLj#-?nC#diqvX$R(`mb@a_m-0?BRQr#>B3%z)?#&;fjJV_uL)tb2 zF-U#nV8;;`rJBc!6(Pkmkd%- z3mT#e0EVdeyx!FT@aM$kN<{zttg36a>bncpKubr{GM>6X(n&9{9Q42lTekc&x%&~o zc)90b(iV@9Gd9#>IIih zb7=*mQyA0X&~f^*n-7QQvX(hgVKu4}n)xvmhr=c}QLCkQA1@R@mq%W$@Ti+(n^o8`Vq+iQLN|HN1Va zFD)SFlLRFrnWU6AIH7*{yX9W?dArRQ8aiDMaq+1ZJK(w(1BM94dpB%j#}frSs>Zt8 zECM7wz6^_#+6pQ|stdALX1Kz}Qfz;C-YYq28EJoT<8e!sOHc5MuRG?oJR)GHAI%Jm ziT{hZoGcLPgEKHW0}F5sJFATe``B61!%=rC6Jo1UPlAT!iexR|gW8|}C9uwO@8Hof zk4?yvBKGEZFC|G8SsH24Ac(nT{0R6?*$;55(6dUXr%#fqIzgm_v#ogTev`-4-^2UH zaatayVMnjkXNj5sVT8}8>>}vwR7UZ}ip@ofZe8}I>2AQO z%-#fRi}04Vw1Md;{3VqxdvUW?>)8O}&2e5%YTKqMh1g>S24caL&bIalHZ;2x)j*pK zAL->v*~>;{|0j?#O?jAuQbKobHaibQ1y)cv{QTwG`=`WEeokii;BtV|0snLhnmpC> z6fm}YOp*30UNtf<|1IK@#STLhRp7ljYnPKwZW#(y@!$w0>g}O&{5l!5+nkz1KMH)g ze@k~mbN~dPNgcTmvSMhFCDtmYMkzc_Hh@q%n)&W?mhM?qDXGX$Ghc?#0=C=vgg~i6 zx~WWgL_1l7#RbQFq5P{8lJHQ!yh{ci3EN!(cEfGl2#1u$A#?r)giSwV#k67=HojRA zYiuw7qm(bc9H~*c=^}Ry;5PK)^CY5(+orB>T`S7(AEUA+Me=MzPo*(8aoW?coYp*p%D%?)!`n$O^Cbrn}qY|1=HUEk)n=^VB*x(+<0utdA zxn37+lOWzPQ({QZ$RK3J{B-kj^#@Qn>edrl-Omn1OVC^7k<-yAp?dKmp^@6mf}U8W zU-VPJu#6N^q=DxI_Z^#l==3@dJOvLxaK6xZ8{0qsc84@|DIQO3muR+VmA()1yL93| z-$c1j{si-Ih6aXRMVJXsFO0o=82b#pw=@-wowQK{vD~#qkpBJ5q0d}V-ABNegaX`V(WT2W6$nGDFZW~TYI@@7ndPD$I9A`X!CT&e9w~rqG^y~b zNhF)g1`Q_eUYPKc-AB^lcw(foFK2CTs@K+9y=V;(`5t~^`J^2)INw?@=R@aGIU}6k zY*O)uw8X-;+C({vHuj$r!sSaL6exPsmG*V^i8A|bgTM!a??Clv2zJ;X5|!C{s6-14 zKN_*9%v~9kGU-J~fcUF)Mc;{sK2wqVB0$d7*Xtz2=@O?~AYaOuaYYZa^S06NUXIKT zrAdsBh@6UeM(VRI21|K3AiUucv#D(ko6>X+8&rlH^OK%}##B6b?!f1 zhk%Wox-i}K z?+h9XxK+WYZXLMI*_E3|!h^C0O_6|00|-_n(SIL^m#RV;UcPUdKnP9OPrPn7MI^$ql1e(=H%g>K{(#V7Y8$n&|9%qD$Tf#LzGjxbr?>OmKp} z`?hXwvK%7r0~Y>xQMg`aY=M#AE~Ex-P+_FhGX=)18^Gt$QV`v^?Fsq@F-AX5`M)C_DyQxIe10s*x5XYKCEYQw1 z2q&V%*msTwhi&>==CuD<6}4FStebJ-y_CfMnEhTWI)_HOQ@TUC zK|)em7&-+6q+!UR1yo8Jr4$KC$swduq`SLofQfhR=i~eQ1JAelu#X+btbMJu*L9x1 zv$uBR;_hxaumUqm-9%ufn{Z9-r-gAnZ1B%T6!pJ*1N+wdm(M5OjR;I>zwC2?)Wpiw zb?iJ6j3@|2y@=cuI2Xc+vvRQ!H7adFD4k3OM%b${Wb zW3WTU#-*)gSa#G))556D*$OLWD2>VMueJ$65uaUxg7;Z9M*aieutbQhQDX9^zKdu4E_WNuF-z?&=ahPpySt}CPiq|teJmZiUhZiXw0&j)!0iW4yLnWU z2_}`epTw)-1|N)2j)$v(G*Df1Y;a_5Homo=d=~s(-6-k)D=X&t(lh;KWzA9X28Gu2 z@LLJHZ6qRS6q#3)ovLgCUE~4 z0Z7zzccKI&UpMP-Va;Jhp4l5o?7Rqq z%-vXJ+zTm}+;|l9#BVF%R^r=Jp*$L~7JFjh_6qkW!=21Bf9s8E-SUK5p+31q09@s zonLzcEGS*!n*3snsHZO*!=;K*!B{y_3~1Btg5MKbZ-5?e;OF<}sDPGkr*u05a(e@( z1QEN0u&azs#X%BdP9Ay#yOn+x|HOptE%V?mbWD40)ODP}-S?bGUszU=!QBDo^QEB3 zGhC;7BuS)JQrz`Z*qYDw&m&0EmW{R1(NZK*jdG+~5z*y>%BdCPG6a_0&MN7{;)^pb zCQ&=Bd_zC*&~+HQkXzrk+S~!Kzxp&bu857``_D)T%;n>I`<8@7Br-KVev?AXl`bI@ zDHfA6q^R&4KI7}bn)u<<=Bgt2ycY2T)u?g6(A9B=iJBo~3mhG!9q>F0gnF6sd}$Tq6<5xys7Wf{W!rfD2S%4bgcPyAl92Pl(9mflc~Q zFZ^~qa0#l=97{BY$o&|F_|Td|2;34G(C5mkzh5b?ucBg&k@wlfWwufZ_jtnm<`&Rc z^nca}j_1I+cB>-}GRQ{J?)Z7LfwaaRd)jFJplVC+lq62-^dWKc<}oKv85Mzc#soC z-O2+W9)HGqOvrE`4HODh_(dZsJOszmV;2+73JV%Q8wup=;;DxtwWoGhl#CT^nkOSh z(Rd-XFHva+&cI#Mr%@|tB5h7NO{_WX*=0_?;5xANBP+~qDiqj~mAQ$?24w;!7iiYV z#0$y9sh{>aG1Fl4Bq&n5Vjq?A08&UntLq7AbJ{S)Sf*d35YZS4GB}eb?3?qDOH$q^ zIkivE23_or(SniL3wU&skc&%tSM^>^98*;=Qr@YSCMpVI{wR?QC#;)raz;!%96B~nP{a31$w;FTID7a-3LHQvdf>yhC*gcwD(7=+QxAX-B1olYbK?aNwti>=b7A1FdHWfWQUFQ$d_uq)7677^q|zyC#|ZB$7g;2YPD;=xFENf3KeL#$h<$CPwW7++V9;MAHO}|tt$>8x3AXfXE>8GI1uYX zeaa!v35BVzHBdR;K!@i0M2u@pY%s_L3Z+RAw0`up)_5%YSw-zi`-yPM%y&#BI@5)j6KESN7+oQNja;)slQdOKybhz1LRm!3 zx7Px|npc5cXkU}<^nRtChvK{m=$$|*l7aR>qoE*}A(WzWc%+YH%-j=68z>;V|F|J9 z9Q`7f8omu>&EA2fZ2qi2$8RQD{(!I5fOM{W0)0rRdk2GOWTKnP4a1#Hv#@W8UkHlI z$@yvJz_}_g`eaLxfPob1*CtU>H?Xgtw}iml%=rk+V=Ij^B)~QiKLn`a0JO($Qs@$? zBNP@F6V7*nkHepk-nj>Uw?$aFJ@vly=E8}JQ?jj}pG1TMuj#L>jx^A9Qjxkee~3{p zJC?%zISKQ>;A#btiv|q6$I%ilI`iEzVqX6UWaw8&F&ARz!&-J{+Ji#i%OTMr5!i;^ z##%3p+SwMnN(i3EG8+D7(o@fxDN8qPi&()4Mc4Hw{2J`ASi^ zgA5~}S|Kdra;piZIz1Vxwl2DYd#__7(jnhh+<$RXikct0MSYM@M1U;s4Y?(;#Ha`H zr%9AyDn+(pZ5J&-G>UVQWOjZ1!Q0K&NwMvT6-DlYGF`>mEmDAyTsic5sGU#t3)Csz zg@@mQmC@wB;iPC~2mr(sB5$iiR*VFGmwJVm&zb9_lx$*Ulh-x%(Ouw}8yqs32b{C@ zDfYgZx(BSR=PFpEWj(|*pn_i?@qa}x-rQQ{BFA{KZJp6RjjV?&E_|ku6vh(qL3+1^ zovnG}Xt=#rCVnP_^M=iNM7lc)Tv}7}G{n*a5kf>}#6`uV-QMpbA^(P;$git^lCK`` zY0gK^#S{oVS0Z1rt&!+Tct)Q9JiQweT?HdweS;#N==-=Y(8D;3eUI7Fh$?w%d=Z-& zT)?eu!-vUYmlOYC?dUj*S0jT$xP5Au>vAO z`=EFW8KHgmZ-i$u9oPxibtX78fF$Qk?5ct>-E|~&GF`36miShpO@)JfO-NxmjQN!g z4%n|)9SmUZ7Vdy@{dl@u51bRQ&rqQTVa_0IHwOU`$FxDrVe;cFcgiqj%)ek58i{%DKo9zXe48!X(5Q zmSx9?^1L5o%)m)bf5_tHArZs4Tz1+we!f*TBA*&CHRxp~uN{lno06 zx0(5#a8`vM?;w%L@3AzmWHEM~BE9NDA1P^m{ACE} z_h*lY&Z>x-c<%7ne?i`C5ec6?M;$5*)1&H=eOL><#AR6b(uV!qdI3Y{ZwIJ_;Wkqg z+22I}PnnDPK<5M>`h#MGB}WxKuvd1DUA(MhDLa^dgD48)Rus)c6s`TGxQUI5+dQ0E zCWSxIDAYQ%9*!wVzeQ{y2O*vy^K%H&8&cfSJ2)|NLu7u3GE?5;ve(VDekv(G3HSYX z{M;LC(_c%an=fr^#YAPwEY|73ckbn=${LOO3tf)vJ4Z?>Q6GcJe zH|4NbdY-QqQBazS?F9LlVHa@TAT8CBEIgQ9;O6tDGkN6}r)w9MP~Q`Z2PmpEQC#H& z#nOH>1L4Ksgqk<03o`GHX1XEWzuv@3T&z$4HB26B@dWwSMO%M4crBs!GOPLKa$3z5 zF@9tUG1DRhu_RWb^qSv(YJ7pQR=H~6JmuJNA9T;Gu~`6$EV*Plzys3nN7?BYQ_hov z-LT#u3sjXa&R^xN!yaFEKt!2yq+5Fi$!!#SF19m|kU}3*rhgD8gp)b0Ui`#Zh;#@d zNTChJnZ5^TLrSA6`{p7Am%5QR>+|s>Ak3x@NbT-IkJ0!4v@Rc!Qj>Hv4>oyn=+spA z=Y)J~E_kaQXXJgxU{thD^Q248tAz`fXy4)nf}Uk+()cys=vS-ut?<_{$lXt_LF(W& zt-R`5K5DFyP{_X;ycCn%*8p=#UDSuUb3LZJ8_2=l1y019Zb93%h9y)3t6-8%J%2tW zO*Zi;Wo#2=@~Z=VT(j;4!aCUH&6M~{@DIRD;!x{(cL#FJr*L|2XxG{T2PcXIVB1}F z>R1;t8mP0Do0c18*uU}Kdrx5Cph+KzZ0{taX@ZD8%<}cr>U(4KCDdK6D{pQcKp$=u zS*LPHg(JF!`w0lEb&^~k`nmd^Y`2GlX$@V#NW%@R2Q}X33Cfp5Lo1Wvin9~ zC|ZQZhUz|LPL8?aRUHPsY_P2j486R#2o$UH>Pw->@2Bk<-N5wd^w%JcZ$$|EjTNNi zs>nqTF%FqJn-MW-*dww3`0rDN==&~o0nDaHkf^6T&RDCNZCBUzlhls`g?(I5ji@kx z&EX23r364%b^r!h`E#xDF=38)N*ZS%m7b{RNL08X0`smRLh+^@MWu*((#-0u1v&c~ zH#O0s@FhU&0a9!x<%q5in@rR(c$lhU85IMHBKyz6CNB{JeIy#-C0dB?O?FyTCcd~& z;O1rw^GZ?EfZ$PI&Ku9Lat8?Xy3o`#TzPjS@ zMKnlrZPJXui6x8qQ^^oG+&%gX6LZTf)P=%+5XzSNNiu$S)>3K|J?uNQzNYDB? zg1}FCLM9E3DoI0sy|6;wTX@BG0D_~Nkw*LPcQ<+irQt9W zU=HL$iY3%!kIs3bUtD@B)n^NgF^8zo(72x~6z)TN2mCz)@q{O%uXyWX{y0-GaD5z( z%n10O-3G-7#0`^N$sh~lAunncjS{Ncl^)6h5O;M;=((*1kOL_MMdMH5RXXxyJ>HFq2zmr( zZ!U^SM03?%!=Uqtse#A@N9(4J!n`E*Z!%~G zuJ*dv?&riR)TQ8#EWc0>M>L5QjI@DG`W>8d`&6_JWN)q*;~-je*LzY?L^gUQ4>e+8 zG~=$DJSpm6+O>og&{x0g3*~!d7+{S4+Vh(t9CvTw9I)PnPUwIs04^&2+%szAHd^dY zZSEi=5*ZV_c|ryzvX%ZuQ~tH~kOi%4^b(^TJeA0U=w_`3=tBNI^nEd=5SRQh2^s1g zAa@SRRkpOG3qy|T*@0i*J3JHlFO4Thbz~7R2I?szuA9dHh@EzO)nNy;lS3uwl=5Oy zQ}lt?d-T~5!akjjJ{~Ep5C}Z_fDIR?5IvdcEUge79}<*Bkh}mR@sF$(CaKu)o`TMV zKGXvE+}}oBBKCN)OK-x}|41dZt#>t%iU-69BXPk6Me3;DJ1&tm%Fi$}8M6#H(S=ms z(k|>twvn71T-9Lmycr<$L=zQOebxQi)>)h=4K%*K^utls zD2xZVcp=G0Kl{yLm%}PL0EYLgk-K_1cZT5i2Lu1nX>yS{)C-91AQJ6IK=G6d&NKK% zVQY$b9aii30JIxNZgvvGoqbKZ56HKsGtk6t8@Y%)M|{CAcGeX1kqs8NZP|=PRR#-5N*UU znxEfaGT`#dLnqS7a2%Z5r;Tu#yx$=&1LZ3JLecX`ka(6Cm`CXd!_JGsTg*Q77qcUp zDZ|+JpOpj(8b(XA&>ezjUxR;99Dq@ek`>;%9vp`a67Im3tWT~9`7*oFvr=ZC(tdl?QRG$6P5))qQ zyf=nY3%kI4@|w50dHUwf04syTgrVv3W9Lzs{FuvRF1BEO+{o28dET}xqxj4(fR+0c?YV*8-=4(hN7bxrxUQS3(S2zp~JNG7@5R&5pMI;J4f;wR)8T95$ zMNS4`qs0ieU*LD_!5au3?LV;C(<@&K{)JSmAYe#F1k+7T$PUc>_3x;$1!vn zrBi{rY8NLoA|sLT&_7qG+}o;j!MfXhTu*;7G@U}@^U$F{7&p$V*Ah6*`pmQn2$b39 za@iKlYz>Kh%*#+t+1_^wD3$d0F6(?b-{g3-@AL*hWt~ zH-vl(X{K!8p~fyY#Pa1`FVEDayyLSR9|#_=6sS&&;UixJri@6@C4Epukzn7rl!^;? zkr;-M_8t}JU2FEY?HdwN#Kt3`Qry3IB=mov<)rk&O4c&&RRHD9j_DPct2 zBGV>9Ek0K{J?eq*d?uy)Z+GF62+YZ-ZEWIVFPlU4X(=Ayk=ak%A6n&;v3x)2ol9Fd z0&j0?-s|fw0_cLeMYIUKxsQ-m9vc8kVk)$#pyWC|b32MB)61!Ls5$flaTK3KF#6$hn z;SD{BLJ<2?lpF<2TP&tUeA#dniIeiIJ3^Y=!`7hq>U3A}!LHn(#}UNA-~2lhi`$)uT|{eQzNp+_)eQ=JApBwh8u78k(n^ex z{2=VV-QI%95_z$9c=?98QG#m6{}A3ytDt}#aQnMoe7`0W_Ly3doivXFLcdF)xqBfu z2O7J%JkJIe4>6ZFL5Qo0#rix6$PXxhBTrB0jXT6ScTuZ)ZU)syOT1#0aEKx1N8GbI z5e^svasg-N#w2+zhnmvS=yM@}f!kZbwF?x43uY!!0QI#Kox+5TF|XH))oCkYJ6nN4 zimUSdJf0}E$#ubI{6-bG?L8_)_>r1s#rhTKP2~HX^G}PEvx&vTZ3o^!lDJI@SL-{T zm{PXBY?nYWDa6onMVMS*u3sRs-kuraym zF)MI|t)fDRR=UrUt{J*?Ryvh9(12uvEO3QfyH$Pgg6qY@0TQ}^sQxx(0+#6w;<5u6WKRBEo~g=3s9TWzvo8v^v%%?< zj}Ni_bMXaTl)n1;yX;NGs?GO!dDm|S>B>HKRp}k)T1+_+9;DYE~%2p=HBF!D> z5eg@&+efo(RU@3oOfGamjpMN<7=2K)!Q*|l`**cV9I2^Ir6OjL&S3V37)`Z~vUIv~ z`{;99S_KX`@`7NY#i(Ntc`7JHmWtAiu7fBR)n1vg z|1U$bN{m2*LPtqs~4B4X{(!2jIO< z3G*g~xd0!zuTwWGF68=I;ajzeQDJ?)Put!Zw)sMT*7^8|>ngJNl7wL)rTsptu;0>{ zpN53MFT@OuFxmTr?3OrDfhnagdqJUe{^pXhq++&DwCK-Z*Qy(QeI#>}lRLH%n5$~H zjQ-z{iXU_^O&3M*7(+*UMg|}kMTZsr@!h)X5uI6|UvLeK78A-0q$7E@#c>m~s5MSGw_>c2(qA1QHS@uqX_X7a#9y;F z<&hXQ=;%0Lkg}o|5p@b!B8#*Uzt$T^%qK}(&CyWsd>1gi{d((*ptTFJ2vR5ny2~8H zGDERg8s&Ng4fO3mRKcPi*3GOL3ZCJzAfIBf*%v5gN-h}kF0GxhTopx5Pr zMp??_Hz1CJ|G@?&B5{IFTyG!l7j+}V@bD1i5nSAl@X>JfiHcsS?hE0FJr_IV81ze2 zLG~#H=BEXE54!x<+B6*sq;4mpqO%rhrs?fqHoe$6GAbKru& z|EqAH7~))RJ@`z+Xc-?3JwZ0K0F2V`*yeMwx^E}Qc<~yNDi+X^Vv3QIKy)ri!wIvx zuvF|-S*S?Ou~y1cm!-?or&3mF2v#UoeA<@JtUwpnZ5(7ut76-SUtq*p?^kIDOir{+ z7N*t)ecxNHHK@WzT1l4Ar-zv>`eV<+NFmc#^-GMdI+Dn za`TAzNV+IAK6bx-tP-4bUx?8-)_IygizTP%Nq`ziC{&Q^W|?3GVAw1Yyj_gpe|Sz0 zd(6H3J|W~A>*m>tL|IB9bh_cVYpP-&U^k2{3vRx;e1ApI(?{sf2}9yIK-oT=I{I z#)+1ep|{-X1ql-V=+)Mo>U})&C+Rx;n$6_GvUEq#pyBeR{@DHjtAe!PamymV%-&3{uD-O0zaqishY^x;SIRVoJ_EbP;m&Be$?6P zw)I+ILsm~`My1su7XOl_mb8S+zL;ISy|7`W8@ochdd(5?Y{qGl|Ai?}Fja#U$)<0V7I}H{t*$Gl3APi^tu6ScimBPp@JThX69DZX{|7=UTeY|gJzqTb54-4Sp~BPipb`M zVK*9Z^hLw9@r-y?UXiwVoVxlVizGv&tPj^21iKYmRxm2|pE{`_^-H~ibV*`2&lP#T z&lC90m*WTHN4ErBp7CYB7$UG*eP63%Nv964JJEa{bIz7rhx#YuM2q7Ec;;dQ_k?vc zd8~J*lW-=2)4ULW`4WS0=`M}hfYshI`BHvBA}k!oHZ;}zPtXgAoE3$%=|akdnHk6Z z=R4wmcT_D`ixxJzci-Y=-CCrY{D`mar-@P#7+`i1xiTvCestvjD#g+av7f^Ms1!hp zyw1JhmN6}D?FyH_A1?a2+j@VV{(XJh?_By4m_u-ruFRSuWr%k_nIVT#y{nGeMvLUvY!UXkPlbL;Xkx9&~=dp z;)0(~eH~MqDX-5mQ>4QAhKV=&J{O6!~Hqau7RTo4Z8%Z+k}E{;LeN)_Y1mxaJ)dkBv8%)ZZjX) zxd+uitdrCnQvezD}nbG%ZL&r_5iyarVf zX=sgabYAr-0d99@bpL)%cLrlSp=Xlvhp04bt;A8VyhEqLtE%SFGSM!Jog%0EqN^Yl zWbPCFkGjrDzWbhEXywOjuKIn=nic8A|jENdfmQ5>Ngtv{lq2I_sE zmlp#ppFMX0*!0BB2|>CS39G0uW-B<-zyRMf;K%L$nV*iDs zE}d}a2J?B}!b^OI$J=CWJz)v?UUOhO4ro!}qUN^@{|1OXwtdlw0XGaF+5 z69)iPH=Rs@ZXm{CzNn(!E;Tx5IbEBENV~i`H#aR)CU&3=#Y&;t_p7_K+jo|ms~sM7 zAPQ}|3}6(wGQ4@fj`kHAo&1P7E+hQAtK+Eln=NW)ZOM=Qk5N}(b4XN`$tCj>4BTqB z@^Px^-KC)je}}FCkU%HUUjB^E-#MP*gsY$==ON9F47^gz@1yH>%0Hxbf6#kP)dZ8Q z=2EVyRkESeNFI^tH~;w}>;|o$po5dP9AF6gl~t7rwEGgf={>Q~NA|^ZjjMhI`ESGw zB!K5-7~o)7tuH3lmV=YHMz7=ZC-z%^HDxb7rOcZpG~Rz5(F7KG2>8p8w;+U@>A9_% zcL}<1kpbu~;)P7|YU~El;Y-Su%BV={x?9WA4;_H`@_NiM?9cBlp4m55i)Ik6>Fa=& z9agMR0vkrzm(G;qjBOaHC2Wk2bjOgDzZzXQGb-^aFEmA3WE~7va+xjiSw^{15x!;~ zum`e@^Z}Ic_~Dm@+kdpG;gpv%>E+_NIri<(1)vP!^vpv)NjQ>f)U0zpYFFiOz5Sx= z5iyj)4#l%*?Y0)oPU{P7!(KP?FF^vmCa5#sq~7yvmt}v!ZRlXDYA*u)(2m1885Npc zkrgRt6R>O*x9T`lsw4Q2`7>Z8;FW^e-qn5h#&BH^Yb!gCxwHrLThe>LOO?r7ky0;r zx4hrwB~%qJO{GHq`Qg{w+D1--0Emxr^KqVp$7^%uDh)?c+a8vrE|mKhbj_weokxMd z(1&`1OOR-0oXTUGOmx0)qYYPDgVX*_a{2r88PnjLNWpn+JS=crB>;AItZ7pF zt-rFQ_lU(%vdImB6dh_C3~IrDafyU#RzQ9VY>|cR-O4(4-rblo`-wGRF$@FkJ%z3C}@x?GrJ$aZz$@&SPh!Gh~==L zli(o0!98rNj?bRk#QbGw2oG5~vwyBG#}9F~J$%y={MS~AkAAfb(J zUc@0pK`+RQWOe+y+vRV*bujX>m`|p~rJzDFDrTEd*}7Kcf_~4+Wav+amZLGj^w|>u zZ%!&5ett@=z#g?tfL)J`*m;zbL7rxkjCfcx$L#*s&th`(R7Jm%zIXghnvs-lJfk?_ z?`S!tP0rFIdXoLkbCd3ItL}tvHfO`9_M|)(T9`P}7uI{*rDm32F8PBQJ*Yjp04It? zrd_E-O^Ki}W5G2cQkMDceEjuX0-XVu31u0E9}^vU*dIsrXhy1uPg1k3 z<%2oJFHGB{)7j7)tBC8fwpf_XxpsFgAF{Y0zq1nX(7h#$@RX8q_4z%jwRPLVFf&bN z8|;onmR7Z@#JJCop{}oK)9)N=MwLBw-UpwqOBKM^ohA?C5N9eJjID7+;2ZBd=z)1<7s5Uu!d3zu0WNE!|loz7}2BtTpUNI>F`3nkdc_ z;m;#p@jbc{(z!Stlg}!v{ag0f)XiD-iYIgnoFw#$L!xQ^?0W63uMkaxEKrn*iA+|s z^449jwgPDnmS5&@GM{{4?n=o})%|IrYzO`Y47I~0 zFG)D=@gy}zmwZE~M)d21&GB=|YHVWnJ2aJ@ifG|~1m^s8;5c{flA_?g(=w=VTiCrl z7r+?1uHat?_29rQC)y9w+RwtIvG>F((s=kR$^c3&_6aD#T$V{!%;e6(g5@Js)`Yn# zIu14m>kAdc{5Yn8a9@+zNsH8aON;DNfo|B%=lrSe72_czrUa_^ihD+(mjV{ri<#O& zYsStiwSKwNWpwad50?#*1RO&aHbqI_m5jUhpEFsStV5m^N)Zq+@>5%l$MMM0Gk@8- z`)B=uwVaAKt)X}S$Rn4Ek~2o2HtST)uxn%g%D~PtUG$5;UYW%h2JYWi(R6VHeX4G42IVG?OPk;KeC*Ib zs?0wyZdQ}D$`=VF;--AF^ncCpiHjATT*V%eltiMSr~+MONlM5^e>6Fyt-PkuDDhSi zm!fR?Z5|WcGtVF@{A0%V!N-`WW%*q&XAc|gV%#=55rO~rubZ}LOFzq75@`|?mKSR! z-Trz?nk+wewK6?IuQKw6W5Ng`c&R5Clo%qDcoW=pX3jLFR>dzP7RP+|N%6z#_JBH* z+qwI}biwnG_2)HHbSxQA&KNyhR$__rA{$w=bwQKx&mtUlALbGPwT%h4%p!tsEh*{s zR%CBC*038@why_8vu81#S3*A4S!WXqgL6$OHcTsz&E{Pu)3wv8kWu{j z;nL8(LP&C1;?gLIbXn#xe0`mf|FASpG`+luU6Dc8p^rzu3s*|$yfmYRU*Uti<4@A8 z@ltoHDuZA95x)o|mo*9wmLJB+Tt40@9{9PbM#%lE{C4aw(R?eHktc6Rek|&_euE_1 z`MCHDyN`;|xg1FoBiqN4H$1s_baf<6{q-s1HN3wcD&d{Lx#?Q~5h(C@=2aIk(`Hd5 z&nBw}!I}2Cc-0YiQW#Cy8el@?VP4lmvHTPF(h6;E+=<(cg`ltEtEr`@n@(~p2A8?D zYYKf4MDs%a4V0KmW4pJBIt86haMx63hWK+;MccbgaDPL=xb9w&UzcC*X{?aBP0?hL z(B44~-|F!luj$BUX#q}fO(APdil>2WaTS0vXRg9{I>I|~c+Hw`TjR7{AH7mHtEKv@gHAa8u(x|E@=o1wDElZxm)1%w8eRtnHaiP&9$V+(qF|O-(&fY zIjGn^EAN`lP(MOvuDC|EBGLi^`EsT}r>ZZrHA(EEcf)Rn#;s#3zoQuA@v3$pvryKboM|g`8gmCj zD75aS=glo0aDv!SnPDnU8T&_EuU59%@>obXzEXSBt~j3BG+`5_x*_jpE&(n}X6B<> zTgf&|3bQ@pmFOQAGu;C;%l1Yu6)ky&lxUO0f(DxkZS7V!iVt&&$HU>`qJhY5m=9=~Q&9q^=iq}{W zNxap>eC(mIejP-tBpGjeyepe2f291Or zj4LkLXWqEf;u?$Dy%NYY{cR6^R)KSfMEI;@qXXxbQT0&HbB^b0b{W+ZeW9wg%vCm>Xk>e(H0FZ0Tbl3y|(?Gq)h zBKhx6CBi4QV$_ZUDu`Nh6~~~o5`g5<8=Gxi38@V;?n>sbGJ+*#Q?f#MSebfK85CVN z%8BtEq*H1cMj|U~zyO~w&rPND70n+0qB~7W1sHi;Q5YB+bUY^`aA14&*RjZltp4yaoWu< zH%81t_fw(w9zL2%F6cceev>IBKy(iGs|6Zb8+-``b?L=nEa!wH3$l#at!dFqLaR*3 zn8k{Xc0bMO`+nH7pH2F?fytwfs@xcKp^aG0r90PAuNW9@yX$@}iw)-Qik>{$Cq#(E zt=N?I9M+R`r5a&dEmM@y1&T!!CgaS2JJDuhfoI{?YUnZ=kBt+ackPF{ve3(*jQI^+Uosz zjF3+J!PCTdu91<4Chy$2Ja_Gu@^*I$b{)@kr313HxZ#=QgljyRe2e033|0nQ{Ej~{ zH(!j<#L7jZjc*~1z@~qb*B(2{7%LVz(R{iZ8vp)GZA&ezV3A$tKBKJI z;>*%D1E11c*`3${7R1`e0F&n%p^5=rovh7`ujkT9nhZ35KmUkrN|}I>W!PgWWeQ~d z`>h`bk*}dFWd7pb% zay1*@AxR#wY*fzePo9AK1#P`L{3L1{qzeth)!w48*9+lAD#|59OZx7+zR$C;Q`=9E zeh~ypZNE>|h+^Nt@-XEW|5AkdU}8B+v2G6NH~>f>qruym9M&ImXx5{BD$GhX0x1j# z%2ri$DjM3oWW&PIzl!P$=c0&KaM5*`>XyR?S90B|gv8+KV)jho+6JW{#ieHMH}I>N zQJ49yFDk(F$<65MVnF;mH_v*?K+mfEuRs2M_fLwR)Brjx8kaHtlv&3)ot$g%8ktA6 zWA{Ui)K&5C^Ju?M^{_AXN~04AgejB0w|U9YkoH8r_6zaT_Mg^CiHHp~rlseW8%hB- z9?L!n7(gCoCq+-D}*@$>OEql8mdsEa*;Kz;dR z5D42>0~_x8YBsq#v?0mRB9dAnqR$@Q^t3tpMDasL?v#eMcKo}_UD!iH$Pb#@L=|xZ zZJAN-CX7UO+*aQ`2=*mfC#8wOY)qAsTE=%ZlltxcfDVLh zmIAtoeT`Ur?zGg`2WN4lPg(Lgv$VmEBlaFZdgNVw&b%K#JKjBSFr9;3Bj%2a@`B{{ zVh)d+kwiUR)>8=OMIrB+`(m)~r}v~nk|OQB;e_HF@5@z{dD^WI$ZSgA6=A<6`CQ- zGdiL-`9`b0N^3qfg-1=92Q2>Dy_W6k$#dkA-nu-@y423-W5D9xQbAqgchg?id)w{E z`_X@lE3zCIKJRnEhuKTn%C$PQXNh+;8~j^a^AQRQW9%>J1!<2pN(NFgwIp;PT++-% z@l~g@9jNtIZdt@D4JfsP|Zzl zPHOsPVJVa0JDi*{9MC1=Kz!LXD$&XAsD^GOD?7KgoSh9i-|$A4ZV6fCie`}uZQp;o ze~4hPs=(sNW3fvirNk>?d7ip>icYdkZO6{BTRJkqJV>mjVxEfGgRAt0 z-Q)K)KmMCASZJ9Vano4w6P?FLF#Y9#7Gbf|v-F!OFeB>&dQ?OugvfG>&b!~kHobMp zJ_x-uBK(-*2zL*F|F(jGZtQScn6c1p+s1KzzKo1636}o=HNUwIsmVND_EMs{zSj>} z)a0_IJPj@<8zrFg5W*4YzP}EgErIqxc=`rMV@56+U&(uU z)Qha#ca-x}&|g)6E6$D~IG^wVU-Vc~IiF_+wx_*&9n?Hx9QPcZtaJEc_incH+5kQq zt+_|TUiwX@C-PtBF=8*qikrFld<;kseOkKpG2j%u$nbI2n3Y_FD`l=GEP01FbHbPF zUIJ(E@lljON2Kqgo4&eb)E?WmYQE8gEN&CSX!i%0jf<*u$K6dZ@m4n`j2%s2zh*{* zG;XuOC7fQ!BXsdnhK68=bW}x&gWHLX^YwSF;J9z!ipxi2cZjZVC|@#uH&DxPbBz`t zOiyJAeb;ekBWE+|JfM%J(r7$>FqZ#-c$mx|lc!=AXGaHz@ z;3kFOyow}dqB)V5V=-U%NrcJ5EeZ`rlHaE3lugOm0>3}j=A9<5Q6^EDSG22+Xe-tP zx_808WoQ;$11|Jw^wfi-?;ZxwdZv79K2S$5r+A5#y;+I2g!Qu&z6hAJs|gm59X^>2 zy>i(n+)w-abFWWIVZXK2@)*Huph);{(VvFZ(ZCr8KUb;0a3`YS`2zVJSl#)XqAl0b z5KvW99d2vN!Jt+~1^LF{%?E$WM_+a8@t|Q@@$`2pOF$Uym-h!gb$!~`3ISbA@d`yD>k z_PnA;&$e7`a;lmY$d}LigP}6`2|Ob-PZ;p}O^VouxfhEY3++!Z1R^?tqvNL#V&}3ZBk1*m8kGsxFJ9a)o+lXjUUG zCp;m2;QDj8^6hm#Lr`JhTP%h#@TU~60jdbsx|9$11ig(In7rS(`n$;% z>k1=Yo$d~N{63B!s5voh5HU0u8S32?gB<^^{ruHhm+=qRmL%>aE=GY?9&Cg0ZsInI z*v~F_iXjLlg@CWAHnN}tb^p6V@oxWrW9ftkqZ9(b>kF?oZEObR6kzNLADNPBpjziq z{o>u&PC(3R0ESg*y1SC&&I-l!_711X_68KZn%<33=PO^Uhh+#o)s@0uU0w7Xla$~R z!A&-?Sj0uXZ0fti`!Y;$Cx#UIbxL+9ksch{?FMf^MI zL>HxG2daO1Dw-^xnRJSV&B(;ol!?Y6 zo*0eBrmU(zjci z4@-zv=-If@&)@ZBWu0t=f2Lebexn2B9_D-y6;FxZy&i$Qo^+D+b<{O!8}ub2) zdikwe)i1P{4vS@b{y4&9ezZr_d^@jT@IF$5N|4q?UHycev@g~L*(w+ z=lObr9>x+eDbJc+FFWwITRl^U#BP%-UXhJ2E8&yKz`A#v?g!JEW%t%&mtTX!gdsZK zyMBkHtiDOfjlTF%Md`Rp*dQodAG;uVo8nWJv{8S(w=*+LQUIz~9b=y%R`DHc_c3pT z{dcfabd(PM--DI0F~a)%Y}^zX_wO*9)iLT|W$Q3Eb;Kv(i*IVTth^;dWUIHI;_k&k z+yUIMwJ0gD`jNl(z;=*e?yn-@Gv(#T&KKB=@)z{=i89~h+=|gY_y77naMJ~f=vZ&N z--aC~ayUYvbn&haq_Om>-7S&;IOSG@2rR$$58|N@N5Qfhdp%}#0pG3c5c}IYG zPVWc*e)Oaz2;t|=l}-qV=}ogRpHWDuIH(p-E;UbP=Ftt+aBdAaP*yROxWuD-`&d#$ zMfzufkrXfE*S0_>SBP25_%ay%_C>+YXnPnKm5+(Qy7$$#KQ6Mmk<*}a6!d8BAIR0f zWjgTmU@IlqJ+U;kX{YaQrAUVMu}fBAbvoP7aG*act<2{=#XyH$*H4qNcixg(5uCZ@ zyXoZJ*9WcPlx{l5HznsJmER(dwSfAj?{7)UgqQqY|G6A)iXtb3p=V8)vf|-)LetxW zZ5?KGb}yOlmLgEstqd!Y2A}5S(keG9PQGvwZ+yMaW{MZy?9zqsG7kp*EMb~ zjibC3G4Ov3#wuw4;(lnpibM8jtMil8q{q)sc4gk1NPcLx7|WLHE|9ahw#FY-=A3s) z*S0-ukN8=y0Df?IxLX{UY4S=tcl~-0mf)VK(qYI4c4-n9Fr;tQ@y05&cg>U+d%R%Y&RHMxV@EYGS2MFhK0W-MZ;S^n7!98gwbkjAb^k|-poBxue|MA|Ba%kLnn*Y$`U-qHU26OIYkx8z-4{%KpA;Q+ z#3(zo;r)#h)*aD=`gtA*i=|_dpxl+;`jF|PAM0Op1ImR_D$TD3VdLM?Fx>NFFWCY{dJz_CU|IB_dJaWFDyeVAh z)F7B{B0OOkB|Wb5GOj;qCPYAGVdg^vp7Nt>ua80~+$Ati}#1wnwM#T%_>m%MK)H?hbwz2c%5b~6E?AB)x3 z)m=HbiW5w}V5h}zWPKuTw0<}Bhh)5lBzv%Nx=Nt#=gf&SH{u-XP@8~sWcw+P*V;9= z%GTj+klE<^eqBUcBTo@soU{BrH@x)IvX;W00baHCr=6TDZS$?a5$EcRLngJ(*2J%_ zpV{4?-){XLYjo{A+5K}3OyVC#`i{NKYV9*-c~fRMZSoafhq9s42Py{F)&w`W7M)gq zv$E}9FO6f3YrSVXI z?sF~a`t#O*|M=xWkUF!@^trVuN&b5u%}ai{e$LoQd^wv6K40@@JFv_BF&*J%E+STA zO=sHQptSYrN8z(n*=DoN>_7BU->r9u4t`5Q9nbZzKfcPVH(eThY0uZAKF=(Z-I`SJ z=S7kh8}HF&KCFZ(scP9#p$sg=a?vXGzvYK{dipOcM;Thh%wdwO_`WrZUm`fhL0oa{ zS(LlB)cWeZuXla)rz9Msja~&v&}GaCNOwoXb#m}j*_F#F{H~0MCO_5~BDAPj^`8R2 zG5Itf9*$Xd8*!EHe+`4Q}0Pe@EUX)jxtu)A}zJH;kqW`z`nVPvAs7i%`gb{}Dgqpz(|TkqyaFhRIwNw`aWcUEVjprQ+aL}H zs$Ha;pHwZe#1&hAw>CM>ppk}V+X=S||JyL;sH#qRu!b=k9|>x%+Bf=#rY+s;s@!u zkTh1#?Spz-JcXgh`}BgGZ~W0kDdF5#li%{Omgg`&*dFaJp_g7X<9vpnuT{rbc9!h* z)-t)uURa>ldQTs@TBA0iwY}$V=+{LqQy!m@Jdpye6ZNjT@|A;?ciu-?zx$!&CBecx^L%+>40n}sb_2>V2(mBML zISMo>J2`}|(mKvX7F1PMEJ_vmrGD(l|LpwwlCz|KTm1aNM>Z0(ln>tu?5bxA;|GyX zj#X+7=dk^#bCy-K%A;h|a`YF*;XMc!1~_7;Xb8e*@)h*nh&sa4&6c5h!cg;qAi$q;8nV^`x@ z?kdJ&6+DfyZdNV-Y0Xv6;+z^Q)0H;YsJyHfdaR_MW{*L8;pDHgDb3`u-nE#nXuAEU zVoW-q;y#zM!Hn5+R=vW=qbQ7Du$Lx|)29mQ1`?+nq3?DvpX7P=$N9(msi&Ko!^*Gh zdHTNn{Gzv`Nyi>y<_fLY38@OXn4U`R`DA_B$%fXegpN%-Ykk%(q^i;4&me;T-i_ya zny3ARe>bm{{EL&2%VOLxl$(;L8YQnJJ2fCYxRm@S3VQfdGjpMNuwQ-Z-)}Cyk*Y{A zX1)(fy38WDwcoGN6*+a8zS9>nzj>!2DQ_mcigNiLVl0^TA%y@&56loJ6@SLAIQGf~ z4(s2}iE>Iz@l&XXjbC{dR*lGze*E~qE0~Wp%epX!He6-&z;8)7VgJpV*A(&yh{9d3mQO@eod~ zwN=b<9g8n+PCY;|LKn9kFD1U)it@?Ykg}-y+LW4m*IM?0He-PQY~R#Rl$Z|7s<=*S zcHCld$#*`+0rBKzH=6^tYP-~CO^YIpu_S!?_9yD-pjqfpn=ZAvurxxZUz?vao51SD zZD#jo8k81KGwX#*RXLn@dil|a$7zGVw{P4)X(o35P>nwq6qzfVDU_5*VFw2P+n$ve(x=-596HbNJLuq$oFk^3rFq z(++YpUfeUSFvFeZy$G*p6_4cZX84jSpPpSZ7e{$%-Ko=35c?Ag#I#z!X85VYotXsd zj;AJKKcw&86>g~PdTck}zWi(HzE=F7u!0>Oc-)olwL*t;zQe)OukmULXlT^J`ztJ^Fz=E^tGi}&mCL~wI-tnOfcqFgm{ou9}mp}o$SMMV=Z*_`oPA`WgK9QYv066=- z{5e1Nya|8>cKOWrHfLV*On?*R!TL?>=lh3m@*N#|nN(sAtu5D;ePPwf3JbCNbwQ2K zT)MWWRL#@x#wM6oc|>^kIw+_-bGyd&WJ}HTh+F%VB$*^Yq3~RlFIp&>{>~HW8FcwA zW5_p~=Z(4|ohmaTh_wFJvq%V{d5%RP5QNZY>FTLORJC_3FO( zJjS9r0iUJeXEzW+CTs7ln%IZg4o>^lWGL^&H6O~`DiBkjubN(E)^xJFTraYmimMPl zc;+*r%Duh+_V7aSL#sku{FMjZg?!z&nJ)3(`NcLIB|bgk{hz!-SQklnd(ZZ`u41`W z#O1wO{Y)wv|$ zEnJ%b{pO8HxTz9hemALq{KK%%@za;3G42{f@J8E=SOUT2hC@9Jfm#JC7IO1-t_P6S zt>;GRBk~E~2V$%&PCA(Hbe)8`!-DR_wq0Q9DCi!(UgMSQCYj>3<@woXCTD@*)>PK= z#;G#g@s3fVx78-Sy41VRXC?!)R-cE9YdS!3j6j@JW*wOR+(7}y!)#X1snywL>tq!EN1__ck zulQh`7R`zLF-@O+d?Z+Uu;Y?`o*_Kh-gi+PFXQjNMR3cdim`;t8sv$#%dt3bm*H_ z`%f=<$C_^wUugdH$kXWe{0i|C!v%eL*kSINHtG^ApMKuIc%fo#ED5N&opFP~GX5cF z>S_1fo6M~6DMtQJSJ``VVtn6PYkF+o!!VG_A{U;b zj69GSn`980O@D{UL5tRru*Q)`s%Z1OA+BPf4OFuCZGYZOQW3jXTJgMU+`qwcw4KmI z{6_U6-V;6G3aL}okdaw=(34qw&v_BG`TCMpBAZf0((F>F z^v8@42AMI>_mY=VoBOOUhmL=1e7ILjBVLSibTl#{hu}P)L2v!#^llzJfWZw7dW-czFtgm%6F!hnBxh$U^s3z!f}g#?Ur%p80fiSUx% zfMHs%;%8pSKbNP#M|#S{ue_yu@Gx{!*SkwoL4jVOj!K}yCWs;bD5s7q5#%YqPt|!w z?4h_9G0%CqNKj7#EhstzaA_4&0tbucxntC1ocZKDKSA2j`ZWMYj-8kej0|yNY@MMAUxP**E>{g za|vCb>P(=a1FFIt%tXOZZBAA+*-2#O8lV{RVSgd2$@%XeJ*Gs?(R8>VoK7MoKTd}K z{!eF52c?-o2+UJ}lV@Hjh)HPj0x${}jRY#X2O?cw*&F4*+M#YgC)-@Memil zG+)I?(?voItriFmA_{Psc)s_T#_mqpgWCsM-q`*q6KGN@{r%Gs{k$kp`Zi#|bD#51 zr@)n98KGbtO#Q|&Gp%7)zCOGVPNzh}j#DwZR4(JjVg63oOB4AiAXU(w0oVkt>bR7!gdJ4G~f7TDcp-{*fUxqvqlQ^m8$BhQGk%w#GUteD*_}Xi1pH0jJ;-ZoPA#- z#q+N$&0%Mh-m$kFrm;wIIJV4D`Yi5TK}e8SRCdADoj-b{tLq@)z~HUc{}#4Y5hvO7 zb6QLi&5D)Z6cdywK z?iZX^KXKz~^l&(EYg=Gsn%L6Q6uIN<5sd>&BwVoG8+W&g73EkhTfz>bv$ApIKQW^8j;^(XvuL zdhg#Xb^B!6Cx2g%JP9Kg?hQl+nP^C;?_eSD<{DLUfIGBxkX*FVr@Myy_NeS7a`^^3 zgz5%kG(5bGZkjoFwmsx#fuJa>qZ+BO z*=&0_x1hUsMYny%hwujzvjuA>FRg|e9y$Fu+W)d=3`wLF-QNkGgd?t z-YQNn24Mwvm7inZ>#Wc_)xKGcY7@{0q?MwRY|pN$P!Z%^H;P89(UwV-jLB$6nQX zxVf)@Go;DWOweu>6!KFm-Y1?9yMr4g*C3}z7u1`vur)kf{Wk|dBrZlRVw4?F$s_c{ zg-K})*2<^b%EUN~PeX(58ZB>5xXww9i2HKXa2d{GYn^kt#j7|S+_^$lZMn zd9!ABntxF+Nn9PJ52Y!ONMJ_)m_F%y>}b3q0CEX+kV2}ks1@6|69&gmjz5yt6xt^| zYO)$`To8c%{lVLoJ)n}0mzaimTECtkfoFQioaTRxfPhHmkc&bE05A*9B9ETuq$QBm zKbQP^2>_0*LZak9pR$R0Cn73=E;}k@VB+je$%;hwlYiP*nbwbfU_vPYfai;6YHn>Z zZoPvM1kt0*xkL~vC>CP$v82O;>#o>eEh_zC7X_vo35|QMp)2SnVEoX89?F}u+B%I9 zVI~;#n|4ytg{GiWJ)L#1JMq+fOPwAM*UA8M_RYa>_zBI`X`D2NVcU>Es9?E3yXXB# z8uNpY`!Odw@ctH1L%wm(V5~U0mDhbal8Brje4W1V{#O6IV9SsiSD=Av%HuN@5GJ*6#d9Sn(8-#A|d}FF`GkT zUCYA+aLy?}FZ|1Vm$4g01^4IL<%FLCoxDBtuY|EwwdC+1mq!(P?0kc(MJyEGxc{r? zM}81E8|&A`ocXs?rCor|;$!r=;t1NB!`(M%x3~vqOcSUk;vMgZyZm8hW#-%S1Nv#O z=p;7=$TWwzxcU=Mh}Oi$mTuz=T26gKl{)?NL7MTnvNHQt`Ujr^-(2+GaI!N_euiZf zGW_G5W8fNbHw2Y_f8b_f5-*b;OQZl*EZ8mG-tDyf{>V8$`&Ey-k)=Cn^dSFC`$*Yt z9Q%rCAHu=G)U5pu-YS?u0(Nlev~&4hvJ-oHKt>mLK^y9@n$z8l%2Zgo7%0#rzKwNZ zs`^O%W4BxaysZC{d&}qzt88hT9R4cQb>J+MSz2hR;acQ__e|X?6v=Gg8*|bY-3^nT z^Br^Lb~m~B%O~M3Xh_JxAK0=sjxBlF23JP7%xfS!7kgaCo02x{C;RA+#rJuQf4$#lsoC+haOk`b)T4kSadp64SB~y4D|AV|(a_&!*yGQ6wD;y$G)K*y^MStEsF19TJ zAhNY}wRurXhMG)srBhv>=z=sN+-Fz@EOcvwYfff4*5h~w)qhR6)GZ!^n#Bd0zGYX# z!(+aTNzJ9#1sq%YP>c(`indtm+g{5A7xtk!JYp`rMV#d9S)V~Mj$a~;IIBCDu zK&69*&8ggC&U9`xeiXuU-$&@_4T{Y@ZbM3fvl2%@HQ$pbcDFf?46^UERg=O@hI;%rl;o7Nr_fT+vxvpyws+nS zKNBQ-EkxY<`b>ROjxiB91f>Fue;sq3*$~X%Q3bdt27$Cpq0lcL@yJDJUFhNQ?;;m_ z#8?O*^0REPak#0UJcaRNI8fL|GEoVKEiXkcY!O~tRT z1Ax6J*Ezs3<3J3&B)F>vQo~07n-dM~uUs0vYDY*nzM7vBc8Mr`DD2~p%Ometd7cbt z!y^}@`=$Fx*bqLV6)s(*ZfJsl$8$ob!6F1PP7*!)QF7|%!(&yP8a#4fg5#R2`7u~# z4Q^=Z8C+2dggHLIs{5<@cX(L;INRv~ieIiscpIHjZP0#D?slnTQ_~IA$;ar2qv(Nw zkFTS+Q1jGxwRJb-LH5BvwvkN~hH@Cwa}Ky90<~ujhGaVX4x}Oc_wXo=fCWP>=r2LD zQyM6M(>hfIk3uCctwV{yc+`Yh1stH59TksXw4wRccnC^o1!8h9swB|HQ2=;ArxVgp zl>$Em0y3L`d@rlty*gLvcE0E>zb%!?VK!i)iI6Juut_g|lSR4^i3K8AJXc6WJdg>7 z#GEMXv;ZIoMO_`BdlYt|kcT`V^FbWPId|wz^F`8Yl^VL31Yr=xhQF(7cJ#2k0LNXt(wVn7qc2LSTea#t)SQ*BpAa+(P zM0L$}T3|?bx*p&$4L%}+QzSn+&h$^rR9D+77kv=}r#Ed%M%xyu1xXN$r$VVo(iGsg zOxYShc5RI;*AL;Ouk_&r#cLm81u+2~Jd`no?{G^zbjszr%5S69%ZuPuGD( z>gl7t-68v!>@ zCcdJ{1IMX<4a#tuxYBhcZ5bZ0I=ukai{B4X`_LRaO~G|C2Gxuj8HP#wMbZl1xC=rS zMlabXJAy_JtYYMt3;ue5kA#lSmKwgrWB&IflUiHy5Yg_k~w-cKR4G^C0DhQ+YC-Wgv2!Je~)!*UUGO-bQ@-U4~ z9_xs{bwVe!&?f0ZdF%~FjSN@ZXO&*mpE(hk-0?nx~x)yaFyw)0*?YQuAG-L7&*sG38Jmf_a^EU zV$-SUZ*zTaAT0V*UA=k-G%L#!y1}hK7rrYfQx|l!JPYq{1B_Ry&^QN^R|p%fK&C#d z3@Gy?FdBX}<1 zj+Az+f)g>zOb~1)3KF9f>}gG8p8MrWmrL~Bc;ZjoiBrMmbBgB&$b`B-t=cDC~SP2t?I zcS=h9d|i>=)0|IJ=Xd?Sw$1y5420anGRhq>dpe7jX5taQ8`0qbRw}}JzD3pFEk)L# z?HnBC2D>a&vjwv zF)fl9Ove3FvG14fn{5Q?Kz4ORyKLER*wyB_qfK7AR&_lHRb`F*1EF6i{Bzm~sbz)fm zb7al`Zy)=dg`!okX@;YndNcl)bJ71-cTJu`mX=;+;bMPv32|s92ax0|V!=L0_$gaLKXXCDS!7Ts;>UFE;(E4HbRfr)J(0 z^GHo`o^Cxmd*ZP>t*yQBFDu4bs~o~mrh0@_4vI>P8{M-Hu;8mHuSGnXtu@CO!XMLU zb%s*v+5A-_U(QouRw;mzw_7q|Q(0ZTmBsBzum|CMQ>ab{IHKyYdOnR9O|(Z*nYP_W zAF@M3*IOv#>vAKEV{TDip`3qS^qtWM>IyjwK>llF-?E^+eK8O9 z5L67rtWUJm_62~_tpouB8=djf*9bhF@RlK+bYjawHQjT!+ENl^UXvUG!#;p+Zqm%p z0w7}mhELGe2=a!O9=!erhdW}1-b$klG>$!*GK0cmwHvEnTYnKH_f<4DiY$>^@4 zF2NZIufML5tCi@$j?U67Vi^EvlW@7N`}R}iph$=bhE0Wp2_}sr1EF+uW4ctn8tGs$ zA2!{S3EEYJ_Z5G^FVXbJwSAI2Y5}^pIcu!+rO^>~#x^T^WB`b#`ctEciB?;ADVHj( z*nFXeo^`g%N^Rl;AO+gXd-;qv29962mHF$PLZo*dR`05N1{Qb7G@E*F6e2)sIKd$X=c z-y_H9>|BomwRqIDN6U`hQVwEk z_G8#<5pCa=pWOg~9h_AZf1lYW8Yia6?4$XlMStOa@RoCzp>Db|vZve3MgN5_V_xj} zf>4I~zjVFaR_b=IyvOs8D23%HJ1z_G7!DmJ83Tf{R|XAvUzVZ=#qho7m@i=S>bszc zR!6~!=q2&jGH_D9@Z{UFj;DaIrU}K_p-1eAwSgIK2~Rg9x!q&|e!A;`#4 zZU=+odNRKZqvnisPZ0V&H_nozYtI0(*R}8!M0ZGkYW`x*#DctP;b0 z81sWEu23@PHPIcwpIsGB=mBSpDY-eM7-|E9;aHJUddS>Ve{=UkaU>7$FRWkzf;@!0|w2H z&BZ27qByDa*0j>P2S4v0gC|D%9TYMUR zpgRO?Oy@e$ojQm33wToY-n0O6tLEN{u5vGNBPD&Xw&>Hepy78?_PuPpBi}C|*5scA z&;e0|hYzyCBysj9JQx&e6z&LD_y2G2tXe_g_yD+73faYWK9AvNh|)VD+b`} zSEMSt?{Ta|fX)3Q4V&sdG!fUT>g6~5Gk2wx#_|LP1~g%frK$KF-`U+ zbH$0Nu$R)Fvf7@(Fcg4@wVIa!z%`hScv9uPArn?R8z~F zRa1@phIjt7J6^R(m(x~)SYe&CDW;Qe06U;mamBP>uNl8=XaQipsP{5n0P(mctwlFs z?norVLfIU})|mm?vMaG*W#tsKT+9cUA8Zpj3htJ+M}0p12cbu{%J-N>8*nV~Jn5E4 zIqTzuZ8W%Vyk%D#%Lw7`Akeova&dMfm(8x)>f@bBwEUb2&P^;2c;7nz34+u) zEmo`hY0QIC{^{_XEX0ln6u26OZWM-L!j|xYXo&l2q}@g0gKw@42Q!OibuWPRv4Q#- zClTKANS1iSV7Kfls-*tE4L({7?L5;RmZ=NnH$R#?HzJ@!&l=TxZO|`PWntc1zI-i? zD>jR5YHtYYZl9Pd{)KJnxJ=y2Y53%$t0^P#-{FtTb0RQ5*fC9RR1a6P%;aeIi6;Et z@=}ite|nmr1X0l8jq+|u<&8KBu&9o{7H`?fnqhqp~9zPJjJ z6TlpkeU3Z%ku9;?C@awqd9UAofX#~VotwTb^U{J$9o8bdiuG#VMFmR>8ah5)`wSa^ z69e0p`!lZVe*CbSw;{iL;Z@A<%M33YgMBrIy3ez^URIS%e@yL{X~O%}YA@VHQ%)b+ zqBhHF9!8h|X8TUO(qN7r$*XQ%e6GU`_QRFQlFFsfht^)?u97j!c~Ho_Aa%g z%IHk(_?byN`FqD{c>Low)RJSNOLvk}?#O1AB8}%%U%__tjmPZH|G0DkuV^)v56Ap5 z`?M1_LJ3bDnsaV9N+PjC&tw;y?ppap2JgG1@=k3fc_Dyn`c@(hD(@Z^ee;lAgC1LL z#AZueE6&edKTLbdxw%y4pvWzW;r%na{5W`AA2FFV}h>=eRyZU3-+zB00sJ&?zYMs3-Wv!lROhK_^P){&SFXfv3$M zy_|k}HP$O&zhkw%33Bx{4D~jZjv5(=g1lPvf=@3n@W+H(D6YEzM7Q^f*zvagy^Yle zA+rq0!_@KE?2!JEgI~|qm*P&NC;0s2rz@qi!9((~d>a2@uC~%K?bwBnTBV4`LTIOp zb?;RlMn(>QhVyo2013VS-TU;98M*;yC#ckoFrs1qF&nekc0y1Y%%Fx++DYBO_rUsqk_gnp4uF=DAB zVu(a0;;$6~>0h)d0S{DI{?i&^pcz{L=_|4YvV853ScB4oxR-BN zThd=@^uRy)-aH#a_x29^14=5ikqy?aXXs%u^s&UH$WfNKty#9&{kah`c_{4s_a5fD zRVY9u!4yR)B`w9ciJ1_*hG^^vC>Q&Hg{5E7#5E$?je z{nRFV6LZ67Zx*d~m$#{ium|LW^cQ?%@5=@X5>SX+*^pRn6&_9qM5eCm%pP$x08do* zb#YjVd()4FP&T;l`OI_WcTahb(!8;xy*w~5df`GO^vU@+&c&31l2=)yn-9GMm>X@R z9xdK&Ba`Q|6@0bF-mNc1X}G`ARt;l+4xyjF&*Z@rAZ|BD^-QhAPcZDBMG;T8`zoT8 zTT#*N7kod_nlUm-3$df#yJYB-?9VT0NU=Zo!G2e9um|^#Prb(gs+?z>YrMDbbj6Uz zxzow3_w0Tjj7=5=y?-%_e8}1)PpkjAw@lvQD?)}g>&8SB?LCD;Llugf{(D8ji2}mW zOPrQqx(Nf(je=YnTVkb=MvKool|cgdN8gW28FOY3nwJ`5hu0@+^E!vWkkO+cONZs| zTmL1mu+>?oY+iLU`KeWqBQ+F)d~%rHI?VQb@jJffH3*bV|Qwzs2M$=WJRyc!HB|I|bM z>~A&I9HStlBj=%-Av6+C>A=lH+9M;;_vsWbe*-mZ#NRKnVu{R&A_L5v^qicW03DCa z>vvX9E#YVH=zS5xkVx|RqQF=6ery3oF6t*aJd<@C=s$kFvep74VL}TC#y@p;P~g#O zu(4EXLE!Ii$c2UKWe+`2wY1bZSk!Z`bdn(OaP7Ky4B}q$3K8~SU-+hrm|+k?R0Ud-V$XsgLH-mzzO%I$hNy=Bohl#VMfk zLMPSE1Sn{0vR;Oc{L`*GAQq7~7dL^5c0NxiZ(?R{y$X)(?g2gTrGL;f)=hZ0gW|ez zIqq}FCkAHq4}CqP5=7=1R>m-KGZCvS3{m|`&BxpdfTugiiILyY7iyp0Jtrs725wPH z#GtRAnOtHJ-;B30@x`y&Kv?tryIlvhWyg=98v35li-fV^F{}>npP@_DM9yAE{m?s**veuCNMs3P75jSdlR&92lj8$9{D9PUoh`(ZU-4v=s;j z$-|#1$nQ&OMIyR3Nrtp~-fc_;4)KDN7gR~iIe;XJ_ShF^h|`kdL|~`+E7)7nqR=~T z=fwPf$`W-q$l?RU#t@}AA!dn2$sGk~+-l1&I3=eC{uLzGJ^99h`zCAHlNT)b^@!AsLiH@en%`0I{i9Tc|5bdkAz+~@j zssf05iq9_w^0c90P<8wK%^dwT=E-xp3Y0lobQi0x#){Ocy$UUM=;p9IIqc|bUOz| z-6cX-Vt#lqC60UtS(VFyLYQzv;A-n1(j**fS_l$|LhP+Ep1SE82@%;iry(bt$^}9~ z-!%JN%mn-)MNa*cM>vE3sIv}#HY0rrd2tAfq1orNC`Us}lKS1eWFh4GF?*wq!XUMZ zjM`8*R|Ne*!9E|hdxfg%76r6u6fFr2FOJg~_958xL;G2Ln@M3kgQH~p=a?<~PA{}h zLG!E3!q?boy_J^kbYg|4S~=wCAQ)A^Yo+Vpf&&`!g;Nr9FK zlt%M75G7ALZ9vaQhs;G3r4(J5<8vj1emG(4NnL953twG-ChaL?d<%@WkOn*Q%m z|JB{vA{+Y}7gy*cQyw!2z^H4qlzz@3e;Dx}Dqy8XGj3&9)?j6WBu=?r4N-a3M#=_1 zKR|eVrE>KAIAuq*@<311KKbk<;ujKgwjZ@huJvb2j%j!T#^T~1=?Ci{j;!dtEAx?0 zz!-oFPq!M?7Z{|&U2**@WU=cUP1MM%4TuHhUybsB3jFxlVUcj1IgoV1ypI7|;SCM3 zmhE(33m|HdUeI-v40?4;Y#5|?hQckh;{Jh?#4Eo6M9!jq%Z+$++h>eZf7sCB4WuV`iPo0_VqhYeIueJc*nDB5G0I(OBEW+EtkbRMi4L%V7!O zq_(UI)=UH)zO@=glDfodrQhOn$$C2jR%HkGZ~-i0+g~bHH+Nsi0UfBiIR39F=8OC- zOR};os<;#d(sIDnwyTtZzauA&oQ1#>Eplk5)DXTpbHgAJ7zSL(?u3CcUh8hOm=NF0 zSxkT*%?)eyo{2Ooz#uBz=1|jv>P}QN#~9wrhN8W^uC zuhM>|TwC__-1D84L%n$DSdLU^OI|e+{&4+c1h_pUa2DBS5vDetOk@ z@UXvbSg=!#PS_W? z@R4c(qt4wj#_YYy#I$x|NVruX348~O25fGhWUkIvxrv5rt&7yl;1b zVLzAZQ-m9%1vaPJk1QwtrlE~JI)U$5m zErvOQlg{#2rZRhmf6;|V_I@Y;C|*!LJDWLq#nB*j{0LRiYP@(q&jk|5XlwNBLrC<1 z5Cvx8xy*_hARP`XG9@;a;buJvIOa%2*6bAS8zoe+&y!YknhEz&PT+<%Ug6Q+Asno%KltBn$*1s!J~Ft zhv))FpF-VG(dO7%rV-`IKkqAvMj3+e@mv5M~G7>DrcEXHJbb8X2wQE(`s!$#=mMPDDK3S~G zzVUCSU|~>^D7sv+YVadNH5}=lr%r{RGVw5{y@`c-t<{l2I$wyq6%~LRBQM#?89)p|hiKm=({MXSP zY#O`T7c^4M@P71UL^Yp}>+`YbZd0hRu$+;_-2nOX(J`>xD*~85t&Qg5@gpg+<@`6t zdV5Lh&i6E0FO}f=1T!oJ&OtJ5j#f|-Zf_ZC~e0+b{bbSwxLa*rG-+*9JDPELt z>ueOzONKJ)YnR72GlOKE_J=&BdBy~MxKrVir3&BZyv33U#+}unH-`>%;@h%kW}7KW zIzi`(I20|P`%i>GVV@ap;ezz=$(!hZYC{JQ^xw^bwn=Q&+XF4RDuz)Q$>OPE;+i{( zfG9xPt&rS}5akd}|8yPW<8&qI)$e;Ws`CjtXZ(y1#T(G)OC4pOyAvnO&Hj&KL_R&3 zN1s0i%oqS`Y5@iJ@qBRip*{tQwydZCx-4H&v95wqoeamv7SCqj8-G;9Hs=unrXd~$ zD3mkDuSc1bfvp@ljF}hx#}K=t&Bai9iNKT4U5WrXn(iSBO?HtC!9g@sO}3|I0jM^bGhOzI@ip zeA@_rJ{xA4c6V{US?Vl%n?Z%|Yg{*GrpZ5nOMwjgu*#l9K!jLieEPXsSVKA6fBLNb z_P@);A88e}6QICQ%NqOmJSBC!t-WAcQFHpUfPzQP=Jot;R-i1{iAvJSAob~V7vKa=L6m&ljvxHiqw+7qo-cQJF;P;K zk~5H1hbBO6hoYivrL4FJm#rgvRAFyRJ=S51DH}J{Az8y-!|_p_cbC;M{+DEKK~44* zFv+6_5Wvn)cF_n4h||?|HPGi(b^*r-Ns+O0jI!DoP|f~-vy&&+ zTaUObl=mImgvkA?A9h_}a&jfN)>Z11l?);*nl8dzk5`LJ{;sGr1`F&*jrM|0wE5YX z!k1RbgDfu+DbHamp_|7#c#LUp(kBY#+Y!G?R)L)J(#OLefqyRQf=oU__pdo*wf4L` zG%eMrWOqHJoo!!naD`C@aL`?dXGm|{`cv%4MewF% zKI(!u%`uqvFCGC16w?B*jGlIZ3+{$*+x?}f-HQOJ=$$;GN`41Yl*>RP_c)wiIb_oN zX-WT>-lY@|-h_gT_;_Mm!OoQH#r%m;syr1c7pPIR@8zoO)1?;5ru|Eu*N=UI@ABu@ z@bV~m=bNO{@fCDHLI=^ZjK=9S;DhWp{EHoYWCjnY(qBc-g+W~Arov}5We9huP}_4> z@L2GBQA)aw?vci+PZjY(COVvsI8^N+fFd?M)k9XP&?S`cM|9iuRV>-h3c$6rjUU~@R+0vY&agol1CF= z!&IX``vcpx4+1KLQ@&c(En%RkDo39R2;n3yEc&~7#j26f(?5T((BS75`RyudvA>=$ zTCG6B#0Sk#(VbE=dj?39xSrPI52pc##H9xfv2kiWk+0_pzcxomd=$YHU?_C;O+WbU zT=NOT$C(Ep(f;*$a1gnQ*_KECENc0B>TX$C8=FsXwulz5^BSEg%>`vmqdE0o!}(K~ zo2CQo!^WulzUJ=IC>nN3GnsKQAV1s>$gg?S(g)xS7VkobntsVTavlIKISMW!K&nt- z0oC&wF5mefS{Xu5LDXM+`7zpGQ2J(+u8*|{98@KIh91C?D2-NL)jz^veF1?}N?tqS zx}rKPeDE3*UxyFM6rYe4NX^LMs1NsS_#wn$%z+Wk(bp~B|9r@oB`uI!=PN|v@%pDn zv;-*(j&xH&u_%mp9j-vQA9KJ*IY3ESd;HNcl1=-R-3aC){z6;+( zq+cdf{V`IGXf#x})J6(=#K)I7JmE%2L!~ z4(L_iMhp%XkX$)PnA0>J?ad>^J@u!7W0!{t&F2o{vLVL^MK@@Ac;TpTMO0A&66nVa ztPQz%a-Ppwo_&$_U)mP(8uYYaL@l@aa?kQl1hqvwiK|w~GJF!V0tSsX9(1*Vu~`xB zWEKz+YC&JR2{sT|n^mXvj!a~5URyb&}c-q>} z)1WDHb61_WR{e^e%WKc3!;_YG96r3zU!3PF@3i<3InR-lWENcb?;cxmXJ_J0G84TvgkdEZ*f>cwG>p8Ci4%b8oF1(7~fcAnys zb+YYD%`5gN-4{=2GIo8=B7PFhTluxs?#;}2(xtTZeyU+Q8K$0ReILJFB^8?%21ph5 zcpO}A{f2CgXS#vM43CO6MHZeSzD`zE0cjf?db^E70UTP3RKNUMfo0u z{y)MH&gnl)BgHePy{v{sHSFSeJ7=`e(P*82W&ixoAFr0uDGtB&n@y9=lg4|m*lC6G z!#3eV=&Sv>^W85L@X^n=9ZHpFrRD5{Wrh1^(J#R9+58?=R?$#BRiI)Wqt*o>6*$97 zv%Yyt(l3nu?5pT!k&%jWD~8Gz4fYyhtDpFml>t4jB9Q*13|yG(&0q$vgeK*gh{}FuGGf$_9Pn>9y~6+jwD@h|q9_>_jXxB}Ed z*3d?oT8dFp?D8TGFkH+ai6-Ewwhkk+s|fvA+&UI@Eu?0KwtzRt&EI)Gg&ML}WQq%cVn)7MYkaBc zTyM9JvRdf8_o&e8!#vo4rqP8SDD=`NqB;zNzJ3^LZT4ZeX!DXofkZbC508MovBI38 z3yzcKpaVigqX⁢pBx9MB;RkzwKg2E{Gp#o6%y5+QeC-ryl}U4wFRD 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/mooring.png b/tests/rsrc/bundles/tiles/objects/mooring.png new file mode 100644 index 0000000000000000000000000000000000000000..e11d98b9a23dcadb2695a43af9d282c3d99e5b67 GIT binary patch literal 5986 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 KG`@rNO!+Sy?el^F literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/tree_oak.png b/tests/rsrc/bundles/tiles/objects/tree_oak.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf1d931befd0cfbee0d3f729c73f5ab518b732a GIT binary patch literal 67720 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/tree_palm.png b/tests/rsrc/bundles/tiles/objects/tree_palm.png new file mode 100644 index 0000000000000000000000000000000000000000..3c143b0c3fea3d87961eeb4590cbef4fc260000c GIT binary patch literal 69112 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 R%0YjJ54i4szn7Ts{{StXPqP33 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/tiles/objects/well.png b/tests/rsrc/bundles/tiles/objects/well.png new file mode 100644 index 0000000000000000000000000000000000000000..bb35cb9d2e3e797ac1d12d14c0ed3047eb2d0e46 GIT binary patch literal 22952 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/config/media/iconmgr.properties b/tests/rsrc/config/media/iconmgr.properties new file mode 100644 index 00000000..e8d7b3ee --- /dev/null +++ b/tests/rsrc/config/media/iconmgr.properties @@ -0,0 +1,7 @@ +# +# $Id: iconmgr.properties 924 2002-02-03 22:43:54Z mdb $ +# +# Test properties for the icon manager + +test.path = /media/miso/tiles/node-icons.png +test.metrics = 8, 16, 16 diff --git a/tests/rsrc/config/miso/components.xml b/tests/rsrc/config/miso/components.xml new file mode 100644 index 00000000..bcf1393b --- /dev/null +++ b/tests/rsrc/config/miso/components.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/rsrc/config/miso/scrolling.properties b/tests/rsrc/config/miso/scrolling.properties new file mode 100644 index 00000000..34dddb02 --- /dev/null +++ b/tests/rsrc/config/miso/scrolling.properties @@ -0,0 +1,59 @@ +# +# $Id: scrolling.properties 1014 2002-02-17 23:48:38Z mdb $ +# +# Initial test config values for miso development. +# + +# the tile set repository class that handles tile set storage +tilesetrepo = com.threerings.miso.tile.XMLTileSetRepository + +# the scene repository class that handles scene storage +scenerepo = com.threerings.miso.scene.xml.XMLSceneRepository + +# the directory containing scene description files +sceneroot = rsrc/scenes + +# the tileset descriptions +tilesets = rsrc/config/miso/tilesets.xml + +# the component descriptions +components = rsrc/config/miso/components.xml + +# the list of building types +buildings = Inn, Hall, Bank, Agent, Palace + +# the tileset id for the building icon images +buildings_icon_tsid = 1007 + +# ---------------------------------- +# begin isometric view configuration + +# tile dimensions in pixels +tile_width = 64 +tile_height = 48 + +# fine coordinate system granularity in intra-tile count +fine_granularity = 4 + +# scene dimensions in tile counts +scene_width = 14 +scene_height = 14 + +# scene viewport dimensions in tile counts +scene_view_width = 5 +scene_view_height = 6 + +# vertical offset for scene display origin in tile count +scene_offset_y = -4 + +# whether to show tile coordinates +show_coords = false + +# whether to show locations +show_locs = false + +# whether to show sprite paths +show_paths = false + +# end isometric view configuration +# ---------------------------------- diff --git a/tests/rsrc/config/miso/tile/.cvsignore b/tests/rsrc/config/miso/tile/.cvsignore new file mode 100644 index 00000000..aa4f5775 --- /dev/null +++ b/tests/rsrc/config/miso/tile/.cvsignore @@ -0,0 +1 @@ +fringeconf.dat diff --git a/tests/rsrc/config/miso/tile/fringeconf.xml b/tests/rsrc/config/miso/tile/fringeconf.xml new file mode 100644 index 00000000..46ae23a1 --- /dev/null +++ b/tests/rsrc/config/miso/tile/fringeconf.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/rsrc/config/miso/tilesets-components.xml b/tests/rsrc/config/miso/tilesets-components.xml new file mode 100644 index 00000000..41b11b39 --- /dev/null +++ b/tests/rsrc/config/miso/tilesets-components.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + 94, 94, 94, 94, 94, 94, 94, 94 + 94, 94, 94, 94, 94, 94, 94, 94 + 1, 1, 1, 1, 1, 1, 1, 1 + 1, 1 + 39, 18 + + + + + 94, 94, 94, 94, 94, 94, 94, 94 + 94, 94, 94, 94, 94, 94, 94, 94 + 6, 6, 6, 6, 6, 6, 6, 6 + 52, 51 + 39, 18 + + + + + diff --git a/tests/rsrc/config/miso/tilesets.xml b/tests/rsrc/config/miso/tilesets.xml new file mode 100644 index 00000000..be631571 --- /dev/null +++ b/tests/rsrc/config/miso/tilesets.xml @@ -0,0 +1,78 @@ + + + + + + + + + + media/miso/tiles/sample.png + 48 + 64 + 14 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 + + + + media/miso/tiles/node-icons.png + 16 + 16 + 8 + + + + media/miso/tiles/editor-icons.png + 22 + 20 + 5 + + + + media/miso/tiles/building.png + 293 + 224 + 4 + 2, 2 + 4, 0 + + + + + + + + + + + + media/miso/tiles/landscape.png + 48 + 64 + 5 + 1, 0, 1, 1, 1 + + + + media/miso/tiles/faux-building.png + 265 + 224 + 4 + + + + + + + + + + + + media/miso/tiles/fringe.png + 48, 48, 48, 48, 48 + 64, 64, 64, 64, 64 + 8, 8, 8, 8, 8 + + + diff --git a/tests/rsrc/config/miso/viewer.properties b/tests/rsrc/config/miso/viewer.properties new file mode 100644 index 00000000..8ee7ee79 --- /dev/null +++ b/tests/rsrc/config/miso/viewer.properties @@ -0,0 +1,7 @@ +# +# $Id: viewer.properties 604 2001-11-08 02:58:24Z mdb $ +# +# Miso scene viewer application config values. +# + +default_scene = scenes/default.xml diff --git a/tests/rsrc/config/resource/editor.properties b/tests/rsrc/config/resource/editor.properties new file mode 100644 index 00000000..55eaa263 --- /dev/null +++ b/tests/rsrc/config/resource/editor.properties @@ -0,0 +1,16 @@ +# +# $Id: manager.properties 2121 2003-01-13 22:55:28Z mdb $ +# +# Test resource manager configuration + +# configure the BundledTileSetRepository +resource.set.tilesets = bundles/tiles/ground/bundle.jar:\ + bundles/tiles/objects/bundle.jar + +# configure the BundledComponentRepository +resource.set.components = bundles/components/metadata.jar:\ + bundles/components/pirate/components.jar: \ + bundles/components/vessel/components.jar + +resource.set.general = \ + bundles/components/pirate/components.jar diff --git a/tests/rsrc/config/resource/manager.properties b/tests/rsrc/config/resource/manager.properties new file mode 100644 index 00000000..55eaa263 --- /dev/null +++ b/tests/rsrc/config/resource/manager.properties @@ -0,0 +1,16 @@ +# +# $Id: manager.properties 2121 2003-01-13 22:55:28Z mdb $ +# +# Test resource manager configuration + +# configure the BundledTileSetRepository +resource.set.tilesets = bundles/tiles/ground/bundle.jar:\ + bundles/tiles/objects/bundle.jar + +# configure the BundledComponentRepository +resource.set.components = bundles/components/metadata.jar:\ + bundles/components/pirate/components.jar: \ + bundles/components/vessel/components.jar + +resource.set.general = \ + bundles/components/pirate/components.jar diff --git a/tests/rsrc/media/miso/tiles/building.png b/tests/rsrc/media/miso/tiles/building.png new file mode 100644 index 0000000000000000000000000000000000000000..16fca4818ae341f28f259dc541baae5eef083642 GIT binary patch literal 158557 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/miso/tiles/components/standing_torso_red.png b/tests/rsrc/media/miso/tiles/components/standing_torso_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0eff5f76b3aa101f951054132ce23663a0ad9e22 GIT binary patch literal 18005 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

      S^W3G&uDQv0?dL@q~_iKbPrJfylb)!V! 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�g$Lhppvl)5S6B-;+YWf4Hz;=ZmnRS`G2vw-~z4=Wn>oZyxd7anjg8h~`-@Ddk2wC?T0MHS1lG6kri_Tkn_9b6$_oYRwpbpW6ah1rNdbf#p?d z0y6Z?i}yQk(f-{o*|rUIN!_awnVsA^?M^ygBccR)PalL8NNxqnGxd4*Md0l0D;M>j z2q=}I5DMtQx$85k3@jF&7Q*qnDeo&gG0Km$It4f0JcMi_$$b-{cI&S~?h?yqt1VCH zBy|o%n~WQspM5@&>1B6ngPVqe83xI&tpEe4pZYT! zRLhBM<8e2}5gS8rS*sIqv)5%nVmKMPXhVwJ-%{ZhGgF9aTlXLPY6Yl9`F3b`vVZE` zJDXgJ>uzWpilr*S8!A+)A2)M&xpW!K@>;k&N7f*x;OgA-yyK-)g^ZFUsb!Ey>vOBD zznTF0*-aq`V)FzMHS-p8MyFukf=ARD*>s#%7&4Q!?TEm|e)pPQA{TtE-3!%kCsuRz z$<7If(6JGk(nUrrq{x z6xK)C##60X+78XDR&iUS_-%;_gRI-tsTST=^pGpCiRZO1QnWIhgnQ;^Y^mSiB_7xs z@_M1O*->0*{C>j1TdEKHDjEIus3P`i{l-2C*HZqA_al3CB)Bej;`^qg$5)T__g>M6 zU6T5lshI&a06FbZp{kTPIj0=9d!j-T6tTi7 zOYLz(Z>A+?HE{ai`uD+TYG(ZRXQt)Fj=oLbg8ycAekjC!R1+U5^T~cX?i*=Ng#dgV zrmH`mXCGvlW6HZWD!FSp@Q-P-T14}Q0|&ls-+wN^Un^$+_MCvf;KRQTAO1yi%K!U^ fNj%$%ds%!ZWa+4s6!_?i1I9NkZdB_1^6-BFJx#QA literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/miso/tiles/components/walking_torso.png b/tests/rsrc/media/miso/tiles/components/walking_torso.png new file mode 100644 index 0000000000000000000000000000000000000000..425124c95f0203843fdd6a7a08a73ad0702257cb GIT binary patch literal 255218 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%0D{g50=*AqquECXZGc?SAd&JD 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

      ;`2`{6Gf&h|naD-YoPjnfhw@&sn@mN;u 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�R8%3*D3H-C* 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%0AXQ`tjHo7$IZ(tyUifWkp% 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 H@!9_aM23z{ literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/miso/tiles/node-icons.png b/tests/rsrc/media/miso/tiles/node-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..e267fd01128b83654a295a9d690824062cc0a134 GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^4L~fw!VDyJ%CdF?Dd_;85Lbr(FM-UrU*y>Z_5j(e z2Swj6SNzKG^FITF<;+?j$-r0= zrMq>1fP(BLp1!W^7db>l*`?>6*!~SDbl%g&F{EP7+jAQQTNFfE65l*v5Db2CU?Wp{ z#(@SVpA)?uXElDy?G8z(D4w13?fmj7L6_YV^W!tmZkMjN`|<9HzWDw7f4)APZQvB8 zZ2H#PUbXJrpP(OGKSe)2{zH;M=*_-ngXJturzKmKiU`!KRampOF(HYEnW2fnL4bjS ziNTRUfrEjCu|a`BXp7pxZwJ^IIM%WIF*tm%EdVNd*=WGv#Nfcez`@9%$e_T&(8ACl z!0>{_Hcj$I8XMp713L{0D%svmZ9Hxu@UQVc*PgrLJ!waLmu+je2YQXc)78&qol`;+ E073wO{{R30 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/miso/tiles/sample.png b/tests/rsrc/media/miso/tiles/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..d971bef06784db6075dfbb3535b7cd9b7b4ebdc8 GIT binary patch literal 19248 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%0ABBxF#tQ+CO+saAEjLr& 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ʌ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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/tile/bundle/tools/.cvsignore b/tests/rsrc/media/tile/bundle/tools/.cvsignore new file mode 100644 index 00000000..edfd8732 --- /dev/null +++ b/tests/rsrc/media/tile/bundle/tools/.cvsignore @@ -0,0 +1 @@ +bundle.jar diff --git a/tests/rsrc/media/tile/bundle/tools/building.png b/tests/rsrc/media/tile/bundle/tools/building.png new file mode 100644 index 0000000000000000000000000000000000000000..16fca4818ae341f28f259dc541baae5eef083642 GIT binary patch literal 158557 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

      l-`tp}vrdx)RzE>PLja*1nLZ`TyK8FgVLIAHs#~ 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 + + + + + + node-icons.png + + 16 + 8 + + + + + + fringe.png + 48, 48, 48, 48, 48 + 64, 64, 64, 64, 64 + 8, 8, 8, 8, 8 + + + + + + building.png + 293 + 224 + 4 + 2, 2 + 4, 0 + 4, 3, 4, 3 + 3, 4, 3, 4 + + + diff --git a/tests/rsrc/media/tile/bundle/tools/bundler-config.xml b/tests/rsrc/media/tile/bundle/tools/bundler-config.xml new file mode 100644 index 00000000..3edd05d9 --- /dev/null +++ b/tests/rsrc/media/tile/bundle/tools/bundler-config.xml @@ -0,0 +1,19 @@ + + + + + + bundle/uniform + com.threerings.media.tools.tile.xml.UniformTileSetRuleSet + + + bundle/swissarmy + + com.threerings.media.tools.tile.xml.SwissArmyTileSetRuleSet + + + + bundle/object + com.threerings.media.tools.tile.xml.ObjectTileSetRuleSet + + diff --git a/tests/rsrc/media/tile/bundle/tools/fringe.png b/tests/rsrc/media/tile/bundle/tools/fringe.png new file mode 100644 index 0000000000000000000000000000000000000000..390f45619a33f5bd9008646034cf5aaf70272f30 GIT binary patch literal 14012 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 Mq^;O0Zxi$X0H1?KTmS$7 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/tile/bundle/tools/node-icons.png b/tests/rsrc/media/tile/bundle/tools/node-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..e267fd01128b83654a295a9d690824062cc0a134 GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^4L~fw!VDyJ%CdF?Dd_;85Lbr(FM-UrU*y>Z_5j(e z2Swj6SNzKG^FITF<;+?j$-r0= zrMq>1fP(BLp1!W^7db>l*`?>6*!~SDbl%g&F{EP7+jAQQTNFfE65l*v5Db2CU?Wp{ z#(@SVpA)?uXElDy?G8z(D4w13?fmj7L6_YV^W!tmZkMjN`|<9HzWDw7f4)APZQvB8 zZ2H#PUbXJrpP(OGKSe)2{zH;M=*_-ngXJturzKmKiU`!KRampOF(HYEnW2fnL4bjS ziNTRUfrEjCu|a`BXp7pxZwJ^IIM%WIF*tm%EdVNd*=WGv#Nfcez`@9%$e_T&(8ACl z!0>{_Hcj$I8XMp713L{0D%svmZ9Hxu@UQVc*PgrLJ!waLmu+je2YQXc)78&qol`;+ E073wO{{R30 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/tile/tools/xml/tilesets.xml b/tests/rsrc/media/tile/tools/xml/tilesets.xml new file mode 100644 index 00000000..f75bb667 --- /dev/null +++ b/tests/rsrc/media/tile/tools/xml/tilesets.xml @@ -0,0 +1,37 @@ + + + + + + + node-icons.png + 16 + 16 + 8 + + + + + + fringe.png + 48, 48, 48, 48, 48 + 64, 64, 64, 64, 64 + 8, 8, 8, 8, 8 + 5, 5 + 10, 10 + + + + + + building.png + 293 + 224 + 4 + 2, 2 + 4, 0 + 4, 3, 4, 3 + 3, 4, 3, 4 + + + diff --git a/tests/rsrc/scenes/idyll.xml b/tests/rsrc/scenes/idyll.xml new file mode 100644 index 00000000..2c5abae1 --- /dev/null +++ b/tests/rsrc/scenes/idyll.xml @@ -0,0 +1,19 @@ + + + + 22 + 22 + 10 + 12 + 131072, 131072, 131072, 131072, 131073, 131073, 131073, 131073, 131074, 65537, 65537, 131072, 131074, 131074, 131074, 131074, 131072, 131073, 131074, 131074, 131072, 131074, 131074, 131072, 131072, 131072, 131073, 131073, 131073, 131074, 131072, 65536, 65538, 131072, 131072, 131074, 131072, 131072, 131073, 131074, 131072, 131072, 131072, 131072, 131072, 131074, 131072, 131074, 131072, 131073, 131074, 131073, 131074, 65537, 65536, 131072, 131073, 131072, 131073, 131072, 131074, 131073, 131073, 131073, 131072, 131074, 131073, 131072, 131073, 131074, 131074, 131072, 131074, 131072, 131073, 65536, 65538, 131074, 131074, 131074, 131073, 131073, 131072, 131072, 131073, 131072, 131072, 131072, 131074, 131072, 131074, 131072, 131074, 131074, 131073, 131074, 131074, 65536, 65536, 131073, 131072, 131072, 131074, 131074, 131074, 131073, 131072, 131072, 131074, 131073, 131074, 131073, 131074, 131072, 131073, 131072, 131073, 131073, 131074, 65537, 65538, 131072, 131072, 131072, 131072, 131073, 131072, 131072, 131073, 131074, 131074, 131074, 131073, 131074, 131072, 131073, 131074, 131073, 131072, 131072, 131072, 65536, 65537, 131074, 131073, 131074, 131072, 131074, 131073, 131074, 131073, 131072, 131073, 131072, 131073, 131074, 131074, 131074, 131072, 131074, 131074, 131074, 131072, 65538, 65538, 131074, 131074, 131073, 131073, 131074, 131073, 131073, 131074, 131074, 131072, 131072, 131072, 131073, 131073, 131072, 131072, 131073, 131073, 131074, 131073, 65536, 65537, 65538, 65536, 65537, 65536, 65537, 65537, 65538, 65538, 65536, 131074, 131073, 131073, 131072, 131073, 131074, 131074, 131074, 131073, 131074, 131072, 65536, 65537, 65538, 65536, 65537, 65536, 65538, 65536, 65538, 65537, 65536, 131073, 131073, 131074, 131072, 131074, 131073, 131072, 131074, 131072, 131073, 131072, 65536, 65538, 65536, 65538, 65537, 65538, 65537, 65538, 65536, 65536, 65538, 65538, 131074, 131072, 131074, 131073, 131074, 131074, 131074, 131073, 131074, 131072, 65538, 131073, 131074, 131074, 131072, 131074, 131072, 131074, 131074, 131074, 131072, 131074, 131073, 131073, 131072, 131073, 131072, 131072, 131073, 131073, 131074, 131072, 65537, 131074, 131073, 131073, 131072, 131073, 131072, 131074, 131074, 131073, 131072, 131073, 131072, 131072, 131073, 131074, 131073, 131073, 131074, 65536, 65538, 65538, 65538, 131074, 131073, 131073, 131074, 131073, 131073, 131072, 131073, 131074, 131074, 131072, 131074, 131074, 131073, 131072, 131072, 131074, 131072, 65536, 65538, 65538, 65538, 131073, 131074, 131073, 131074, 131073, 131072, 131073, 131074, 131074, 131073, 131073, 131074, 131072, 131074, 131072, 131073, 131073, 131074, 65536, 65536, 65537, 65537, 131073, 131074, 131073, 131074, 131073, 131072, 131074, 131074, 131073, 131073, 131074, 131074, 131072, 131073, 131073, 131074, 131073, 131074, 65536, 65536, 65537, 65538, 131072, 131073, 131074, 131073, 131073, 131074, 131072, 131074, 131073, 131072, 131074, 131072, 131073, 131073, 131072, 131073, 131073, 131072, 131072, 131072, 65537, 65538, 131074, 131072, 131072, 131072, 131073, 131072, 131072, 131074, 131073, 131074, 131073, 131072, 131073, 131072, 131072, 131072, 131072, 131072, 131073, 131072, 65537, 65536, 131073, 131073, 131074, 131073, 131074, 131074, 131073, 131073, 131072, 131074, 131073, 131074, 131072, 131073, 131073, 131073, 131073, 131072, 131072, 131072, 65537, 65537, 131074, 131074, 131074, 131072, 131073, 131074, 131072, 131074, 131072, 131072, 131074, 131072, 131074, 131074, 131073, 131073, 131073, 131072, 131072, 131074, 131074, 131073, 131073, 131073, 131072, 131072, 131072, 131074, 131074, 131072, 131072, 131074, 131074, 131072, 131074, 131072, 131073, 131074, 131073, 131073, 131072, 131074, 131072, 131073, 131072, 131073, 131073, 131073, 131074, 131074, 131073, 131074, 131073, 131074, 131072, 131074 + + + + + + + + + + + diff --git a/tests/rsrc/scenes/wooded.xml b/tests/rsrc/scenes/wooded.xml new file mode 100644 index 00000000..479f33d3 --- /dev/null +++ b/tests/rsrc/scenes/wooded.xml @@ -0,0 +1,31 @@ + + + + 22 + 22 + 10 + 12 + 131072, 131073, 131073, 131073, 131074, 131072, 131072, 131072, 131073, 131074, 131074, 131072, 131074, 131074, 131072, 131072, 131073, 131073, 131072, 131073, 131073, 131072, 131074, 131072, 131074, 131074, 131072, 131073, 131074, 131072, 131074, 131074, 131074, 131072, 131074, 131074, 131072, 131074, 131072, 131072, 131073, 131074, 131074, 131072, 131074, 131072, 131072, 131072, 131072, 131074, 131073, 131073, 131074, 131073, 131074, 131073, 131074, 131073, 131074, 131074, 131072, 131072, 131073, 131074, 131074, 131073, 131073, 131073, 131073, 131073, 131072, 131073, 131072, 131072, 131072, 131072, 131072, 131074, 131074, 131073, 131074, 131072, 131074, 131074, 131073, 131074, 131073, 131073, 131072, 131073, 131073, 131072, 131074, 131073, 131073, 131074, 131072, 131072, 131073, 131072, 131072, 131073, 131072, 131072, 131074, 131072, 131072, 131074, 131073, 131072, 131072, 131072, 131074, 131074, 131073, 131073, 131073, 131073, 131074, 131073, 131074, 131072, 131074, 131073, 131073, 131072, 131074, 131073, 131072, 131074, 131073, 131072, 131074, 131074, 131074, 131072, 131074, 131073, 131074, 131072, 131073, 131072, 131072, 131072, 131073, 131074, 131073, 131073, 131072, 131072, 131073, 131072, 131072, 131074, 131074, 131074, 131072, 131074, 131074, 131074, 131074, 131074, 131074, 131072, 131072, 131073, 131074, 131073, 131073, 131073, 131072, 131073, 131073, 131073, 131073, 131074, 131073, 131074, 131072, 131072, 131073, 131073, 131072, 131073, 131074, 131074, 131074, 131074, 131072, 131073, 131074, 131072, 131072, 131072, 131074, 131072, 131073, 131073, 131074, 131072, 131072, 131073, 131073, 131072, 131074, 131072, 131073, 131073, 131073, 131073, 131074, 131073, 131072, 131073, 131072, 131073, 131072, 131073, 131072, 131072, 131074, 131074, 131072, 131073, 131074, 131074, 131073, 131074, 131074, 131072, 131073, 131072, 131072, 131072, 131073, 131073, 131072, 131073, 131072, 131074, 131074, 131074, 131073, 131073, 131073, 131073, 131073, 131073, 131073, 131073, 131074, 131073, 131072, 131072, 131074, 131072, 131074, 131073, 131073, 131074, 131074, 131074, 131074, 131072, 131073, 131073, 131074, 131072, 131072, 131073, 131072, 131074, 131073, 131074, 131072, 131072, 131073, 131073, 131074, 131072, 131073, 131074, 131072, 131073, 131074, 131073, 131072, 131072, 131074, 131072, 131073, 131073, 131072, 131074, 131073, 131072, 131074, 131072, 131074, 131072, 131072, 131074, 131073, 131074, 131074, 131073, 131072, 131074, 131072, 131074, 131073, 131073, 131073, 131073, 131072, 131074, 131073, 131073, 131074, 131073, 131073, 131074, 131074, 131074, 131072, 131073, 131072, 131074, 131072, 131074, 131072, 131072, 131073, 131074, 131073, 131072, 131074, 131073, 131073, 131073, 131074, 131073, 131073, 131072, 131074, 131072, 131072, 131072, 131073, 131074, 131074, 131073, 131072, 131074, 131073, 131074, 131074, 131073, 131074, 131073, 131073, 131072, 131072, 131074, 131073, 131072, 131073, 131074, 131073, 131074, 131073, 131072, 131073, 131073, 131072, 131074, 131072, 131074, 131074, 131072, 131074, 131074, 131072, 131072, 131072, 131073, 131072, 131073, 131072, 131073, 131073, 131074, 131074, 131073, 131074, 131074, 131073, 131074, 131072, 131073, 131072, 131074, 131073, 131073, 131073, 131073, 131073, 131073, 131072, 131073, 131073, 131074, 131073, 131072, 131072, 131074, 131072, 131073, 131072, 131074, 131073, 131073, 131073, 131073, 131073, 131072, 131072, 131072, 131072, 131074, 131072, 131073, 131073, 131073, 131074, 131074, 131072, 131072, 131074, 131073, 131073, 131073, 131072, 131072, 131074, 131073, 131074, 131073, 131074, 131073, 131073, 131073, 131074, 131073, 131074, 131072, 131073, 131072, 131073, 131073, 131074, 131072, 131073, 131072, 131072, 131072, 131074, 131073, 131072, 131072, 131074, 131073, 131072, 131072, 131073, 131073, 131074, 131072, 131074, 131072, 131072, 131074, 131074, 131074 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/java/com/threerings/cast/CharSpriteViz.java b/tests/src/java/com/threerings/cast/CharSpriteViz.java new file mode 100644 index 00000000..a560ef54 --- /dev/null +++ b/tests/src/java/com/threerings/cast/CharSpriteViz.java @@ -0,0 +1,153 @@ +// +// $Id: CharSpriteViz.java 3355 2005-02-17 01:54:54Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Graphics; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.image.ImageManager; +import com.threerings.resource.ResourceManager; +import com.threerings.util.DirectionCodes; +import com.threerings.util.DirectionUtil; + +import com.threerings.cast.bundle.BundledComponentRepository; + +/** + * Displays a character sprite in all of the various orientations. + */ +public class CharSpriteViz extends JPanel + implements DirectionCodes, MouseMotionListener +{ + public CharSpriteViz ( + CharacterManager charmgr, CharacterComponent ccomp, String action) + { + // get a handle on our sprite + _sprite = charmgr.getCharacter( + new CharacterDescriptor( + new int[] { ccomp.componentId }, null)); + + // put the sprite in the appropriate action mode + _sprite.setRestingAction(action); + _sprite.setFollowingPathAction(action); + _sprite.setActionSequence(action); + + addMouseMotionListener(this); + } + + public void mouseDragged (MouseEvent event) + { + } + + public void mouseMoved (MouseEvent event) + { + int orient = DirectionUtil.getFineDirection( + getWidth()/2, getHeight()/2, event.getX(), event.getY()); + if (_orient != orient) { + System.out.println("Switching to " + + DirectionUtil.toShortString(orient) + "."); + _orient = orient; + repaint(); + } + } + + public void paintComponent (Graphics g) + { + super.paintComponent(g); + + int width = getWidth(), height = getHeight(); + int cx = width/2, cy = height/2; + g.setColor(Color.darkGray); + g.drawLine(cx, cy, 0, cy); + g.drawLine(cx, cy, 0, cy/2); + g.drawLine(cx, cy, 0, 0); + g.drawLine(cx, cy, cx/2, 0); + g.drawLine(cx, cy, cx, 0); + g.drawLine(cx, cy, 3*width/4, 0); + g.drawLine(cx, cy, width, 0); + g.drawLine(cx, cy, width, cy/2); + g.drawLine(cx, cy, width, cy); + g.drawLine(cx, cy, width, 3*height/4); + g.drawLine(cx, cy, width, height); + g.drawLine(cx, cy, 3*width/4, height); + g.drawLine(cx, cy, cx, height); + g.drawLine(cx, cy, cx/2, height); + g.drawLine(cx, cy, 0, height); + g.drawLine(cx, cy, 0, 3*height/4); + + _sprite.setLocation(cx, cy); + _sprite.setOrientation(_orient); + _sprite.paint((Graphics2D)g); + } + + public static void main (String[] args) + { + if (args.length < 3) { + System.err.println("Usage: CharSpriteViz cclass cname action"); + System.err.println(" (eg. CharSpriteViz navsail smsloop sailing"); + System.exit(-1); + } + + JFrame frame = new JFrame("CharSpriteViz"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + try { + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + ImageManager imgr = new ImageManager(rmgr, frame); + ComponentRepository crepo = + new BundledComponentRepository(rmgr, imgr, "components"); + CharacterManager charmgr = new CharacterManager(imgr, crepo); + CharacterComponent ccomp = crepo.getComponent(args[0], args[1]); + + frame.getContentPane().add( + new CharSpriteViz(charmgr, ccomp, args[2]), + BorderLayout.CENTER); + frame.setSize(200, 200); + SwingUtil.centerWindow(frame); + frame.show(); + + } catch (NoSuchComponentException nsce) { + System.err.println("No component with specified class " + + "and name [cclass=" + args[0] + + ", cname=" + args[1] + "]."); + System.exit(-1); + + } catch (Exception e) { + e.printStackTrace(System.err); + System.exit(-1); + } + } + + protected CharacterSprite _sprite; + protected int _orient = NORTH; +} diff --git a/tests/src/java/com/threerings/cast/builder/TestApp.java b/tests/src/java/com/threerings/cast/builder/TestApp.java new file mode 100644 index 00000000..bfaa5c10 --- /dev/null +++ b/tests/src/java/com/threerings/cast/builder/TestApp.java @@ -0,0 +1,76 @@ +// +// $Id: TestApp.java 3355 2005-02-17 01:54:54Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import java.io.IOException; +import javax.swing.JFrame; + +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.image.ImageManager; +import com.threerings.resource.ResourceManager; + +import com.threerings.cast.CharacterManager; +import com.threerings.cast.ComponentRepository; +import com.threerings.cast.bundle.BundledComponentRepository; + +public class TestApp +{ + public TestApp (String[] args) + throws IOException + { + _frame = new TestFrame(); + _frame.setSize(800, 600); + SwingUtil.centerWindow(_frame); + + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + ImageManager imgr = new ImageManager(rmgr, _frame); + + ComponentRepository crepo = + new BundledComponentRepository(rmgr, imgr, "components"); + CharacterManager charmgr = new CharacterManager(imgr, crepo); + + // initialize the frame + ((TestFrame)_frame).init(charmgr, crepo); + } + + public void run () + { + _frame.pack(); + _frame.show(); + } + + public static void main (String[] args) + { + try { + TestApp app = new TestApp(args); + app.run(); + } catch (IOException ioe) { + System.err.println("Error initializing app."); + ioe.printStackTrace(); + } + } + + protected JFrame _frame; +} diff --git a/tests/src/java/com/threerings/cast/builder/TestFrame.java b/tests/src/java/com/threerings/cast/builder/TestFrame.java new file mode 100644 index 00000000..734eafa4 --- /dev/null +++ b/tests/src/java/com/threerings/cast/builder/TestFrame.java @@ -0,0 +1,43 @@ +// +// $Id: TestFrame.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.builder; + +import javax.swing.JFrame; + +import com.threerings.cast.CharacterManager; +import com.threerings.cast.ComponentRepository; + +public class TestFrame extends JFrame +{ + public TestFrame () + { + super("Character Builder"); + + setResizable(false); + setDefaultCloseOperation(EXIT_ON_CLOSE); + } + + public void init (CharacterManager charmgr, ComponentRepository crepo) + { + getContentPane().add(new BuilderPanel(charmgr, crepo, "male/")); + } +} diff --git a/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java b/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java new file mode 100644 index 00000000..599f9244 --- /dev/null +++ b/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java @@ -0,0 +1,85 @@ +// +// $Id: BundledComponentRepositoryTest.java 3720 2005-10-05 01:39:45Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.cast.bundle; + +import java.awt.Component; +import java.util.Iterator; + +import com.threerings.cast.ComponentClass; +import com.threerings.media.image.ImageManager; +import com.threerings.resource.ResourceManager; + +import junit.framework.Test; +import junit.framework.TestCase; + +public class BundledComponentRepositoryTest extends TestCase +{ + public BundledComponentRepositoryTest () + { + super(BundledComponentRepositoryTest.class.getName()); + } + + public void runTest () + { + try { + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + ImageManager imgr = new ImageManager(rmgr, (Component)null); + BundledComponentRepository repo = + new BundledComponentRepository(rmgr, imgr, "components"); + +// System.out.println("Classes: " + StringUtil.toString( +// repo.enumerateComponentClasses())); + +// System.out.println("Actions: " + StringUtil.toString( +// repo.enumerateActionSequences())); + +// System.out.println("Action sets: " + StringUtil.toString( +// repo._actionSets.values().iterator())); + + Iterator iter = repo.enumerateComponentClasses(); + while (iter.hasNext()) { + ComponentClass cclass = (ComponentClass)iter.next(); +// System.out.println("IDs [" + cclass + "]: " + +// StringUtil.toString( +// repo.enumerateComponentIds(cclass))); + } + + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } + + public static void main (String[] args) + { + BundledComponentRepositoryTest test = + new BundledComponentRepositoryTest(); + test.runTest(); + } + + public static Test suite () + { + return new BundledComponentRepositoryTest(); + } +} diff --git a/tests/src/java/com/threerings/geom/NearestViz.java b/tests/src/java/com/threerings/geom/NearestViz.java new file mode 100644 index 00000000..51c58c8b --- /dev/null +++ b/tests/src/java/com/threerings/geom/NearestViz.java @@ -0,0 +1,101 @@ +// +// $Id: NearestViz.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.geom; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Point; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.samskivert.swing.util.SwingUtil; + +/** + * Renders the nearest point on a line just for kicks. + */ +public class NearestViz extends JPanel + implements MouseMotionListener +{ + public NearestViz () + { + addMouseMotionListener(this); + } + + public void doLayout () + { + super.doLayout(); + _center = new Point(getWidth() / 2, getHeight() / 2); + } + + public void paintComponent (Graphics g) + { + super.paintComponent(g); + + int dx = (int)Math.round(Math.cos(_theta) * 200); + int dy = (int)Math.round(Math.sin(_theta) * 200); + + g.setColor(Color.blue); + g.drawLine(_center.x, _center.y, _center.x + dx, _center.y - dy); + g.drawLine(_center.x, _center.y, _center.x - dx, _center.y + dy); + + // locate the point nearest the spot + Point p2 = new Point(_center.x + dx, _center.y - dy); + Point n = new Point(); + GeomUtil.nearestToLine(_center, p2, _spot, n); + + g.setColor(Color.red); + g.drawOval(n.x - 4, n.y - 4, 8, 8); + + // kick theta along for the next tick because it's fun + _theta += (float)(Math.PI/100); + } + + public void mouseDragged (MouseEvent event) + { + } + + public void mouseMoved (MouseEvent event) + { + _spot.x = event.getX(); + _spot.y = event.getY(); + repaint(); + } + + public static void main (String[] args) + { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(new NearestViz(), BorderLayout.CENTER); + frame.setSize(300, 300); + SwingUtil.centerWindow(frame); + frame.show(); + } + + protected float _theta = (float)(3 * Math.PI / 5); + protected Point _center; + protected Point _spot = new Point(); +} diff --git a/tests/src/java/com/threerings/geom/WhichSideViz.java b/tests/src/java/com/threerings/geom/WhichSideViz.java new file mode 100644 index 00000000..6914b9e8 --- /dev/null +++ b/tests/src/java/com/threerings/geom/WhichSideViz.java @@ -0,0 +1,113 @@ +// +// $Id: WhichSideViz.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.geom; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Point; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.samskivert.swing.util.SwingUtil; + +/** + * Renders the nearest point on a line just for kicks. + */ +public class WhichSideViz extends JPanel + implements MouseMotionListener +{ + public WhichSideViz () + { + addMouseMotionListener(this); + } + + public void doLayout () + { + super.doLayout(); + _center = new Point(getWidth() / 2, getHeight() / 2); + } + + public void paintComponent (Graphics g) + { + super.paintComponent(g); + + int dx = (int)Math.round(Math.cos(_theta) * 200); + int dy = (int)Math.round(Math.sin(_theta) * 200); + + g.setColor(Color.blue); + g.drawLine(_center.x, _center.y, _center.x + dx, _center.y + dy); + g.setColor(Color.white); + g.drawLine(_center.x, _center.y, _center.x - dx, _center.y - dy); + + int nx = _center.x + (int)Math.round(1000*Math.cos(_theta + Math.PI/2)), + ny = _center.y + (int)Math.round(1000*Math.sin(_theta + Math.PI/2)); + g.setColor(Color.pink); + g.drawLine(_center.x, _center.y, nx, ny); + + // figure out which side the line is on + String str; + int side = GeomUtil.whichSide(_center, _theta, _spot); + if (side > 0) { + str = "R"; + } else if (side < 0) { + str = "L"; + } else { + str = "O"; + } + + g.setColor(Color.black); + g.drawString(str, _spot.x, _spot.y); + + // kick theta along for the next tick because it's fun + _theta += (float)(Math.PI/100); + } + + public void mouseDragged (MouseEvent event) + { + } + + public void mouseMoved (MouseEvent event) + { + _spot.x = event.getX(); + _spot.y = event.getY(); + repaint(); + } + + public static void main (String[] args) + { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(new WhichSideViz(), BorderLayout.CENTER); + frame.setSize(300, 300); + SwingUtil.centerWindow(frame); + frame.show(); + } + + protected float _theta = (float)(3 * Math.PI / 5); + protected Point _center; + protected Point _spot = new Point(); +} diff --git a/tests/src/java/com/threerings/jme/JmeCanvasTest.java b/tests/src/java/com/threerings/jme/JmeCanvasTest.java new file mode 100644 index 00000000..089778dd --- /dev/null +++ b/tests/src/java/com/threerings/jme/JmeCanvasTest.java @@ -0,0 +1,62 @@ +// +// $Id$ + +package com.threerings.jme; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JFrame; + +import com.jme.bounding.BoundingBox; +import com.jme.math.Vector3f; +import com.jme.scene.shape.Box; + +/** + * Tests the JME/AWT integration bits. + */ +public class JmeCanvasTest extends JmeCanvasApp +{ + public static void main (String[] args) + { + final JmeCanvasTest app = new JmeCanvasTest(); + JFrame frame = new JFrame("JmeCanvasTest"); + frame.getContentPane().add(app.getCanvas(), BorderLayout.CENTER); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(800, 600); + frame.setVisible(true); + + JButton button = new JButton("Create box"); + frame.getContentPane().add(button, BorderLayout.SOUTH); + button.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent event) { + app.addBox(); + } + }); + app.run(); + } + + public void addBox () + { + Vector3f max = new Vector3f(5, 5, 5); + Vector3f min = new Vector3f(-5, -5, -5); + + Box box = new Box("Box", min, max); + box.setModelBound(new BoundingBox()); + box.updateModelBound(); + box.setLocalTranslation(new Vector3f(0, 0, -10)); + _geom.attachChild(box); + _geom.updateRenderState(); + } + + protected JmeCanvasTest () + { + super(800, 600); + } + + protected void initRoot () + { + super.initRoot(); + } +} diff --git a/tests/src/java/com/threerings/jme/client/JabberApp.java b/tests/src/java/com/threerings/jme/client/JabberApp.java new file mode 100644 index 00000000..523ea4db --- /dev/null +++ b/tests/src/java/com/threerings/jme/client/JabberApp.java @@ -0,0 +1,160 @@ +// +// $Id: JabberApp.java 3098 2004-08-27 02:12:55Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.client; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import com.jme.bounding.BoundingBox; +import com.jme.math.FastMath; +import com.jme.math.Matrix3f; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.scene.shape.Box; +import com.jme.util.LoggingSystem; +import com.jme.util.geom.BufferUtils; +import com.jmex.bui.BStyleSheet; + +import com.threerings.util.Name; + +import com.threerings.presents.client.Client; +import com.threerings.presents.net.UsernamePasswordCreds; + +import com.threerings.jme.Log; +import com.threerings.jme.JmeApp; + +/** + * The main point of entry for the Jabber client application. It creates + * and initializes the myriad components of the client and sets all the + * proper wheels in motion. + */ +public class JabberApp extends JmeApp +{ + /** Used to configure our user interface. */ + public static BStyleSheet stylesheet; + + // documentation inherited + public boolean init () + { + if (!super.init()) { + return false; + } + + // initialize our client instance + _client = new JabberClient(); + _client.init(this); + + // add some simple geometry for kicks + Vector3f max = new Vector3f(15, 15, 15); + Vector3f min = new Vector3f(5, 5, 5); + + Box t = new Box("Box", min, max); + t.setModelBound(new BoundingBox()); + t.updateModelBound(); + t.setLocalTranslation(new Vector3f(0, 0, -15)); + ColorRGBA[] colors = new ColorRGBA[24]; + for (int i = 0; i < 24; i++) { + colors[i] = ColorRGBA.randomColor(); + } + t.setColorBuffer(0, BufferUtils.createFloatBuffer(colors)); + _root.attachChild(t); + _root.updateRenderState(); + + // set up the camera + Vector3f loc = new Vector3f(0, -200, 200); + _camera.setLocation(loc); + Matrix3f rotm = new Matrix3f(); + rotm.fromAngleAxis(-FastMath.PI/5, _camera.getLeft()); + rotm.mult(_camera.getDirection(), _camera.getDirection()); + rotm.mult(_camera.getUp(), _camera.getUp()); + rotm.mult(_camera.getLeft(), _camera.getLeft()); + _camera.update(); + + // speed up key input + _input.setActionSpeed(100f); + + return true; + } + + public void run (String server, String username, String password) + { + Client client = _client.getContext().getClient(); + + // pass them on to the client + Log.info("Using [server=" + server + "."); + client.setServer(server, Client.DEFAULT_SERVER_PORTS); + + // configure the client with some credentials and logon + if (username != null && password != null) { + // create and set our credentials + client.setCredentials( + new UsernamePasswordCreds(new Name(username), password)); + client.logon(); + } + + // now start up the main event loop + run(); + } + + // documentation inherited + public void stop () + { + // log off before we shutdown + Client client = _client.getContext().getClient(); + if (client.isLoggedOn()) { + client.logoff(false); + } + Log.info("Stopping."); + super.stop(); + } + + public static void main (String[] args) + { + LoggingSystem.getLogger().setLevel(java.util.logging.Level.OFF); + + String server = "localhost"; + if (args.length > 0) { + server = args[0]; + } + + // load up the default BUI stylesheet + try { + InputStream stin = JabberApp.class.getClassLoader(). + getResourceAsStream("rsrc/style.bss"); + stylesheet = new BStyleSheet( + new InputStreamReader(stin), + new BStyleSheet.DefaultResourceProvider()); + } catch (Exception e) { + e.printStackTrace(System.err); + System.exit(-1); + } + + String username = (args.length > 1) ? args[1] : null; + String password = (args.length > 2) ? args[2] : null; + + JabberApp app = new JabberApp(); + app.init(); + app.run(server, username, password); + } + + protected JabberClient _client; +} diff --git a/tests/src/java/com/threerings/jme/client/JabberClient.java b/tests/src/java/com/threerings/jme/client/JabberClient.java new file mode 100644 index 00000000..2fc854f9 --- /dev/null +++ b/tests/src/java/com/threerings/jme/client/JabberClient.java @@ -0,0 +1,228 @@ +// +// $Id: JabberClient.java 3283 2004-12-22 19:23:00Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.client; + +import com.jmex.bui.BRootNode; +import com.jme.input.InputHandler; +import com.jme.renderer.Renderer; +import com.jme.scene.Node; +import com.jme.system.DisplaySystem; + +import com.samskivert.util.Config; +import com.threerings.util.MessageManager; + +import com.threerings.presents.client.Client; +import com.threerings.presents.client.SessionObserver; +import com.threerings.presents.dobj.DObjectManager; + +import com.threerings.crowd.chat.client.ChatDirector; +import com.threerings.crowd.client.LocationDirector; +import com.threerings.crowd.client.OccupantDirector; +import com.threerings.crowd.client.PlaceView; +import com.threerings.crowd.util.CrowdContext; + +import com.threerings.jme.JmeContext; +import com.threerings.jme.camera.CameraHandler; + +/** + * The Jabber client takes care of instantiating all of the proper + * managers and loading up all of the necessary configuration and getting + * the client bootstrapped. It can be extended by games that require an + * extended context implementation. + */ +public class JabberClient + implements SessionObserver +{ + /** + * Initializes a new client and provides it with a frame in which to + * display everything. + */ + public void init (JabberApp app) + { + _app = app; + + // create our context + _ctx = createContextImpl(); + + // create the directors/managers/etc. provided by the context + createContextServices(app); + + // for test purposes, hardcode the server info + _client.setServer("localhost", Client.DEFAULT_SERVER_PORTS); + _client.addClientObserver(this); + } + + /** + * Returns a reference to the context in effect for this client. This + * reference is valid for the lifetime of the application. + */ + public CrowdContext getContext () + { + return _ctx; + } + + // documentation inherited from interface SessionObserver + public void clientDidLogon (Client client) + { + // enter the one and only chat room; giant hack warning: we know + // that the place we're headed to is ID 2 because there's only one + // place on the whole server; a normal client would either issue + // an invocation service request at this point or look at + // something in the BootstrapData to figure out what to do + _ctx.getLocationDirector().moveTo(2); + } + + // documentation inherited from interface SessionObserver + public void clientObjectDidChange (Client client) + { + // nada + } + + // documentation inherited from interface SessionObserver + public void clientDidLogoff (Client client) + { + System.exit(0); + } + + /** + * Creates the {@link JabberContext} implementation that will be + * passed around to all of the client code. Derived classes may wish + * to override this and create some extended context implementation. + */ + protected CrowdContext createContextImpl () + { + return new JabberContextImpl(); + } + + /** + * Creates and initializes the various services that are provided by + * the context. Derived classes that provide an extended context + * should override this method and create their own extended + * services. They should be sure to call + * super.createContextServices. + */ + protected void createContextServices (JabberApp app) + { + // create the handles on our various services + _client = new Client(null, app); + + // create our managers and directors + _locdir = new LocationDirector(_ctx); + _occdir = new OccupantDirector(_ctx); + _msgmgr = new MessageManager(MESSAGE_MANAGER_PREFIX); + _chatdir = new ChatDirector(_ctx, _msgmgr, null); + } + + /** + * The context implementation. This provides access to all of the + * objects and services that are needed by the operating client. + */ + protected class JabberContextImpl implements CrowdContext, JmeContext + { + /** + * Apparently the default constructor has default access, rather + * than protected access, even though this class is declared to be + * protected. Why, I don't know, but we need to be able to extend + * this class elsewhere, so we need this. + */ + protected JabberContextImpl () { + } + + public Client getClient () { + return _client; + } + + public DObjectManager getDObjectManager () { + return _client.getDObjectManager(); + } + + public Config getConfig () { + return _config; + } + + public LocationDirector getLocationDirector () { + return _locdir; + } + + public OccupantDirector getOccupantDirector () { + return _occdir; + } + + public ChatDirector getChatDirector () { + return _chatdir; + } + + public void setPlaceView (PlaceView view) { + // TBD + } + + public void clearPlaceView (PlaceView view) { + // we'll just let the next place view replace our old one + } + + public Renderer getRenderer () { + return _app.getContext().getRenderer(); + } + + public DisplaySystem getDisplay () { + return _app.getContext().getDisplay(); + } + + public CameraHandler getCameraHandler () { + return _app.getContext().getCameraHandler(); + } + + public Node getGeometry () { + return _app.getContext().getGeometry(); + } + + public Node getInterface () { + return _app.getContext().getInterface(); + } + + public InputHandler getInputHandler () { + return _app.getContext().getInputHandler(); + } + +// public InputHandler getBufferedInputHandler () { +// return _app.getContext().getBufferedInputHandler(); +// } + + public BRootNode getRootNode () { + return _app.getContext().getRootNode(); + } + } + + protected CrowdContext _ctx; + protected JabberApp _app; + protected Config _config = new Config("jabber"); + + protected Client _client; + protected LocationDirector _locdir; + protected OccupantDirector _occdir; + protected ChatDirector _chatdir; + protected MessageManager _msgmgr; + + /** The prefix prepended to localization bundle names before looking + * them up in the classpath. */ + protected static final String MESSAGE_MANAGER_PREFIX = "rsrc.i18n"; +} diff --git a/tests/src/java/com/threerings/jme/client/JabberController.java b/tests/src/java/com/threerings/jme/client/JabberController.java new file mode 100644 index 00000000..329381b6 --- /dev/null +++ b/tests/src/java/com/threerings/jme/client/JabberController.java @@ -0,0 +1,19 @@ +// +// $Id$ + +package com.threerings.jme.client; + +import com.threerings.crowd.client.PlaceController; +import com.threerings.crowd.client.PlaceView; +import com.threerings.crowd.util.CrowdContext; + +/** + * Handles the basic bits for our simple chat room. + */ +public class JabberController extends PlaceController +{ + protected PlaceView createPlaceView (CrowdContext ctx) + { + return new JabberView(ctx); + } +} diff --git a/tests/src/java/com/threerings/jme/client/JabberView.java b/tests/src/java/com/threerings/jme/client/JabberView.java new file mode 100644 index 00000000..c0c810fd --- /dev/null +++ b/tests/src/java/com/threerings/jme/client/JabberView.java @@ -0,0 +1,51 @@ +// +// $Id$ + +package com.threerings.jme.client; + +import com.jmex.bui.BLabel; +import com.jmex.bui.BWindow; +import com.jmex.bui.layout.BorderLayout; + +import com.threerings.crowd.client.PlaceView; +import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.util.CrowdContext; + +import com.threerings.jme.JmeContext; +import com.threerings.jme.chat.ChatView; + +/** + * Manages the "view" when we're in the chat room. + */ +public class JabberView extends BWindow + implements PlaceView +{ + public JabberView (CrowdContext ctx) + { + super(JabberApp.stylesheet, new BorderLayout()); + + _ctx = ctx; + _jctx = (JmeContext)ctx; + _chat = new ChatView(_jctx, _ctx.getChatDirector()); + add(_chat, BorderLayout.CENTER); + + _jctx.getRootNode().addWindow(this); + setBounds(0, 40, 640, 240); + } + + // documentation inherited from interface PlaceView + public void willEnterPlace (PlaceObject plobj) + { + _chat.willEnterPlace(plobj); + } + + // documentation inherited from interface PlaceView + public void didLeavePlace (PlaceObject plobj) + { + _chat.didLeavePlace(plobj); + } + + protected CrowdContext _ctx; + protected JmeContext _jctx; + protected ChatView _chat; +} diff --git a/tests/src/java/com/threerings/jme/data/JabberConfig.java b/tests/src/java/com/threerings/jme/data/JabberConfig.java new file mode 100644 index 00000000..4f640013 --- /dev/null +++ b/tests/src/java/com/threerings/jme/data/JabberConfig.java @@ -0,0 +1,26 @@ +// +// $Id$ + +package com.threerings.jme.data; + +import com.threerings.crowd.data.PlaceConfig; +import com.threerings.jme.client.JabberController; + +/** + * Defines the necessary bits for our chat room. + */ +public class JabberConfig extends PlaceConfig +{ + // documentation inherited + public Class getControllerClass () + { + return JabberController.class; + } + + // documentation inherited + public String getManagerClassName () + { + // nothing special needed on the server side + return "com.threerings.crowd.server.PlaceManager"; + } +} diff --git a/tests/src/java/com/threerings/jme/server/JabberServer.java b/tests/src/java/com/threerings/jme/server/JabberServer.java new file mode 100644 index 00000000..8ff43870 --- /dev/null +++ b/tests/src/java/com/threerings/jme/server/JabberServer.java @@ -0,0 +1,49 @@ +// +// $Id$ + +package com.threerings.jme.server; + +import com.threerings.crowd.Log; +import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.server.CrowdServer; +import com.threerings.crowd.server.PlaceManager; +import com.threerings.crowd.server.PlaceRegistry; + +import com.threerings.jme.data.JabberConfig; + +/** + * A basic server that creates a single room and sticks everyone in it + * where they can chat with one another. + */ +public class JabberServer extends CrowdServer +{ + // documentation inherited + public void init () + throws Exception + { + super.init(); + + // create a single location + plreg.createPlace( + new JabberConfig(), new PlaceRegistry.CreationObserver() { + public void placeCreated (PlaceObject place, PlaceManager pmgr) { + Log.info("Created chat room " + pmgr.where() + "."); + _place = pmgr; + } + }); + } + + public static void main (String[] args) + { + JabberServer server = new JabberServer(); + try { + server.init(); + server.run(); + } catch (Exception e) { + Log.warning("Unable to initialize server."); + Log.logStackTrace(e); + } + } + + protected PlaceManager _place; +} diff --git a/tests/src/java/com/threerings/jme/sprite/PathTest.java b/tests/src/java/com/threerings/jme/sprite/PathTest.java new file mode 100644 index 00000000..ee6d0273 --- /dev/null +++ b/tests/src/java/com/threerings/jme/sprite/PathTest.java @@ -0,0 +1,150 @@ +// +// $Id$ + +package com.threerings.jme.sprite; + +import java.util.Arrays; +import java.util.logging.Level; + +import com.jme.math.FastMath; +import com.jme.math.Matrix3f; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.scene.shape.Box; +import com.jme.scene.shape.Disk; +import com.jme.scene.shape.Quad; +import com.jme.scene.shape.Sphere; +import com.jme.scene.state.LightState; +import com.jme.util.LoggingSystem; + +import com.threerings.jme.JmeApp; +import com.threerings.jme.sprite.LineSegmentPath; + +/** + * Used for testing paths. + */ +public class PathTest extends JmeApp +{ + protected void initRoot () + { + super.initRoot(); + + float dist = 10; + + // set up the camera + Vector3f loc = new Vector3f(0, -dist, 10); + _camera.setLocation(loc); + Matrix3f rotm = new Matrix3f(); + rotm.fromAngleAxis(-FastMath.PI/4, _camera.getLeft()); + rotm.multLocal(_camera.getDirection()); + rotm.multLocal(_camera.getUp()); + rotm.multLocal(_camera.getLeft()); + _camera.update(); + + for (int yy = -1; yy < 1; yy++) { + for (int xx = -1; xx < 1; xx++) { + Quad quad = new Quad("ground", 10, 10); + quad.setLightCombineMode(LightState.OFF); + int index = (yy+1)*2 + (xx+1); + quad.setSolidColor(COLORS[index]); + quad.setLocalTranslation( + new Vector3f(xx * 10 + 5, yy * 10 + 5, -1)); + _geom.attachChild(quad); + } + } + + for (int yy = -1; yy <= 1; yy++) { + for (int xx = -1; xx <= 1; xx++) { + if (xx != 0 || yy != 0) { + setup(xx * dist, yy * dist); + } + } + } + } + + protected void setup (float x, float y) + { + Box target = new Box("target", new Vector3f(-.1f, -.1f, -.1f), + new Vector3f(.1f, .1f, .1f)); + target.setLocalTranslation(new Vector3f(x, y, 0)); + _geom.attachChild(target); + + Box box = new Box("box", new Vector3f(-1, -0.5f, -0.25f), + new Vector3f(1, 0.5f, 0.25f)); + Disk disk = new Disk("dot", 10, 10, 0.5f); + disk.setLightCombineMode(LightState.OFF); + disk.setLocalTranslation(new Vector3f(0.5f, 0f, 0.3f)); + Sprite shot = new Sprite(); + shot.attachChild(box); + shot.attachChild(disk); + _geom.attachChild(shot); + + testBallistic(shot, target); +// testLineSegment(shot); + } + + protected void testBallistic (Sprite shot, Box target) + { + // start with the "cannon" pointed along the x axis + Vector3f diff = target.getLocalTranslation().subtract( + shot.getLocalTranslation()); + Vector3f vel = diff.normalize(); + float range = diff.length(), angle = -FastMath.PI/4; + + Vector3f axis = UP.cross(vel); + axis.normalizeLocal(); + + // rotate it up (around the y axis) the necessary elevation + Quaternion rot = new Quaternion(); + rot.fromAngleAxis(angle, axis); + rot.multLocal(vel); + + // give the cannon its muzzle velocity + float muzvel = FastMath.sqrt(range * BallisticPath.G / + FastMath.sin(2*angle)); + vel.multLocal(muzvel); + + Vector3f start = new Vector3f(0, 0, 0); + float time = BallisticPath.computeFlightTime(range, muzvel, angle); + shot.move(new OrientingBallisticPath( + shot, new Vector3f(1, 0, 0), start, vel, GRAVITY, time)); + + System.out.println("Range: " + range); + System.out.println("Muzzle velocity: " + muzvel); + System.out.println("Rotation axis: " + axis); + System.out.println("Angle: " + angle + " (" + + (angle * 180 / FastMath.PI) + ")"); + System.out.println("Flight time: " + time); + System.out.println("Velocity: " + vel); + } + + protected void testLineSegment (Sprite shot) + { + Vector3f[] points = new Vector3f[] { + new Vector3f(0, 0, 0), new Vector3f(2, 0, 0), new Vector3f(3, 0, 0), + new Vector3f(3, 2, 0), new Vector3f(5, 2, 0), new Vector3f(5, -2, 0), + new Vector3f(-4, -2, 0) + }; + float[] durations = new float[points.length]; + Arrays.fill(durations, 1f); + Vector3f up = new Vector3f(0, 0, 1); + Vector3f orient = new Vector3f(1, 0, 0); + shot.move(new LineSegmentPath(shot, up, orient, points, durations)); + } + + public static void main (String[] args) + { + LoggingSystem.getLogger().setLevel(Level.OFF); + PathTest test = new PathTest(); + if (!test.init()) { + System.exit(-1); + } + test.run(); + } + + protected static final Vector3f GRAVITY = new Vector3f(0, 0, -9.8f); + protected static final Vector3f UP = new Vector3f(0, 0, 1); + protected static final ColorRGBA[] COLORS = { + ColorRGBA.red, ColorRGBA.green, ColorRGBA.blue, ColorRGBA.gray }; +} diff --git a/tests/src/java/com/threerings/media/ImageLoadingSpeed.java b/tests/src/java/com/threerings/media/ImageLoadingSpeed.java new file mode 100644 index 00000000..749475de --- /dev/null +++ b/tests/src/java/com/threerings/media/ImageLoadingSpeed.java @@ -0,0 +1,80 @@ +// +// $Id: ImageLoadingSpeed.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +import java.io.*; + +import com.threerings.media.image.FastImageIO; + +/** + * Tests our image loading speed. + */ +public class ImageLoadingSpeed +{ + public static void main (String[] args) + { + if (args.length < 1) { + System.err.println("Usage: ImageLoadingTest image"); + System.exit(-1); + } + + File file = new File(args[0]); + File ffile = new File(args[0] + FastImageIO.FILE_SUFFIX); + try { + BufferedImage image = ImageIO.read(file); + FastImageIO.write(image, new FileOutputStream(ffile)); + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + System.exit(-1); + } + + long start = System.currentTimeMillis(); + int iter = 0; + while (true) { + try { + FastImageIO.read(ffile).getWidth(); + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + System.exit(-1); + } + + if (++iter == 100) { + long now = System.currentTimeMillis(); + long elapsed = now - start; + System.err.println("Loaded " + args.length + + " images a total of " + iter + + " times in " + elapsed + "ms."); + System.err.println("An average of " + (elapsed/iter) + + "ms per image."); + + System.gc(); + try { Thread.sleep(1000); } catch (Throwable t) {} + + start = now; + iter = 0; + } + } + } +} diff --git a/tests/src/java/com/threerings/media/TestIconManager.java b/tests/src/java/com/threerings/media/TestIconManager.java new file mode 100644 index 00000000..3aa73bce --- /dev/null +++ b/tests/src/java/com/threerings/media/TestIconManager.java @@ -0,0 +1,65 @@ +// +// $Id: TestIconManager.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media; + +import java.awt.BorderLayout; +import javax.swing.*; + +import com.samskivert.swing.HGroupLayout; +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.image.ImageManager; +import com.threerings.media.tile.TileManager; +import com.threerings.resource.ResourceManager; + +/** + * Does something extraordinary. + */ +public class TestIconManager +{ + public static void main (String[] args) + { + try { + JFrame frame = new JFrame("TestIconManager"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + ResourceManager rmgr = new ResourceManager("rsrc"); + ImageManager imgr = new ImageManager(rmgr, frame); + TileManager tmgr = new TileManager(imgr); + IconManager iconmgr = new IconManager( + tmgr, "rsrc/config/media/iconmgr.properties"); + + JPanel panel = new JPanel(new HGroupLayout()); + for (int i = 0; i < 8; i++) { + panel.add(new JButton(iconmgr.getIcon("test", i))); + } + + frame.getContentPane().add(panel, BorderLayout.CENTER); + frame.pack(); + SwingUtil.centerWindow(frame); + frame.show(); + + } catch (Exception e) { + e.printStackTrace(System.err); + } + } +} diff --git a/tests/src/java/com/threerings/media/sound/SoundTestApp.java b/tests/src/java/com/threerings/media/sound/SoundTestApp.java new file mode 100644 index 00000000..e6f2ed61 --- /dev/null +++ b/tests/src/java/com/threerings/media/sound/SoundTestApp.java @@ -0,0 +1,68 @@ +// +// $Id: SoundTestApp.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.sound; + +import com.threerings.resource.ResourceManager; +import com.threerings.media.Log; + +public class SoundTestApp +{ + public SoundTestApp (String[] args) + { + if (args.length == 0) { + Log.info("Usage: runjava com.threerings.media.SoundTestApp " + + " [ ...]"); + System.exit(0); + } + + ResourceManager rmgr = new ResourceManager("rsrc"); + _soundmgr = new SoundManager(rmgr, null, null); + _keys = args; + } + + public void run () + { + for (int ii = 0; ii < _keys.length; ii++) { + System.out.println("Playing " + _keys[ii] + "."); + _soundmgr.play(SoundManager.DEFAULT, + "com/threerings/media/sound/", _keys[ii]); + } + _soundmgr.shutdown(); + + // the sound manager starts up threads that never seem to exit so + // we have to stick a fork in things after a short while + try { + Thread.sleep(5000L); + } catch (InterruptedException ie) { + } + System.exit(0); + } + + public static void main (String[] args) + { + SoundTestApp app = new SoundTestApp(args); + app.run(); + } + + protected String[] _keys; + protected SoundManager _soundmgr; +} diff --git a/tests/src/java/com/threerings/media/sound/sounds.properties b/tests/src/java/com/threerings/media/sound/sounds.properties new file mode 100644 index 00000000..e2952dc1 --- /dev/null +++ b/tests/src/java/com/threerings/media/sound/sounds.properties @@ -0,0 +1,7 @@ +# +# $Id: sounds.properties 2051 2002-12-10 21:36:53Z mdb $ +# +# Sound test app configuration file + +sound1 = media/test.wav +sound2 = foo/bar.wav diff --git a/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java b/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java new file mode 100644 index 00000000..1e73fad8 --- /dev/null +++ b/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java @@ -0,0 +1,70 @@ +// +// $Id: BundledTileSetRepositoryTest.java 3720 2005-10-05 01:39:45Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle; + +import java.awt.Component; +import java.util.Iterator; + +import com.threerings.media.image.ImageManager; +import com.threerings.resource.ResourceManager; + +import junit.framework.Test; +import junit.framework.TestCase; + +public class BundledTileSetRepositoryTest extends TestCase +{ + public BundledTileSetRepositoryTest () + { + super(BundledTileSetRepositoryTest.class.getName()); + } + + public void runTest () + { + try { + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + BundledTileSetRepository repo = new BundledTileSetRepository( + rmgr, new ImageManager(rmgr, (Component)null), "tilesets"); + Iterator sets = repo.enumerateTileSets(); + while (sets.hasNext()) { + sets.next(); +// System.out.println(sets.next()); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Test suite () + { + return new BundledTileSetRepositoryTest(); + } + + public static void main (String[] args) + { + BundledTileSetRepositoryTest test = + new BundledTileSetRepositoryTest(); + test.runTest(); + } +} diff --git a/tests/src/java/com/threerings/media/tile/bundle/tools/BuildTestTileSetBundle.java b/tests/src/java/com/threerings/media/tile/bundle/tools/BuildTestTileSetBundle.java new file mode 100644 index 00000000..da1f285a --- /dev/null +++ b/tests/src/java/com/threerings/media/tile/bundle/tools/BuildTestTileSetBundle.java @@ -0,0 +1,94 @@ +// +// $Id: BuildTestTileSetBundle.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.bundle.tools; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import com.samskivert.io.PersistenceException; +import com.samskivert.test.TestUtil; + +import com.threerings.media.tile.TileSetIDBroker; + +public class BuildTestTileSetBundle +{ + public static void main (String[] args) + { + try { + TileSetIDBroker broker = new DummyTileSetIDBroker(); + + // sort out some paths + String configPath = TestUtil.getResourcePath(CONFIG_PATH); + String descPath = TestUtil.getResourcePath(BUNDLE_DESC_PATH); + String targetPath = TestUtil.getResourcePath(TARGET_PATH); + + // create our bundler and get going + TileSetBundler bundler = new TileSetBundler(configPath); + File descFile = new File(descPath); + bundler.createBundle(broker, descFile, targetPath); + + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + /** Dummy tileset id broker that makes up tileset ids (which are + * consistent in the course of execution of the application, but not + * between invocations). */ + protected static class DummyTileSetIDBroker + extends HashMap + implements TileSetIDBroker + { + public int getTileSetID (String tileSetName) + throws PersistenceException + { + Integer id = (Integer)get(tileSetName); + if (id == null) { + id = new Integer(++_nextId); + put(tileSetName, id); + } + return id.intValue(); + } + + public boolean tileSetMapped (String tileSetName) + { + return containsKey(tileSetName); + } + + public void commit () + throws PersistenceException + { + } + + protected int _nextId; + } + + protected static final String CONFIG_PATH = + "rsrc/media/tile/bundle/tools/bundler-config.xml"; + + protected static final String BUNDLE_DESC_PATH = + "rsrc/media/tile/bundle/tools/bundle.xml"; + + protected static final String TARGET_PATH = + "rsrc/media/tile/bundle/tools/bundle.jar"; +} diff --git a/tests/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParserTest.java b/tests/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParserTest.java new file mode 100644 index 00000000..d36bc3bf --- /dev/null +++ b/tests/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParserTest.java @@ -0,0 +1,78 @@ +// +// $Id: XMLTileSetParserTest.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.tile.tools.xml; + +import java.io.IOException; +import java.util.Iterator; +import java.util.HashMap; + +import junit.framework.Test; +import junit.framework.TestCase; + +public class XMLTileSetParserTest extends TestCase +{ + public XMLTileSetParserTest () + { + super(XMLTileSetParserTest.class.getName()); + } + + public void runTest () + { + HashMap sets = new HashMap(); + + XMLTileSetParser parser = new XMLTileSetParser(); + // add some rulesets + parser.addRuleSet("tilesets/uniform", new UniformTileSetRuleSet()); + parser.addRuleSet("tilesets/swissarmy", new SwissArmyTileSetRuleSet()); + parser.addRuleSet("tilesets/object", new ObjectTileSetRuleSet()); + + // load up the tilesets + try { + parser.loadTileSets(TILESET_PATH, sets); + + // print them out + Iterator iter = sets.values().iterator(); + while (iter.hasNext()) { + iter.next(); + // System.out.println(iter.next()); + } + + } catch (IOException ioe) { + ioe.printStackTrace(); + fail("loadTileSets() failed"); + } + } + + public static Test suite () + { + return new XMLTileSetParserTest(); + } + + public static void main (String[] args) + { + XMLTileSetParserTest test = new XMLTileSetParserTest(); + test.runTest(); + } + + protected static final String TILESET_PATH = + "rsrc/media/tile/tools/xml/tilesets.xml"; +} diff --git a/tests/src/java/com/threerings/media/util/PathViz.java b/tests/src/java/com/threerings/media/util/PathViz.java new file mode 100644 index 00000000..9575c991 --- /dev/null +++ b/tests/src/java/com/threerings/media/util/PathViz.java @@ -0,0 +1,111 @@ +// +// $Id: PathViz.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import javax.swing.JFrame; + +import com.threerings.media.FrameManager; +import com.threerings.media.ManagedJFrame; +import com.threerings.media.MediaPanel; + +import com.threerings.media.sprite.Sprite; + +/** + * A test app that is useful for visualizing paths during their + * development. + */ +public class PathViz extends MediaPanel +{ + public PathViz (FrameManager fmgr) + { + super(fmgr); + + // create a sprite that we can send along a path + Sprite sprite = new HappySprite(); + addSprite(sprite); + + // create a path for our sprite + Point start = new Point(150, 150); + double sangle = -3*Math.PI/4; + ArcPath path = new ArcPath( + start, 64, 48, sangle, -Math.PI/2, MOVE_DURATION, ArcPath.NORMAL); +// LinePath path = new LinePath(0, 0, 300, 300, MOVE_DURATION); + sprite.move(path); + } + + // documentation inherited from interface + public void paintBetween (Graphics2D gfx, Rectangle dirtyRect) + { + super.paintBetween(gfx, dirtyRect); + gfx.setColor(Color.gray); + gfx.fill(dirtyRect); + _spritemgr.renderSpritePaths(gfx); + } + + public Dimension getPreferredSize () + { + return new Dimension(300, 300); + } + + public static void main (String[] args) + { + ManagedJFrame frame = new ManagedJFrame("Path viz"); + FrameManager fmgr = FrameManager.newInstance(frame, frame); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setContentPane(new PathViz(fmgr)); + + fmgr.start(); + frame.pack(); + frame.setVisible(true); + } + + protected static class HappySprite extends Sprite + { + public HappySprite () + { + _bounds.width = 32; + _bounds.height = 32; + _oxoff = 16; + _oyoff = 16; + } + + public void paint (Graphics2D gfx) + { + gfx.setColor(Color.blue); + int hx = _bounds.x + _bounds.width/2; + int hy = _bounds.y + _bounds.height/2; + gfx.drawLine(hx, _bounds.y, hx, _bounds.y + _bounds.height-1); + gfx.drawLine(_bounds.x, hy, _bounds.x+_bounds.width-1, hy); + gfx.setColor(Color.black); + gfx.drawRect(_bounds.x, _bounds.y, + _bounds.width-1, _bounds.height-1); + } + } + + protected static final long MOVE_DURATION = 10*1000L; +} diff --git a/tests/src/java/com/threerings/media/util/TraceViz.java b/tests/src/java/com/threerings/media/util/TraceViz.java new file mode 100644 index 00000000..43ac47d9 --- /dev/null +++ b/tests/src/java/com/threerings/media/util/TraceViz.java @@ -0,0 +1,115 @@ +// +// $Id: TraceViz.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.media.util; + +import java.awt.Color; +import java.awt.Image; +import java.awt.image.BufferedImage; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import com.samskivert.swing.VGroupLayout; +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.media.Log; +import com.threerings.media.image.ImageManager; +import com.threerings.media.image.ImageUtil; + +/** + * Simple application for testing image trace functionality. + */ +public class TraceViz +{ + public TraceViz (String[] args) + throws IOException + { + // create the frame and image manager + _frame = new JFrame(); + _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + ImageManager imgr = new ImageManager(null, _frame); + + // set up the content panel + JPanel content = (JPanel)_frame.getContentPane(); + content.setBackground(Color.white); + content.setLayout(new VGroupLayout()); + + // load the image + BufferedImage image = ImageIO.read(new File(args[0])); + if (image == null) { + throw new RuntimeException("Failed to read file " + + "[file=" + args[0] + "]."); + } + +// // create a compatible image +// BufferedImage cimage = imgr.createImage( +// image.getWidth(null), image.getHeight(null), +// Transparency.TRANSLUCENT); +// Graphics g = cimage.getGraphics(); +// g.drawImage(image, 0, 0, null); +// g.dispose(); +// image = cimage; + + // create the traced image + Image timage = ImageUtil.createTracedImage( + imgr, image, Color.red, 5, 0.4f, 0.1f); + + // display the (prepared) original and traced image + content.add(new JLabel(new ImageIcon(image))); + content.add(new JLabel(new ImageIcon(timage))); + } + + public void run () + { + _frame.pack(); + SwingUtil.centerWindow(_frame); + _frame.show(); + } + + public static void main (String[] args) + { + try { + if (args.length == 0) { + System.out.println( + "Usage: java com.threerings.media.util.TraceViz " + + ""); + return; + } + + TraceViz app = new TraceViz(args); + app.run(); + + } catch (Exception e) { + Log.warning("Failed to run application: " + e); + Log.logStackTrace(e); + } + } + + protected JFrame _frame; +} diff --git a/tests/src/java/com/threerings/miso/client/ScrollingFrame.java b/tests/src/java/com/threerings/miso/client/ScrollingFrame.java new file mode 100644 index 00000000..38b6c720 --- /dev/null +++ b/tests/src/java/com/threerings/miso/client/ScrollingFrame.java @@ -0,0 +1,89 @@ +// +// $Id: ScrollingFrame.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Color; +import java.awt.Component; +import java.awt.GraphicsConfiguration; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.samskivert.swing.VGroupLayout; + +import com.threerings.media.SafeScrollPane; + +/** + * The main application window. + */ +public class ScrollingFrame extends JFrame +{ + /** + * Creates a frame in which the scrolling test app can operate. + */ + public ScrollingFrame (GraphicsConfiguration gc) + { + super(gc); + + // set up the frame options + setTitle("Scene scrolling test"); + // setUndecorated(true); + setIgnoreRepaint(true); + setResizable(false); + setDefaultCloseOperation(EXIT_ON_CLOSE); + + // set the frame and content panel background to black + setBackground(Color.black); + getContentPane().setBackground(Color.black); + + // create some interface elements to go with our scrolling panel + VGroupLayout vgl = new VGroupLayout(VGroupLayout.STRETCH); + vgl.setOffAxisPolicy(VGroupLayout.STRETCH); + getContentPane().setLayout(vgl); + + vgl = new VGroupLayout(VGroupLayout.NONE); + vgl.setOffAxisPolicy(VGroupLayout.STRETCH); + JPanel stuff = new JPanel(vgl); + for (int i = 0; i < 10; i++) { + stuff.add(new JButton("Button " + i)); + } + getContentPane().add(new SafeScrollPane(stuff)); + } + + /** + * Sets the panel displayed by this frame. + */ + public void setPanel (Component panel) + { + // if we had an old panel, remove it + if (_panel != null) { + getContentPane().remove(_panel); + } + + // now add the new one + _panel = panel; + getContentPane().add(_panel, 0); + } + + protected Component _panel; +} diff --git a/tests/src/java/com/threerings/miso/client/ScrollingScene.java b/tests/src/java/com/threerings/miso/client/ScrollingScene.java new file mode 100644 index 00000000..b7aa76c4 --- /dev/null +++ b/tests/src/java/com/threerings/miso/client/ScrollingScene.java @@ -0,0 +1,124 @@ +// +// $Id: ScrollingScene.java 3355 2005-02-17 01:54:54Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.Rectangle; + +import java.util.Iterator; +import java.util.Random; + +import com.samskivert.io.PersistenceException; + +import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.TileSet; +import com.threerings.media.tile.TileSetRepository; + +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.tile.BaseTile; +import com.threerings.miso.tile.BaseTileSet; +import com.threerings.miso.util.MisoContext; +import com.threerings.miso.util.ObjectSet; +import com.threerings.miso.data.ObjectInfo; + +/** + * Provides an infinite array of tiles in which to scroll. + */ +public class ScrollingScene extends MisoSceneModel +{ + public ScrollingScene (MisoContext ctx) + throws NoSuchTileSetException, PersistenceException + { + // locate the water tileset + TileSetRepository tsrepo = ctx.getTileManager().getTileSetRepository(); + Iterator iter = tsrepo.enumerateTileSets(); + String tsname = null; + while (iter.hasNext()) { + TileSet tset = (TileSet)iter.next(); + // yay for built-in regex support! + if (tset.getName().matches(".*[Ww]ater.*") && + tset instanceof BaseTileSet) { + tsname = tset.getName(); + break; + } + } + + if (tsname == null) { + throw new RuntimeException("Unable to locate water tileset."); + } + + // now we look the tileset up by name so that it is properly + // initialized and all that business + TileSet wtset = ctx.getTileManager().getTileSet(tsname); + + // grab our four repeating tiles + _tiles = new BaseTile[wtset.getTileCount()]; + for (int ii = 0; ii < wtset.getTileCount(); ii++) { + _tiles[ii] = (BaseTile)wtset.getTile(ii); + } + } + + public int getBaseTileId (int x, int y) + { + return -1; + } + + public boolean setBaseTile (int fqTileId, int x, int y) + { + return false; + } + + public boolean addObject (ObjectInfo info) + { + return true; + } + + public void getObjects (Rectangle region, ObjectSet set) + { + } + + public void updateObject (ObjectInfo info) + { + } + + public boolean removeObject (ObjectInfo info) + { + return false; + } + + // documentation inherited from interface + public BaseTile getBaseTile (int x, int y) + { + long seed = ((x^y) ^ multiplier) & mask; + long hash = (seed * multiplier + addend) & mask; + int tidx = (int)((hash >> 10) % _tiles.length); + return _tiles[tidx]; + } + + protected BaseTile[] _tiles; + protected Random _rand = new Random(); + + protected final static long multiplier = 0x5DEECE66DL; + protected final static long addend = 0xBL; + protected final static long mask = (1L << 48) - 1; + + protected static final int WATER_TILESET_ID = 8; +} diff --git a/tests/src/java/com/threerings/miso/client/ScrollingTestApp.java b/tests/src/java/com/threerings/miso/client/ScrollingTestApp.java new file mode 100644 index 00000000..091f2b12 --- /dev/null +++ b/tests/src/java/com/threerings/miso/client/ScrollingTestApp.java @@ -0,0 +1,234 @@ +// +// $Id: ScrollingTestApp.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.client; + +import java.awt.DisplayMode; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import java.io.IOException; + +import com.samskivert.swing.util.SwingUtil; +import com.samskivert.util.Config; + +import com.threerings.resource.ResourceManager; + +import com.threerings.media.FrameManager; +import com.threerings.media.image.ImageManager; +import com.threerings.media.util.LinePath; +import com.threerings.media.util.Path; + +import com.threerings.media.sprite.PathAdapter; +import com.threerings.media.sprite.Sprite; + +import com.threerings.media.tile.bundle.BundledTileSetRepository; + +import com.threerings.cast.CharacterComponent; +import com.threerings.cast.CharacterDescriptor; +import com.threerings.cast.CharacterManager; +import com.threerings.cast.CharacterSprite; +import com.threerings.cast.NoSuchComponentException; +import com.threerings.cast.bundle.BundledComponentRepository; + +import com.threerings.miso.Log; +import com.threerings.miso.MisoConfig; +import com.threerings.miso.tile.MisoTileManager; +import com.threerings.miso.util.MisoContext; + +/** + * Tests the scrolling capabilities of the IsoSceneView. + */ +public class ScrollingTestApp +{ + /** + * Construct and initialize the scrolling test app. + */ + public ScrollingTestApp (String[] args) + throws IOException + { + // get the graphics environment + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + // get the target graphics device + GraphicsDevice gd = env.getDefaultScreenDevice(); + Log.info("Graphics device [dev=" + gd + + ", mem=" + gd.getAvailableAcceleratedMemory() + + ", displayChange=" + gd.isDisplayChangeSupported() + + ", fullScreen=" + gd.isFullScreenSupported() + "]."); + + // get the graphics configuration and display mode information + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + DisplayMode dm = gd.getDisplayMode(); + Log.info("Display mode [bits=" + dm.getBitDepth() + + ", wid=" + dm.getWidth() + ", hei=" + dm.getHeight() + + ", refresh=" + dm.getRefreshRate() + "]."); + + // create the window + _frame = new ScrollingFrame(gc); + + // set up our frame manager + _framemgr = FrameManager.newInstance(_frame, _frame); + + // we don't need to configure anything + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + ImageManager imgr = new ImageManager(rmgr, _frame); + _tilemgr = new MisoTileManager(rmgr, imgr); + _tilemgr.setTileSetRepository( + new BundledTileSetRepository(rmgr, imgr, "tilesets")); + + // hack in some different MisoProperties + MisoConfig.config = new Config("rsrc/config/miso/scrolling"); + + // create the context object + MisoContext ctx = new ContextImpl(); + + // create the various managers + BundledComponentRepository crepo = + new BundledComponentRepository(rmgr, imgr, "components"); + CharacterManager charmgr = new CharacterManager(imgr, crepo); + + // create our scene view panel + _panel = new MisoScenePanel(ctx, MisoConfig.getSceneMetrics()); + _frame.setPanel(_panel); + + // create our "ship" sprite + String scclass = "navsail", scname = "smsloop"; + try { + CharacterComponent ccomp = crepo.getComponent(scclass, scname); + CharacterDescriptor desc = new CharacterDescriptor( + new int[] { ccomp.componentId }, null); + + // now create the actual sprite and stick 'em in the scene + _ship = charmgr.getCharacter(desc); + if (_ship != null) { + _ship.setFollowingPathAction("sailing"); + _ship.setRestingAction("sailing"); + _ship.setActionSequence("sailing"); + _ship.setLocation(0, 0); + _panel.addSprite(_ship); + } + + } catch (NoSuchComponentException nsce) { + Log.warning("Can't locate ship component [class=" + scclass + + ", name=" + scname + "]."); + } + + _ship.addSpriteObserver(new PathAdapter() { + public void pathCompleted (Sprite sprite, Path path, long when) { + // keep scrolling for a spell + if (++_sidx < DX.length) { + int x = _ship.getX(), y = _ship.getY(); + LinePath lpath = new LinePath( + x, y, x + DX[_sidx], y + DY[_sidx], 30000l); + _ship.move(lpath); + } + } + protected int _sidx = -1; + protected final int[] DX = { 1620, 0, 1000, -1000, 1000, 2000 }; + protected final int[] DY = { 1400, 1000, 0, 1000, -1000, 1000 }; + }); + + // make the panel follow the ship around + _panel.setFollowsPathable(_ship, MisoScenePanel.CENTER_ON_PATHABLE); + int x = _ship.getX(), y = _ship.getY(); + _ship.move(new LinePath(x, y, x, y + 1000, 3000l)); + + // size and position the window, entering full-screen exclusive + // mode if available + if (gd.isFullScreenSupported()) { + Log.info("Entering full-screen exclusive mode."); + gd.setFullScreenWindow(_frame); + _frame.setUndecorated(true); + + } else { + Log.warning("Full-screen exclusive mode not available."); + // _frame.pack(); + _frame.setSize(200, 300); + SwingUtil.centerWindow(_frame); + } + + try { + _panel.setSceneModel(new ScrollingScene(ctx)); + } catch (Exception e) { + Log.warning("Error creating scene: " + e); + Log.logStackTrace(e); + } + } + + /** + * The implementation of the MisoContext interface that provides + * handles to the manager objects that offer commonly used services. + */ + protected class ContextImpl implements MisoContext + { + public MisoTileManager getTileManager () { + return _tilemgr; + } + + public FrameManager getFrameManager () { + return _framemgr; + } + } + + /** + * Run the application. + */ + public void run () + { + // show the window + _frame.show(); + _framemgr.start(); + } + + /** + * Instantiate the application object and start it running. + */ + public static void main (String[] args) + { + try { + ScrollingTestApp app = new ScrollingTestApp(args); + app.run(); + } catch (IOException ioe) { + System.err.println("Error initializing scrolling app."); + ioe.printStackTrace(); + } + } + + /** The tile manager object. */ + protected MisoTileManager _tilemgr; + + /** The frame manager. */ + protected FrameManager _framemgr; + + /** The main application window. */ + protected ScrollingFrame _frame; + + /** The main panel. */ + protected MisoScenePanel _panel; + + /** The ship in the center of our screen. */ + protected CharacterSprite _ship; +} diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java new file mode 100644 index 00000000..c488fcf9 --- /dev/null +++ b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java @@ -0,0 +1,191 @@ +// +// $Id: ViewerApp.java 4181 2006-06-07 21:54:12Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.viewer; + +import java.awt.DisplayMode; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.io.IOException; + +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.resource.ResourceManager; + +import com.threerings.media.FrameManager; +import com.threerings.media.image.ImageManager; +import com.threerings.media.tile.bundle.BundledTileSetRepository; + +import com.threerings.cast.CharacterManager; +import com.threerings.cast.bundle.BundledComponentRepository; + +import com.threerings.miso.Log; +import com.threerings.miso.data.SimpleMisoSceneModel; +import com.threerings.miso.tile.MisoTileManager; +import com.threerings.miso.tools.xml.SimpleMisoSceneParser; +import com.threerings.miso.util.MisoContext; + +/** + * The ViewerApp is a scene viewing application that allows for trying + * out game scenes in a pseudo-runtime environment. + */ +public class ViewerApp +{ + /** + * Construct and initialize the ViewerApp object. + */ + public ViewerApp (String[] args) + throws IOException + { + if (args.length < 1) { + System.err.println("Usage: ViewerApp scene_file.xml"); + System.exit(-1); + } + + // get the graphics environment + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + // get the target graphics device + GraphicsDevice gd = env.getDefaultScreenDevice(); + Log.info("Graphics device [dev=" + gd + + ", mem=" + gd.getAvailableAcceleratedMemory() + + ", displayChange=" + gd.isDisplayChangeSupported() + + ", fullScreen=" + gd.isFullScreenSupported() + "]."); + + // get the graphics configuration and display mode information + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + DisplayMode dm = gd.getDisplayMode(); + Log.info("Display mode [bits=" + dm.getBitDepth() + + ", wid=" + dm.getWidth() + ", hei=" + dm.getHeight() + + ", refresh=" + dm.getRefreshRate() + "]."); + + // create the window + _frame = new ViewerFrame(gc); + _framemgr = FrameManager.newInstance(_frame, _frame); + + // we don't need to configure anything + ResourceManager rmgr = new ResourceManager("rsrc"); + rmgr.initBundles( + null, "config/resource/manager.properties", null); + ImageManager imgr = new ImageManager(rmgr, _frame); + _tilemgr = new MisoTileManager(rmgr, imgr); + _tilemgr.setTileSetRepository( + new BundledTileSetRepository(rmgr, imgr, "tilesets")); + + // create the context object + MisoContext ctx = new ContextImpl(); + + // create the various managers + BundledComponentRepository crepo = + new BundledComponentRepository(rmgr, imgr, "components"); + CharacterManager charmgr = new CharacterManager(imgr, crepo); + + // create our scene view panel + _panel = new ViewerSceneViewPanel(ctx, charmgr, crepo); + _frame.setPanel(_panel); + + // load up the scene specified by the user + try { + SimpleMisoSceneParser parser = new SimpleMisoSceneParser(""); + SimpleMisoSceneModel model = parser.parseScene(args[0]); + if (model == null) { + Log.warning("No miso scene found in scene file " + + "[path=" + args[0] + "]."); + System.exit(-1); + } + _panel.setSceneModel(model); + + } catch (Exception e) { + Log.warning("Unable to parse scene [path=" + args[0] + "]."); + Log.logStackTrace(e); + System.exit(-1); + } + + // size and position the window, entering full-screen exclusive + // mode if available + if (gd.isFullScreenSupported()) { + Log.info("Entering full-screen exclusive mode."); + gd.setFullScreenWindow(_frame); + + } else { + Log.warning("Full-screen exclusive mode not available."); + // _frame.pack(); + _frame.setSize(600, 400); + SwingUtil.centerWindow(_frame); + } + } + + /** + * The implementation of the MisoContext interface that provides + * handles to the config and manager objects that offer commonly used + * services. + */ + protected class ContextImpl implements MisoContext + { + public MisoTileManager getTileManager () + { + return _tilemgr; + } + + public FrameManager getFrameManager () + { + return _framemgr; + } + } + + /** + * Run the application. + */ + public void run () + { + // show the window + _frame.show(); + _framemgr.start(); + } + + /** + * Instantiate the application object and start it running. + */ + public static void main (String[] args) + { + try { + ViewerApp app = new ViewerApp(args); + app.run(); + } catch (IOException ioe) { + System.err.println("Error initializing viewer app."); + ioe.printStackTrace(); + } + } + + /** The tile manager object. */ + protected MisoTileManager _tilemgr; + + /** The frame manager. */ + protected FrameManager _framemgr; + + /** The main application window. */ + protected ViewerFrame _frame; + + /** The main panel. */ + protected ViewerSceneViewPanel _panel; +} diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java new file mode 100644 index 00000000..5728f18d --- /dev/null +++ b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java @@ -0,0 +1,94 @@ +// +// $Id: ViewerFrame.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.viewer; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.GraphicsConfiguration; +import java.awt.event.ActionEvent; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; + +import com.samskivert.swing.util.MenuUtil; + +/** + * The viewer frame is the main application window. + */ +public class ViewerFrame extends JFrame +{ + /** + * Creates a frame in which the viewer application can operate. + */ + public ViewerFrame (GraphicsConfiguration gc) + { + super(gc); + + // set up the frame options + setTitle("Scene Viewer"); + setResizable(false); + setDefaultCloseOperation(EXIT_ON_CLOSE); + + // set the frame and content panel background to black + setBackground(Color.black); + getContentPane().setBackground(Color.black); + + // create the "Settings" menu + JMenu menuSettings = new JMenu("Settings"); + MenuUtil.addMenuItem( + menuSettings, "Preferences", this, "handlePreferences"); + + // create the menu bar + JMenuBar bar = new JMenuBar(); + bar.add(menuSettings); + + // add the menu bar to the frame + setJMenuBar(bar); + } + + /** + * Sets the panel displayed by this frame. + */ + public void setPanel (Component panel) + { + // if we had an old panel, remove it + if (_panel != null) { + getContentPane().remove(_panel); + } + + // now add the new one + _panel = panel; + getContentPane().add(_panel, BorderLayout.CENTER); + } + + /** + * Dummy callback method. + */ + public void handlePreferences (ActionEvent event) + { + System.err.println("Nothing doing!"); + } + + protected Component _panel; +} diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java new file mode 100644 index 00000000..e045efae --- /dev/null +++ b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java @@ -0,0 +1,237 @@ +// +// $Id: ViewerSceneViewPanel.java 4188 2006-06-13 18:03:48Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.viewer; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.MouseEvent; + +import com.samskivert.util.RandomUtil; + +import com.threerings.cast.CharacterDescriptor; +import com.threerings.cast.CharacterManager; +import com.threerings.cast.CharacterSprite; +import com.threerings.cast.ComponentRepository; +import com.threerings.cast.util.CastUtil; + +import com.threerings.media.sprite.PathObserver; +import com.threerings.media.sprite.Sprite; +import com.threerings.media.sprite.SpriteManager; +import com.threerings.media.util.LineSegmentPath; + +import com.threerings.media.util.Path; +import com.threerings.media.util.PerformanceMonitor; +import com.threerings.media.util.PerformanceObserver; + +import com.threerings.miso.Log; +import com.threerings.miso.MisoConfig; +import com.threerings.miso.client.MisoScenePanel; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.util.MisoContext; + +public class ViewerSceneViewPanel extends MisoScenePanel + implements PerformanceObserver, PathObserver +{ + /** + * Construct the panel and initialize it with a context. + */ + public ViewerSceneViewPanel (MisoContext ctx, + CharacterManager charmgr, + ComponentRepository crepo) + { + super(ctx, MisoConfig.getSceneMetrics()); + + // create the character descriptors + _descUser = CastUtil.getRandomDescriptor("female", crepo); + _descDecoy = CastUtil.getRandomDescriptor("male", crepo); + + // create the manipulable sprite + _sprite = createSprite(_spritemgr, charmgr, _descUser); + setFollowsPathable(_sprite, CENTER_ON_PATHABLE); + + // create the decoy sprites + createDecoys(_spritemgr, charmgr); + + PerformanceMonitor.register(this, "paint", 1000); + } + + // documentation inherited + public void setSceneModel (MisoSceneModel model) + { + super.setSceneModel(model); + Log.info("Using " + model + "."); + } + + // documentation inherited + public void doLayout () + { + super.doLayout(); + + // now that we have a scene, we can create valid paths for our + // decoy sprites + createDecoyPaths(); + } + + /** + * Creates a new sprite. + */ + protected CharacterSprite createSprite ( + SpriteManager spritemgr, CharacterManager charmgr, + CharacterDescriptor desc) + { + CharacterSprite s = charmgr.getCharacter(desc); + if (s != null) { + // start 'em out standing + s.setActionSequence(CharacterSprite.STANDING); + s.setLocation(300, 300); + s.addSpriteObserver(this); + spritemgr.addSprite(s); + } + + return s; + } + + /** + * Creates the decoy sprites. + */ + protected void createDecoys ( + SpriteManager spritemgr, CharacterManager charmgr) + { + _decoys = new CharacterSprite[NUM_DECOYS]; + for (int ii = 0; ii < NUM_DECOYS; ii++) { + _decoys[ii] = createSprite(spritemgr, charmgr, _descDecoy); + } + } + + /** + * Creates paths for the decoy sprites. + */ + protected void createDecoyPaths () + { + for (int ii = 0; ii < NUM_DECOYS; ii++) { + if (_decoys[ii] != null) { + createRandomPath(_decoys[ii]); + } + } + } + + // documentation inherited + public void paint (Graphics g) + { + super.paint(g); + PerformanceMonitor.tick(this, "paint"); + } + + // documentation inherited + public void checkpoint (String name, int ticks) + { + Log.info(name + " [ticks=" + ticks + "]."); + } + + // documentation inherited + public void mousePressed (MouseEvent e) + { + super.mousePressed(e); + + int x = e.getX(), y = e.getY(); + Log.info("Mouse pressed +" + x + "+" + y); + + switch (e.getModifiers()) { + case MouseEvent.BUTTON1_MASK: + createPath(_sprite, x, y); + break; + + case MouseEvent.BUTTON2_MASK: + for (int ii = 0; ii < NUM_DECOYS; ii++) { + createPath(_decoys[ii], x, y); + } + break; + } + } + + /** + * Assigns the sprite a path leading to the given destination + * screen coordinates. Returns whether a path was successfully + * assigned. + */ + protected boolean createPath (CharacterSprite s, int x, int y) + { + // get the path from here to there + LineSegmentPath path = (LineSegmentPath)getPath(s, x, y, true); + if (path == null) { + s.cancelMove(); + return false; + } + + // start the sprite moving along the path + path.setVelocity(100f/1000f); + s.move(path); + return true; + } + + /** + * Assigns a new random path to the given sprite. + */ + protected void createRandomPath (CharacterSprite s) + { + Dimension d = _vbounds.getSize(); + if (d.width <= 0 || d.height <= 0) { + return; + } + int x, y; + do { + x = RandomUtil.getInt(d.width); + y = RandomUtil.getInt(d.height); + } while (!createPath(s, x, y)); + } + + // documentation inherited + public void pathCompleted (Sprite sprite, Path path, long when) + { + CharacterSprite s = (CharacterSprite)sprite; + if (s != _sprite) { + // move the sprite to a new random location + createRandomPath(s); + } + } + + // documentation inherited + public void pathCancelled (Sprite sprite, Path path) + { + // nothing doing + } + + /** The number of decoy characters milling about. */ + protected static final int NUM_DECOYS = 5; + + /** The character descriptor for the user character. */ + protected CharacterDescriptor _descUser; + + /** The character descriptor for the decoy characters. */ + protected CharacterDescriptor _descDecoy; + + /** The sprite we're manipulating within the view. */ + protected CharacterSprite _sprite; + + /** The test sprites that meander about aimlessly. */ + protected CharacterSprite _decoys[]; +} diff --git a/tests/src/java/com/threerings/openal/TestSoundManager.java b/tests/src/java/com/threerings/openal/TestSoundManager.java new file mode 100644 index 00000000..caf3fdc6 --- /dev/null +++ b/tests/src/java/com/threerings/openal/TestSoundManager.java @@ -0,0 +1,55 @@ +// +// $Id$ + +package com.threerings.openal; + +import java.io.IOException; + +import com.samskivert.util.Interval; +import com.samskivert.util.Queue; +import com.samskivert.util.RunQueue; + +/** + * Tests the OpenAL sound system. + */ +public class TestSoundManager +{ + public static void main (String[] args) + { + if (args.length == 0) { + System.err.println("Usage: TestSoundManager sound.wav"); + System.exit(-1); + } + + final Thread current = Thread.currentThread(); + RunQueue rqueue = new RunQueue() { + public void postRunnable (Runnable r) { + _queue.append(r); + } + public boolean isDispatchThread () { + return (current == Thread.currentThread()); + } + }; + + SoundManager smgr = SoundManager.createSoundManager(rqueue); + ClipProvider provider = new WaveDataClipProvider(); + final SoundGroup group = smgr.createGroup(provider, 5); + final String path = args[0]; + + // queue up an interval to play a sound over and over + Interval i = new Interval(rqueue) { + public void expired () { + Sound sound = group.getSound(path); + sound.play(true); + } + }; + i.schedule(100L, true); + + while (true) { + Runnable r = (Runnable)_queue.get(); + r.run(); + } + } + + protected static Queue _queue = new Queue(); +} diff --git a/tests/src/java/com/threerings/util/DirectionTest.java b/tests/src/java/com/threerings/util/DirectionTest.java new file mode 100644 index 00000000..28501b12 --- /dev/null +++ b/tests/src/java/com/threerings/util/DirectionTest.java @@ -0,0 +1,73 @@ +// +// $Id: DirectionTest.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import junit.framework.Test; +import junit.framework.TestCase; + +/** + * Tests the {@link Direction} class. + */ +public class DirectionTest extends TestCase + implements DirectionCodes +{ + public DirectionTest () + { + super(DirectionTest.class.getName()); + } + + public void runTest () + { + int orient = NORTH; + + for (int i = 0; i < FINE_DIRECTION_COUNT; i++) { +// System.out.print(DirectionUtil.toShortString(orient) + " -> "); + orient = DirectionUtil.rotateCW(orient, 1); + } +// System.out.println(DirectionUtil.toShortString(orient)); + assertTrue("CW rotate", orient == NORTH); + + for (int i = 0; i < FINE_DIRECTION_COUNT; i++) { +// System.out.print(DirectionUtil.toShortString(orient) + " -> "); + orient = DirectionUtil.rotateCCW(orient, 1); + } +// System.out.println(DirectionUtil.toShortString(orient)); + assertTrue("CCW rotate", orient == NORTH); + +// for (double theta = -Math.PI; theta <= Math.PI; theta += Math.PI/1000) { +// orient = DirectionUtil.getFineDirection(theta); +// System.out.println(Math.toDegrees(theta) + " => " + +// DirectionUtil.toShortString(orient)); +// } + } + + public static Test suite () + { + return new DirectionTest(); + } + + public static void main (String[] args) + { + DirectionTest test = new DirectionTest(); + test.runTest(); + } +} diff --git a/tests/src/java/com/threerings/util/DirectionViz.java b/tests/src/java/com/threerings/util/DirectionViz.java new file mode 100644 index 00000000..6d3c2472 --- /dev/null +++ b/tests/src/java/com/threerings/util/DirectionViz.java @@ -0,0 +1,86 @@ +// +// $Id: DirectionViz.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Point; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * Renders the output of {@link DirectionUtil#getDirection} just for + * kicks. + */ +public class DirectionViz extends JPanel + implements MouseMotionListener +{ + public DirectionViz () + { + addMouseMotionListener(this); + } + + public void doLayout () + { + super.doLayout(); + _center = new Point(getWidth() / 2, getHeight() / 2); + } + + public void paintComponent (Graphics g) + { + super.paintComponent(g); + + g.setColor(Color.blue); + g.drawLine(_center.x, _center.y, _spot.x, _spot.y); + + int orient = DirectionUtil.getFineDirection(_center, _spot); + g.drawString(DirectionUtil.toShortString(orient), _spot.x, _spot.y); + } + + public void mouseDragged (MouseEvent event) + { + } + + public void mouseMoved (MouseEvent event) + { + _spot.x = event.getX(); + _spot.y = event.getY(); + repaint(); + } + + public static void main (String[] args) + { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(new DirectionViz(), BorderLayout.CENTER); + frame.setSize(300, 300); + frame.show(); + } + + protected Point _center; + protected Point _spot = new Point(); +} diff --git a/tests/src/java/com/threerings/util/KeyTimerApp.java b/tests/src/java/com/threerings/util/KeyTimerApp.java new file mode 100644 index 00000000..bc4c4cc9 --- /dev/null +++ b/tests/src/java/com/threerings/util/KeyTimerApp.java @@ -0,0 +1,97 @@ +// +// $Id: KeyTimerApp.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.Frame; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import com.threerings.util.Log; + +public class KeyTimerApp +{ + public KeyTimerApp () + { + _frame = new TestFrame(); + _frame.setSize(400, 300); + } + + public void run () + { + _frame.show(); + } + + public static void main (String[] args) + { + KeyTimerApp app = new KeyTimerApp(); + app.run(); + } + + protected class TestFrame extends Frame implements KeyListener + { + public TestFrame () + { + addKeyListener(this); + _prStart = _rpStart = -1; + } + + public void keyPressed (KeyEvent e) + { + long now = System.currentTimeMillis(); + _prStart = now; + + if (_rpStart != -1) { + Log.info("RP\t" + (now - _rpStart)); + } + + logKey("keyPressed", e); + } + + public void keyReleased (KeyEvent e) + { + long now = System.currentTimeMillis(); + _rpStart = now; + + Log.info("PR\t" + (now - _prStart)); + + logKey("keyReleased", e); + } + + public void keyTyped (KeyEvent e) + { + logKey("keyTyped", e); + } + + /** + * Logs the given message and key. + */ + protected void logKey (String msg, KeyEvent e) + { + int keyCode = e.getKeyCode(); + Log.info(msg + " [key=" + KeyEvent.getKeyText(keyCode) + "]."); + } + + protected long _prStart, _rpStart; + } + + protected Frame _frame; +} diff --git a/tests/src/java/com/threerings/util/KeyboardManagerApp.java b/tests/src/java/com/threerings/util/KeyboardManagerApp.java new file mode 100644 index 00000000..822fd650 --- /dev/null +++ b/tests/src/java/com/threerings/util/KeyboardManagerApp.java @@ -0,0 +1,108 @@ +// +// $Id: KeyboardManagerApp.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.samskivert.swing.Controller; +import com.samskivert.swing.ControllerProvider; + +import com.threerings.util.Log; + +public class KeyboardManagerApp +{ + public KeyboardManagerApp () + { + _frame = new TestFrame(); + _frame.setSize(400, 300); + } + + public void run () + { + _frame.show(); + } + + public static void main (String[] args) + { + KeyboardManagerApp app = new KeyboardManagerApp(); + app.run(); + } + + protected static class TestFrame extends JFrame + implements ControllerProvider + { + public TestFrame () + { + // create the test controller + _ctrl = new TestController(); + + setDefaultCloseOperation(EXIT_ON_CLOSE); + + JPanel top = new JPanel(); + + // add some sample key mappings + KeyTranslatorImpl xlate = new KeyTranslatorImpl(); + xlate.addPressCommand(KeyEvent.VK_LEFT, TestController.MOVE_LEFT); + xlate.addPressCommand( + KeyEvent.VK_RIGHT, TestController.MOVE_RIGHT); + xlate.addPressCommand(KeyEvent.VK_SPACE, TestController.DROP); + + // create the keyboard manager + KeyboardManager keymgr = new KeyboardManager(); + keymgr.setTarget(top, xlate); + keymgr.setEnabled(true); + + getContentPane().add(top); + } + + // documentation inherited + public Controller getController () + { + return _ctrl; + } + + /** The test controller. */ + protected Controller _ctrl; + } + + protected static class TestController extends Controller + { + public static final String MOVE_LEFT = "move_left"; + public static final String MOVE_RIGHT = "move_right"; + public static final String DROP = "drop"; + + // documentation inherited + public boolean handleAction (ActionEvent action) + { + String cmd = action.getActionCommand(); + Log.info("handleAction [cmd=" + cmd + "]."); + return true; + } + } + + /** The test frame. */ + protected JFrame _frame; +} diff --git a/tests/src/java/com/threerings/util/MessageBundleTest.java b/tests/src/java/com/threerings/util/MessageBundleTest.java new file mode 100644 index 00000000..25f74049 --- /dev/null +++ b/tests/src/java/com/threerings/util/MessageBundleTest.java @@ -0,0 +1,79 @@ +// +// $Id: MessageBundleTest.java 3099 2004-08-27 02:21:06Z mdb $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.util; + +import java.util.ResourceBundle; + +import junit.framework.Test; +import junit.framework.TestCase; + +/** + * Tests the {@link MessageBundle} class. + */ +public class MessageBundleTest extends TestCase +{ + public MessageBundleTest () + { + super(MessageBundleTest.class.getName()); + } + + public void runTest () + { + try { + String path = "rsrc.i18n.messages"; + ResourceBundle rbundle = ResourceBundle.getBundle(path); + MessageBundle bundle = new MessageBundle(); + bundle.init(null, "test", rbundle, null); + + String key1 = MessageBundle.compose("m.foo", + MessageBundle.taint("bar"), + MessageBundle.taint("baz")); + String key2 = MessageBundle.compose("m.biff", + MessageBundle.taint("beep"), + MessageBundle.taint("boop")); + String key = MessageBundle.compose("m.meta", key1, key2); + + String output = bundle.xlate(key); + if (!OUTPUT.equals(output)) { + fail("xlate failed: " + output); + } + + } catch (Exception e) { + fail("Test failed: " + e); + } + } + + public static Test suite () + { + return new MessageBundleTest(); + } + + public static void main (String[] args) + { + MessageBundleTest test = new MessageBundleTest(); + test.runTest(); + } + + protected static final String OUTPUT = + "Meta arg one is 'Foo arg one is 'bar' and two is 'baz'.' and " + + "two is 'Biff arg one is 'beep' and two is 'boop'.'."; +} diff --git a/tests/src/java/com/threerings/util/UIDTest.java b/tests/src/java/com/threerings/util/UIDTest.java new file mode 100644 index 00000000..cabc45b6 --- /dev/null +++ b/tests/src/java/com/threerings/util/UIDTest.java @@ -0,0 +1,30 @@ +// +// $Id$ + +package com.threerings.util; + +import com.threerings.util.unsafe.Unsafe; + +/** + * Does something extraordinary. + */ +public class UIDTest +{ + public static void main (String[] args) + { + if (Unsafe.setuid(1000)) { + System.err.println("Yay! My uid is changed."); + } else { + System.err.println("Boo hoo! I couldn't change my uid."); + } + if (Unsafe.setgid(60)) { + System.err.println("Yay! My gid is changed."); + } else { + System.err.println("Boo hoo! I couldn't change my gid."); + } + try { + Thread.sleep(60*1000L); + } catch (Exception e) { + } + } +}

      l-`tp}vrdx)RzE>PLja*1nLZ`TyK8FgVLIAHs#~ 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/media/miso/tiles/components/standing_torso.png b/tests/rsrc/media/miso/tiles/components/standing_torso.png new file mode 100644 index 0000000000000000000000000000000000000000..e3d4801fd6cbec4a6935e553bbf85ac76c3ff8fc GIT binary patch literal 54712 zcmYg%dpy(c`@gec*yc26n=^@-GlerQd7JHgEPY|h90LQ> zGJuW#KM6PDM+S!XF_xyrPFFwSGCQ~#)BsH9&umD>5o|=_dvBS@)<2fwka?4hLl0z6 zGz=ObFHBw7n3cUgemk0~TAlGaGHQ{Lfq_QD5QWCn(iWt=Z4@f-SD;73RtnQ4)V^QL zVwQB}J^C_hZI4Ei%t+B>cVX%jECkYj^zHY*Gu9IO$n?iORs~e+nzXgLT{ zXsfPVs}w~PUM1sT2b8LLZ4}V$4n;|%w)1F{7*54!x|i_%cMF8|Xe5MBfjX~>y)IvQ z-DHDAqtS#9zUs)=**CV`}!s(BC${onlEfCxCCAO;0=plxj`y#|l@aVOy3xSI)2j{4? zOjNC`V`XTX;&L%Fu?dM&_B+odh4sB7RMrCLb-Q!E$_4*uIAnz`;(b}cE8n)~^#<#v z705}K*9*D41EH0f+rnIZ9Qc)>#Y(Bsx>Ty_d-h?pbz$ zxbuC8mKzGFr}}}N+|{!h)yF~ohpHgvsxJ$$Q!fU&KZ2mG6AI*n3B8hN9=K-3%4XS^ zgi4bj?8X1YlgkNcJRN-B0;_3&cnZUkm~o$aT5fP-OOIjnOvjX50{7%b+|5pN{o@=q zBGR6(w0u9<{SlMPx;+1P96a8kCeL9AGI55tDMR?UHYHU7N?-f;n7;0D4yb1=@MfVU>a8aqA9*v-<$QihgeVum1Q-P<5io0XaUH4{cK<=L^55cMkba*vgIwdeWs)cC4=%YJvp=q!}g10HlY z-#@X!DxvM#UABRj>;i+pj0LPmJ^YG8=O`23%i69Z0b$p@dV(=tlb%#!`*K-aTpaiY zjpj$CF4jGNKBm079dt%GP!rc*4N(N-+xDS zBj31Wn~!w&+9))mVb3cwH*a&B&d28BU3uW><#S#j3bngkuD3gQDvp7fJ(+=7=%*^% z(TG_9qwyPMx_V-M(^pS#kE*&{r|pF#ITWQcByCjS02qdL13^AW1!3We?=Qq(N~d)}bQz1Pdr z8$n6hLyJhYot>VY?ICoMeOa42Afy4Qw&&-0b+xoKF4rT6vSDb>#@2-fiWI?jLOD5a z<>oXBU*FvuSe{)|PSS6#5yx(CU0{_awegWhr`K zF_=yqWmQU)6V%c=-Sw{EJGVi4V)Ji7K`o|ipU5m$lDy1SM&l*5TZK{5$;8VKkM2f$ z?+qjomgH6Ejyij==%o+qb$!D1%YBPV$`SA06=VS@RX0n_oOOEhmg8p1lC;6iF-?{R z#VWJd>qCmxBwrO>@rWMx^LO>lyP?}M&ah8pjVsTwI7*a_gUJ#99@dGgLt}8-UlATK z$eKK4m3HIInc*{4>8zzL^^I#s1#fprLzSoH5j~tOM)3>Lj3@(AfbUnGll;3LL!W

    vj+HW2_o{#{bRZ4D7sM zAtc=nX}}-3K@XXCVUxj8Jx|`gE&KE#QJtrhn2PzESGC^VqQZw~-mM?yp{M!TN_QKt zyDz6g1$$ApX4uQaLq-?Ai(NGIELxjS3eJKf(=U*utGpne19*Xl9XfvVt8etIazKim z7~;@{7BPkI60v=q&U_y3~#L3`{y%xt>~qWRp%D)V79%7*DZ@# znZ7lZz${Lz?qRd`&eaT;4pw7ewR%wH%hnMGGfvGl;XQp&m0}j#6xMCW025a8tvSJ4 zjc#{dw`?*;Md{1<0Z*TY9(vqmqfkhhHQx6;JVpp54+T=Kpo|0nQ5w|MsriPs+YkFb zwY{dC7I`^FM)}7@b~dTZ!VHQTS7*C=(OK#X=0w5YK@vB^L3FV- zCzFy}aza+iKPYg0$kz5Yu`w!4tn<8yYp4ZF6S}|O?XC)JcIoh=*J$5~x5A_huLBtw z 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 Cwp-x< literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/walking.png b/tests/rsrc/bundles/components/pirate/female/legs/dressbottom_long/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..75789a7ad9bed2db80f78001aeaf805138f7b52a GIT binary patch literal 70442 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

    30{F;HaZ6kQz>9>R43CkHxz(MH0T8CA~_ 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 S$;{&b52&)1Ql)}b$bSJmjR@HQ literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/behind_back.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..7944f1aee2eab894cb592bdcc03765de66dbfea8 GIT binary patch literal 11179 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 F@?Q$ppK1UA literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/standing.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..2240c2eab1cb6351d9105d2c49e40439724eaaa8 GIT binary patch literal 11293 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/walking.png b/tests/rsrc/bundles/components/pirate/female/feet/pegleg_buckleshoes/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..334c2b1227e2da1a3fa105bd49206f49307c4fb6 GIT binary patch literal 32226 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 VzsOD^xYY_#QPfl@cwq7B{{ZwHh-v@; literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hair/long_straight/standing.png b/tests/rsrc/bundles/components/pirate/female/hair/long_straight/standing.png new file mode 100644 index 0000000000000000000000000000000000000000..6e3c4a901cb2925a02be280e0aa11a79522341b2 GIT binary patch literal 15006 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 Z3bN=(qD4F}J^}$BRb>sOQpKmi{|_#bN-+Qc literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hair/long_straight/walking.png b/tests/rsrc/bundles/components/pirate/female/hair/long_straight/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..2538c06910f659bd7db53d69ffbb71c1fb0df0ee GIT binary patch literal 56485 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 iKYBmn|2xWrbzit$o~LZskes! literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hair/messy_short/walking.png b/tests/rsrc/bundles/components/pirate/female/hair/messy_short/walking.png new file mode 100644 index 0000000000000000000000000000000000000000..ded1602e007475c5552310d4b52adafe68167e78 GIT binary patch literal 36424 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 literal 0 HcmV?d00001 diff --git a/tests/rsrc/bundles/components/pirate/female/hair/ponytail/behind_back.png b/tests/rsrc/bundles/components/pirate/female/hair/ponytail/behind_back.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd5596481528839ce1a6211b8f5bd388dd3749f GIT binary patch literal 13870 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 uz>N{I`_mf00(E= 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