diff --git a/build.xml b/build.xml index 8b6b3921e..1fb9edb56 100644 --- a/build.xml +++ b/build.xml @@ -61,11 +61,7 @@ - - - - @@ -89,30 +85,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -135,17 +107,11 @@ - + - - - - - - @@ -155,10 +121,6 @@ - - @@ -172,15 +134,14 @@ - - + + @@ -203,13 +164,8 @@ - - - - - @@ -217,39 +173,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -279,27 +204,11 @@ - - - - - - - - - - - - - - - - diff --git a/src/java/com/threerings/admin/client/ConfigEditorPanel.java b/src/java/com/threerings/admin/client/ConfigEditorPanel.java index 09d9da281..06d1b1f60 100644 --- a/src/java/com/threerings/admin/client/ConfigEditorPanel.java +++ b/src/java/com/threerings/admin/client/ConfigEditorPanel.java @@ -23,11 +23,11 @@ package com.threerings.admin.client; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import com.samskivert.swing.VGroupLayout; -import com.threerings.media.SafeScrollPane; import com.threerings.presents.util.PresentsContext; import com.threerings.admin.Log; @@ -84,7 +84,7 @@ public class ConfigEditorPanel extends JPanel // when we're hidden, we want to clear out our subscriptions int ccount = _oeditors.getComponentCount(); for (int ii = 0; ii < ccount; ii++) { - SafeScrollPane scrolly = (SafeScrollPane)_oeditors.getComponent(ii); + JScrollPane scrolly = (JScrollPane)_oeditors.getComponent(ii); ObjectEditorPanel opanel = (ObjectEditorPanel) scrolly.getViewport().getView(); opanel.cleanup(); @@ -101,7 +101,7 @@ public class ConfigEditorPanel extends JPanel for (int ii = 0; ii < keys.length; ii++) { ObjectEditorPanel panel = new ObjectEditorPanel(_ctx, keys[ii], oids[ii]); - SafeScrollPane scrolly = new SafeScrollPane(panel); + JScrollPane scrolly = new JScrollPane(panel); _oeditors.addTab(keys[ii], scrolly); if (keys[ii].equals(_defaultPane)) { _oeditors.setSelectedComponent(scrolly); diff --git a/src/java/com/threerings/admin/client/DSetEditor.java b/src/java/com/threerings/admin/client/DSetEditor.java index b9345fbf9..8c5c45eb6 100644 --- a/src/java/com/threerings/admin/client/DSetEditor.java +++ b/src/java/com/threerings/admin/client/DSetEditor.java @@ -29,6 +29,7 @@ import java.lang.reflect.Field; import java.util.BitSet; import javax.swing.JPanel; +import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; @@ -39,8 +40,6 @@ import com.samskivert.util.ClassUtil; import com.samskivert.util.ComparableArrayList; import com.samskivert.util.ListUtil; -import com.threerings.media.SafeScrollPane; - import com.threerings.presents.Log; import com.threerings.presents.dobj.AttributeChangeListener; import com.threerings.presents.dobj.AttributeChangedEvent; @@ -109,7 +108,7 @@ public class DSetEditor extends JPanel _table = new ObjectEditorTable(entryClass, editableFields, interp); - add(new SafeScrollPane(_table), BorderLayout.CENTER); + add(new JScrollPane(_table), BorderLayout.CENTER); } /** diff --git a/src/java/com/threerings/cast/ActionCache.java b/src/java/com/threerings/cast/ActionCache.java deleted file mode 100644 index 797c945d0..000000000 --- a/src/java/com/threerings/cast/ActionCache.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 27028f3cf..000000000 --- a/src/java/com/threerings/cast/ActionFrames.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $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.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 deleted file mode 100644 index ae274e5c5..000000000 --- a/src/java/com/threerings/cast/ActionSequence.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 4260a4ae7..000000000 --- a/src/java/com/threerings/cast/CastPrefs.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8e2df3d2f..000000000 --- a/src/java/com/threerings/cast/CharacterComponent.java +++ /dev/null @@ -1,100 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9f02762e0..000000000 --- a/src/java/com/threerings/cast/CharacterDescriptor.java +++ /dev/null @@ -1,144 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fb5008c62..000000000 --- a/src/java/com/threerings/cast/CharacterManager.java +++ /dev/null @@ -1,430 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 59811c8d5..000000000 --- a/src/java/com/threerings/cast/CharacterSprite.java +++ /dev/null @@ -1,402 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 65d3d6cf3..000000000 --- a/src/java/com/threerings/cast/ComponentClass.java +++ /dev/null @@ -1,241 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 889e2a2f1..000000000 --- a/src/java/com/threerings/cast/ComponentIDBroker.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 32c019042..000000000 --- a/src/java/com/threerings/cast/ComponentRepository.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 17bb23f22..000000000 --- a/src/java/com/threerings/cast/CompositedActionFrames.java +++ /dev/null @@ -1,186 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 21d31e895..000000000 --- a/src/java/com/threerings/cast/CompositedMaskedImage.java +++ /dev/null @@ -1,131 +0,0 @@ -// -// $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 deleted file mode 100644 index b30bd19e0..000000000 --- a/src/java/com/threerings/cast/CompositedMultiFrameImage.java +++ /dev/null @@ -1,254 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 3c75d8c3b..000000000 --- a/src/java/com/threerings/cast/CompositedShadowImage.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $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 deleted file mode 100644 index 02885de3d..000000000 --- a/src/java/com/threerings/cast/FrameProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f7ad622af..000000000 --- a/src/java/com/threerings/cast/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.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 deleted file mode 100644 index bfd76a5d1..000000000 --- a/src/java/com/threerings/cast/NoSuchComponentException.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 322aaf867..000000000 --- a/src/java/com/threerings/cast/StandardActions.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 14bf3fd1e..000000000 --- a/src/java/com/threerings/cast/TrimmedMultiFrameImage.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// $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.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 deleted file mode 100644 index cee526384..000000000 --- a/src/java/com/threerings/cast/builder/BuilderModel.java +++ /dev/null @@ -1,151 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1fec99617..000000000 --- a/src/java/com/threerings/cast/builder/BuilderModelListener.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d0cf3c0f1..000000000 --- a/src/java/com/threerings/cast/builder/BuilderPanel.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 32222aafd..000000000 --- a/src/java/com/threerings/cast/builder/ClassEditor.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fbb0746f5..000000000 --- a/src/java/com/threerings/cast/builder/ComponentPanel.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a1a097ced..000000000 --- a/src/java/com/threerings/cast/builder/SpritePanel.java +++ /dev/null @@ -1,131 +0,0 @@ -// -// $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.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 deleted file mode 100644 index de3c6e96a..000000000 --- a/src/java/com/threerings/cast/bundle/BundleUtil.java +++ /dev/null @@ -1,110 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c35908cad..000000000 --- a/src/java/com/threerings/cast/bundle/BundledComponentRepository.java +++ /dev/null @@ -1,528 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 51a163649..000000000 --- a/src/java/com/threerings/cast/bundle/tools/ComponentBundlerTask.java +++ /dev/null @@ -1,624 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 29759e5ff..000000000 --- a/src/java/com/threerings/cast/bundle/tools/DumpBundle.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 566848f44..000000000 --- a/src/java/com/threerings/cast/bundle/tools/MetadataBundlerTask.java +++ /dev/null @@ -1,267 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0bd67b561..000000000 --- a/src/java/com/threerings/cast/tools/xml/ActionRuleSet.java +++ /dev/null @@ -1,146 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8816055c7..000000000 --- a/src/java/com/threerings/cast/tools/xml/ClassRuleSet.java +++ /dev/null @@ -1,110 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1b6b70a42..000000000 --- a/src/java/com/threerings/cast/util/CastUtil.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c81ba9d95..000000000 --- a/src/java/com/threerings/geom/GeomUtil.java +++ /dev/null @@ -1,251 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6a90f8b5f..000000000 --- a/src/java/com/threerings/geom/Log.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d80cc5d29..000000000 --- a/src/java/com/threerings/jme/JmeApp.java +++ /dev/null @@ -1,582 +0,0 @@ -// -// $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 deleted file mode 100644 index 3e7faf587..000000000 --- a/src/java/com/threerings/jme/JmeCanvasApp.java +++ /dev/null @@ -1,184 +0,0 @@ -// -// $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 deleted file mode 100644 index 6dcc4c329..000000000 --- a/src/java/com/threerings/jme/JmeContext.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// $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 deleted file mode 100644 index da1cee03f..000000000 --- a/src/java/com/threerings/jme/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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 deleted file mode 100644 index c03d3ff8d..000000000 --- a/src/java/com/threerings/jme/StatsDisplay.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $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 deleted file mode 100644 index bdb362d85..000000000 --- a/src/java/com/threerings/jme/camera/CameraHandler.java +++ /dev/null @@ -1,412 +0,0 @@ -// -// $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 deleted file mode 100644 index 3837b6035..000000000 --- a/src/java/com/threerings/jme/camera/CameraPath.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// $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 deleted file mode 100644 index 68c4ec2cc..000000000 --- a/src/java/com/threerings/jme/camera/GodViewHandler.java +++ /dev/null @@ -1,191 +0,0 @@ -// -// $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 deleted file mode 100644 index ac3fd9dfd..000000000 --- a/src/java/com/threerings/jme/camera/PanPath.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// $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 deleted file mode 100644 index b29697cbe..000000000 --- a/src/java/com/threerings/jme/camera/SplinePath.java +++ /dev/null @@ -1,113 +0,0 @@ -// -// $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 deleted file mode 100644 index 16836136f..000000000 --- a/src/java/com/threerings/jme/camera/SwingPath.java +++ /dev/null @@ -1,168 +0,0 @@ -// -// $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 deleted file mode 100644 index 603bd5cc9..000000000 Binary files a/src/java/com/threerings/jme/camera/rotate_zoom.dia and /dev/null differ diff --git a/src/java/com/threerings/jme/camera/rotate_zoom.png b/src/java/com/threerings/jme/camera/rotate_zoom.png deleted file mode 100644 index 82ce4f88a..000000000 Binary files a/src/java/com/threerings/jme/camera/rotate_zoom.png and /dev/null differ diff --git a/src/java/com/threerings/jme/chat/ChatView.java b/src/java/com/threerings/jme/chat/ChatView.java deleted file mode 100644 index 6a6a4be86..000000000 --- a/src/java/com/threerings/jme/chat/ChatView.java +++ /dev/null @@ -1,181 +0,0 @@ -// -// $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.chat; - -import java.util.StringTokenizer; - -import com.jmex.bui.BContainer; -import com.jmex.bui.BTextArea; -import com.jmex.bui.BTextField; -import com.jmex.bui.event.ActionEvent; -import com.jmex.bui.event.ActionListener; -import com.jmex.bui.layout.BorderLayout; - -import com.jme.renderer.ColorRGBA; - -import com.threerings.util.Name; - -import com.threerings.crowd.chat.client.ChatDirector; -import com.threerings.crowd.chat.client.ChatDisplay; -import com.threerings.crowd.chat.client.SpeakService; -import com.threerings.crowd.chat.data.ChatCodes; -import com.threerings.crowd.chat.data.ChatMessage; -import com.threerings.crowd.chat.data.SystemMessage; -import com.threerings.crowd.chat.data.UserMessage; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.jme.JmeContext; -import com.threerings.jme.Log; - -/** - * Displays chat messages and allows for their input. - */ -public class ChatView extends BContainer - implements ChatDisplay -{ - public ChatView (JmeContext ctx, ChatDirector chatdtr) - { - _chatdtr = chatdtr; - setLayoutManager(new BorderLayout(2, 2)); - add(_text = new BTextArea(), BorderLayout.CENTER); - add(_input = new BTextField(), BorderLayout.SOUTH); - - _input.addListener(new ActionListener() { - public void actionPerformed (ActionEvent event) { - if (handleInput(_input.getText())) { - _input.setText(""); - } - } - }); - } - - public void willEnterPlace (PlaceObject plobj) - { - setSpeakService(plobj.speakService); - } - - public void didLeavePlace (PlaceObject plobj) - { - clearSpeakService(); - } - - public void setSpeakService (SpeakService spsvc) - { - if (spsvc != null) { - _spsvc = spsvc; - _chatdtr.addChatDisplay(this); - } - } - - public void clearSpeakService () - { - if (_spsvc != null) { - _chatdtr.removeChatDisplay(this); - _spsvc = null; - } - } - - /** - * Instructs our chat input field to request focus. - */ - public void requestFocus () - { - _input.requestFocus(); - } - - // documentation inherited from interface ChatDisplay - public void clear () - { - } - - // documentation inherited from interface ChatDisplay - public void displayMessage (ChatMessage msg) - { - // we may be restricted in the chat types we handle - if (!handlesType(msg.localtype)) { - return; - } - - if (msg instanceof UserMessage) { - UserMessage umsg = (UserMessage) msg; - if (umsg.localtype == ChatCodes.USER_CHAT_TYPE) { - append("[" + umsg.speaker + " whispers] ", ColorRGBA.green); - append(umsg.message + "\n"); - } else { - append("<" + umsg.speaker + "> ", 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 deleted file mode 100644 index 9898dd651..000000000 --- a/src/java/com/threerings/jme/effect/FadeInOutEffect.java +++ /dev/null @@ -1,148 +0,0 @@ -// -// $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 deleted file mode 100644 index f8d6151f4..000000000 --- a/src/java/com/threerings/jme/effect/WindowSlider.java +++ /dev/null @@ -1,127 +0,0 @@ -// -// $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 deleted file mode 100644 index 26907cdb1..000000000 --- a/src/java/com/threerings/jme/model/EmissionController.java +++ /dev/null @@ -1,79 +0,0 @@ -// -// $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 deleted file mode 100644 index d4bf1b904..000000000 --- a/src/java/com/threerings/jme/model/Model.java +++ /dev/null @@ -1,1036 +0,0 @@ -// -// $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 deleted file mode 100644 index f129c7f71..000000000 --- a/src/java/com/threerings/jme/model/ModelController.java +++ /dev/null @@ -1,167 +0,0 @@ -// -// $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 deleted file mode 100644 index fdb936a60..000000000 --- a/src/java/com/threerings/jme/model/ModelMesh.java +++ /dev/null @@ -1,557 +0,0 @@ -// -// $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 deleted file mode 100644 index 9af6b79e0..000000000 --- a/src/java/com/threerings/jme/model/ModelNode.java +++ /dev/null @@ -1,407 +0,0 @@ -// -// $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 deleted file mode 100644 index bb85ce6d7..000000000 --- a/src/java/com/threerings/jme/model/ModelSpatial.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $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 deleted file mode 100644 index e99da213f..000000000 --- a/src/java/com/threerings/jme/model/Rotator.java +++ /dev/null @@ -1,128 +0,0 @@ -// -// $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 deleted file mode 100644 index e9a21e83a..000000000 --- a/src/java/com/threerings/jme/model/SkinMesh.java +++ /dev/null @@ -1,495 +0,0 @@ -// -// $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 deleted file mode 100644 index 9734f7ad2..000000000 --- a/src/java/com/threerings/jme/model/TextureProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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 deleted file mode 100644 index e6df5fa9c..000000000 --- a/src/java/com/threerings/jme/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - 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 deleted file mode 100644 index 51ad7b83a..000000000 --- a/src/java/com/threerings/jme/sprite/BallisticPath.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $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 deleted file mode 100644 index dc973cd48..000000000 --- a/src/java/com/threerings/jme/sprite/LinePath.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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 deleted file mode 100644 index 9d62f4f90..000000000 --- a/src/java/com/threerings/jme/sprite/LineSegmentPath.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// $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 deleted file mode 100644 index 7f85b38df..000000000 --- a/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// $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 deleted file mode 100644 index 3693d0f5d..000000000 --- a/src/java/com/threerings/jme/sprite/Path.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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 deleted file mode 100644 index 597bb22ec..000000000 --- a/src/java/com/threerings/jme/sprite/PathObserver.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $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 deleted file mode 100644 index 7512377d9..000000000 --- a/src/java/com/threerings/jme/sprite/PathUtil.java +++ /dev/null @@ -1,95 +0,0 @@ -// -// $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 deleted file mode 100644 index 8261cf2f3..000000000 --- a/src/java/com/threerings/jme/sprite/Sprite.java +++ /dev/null @@ -1,244 +0,0 @@ -// -// $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 deleted file mode 100644 index 4b1249e72..000000000 --- a/src/java/com/threerings/jme/sprite/SpriteObserver.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// $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 deleted file mode 100644 index ba7ca2ee0..000000000 --- a/src/java/com/threerings/jme/tile/FringeConfiguration.java +++ /dev/null @@ -1,160 +0,0 @@ -// -// $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 deleted file mode 100644 index 6ddb7521d..000000000 --- a/src/java/com/threerings/jme/tile/TileFringer.java +++ /dev/null @@ -1,404 +0,0 @@ -// -// $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 deleted file mode 100644 index 6e220862f..000000000 --- a/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// $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 deleted file mode 100644 index a769ef5ce..000000000 --- a/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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 deleted file mode 100644 index 709e91174..000000000 --- a/src/java/com/threerings/jme/tools/AnimationDef.java +++ /dev/null @@ -1,165 +0,0 @@ -// -// $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 deleted file mode 100644 index a147893c4..000000000 --- a/src/java/com/threerings/jme/tools/BuildSphereMap.java +++ /dev/null @@ -1,167 +0,0 @@ -// -// $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 deleted file mode 100644 index 27ad058a8..000000000 --- a/src/java/com/threerings/jme/tools/BuildSphereMapTask.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $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 deleted file mode 100644 index 8e5536eaf..000000000 --- a/src/java/com/threerings/jme/tools/CompileModel.java +++ /dev/null @@ -1,139 +0,0 @@ -// -// $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 deleted file mode 100644 index 2e16bc5bd..000000000 --- a/src/java/com/threerings/jme/tools/CompileModelTask.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// $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 deleted file mode 100644 index 20e9895f6..000000000 --- a/src/java/com/threerings/jme/tools/ConvertModel.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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 deleted file mode 100644 index f59bc9ad2..000000000 --- a/src/java/com/threerings/jme/tools/ConvertModelTask.java +++ /dev/null @@ -1,135 +0,0 @@ -// -// $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 deleted file mode 100644 index 84f2f3fd0..000000000 --- a/src/java/com/threerings/jme/tools/ModelDef.java +++ /dev/null @@ -1,573 +0,0 @@ -// -// $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 deleted file mode 100644 index b4f45dd8f..000000000 --- a/src/java/com/threerings/jme/tools/ModelViewer.java +++ /dev/null @@ -1,1019 +0,0 @@ -// -// $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 deleted file mode 100644 index 5da48a964..000000000 --- a/src/java/com/threerings/jme/tools/xml/AnimationParser.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// $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 deleted file mode 100644 index e55469fa3..000000000 --- a/src/java/com/threerings/jme/tools/xml/ModelParser.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $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 deleted file mode 100644 index d29ccd7ad..000000000 --- a/src/java/com/threerings/jme/util/LinearTimeFunction.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $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 deleted file mode 100644 index 73afaa0f5..000000000 --- a/src/java/com/threerings/jme/util/TimeFunction.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// $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 deleted file mode 100644 index d8110ca73..000000000 --- a/src/java/com/threerings/media/AbstractMedia.java +++ /dev/null @@ -1,332 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 06978e4a5..000000000 --- a/src/java/com/threerings/media/AbstractMediaManager.java +++ /dev/null @@ -1,335 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9ee0703f2..000000000 --- a/src/java/com/threerings/media/ActiveRepaintManager.java +++ /dev/null @@ -1,502 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 4d2144bca..000000000 --- a/src/java/com/threerings/media/BackFrameManager.java +++ /dev/null @@ -1,148 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f6d0ef5ea..000000000 --- a/src/java/com/threerings/media/FlipFrameManager.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f168c3960..000000000 --- a/src/java/com/threerings/media/FrameInterval.java +++ /dev/null @@ -1,111 +0,0 @@ -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 deleted file mode 100644 index 7fa420858..000000000 --- a/src/java/com/threerings/media/FrameManager.java +++ /dev/null @@ -1,846 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0537025d2..000000000 --- a/src/java/com/threerings/media/FrameParticipant.java +++ /dev/null @@ -1,64 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 50dc608cc..000000000 --- a/src/java/com/threerings/media/HourglassView.java +++ /dev/null @@ -1,175 +0,0 @@ -// -// $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 deleted file mode 100644 index 1a607eff8..000000000 --- a/src/java/com/threerings/media/IconManager.java +++ /dev/null @@ -1,183 +0,0 @@ -// -// $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.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 deleted file mode 100644 index eb4df3a4f..000000000 --- a/src/java/com/threerings/media/Log.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// $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; - -/** - * 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 deleted file mode 100644 index 728e9b4ce..000000000 --- a/src/java/com/threerings/media/ManagedJFrame.java +++ /dev/null @@ -1,117 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fd40235ae..000000000 --- a/src/java/com/threerings/media/MediaConstants.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// $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; - -/** - * 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 deleted file mode 100644 index fd75c3e91..000000000 --- a/src/java/com/threerings/media/MediaPanel.java +++ /dev/null @@ -1,783 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b54300d6a..000000000 --- a/src/java/com/threerings/media/MediaPrefs.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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 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 deleted file mode 100644 index 472d9004b..000000000 --- a/src/java/com/threerings/media/RegionManager.java +++ /dev/null @@ -1,165 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0d97fe26d..000000000 --- a/src/java/com/threerings/media/SafeScrollPane.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c3767e328..000000000 --- a/src/java/com/threerings/media/TimerView.java +++ /dev/null @@ -1,513 +0,0 @@ -// -// $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 deleted file mode 100644 index cc28985da..000000000 --- a/src/java/com/threerings/media/ViewTracker.java +++ /dev/null @@ -1,18 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index aed9a3503..000000000 --- a/src/java/com/threerings/media/VirtualMediaPanel.java +++ /dev/null @@ -1,463 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fdc80c01b..000000000 --- a/src/java/com/threerings/media/VirtualRangeModel.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $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 deleted file mode 100644 index 1f93ab9d4..000000000 --- a/src/java/com/threerings/media/animation/Animation.java +++ /dev/null @@ -1,169 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0ef5578f3..000000000 --- a/src/java/com/threerings/media/animation/AnimationAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fafd0b4c1..000000000 --- a/src/java/com/threerings/media/animation/AnimationArranger.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// $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 deleted file mode 100644 index e575eeff1..000000000 --- a/src/java/com/threerings/media/animation/AnimationFrameSequencer.java +++ /dev/null @@ -1,260 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 906095ed4..000000000 --- a/src/java/com/threerings/media/animation/AnimationManager.java +++ /dev/null @@ -1,81 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 265b315df..000000000 --- a/src/java/com/threerings/media/animation/AnimationObserver.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 592140a69..000000000 --- a/src/java/com/threerings/media/animation/AnimationSequencer.java +++ /dev/null @@ -1,295 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 36d953fb9..000000000 --- a/src/java/com/threerings/media/animation/AnimationWaiter.java +++ /dev/null @@ -1,95 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 259bd2cb9..000000000 --- a/src/java/com/threerings/media/animation/BlankAnimation.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f8fef1dec..000000000 --- a/src/java/com/threerings/media/animation/BlendAnimation.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index c5715e82f..000000000 --- a/src/java/com/threerings/media/animation/BobbleAnimation.java +++ /dev/null @@ -1,120 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 458703e02..000000000 --- a/src/java/com/threerings/media/animation/ExplodeAnimation.java +++ /dev/null @@ -1,336 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c276a0931..000000000 --- a/src/java/com/threerings/media/animation/FadeAnimation.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 11814efbd..000000000 --- a/src/java/com/threerings/media/animation/FadeImageAnimation.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// $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 deleted file mode 100644 index 688378837..000000000 --- a/src/java/com/threerings/media/animation/FadeLabelAnimation.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// $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 deleted file mode 100644 index d0f25131f..000000000 --- a/src/java/com/threerings/media/animation/FloatingTextAnimation.java +++ /dev/null @@ -1,248 +0,0 @@ -// -// $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 deleted file mode 100644 index c53628d10..000000000 --- a/src/java/com/threerings/media/animation/GleamAnimation.java +++ /dev/null @@ -1,150 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index ae631ba92..000000000 --- a/src/java/com/threerings/media/animation/MultiFrameAnimation.java +++ /dev/null @@ -1,134 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c3714de9f..000000000 --- a/src/java/com/threerings/media/animation/RainAnimation.java +++ /dev/null @@ -1,134 +0,0 @@ -// -// $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.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 deleted file mode 100644 index bc6127529..000000000 --- a/src/java/com/threerings/media/animation/ScaleAnimation.java +++ /dev/null @@ -1,192 +0,0 @@ -// -// $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 deleted file mode 100644 index a77f52aaa..000000000 --- a/src/java/com/threerings/media/animation/SequencedAnimationObserver.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6f278c99a..000000000 --- a/src/java/com/threerings/media/animation/SparkAnimation.java +++ /dev/null @@ -1,257 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 22c8ed165..000000000 --- a/src/java/com/threerings/media/animation/SpriteAnimation.java +++ /dev/null @@ -1,102 +0,0 @@ -// -// $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.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 deleted file mode 100644 index e475b4ef7..000000000 --- a/src/java/com/threerings/media/effects/FadeEffect.java +++ /dev/null @@ -1,125 +0,0 @@ -// -// $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 deleted file mode 100644 index 92cbfeb6a..000000000 --- a/src/java/com/threerings/media/image/AWTImageCreator.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// $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 deleted file mode 100644 index 8ddf0aa34..000000000 --- a/src/java/com/threerings/media/image/BackedVolatileMirage.java +++ /dev/null @@ -1,82 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0e7482dcb..000000000 --- a/src/java/com/threerings/media/image/BlankMirage.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9413020cf..000000000 --- a/src/java/com/threerings/media/image/BufferedMirage.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 5e75d97c8..000000000 --- a/src/java/com/threerings/media/image/CachedVolatileMirage.java +++ /dev/null @@ -1,104 +0,0 @@ -// -// $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.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 deleted file mode 100644 index bf56b74e0..000000000 --- a/src/java/com/threerings/media/image/ColorPository.java +++ /dev/null @@ -1,461 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 5f5e91837..000000000 --- a/src/java/com/threerings/media/image/ColorUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0f502dce6..000000000 --- a/src/java/com/threerings/media/image/Colorization.java +++ /dev/null @@ -1,194 +0,0 @@ -// -// $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.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 deleted file mode 100644 index e1a18a160..000000000 --- a/src/java/com/threerings/media/image/CompositeMirage.java +++ /dev/null @@ -1,96 +0,0 @@ -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 deleted file mode 100644 index a07882658..000000000 --- a/src/java/com/threerings/media/image/FastImageIO.java +++ /dev/null @@ -1,174 +0,0 @@ -// -// $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.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 deleted file mode 100644 index dfe0a03be..000000000 --- a/src/java/com/threerings/media/image/ImageDataProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 66cb1161e..000000000 --- a/src/java/com/threerings/media/image/ImageManager.java +++ /dev/null @@ -1,615 +0,0 @@ -// -// $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.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 deleted file mode 100644 index db173e407..000000000 --- a/src/java/com/threerings/media/image/ImageUtil.java +++ /dev/null @@ -1,647 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f5567fc62..000000000 --- a/src/java/com/threerings/media/image/Mirage.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 2fd1fc43a..000000000 --- a/src/java/com/threerings/media/image/MirageIcon.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8a6cfeccd..000000000 --- a/src/java/com/threerings/media/image/Quantize.java +++ /dev/null @@ -1,776 +0,0 @@ -// -// $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 deleted file mode 100644 index 87e06fa28..000000000 --- a/src/java/com/threerings/media/image/TransformedMirage.java +++ /dev/null @@ -1,145 +0,0 @@ -// -// $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 deleted file mode 100644 index a56647c54..000000000 --- a/src/java/com/threerings/media/image/VolatileMirage.java +++ /dev/null @@ -1,202 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1715a0375..000000000 --- a/src/java/com/threerings/media/image/tools/DumpColorPository.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6d47d095f..000000000 --- a/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 695ed4458..000000000 --- a/src/java/com/threerings/media/sound/MidiPlayer.java +++ /dev/null @@ -1,178 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d2d01e432..000000000 --- a/src/java/com/threerings/media/sound/ModPlayer.java +++ /dev/null @@ -1,135 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 123c8cab8..000000000 --- a/src/java/com/threerings/media/sound/Mp3Player.java +++ /dev/null @@ -1,148 +0,0 @@ -// -// $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.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 deleted file mode 100644 index caa03ff96..000000000 --- a/src/java/com/threerings/media/sound/MusicManager.java +++ /dev/null @@ -1,353 +0,0 @@ -// -// $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 deleted file mode 100644 index e7259a543..000000000 --- a/src/java/com/threerings/media/sound/MusicPlayer.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 53882c109..000000000 --- a/src/java/com/threerings/media/sound/OggPlayer.java +++ /dev/null @@ -1,401 +0,0 @@ -// -// $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.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 deleted file mode 100644 index aad78510b..000000000 --- a/src/java/com/threerings/media/sound/SoundCodes.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 3a3900d11..000000000 --- a/src/java/com/threerings/media/sound/SoundManager.java +++ /dev/null @@ -1,1044 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a92b53ff8..000000000 --- a/src/java/com/threerings/media/sound/Sounds.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 437fc2fef..000000000 --- a/src/java/com/threerings/media/sprite/ButtonSprite.java +++ /dev/null @@ -1,384 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6d9a5be0b..000000000 --- a/src/java/com/threerings/media/sprite/FadableImageSprite.java +++ /dev/null @@ -1,203 +0,0 @@ -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 deleted file mode 100644 index 64e954ffd..000000000 --- a/src/java/com/threerings/media/sprite/ImageSprite.java +++ /dev/null @@ -1,331 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 905927e9c..000000000 --- a/src/java/com/threerings/media/sprite/LabelSprite.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 84b44fd23..000000000 --- a/src/java/com/threerings/media/sprite/OrientableImageSprite.java +++ /dev/null @@ -1,198 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 513a8c183..000000000 --- a/src/java/com/threerings/media/sprite/PathAdapter.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 3660ec103..000000000 --- a/src/java/com/threerings/media/sprite/PathObserver.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 03f54048b..000000000 --- a/src/java/com/threerings/media/sprite/Sprite.java +++ /dev/null @@ -1,462 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 20671a19e..000000000 --- a/src/java/com/threerings/media/sprite/SpriteIcon.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6172be91a..000000000 --- a/src/java/com/threerings/media/sprite/SpriteManager.java +++ /dev/null @@ -1,269 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 30bb61587..000000000 --- a/src/java/com/threerings/media/sprite/action/ActionSprite.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $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 deleted file mode 100644 index 8d0763f3c..000000000 --- a/src/java/com/threerings/media/sprite/action/ArmingSprite.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $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 deleted file mode 100644 index 8384be2b4..000000000 --- a/src/java/com/threerings/media/sprite/action/CommandSprite.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $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 deleted file mode 100644 index c19a7d8b9..000000000 --- a/src/java/com/threerings/media/sprite/action/DisableableSprite.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $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 deleted file mode 100644 index 409da3da6..000000000 --- a/src/java/com/threerings/media/sprite/action/HoverSprite.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $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 deleted file mode 100644 index cc7dd916c..000000000 --- a/src/java/com/threerings/media/tile/IMImageProvider.java +++ /dev/null @@ -1,73 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 354cc5bad..000000000 --- a/src/java/com/threerings/media/tile/ImageProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -// -// $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.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 deleted file mode 100644 index adac22b79..000000000 --- a/src/java/com/threerings/media/tile/NoSuchTileSetException.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 56c3dd1ee..000000000 --- a/src/java/com/threerings/media/tile/ObjectTile.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9e9a8f782..000000000 --- a/src/java/com/threerings/media/tile/ObjectTileSet.java +++ /dev/null @@ -1,295 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0f709c31a..000000000 --- a/src/java/com/threerings/media/tile/RecolorableTileSet.java +++ /dev/null @@ -1,16 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index 2549da230..000000000 --- a/src/java/com/threerings/media/tile/SimpleCachingImageProvider.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// $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.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 deleted file mode 100644 index cba679f7a..000000000 --- a/src/java/com/threerings/media/tile/SwissArmyTileSet.java +++ /dev/null @@ -1,207 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 84c1000a6..000000000 --- a/src/java/com/threerings/media/tile/Tile.java +++ /dev/null @@ -1,178 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c8399d78e..000000000 --- a/src/java/com/threerings/media/tile/TileIcon.java +++ /dev/null @@ -1,64 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 3b5d46b46..000000000 --- a/src/java/com/threerings/media/tile/TileManager.java +++ /dev/null @@ -1,247 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b28f8740a..000000000 --- a/src/java/com/threerings/media/tile/TileMultiFrameImage.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c6992e880..000000000 --- a/src/java/com/threerings/media/tile/TileSet.java +++ /dev/null @@ -1,454 +0,0 @@ -// -// $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.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 deleted file mode 100644 index ae4880c0c..000000000 --- a/src/java/com/threerings/media/tile/TileSetIDBroker.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 69ab95f68..000000000 --- a/src/java/com/threerings/media/tile/TileSetRepository.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 46b780193..000000000 --- a/src/java/com/threerings/media/tile/TileUtil.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 7bc0204fb..000000000 --- a/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java +++ /dev/null @@ -1,301 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8e853e2e3..000000000 --- a/src/java/com/threerings/media/tile/TrimmedTile.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a2df0a95a..000000000 --- a/src/java/com/threerings/media/tile/TrimmedTileSet.java +++ /dev/null @@ -1,114 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6e9b1ae17..000000000 --- a/src/java/com/threerings/media/tile/UniformTileSet.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d69f58be1..000000000 --- a/src/java/com/threerings/media/tile/bundle/BundleUtil.java +++ /dev/null @@ -1,82 +0,0 @@ -// -// $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.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 deleted file mode 100644 index feaaf1135..000000000 --- a/src/java/com/threerings/media/tile/bundle/BundledTileSetRepository.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f4db2b417..000000000 --- a/src/java/com/threerings/media/tile/bundle/TileSetBundle.java +++ /dev/null @@ -1,148 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 837d33d21..000000000 --- a/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java +++ /dev/null @@ -1,93 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 70ec79b12..000000000 --- a/src/java/com/threerings/media/tile/bundle/tools/TileSetBundler.java +++ /dev/null @@ -1,482 +0,0 @@ -// -// $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.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 deleted file mode 100644 index ea463c3d0..000000000 --- a/src/java/com/threerings/media/tile/bundle/tools/TileSetBundlerTask.java +++ /dev/null @@ -1,143 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 797fb6fe3..000000000 --- a/src/java/com/threerings/media/tile/tools/DumpTileSetMap.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c0425ddc1..000000000 --- a/src/java/com/threerings/media/tile/tools/MapFileTileSetIDBroker.java +++ /dev/null @@ -1,224 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 66b207282..000000000 --- a/src/java/com/threerings/media/tile/tools/RenameTileSet.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 3440996a6..000000000 --- a/src/java/com/threerings/media/tile/tools/xml/ObjectTileSetRuleSet.java +++ /dev/null @@ -1,188 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 691f94f8b..000000000 --- a/src/java/com/threerings/media/tile/tools/xml/SwissArmyTileSetRuleSet.java +++ /dev/null @@ -1,156 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8c159e8ae..000000000 --- a/src/java/com/threerings/media/tile/tools/xml/TileSetRuleSet.java +++ /dev/null @@ -1,128 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8e9012b32..000000000 --- a/src/java/com/threerings/media/tile/tools/xml/UniformTileSetRuleSet.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 16fd6eb0b..000000000 --- a/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParser.java +++ /dev/null @@ -1,172 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1e13c4d6d..000000000 --- a/src/java/com/threerings/media/tile/util/TileSetTrimmer.java +++ /dev/null @@ -1,146 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 91496a4e1..000000000 --- a/src/java/com/threerings/media/timer/MediaTimer.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 067721a96..000000000 --- a/src/java/com/threerings/media/timer/PerfTimer.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 398701168..000000000 --- a/src/java/com/threerings/media/timer/SystemMediaTimer.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 47cc74292..000000000 --- a/src/java/com/threerings/media/tools/RecolorImage.java +++ /dev/null @@ -1,476 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1d4035366..000000000 --- a/src/java/com/threerings/media/util/AStarPathUtil.java +++ /dev/null @@ -1,437 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 34d094029..000000000 --- a/src/java/com/threerings/media/util/ArcPath.java +++ /dev/null @@ -1,238 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 69892bfed..000000000 --- a/src/java/com/threerings/media/util/BackgroundTiler.java +++ /dev/null @@ -1,208 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c6282f66f..000000000 --- a/src/java/com/threerings/media/util/BobblePath.java +++ /dev/null @@ -1,191 +0,0 @@ -// -// $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.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 deleted file mode 100644 index ef83b4824..000000000 --- a/src/java/com/threerings/media/util/DelayPath.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// $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 deleted file mode 100644 index 4fe50beae..000000000 --- a/src/java/com/threerings/media/util/DelegatingPathable.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// $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.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 deleted file mode 100644 index ed1919066..000000000 --- a/src/java/com/threerings/media/util/FrameSequencer.java +++ /dev/null @@ -1,113 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 814abb2a1..000000000 --- a/src/java/com/threerings/media/util/LinePath.java +++ /dev/null @@ -1,151 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 016208354..000000000 --- a/src/java/com/threerings/media/util/LineSegmentPath.java +++ /dev/null @@ -1,388 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 7876947d9..000000000 --- a/src/java/com/threerings/media/util/LinearTimeFunction.java +++ /dev/null @@ -1,22 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index 298313077..000000000 --- a/src/java/com/threerings/media/util/MathUtil.java +++ /dev/null @@ -1,162 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b7349b906..000000000 --- a/src/java/com/threerings/media/util/ModeUtil.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8f30fb829..000000000 --- a/src/java/com/threerings/media/util/MultiFrameImage.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 45bf2565b..000000000 --- a/src/java/com/threerings/media/util/MultiFrameImageImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 53a2e80fe..000000000 --- a/src/java/com/threerings/media/util/Path.java +++ /dev/null @@ -1,82 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9b7663697..000000000 --- a/src/java/com/threerings/media/util/PathNode.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// $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.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 deleted file mode 100644 index cc5258495..000000000 --- a/src/java/com/threerings/media/util/PathSequence.java +++ /dev/null @@ -1,143 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 2650c25b8..000000000 --- a/src/java/com/threerings/media/util/Pathable.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b158850a9..000000000 --- a/src/java/com/threerings/media/util/PerformanceMonitor.java +++ /dev/null @@ -1,215 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 419efac2f..000000000 --- a/src/java/com/threerings/media/util/PerformanceObserver.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 87eed8774..000000000 --- a/src/java/com/threerings/media/util/SingleFrameImageImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1c32276bc..000000000 --- a/src/java/com/threerings/media/util/SingleTileImageImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 2ba20b560..000000000 --- a/src/java/com/threerings/media/util/SmoothBobblePath.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $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 deleted file mode 100644 index c22a2eb3b..000000000 --- a/src/java/com/threerings/media/util/TiledArea.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 055b8b644..000000000 --- a/src/java/com/threerings/media/util/TimeFunction.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $Id$ - -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 deleted file mode 100644 index 548491c5e..000000000 --- a/src/java/com/threerings/media/util/TimedPath.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// $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.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 deleted file mode 100644 index abf562be3..000000000 --- a/src/java/com/threerings/media/util/TrailingAverage.java +++ /dev/null @@ -1,81 +0,0 @@ -// -// $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.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/micasa/Log.java b/src/java/com/threerings/micasa/Log.java deleted file mode 100644 index 338a8184a..000000000 --- a/src/java/com/threerings/micasa/Log.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// $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.micasa; - -/** - * A placeholder class that contains a reference to the log object used by - * the MiCasa package. This is a useful pattern to use when using the - * samskivert logging facilities. One creates a top-level class like this - * one that instantiates a log object with an name that identifies log - * messages from that package and then provides static methods that - * generate log messages using that instance. Then, classes in that - * package need only import the log wrapper class and can easily use it to - * generate log messages. For example: - * - *

- * import com.threerings.micasa.Log;
- * // ...
- * Log.warning("All hell is breaking loose!");
- * // ...
- * 
- * - * @see com.samskivert.util.Log - */ -public class Log -{ - /** The static log instance configured for use by this package. */ - public static com.samskivert.util.Log log = - new com.samskivert.util.Log("micasa"); - - /** 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/micasa/client/ChatPanel.java b/src/java/com/threerings/micasa/client/ChatPanel.java deleted file mode 100644 index ac3b3b14d..000000000 --- a/src/java/com/threerings/micasa/client/ChatPanel.java +++ /dev/null @@ -1,336 +0,0 @@ -// -// $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.micasa.client; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import java.util.StringTokenizer; - -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; -import javax.swing.JTextPane; - -import javax.swing.event.AncestorEvent; -import javax.swing.event.AncestorListener; - -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Style; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyleContext; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; -import com.samskivert.swing.event.AncestorAdapter; - -import com.threerings.util.Name; - -import com.threerings.crowd.chat.client.ChatDirector; -import com.threerings.crowd.chat.client.ChatDisplay; -import com.threerings.crowd.chat.data.ChatCodes; -import com.threerings.crowd.chat.data.ChatMessage; -import com.threerings.crowd.chat.data.SystemMessage; -import com.threerings.crowd.chat.data.UserMessage; - -import com.threerings.crowd.client.OccupantObserver; -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.OccupantInfo; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.micasa.Log; - -public class ChatPanel - extends JPanel - implements ActionListener, ChatDisplay, OccupantObserver, PlaceView -{ - public ChatPanel (CrowdContext ctx) - { - // keep this around for later - _ctx = ctx; - - // create our chat director and register ourselves with it - _chatdtr = new ChatDirector(_ctx, null, null); - // XXX - the line above royally borks things because it sends - // null, null downstream. - _chatdtr.addChatDisplay(this); - - // register as an occupant observer - _ctx.getOccupantDirector().addOccupantObserver(this); - - GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - setLayout(gl); - - // create our scrolling chat text display - _text = new JTextPane(); - _text.setEditable(false); - add(new JScrollPane(_text)); - - // create our styles and add those to the text pane - createStyles(_text); - - // add a label for the text entry stuff - add(new JLabel("Type here to chat:"), GroupLayout.FIXED); - - // create a horizontal group for the text entry bar - gl = new HGroupLayout(GroupLayout.STRETCH); - JPanel epanel = new JPanel(gl); - epanel.add(_entry = new JTextField()); - _entry.setActionCommand("send"); - _entry.addActionListener(this); - _entry.setEnabled(false); - - _send = new JButton("Send"); - _send.setEnabled(false); - _send.addActionListener(this); - _send.setActionCommand("send"); - epanel.add(_send, GroupLayout.FIXED); - add(epanel, GroupLayout.FIXED); - - // listen to ancestor events to request focus when added - addAncestorListener(new AncestorAdapter() { - public void ancestorAdded (AncestorEvent e) { - if (_focus) { - _entry.requestFocusInWindow(); - } - } - }); - } - - /** - * For applications where the chat box has extremely limited space, - * the send button can be removed to leave more space for the text - * input box. - */ - public void removeSendButton () - { - if (_send.isVisible()) { - // _send.getParent().remove(_send); - _send.setVisible(false); - } - } - - /** - * Sets whether the chat box text entry field requests the keyboard - * focus when the panel receives {@link - * AncestorListener#ancestorAdded} or {@link PlaceView#willEnterPlace} - * events. - */ - public void setRequestFocus (boolean focus) - { - _focus = focus; - } - - protected void createStyles (JTextPane text) - { - StyleContext sctx = StyleContext.getDefaultStyleContext(); - Style defstyle = sctx.getStyle(StyleContext.DEFAULT_STYLE); - - _nameStyle = text.addStyle("name", defstyle); - StyleConstants.setForeground(_nameStyle, Color.blue); - - _msgStyle = text.addStyle("msg", defstyle); - StyleConstants.setForeground(_msgStyle, Color.black); - - _errStyle = text.addStyle("err", defstyle); - StyleConstants.setForeground(_errStyle, Color.red); - - _noticeStyle = text.addStyle("notice", defstyle); - StyleConstants.setForeground(_noticeStyle, Color.magenta); - } - - // documentation inherited - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - if (cmd.equals("send")) { - sendText(); - - } else { - System.out.println("Unknown action event: " + cmd); - } - } - - // documentation inherited - public void occupantEntered (OccupantInfo info) - { - displayOccupantMessage("*** " + info.username + " entered."); - } - - // documentation inherited - public void occupantLeft (OccupantInfo info) - { - displayOccupantMessage("*** " + info.username + " left."); - } - - // documentation inherited - public void occupantUpdated (OccupantInfo oinfo, OccupantInfo info) - { - } - - protected void displayOccupantMessage (String message) - { - append(message + "\n", _noticeStyle); - } - - protected void sendText () - { - String text = _entry.getText(); - - // if the message to send begins with /tell then parse it and - // generate a tell request rather than a speak request - if (text.startsWith("/tell")) { - StringTokenizer tok = new StringTokenizer(text); - // there should be at least three tokens: '/tell target word' - if (tok.countTokens() < 3) { - displayError("Usage: /tell username message"); - return; - } - - // skip the /tell and grab the username - tok.nextToken(); - String username = tok.nextToken(); - - // now strip off everything up to the username to get the - // message - int uidx = text.indexOf(username); - String message = text.substring(uidx + username.length()).trim(); - - // request to send this text as a tell message - _chatdtr.requestTell(new Name(username), message, null); - - } else if (text.startsWith("/clear")) { - // clear the chat box - _chatdtr.clearDisplays(); - - } else { - // request to send this text as a chat message - _chatdtr.requestSpeak(null, text, ChatCodes.DEFAULT_MODE); - } - - // clear out the input because we sent a request - _entry.setText(""); - } - - // documentation inherited from interface ChatDisplay - public void clear () - { - _text.setText(""); - } - - // documentation inherited from interface ChatDisplay - public void displayMessage (ChatMessage message) - { - if (message instanceof UserMessage) { - UserMessage msg = (UserMessage) message; - if (msg.localtype == ChatCodes.USER_CHAT_TYPE) { - append("[" + msg.speaker + " whispers] ", _nameStyle); - append(msg.message + "\n", _msgStyle); - } else { - append("<" + msg.speaker + "> ", _nameStyle); - append(msg.message + "\n", _msgStyle); - } - - } else if (message instanceof SystemMessage) { - append(message.message + "\n", _noticeStyle); - - } else { - Log.warning("Received unknown message type [message=" + - message + "]."); - } - } - - protected void displayError (String message) - { - append(message + "\n", _errStyle); - } - - /** - * Append the specified text in the specified style. - */ - protected void append (String text, Style style) - { - Document doc = _text.getDocument(); - try { - doc.insertString(doc.getLength(), text, style); - } catch (BadLocationException ble) { - Log.warning("Unable to insert text!? [error=" + ble + "]."); - } - } - - public void willEnterPlace (PlaceObject place) - { - // enable our chat input elements since we're now somewhere that - // we can chat - _entry.setEnabled(true); - _send.setEnabled(true); - if (_focus) { - _entry.requestFocusInWindow(); - } - } - - // documentation inherited - public void didLeavePlace (PlaceObject place) - { - // nothing doing - } - - // documentation inherited - public Dimension getPreferredSize () - { - Dimension size = super.getPreferredSize(); - // always prefer a sensible but not overly large width. this also - // prevents us from inheriting a foolishly large preferred width - // from the JTextPane which sometimes decides it wants to be as - // wide as its widest line of text rather than wrap that line of - // text. - size.width = PREFERRED_WIDTH; - return size; - } - - protected CrowdContext _ctx; - protected ChatDirector _chatdtr; - - protected boolean _focus = true; - - protected JComboBox _roombox; - protected JTextPane _text; - protected JButton _send; - protected JTextField _entry; - - protected Style _nameStyle; - protected Style _msgStyle; - protected Style _errStyle; - protected Style _noticeStyle; - - /** A width that isn't so skinny that the text is teeny. */ - protected static final int PREFERRED_WIDTH = 200; -} diff --git a/src/java/com/threerings/micasa/client/ClientController.java b/src/java/com/threerings/micasa/client/ClientController.java deleted file mode 100644 index 6b838ef7c..000000000 --- a/src/java/com/threerings/micasa/client/ClientController.java +++ /dev/null @@ -1,140 +0,0 @@ -// -// $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.micasa.client; - -import java.awt.event.ActionEvent; -import com.samskivert.swing.Controller; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.SessionObserver; - -import com.threerings.crowd.data.BodyObject; - -import com.threerings.micasa.Log; -import com.threerings.micasa.data.MiCasaBootstrapData; -import com.threerings.micasa.util.MiCasaContext; - -/** - * Responsible for top-level control of the client user interface. - */ -public class ClientController extends Controller - implements SessionObserver -{ - /** - * Creates a new client controller. The controller will set everything - * up in preparation for logging on. - */ - public ClientController (MiCasaContext ctx, MiCasaFrame frame) - { - // we'll want to keep these around - _ctx = ctx; - _frame = frame; - - // we want to know about logon/logoff - _ctx.getClient().addClientObserver(this); - - // create the logon panel and display it - _logonPanel = new LogonPanel(_ctx); - _frame.setPanel(_logonPanel); - } - - // documentation inherited - public boolean handleAction (ActionEvent action) - { - String cmd = action.getActionCommand(); - - if (cmd.equals("logoff")) { - // request that we logoff - _ctx.getClient().logoff(true); - return true; - } - - Log.info("Unhandled action: " + action); - return false; - } - - // documentation inherited - public void clientDidLogon (Client client) - { - Log.info("Client did logon [client=" + client + "]."); - - // keep the body object around for stuff - _body = (BodyObject)client.getClientObject(); - - // figure out where to go - int moveOid = -1; - - // hacky hack - String jumpOidStr = null; - try { - jumpOidStr = System.getProperty("jumpoid"); - } catch (SecurityException se) { - Log.info("Not checking for jumpOid as we're in an applet."); - } - - if (jumpOidStr != null) { - try { - moveOid = Integer.parseInt(jumpOidStr); - } catch (NumberFormatException nfe) { - Log.warning("Invalid jump oid [oid=" + jumpOidStr + - ", err=" + nfe + "]."); - } - - } else if (_body.location != -1) { - // if we were already in a location, go there - moveOid = _body.location; - - } else { - // otherwise head to the default lobby to start things off - MiCasaBootstrapData data = (MiCasaBootstrapData) - client.getBootstrapData(); - moveOid = data.defLobbyOid; - } - - if (moveOid > 0) { - _ctx.getLocationDirector().moveTo(moveOid); - } - } - - // documentation inherited - public void clientObjectDidChange (Client client) - { - // regrab our body object - _body = (BodyObject)client.getClientObject(); - } - - // documentation inherited - public void clientDidLogoff (Client client) - { - Log.info("Client did logoff [client=" + client + "]."); - - // reinstate the logon panel - _frame.setPanel(_logonPanel); - } - - protected MiCasaContext _ctx; - protected MiCasaFrame _frame; - protected BodyObject _body; - - // our panels - protected LogonPanel _logonPanel; -} diff --git a/src/java/com/threerings/micasa/client/LogonPanel.java b/src/java/com/threerings/micasa/client/LogonPanel.java deleted file mode 100644 index 38784f3be..000000000 --- a/src/java/com/threerings/micasa/client/LogonPanel.java +++ /dev/null @@ -1,234 +0,0 @@ -// -// $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.micasa.client; - -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.JTextField; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; - -import com.threerings.util.MessageBundle; -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.ClientObserver; -import com.threerings.presents.client.LogonException; -import com.threerings.presents.net.Credentials; -import com.threerings.presents.net.UsernamePasswordCreds; - -import com.threerings.micasa.util.MiCasaContext; - -public class LogonPanel extends JPanel - implements ActionListener, ClientObserver -{ - public LogonPanel (MiCasaContext ctx) - { - // keep these around for later - _ctx = ctx; - _msgs = _ctx.getMessageManager().getBundle("micasa"); - - setLayout(new VGroupLayout()); - - // stick the logon components into a panel that will stretch them - // to a sensible width - JPanel box = new JPanel( - new VGroupLayout(VGroupLayout.NONE, VGroupLayout.STRETCH, - 5, VGroupLayout.CENTER)) { - public Dimension getPreferredSize () { - Dimension psize = super.getPreferredSize(); - psize.width = Math.max(psize.width, 300); - return psize; - } - }; - add(box); - - // try obtaining our title text from a system property - String tstr = null; - try { - tstr = System.getProperty("logon.title"); - } catch (Throwable t) { - } - if (tstr == null) { - tstr = "Mi Casa!"; - } - - // create a big fat label - JLabel title = new JLabel(tstr, JLabel.CENTER); - title.setFont(new Font("Helvetica", Font.BOLD, 24)); - box.add(title); - - // create the username bar - JPanel bar = new JPanel(new HGroupLayout(GroupLayout.STRETCH)); - bar.add(new JLabel(_msgs.get("m.username")), GroupLayout.FIXED); - _username = new JTextField(); - _username.setActionCommand("skipToPassword"); - _username.addActionListener(this); - bar.add(_username); - box.add(bar); - - // create the password bar - bar = new JPanel(new HGroupLayout(GroupLayout.STRETCH)); - bar.add(new JLabel(_msgs.get("m.password")), GroupLayout.FIXED); - _password = new JPasswordField(); - _password.setActionCommand("logon"); - _password.addActionListener(this); - bar.add(_password); - box.add(bar); - - // create the logon button bar - HGroupLayout gl = new HGroupLayout(GroupLayout.NONE); - gl.setJustification(GroupLayout.RIGHT); - bar = new JPanel(gl); - _logon = new JButton(_msgs.get("m.logon")); - _logon.setActionCommand("logon"); - _logon.addActionListener(this); - bar.add(_logon); - box.add(bar); - - box.add(new JLabel(_msgs.get("m.status"))); - _status = new JTextArea() { - public Dimension getPreferredScrollableViewportSize () - { - return new Dimension(10, 100); - } - }; - _status.setEditable(false); - JScrollPane scroller = new JScrollPane(_status); - box.add(scroller); - - // we'll want to listen for logon failure - _ctx.getClient().addClientObserver(this); - - // start with focus in the username field - _username.requestFocusInWindow(); - } - - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - if (cmd.equals("skipToPassword")) { - _password.requestFocusInWindow(); - - } else if (cmd.equals("logon")) { - logon(); - - } else { - System.out.println("Unknown action event: " + cmd); - } - } - - // documentation inherited from interface - public void clientDidLogon (Client client) - { - _status.append(_msgs.get("m.logon_success") + "\n"); - } - - // documentation inherited from interface - public void clientDidLogoff (Client client) - { - _status.append(_msgs.get("m.logged_off") + "\n"); - setLogonEnabled(true); - } - - // documentation inherited from interface - public void clientFailedToLogon (Client client, Exception cause) - { - String msg; - if (cause instanceof LogonException) { - msg = MessageBundle.compose("m.logon_failed", cause.getMessage()); - } else { - msg = MessageBundle.tcompose("m.logon_failed", cause.getMessage()); - } - _status.append(_msgs.xlate(msg) + "\n"); - setLogonEnabled(true); - } - - // documentation inherited from interface - public void clientObjectDidChange (Client client) - { - // nothing we can do here... - } - - // documentation inherited from interface - public void clientConnectionFailed (Client client, Exception cause) - { - String msg = MessageBundle.tcompose("m.connection_failed", - cause.getMessage()); - _status.append(_msgs.xlate(msg) + "\n"); - setLogonEnabled(true); - } - - // documentation inherited from interface - public boolean clientWillLogoff (Client client) - { - // no vetoing here - return true; - } - - protected void logon () - { - // disable further logon attempts until we hear back - setLogonEnabled(false); - - Name username = new Name(_username.getText().trim()); - String password = new String(_password.getPassword()).trim(); - - String server = _ctx.getClient().getHostname(); - int port = _ctx.getClient().getPorts()[0]; - String msg = MessageBundle.tcompose("m.logging_on", - server, String.valueOf(port)); - _status.append(_msgs.xlate(msg) + "\n"); - - // configure the client with some credentials and logon - Credentials creds = new UsernamePasswordCreds(username, password); - Client client = _ctx.getClient(); - client.setCredentials(creds); - client.logon(); - } - - protected void setLogonEnabled (boolean enabled) - { - _username.setEnabled(enabled); - _password.setEnabled(enabled); - _logon.setEnabled(enabled); - } - - protected MiCasaContext _ctx; - protected MessageBundle _msgs; - - protected JTextField _username; - protected JPasswordField _password; - protected JButton _logon; - protected JTextArea _status; -} diff --git a/src/java/com/threerings/micasa/client/MiCasaApp.java b/src/java/com/threerings/micasa/client/MiCasaApp.java deleted file mode 100644 index e81b34381..000000000 --- a/src/java/com/threerings/micasa/client/MiCasaApp.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $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.micasa.client; - -import java.io.IOException; - -import com.samskivert.swing.util.SwingUtil; -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.net.UsernamePasswordCreds; - -import com.threerings.micasa.Log; - -/** - * The micasa app is the main point of entry for the MiCasa client - * application. It creates and initializes the myriad components of the - * client and sets all the proper wheels in motion. - */ -public class MiCasaApp -{ - public void init () - throws IOException - { - // create a frame - _frame = new MiCasaFrame(); - - // create our client instance - String cclass = null; - try { - cclass = System.getProperty("client"); - } catch (Throwable t) { - // security manager in effect, no problem - } - if (cclass == null) { - cclass = MiCasaClient.class.getName(); - } - - try { - _client = (MiCasaClient)Class.forName(cclass).newInstance(); - } catch (Exception e) { - Log.warning("Unable to instantiate client class " + - "[cclass=" + cclass + "]."); - Log.logStackTrace(e); - } - - // initialize our client instance - _client.init(_frame); - } - - public void run (String server, String username, String password) - { - // position everything and show the frame - _frame.setSize(800, 600); - SwingUtil.centerWindow(_frame); - _frame.setVisible(true); - - Client client = _client.getContext().getClient(); - - 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(); - } - } - - public static void main (String[] args) - { - String server = "localhost"; - if (args.length > 0) { - server = args[0]; - } - String username = (args.length > 1) ? args[1] : null; - String password = (args.length > 2) ? args[2] : null; - - MiCasaApp app = new MiCasaApp(); - try { - // initialize the app - app.init(); - } catch (IOException ioe) { - Log.warning("Error initializing application."); - Log.logStackTrace(ioe); - } - - // and run it - app.run(server, username, password); - } - - protected MiCasaClient _client; - protected MiCasaFrame _frame; -} diff --git a/src/java/com/threerings/micasa/client/MiCasaApplet.java b/src/java/com/threerings/micasa/client/MiCasaApplet.java deleted file mode 100644 index f9ef0ff48..000000000 --- a/src/java/com/threerings/micasa/client/MiCasaApplet.java +++ /dev/null @@ -1,124 +0,0 @@ -// -// $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.micasa.client; - -import java.applet.Applet; -import java.io.IOException; - -import com.samskivert.swing.util.SwingUtil; -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.ClientAdapter; -import com.threerings.presents.net.UsernamePasswordCreds; - -import com.threerings.micasa.Log; - -/** - * The MiCasa applet is used to make MiCasa games available via the web - * browser. - */ -public class MiCasaApplet extends Applet -{ - /** - * Create the client instance and set things up. - */ - public void init () - { - try { - // create a frame - _frame = new MiCasaFrame(); - - // create our client instance - _client = new MiCasaClient(); - _client.init(_frame); - - Name username = new Name(requireParameter("username")); - String authkey = requireParameter("authkey"); - String server = getCodeBase().getHost(); - - Client client = _client.getContext().getClient(); - - // indicate which server to which we should connect - client.setServer(server, Client.DEFAULT_SERVER_PORTS); - - // create and set our credentials - client.setCredentials( - new UsernamePasswordCreds(username, authkey)); - - // we want to hide the client frame when we logoff - client.addClientObserver(new ClientAdapter() { - public void clientDidLogoff (Client c) - { - _frame.setVisible(false); - } - }); - - } catch (IOException ioe) { - Log.warning("Unable to create client."); - Log.logStackTrace(ioe); - } - } - - protected String requireParameter (String name) - throws IOException - { - String value = getParameter(name); - if (value == null) { - throw new IOException("Applet missing '" + name + "' parameter."); - } - return value; - } - - /** - * Display the client frame and really get things going. - */ - public void start () - { - if (_client != null) { - // show the frame - _frame.setSize(800, 600); - SwingUtil.centerWindow(_frame); - _frame.setVisible(true); - // and log on - _client.getContext().getClient().logon(); - } - } - - /** - * Log off and shut on down. - */ - public void stop () - { - if (_client != null) { - // hide the frame and log off - _frame.setVisible(false); - Client client = _client.getContext().getClient(); - if (client.isLoggedOn()) { - client.logoff(false); - } - } - } - - protected MiCasaClient _client; - protected MiCasaFrame _frame; -} diff --git a/src/java/com/threerings/micasa/client/MiCasaClient.java b/src/java/com/threerings/micasa/client/MiCasaClient.java deleted file mode 100644 index 6a7304024..000000000 --- a/src/java/com/threerings/micasa/client/MiCasaClient.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// $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.micasa.client; - -import java.awt.EventQueue; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.IOException; -import javax.swing.JPanel; - -import com.samskivert.util.Config; -import com.samskivert.util.RunQueue; -import com.threerings.util.MessageManager; - -import com.threerings.presents.client.Client; -import com.threerings.presents.dobj.DObjectManager; - -import com.threerings.crowd.client.LocationDirector; -import com.threerings.crowd.client.OccupantDirector; -import com.threerings.crowd.client.PlaceView; - -import com.threerings.crowd.chat.client.ChatDirector; - -import com.threerings.parlor.client.ParlorDirector; - -import com.threerings.micasa.util.MiCasaContext; - -/** - * The MiCasa 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 MiCasaClient - implements RunQueue -{ - /** - * Initializes a new client and provides it with a frame in which to - * display everything. - */ - public void init (MiCasaFrame frame) - throws IOException - { - // create our context - _ctx = createContextImpl(); - - // create the directors/managers/etc. provided by the context - createContextServices(); - - // for test purposes, hardcode the server info - _client.setServer("localhost", Client.DEFAULT_SERVER_PORTS); - - // keep this for later - _frame = frame; - - // log off when they close the window - _frame.addWindowListener(new WindowAdapter() { - public void windowClosing (WindowEvent evt) { - // if we're logged on, log off - if (_client.isLoggedOn()) { - _client.logoff(true); - } else { - // otherwise get the heck out - System.exit(0); - } - } - }); - - // create our client controller and stick it in the frame - _frame.setController(new ClientController(_ctx, _frame)); - } - - /** - * Returns a reference to the context in effect for this client. This - * reference is valid for the lifetime of the application. - */ - public MiCasaContext getContext () - { - return _ctx; - } - - /** - * Creates the {@link MiCasaContext} 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 MiCasaContext createContextImpl () - { - return new MiCasaContextImpl(); - } - - /** - * 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 () - throws IOException - { - // create the handles on our various services - _client = new Client(null, this); - - // create our managers and directors - _locdir = new LocationDirector(_ctx); - _occdir = new OccupantDirector(_ctx); - _pardtr = new ParlorDirector(_ctx); - _msgmgr = new MessageManager(MESSAGE_MANAGER_PREFIX); - _chatdir = new ChatDirector(_ctx, _msgmgr, null); - } - - // documentation inherited from interface RunQueue - public void postRunnable (Runnable run) - { - // queue it on up on the awt thread - EventQueue.invokeLater(run); - } - - // documentation inherited from interface RunQueue - public boolean isDispatchThread () - { - return EventQueue.isDispatchThread(); - } - - /** - * The context implementation. This provides access to all of the - * objects and services that are needed by the operating client. - */ - protected class MiCasaContextImpl implements MiCasaContext - { - /** - * 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 MiCasaContextImpl () - { - } - - 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 ParlorDirector getParlorDirector () - { - return _pardtr; - } - - public void setPlaceView (PlaceView view) - { - // stick the place view into our frame - _frame.setPanel((JPanel)view); - } - - public void clearPlaceView (PlaceView view) - { - // we'll just let the next place view replace our old one - } - - public MiCasaFrame getFrame () - { - return _frame; - } - - public MessageManager getMessageManager () - { - return _msgmgr; - } - } - - protected MiCasaContext _ctx; - protected MiCasaFrame _frame; - protected Config _config = new Config("micasa"); - - protected Client _client; - protected LocationDirector _locdir; - protected OccupantDirector _occdir; - protected ChatDirector _chatdir; - protected ParlorDirector _pardtr; - 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/src/java/com/threerings/micasa/client/MiCasaFrame.java b/src/java/com/threerings/micasa/client/MiCasaFrame.java deleted file mode 100644 index 7b8158f0d..000000000 --- a/src/java/com/threerings/micasa/client/MiCasaFrame.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// $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.micasa.client; - -import java.awt.BorderLayout; - -import javax.swing.JFrame; -import javax.swing.JPanel; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.ControllerProvider; - -/** - * Contains the user interface for the MiCasa client application. - */ -public class MiCasaFrame - extends JFrame implements ControllerProvider -{ - /** - * Constructs the top-level MiCasa client frame. - */ - public MiCasaFrame () - { - this("MiCasa Client"); - } - - /** - * Constructs the top-level MiCasa client frame with the specified - * window title. - */ - public MiCasaFrame (String title) - { - super(title); - - // we'll handle shutting things down ourselves - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - } - - /** - * Sets the panel that makes up the entire client display. - */ - public void setPanel (JPanel panel) - { - // remove the old panel - getContentPane().removeAll(); - // add the new one - getContentPane().add(panel, BorderLayout.CENTER); - // swing doesn't properly repaint after adding/removing children - panel.revalidate(); - repaint(); - } - - /** - * Sets the controller for the outermost scope. This controller will - * handle all actions that aren't handled by controllers of tigher - * scope. - */ - public void setController (Controller controller) - { - _controller = controller; - } - - // documentation inherited - public Controller getController () - { - return _controller; - } - - protected Controller _controller; -} diff --git a/src/java/com/threerings/micasa/client/OccupantList.java b/src/java/com/threerings/micasa/client/OccupantList.java deleted file mode 100644 index ca08e4ecb..000000000 --- a/src/java/com/threerings/micasa/client/OccupantList.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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.micasa.client; - -import java.util.Iterator; -import javax.swing.DefaultListModel; -import javax.swing.JList; - -import com.threerings.crowd.client.OccupantObserver; -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.OccupantInfo; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -/** - * The occupant list displays the list of users that are in a particular - * place. - */ -public class OccupantList - extends JList implements PlaceView, OccupantObserver -{ - /** - * Constructs an occupant list with the supplied context which it will - * use to register itself with the necessary managers. - */ - public OccupantList (CrowdContext ctx) - { - // set up our list model - _model = new DefaultListModel(); - setModel(_model); - - // keep our context around for later - _ctx = ctx; - - // register ourselves as an occupant observer - _ctx.getOccupantDirector().addOccupantObserver(this); - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - // add all of the occupants of the place to our list - Iterator users = plobj.occupantInfo.iterator(); - while (users.hasNext()) { - OccupantInfo info = (OccupantInfo)users.next(); - _model.addElement(info.username); - } - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - // clear out our occupant entries - _model.clear(); - } - - // documentation inherited - public void occupantEntered (OccupantInfo info) - { - // simply add this user to our list - _model.addElement(info.username); - } - - // documentation inherited - public void occupantLeft (OccupantInfo info) - { - // remove this occupant from our list - _model.removeElement(info.username); - } - - // documentation inherited - public void occupantUpdated (OccupantInfo oinfo, OccupantInfo info) - { - // nothing doing - } - - /** Our client context. */ - protected CrowdContext _ctx; - - /** A list model that provides a vector interface. */ - protected DefaultListModel _model; -} diff --git a/src/java/com/threerings/micasa/data/MiCasaBootstrapData.java b/src/java/com/threerings/micasa/data/MiCasaBootstrapData.java deleted file mode 100644 index 1d36d99d9..000000000 --- a/src/java/com/threerings/micasa/data/MiCasaBootstrapData.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// $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.micasa.data; - -import com.threerings.presents.net.BootstrapData; - -/** - * Extends the basic Presents bootstrap data and provides some bootstrap - * information specific to the MiCasa services. - */ -public class MiCasaBootstrapData extends BootstrapData -{ - /** The oid of the default lobby. */ - public int defLobbyOid; -} diff --git a/src/java/com/threerings/micasa/lobby/Lobby.java b/src/java/com/threerings/micasa/lobby/Lobby.java deleted file mode 100644 index 308b1cb91..000000000 --- a/src/java/com/threerings/micasa/lobby/Lobby.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.io.SimpleStreamableObject; - -/** - * A simple class for keeping track of information for each lobby in - * operation on the server. - */ -public class Lobby extends SimpleStreamableObject -{ - /** The object id of the lobby place object. */ - public int placeOid; - - /** The universal game identifier string for the game matchmade by - * this lobby. */ - public String gameIdent; - - /** The human readable name of the lobby. */ - public String name; - - /** - * Constructs a lobby record and initializes it with the specified - * values. - */ - public Lobby (int placeOid, String gameIdent, String name) - { - this.placeOid = placeOid; - this.gameIdent = gameIdent; - this.name = name; - } - - /** - * Constructs a blank lobby record suitable for unserialization. - */ - public Lobby () - { - } -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyConfig.java b/src/java/com/threerings/micasa/lobby/LobbyConfig.java deleted file mode 100644 index 340f3d594..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyConfig.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// $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.micasa.lobby; - -import javax.swing.JComponent; -import javax.swing.JLabel; - -import java.util.Properties; -import com.samskivert.util.StringUtil; - -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.micasa.util.MiCasaContext; -import com.threerings.parlor.game.data.GameConfig; - -public class LobbyConfig extends PlaceConfig -{ - // documentation inherited - public PlaceController createController () - { - return new LobbyController(); - } - - // documentation inherited - public String getManagerClassName () - { - return "com.threerings.micasa.lobby.LobbyManager"; - } - - /** - * Derived classes override this function and create the appropriate - * matchmaking user interface component. - */ - public JComponent createMatchMakingView (MiCasaContext ctx) - { - return new JLabel("Match-making view goes here."); - } - - /** - * Instantiates and returns a game config instance using the game - * config classname provided by the lobby configuration parameters. - * - * @exception Exception thrown if a problem occurs loading or - * instantiating the class. - */ - public GameConfig getGameConfig () - throws Exception - { - return (GameConfig)Class.forName(_gameConfigClass).newInstance(); - } - - /** - * Initializes this lobby config object with the properties that are - * used to configure the lobby. This is called on the server when the - * lobby is loaded. - */ - public void init (Properties config) - throws Exception - { - _gameConfigClass = getConfigValue(config, "game_config"); - } - - // documentation inherited - protected void toString (StringBuilder buf) - { - super.toString(buf); - if (buf.length() > 1) { - buf.append(", "); - } - buf.append("game_config=").append(_gameConfigClass); - } - - /** Looks up a configuration property in the supplied properties - * object and throws an exception if it's not found. */ - protected String getConfigValue (Properties config, String key) - throws Exception - { - String value = config.getProperty(key); - if (StringUtil.isBlank(value)) { - throw new Exception("Missing '" + key + "' definition in " + - "lobby configuration."); - } - return value; - } - - /** The name of the game config class that represents the type of game - * we are matchmaking for in this lobby. */ - protected String _gameConfigClass; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyController.java b/src/java/com/threerings/micasa/lobby/LobbyController.java deleted file mode 100644 index f73b2011f..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyController.java +++ /dev/null @@ -1,121 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.util.Name; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.parlor.client.*; -import com.threerings.parlor.game.data.GameConfig; - -import com.threerings.micasa.Log; -import com.threerings.micasa.util.MiCasaContext; - -public class LobbyController extends PlaceController - implements InvitationHandler, InvitationResponseObserver -{ - public void init (CrowdContext ctx, PlaceConfig config) - { - // cast our context reference - _ctx = (MiCasaContext)ctx; - _config = (LobbyConfig)config; - - super.init(ctx, config); - - // register ourselves as the invitation handler - _ctx.getParlorDirector().setInvitationHandler(this); - } - - protected PlaceView createPlaceView (CrowdContext ctx) - { - return new LobbyPanel(_ctx, _config); - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - try { - // if a system property has been specified requesting that we - // invite another player, do so now - String invitee = System.getProperty("invitee"); - if (invitee != null) { - // create a game config object - try { - GameConfig config = _config.getGameConfig(); - _ctx.getParlorDirector().invite( - new Name(invitee), config, this); - } catch (Exception e) { - Log.warning("Error instantiating game config."); - Log.logStackTrace(e); - } - } - - } catch (SecurityException se) { - // nothing to see here, move it along... - } - } - - // documentation inherited from interface - public void invitationReceived (Invitation invite) - { - Log.info("Invitation received [invite=" + invite + "]."); - - // accept the invitation. we're game... - invite.accept(); - } - - // documentation inherited from interface - public void invitationCancelled (Invitation invite) - { - Log.info("Invitation cancelled " + invite + "."); - } - - // documentation inherited from interface - public void invitationAccepted (Invitation invite) - { - Log.info("Invitation accepted " + invite + "."); - } - - // documentation inherited from interface - public void invitationRefused (Invitation invite, String message) - { - Log.info("Invitation refused [invite=" + invite + - ", message=" + message + "]."); - } - - // documentation inherited from interface - public void invitationCountered (Invitation invite, GameConfig config) - { - Log.info("Invitation countered [invite=" + invite + - ", config=" + config + "]."); - } - - protected MiCasaContext _ctx; - protected LobbyConfig _config; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyDispatcher.java b/src/java/com/threerings/micasa/lobby/LobbyDispatcher.java deleted file mode 100644 index 4f76e126a..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyDispatcher.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.micasa.lobby.LobbyMarshaller; -import com.threerings.micasa.lobby.LobbyService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; -import java.util.List; - -/** - * Dispatches requests to the {@link LobbyProvider}. - */ -public class LobbyDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public LobbyDispatcher (LobbyProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new LobbyMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case LobbyMarshaller.GET_CATEGORIES: - ((LobbyProvider)provider).getCategories( - source, - (LobbyService.CategoriesListener)args[0] - ); - return; - - case LobbyMarshaller.GET_LOBBIES: - ((LobbyProvider)provider).getLobbies( - source, - (String)args[0], (LobbyService.LobbiesListener)args[1] - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyManager.java b/src/java/com/threerings/micasa/lobby/LobbyManager.java deleted file mode 100644 index 329ade5e8..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyManager.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// $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.micasa.lobby; - -import java.util.Properties; -import com.samskivert.util.StringUtil; - -import com.threerings.crowd.server.PlaceManager; -import com.threerings.micasa.Log; - -/** - * Takes care of the server side of a particular lobby. - */ -public class LobbyManager extends PlaceManager -{ - /** - * Initializes this lobby manager with its configuration properties. - * - * @exception Exception thrown if a configuration error is detected. - */ - public void init (LobbyRegistry lobreg, Properties config) - throws Exception - { - // look up some configuration parameters - _gameIdent = getConfigValue(config, "ugi"); - _name = getConfigValue(config, "name"); - - // keep this for later - _lobreg = lobreg; - - Log.info("Lobby manager initialized [ident=" + _gameIdent + - ", name=" + _name + "]."); - } - - /** Looks up a configuration property in the supplied properties - * object and throws an exception if it's not found. */ - protected String getConfigValue (Properties config, String key) - throws Exception - { - String value = config.getProperty(key); - if (StringUtil.isBlank(value)) { - throw new Exception("Missing '" + key + "' definition in " + - "lobby configuration."); - } - return value; - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return LobbyObject.class; - } - - // documentation inherited - protected void didStartup () - { - super.didStartup(); - - // let the lobby registry know that we're up and running - _lobreg.lobbyReady(_plobj.getOid(), _gameIdent, _name); - } - - /** The universal game identifier for the game matchmade by this - * lobby. */ - protected String _gameIdent; - - /** The human readable name of this lobby. */ - protected String _name; - - /** A reference to the lobby registry. */ - protected LobbyRegistry _lobreg; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyMarshaller.java b/src/java/com/threerings/micasa/lobby/LobbyMarshaller.java deleted file mode 100644 index c8f10fdb8..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyMarshaller.java +++ /dev/null @@ -1,132 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.micasa.lobby.LobbyService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; -import java.util.List; - -/** - * Provides the implementation of the {@link LobbyService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class LobbyMarshaller extends InvocationMarshaller - implements LobbyService -{ - // documentation inherited - public static class CategoriesMarshaller extends ListenerMarshaller - implements CategoriesListener - { - /** The method id used to dispatch {@link #gotCategories} - * responses. */ - public static final int GOT_CATEGORIES = 1; - - // documentation inherited from interface - public void gotCategories (String[] arg1) - { - _invId = null; - omgr.postEvent(new InvocationResponseEvent( - callerOid, requestId, GOT_CATEGORIES, - new Object[] { arg1 })); - } - - // documentation inherited - public void dispatchResponse (int methodId, Object[] args) - { - switch (methodId) { - case GOT_CATEGORIES: - ((CategoriesListener)listener).gotCategories( - (String[])args[0]); - return; - - default: - super.dispatchResponse(methodId, args); - return; - } - } - } - - // documentation inherited - public static class LobbiesMarshaller extends ListenerMarshaller - implements LobbiesListener - { - /** The method id used to dispatch {@link #gotLobbies} - * responses. */ - public static final int GOT_LOBBIES = 1; - - // documentation inherited from interface - public void gotLobbies (List arg1) - { - _invId = null; - omgr.postEvent(new InvocationResponseEvent( - callerOid, requestId, GOT_LOBBIES, - new Object[] { arg1 })); - } - - // documentation inherited - public void dispatchResponse (int methodId, Object[] args) - { - switch (methodId) { - case GOT_LOBBIES: - ((LobbiesListener)listener).gotLobbies( - (List)args[0]); - return; - - default: - super.dispatchResponse(methodId, args); - return; - } - } - } - - /** The method id used to dispatch {@link #getCategories} requests. */ - public static final int GET_CATEGORIES = 1; - - // documentation inherited from interface - public void getCategories (Client arg1, LobbyService.CategoriesListener arg2) - { - LobbyMarshaller.CategoriesMarshaller listener2 = new LobbyMarshaller.CategoriesMarshaller(); - listener2.listener = arg2; - sendRequest(arg1, GET_CATEGORIES, new Object[] { - listener2 - }); - } - - /** The method id used to dispatch {@link #getLobbies} requests. */ - public static final int GET_LOBBIES = 2; - - // documentation inherited from interface - public void getLobbies (Client arg1, String arg2, LobbyService.LobbiesListener arg3) - { - LobbyMarshaller.LobbiesMarshaller listener3 = new LobbyMarshaller.LobbiesMarshaller(); - listener3.listener = arg3; - sendRequest(arg1, GET_LOBBIES, new Object[] { - arg2, listener3 - }); - } - -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyObject.java b/src/java/com/threerings/micasa/lobby/LobbyObject.java deleted file mode 100644 index 3c3abb935..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyObject.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.crowd.data.PlaceObject; - -/** - * Presently the lobby object contains nothing specific, but the class - * acts as a placeholder in case lobby-wide fields are needed in the - * future. - */ -public class LobbyObject extends PlaceObject -{ -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyPanel.java b/src/java/com/threerings/micasa/lobby/LobbyPanel.java deleted file mode 100644 index 8ed4fad1c..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyPanel.java +++ /dev/null @@ -1,114 +0,0 @@ -// -// $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.micasa.lobby; - -import javax.swing.*; -import com.samskivert.swing.*; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.micasa.client.*; -import com.threerings.micasa.util.MiCasaContext; - -/** - * Used to display the interface for the lobbies. It contains a lobby - * selection mechanism, a chat interface and a user interface for whatever - * match-making mechanism is appropriate for this particular lobby. - */ -public class LobbyPanel - extends JPanel implements PlaceView -{ - /** - * Constructs a new lobby panel and the associated user interface - * elements. - */ - public LobbyPanel (MiCasaContext ctx, LobbyConfig config) - { - // we want a five pixel border around everything - setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - // create our primary layout which divides the display in two - // horizontally - GroupLayout gl = new HGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - gl.setJustification(GroupLayout.RIGHT); - setLayout(gl); - - // create our main panel - gl = new VGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - _main = new JPanel(gl); - - // create our match-making view - _main.add(config.createMatchMakingView(ctx)); - - // create a chat box and stick that in as well - _main.add(new ChatPanel(ctx)); - - // now add the main panel into the mix - add(_main); - - // create our sidebar panel - gl = new VGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - JPanel sidePanel = new JPanel(gl); - - // the sidebar contains a lobby info display... - - // ...a lobby selector... - JLabel label = new JLabel("Select a lobby..."); - sidePanel.add(label, GroupLayout.FIXED); - LobbySelector selector = new LobbySelector(ctx); - sidePanel.add(selector); - - // and an occupants list - label = new JLabel("People in lobby"); - sidePanel.add(label, GroupLayout.FIXED); - _occupants = new OccupantList(ctx); - sidePanel.add(_occupants); - - JButton logoff = new JButton("Logoff"); - logoff.addActionListener(Controller.DISPATCHER); - logoff.setActionCommand("logoff"); - sidePanel.add(logoff, GroupLayout.FIXED); - - // add our sidebar panel into the mix - add(sidePanel, GroupLayout.FIXED); - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - } - - /** Contains the match-making view and the chatbox. */ - protected JPanel _main; - - /** Our occupant list display. */ - protected OccupantList _occupants; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyProvider.java b/src/java/com/threerings/micasa/lobby/LobbyProvider.java deleted file mode 100644 index c219e1bba..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// $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.micasa.lobby; - -import com.threerings.micasa.lobby.LobbyService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; -import java.util.List; - -/** - * Defines the server-side of the {@link LobbyService}. - */ -public interface LobbyProvider extends InvocationProvider -{ - /** - * Handles a {@link LobbyService#getCategories} request. - */ - public void getCategories (ClientObject caller, LobbyService.CategoriesListener arg1) - throws InvocationException; - - /** - * Handles a {@link LobbyService#getLobbies} request. - */ - public void getLobbies (ClientObject caller, String arg1, LobbyService.LobbiesListener arg2) - throws InvocationException; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyRegistry.java b/src/java/com/threerings/micasa/lobby/LobbyRegistry.java deleted file mode 100644 index 8c919740e..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyRegistry.java +++ /dev/null @@ -1,272 +0,0 @@ -// -// $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.micasa.lobby; - -import java.util.*; -import com.samskivert.util.*; -import com.threerings.util.StreamableArrayList; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationManager; - -import com.threerings.crowd.data.BodyObject; - -import com.threerings.micasa.Log; -import com.threerings.micasa.lobby.LobbyService.CategoriesListener; -import com.threerings.micasa.lobby.LobbyService.LobbiesListener; -import com.threerings.micasa.server.MiCasaConfig; -import com.threerings.micasa.server.MiCasaServer; - -/** - * The lobby registry is the primary class that coordinates the lobby - * services on the client. It sets up the necessary invocation services - * and keeps track of the lobbies in operation on the server. Only one - * lobby registry should be created on a server. - * - *

Presently, the lobby registry is configured with lobbies via the - * server configuration. An example configuration follows: - * - *

- * lobby_ids = foolobby, barlobby, bazlobby
- *
- * foolobby.mgrclass = com.threerings.micasa.lobby.LobbyManager
- * foolobby.ugi = 
- * foolobby.name = 
- * foolobby.config1 = some config value
- * foolobby.config2 = some other config value
- *
- * barlobby.mgrclass = com.threerings.micasa.lobby.LobbyManager
- * barlobby.ugi = 
- * barlobby.name = 
- * ...
- * 
- * - * This information will be loaded from the MiCasa server configuration - * which means that it should live in - * rsrc/config/micasa/server.properties somwhere in the - * classpath where it will override the default MiCasa server properties - * file. - * - *

The UGI or universal game identifier is a string that - * is used to uniquely identify every type of game and also to classify it - * according to meaningful keywords. It is best described with a few - * examples: - * - *

- * backgammon,board,strategy
- * spades,card,partner
- * yahtzee,dice
- * 
- * - * As you can see, a UGI should start with an identifier uniquely - * identifying the type of game and can be followed by a list of keywords - * that classify it as a member of a particular category of games - * (eg. board, card, dice, partner game, strategy game). A game can belong - * to multiple categories. - * - *

As long as the UGIs in use by a particular server make some kind of - * sense, the client will be able to use them to search for lobbies - * containing games of similar types using the provided facilities. - */ -public class LobbyRegistry - implements LobbyProvider -{ - /** - * Initializes the registry. It will use the supplied configuration - * instance to determine which lobbies to load, etc. - * - * @param invmgr a reference to the server's invocation manager. - */ - public void init (InvocationManager invmgr) - { - // register ourselves as an invocation service handler - invmgr.registerDispatcher(new LobbyDispatcher(this), true); - - // create our lobby managers - String[] lmgrs = null; - lmgrs = MiCasaConfig.config.getValue(LOBIDS_KEY, lmgrs); - if (lmgrs == null || lmgrs.length == 0) { - Log.warning("No lobbies specified in config file (via '" + - LOBIDS_KEY + "' parameter)."); - - } else { - for (int i = 0; i < lmgrs.length; i++) { - loadLobby(lmgrs[i]); - } - } - } - - /** - * Returns the oid of the default lobby. - */ - public int getDefaultLobbyOid () - { - return _defLobbyOid; - } - - /** - * Extracts the properties for a lobby from the server config and - * creates and initializes the lobby manager. - */ - protected void loadLobby (String lobbyId) - { - try { - // extract the properties for this lobby - Properties props = MiCasaConfig.config.getSubProperties(lobbyId); - - // get the lobby manager class and UGI - String cfgClass = props.getProperty("config"); - if (StringUtil.isBlank(cfgClass)) { - throw new Exception("Missing 'config' definition in " + - "lobby configuration."); - } - - // create and initialize the lobby config object - LobbyConfig config = (LobbyConfig) - Class.forName(cfgClass).newInstance(); - config.init(props); - - // create and initialize the lobby manager. it will call - // lobbyReady() when it has obtained a reference to its lobby - // object and is ready to roll - LobbyManager lobmgr = (LobbyManager) - MiCasaServer.plreg.createPlace(config, null); - lobmgr.init(this, props); - - } catch (Exception e) { - Log.warning("Unable to create lobby manager " + - "[lobbyId=" + lobbyId + ", error=" + e + "]."); - } - } - - /** - * Returns information about all lobbies hosting games in the - * specified category. - * - * @param requester the body object of the client requesting the lobby - * list (which can be used to filter the list based on their - * capabilities). - * @param category the category of game for which the lobbies are - * desired. - * @param target the list into which the matching lobbies will be - * deposited. - */ - public void getLobbies (BodyObject requester, String category, - List target) - { - ArrayList list = (ArrayList)_lobbies.get(category); - if (list != null) { - target.addAll(list); - } - } - - /** - * Returns an array containing the category identifiers of all the - * categories in which lobbies have been registered with the registry. - * - * @param requester the body object of the client requesting the - * cateogory list (which can be used to filter the list based on their - * capabilities). - */ - public String[] getCategories (BodyObject requester) - { - // might want to cache this some day so that we don't recreate it - // every time someone wants it. we can cache the array until the - // category count changes - String[] cats = new String[_lobbies.size()]; - Iterator iter = _lobbies.keySet().iterator(); - for (int i = 0; iter.hasNext(); i++) { - cats[i] = (String)iter.next(); - } - return cats; - } - - /** - * Processes a request by the client to obtain a list of the lobby - * categories available on this server. - */ - public void getCategories (ClientObject caller, CategoriesListener listener) - { - listener.gotCategories(getCategories((BodyObject)caller)); - } - - /** - * Processes a request by the client to obtain a list of lobbies - * matching the supplied category string. - */ - public void getLobbies (ClientObject caller, String category, - LobbiesListener listener) - { - StreamableArrayList target = new StreamableArrayList(); - ArrayList list = (ArrayList)_lobbies.get(category); - if (list != null) { - target.addAll(list); - } - listener.gotLobbies(target); - } - - /** - * Called by our lobby managers once they have started up and are - * ready to do their lobby duties. - */ - protected void lobbyReady (int placeOid, String gameIdent, String name) - { - // create a lobby record - Lobby record = new Lobby(placeOid, gameIdent, name); - - // if we don't already have a default lobby, this one is the big - // winner - if (_defLobbyOid == -1) { - _defLobbyOid = placeOid; - } - - // and register it in all the right lobby tables - StringTokenizer tok = new StringTokenizer(gameIdent, ","); - while (tok.hasMoreTokens()) { - String category = tok.nextToken(); - registerLobby(category, record); - } - } - - /** Registers the supplied lobby in the specified category table. */ - protected void registerLobby (String category, Lobby record) - { - ArrayList catlist = (ArrayList)_lobbies.get(category); - if (catlist == null) { - catlist = new ArrayList(); - _lobbies.put(category, catlist); - } - catlist.add(record); - Log.info("Registered lobby [cat=" + category + - ", record=" + record + "]."); - } - - /** A table containing references to all of our lobby records (in the - * form of category lists. */ - protected HashMap _lobbies = new HashMap(); - - /** The oid of the default lobby. */ - protected int _defLobbyOid = -1; - - /** The configuration key for the lobby managers list. */ - protected static final String LOBIDS_KEY = "lobby_ids"; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbySelector.java b/src/java/com/threerings/micasa/lobby/LobbySelector.java deleted file mode 100644 index e78bd94f8..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbySelector.java +++ /dev/null @@ -1,219 +0,0 @@ -// -// $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.micasa.lobby; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.event.*; - -import java.util.*; - -import javax.swing.*; - -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.micasa.Log; -import com.threerings.micasa.util.MiCasaContext; - -/** - * The lobby selector displays a drop-down box listing the categories of - * lobbies available on this server and when a category is selected, it - * displays a list of the lobbies that are available in that category. If - * a lobby is double-clicked, it moves the client into that lobby room. - */ -public class LobbySelector extends JPanel - implements ActionListener, LobbyService.CategoriesListener, - LobbyService.LobbiesListener -{ - /** - * Constructs a new lobby selector component. It will wait until it is - * visible before issuing a get categories request to download a list - * of categories. - */ - public LobbySelector (MiCasaContext ctx) - { - setLayout(new BorderLayout()); - - // keep this around for later - _ctx = ctx; - - // create our drop-down box with a bogus entry at the moment - String[] options = new String[] { CAT_FIRST_ITEM }; - _combo = new JComboBox(options); - _combo.addActionListener(this); - add(_combo, BorderLayout.NORTH); - - // and create our empty lobby list - _loblist = new JList(); - _loblist.setCellRenderer(new LobbyCellRenderer()); - // add a mouse listener that tells us about double clicks - MouseListener ml = new MouseAdapter() { - public void mouseClicked (MouseEvent e) { - if (e.getClickCount() == 2) { - int index = _loblist.locationToIndex(e.getPoint()); - Object item = _loblist.getSelectedValue(); - enterLobby((Lobby)item); - } - } - }; - _loblist.addMouseListener(ml); - add(_loblist, BorderLayout.CENTER); - } - - // documentation inherited - public void addNotify () - { - super.addNotify(); - - // get a handle on our lobby service instance - _lservice = (LobbyService) - _ctx.getClient().requireService(LobbyService.class); - // and use them to look up the lobby categories - _lservice.getCategories(_ctx.getClient(), this); - } - - /** - * Called when the user selects a category or double-clicks on a - * lobby. - */ - public void actionPerformed (ActionEvent evt) - { - if (evt.getSource() == _combo) { - String selcat = (String)_combo.getSelectedItem(); - if (!selcat.equals(CAT_FIRST_ITEM)) { - selectCategory(selcat); - } - } - } - - // documentation inherited from interface - public void gotCategories (String[] categories) - { - // append these to our "unselected" item - for (int i = 0; i < categories.length; i++) { - _combo.addItem(categories[i]); - } - } - - // documentation inherited from interface - public void gotLobbies (List lobbies) - { - // create a list model for this category - DefaultListModel model = new DefaultListModel(); - - // populate it with the lobby info - Iterator iter = lobbies.iterator(); - while (iter.hasNext()) { - model.addElement(iter.next()); - } - - // stick it in the table - _catlists.put(_pendingCategory, model); - - // finally tell the lobby list to update the display (which we do - // by setting the combo box to this category in case the luser - // decided to try to select some new category while we weren't - // looking) - _combo.setSelectedItem(_pendingCategory); - - // clear out our pending category indicator - _pendingCategory = null; - } - - // documentation inherited from interface - public void requestFailed (String reason) - { - Log.info("Request failed [reason=" + reason + "]."); - - // clear out our pending category indicator in case this was a - // failed getLobbies() request - _pendingCategory = null; - } - - /** - * Fetches the list of lobbies available in a particular category (if - * they haven't already been fetched) and displays them in the lobby - * list. - */ - protected void selectCategory (String category) - { - DefaultListModel model = (DefaultListModel)_catlists.get(category); - if (model != null) { - _loblist.setModel(model); - - } else if (_pendingCategory == null) { - // make a note that we're loading up this category - _pendingCategory = category; - // issue a request to load up the lobbies in this category - _lservice.getLobbies(_ctx.getClient(), category, this); - - } else { - Log.info("Ignoring category select request because " + - "one is outstanding [pcat=" + _pendingCategory + - ", newcat=" + category + "]."); - } - } - - /** Called when the user selects a lobby from the lobby list. */ - protected void enterLobby (Lobby lobby) - { - // make sure we're not already in this lobby - PlaceObject plobj = _ctx.getLocationDirector().getPlaceObject(); - if (plobj != null && plobj.getOid() == lobby.placeOid) { - return; - } - - // otherwise request that we go there - _ctx.getLocationDirector().moveTo(lobby.placeOid); - - Log.info("Entering lobby " + lobby + "."); - - } - - /** Used to render Lobby instances in our lobby list. */ - protected static class LobbyCellRenderer - extends DefaultListCellRenderer - { - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) { - // use the lobby's name rather than the value of toString() - value = ((Lobby)value).name; - return super.getListCellRendererComponent( - list, value, index, isSelected, cellHasFocus); - } - } - - protected MiCasaContext _ctx; - protected LobbyService _lservice; - - protected JComboBox _combo; - protected JList _loblist; - - protected HashMap _catlists = new HashMap(); - protected String _pendingCategory; - - protected static final String CAT_FIRST_ITEM = ""; -} diff --git a/src/java/com/threerings/micasa/lobby/LobbyService.java b/src/java/com/threerings/micasa/lobby/LobbyService.java deleted file mode 100644 index 9475cacfb..000000000 --- a/src/java/com/threerings/micasa/lobby/LobbyService.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $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.micasa.lobby; - -import java.util.List; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -/** - * Provides an interface to the various parlor services that are directly - * invokable by the client (by means of the invocation services). - */ -public interface LobbyService extends InvocationService -{ - /** - * Used to communicate the results of a {@link #getCategories} - * request. - */ - public static interface CategoriesListener extends InvocationListener - { - /** - * Supplies the listener with the results of a {@link - * #getCategories} request. - */ - public void gotCategories (String[] categories); - } - - /** - * Used to communicate the results of a {@link #getLobbies} - * request. - */ - public static interface LobbiesListener extends InvocationListener - { - /** - * Supplies the listener with the results of a {@link - * #getLobbies} request. - */ - public void gotLobbies (List lobbies); - } - - /** - * Requests the list of lobby cateogories that are available on this - * server. - * - * @param client a connected, operational client instance. - * @param listener the listener that will receive and process the - * response. - */ - public void getCategories (Client client, CategoriesListener listener); - - /** - * Requests information on all active lobbies that match the specified - * category. - * - * @param client a connected, operational client instance. - * @param category the category of game for which a list of lobbies is - * desired. - * @param listener the listener that will receive and process the - * response. - */ - public void getLobbies (Client client, String category, - LobbiesListener listener); -} diff --git a/src/java/com/threerings/micasa/lobby/table/TableItem.java b/src/java/com/threerings/micasa/lobby/table/TableItem.java deleted file mode 100644 index e9d82ecd8..000000000 --- a/src/java/com/threerings/micasa/lobby/table/TableItem.java +++ /dev/null @@ -1,252 +0,0 @@ -// -// $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.micasa.lobby.table; - -import java.awt.Color; -import java.awt.GridBagLayout; -import java.awt.GridBagConstraints; -import java.awt.Insets; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import com.threerings.util.Name; - -import com.threerings.crowd.data.BodyObject; - -import com.threerings.parlor.client.TableDirector; -import com.threerings.parlor.client.SeatednessObserver; -import com.threerings.parlor.data.Table; - -import com.threerings.micasa.Log; -import com.threerings.micasa.util.MiCasaContext; - -/** - * A table item displays the user interface for a single table (whether it - * be in-play or still being matchmade). - */ -public class TableItem - extends JPanel - implements ActionListener, SeatednessObserver -{ - /** A reference to the table we are displaying. */ - public Table table; - - /** - * Creates a new table item to display and interact with the supplied - * table. - */ - public TableItem (MiCasaContext ctx, TableDirector tdtr, Table table) - { - // keep track of these - _tdtr = tdtr; - _ctx = ctx; - - // add ourselves as a seatedness observer - _tdtr.addSeatednessObserver(this); - - // figure out who we are - _self = ((BodyObject)ctx.getClient().getClientObject()).getVisibleName(); - - // now create our user interface - setBorder(BorderFactory.createLineBorder(Color.black)); - setLayout(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - - // create a label for the table - JLabel tlabel = new JLabel("Table " + table.tableId); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.insets = new Insets(2, 0, 0, 0); - add(tlabel, gbc); - - // we have one button for every "seat" at the table - int bcount = table.occupants.length; - - // create blank buttons for now and then we'll update everything - // with the current state when we're done - gbc.weightx = 1.0; - gbc.insets = new Insets(2, 0, 2, 0); - _seats = new JButton[bcount]; - for (int i = 0; i < bcount; i++) { - // create the button - _seats[i] = new JButton(JOIN_LABEL); - _seats[i].addActionListener(this); - - // if we're on the left - if (i % 2 == 0) { - // if we're the last seat, then we've got an odd number - // and need to center this final seat - if (i == bcount-1) { - gbc.gridwidth = GridBagConstraints.REMAINDER; - } else { - gbc.gridwidth = 1; - } - - } else { - gbc.gridwidth = GridBagConstraints.REMAINDER; - } - - // adjust the insets of our last element - if (i == bcount-1) { - gbc.insets = new Insets(2, 0, 4, 0); - } - - // and add the button with the configured constraints - add(_seats[i], gbc); - - // if we just added the first button, add the "go" button - // right after it - if (i == 0) { - _goButton = new JButton("Go"); - _goButton.setActionCommand("go"); - _goButton.addActionListener(this); - add(_goButton, gbc); - } - } - - // and update ourselves based on the contents of the occupants - // list - tableUpdated(table); - } - - /** - * Called when our table has been updated and we need to update the UI - * to reflect the new information. - */ - public void tableUpdated (Table table) - { - // grab this new table reference - this.table = table; - - // first look to see if we're already sitting at a table - boolean isSeated = _tdtr.isSeated(); - - // now enable and label the buttons accordingly - int slength = _seats.length; - for (int i = 0; i < slength; i++) { - if (table.occupants[i] == null) { - _seats[i].setText(JOIN_LABEL); - _seats[i].setEnabled(!isSeated); - _seats[i].setActionCommand("join"); - - } else if (table.occupants[i].equals(_self) && - !table.inPlay()) { - _seats[i].setText(LEAVE_LABEL); - _seats[i].setEnabled(true); - _seats[i].setActionCommand("leave"); - - } else { - _seats[i].setText(table.occupants[i].toString()); - _seats[i].setEnabled(false); - } - } - - // show or hide our "go" button appropriately - _goButton.setVisible(table.gameOid != -1); - } - - /** - * Called by the table list view prior to removing us. Here we clean - * up. - */ - public void tableRemoved () - { - // no more observy - _tdtr.removeSeatednessObserver(this); - } - - // documentation inherited - public void actionPerformed (ActionEvent event) - { - String cmd = event.getActionCommand(); - if (cmd.equals("join")) { - // figure out what position this button is in - int position = -1; - for (int i = 0; i < _seats.length; i++) { - if (_seats[i] == event.getSource()) { - position = i; - break; - } - } - - // sanity check - if (position == -1) { - Log.warning("Unable to figure out what position a " + - "click came from [event=" + event + "]."); - } else { - // otherwise, request to join the table at this position - _tdtr.joinTable(table.getTableId(), position); - } - - } else if (cmd.equals("leave")) { - // if we're not joining, we're leaving - _tdtr.leaveTable(table.getTableId()); - - } else if (cmd.equals("go")) { - // they want to see the game... so go there - _ctx.getLocationDirector().moveTo(table.gameOid); - - } else { - Log.warning("Received unknown action [event=" + event + "]."); - } - } - - // documentation inherited - public void seatednessDidChange (boolean isSeated) - { - // just update ourselves - tableUpdated(table); - - // enable or disable the go button based on our seatedness - if (_goButton.isVisible()) { - _goButton.setEnabled(!isSeated); - } - } - - /** A reference to our context. */ - protected MiCasaContext _ctx; - - /** Our username. */ - protected Name _self; - - /** A reference to our table director. */ - protected TableDirector _tdtr; - - /** We have a button for each "seat" at the table. */ - protected JButton[] _seats; - - /** We have a button for going to games that are already in - * progress. */ - protected JButton _goButton; - - /** The text shown for seats at which the user can join. */ - protected static final String JOIN_LABEL = ""; - - /** The text shown for the seat in which this user occupies and which - * lets her/him know that they can leave that seat by clicking. */ - protected static final String LEAVE_LABEL = ""; -} diff --git a/src/java/com/threerings/micasa/lobby/table/TableListView.java b/src/java/com/threerings/micasa/lobby/table/TableListView.java deleted file mode 100644 index 4c5be67ee..000000000 --- a/src/java/com/threerings/micasa/lobby/table/TableListView.java +++ /dev/null @@ -1,305 +0,0 @@ -// -// $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.micasa.lobby.table; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Iterator; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; - -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.micasa.Log; -import com.threerings.micasa.lobby.LobbyConfig; -import com.threerings.micasa.util.MiCasaContext; - -import com.threerings.parlor.client.SeatednessObserver; -import com.threerings.parlor.client.TableConfigurator; -import com.threerings.parlor.client.TableDirector; -import com.threerings.parlor.client.TableObserver; -import com.threerings.parlor.data.Table; -import com.threerings.parlor.game.client.GameConfigurator; -import com.threerings.parlor.game.client.SwingGameConfigurator; -import com.threerings.parlor.game.data.GameConfig; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -/** - * A view that displays the tables in a table lobby. It displays two - * separate lists, one of tables being matchmade and another of games in - * progress. These tables are updated dynamically as they proceed through - * the matchmaking process. UI mechanisms for creating and joining tables - * are also provided. - */ -public class TableListView extends JPanel - implements PlaceView, TableObserver, ActionListener, SeatednessObserver -{ - /** - * Creates a new table list view, suitable for providing the user - * interface for table-style matchmaking in a table lobby. - */ - public TableListView (MiCasaContext ctx, LobbyConfig config) - { - // keep track of these - _config = config; - _ctx = ctx; - - // create our table director - _tdtr = new TableDirector(ctx, TableLobbyObject.TABLE_SET, this); - - // add ourselves as a seatedness observer - _tdtr.addSeatednessObserver(this); - - // set up a layout manager - HGroupLayout gl = new HGroupLayout(HGroupLayout.STRETCH); - gl.setOffAxisPolicy(HGroupLayout.STRETCH); - setLayout(gl); - - // we have two lists of tables, one of tables being matchmade... - VGroupLayout pgl = new VGroupLayout(VGroupLayout.STRETCH); - pgl.setOffAxisPolicy(VGroupLayout.STRETCH); - JPanel panel = new JPanel(pgl); - panel.add(new JLabel("Pending tables"), VGroupLayout.FIXED); - - VGroupLayout mgl = new VGroupLayout(VGroupLayout.NONE); - mgl.setOffAxisPolicy(VGroupLayout.STRETCH); - mgl.setJustification(VGroupLayout.TOP); - _matchList = new JPanel(mgl); - _matchList.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - panel.add(new JScrollPane(_matchList)); - - // create and initialize the configurator interface - GameConfig gconfig = null; - try { - gconfig = config.getGameConfig(); - - _tableFigger = gconfig.createTableConfigurator(); - if (_tableFigger == null) { - Log.warning("Game config has not been set up to work with " + - "tables: it needs to return non-null from " + - "createTableConfigurator()."); - // let's just wait until we throw an NPE below - } - - _figger = gconfig.createConfigurator(); - _tableFigger.init(_ctx, _figger); - if (_figger != null) { - _figger.init(_ctx); - _figger.setGameConfig(gconfig); - panel.add(((SwingGameConfigurator) _figger).getPanel(), - VGroupLayout.FIXED); - } - - _create = new JButton("Create table"); - _create.addActionListener(this); - panel.add(_create, VGroupLayout.FIXED); - - } catch (Exception e) { - Log.warning("Unable to create configurator interface " + - "[config=" + gconfig + "]."); - Log.logStackTrace(e); - - // stick something in the UI to let them know we're hosed - panel.add(new JLabel("Aiya! Can't create tables. " + - "Configuration borked."), VGroupLayout.FIXED); - } - - add(panel); - - // ...and one of games in progress - panel = new JPanel(pgl); - panel.add(new JLabel("Games in progress"), VGroupLayout.FIXED); - - _playList = new JPanel(mgl); - _playList.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - panel.add(new JScrollPane(_playList)); - - add(panel); - } - - // documentation inherited - public void willEnterPlace (PlaceObject place) - { - // pass the good word on to our table director - _tdtr.willEnterPlace(place); - - // iterate over the tables already active in this lobby and put - // them in their respective lists - TableLobbyObject tlobj = (TableLobbyObject)place; - Iterator iter = tlobj.tableSet.iterator(); - while (iter.hasNext()) { - tableAdded((Table)iter.next()); - } - } - - // documentation inherited - public void didLeavePlace (PlaceObject place) - { - // pass the good word on to our table director - _tdtr.didLeavePlace(place); - - // clear out our table lists - _matchList.removeAll(); - _playList.removeAll(); - } - - // documentation inherited - public void tableAdded (Table table) - { - Log.info("Table added [table=" + table + "]."); - - // create a table item for this table and insert it into the - // appropriate list - JPanel panel = table.inPlay() ? _playList : _matchList; - panel.add(new TableItem(_ctx, _tdtr, table)); - SwingUtil.refresh(panel); - } - - // documentation inherited - public void tableUpdated (Table table) - { - Log.info("Table updated [table=" + table + "]."); - - // locate the table item associated with this table - TableItem item = getTableItem(table.getTableId()); - if (item == null) { - Log.warning("Received table updated notification for " + - "unknown table [table=" + table + "]."); - return; - } - - // let the item perform any updates it finds necessary - item.tableUpdated(table); - - // and we may need to move the item from the match to the in-play - // list if it just transitioned - if (table.gameOid != -1 && item.getParent() == _matchList) { - _matchList.remove(item); - SwingUtil.refresh(_matchList); - _playList.add(item); - SwingUtil.refresh(_playList); - } - } - - // documentation inherited - public void tableRemoved (int tableId) - { - Log.info("Table removed [tableId=" + tableId + "]."); - - // locate the table item associated with this table - TableItem item = getTableItem(tableId); - if (item == null) { - Log.warning("Received table removed notification for " + - "unknown table [tableId=" + tableId + "]."); - return; - } - - // remove this item from the user interface - JPanel panel = (JPanel)item.getParent(); - panel.remove(item); - SwingUtil.refresh(panel); - - // let the little fellow know that we gave him the boot - item.tableRemoved(); - } - - // documentation inherited - public void actionPerformed (ActionEvent event) - { - // the create table button was clicked. use the game config as - // configured by the configurator to create a table - _tdtr.createTable(_tableFigger.getTableConfig(), - _figger.getGameConfig()); - } - - // documentation inherited - public void seatednessDidChange (boolean isSeated) - { - // update the create table button - _create.setEnabled(!isSeated); - } - - /** - * Fetches the table item component associated with the specified - * table id. - */ - protected TableItem getTableItem (int tableId) - { - // first check the match list - int ccount = _matchList.getComponentCount(); - for (int i = 0; i < ccount; i++) { - TableItem child = (TableItem)_matchList.getComponent(i); - if (child.table.getTableId() == tableId) { - return child; - } - } - - // then the inplay list - ccount = _playList.getComponentCount(); - for (int i = 0; i < ccount; i++) { - TableItem child = (TableItem)_playList.getComponent(i); - if (child.table.getTableId() == tableId) { - return child; - } - } - - // sorry charlie - return null; - } - - /** A reference to the client context. */ - protected MiCasaContext _ctx; - - /** A reference to the lobby config for the lobby in which we are - * doing table-style matchmaking. */ - protected LobbyConfig _config; - - /** A reference to our table director. */ - protected TableDirector _tdtr; - - /** The list of tables currently being matchmade. */ - protected JPanel _matchList; - - /** The list of tables that are in play. */ - protected JPanel _playList; - - /** The interface used to configure the table for a game. */ - protected TableConfigurator _tableFigger; - - /** The interface used to configure a game before creating it. */ - protected GameConfigurator _figger; - - /** Our create table button. */ - protected JButton _create; - - /** Our number of players indicator. */ - protected JLabel _pcount; -} diff --git a/src/java/com/threerings/micasa/lobby/table/TableLobbyConfig.java b/src/java/com/threerings/micasa/lobby/table/TableLobbyConfig.java deleted file mode 100644 index 5676f5d44..000000000 --- a/src/java/com/threerings/micasa/lobby/table/TableLobbyConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// $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.micasa.lobby.table; - -import javax.swing.JComponent; -import com.threerings.micasa.lobby.LobbyConfig; -import com.threerings.micasa.util.MiCasaContext; - -/** - * Instructs the lobby services to use a {@link TableListView} as the - * matchmaking component. - */ -public class TableLobbyConfig extends LobbyConfig -{ - // documentation inherited - public String getManagerClassName () - { - return "com.threerings.micasa.lobby.table.TableLobbyManager"; - } - - // documentation inherited - public JComponent createMatchMakingView (MiCasaContext ctx) - { - return new TableListView(ctx, this); - } -} diff --git a/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java b/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java deleted file mode 100644 index a0d3a6aee..000000000 --- a/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// $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.micasa.lobby.table; - -import com.threerings.parlor.server.TableManager; -import com.threerings.parlor.server.TableManagerProvider; -import com.threerings.micasa.lobby.LobbyManager; - -/** - * Extends lobby manager only to ensure that a table lobby object is used - * for table lobbies. - */ -public class TableLobbyManager - extends LobbyManager implements TableManagerProvider -{ - // documentation inherited - protected void didStartup () - { - super.didStartup(); - - // now that we have our place object, we can create our table - // manager - _tmgr = new TableManager(this); - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return TableLobbyObject.class; - } - - // documentation inherited - public TableManager getTableManager () - { - return _tmgr; - } - - /** A reference to our table manager. */ - protected TableManager _tmgr; -} diff --git a/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java b/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java deleted file mode 100644 index 2df53f718..000000000 --- a/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// $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.micasa.lobby.table; - -import com.threerings.presents.dobj.DSet; -import com.threerings.parlor.data.Table; -import com.threerings.micasa.lobby.LobbyObject; - -public class TableLobbyObject - extends LobbyObject - implements com.threerings.parlor.data.TableLobbyObject -{ - // AUTO-GENERATED: FIELDS START - /** The field name of the tableSet field. */ - public static final String TABLE_SET = "tableSet"; - // AUTO-GENERATED: FIELDS END - - /** A set containing all of the tables being managed by this lobby. */ - public DSet tableSet = new DSet(); - - // documentation inherited - public DSet getTables () - { - return tableSet; - } - - // documentation inherited from interface - public void addToTables (Table table) - { - addToTableSet(table); - } - - // documentation inherited from interface - public void updateTables (Table table) - { - updateTableSet(table); - } - - // documentation inherited from interface - public void removeFromTables (Comparable key) - { - removeFromTableSet(key); - } - - // AUTO-GENERATED: METHODS START - /** - * Requests that the specified entry be added to the - * tableSet set. The set will not change until the event is - * actually propagated through the system. - */ - public void addToTableSet (DSet.Entry elem) - { - requestEntryAdd(TABLE_SET, tableSet, elem); - } - - /** - * Requests that the entry matching the supplied key be removed from - * the tableSet set. The set will not change until the - * event is actually propagated through the system. - */ - public void removeFromTableSet (Comparable key) - { - requestEntryRemove(TABLE_SET, tableSet, key); - } - - /** - * Requests that the specified entry be updated in the - * tableSet set. The set will not change until the event is - * actually propagated through the system. - */ - public void updateTableSet (DSet.Entry elem) - { - requestEntryUpdate(TABLE_SET, tableSet, elem); - } - - /** - * Requests that the tableSet field be set to the - * specified value. Generally one only adds, updates and removes - * entries of a distributed set, but certain situations call for a - * complete replacement of the set value. The local value will be - * updated immediately and an event will be propagated through the - * system to notify all listeners that the attribute did - * change. Proxied copies of this object (on clients) will apply the - * value change when they received the attribute changed notification. - */ - public void setTableSet (DSet value) - { - requestAttributeChange(TABLE_SET, value, this.tableSet); - this.tableSet = (value == null) ? null : value.typedClone(); - } - // AUTO-GENERATED: METHODS END -} diff --git a/src/java/com/threerings/micasa/server/MiCasaClient.java b/src/java/com/threerings/micasa/server/MiCasaClient.java deleted file mode 100644 index fccc97e83..000000000 --- a/src/java/com/threerings/micasa/server/MiCasaClient.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.micasa.server; - -import com.threerings.presents.net.BootstrapData; -import com.threerings.crowd.server.CrowdClient; - -import com.threerings.micasa.data.MiCasaBootstrapData; - -/** - * Extends the Crowd client and provides bootstrap data specific to the - * MiCasa services. - */ -public class MiCasaClient extends CrowdClient -{ - // documentation inherited - protected BootstrapData createBootstrapData () - { - return new MiCasaBootstrapData(); - } - - // documentation inherited - protected void populateBootstrapData (BootstrapData data) - { - super.populateBootstrapData(data); - - // let the client know their default lobby oid - ((MiCasaBootstrapData)data).defLobbyOid = - MiCasaServer.lobreg.getDefaultLobbyOid(); - } -} diff --git a/src/java/com/threerings/micasa/server/MiCasaConfig.java b/src/java/com/threerings/micasa/server/MiCasaConfig.java deleted file mode 100644 index 977e1993e..000000000 --- a/src/java/com/threerings/micasa/server/MiCasaConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// $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.micasa.server; - -import com.samskivert.util.Config; - -/** - * Provides access to the MiCasa server configuration. - */ -public class MiCasaConfig -{ - /** Provides access to configuration data for this package. */ - public static Config config = new Config("rsrc/config/micasa/server"); -} diff --git a/src/java/com/threerings/micasa/server/MiCasaServer.java b/src/java/com/threerings/micasa/server/MiCasaServer.java deleted file mode 100644 index 801572f8a..000000000 --- a/src/java/com/threerings/micasa/server/MiCasaServer.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.micasa.server; - -import com.threerings.crowd.server.CrowdServer; -import com.threerings.parlor.server.ParlorManager; - -import com.threerings.micasa.Log; -import com.threerings.micasa.lobby.LobbyRegistry; - -/** - * This class is the main entry point and general organizer of everything - * that goes on in the MiCasa game server process. - */ -public class MiCasaServer extends CrowdServer -{ - /** The parlor manager in operation on this server. */ - public static ParlorManager parmgr = new ParlorManager(); - - /** The lobby registry operating on this server. */ - public static LobbyRegistry lobreg = new LobbyRegistry(); - - /** - * Initializes all of the server services and prepares for operation. - */ - public void init () - throws Exception - { - // do the base server initialization - super.init(); - - // configure the client manager to use our client class - clmgr.setClientClass(MiCasaClient.class); - - // initialize our parlor manager - parmgr.init(invmgr, plreg); - - // initialize the lobby registry - lobreg.init(invmgr); - - Log.info("MiCasa server initialized."); - } - - public static void main (String[] args) - { - MiCasaServer server = new MiCasaServer(); - try { - server.init(); - server.run(); - } catch (Exception e) { - Log.warning("Unable to initialize server."); - Log.logStackTrace(e); - } - } -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimpleClient.java b/src/java/com/threerings/micasa/simulator/client/SimpleClient.java deleted file mode 100644 index 66a0e9316..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimpleClient.java +++ /dev/null @@ -1,197 +0,0 @@ -// -// $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.micasa.simulator.client; - -import java.awt.EventQueue; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import java.io.IOException; - -import javax.swing.JPanel; - -import com.samskivert.util.Config; -import com.samskivert.util.RunQueue; -import com.threerings.util.MessageManager; - -import com.threerings.presents.client.Client; -import com.threerings.presents.dobj.DObjectManager; - -import com.threerings.crowd.client.LocationDirector; -import com.threerings.crowd.client.OccupantDirector; -import com.threerings.crowd.client.PlaceView; - -import com.threerings.crowd.chat.client.ChatDirector; - -import com.threerings.parlor.client.ParlorDirector; -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.micasa.client.MiCasaFrame; -import com.threerings.micasa.util.MiCasaContext; - -public class SimpleClient - implements RunQueue, SimulatorClient -{ - public SimpleClient (SimulatorFrame frame) - throws IOException - { - // create our context - _ctx = createContext(); - - // create the handles on our various services - _client = new Client(null, this); - - // create our managers and directors - _msgmgr = new MessageManager(getMessageManagerPrefix()); - _locdir = new LocationDirector(_ctx); - _occdir = new OccupantDirector(_ctx); - _pardtr = new ParlorDirector(_ctx); - _chatdir = new ChatDirector(_ctx, _msgmgr, null); - - // keep this for later - _frame = frame; - - // log off when they close the window - _frame.getFrame().addWindowListener(new WindowAdapter() { - public void windowClosing (WindowEvent evt) { - // if we're logged on, log off - if (_client.isLoggedOn()) { - _client.logoff(true); - } - } - }); - } - - /** - * Creates our context reference. - */ - protected MiCasaContext createContext () - { - return new MiCasaContextImpl(); - } - - /** - * Returns the prefix used by the message manager when looking for - * translation properties files. - */ - protected String getMessageManagerPrefix () - { - return "rsrc"; - } - - /** - * Returns a reference to the context in effect for this client. This - * reference is valid for the lifetime of the application. - */ - public ParlorContext getParlorContext () - { - return _ctx; - } - - // documentation inherited from interface RunQueue - public void postRunnable (Runnable run) - { - // queue it on up on the awt thread - EventQueue.invokeLater(run); - } - - // documentation inherited from interface RunQueue - public boolean isDispatchThread () - { - return EventQueue.isDispatchThread(); - } - - /** - * The context implementation. This provides access to all of the - * objects and services that are needed by the operating client. - */ - protected class MiCasaContextImpl implements MiCasaContext - { - public Config getConfig () - { - return _config; - } - - public Client getClient () - { - return _client; - } - - public DObjectManager getDObjectManager () - { - return _client.getDObjectManager(); - } - - public LocationDirector getLocationDirector () - { - return _locdir; - } - - public OccupantDirector getOccupantDirector () - { - return _occdir; - } - - public ParlorDirector getParlorDirector () - { - return _pardtr; - } - - public ChatDirector getChatDirector () - { - return _chatdir; - } - - public void setPlaceView (PlaceView view) - { - // stick the place view into our frame - _frame.setPanel((JPanel)view); - } - - public void clearPlaceView (PlaceView view) - { - // we'll just let the next view replace the old one - } - - public MiCasaFrame getFrame () - { - return (MiCasaFrame)_frame; - } - - public MessageManager getMessageManager () - { - return _msgmgr; - } - } - - protected MiCasaContext _ctx; - protected SimulatorFrame _frame; - protected MessageManager _msgmgr; - - protected Config _config = new Config("micasa"); - protected Client _client; - protected LocationDirector _locdir; - protected OccupantDirector _occdir; - protected ParlorDirector _pardtr; - protected ChatDirector _chatdir; -} - diff --git a/src/java/com/threerings/micasa/simulator/client/SimpleFrame.java b/src/java/com/threerings/micasa/simulator/client/SimpleFrame.java deleted file mode 100644 index ce6599f94..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimpleFrame.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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.micasa.simulator.client; - -import javax.swing.JFrame; - -import com.samskivert.swing.Controller; - -import com.threerings.micasa.client.MiCasaFrame; - -/** - * Contains the user interface for the Simulator client application. - */ -public class SimpleFrame extends MiCasaFrame - implements SimulatorFrame -{ - /** - * Constructs the top-level Simulator client frame. - */ - public SimpleFrame () - { - super("Simulator"); - } - - // documentation inherited - public JFrame getFrame () - { - return this; - } - - protected Controller _controller; -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimulatorApp.java b/src/java/com/threerings/micasa/simulator/client/SimulatorApp.java deleted file mode 100644 index 7d65ff1a2..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimulatorApp.java +++ /dev/null @@ -1,227 +0,0 @@ -// -// $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.micasa.simulator.client; - -import javax.swing.JFrame; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.util.SwingUtil; -import com.samskivert.util.Interval; -import com.samskivert.util.ResultListener; - -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.ClientAdapter; -import com.threerings.presents.net.UsernamePasswordCreds; - -import com.threerings.micasa.Log; -import com.threerings.micasa.simulator.data.SimulatorInfo; -import com.threerings.micasa.simulator.server.SimpleServer; -import com.threerings.micasa.simulator.server.SimulatorServer; - -/** - * The simulator application is a test harness to facilitate development - * and debugging of games. - */ -public class SimulatorApp -{ - public void start (final String[] args) throws Exception - { - // create a frame - _frame = createSimulatorFrame(); - - // create the simulator info object - SimulatorInfo siminfo = new SimulatorInfo(); - siminfo.gameConfigClass = args[0]; - siminfo.simClass = args[1]; - siminfo.playerCount = getInt( - System.getProperty("playercount"), DEFAULT_PLAYER_COUNT); - - // create our client instance - _client = createSimulatorClient(_frame); - - // set up the top-level client controller - Controller ctrl = createController(siminfo); - _frame.setController(ctrl); - - // create the server - SimulatorServer server = createSimulatorServer(); - server.init(new ResultListener() { - public void requestCompleted (Object result) { - try { - run(); - } catch (Exception e) { - Log.warning("Simulator initialization failed " + - "[e=" + e + "]."); - } - } - public void requestFailed (Exception e) { - Log.warning("Simulator initialization failed [e=" + e + "]."); - } - }); - - // run the server on a separate thread - _serverThread = new ServerThread(server); - // start up the server so that we can be notified when - // initialization is complete - _serverThread.start(); - } - - protected SimulatorServer createSimulatorServer () - { - return new SimpleServer(); - } - - protected SimulatorFrame createSimulatorFrame () - { - return new SimpleFrame(); - } - - protected SimulatorClient createSimulatorClient (SimulatorFrame frame) - throws Exception - { - return new SimpleClient(_frame); - } - - protected SimulatorController createController (SimulatorInfo siminfo) - { - return new SimulatorController( - _client.getParlorContext(), _frame, siminfo); - } - - public void run () - { - // configure and display the main frame - JFrame frame = _frame.getFrame(); - frame.setSize(800, 600); - SwingUtil.centerWindow(frame); - frame.setVisible(true); - - // start up the client - Client client = _client.getParlorContext().getClient(); - Log.info("Connecting to localhost."); - client.setServer("localhost", Client.DEFAULT_SERVER_PORTS); - - // we want to exit when we logged off or failed to log on - client.addClientObserver(new ClientAdapter() { - public void clientFailedToLogon (Client c, Exception cause) { - Log.info("Client failed to logon: " + cause); - System.exit(0); - } - public void clientDidLogoff (Client c) { - System.exit(0); - } - }); - - // configure the client with some credentials and logon - String username = System.getProperty("username"); - if (username == null) { - username = - "bob" + ((int)(Math.random() * Integer.MAX_VALUE) % 500); - } - String password = System.getProperty("password"); - if (password == null) { - password = "test"; - } - - // create and set our credentials - client.setCredentials( - new UsernamePasswordCreds(new Name(username), password)); - - // this is a bit of a hack, but we need to give the server long - // enough to fully initialize and start listening on its socket - // before we try to logon; there's no good way for this otherwise - // wholly independent thread to wait for the server to be ready as - // in normal circumstances they are entirely different processes; - // so we just wait half a second which does the job - new Interval() { - public void expired () { - _client.getParlorContext().getClient().logon(); - } - }.schedule(500L); - } - - public static void main (String[] args) - { - if (!checkArgs(args)) { - return; - } - - SimulatorApp app = new SimulatorApp(); - try { - app.start(args); - } catch (Exception e) { - Log.warning("Error starting up application."); - Log.logStackTrace(e); - } - } - - protected static boolean checkArgs (String[] args) - { - if (args.length < 2) { - String msg = "Usage:\n" + - " java com.threerings.simulator.SimulatorApp " + - " \n" + - "Optional properties:\n" + - " -Dusername=\n" + - " -Dplayercount=\n" + - " -Dwidth=\n" + - " -Dheight="; - System.out.println(msg); - return false; - } - - return true; - } - - protected int getInt (String value, int defval) - { - try { - return Integer.parseInt(value); - } catch (NumberFormatException nfe) { - return defval; - } - } - - protected static class ServerThread extends Thread - { - public ServerThread (SimulatorServer server) - { - _server = server; - } - - public void run () - { - _server.run(); - } - - protected SimulatorServer _server; - } - - protected SimulatorClient _client; - protected SimulatorFrame _frame; - protected ServerThread _serverThread; - - /** The default number of players in the game. */ - protected static final int DEFAULT_PLAYER_COUNT = 2; -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimulatorClient.java b/src/java/com/threerings/micasa/simulator/client/SimulatorClient.java deleted file mode 100644 index d8b4a6ec3..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimulatorClient.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// $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.micasa.simulator.client; - -import com.threerings.parlor.util.ParlorContext; - -public interface SimulatorClient -{ - public ParlorContext getParlorContext (); -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimulatorController.java b/src/java/com/threerings/micasa/simulator/client/SimulatorController.java deleted file mode 100644 index 39745c6ea..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimulatorController.java +++ /dev/null @@ -1,134 +0,0 @@ -// -// $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.micasa.simulator.client; - -import java.awt.event.ActionEvent; -import com.samskivert.swing.Controller; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.SessionObserver; - -import com.threerings.crowd.data.BodyObject; - -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.micasa.Log; -import com.threerings.micasa.simulator.data.SimulatorInfo; - -/** - * Responsible for top-level control of the simulator client user interface. - */ -public class SimulatorController extends Controller - implements SessionObserver -{ - /** Command constant used to logoff the client. */ - public static final String LOGOFF = "logoff"; - -// 577-2028 - - /** - * Creates a new simulator controller. The controller will set - * everything up in preparation for logging on. - */ - public SimulatorController (ParlorContext ctx, SimulatorFrame frame, - SimulatorInfo info) - { - // we'll want to keep these around - _ctx = ctx; - _frame = frame; - _info = info; - - // we want to know about logon/logoff - _ctx.getClient().addClientObserver(this); - } - - // documentation inherited - public boolean handleAction (ActionEvent action) - { - String cmd = action.getActionCommand(); - - if (cmd.equals(LOGOFF)) { - // request that we logoff - _ctx.getClient().logoff(true); - return true; - } - - Log.info("Unhandled action: " + action); - return false; - } - - // documentation inherited - public void clientDidLogon (Client client) - { - Log.info("Client did logon [client=" + client + "]."); - - // keep the body object around for stuff - _body = (BodyObject)client.getClientObject(); - - // have at it - createGame(client); - } - - public void createGame (Client client) - { - GameConfig config = null; - try { - // create the game config object - config = (GameConfig) - Class.forName(_info.gameConfigClass).newInstance(); - - // get the simulator service and use it to request that our - // game be created - SimulatorService sservice = (SimulatorService) - client.requireService(SimulatorService.class); - sservice.createGame( - client, config, _info.simClass, _info.playerCount); - - // our work here is done, as the location manager will move us - // into the game room straightaway - - } catch (Exception e) { - Log.warning("Failed to instantiate game config " + - "[class=" + _info.gameConfigClass + - ", error=" + e + "]."); - } - } - - // documentation inherited - public void clientObjectDidChange (Client client) - { - // regrab our body object - _body = (BodyObject)client.getClientObject(); - } - - // documentation inherited - public void clientDidLogoff (Client client) - { - Log.info("Client did logoff [client=" + client + "]."); - } - - protected ParlorContext _ctx; - protected SimulatorFrame _frame; - protected SimulatorInfo _info; - protected BodyObject _body; -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimulatorFrame.java b/src/java/com/threerings/micasa/simulator/client/SimulatorFrame.java deleted file mode 100644 index 1926cffea..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimulatorFrame.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// $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.micasa.simulator.client; - -import javax.swing.JFrame; -import javax.swing.JPanel; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.ControllerProvider; - -/** - * Contains the user interface for the Simulator client application. - */ -public interface SimulatorFrame extends ControllerProvider -{ - /** - * Returns a reference to the top-level frame that the simulator will - * use to display everything. - */ - public JFrame getFrame (); - - /** - * Sets the panel that makes up the entire client display. - */ - public void setPanel (JPanel panel); - - /** - * Sets the controller for the outermost scope. This controller will - * handle all actions that aren't handled by controllers of higher - * scope. - */ - public void setController (Controller controller); -} diff --git a/src/java/com/threerings/micasa/simulator/client/SimulatorService.java b/src/java/com/threerings/micasa/simulator/client/SimulatorService.java deleted file mode 100644 index f444aee29..000000000 --- a/src/java/com/threerings/micasa/simulator/client/SimulatorService.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $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.micasa.simulator.client; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -import com.threerings.parlor.game.data.GameConfig; - -/** - * Provides access to simulator invocation services. - */ -public interface SimulatorService extends InvocationService -{ - /** - * Requests that a new game be created. - * - * @param client a connected, operational client instance. - * @param config the game config for the game to be created. - * @param simClass the class name of the simulant to create. - * @param playerCount the number of players in the game. - */ - public void createGame (Client client, GameConfig config, - String simClass, int playerCount); -} diff --git a/src/java/com/threerings/micasa/simulator/data/SimulatorInfo.java b/src/java/com/threerings/micasa/simulator/data/SimulatorInfo.java deleted file mode 100644 index 2cd1dbadc..000000000 --- a/src/java/com/threerings/micasa/simulator/data/SimulatorInfo.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// $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.micasa.simulator.data; - -public class SimulatorInfo -{ - /** The game config classname. */ - public String gameConfigClass; - - /** The simulant classname. */ - public String simClass; - - /** The number of players in the game. */ - public int playerCount; - - public String toString () - { - return "[gameConfigClass=" + gameConfigClass + - ", simClass=" + simClass + ", playerCount=" + playerCount + "]"; - } -} diff --git a/src/java/com/threerings/micasa/simulator/data/SimulatorMarshaller.java b/src/java/com/threerings/micasa/simulator/data/SimulatorMarshaller.java deleted file mode 100644 index 43fbee69b..000000000 --- a/src/java/com/threerings/micasa/simulator/data/SimulatorMarshaller.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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.micasa.simulator.data; - -import com.threerings.micasa.simulator.client.SimulatorService; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; - -/** - * Provides the implementation of the {@link SimulatorService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class SimulatorMarshaller extends InvocationMarshaller - implements SimulatorService -{ - /** The method id used to dispatch {@link #createGame} requests. */ - public static final int CREATE_GAME = 1; - - // documentation inherited from interface - public void createGame (Client arg1, GameConfig arg2, String arg3, int arg4) - { - sendRequest(arg1, CREATE_GAME, new Object[] { - arg2, arg3, Integer.valueOf(arg4) - }); - } - -} diff --git a/src/java/com/threerings/micasa/simulator/server/SimpleServer.java b/src/java/com/threerings/micasa/simulator/server/SimpleServer.java deleted file mode 100644 index bbf560731..000000000 --- a/src/java/com/threerings/micasa/simulator/server/SimpleServer.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.micasa.simulator.server; - -import com.samskivert.util.ResultListener; - -import com.threerings.micasa.server.MiCasaServer; - -/** - * A simple simulator server implementation that extends the MiCasa server - * and provides no special functionality. - */ -public class SimpleServer extends MiCasaServer - implements SimulatorServer -{ - // documentation inherited - public void init (ResultListener obs) - throws Exception - { - super.init(); - - // create the simulator manager - SimulatorManager simmgr = new SimulatorManager(); - simmgr.init(invmgr, plreg, clmgr, omgr, this); - - if (obs != null) { - // let the initialization observer know that we've started up - obs.requestCompleted(this); - } - } -} diff --git a/src/java/com/threerings/micasa/simulator/server/Simulant.java b/src/java/com/threerings/micasa/simulator/server/Simulant.java deleted file mode 100644 index 5256f5acd..000000000 --- a/src/java/com/threerings/micasa/simulator/server/Simulant.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// $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.micasa.simulator.server; - -import com.threerings.presents.dobj.DObjectManager; -import com.threerings.presents.dobj.MessageEvent; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.server.GameManager; - -public abstract class Simulant -{ - /** - * Initializes the simulant with a body object and the game config for - * the game they'll be engaged in. - */ - public void init (BodyObject self, GameConfig config, - GameManager gmgr, DObjectManager omgr) - { - _self = self; - _config = config; - _gmgr = gmgr; - _omgr = omgr; - } - - /** - * Called when the simulant is about to enter the room in which it - * will be doing all of its business. Default implementation - * immediately notifies the game manager that the simulant is ready to - * play. Sub-classes may wish to override this to do things like - * subscribe to the game object, but should be sure to call this - * method when they're finished to give the game manager the go-ahead - * to proceed. - */ - public void willEnterPlace (PlaceObject plobj) - { - // let the game manager know that the simulant's ready - _gmgr.playerReady(_self); - } - - /** - * Posts the given message event to the server. Since the simulant - * resides within the server itself, it has no available client - * distributed object manager and so we must set up the source oid - * ourselves before sending it on its merry way. Sub-classes should - * accordingly be sure to make use of this method to send any - * messages. - */ - protected void postEvent (MessageEvent mevt) - { - mevt.setSourceOid(_self.getOid()); - _omgr.postEvent(mevt); - } - - /** The game config object. */ - protected GameConfig _config; - - /** The game manager for the game we're playing. */ - protected GameManager _gmgr; - - /** Our body object. */ - protected BodyObject _self; - - /** The object manager with which we're interacting. */ - protected DObjectManager _omgr; -} diff --git a/src/java/com/threerings/micasa/simulator/server/SimulatorDispatcher.java b/src/java/com/threerings/micasa/simulator/server/SimulatorDispatcher.java deleted file mode 100644 index 2609a017e..000000000 --- a/src/java/com/threerings/micasa/simulator/server/SimulatorDispatcher.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// $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.micasa.simulator.server; - -import com.threerings.micasa.simulator.client.SimulatorService; -import com.threerings.micasa.simulator.data.SimulatorMarshaller; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; - -/** - * Dispatches requests to the {@link SimulatorProvider}. - */ -public class SimulatorDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public SimulatorDispatcher (SimulatorProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new SimulatorMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case SimulatorMarshaller.CREATE_GAME: - ((SimulatorProvider)provider).createGame( - source, - (GameConfig)args[0], (String)args[1], ((Integer)args[2]).intValue() - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/micasa/simulator/server/SimulatorManager.java b/src/java/com/threerings/micasa/simulator/server/SimulatorManager.java deleted file mode 100644 index 193f07139..000000000 --- a/src/java/com/threerings/micasa/simulator/server/SimulatorManager.java +++ /dev/null @@ -1,237 +0,0 @@ -// -// $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.micasa.simulator.server; - -import java.util.ArrayList; - -import com.threerings.util.Name; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.dobj.RootDObjectManager; -import com.threerings.presents.server.ClientManager; -import com.threerings.presents.server.ClientResolutionListener; -import com.threerings.presents.server.InvocationManager; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.server.PlaceManager; -import com.threerings.crowd.server.PlaceRegistry.CreationObserver; -import com.threerings.crowd.server.PlaceRegistry; - -import com.threerings.parlor.game.data.GameAI; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.game.server.GameManager; - -import com.threerings.micasa.Log; - -/** - * The simulator manager is responsible for handling the simulator - * services on the server side. - */ -public class SimulatorManager -{ - /** - * Initializes the simulator manager manager. This should be called by - * the server that is making use of the simulator services on the - * single instance of simulator manager that it has created. - * - * @param invmgr a reference to the invocation manager in use by this - * server. - */ - public void init (InvocationManager invmgr, PlaceRegistry plreg, - ClientManager clmgr, RootDObjectManager omgr, - SimulatorServer simserv) - { - // register our simulator provider - SimulatorProvider sprov = new SimulatorProvider(this); - invmgr.registerDispatcher(new SimulatorDispatcher(sprov), true); - - // keep these for later - _plreg = plreg; - _clmgr = clmgr; - _omgr = omgr; - _simserv = simserv; - } - - /** - * Creates a game along with the specified number of simulant players - * and forcibly moves all players into the game room. - */ - public void createGame ( - BodyObject source, GameConfig config, String simClass, int playerCount) - { - new CreateGameTask(source, config, simClass, playerCount); - } - - public class CreateGameTask implements CreationObserver - { - public CreateGameTask ( - BodyObject source, GameConfig config, String simClass, - int playerCount) - { - // save off game request info - _source = source; - _config = config; - _simClass = simClass; - _playerCount = playerCount; - - try { - // create the game manager and begin its initialization - // process. the game manager will take care of notifying - // the players that the game has been created once it has - // been started up (which is done by the place registry - // once the game object creation has completed) - - // configure the game config with the player names - config.players = new Name[_playerCount]; - config.players[0] = _source.getVisibleName(); - for (int ii = 1; ii < _playerCount; ii++) { - config.players[ii] = new Name("simulant" + ii); - } - - // we needn't hang around and wait for game object - // creation if it's just us - CreationObserver obs = (_playerCount == 1) ? null : this; - _gmgr = (GameManager)_plreg.createPlace(config, obs); - - } catch (Exception e) { - Log.warning("Unable to create game manager [e=" + e + "]."); - Log.logStackTrace(e); - } - } - - // documentation inherited - public void placeCreated (PlaceObject place, PlaceManager pmgr) - { - // cast the place to the game object for the game we're creating - _gobj = (GameObject)place; - - // determine the AI player skill level - byte skill; - try { - skill = Byte.parseByte(System.getProperty("skill")); - } catch (NumberFormatException nfe) { - skill = DEFAULT_SKILL; - } - - for (int ii = 1; ii < _playerCount; ii++) { - // mark all simulants as AI players - _gmgr.setAI(ii, new GameAI(0, skill)); - } - - // resolve the simulant body objects - ClientResolutionListener listener = new ClientResolutionListener() - { - public void clientResolved (Name username, ClientObject clobj) - { - // hold onto the body object for later game creation - _sims.add(clobj); - - // create the game if we've received all body objects - if (_sims.size() == (_playerCount - 1)) { - createSimulants(); - } - } - - public void resolutionFailed (Name username, Exception cause) - { - Log.warning("Unable to create simulant body object " + - "[error=" + cause + "]."); - } - }; - - // resolve client objects for all of our simulants - for (int ii = 1; ii < _playerCount; ii++) { - Name username = new Name("simulant" + ii); - _clmgr.resolveClientObject(username, listener); - } - } - - /** - * Called when all simulant body objects are present and the - * simulants are ready to be created. - */ - protected void createSimulants () - { - // finish setting up the simulants - for (int ii = 1; ii < _playerCount; ii++) { - // create the simulant object - Simulant sim; - try { - sim = (Simulant)Class.forName(_simClass).newInstance(); - } catch (Exception e) { - Log.warning("Unable to create simulant " + - "[class=" + _simClass + "]."); - return; - } - - // give the simulant its body - BodyObject bobj = (BodyObject)_sims.get(ii - 1); - sim.init(bobj, _config, _gmgr, _omgr); - - // give the simulant a chance to engage in place antics - sim.willEnterPlace(_gobj); - - // move the simulant into the game room since they have no - // location director to move them automagically - try { - _plreg.locprov.moveTo(bobj, _gobj.getOid()); - } catch (Exception e) { - Log.warning("Failed to move simulant into room " + - "[e=" + e + "]."); - return; - } - } - } - - /** The simulant body objects. */ - protected ArrayList _sims = new ArrayList(); - - /** The game object for the game being created. */ - protected GameObject _gobj; - - /** The game manager for the game being created. */ - protected GameManager _gmgr; - - /** The number of players in the game. */ - protected int _playerCount; - - /** The simulant class instantiated on game creation. */ - protected String _simClass; - - /** The game config object. */ - protected GameConfig _config; - - /** The body object of the player requesting the game creation. */ - protected BodyObject _source; - } - - // needed for general operation - protected PlaceRegistry _plreg; - protected ClientManager _clmgr; - protected RootDObjectManager _omgr; - protected SimulatorServer _simserv; - - /** The default skill level for AI players. */ - protected static final byte DEFAULT_SKILL = 50; -} diff --git a/src/java/com/threerings/micasa/simulator/server/SimulatorProvider.java b/src/java/com/threerings/micasa/simulator/server/SimulatorProvider.java deleted file mode 100644 index 901a3812a..000000000 --- a/src/java/com/threerings/micasa/simulator/server/SimulatorProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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.micasa.simulator.server; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationProvider; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.parlor.game.data.GameConfig; - -import com.threerings.micasa.Log; - -/** - * The simulator provider handles game creation requests on the server - * side, passing them off to the {@link SimulatorManager}. - */ -public class SimulatorProvider - implements InvocationProvider -{ - /** - * Constructs a simulator provider. - */ - public SimulatorProvider (SimulatorManager simmgr) - { - _simmgr = simmgr; - } - - /** - * Processes a request from the client to create a new game. - */ - public void createGame (ClientObject caller, GameConfig config, - String simClass, int playerCount) - { - Log.info("handleCreateGameRequest [caller=" + caller.who() + - ", config=" + config + ", simClass=" + simClass + - ", playerCount=" + playerCount + "]."); - - _simmgr.createGame((BodyObject)caller, config, simClass, playerCount); - } - - /** The simulator manager. */ - protected SimulatorManager _simmgr; -} diff --git a/src/java/com/threerings/micasa/simulator/server/SimulatorServer.java b/src/java/com/threerings/micasa/simulator/server/SimulatorServer.java deleted file mode 100644 index 22b048e10..000000000 --- a/src/java/com/threerings/micasa/simulator/server/SimulatorServer.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.micasa.simulator.server; - -import com.samskivert.util.ResultListener; - -/** - * The simulator manager needs a mechanism for faking body object - * registrations, which is provided by implementations of this interface. - */ -public interface SimulatorServer -{ - /** - * Called to initialize this server instance. - * - * @param obs the observer to notify when the server has finished - * starting up, or null if no notification is desired. - * - * @exception Exception thrown if anything goes wrong initializing the - * server. - */ - public void init (ResultListener obs) throws Exception; - - /** - * Called to perform the main body of server processing. This is - * called from the server thread and should do the simulator server's - * primary business. - */ - public void run (); -} diff --git a/src/java/com/threerings/micasa/simulator/util/SimulatorContext.java b/src/java/com/threerings/micasa/simulator/util/SimulatorContext.java deleted file mode 100644 index 30d88c833..000000000 --- a/src/java/com/threerings/micasa/simulator/util/SimulatorContext.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $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.micasa.simulator.util; - -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.micasa.simulator.client.SimulatorFrame; -import com.threerings.micasa.simulator.data.SimulatorInfo; - -/** - * The simulator context encapsulates the contexts of all of the services - * that are used by the simulator client so that we can pass around one - * single context implementation that provides all of the necessary - * components to all of the services in use. - */ -public interface SimulatorContext - extends ParlorContext -{ - /** Returns a reference to the primary user interface frame. */ - public SimulatorFrame getFrame (); - - /** Returns a reference to the simulator info describing the game and - * other details of the simulation. */ - public SimulatorInfo getSimulatorInfo (); -} diff --git a/src/java/com/threerings/micasa/util/MiCasaContext.java b/src/java/com/threerings/micasa/util/MiCasaContext.java deleted file mode 100644 index 0d4626bac..000000000 --- a/src/java/com/threerings/micasa/util/MiCasaContext.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// $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.micasa.util; - -import com.threerings.util.MessageManager; -import com.threerings.parlor.util.ParlorContext; -import com.threerings.micasa.client.MiCasaFrame; - -/** - * The micasa context encapsulates the contexts of all of the services - * that are used by the micasa client so that we can pass around one - * single context implementation that provides all of the necessary - * components to all of the services in use. - */ -public interface MiCasaContext - extends ParlorContext -{ - /** Returns a reference to the primary user interface frame. This can - * be used to set the top-level panel when we enter a game, etc. */ - public MiCasaFrame getFrame (); - - /** - * Returns a reference to the message manager used by the client to - * generate localized messages. - */ - public MessageManager getMessageManager (); -} diff --git a/src/java/com/threerings/miso/Log.java b/src/java/com/threerings/miso/Log.java deleted file mode 100644 index dfb16ad11..000000000 --- a/src/java/com/threerings/miso/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 35c39175d..000000000 --- a/src/java/com/threerings/miso/MisoConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// $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.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 deleted file mode 100644 index eb5d2fb87..000000000 --- a/src/java/com/threerings/miso/MisoPrefs.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a86a4fefc..000000000 --- a/src/java/com/threerings/miso/client/DirtyItemList.java +++ /dev/null @@ -1,680 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 0ad6c57ec..000000000 --- a/src/java/com/threerings/miso/client/MisoScenePanel.java +++ /dev/null @@ -1,1735 +0,0 @@ -// -// $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.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 deleted file mode 100644 index eabdc0298..000000000 --- a/src/java/com/threerings/miso/client/ObjectActionHandler.java +++ /dev/null @@ -1,151 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6c4d28cb0..000000000 --- a/src/java/com/threerings/miso/client/ResolutionView.java +++ /dev/null @@ -1,164 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 82943ef6e..000000000 --- a/src/java/com/threerings/miso/client/SceneBlock.java +++ /dev/null @@ -1,596 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 030ea08ee..000000000 --- a/src/java/com/threerings/miso/client/SceneBlockResolver.java +++ /dev/null @@ -1,138 +0,0 @@ -// -// $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.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 deleted file mode 100644 index fef13e0aa..000000000 --- a/src/java/com/threerings/miso/client/SceneObject.java +++ /dev/null @@ -1,358 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 2a80f7e66..000000000 --- a/src/java/com/threerings/miso/client/SceneObjectActionEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 1d4a05cdf..000000000 --- a/src/java/com/threerings/miso/client/SceneObjectTip.java +++ /dev/null @@ -1,206 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 988cb746b..000000000 --- a/src/java/com/threerings/miso/client/TilePath.java +++ /dev/null @@ -1,144 +0,0 @@ -// -// $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.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 deleted file mode 100644 index e5a0fe780..000000000 --- a/src/java/com/threerings/miso/data/MisoSceneModel.java +++ /dev/null @@ -1,129 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 08f7c29a8..000000000 --- a/src/java/com/threerings/miso/data/ObjectInfo.java +++ /dev/null @@ -1,168 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 8ef84ee89..000000000 --- a/src/java/com/threerings/miso/data/SimpleMisoSceneModel.java +++ /dev/null @@ -1,282 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d32c690a3..000000000 --- a/src/java/com/threerings/miso/data/SparseMisoSceneModel.java +++ /dev/null @@ -1,445 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 42ad656e2..000000000 --- a/src/java/com/threerings/miso/data/VirtualMisoSceneModel.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 08ee9a28e..000000000 --- a/src/java/com/threerings/miso/tile/AutoFringer.java +++ /dev/null @@ -1,390 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 93da583a4..000000000 --- a/src/java/com/threerings/miso/tile/BaseTile.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 99e2dfd41..000000000 --- a/src/java/com/threerings/miso/tile/BaseTileSet.java +++ /dev/null @@ -1,81 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 09945199e..000000000 --- a/src/java/com/threerings/miso/tile/FringeConfiguration.java +++ /dev/null @@ -1,158 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9b5d3d6e2..000000000 --- a/src/java/com/threerings/miso/tile/MisoTileManager.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b107d1a52..000000000 --- a/src/java/com/threerings/miso/tile/tools/CompileFringeConfigurationTask.java +++ /dev/null @@ -1,96 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 9cf7a9136..000000000 --- a/src/java/com/threerings/miso/tile/tools/xml/BaseTileSetRuleSet.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 693b299fe..000000000 --- a/src/java/com/threerings/miso/tile/tools/xml/FringeConfigurationParser.java +++ /dev/null @@ -1,168 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 65a3552dd..000000000 --- a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneParser.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d4396e6bd..000000000 --- a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneRuleSet.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 041e61ffc..000000000 --- a/src/java/com/threerings/miso/tools/xml/SimpleMisoSceneWriter.java +++ /dev/null @@ -1,116 +0,0 @@ -// -// $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.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 deleted file mode 100644 index cef3416c3..000000000 --- a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneParser.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 20ee4218b..000000000 --- a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneRuleSet.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 03b404abd..000000000 --- a/src/java/com/threerings/miso/tools/xml/SparseMisoSceneWriter.java +++ /dev/null @@ -1,131 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 42eabf6ba..000000000 --- a/src/java/com/threerings/miso/util/MisoContext.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c3e6877a6..000000000 --- a/src/java/com/threerings/miso/util/MisoSceneMetrics.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a23ae3ed6..000000000 --- a/src/java/com/threerings/miso/util/MisoUtil.java +++ /dev/null @@ -1,518 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a5e3fda71..000000000 --- a/src/java/com/threerings/miso/util/ObjectSet.java +++ /dev/null @@ -1,182 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 977744281..000000000 --- a/src/java/com/threerings/openal/BlankSound.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $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 deleted file mode 100644 index bda9d8af9..000000000 --- a/src/java/com/threerings/openal/Clip.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// $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 deleted file mode 100644 index f78cebe70..000000000 --- a/src/java/com/threerings/openal/ClipBuffer.java +++ /dev/null @@ -1,287 +0,0 @@ -// -// $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 deleted file mode 100644 index 855be786d..000000000 --- a/src/java/com/threerings/openal/ClipProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// $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 deleted file mode 100644 index ff125d442..000000000 --- a/src/java/com/threerings/openal/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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 deleted file mode 100644 index 562f49802..000000000 --- a/src/java/com/threerings/openal/OggFileStream.java +++ /dev/null @@ -1,121 +0,0 @@ -// -// $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 deleted file mode 100644 index fbe67ca76..000000000 --- a/src/java/com/threerings/openal/Sound.java +++ /dev/null @@ -1,298 +0,0 @@ -// -// $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 deleted file mode 100644 index efd2ec218..000000000 --- a/src/java/com/threerings/openal/SoundGroup.java +++ /dev/null @@ -1,155 +0,0 @@ -// -// $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 deleted file mode 100644 index 3f2a8cc25..000000000 --- a/src/java/com/threerings/openal/SoundManager.java +++ /dev/null @@ -1,347 +0,0 @@ -// -// $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.debug("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 deleted file mode 100644 index 92a06155d..000000000 --- a/src/java/com/threerings/openal/Stream.java +++ /dev/null @@ -1,350 +0,0 @@ -// -// $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 deleted file mode 100644 index 9630e1a69..000000000 --- a/src/java/com/threerings/openal/WaveDataClipProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// $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/parlor/Log.java b/src/java/com/threerings/parlor/Log.java deleted file mode 100644 index f7684f62a..000000000 --- a/src/java/com/threerings/parlor/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.parlor; - -/** - * A placeholder class that contains a reference to the log object used by - * the Parlor services. - */ -public class Log -{ - public static com.samskivert.util.Log log = - new com.samskivert.util.Log("parlor"); - - /** 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/parlor/card/Log.java b/src/java/com/threerings/parlor/card/Log.java deleted file mode 100644 index a10bdab04..000000000 --- a/src/java/com/threerings/parlor/card/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.parlor.card; - -/** - * A placeholder class that contains a reference to the log object used by - * the Card services. - */ -public class Log -{ - public static com.samskivert.util.Log log = - new com.samskivert.util.Log("card"); - - /** 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/parlor/card/client/CardGameController.java b/src/java/com/threerings/parlor/card/client/CardGameController.java deleted file mode 100644 index 9876d306b..000000000 --- a/src/java/com/threerings/parlor/card/client/CardGameController.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// $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.parlor.card.client; - -import com.threerings.util.Name; - -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.card.Log; -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.CardCodes; -import com.threerings.parlor.card.data.Hand; -import com.threerings.parlor.game.client.GameController; -import com.threerings.parlor.turn.client.TurnGameController; - -/** - * A controller class for card games. Handles common functions like - * accepting dealt hands. - */ -public abstract class CardGameController extends GameController - implements TurnGameController, CardCodes, CardGameReceiver -{ - // Documentation inherited. - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - if (_ctx.getClient().getClientObject().receivers.containsKey( - CardGameDecoder.RECEIVER_CODE)) { - Log.warning("Yuh oh, we already have a card game receiver " + - "registered and are trying for another...!"); - Thread.dumpStack(); - } - - _ctx.getClient().getInvocationDirector().registerReceiver( - new CardGameDecoder(this)); - } - - // Documentation inherited. - public void didLeavePlace (PlaceObject plobj) - { - super.didLeavePlace(plobj); - - _ctx.getClient().getInvocationDirector().unregisterReceiver( - CardGameDecoder.RECEIVER_CODE); - } - - // Documentation inherited. - public void turnDidChange (Name turnHolder) - {} - - /** - * Called by our sender to notify us of a received hand. - */ - public final void receivedHand (int oid, Hand hand) - { - if (oid == _gobj.getOid()) { - receivedHand(hand); - } - } - - /** - * Called when the server deals the client a new hand of cards. Default - * implementation does nothing. - * - * @param hand the hand dealt to the user - */ - public void receivedHand (Hand hand) - {} - - /** - * Dispatched to the client when it has received a set of cards - * from another player. Default implementation does nothing. - * - * @param plidx the index of the player providing the cards - * @param cards the cards received - */ - public void receivedCardsFromPlayer (int plidx, Card[] cards) - {} - - /** - * Dispatched to the client when the server has forced it to send - * a set of cards to another player. Default implementation does - * nothing. - * - * @param plidx the index of the player to which the cards were sent - * @param cards the cards sent - */ - public void sentCardsToPlayer (int plidx, Card[] cards) - {} - - /** - * Dispatched to the client when a set of cards is transferred between - * two other players in the game. Default implementation does nothing. - * - * @param fromidx the index of the player sending the cards - * @param toidx the index of the player receiving the cards - * @param cards the number of cards transferred - */ - public void cardsTransferredBetweenPlayers (int fromidx, int toidx, - int cards) - {} -} diff --git a/src/java/com/threerings/parlor/card/client/CardGameDecoder.java b/src/java/com/threerings/parlor/card/client/CardGameDecoder.java deleted file mode 100644 index ab05fcfe6..000000000 --- a/src/java/com/threerings/parlor/card/client/CardGameDecoder.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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.parlor.card.client; - -import com.threerings.parlor.card.client.CardGameReceiver; -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.Hand; -import com.threerings.presents.client.InvocationDecoder; - -/** - * Dispatches calls to a {@link CardGameReceiver} instance. - */ -public class CardGameDecoder extends InvocationDecoder -{ - /** The generated hash code used to identify this receiver class. */ - public static final String RECEIVER_CODE = "0718199d459e31d8d673744c71b0e788"; - - /** The method id used to dispatch {@link CardGameReceiver#cardsTransferredBetweenPlayers} - * notifications. */ - public static final int CARDS_TRANSFERRED_BETWEEN_PLAYERS = 1; - - /** The method id used to dispatch {@link CardGameReceiver#receivedCardsFromPlayer} - * notifications. */ - public static final int RECEIVED_CARDS_FROM_PLAYER = 2; - - /** The method id used to dispatch {@link CardGameReceiver#receivedHand} - * notifications. */ - public static final int RECEIVED_HAND = 3; - - /** The method id used to dispatch {@link CardGameReceiver#sentCardsToPlayer} - * notifications. */ - public static final int SENT_CARDS_TO_PLAYER = 4; - - /** - * Creates a decoder that may be registered to dispatch invocation - * service notifications to the specified receiver. - */ - public CardGameDecoder (CardGameReceiver receiver) - { - this.receiver = receiver; - } - - // documentation inherited - public String getReceiverCode () - { - return RECEIVER_CODE; - } - - // documentation inherited - public void dispatchNotification (int methodId, Object[] args) - { - switch (methodId) { - case CARDS_TRANSFERRED_BETWEEN_PLAYERS: - ((CardGameReceiver)receiver).cardsTransferredBetweenPlayers( - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue() - ); - return; - - case RECEIVED_CARDS_FROM_PLAYER: - ((CardGameReceiver)receiver).receivedCardsFromPlayer( - ((Integer)args[0]).intValue(), (Card[])args[1] - ); - return; - - case RECEIVED_HAND: - ((CardGameReceiver)receiver).receivedHand( - ((Integer)args[0]).intValue(), (Hand)args[1] - ); - return; - - case SENT_CARDS_TO_PLAYER: - ((CardGameReceiver)receiver).sentCardsToPlayer( - ((Integer)args[0]).intValue(), (Card[])args[1] - ); - return; - - default: - super.dispatchNotification(methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/parlor/card/client/CardGameReceiver.java b/src/java/com/threerings/parlor/card/client/CardGameReceiver.java deleted file mode 100644 index f3ebbf708..000000000 --- a/src/java/com/threerings/parlor/card/client/CardGameReceiver.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// $Id: ParlorReceiver.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.parlor.card.client; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.Hand; - -import com.threerings.presents.client.InvocationReceiver; - -/** - * Defines, for the card game services, a set of notifications delivered - * asynchronously by the server to the client. - */ -public interface CardGameReceiver extends InvocationReceiver -{ - /** - * Dispatched to the client when it has received a hand of cards. - * - * @param oid the oid of the game for which this hand applies - * @param hand the received hand - */ - public void receivedHand (int oid, Hand hand); - - /** - * Dispatched to the client when it has received a set of cards - * from another player. - * - * @param plidx the index of the player providing the cards - * @param cards the cards received - */ - public void receivedCardsFromPlayer (int plidx, Card[] cards); - - /** - * Dispatched to the client when the server has forced it to send - * a set of cards to another player. - * - * @param plidx the index of the player to which the cards were sent - * @param cards the cards sent - */ - public void sentCardsToPlayer (int plidx, Card[] cards); - - /** - * Dispatched to the client when a set of cards is transferred between - * two other players in the game. - * - * @param fromidx the index of the player sending the cards - * @param toidx the index of the player receiving the cards - * @param cards the number of cards transferred - */ - public void cardsTransferredBetweenPlayers (int fromidx, int toidx, - int cards); -} diff --git a/src/java/com/threerings/parlor/card/client/CardPanel.java b/src/java/com/threerings/parlor/card/client/CardPanel.java deleted file mode 100644 index aa4403c69..000000000 --- a/src/java/com/threerings/parlor/card/client/CardPanel.java +++ /dev/null @@ -1,1149 +0,0 @@ -// -// $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.parlor.card.client; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.swing.event.MouseInputAdapter; - -import com.samskivert.util.ObserverList; -import com.samskivert.util.QuickSort; - -import com.threerings.media.FrameManager; -import com.threerings.media.VirtualMediaPanel; -import com.threerings.media.image.Mirage; -import com.threerings.media.sprite.PathAdapter; -import com.threerings.media.sprite.Sprite; -import com.threerings.media.util.LinePath; -import com.threerings.media.util.Path; -import com.threerings.media.util.PathSequence; -import com.threerings.media.util.Pathable; - -import com.threerings.parlor.card.Log; -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.CardCodes; -import com.threerings.parlor.card.data.Deck; -import com.threerings.parlor.card.data.Hand; - -/** - * Extends VirtualMediaPanel to provide services specific to rendering - * and manipulating playing cards. - */ -public abstract class CardPanel extends VirtualMediaPanel - implements CardCodes -{ - /** The selection mode in which cards are not selectable. */ - public static final int NONE = 0; - - /** The selection mode in which the user can select a single card. */ - public static final int SINGLE = 1; - - /** The selection mode in which the user can select multiple cards. */ - public static final int MULTIPLE = 2; - - /** - * A predicate class for {@link CardSprite}s. Provides control over which - * cards are selectable, playable, etc. - */ - public static interface CardSpritePredicate - { - /** - * Evaluates the specified sprite. - */ - public boolean evaluate (CardSprite sprite); - } - - /** - * A listener for card selection/deselection. - */ - public static interface CardSelectionObserver - { - /** - * Called when a card has been selected. - */ - public void cardSpriteSelected (CardSprite sprite); - - /** - * Called when a card has been deselected. - */ - public void cardSpriteDeselected (CardSprite sprite); - } - - /** - * Constructor. - * - * @param frameManager the frame manager - */ - public CardPanel (FrameManager frameManager) - { - super(frameManager); - - // add a listener for mouse events - CardListener cl = new CardListener(); - addMouseListener(cl); - addMouseMotionListener(cl); - } - - /** - * Returns the full-sized image for the back of a playing card. - */ - public abstract Mirage getCardBackImage (); - - /** - * Returns the full-sized image for the front of the specified card. - */ - public abstract Mirage getCardImage (Card card); - - /** - * Returns the small-sized image for the back of a playing card. - */ - public abstract Mirage getMicroCardBackImage (); - - /** - * Returns the small-sized image for the front of the specified card. - */ - public abstract Mirage getMicroCardImage (Card card); - - /** - * Sets the location of the hand (the location of the center of the hand's - * upper edge). - */ - public void setHandLocation (int x, int y) - { - _handLocation.setLocation(x, y); - } - - /** - * Sets the horizontal spacing between cards in the hand. - */ - public void setHandSpacing (int spacing) - { - _handSpacing = spacing; - } - - /** - * Sets the vertical distance to offset cards that are selectable or - * playable. - */ - public void setSelectableCardOffset (int offset) - { - _selectableCardOffset = offset; - } - - /** - * Sets the vertical distance to offset cards that are selected. - */ - public void setSelectedCardOffset (int offset) - { - _selectedCardOffset = offset; - } - - /** - * Sets the selection mode for the hand (NONE, PLAY_SINGLE, SINGLE, - * or MULTIPLE). Changing the selection mode does not change the - * current selection. - */ - public void setHandSelectionMode (int mode) - { - _handSelectionMode = mode; - - // update the offsets of all cards in the hand - updateHandOffsets(); - } - - /** - * Sets the selection predicate that determines which cards from the hand - * may be selected (if null, all cards may be selected). Changing the - * predicate does not change the current selection. - */ - public void setHandSelectionPredicate (CardSpritePredicate pred) - { - _handSelectionPredicate = pred; - - // update the offsets of all cards in the hand - updateHandOffsets(); - } - - /** - * Returns the currently selected hand sprite (null if no sprites are - * selected, the first sprite if multiple sprites are selected). - */ - public CardSprite getSelectedHandSprite () - { - return _selectedHandSprites.size() == 0 ? - null : (CardSprite)_selectedHandSprites.get(0); - } - - /** - * Returns an array containing the currently selected hand sprites - * (returns an empty array if no sprites are selected). - */ - public CardSprite[] getSelectedHandSprites () - { - return (CardSprite[])_selectedHandSprites.toArray( - new CardSprite[_selectedHandSprites.size()]); - } - - /** - * Programmatically selects a sprite in the hand. - */ - public void selectHandSprite (final CardSprite sprite) - { - // make sure it's not already selected - if (_selectedHandSprites.contains(sprite)) { - return; - } - - // if in single card mode and there's another card selected, - // deselect it - if (_handSelectionMode == SINGLE) { - CardSprite oldSprite = getSelectedHandSprite(); - if (oldSprite != null) { - deselectHandSprite(oldSprite); - } - } - - // add to list and update offset - _selectedHandSprites.add(sprite); - sprite.setLocation(sprite.getX(), getHandY(sprite)); - - // notify the observers - ObserverList.ObserverOp op = new ObserverList.ObserverOp() { - public boolean apply (Object obs) { - ((CardSelectionObserver)obs).cardSpriteSelected(sprite); - return true; - } - }; - _handSelectionObservers.apply(op); - } - - /** - * Programmatically deselects a sprite in the hand. - */ - public void deselectHandSprite (final CardSprite sprite) - { - // make sure it's selected - if (!_selectedHandSprites.contains(sprite)) { - return; - } - - // remove from list and update offset - _selectedHandSprites.remove(sprite); - sprite.setLocation(sprite.getX(), getHandY(sprite)); - - // notify the observers - ObserverList.ObserverOp op = new ObserverList.ObserverOp() { - public boolean apply (Object obs) { - ((CardSelectionObserver)obs).cardSpriteDeselected(sprite); - return true; - } - }; - _handSelectionObservers.apply(op); - } - - /** - * Clears any existing hand sprite selection. - */ - public void clearHandSelection () - { - CardSprite[] sprites = getSelectedHandSprites(); - for (int i = 0; i < sprites.length; i++) { - deselectHandSprite(sprites[i]); - } - } - - /** - * Adds an object to the list of observers to notify when cards in the - * hand are selected/deselected. - */ - public void addHandSelectionObserver (CardSelectionObserver obs) - { - _handSelectionObservers.add(obs); - } - - /** - * Removes an object from the hand selection observer list. - */ - public void removeHandSelectionObserver (CardSelectionObserver obs) - { - _handSelectionObservers.remove(obs); - } - - /** - * Fades a hand of cards in. - * - * @param hand the hand of cards - * @param fadeDuration the amount of time to spend fading in - * the entire hand - */ - public void setHand (Hand hand, long fadeDuration) - { - // make sure no cards are hanging around - clearHand(); - - // create the sprites - int size = hand.size(); - for (int i = 0; i < size; i++) { - CardSprite cs = new CardSprite(this, (Card)hand.get(i)); - _handSprites.add(cs); - } - - // sort them - if (shouldSortHand()) { - QuickSort.sort(_handSprites); - } - - // fade them in at proper locations and layers - long cardDuration = fadeDuration / size; - for (int i = 0; i < size; i++) { - CardSprite cs = (CardSprite)_handSprites.get(i); - cs.setLocation(getHandX(size, i), _handLocation.y); - cs.setRenderOrder(i); - cs.addSpriteObserver(_handSpriteObserver); - addSprite(cs); - cs.fadeIn(i * cardDuration, cardDuration); - } - - // make sure we have the right card sprite active - updateActiveCardSprite(); - } - - /** - * Fades a hand of cards in face-down. - * - * @param size the size of the hand - * @param fadeDuration the amount of time to spend fading in - * each card - */ - public void setHand (int size, long fadeDuration) - { - // fill hand will null entries to signify unknown cards - Hand hand = new Hand(); - for (int i = 0; i < size; i++) { - hand.add(null); - } - setHand(hand, fadeDuration); - } - - /** - * Shows a hand that was previous set face-down. - * - * @param hand the hand of cards - */ - public void showHand (Hand hand) - { - // sort the hand - if (shouldSortHand()) { - QuickSort.sort(hand); - } - - // set the sprites - int len = Math.min(_handSprites.size(), hand.size()); - for (int i = 0; i < len; i++) { - CardSprite cs = (CardSprite)_handSprites.get(i); - cs.setCard((Card)hand.get(i)); - } - } - - /** - * Returns the first sprite in the hand that corresponds to the - * specified card, or null if the card is not in the hand. - */ - public CardSprite getHandSprite (Card card) - { - return getCardSprite(_handSprites, card); - } - - /** - * Clears all cards from the hand. - */ - public void clearHand () - { - clearHandSelection(); - clearSprites(_handSprites); - } - - /** - * Clears all cards from the board. - */ - public void clearBoard () - { - clearSprites(_boardSprites); - } - - /** - * Flies a set of cards from the hand into the ether. Clears any selected - * cards. - * - * @param cards the card sprites to remove from the hand - * @param dest the point to fly the cards to - * @param flightDuration the duration of the cards' flight - * @param fadePortion the amount of time to spend fading out - * as a proportion of the flight duration - */ - public void flyFromHand (CardSprite[] cards, Point dest, - long flightDuration, float fadePortion) - { - // fly each sprite over, removing it from the hand immediately and - // from the board when it finishes its path - for (int i = 0; i < cards.length; i++) { - removeFromHand(cards[i]); - LinePath flight = new LinePath(dest, flightDuration); - cards[i].addSpriteObserver(_pathEndRemover); - cards[i].moveAndFadeOut(flight, flightDuration, fadePortion); - } - - // adjust the hand to cover the hole - adjustHand(flightDuration, false); - } - - /** - * Flies a set of cards from the ether into the hand. Clears any selected - * cards. The cards will first fly to the selected card offset, pause for - * the specified duration, and then drop into the hand. - * - * @param cards the cards to add to the hand - * @param src the point to fly the cards from - * @param flightDuration the duration of the cards' flight - * @param pauseDuration the duration of the pause before dropping into the - * hand - * @param dropDuration the duration of the cards' drop into the - * hand - * @param fadePortion the amount of time to spend fading in - * as a proportion of the flight duration - */ - public void flyIntoHand (Card[] cards, Point src, long flightDuration, - long pauseDuration, long dropDuration, float fadePortion) - { - // first create the sprites and add them to the list - CardSprite[] sprites = new CardSprite[cards.length]; - for (int i = 0; i < cards.length; i++) { - sprites[i] = new CardSprite(this, cards[i]); - _handSprites.add(sprites[i]); - } - - // settle the hand - adjustHand(flightDuration, true); - - // then set the layers and fly the cards in - int size = _handSprites.size(); - for (int i = 0; i < sprites.length; i++) { - int idx = _handSprites.indexOf(sprites[i]); - sprites[i].setLocation(src.x, src.y); - sprites[i].setRenderOrder(idx); - sprites[i].addSpriteObserver(_handSpriteObserver); - addSprite(sprites[i]); - - // create a path sequence containing flight, pause, and drop - ArrayList paths = new ArrayList(); - Point hp2 = new Point(getHandX(size, idx), _handLocation.y), - hp1 = new Point(hp2.x, hp2.y - _selectedCardOffset); - paths.add(new LinePath(hp1, flightDuration)); - paths.add(new LinePath(hp1, pauseDuration)); - paths.add(new LinePath(hp2, dropDuration)); - sprites[i].moveAndFadeIn(new PathSequence(paths), flightDuration + - pauseDuration + dropDuration, fadePortion); - } - } - - /** - * Flies a set of cards from the ether into the ether. - * - * @param cards the cards to fly across - * @param src the point to fly the cards from - * @param dest the point to fly the cards to - * @param flightDuration the duration of the cards' flight - * @param cardDelay the amount of time to wait between cards - * @param fadePortion the amount of time to spend fading in and out - * as a proportion of the flight duration - */ - public void flyAcross (Card[] cards, Point src, Point dest, - long flightDuration, long cardDelay, float fadePortion) - { - for (int i = 0; i < cards.length; i++) { - // add on top of all board sprites - CardSprite cs = new CardSprite(this, cards[i]); - cs.setRenderOrder(getHighestBoardLayer() + 1 + i); - cs.setLocation(src.x, src.y); - addSprite(cs); - - // prepend an initial delay to all cards after the first - Path path; - long pathDuration; - LinePath flight = new LinePath(dest, flightDuration); - if (i > 0) { - long delayDuration = cardDelay * i; - LinePath delay = new LinePath(src, delayDuration); - path = new PathSequence(delay, flight); - pathDuration = delayDuration + flightDuration; - - } else { - path = flight; - pathDuration = flightDuration; - } - cs.addSpriteObserver(_pathEndRemover); - cs.moveAndFadeInAndOut(path, pathDuration, fadePortion); - } - } - - /** - * Flies a set of cards from the ether into the ether face-down. - * - * @param number the number of cards to fly across - * @param src the point to fly the cards from - * @param dest the point to fly the cards to - * @param flightDuration the duration of the cards' flight - * @param cardDelay the amount of time to wait between cards - * @param fadePortion the amount of time to spend fading in and out - * as a proportion of the flight duration - */ - public void flyAcross (int number, Point src, Point dest, - long flightDuration, long cardDelay, float fadePortion) - { - // use null values to signify unknown cards - flyAcross(new Card[number], src, dest, flightDuration, - cardDelay, fadePortion); - } - - /** - * Flies a card from the hand onto the board. Clears any cards selected. - * - * @param card the sprite to remove from the hand - * @param dest the point to fly the card to - * @param flightDuration the duration of the card's flight - */ - public void flyFromHandToBoard (CardSprite card, Point dest, - long flightDuration) - { - // fly it over - LinePath flight = new LinePath(dest, flightDuration); - card.move(flight); - - // lower the board so that the card from hand is on top - lowerBoardSprites(card.getRenderOrder() - 1); - - // move from one list to the other - removeFromHand(card); - _boardSprites.add(card); - - // adjust the hand to cover the hole - adjustHand(flightDuration, false); - } - - /** - * Flies a card from the ether onto the board. - * - * @param card the card to add to the board - * @param src the point to fly the card from - * @param dest the point to fly the card to - * @param flightDuration the duration of the card's flight - * @param fadePortion the amount of time to spend fading in as a - * proportion of the flight duration - */ - public void flyToBoard (Card card, Point src, Point dest, - long flightDuration, float fadePortion) - { - // add it on top of the existing cards - CardSprite cs = new CardSprite(this, card); - cs.setRenderOrder(getHighestBoardLayer() + 1); - cs.setLocation(src.x, src.y); - addSprite(cs); - _boardSprites.add(cs); - - // and fly it over - LinePath flight = new LinePath(dest, flightDuration); - cs.moveAndFadeIn(flight, flightDuration, fadePortion); - } - - /** - * Adds a card to the board immediately. - * - * @param card the card to add to the board - * @param dest the point at which to add the card - */ - public void addToBoard (Card card, Point dest) - { - CardSprite cs = new CardSprite(this, card); - cs.setRenderOrder(getHighestBoardLayer() + 1); - cs.setLocation(dest.x, dest.y); - addSprite(cs); - _boardSprites.add(cs); - } - - /** - * Flies a set of cards from the board into the ether. - * - * @param cards the cards to remove from the board - * @param dest the point to fly the cards to - * @param flightDuration the duration of the cards' flight - * @param fadePortion the amount of time to spend fading out as a - * proportion of the flight duration - */ - public void flyFromBoard (CardSprite[] cards, Point dest, - long flightDuration, float fadePortion) - { - for (int i = 0; i < cards.length; i++) { - LinePath flight = new LinePath(dest, flightDuration); - cards[i].addSpriteObserver(_pathEndRemover); - cards[i].moveAndFadeOut(flight, flightDuration, fadePortion); - _boardSprites.remove(cards[i]); - } - } - - // documentation inherited - protected void paintBehind (Graphics2D gfx, Rectangle dirtyRect) - { - gfx.setColor(DEFAULT_BACKGROUND); - gfx.fill(dirtyRect); - super.paintBehind(gfx, dirtyRect); - } - - /** - * Flies a set of cards from the board into the ether through an - * intermediate point. - * - * @param cards the cards to remove from the board - * @param dest1 the first point to fly the cards to - * @param dest2 the final destination of the cards - * @param flightDuration the duration of the cards' flight - * @param fadePortion the amount of time to spend fading out as a - * proportion of the flight duration - */ - public void flyFromBoard (CardSprite[] cards, Point dest1, Point dest2, - long flightDuration, float fadePortion) - { - for (int i = 0; i < cards.length; i++) { - PathSequence flight = new PathSequence( - new LinePath(dest1, flightDuration/2), - new LinePath(dest1, dest2, flightDuration/2)); - cards[i].addSpriteObserver(_pathEndRemover); - cards[i].moveAndFadeOut(flight, flightDuration, fadePortion); - _boardSprites.remove(cards[i]); - } - } - - /** - * Returns the first card sprite in the specified list that represents - * the specified card, or null if there is no such sprite in the list. - */ - protected CardSprite getCardSprite (ArrayList list, Card card) - { - for (int i = 0; i < list.size(); i++) { - CardSprite cs = (CardSprite)list.get(i); - if (card.equals(cs.getCard())) { - return cs; - } - } - return null; - } - - /** - * Returns whether the user's hand should be sorted when displayed. By - * default, hands are sorted. - */ - protected boolean shouldSortHand () - { - return true; - } - - /** - * Expands or collapses the hand to accommodate new cards or cover the - * space left by removed cards. Skips unmanaged sprites. Clears out - * any selected cards. - * - * @param adjustDuration the amount of time to spend settling the cards - * into their new locations - * @param updateLayers whether or not to update the layers of the cards - */ - protected void adjustHand (long adjustDuration, boolean updateLayers) - { - // clear out selected cards - clearHandSelection(); - - // Sort the hand - if (shouldSortHand()) { - QuickSort.sort(_handSprites); - } - - // Move each card to its proper position (and, optionally, layer) - int size = _handSprites.size(); - for (int i = 0; i < size; i++) { - CardSprite cs = (CardSprite)_handSprites.get(i); - if (!isManaged(cs)) { - continue; - } - if (updateLayers) { - cs.setRenderOrder(i); - } - LinePath adjust = new LinePath(new Point(getHandX(size, i), - _handLocation.y), adjustDuration); - cs.move(adjust); - } - } - - /** - * Removes a card from the hand. - */ - protected void removeFromHand (CardSprite card) - { - _selectedHandSprites.remove(card); - _handSprites.remove(card); - } - - /** - * Updates the offsets of all the cards in the hand. If there is only - * one selectable card, that card will always be raised slightly. - */ - protected void updateHandOffsets () - { - // make active card sprite is up-to-date - updateActiveCardSprite(); - - int size = _handSprites.size(); - for (int i = 0; i < size; i++) { - CardSprite cs = (CardSprite)_handSprites.get(i); - if (!cs.isMoving()) { - cs.setLocation(cs.getX(), getHandY(cs)); - } - } - } - - /** - * Given the location and spacing of the hand, returns the x location of - * the card at the specified index within a hand of the specified size. - */ - protected int getHandX (int size, int idx) - { - // get the card width from the image if not yet known - if (_cardWidth == 0) { - _cardWidth = getCardBackImage().getWidth(); - } - // first compute the width of the entire hand, then use that to - // determine the centered location - int width = (size - 1) * _handSpacing + _cardWidth; - return (_handLocation.x - width/2) + idx * _handSpacing; - } - - /** - * Determines the y location of the specified card sprite, given its - * selection state. - */ - protected int getHandY (CardSprite sprite) - { - if (_selectedHandSprites.contains(sprite)) { - return _handLocation.y - _selectedCardOffset; - - } else if (isSelectable(sprite) && - (sprite == _activeCardSprite || isOnlySelectable(sprite))) { - return _handLocation.y - _selectableCardOffset; - - } else { - return _handLocation.y; - } - } - - /** - * Given the current selection mode and predicate, determines if the - * specified sprite is selectable. - */ - protected boolean isSelectable (CardSprite sprite) - { - return _handSelectionMode != NONE && - (_handSelectionPredicate == null || - _handSelectionPredicate.evaluate(sprite)); - } - - /** - * Determines whether the specified sprite is the only selectable sprite - * in the hand according to the selection predicate. - */ - protected boolean isOnlySelectable (CardSprite sprite) - { - // if there's no predicate, last remaining card is only selectable - if (_handSelectionPredicate == null) { - return _handSprites.size() == 1 && _handSprites.contains(sprite); - } - - // otherwise, look for a sprite that fits the predicate and isn't the - // parameter - int size = _handSprites.size(); - for (int i = 0; i < size; i++) { - CardSprite cs = (CardSprite)_handSprites.get(i); - if (cs != sprite && _handSelectionPredicate.evaluate(cs)) { - return false; - } - } - return true; - } - - /** - * Lowers all board sprites so that they are rendered at or below the - * specified layer. - */ - protected void lowerBoardSprites (int layer) - { - // see if they're already lower - int highest = getHighestBoardLayer(); - if (highest <= layer) { - return; - } - - // lower them just enough - int size = _boardSprites.size(), adjustment = layer - highest; - for (int i = 0; i < size; i++) { - CardSprite cs = (CardSprite)_boardSprites.get(i); - cs.setRenderOrder(cs.getRenderOrder() + adjustment); - } - } - - /** - * Returns the highest render order of any sprite on the board. - */ - protected int getHighestBoardLayer () - { - // must be at least zero, because that's the lowest number we can push - // the sprites down to (the layer of the first card in the hand) - int size = _boardSprites.size(), highest = 0; - for (int i = 0; i < size; i++) { - highest = Math.max(highest, - ((CardSprite)_boardSprites.get(i)).getRenderOrder()); - } - return highest; - } - - /** - * Clears an array of sprites from the specified list and from the panel. - */ - protected void clearSprites (ArrayList sprites) - { - for (Iterator it = sprites.iterator(); it.hasNext(); ) { - removeSprite((CardSprite)it.next()); - it.remove(); - } - } - - /** - * Updates the active card sprite based on the location of the mouse - * pointer. - */ - protected void updateActiveCardSprite () - { - // can't do anything if we don't know where the mouse pointer is - if (_mouseEvent == null) { - return; - } - - Sprite newHighestHit = _spritemgr.getHighestHitSprite( - _mouseEvent.getX(), _mouseEvent.getY()); - - CardSprite newActiveCardSprite = - (newHighestHit instanceof CardSprite ? - (CardSprite)newHighestHit : null); - - if (_activeCardSprite != newActiveCardSprite) { - if (_activeCardSprite != null && - isManaged(_activeCardSprite)) { - _activeCardSprite.queueNotification( - new CardSpriteExitedOp(_activeCardSprite, - _mouseEvent) - ); - } - _activeCardSprite = newActiveCardSprite; - if (_activeCardSprite != null) { - _activeCardSprite.queueNotification( - new CardSpriteEnteredOp(_activeCardSprite, - _mouseEvent) - ); - } - } - } - - /** The width of the playing cards. */ - protected int _cardWidth; - - /** The last motion/entrance/exit event received from the mouse. */ - protected MouseEvent _mouseEvent; - - /** The currently active card sprite (the one that the mouse is over). */ - protected CardSprite _activeCardSprite; - - /** The sprites for cards within the hand. */ - protected ArrayList _handSprites = new ArrayList(); - - /** The sprites for cards within the hand that have been selected. */ - protected ArrayList _selectedHandSprites = new ArrayList(); - - /** The current selection mode for the hand. */ - protected int _handSelectionMode; - - /** The predicate that determines which cards are selectable (if null, all - * cards are selectable). */ - protected CardSpritePredicate _handSelectionPredicate; - - /** Observers of hand card selection/deselection. */ - protected ObserverList _handSelectionObservers = new ObserverList( - ObserverList.FAST_UNSAFE_NOTIFY); - - /** The location of the center of the hand's upper edge. */ - protected Point _handLocation = new Point(); - - /** The horizontal distance between cards in the hand. */ - protected int _handSpacing; - - /** The vertical distance to offset cards that are selectable. */ - protected int _selectableCardOffset; - - /** The vertical distance to offset cards that are selected. */ - protected int _selectedCardOffset; - - /** The sprites for cards on the board. */ - protected ArrayList _boardSprites = new ArrayList(); - - /** The hand sprite observer instance. */ - protected HandSpriteObserver _handSpriteObserver = - new HandSpriteObserver(); - - /** A path observer that removes the sprite at the end of its path. */ - protected PathAdapter _pathEndRemover = new PathAdapter() { - public void pathCompleted (Sprite sprite, Path path, long when) { - removeSprite(sprite); - } - }; - - /** Listens for interactions with cards in hand. */ - protected class HandSpriteObserver extends PathAdapter - implements CardSpriteObserver - { - public void pathCompleted (Sprite sprite, Path path, long when) - { - updateActiveCardSprite(); - maybeUpdateOffset((CardSprite)sprite); - } - - public void cardSpriteClicked (CardSprite sprite, MouseEvent me) - { - // select, deselect, or play card in hand - if (_selectedHandSprites.contains(sprite) && - _handSelectionMode != NONE) { - deselectHandSprite(sprite); - - } else if (_handSprites.contains(sprite) && isSelectable(sprite)) { - selectHandSprite(sprite); - } - } - - public void cardSpriteEntered (CardSprite sprite, MouseEvent me) - { - maybeUpdateOffset(sprite); - } - - public void cardSpriteExited (CardSprite sprite, MouseEvent me) - { - maybeUpdateOffset(sprite); - } - - public void cardSpriteDragged (CardSprite sprite, MouseEvent me) - {} - - protected void maybeUpdateOffset (CardSprite sprite) - { - // update the offset if it's in the hand and isn't moving - if (_handSprites.contains(sprite) && !sprite.isMoving()) { - sprite.setLocation(sprite.getX(), getHandY(sprite)); - } - } - }; - - /** Listens for mouse interactions with cards. */ - protected class CardListener extends MouseInputAdapter - { - public void mousePressed (MouseEvent me) - { - if (_activeCardSprite != null && - isManaged(_activeCardSprite)) { - _handleX = _activeCardSprite.getX() - me.getX(); - _handleY = _activeCardSprite.getY() - me.getY(); - _hasBeenDragged = false; - } - } - - public void mouseReleased (MouseEvent me) - { - if (_activeCardSprite != null && - isManaged(_activeCardSprite) && - _hasBeenDragged) { - _activeCardSprite.queueNotification( - new CardSpriteDraggedOp(_activeCardSprite, me) - ); - } - } - - public void mouseClicked (MouseEvent me) - { - if (_activeCardSprite != null && - isManaged(_activeCardSprite)) { - _activeCardSprite.queueNotification( - new CardSpriteClickedOp(_activeCardSprite, me) - ); - } - } - - public void mouseMoved (MouseEvent me) - { - _mouseEvent = me; - - updateActiveCardSprite(); - } - - public void mouseDragged (MouseEvent me) - { - _mouseEvent = me; - - if (_activeCardSprite != null && - isManaged(_activeCardSprite) && - _activeCardSprite.isDraggable()) { - _activeCardSprite.setLocation( - me.getX() + _handleX, - me.getY() + _handleY - ); - _hasBeenDragged = true; - - } else { - updateActiveCardSprite(); - } - } - - public void mouseEntered (MouseEvent me) - { - _mouseEvent = me; - } - - public void mouseExited (MouseEvent me) - { - _mouseEvent = me; - } - - protected int _handleX, _handleY; - protected boolean _hasBeenDragged; - } - - /** Calls CardSpriteObserver.cardSpriteClicked. */ - protected static class CardSpriteClickedOp implements - ObserverList.ObserverOp - { - public CardSpriteClickedOp (CardSprite sprite, MouseEvent me) - { - _sprite = sprite; - _me = me; - } - - public boolean apply (Object observer) - { - if (observer instanceof CardSpriteObserver) { - ((CardSpriteObserver)observer).cardSpriteClicked(_sprite, - _me); - } - return true; - } - - protected CardSprite _sprite; - protected MouseEvent _me; - } - - /** Calls CardSpriteObserver.cardSpriteEntered. */ - protected static class CardSpriteEnteredOp implements - ObserverList.ObserverOp - { - public CardSpriteEnteredOp (CardSprite sprite, MouseEvent me) - { - _sprite = sprite; - _me = me; - } - - public boolean apply (Object observer) - { - if (observer instanceof CardSpriteObserver) { - ((CardSpriteObserver)observer).cardSpriteEntered(_sprite, - _me); - } - return true; - } - - protected CardSprite _sprite; - protected MouseEvent _me; - } - - /** Calls CardSpriteObserver.cardSpriteExited. */ - protected static class CardSpriteExitedOp implements - ObserverList.ObserverOp - { - public CardSpriteExitedOp (CardSprite sprite, MouseEvent me) - { - _sprite = sprite; - _me = me; - } - - public boolean apply (Object observer) - { - if (observer instanceof CardSpriteObserver) { - ((CardSpriteObserver)observer).cardSpriteExited(_sprite, _me); - } - return true; - } - - protected CardSprite _sprite; - protected MouseEvent _me; - } - - /** Calls CardSpriteObserver.cardSpriteDragged. */ - protected static class CardSpriteDraggedOp implements - ObserverList.ObserverOp - { - public CardSpriteDraggedOp (CardSprite sprite, MouseEvent me) - { - _sprite = sprite; - _me = me; - } - - public boolean apply (Object observer) - { - if (observer instanceof CardSpriteObserver) { - ((CardSpriteObserver)observer).cardSpriteDragged(_sprite, - _me); - } - return true; - } - - protected CardSprite _sprite; - protected MouseEvent _me; - } - - /** A nice default green card table background color. */ - protected static Color DEFAULT_BACKGROUND = new Color(0x326D36); -} diff --git a/src/java/com/threerings/parlor/card/client/CardSprite.java b/src/java/com/threerings/parlor/card/client/CardSprite.java deleted file mode 100644 index 5e6df036a..000000000 --- a/src/java/com/threerings/parlor/card/client/CardSprite.java +++ /dev/null @@ -1,252 +0,0 @@ -// -// $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.parlor.card.client; - -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; - -import com.threerings.media.image.Mirage; -import com.threerings.media.sprite.FadableImageSprite; -import com.threerings.media.util.Path; - -import com.threerings.parlor.card.data.Card; - -/** - * A sprite representing a playing card. - */ -public class CardSprite extends FadableImageSprite - implements Comparable -{ - /** - * Creates a new upward-facing card sprite. - * - * @param panel the panel responsible for the sprite - * @param card the card to depict (can be null, in which case the - * card back will be shown) - */ - public CardSprite (CardPanel panel, Card card) - { - _panel = panel; - _card = card; - _facingUp = true; - - updateMirage(); - } - - /** - * Creates a new card sprite. - * - * @param panel the panel responsible for the sprite - * @param card the card to depict - * @param facingUp whether or not the card should be facing up - */ - public CardSprite (CardPanel panel, Card card, boolean facingUp) - { - _panel = panel; - _card = card; - _facingUp = facingUp; - - updateMirage(); - } - - /** - * Sets the card to depict. - * - * @param card the new card - */ - public void setCard (Card card) - { - _card = card; - - updateMirage(); - } - - /** - * Returns the card being depicted. - * - * @return the current card - */ - public Card getCard () - { - return _card; - } - - /** - * Turns this card up or down. - * - * @param facingUp whether or not the card should be facing up - */ - public void setFacingUp (boolean facingUp) - { - _facingUp = facingUp; - - updateMirage(); - } - - /** - * Checks whether this card is facing up or down. - * - * @return true if the card is facing up, false if facing down - */ - public boolean isFacingUp () - { - return _facingUp; - } - - /** - * Sets whether or not the user can drag this card around the board. - * - * @param draggable whether or not the user can drag the card - */ - public void setDraggable (boolean draggable) - { - _draggable = draggable; - } - - /** - * Checks whether or not the user can drag this card. - * - * @return true if the user can drag the card, false if not - */ - public boolean isDraggable () - { - return _draggable; - } - - /** - * Flip the card from its current displayed card to the specified card. - */ - public void flip (Card newCard, long duration) - { - _flipStamp = 0; - _flipDuration = duration; - _flipCard = newCard; - - _scaleFactor = 1.0; - } - - // Documentation inherited. - public void tick (long tickStamp) - { - super.tick(tickStamp); - - // Take care of any flipping we might be doing. - if (_flipDuration != -1) { - if (_flipStamp == 0) { - _flipStamp = tickStamp; - } - - long diff = tickStamp - _flipStamp; - - // Set the new scale while we're flipping - if (diff < _flipDuration/2) { - _scaleFactor = 1.0 - ((float)diff*2)/_flipDuration; - } else { - // Switch the image to the card we're flipping to. - if (_flipCard != null) { - setCard(_flipCard); - _flipCard = null; - } - _scaleFactor = ((float)diff*2)/_flipDuration - 1.0; - } - - // If we're done, stop flipping. - if (_scaleFactor > 1.0) { - _scaleFactor = 1.0; - _flipDuration = -1; - } - - // Make sure we flag our location as needing redrawing - if (_mgr != null) { - _mgr.getRegionManager().invalidateRegion(_bounds); - } - } - - } - - // Documentation inherited. - public void paint (Graphics2D gfx) - { - if (_scaleFactor <= 0) { - return; - } - // If we are flipping the card, scale it horizontally. - AffineTransform otrans = gfx.getTransform(); - if (_scaleFactor < 1.0) { - int xtrans = getX() + getWidth()/2; - gfx.translate(xtrans, 0); - gfx.scale(_scaleFactor, 1.0); - gfx.translate(-xtrans, 0); - } - - super.paint(gfx); - - gfx.setTransform(otrans); - } - - /** - * Compares this to another card sprite based on their cards. - */ - public int compareTo (Object other) - { - CardSprite cs = (CardSprite)other; - if (_card == null || cs._card == null) { - return 0; - - } else { - return _card.compareTo(cs._card); - } - } - - /** - * Updates the mirage according to the current state. - */ - protected void updateMirage () - { - setMirage((_card != null && _facingUp ) ? - _panel.getCardImage(_card) : _panel.getCardBackImage()); - } - - /** The panel responsible for the sprite. */ - protected CardPanel _panel; - - /** The depicted card. */ - protected Card _card; - - /** Whether or not the card is facing up. */ - protected boolean _facingUp; - - /** Whether or not the user can drag the card around the board. */ - protected boolean _draggable; - - /** The horizontal scale factor used while flipping the card. */ - protected double _scaleFactor = 1.0; - - /** If flipping, how long the current flip should take (otherwise -1). */ - protected long _flipDuration; - - /** The timestamp for when we started flipping the card. */ - protected long _flipStamp; - - /** The card which will be revealed when we're done flipping. */ - protected Card _flipCard; -} diff --git a/src/java/com/threerings/parlor/card/client/CardSpriteObserver.java b/src/java/com/threerings/parlor/card/client/CardSpriteObserver.java deleted file mode 100644 index e39483b33..000000000 --- a/src/java/com/threerings/parlor/card/client/CardSpriteObserver.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// $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.parlor.card.client; - -import java.awt.event.MouseEvent; - -/** - * Observer interface for (draggable) card sprites. - */ -public interface CardSpriteObserver -{ - /** - * Notifies the observer that the user clicked a card sprite. - * - * @param sprite the dragged sprite - * @param me the mouse event associated with the drag - */ - public void cardSpriteClicked (CardSprite sprite, MouseEvent me); - - /** - * Notifies the observer that the user moved the mouse pointer onto - * a card sprite. - * - * @param sprite the entered sprite - * @param me the mouse event associated with the entrance - */ - public void cardSpriteEntered (CardSprite sprite, MouseEvent me); - - /** - * Notifies the observer that the user moved the mouse pointer off of - * a card sprite. - * - * @param sprite the exited the sprite - * @param me the mouse event associated with the exit - */ - public void cardSpriteExited (CardSprite sprite, MouseEvent me); - - /** - * Notifies the observer that the user dragged a card sprite to a new - * location. - * - * @param sprite the dragged sprite - * @param me the mouse event associated with the drag - */ - public void cardSpriteDragged (CardSprite sprite, MouseEvent me); -} diff --git a/src/java/com/threerings/parlor/card/client/MicroCardSprite.java b/src/java/com/threerings/parlor/card/client/MicroCardSprite.java deleted file mode 100644 index 31efba058..000000000 --- a/src/java/com/threerings/parlor/card/client/MicroCardSprite.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// 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.parlor.card.client; - -import com.threerings.parlor.card.data.Card; - -public class MicroCardSprite extends CardSprite -{ - /** - * Creates a new upward-facing micro-card sprite. - * - * @param panel the panel responsible for the sprite - * @param card the card to depict (can be null, in which case the - * card back will be shown) - */ - public MicroCardSprite (CardPanel panel, Card card) - { - super(panel, card); - } - - /** - * Creates a new micro-card sprite. - * - * @param panel the panel responsible for the sprite - * @param card the card to depict - * @param facingUp whether or not the card should be facing up - */ - public MicroCardSprite (CardPanel panel, Card card, boolean facingUp) - { - super(panel, card, facingUp); - } - - /** - * Updates the mirage according to the current state. - */ - protected void updateMirage () - { - setMirage((_card != null && _facingUp ) ? - _panel.getMicroCardImage(_card) : _panel.getMicroCardBackImage()); - } - -} diff --git a/src/java/com/threerings/parlor/card/data/Card.java b/src/java/com/threerings/parlor/card/data/Card.java deleted file mode 100644 index a276f9b64..000000000 --- a/src/java/com/threerings/parlor/card/data/Card.java +++ /dev/null @@ -1,244 +0,0 @@ -// -// $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.parlor.card.data; - -import java.io.IOException; - -import com.threerings.io.ObjectInputStream; -import com.threerings.io.ObjectOutputStream; - -import com.threerings.presents.dobj.DSet; - -/** - * Instances of this class represent individual playing cards. - */ -public class Card implements DSet.Entry, Comparable, CardCodes -{ - /** - * No-arg constructor for deserialization. - */ - public Card () - {} - - /** - * Creates a new card. - * - * @param number the number of the card - * @param suit the suit of the card - */ - public Card (int number, int suit) - { - _value = (byte)((suit << 5) | number); - } - - /** - * Returns the value of the card, either from 2 to 11 or - * KING, QUEEN, JACK, ACE, RED_JOKER, or BLACK_JOKER. - * - * @return the value of the card - */ - public int getNumber () - { - return (_value & 0x1F); - } - - /** - * Returns the suit of the card: SPADES, HEARTS, DIAMONDS, or - * CLUBS. If the card is the joker, the suit is undefined. - * - * @return the suit of the card - */ - public int getSuit () - { - return (_value >> 5); - } - - /** - * Checks whether the card is a number card (2 to 10). - * - * @return true if the card is a number card, false otherwise - */ - public boolean isNumber () - { - int number = getNumber(); - - return number >= 2 && number <= 10; - } - - /** - * Checks whether the card is a face card (KING, QUEEN, or JACK). - * - * @return true if the card is a face card, false otherwise - */ - public boolean isFace () - { - int number = getNumber(); - - return number == KING || number == QUEEN || number == JACK; - } - - /** - * Checks whether the card is an ace. - * - * @return true if the card is an ace, false otherwise - */ - public boolean isAce () - { - return getNumber() == ACE; - } - - /** - * Checks whether the card is a joker. - * - * @return true if the card is a joker, false otherwise - */ - public boolean isJoker () - { - int number = getNumber(); - - return number == RED_JOKER || number == BLACK_JOKER; - } - - /** - * Checks whether or not this card is valid. The no-arg public - * constructor for deserialization creates an invalid card. - * - * @return true if this card is valid, false if not - */ - public boolean isValid () - { - int number = getNumber(), suit = getSuit(); - - return number == RED_JOKER || number == BLACK_JOKER || - (number >= 2 && number <= ACE && - suit >= SPADES && suit <= DIAMONDS); - } - - // Documentation inherited. - public Comparable getKey () - { - if (_key == null) { - _key = Byte.valueOf(_value); - } - - return _key; - } - - /** - * Returns a hash code for this card. - * - * @return this card's hash code - */ - public int hashCode () - { - return _value; - } - - /** - * Checks this card for equality with another. - * - * @param other the other card to compare - * @return true if the cards are equal, false otherwise - */ - public boolean equals (Object other) - { - if (other instanceof Card) { - return _value == ((Card)other)._value; - } - else { - return false; - } - } - - /** - * Compares this card to another. The card order is the same as the - * initial deck ordering: two through ten, jack, queen, king, ace for - * spades, hearts, clubs, and diamonds, then the red joker and the - * black joker. - * - * @param other the other card to compare this to - * @return -1, 0, or +1, depending on whether this card is less than, - * equal to, or greater than the other card - */ - public int compareTo (Object other) - { - int otherValue = ((Card)other)._value; - - if (_value > otherValue) { - return +1; - } else if(_value < otherValue) { - return -1; - } else { - return 0; - } - } - - /** - * Returns a string representation of this card. - * - * @return a description of this card - */ - public String toString () - { - int number = getNumber(); - - if (number == RED_JOKER) { - return "RJ"; - } - else if (number == BLACK_JOKER) { - return "BJ"; - } - else { - StringBuilder sb = new StringBuilder(); - - if (number >= 2 && number <= 9) { - sb.append(Integer.toString(number)); - } - else { - switch (number) { - case 10: sb.append('T'); break; - case JACK: sb.append('J'); break; - case QUEEN: sb.append('Q'); break; - case KING: sb.append('K'); break; - case ACE: sb.append('A'); break; - default: sb.append('?'); break; - } - } - - switch (getSuit()) { - case SPADES: sb.append('s'); break; - case HEARTS: sb.append('h'); break; - case CLUBS: sb.append('c'); break; - case DIAMONDS: sb.append('d'); break; - default: sb.append('?'); break; - } - - return sb.toString(); - } - } - - /** The number of the card. */ - protected byte _value; - - /** The comparison key. */ - protected transient Byte _key; -} diff --git a/src/java/com/threerings/parlor/card/data/CardCodes.java b/src/java/com/threerings/parlor/card/data/CardCodes.java deleted file mode 100644 index c9504d318..000000000 --- a/src/java/com/threerings/parlor/card/data/CardCodes.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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.parlor.card.data; - -import com.threerings.presents.data.InvocationCodes; - -/** - * Constants relating to the card services. - */ -public interface CardCodes extends InvocationCodes -{ - /** The suit of spades. */ - public static final int SPADES = 0; - - /** The suit of hearts. */ - public static final int HEARTS = 1; - - /** The suit of clubs. */ - public static final int CLUBS = 2; - - /** The suit of diamonds. */ - public static final int DIAMONDS = 3; - - /** The number of the jack. */ - public static final int JACK = 11; - - /** The number of the queen. */ - public static final int QUEEN = 12; - - /** The number of the king. */ - public static final int KING = 13; - - /** The number of the ace. */ - public static final int ACE = 14; - - /** The number of the red joker. */ - public static final int RED_JOKER = 15; - - /** The number of the black joker. */ - public static final int BLACK_JOKER = 16; -} diff --git a/src/java/com/threerings/parlor/card/data/CardGameObject.java b/src/java/com/threerings/parlor/card/data/CardGameObject.java deleted file mode 100644 index 14cd594f6..000000000 --- a/src/java/com/threerings/parlor/card/data/CardGameObject.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// $Id: TurnGameObject.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.parlor.card.data; - -import com.threerings.parlor.game.data.GameObject; - -/** - * Game object class for card games. - */ -public class CardGameObject extends GameObject -{ -} diff --git a/src/java/com/threerings/parlor/card/data/Deck.java b/src/java/com/threerings/parlor/card/data/Deck.java deleted file mode 100644 index 3f7a5b07d..000000000 --- a/src/java/com/threerings/parlor/card/data/Deck.java +++ /dev/null @@ -1,121 +0,0 @@ -// -// $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.parlor.card.data; - -import java.util.Collections; -import java.util.List; - -import com.threerings.util.StreamableArrayList; - -/** - * Instances of this class represent decks of cards. - */ -public class Deck extends StreamableArrayList - implements CardCodes -{ - /** - * Default constructor creates an unshuffled deck of cards without - * jokers. - */ - public Deck () - { - reset(false); - } - - /** - * Constructor. - * - * @param includeJokers whether or not to include the two jokers - * in the deck - */ - public Deck (boolean includeJokers) - { - reset(includeJokers); - } - - /** - * Resets the deck to its initial state: an unshuffled deck of - * 52 or 54 cards, depending on whether the jokers are included. - * - * @param includeJokers whether or not to include the two jokers - * in the deck - */ - public void reset (boolean includeJokers) - { - clear(); - - for (int i = SPADES; i <= DIAMONDS; i++) { - for (int j = 2; j <= ACE; j++) { - add(new Card(j, i)); - } - } - - if (includeJokers) { - add(new Card(RED_JOKER, 3)); - add(new Card(BLACK_JOKER, 3)); - } - } - - /** - * Shuffles the deck. - */ - public void shuffle () - { - Collections.shuffle(this); - } - - /** - * Deals a hand of cards from the deck. - * - * @param size the size of the hand to deal - * @return the newly created and populated hand, or null - * if there are not enough cards in the deck to deal the hand - */ - public Hand dealHand (int size) - { - int dsize = size(); - if (dsize < size) { - return null; - - } else { - Hand hand = new Hand(); - - // use a sublist view to manipulate the top of the deck - List sublist = subList(dsize - size, dsize); - hand.addAll(sublist); - sublist.clear(); - - return hand; - } - } - - /** - * Returns a hand of cards to the deck. - * - * @param hand the hand of cards to return - */ - public void returnHand (Hand hand) - { - addAll(hand); - hand.clear(); - } -} diff --git a/src/java/com/threerings/parlor/card/data/Hand.java b/src/java/com/threerings/parlor/card/data/Hand.java deleted file mode 100644 index 033aad5aa..000000000 --- a/src/java/com/threerings/parlor/card/data/Hand.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// $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.parlor.card.data; - -import com.threerings.util.StreamableArrayList; - -/** - * Instances of this class represent hands of cards. - */ -public class Hand extends StreamableArrayList -{ - /** - * Adds all of the specified cards to this hand. - */ - public void addAll (Card[] cards) - { - for (int i = 0; i < cards.length; i++) { - add(cards[i]); - } - } - - /** - * Removes all of the specified cards from this hand. - */ - public void removeAll (Card[] cards) - { - for (int i = 0; i < cards.length; i++) { - remove(cards[i]); - } - } - - /** - * Checks whether this hand contains all of the specified cards. - */ - public boolean containsAll (Card[] cards) - { - for (int i = 0; i < cards.length; i++) { - if (!contains(cards[i])) { - return false; - } - } - return true; - } - - /** - * Counts the members of a particular suit within this hand. - * - * @param suit the suit of interest - * @return the number of cards in the specified suit - */ - public int getSuitMemberCount (int suit) - { - int len = size(), members = 0; - for (int i = 0; i < len; i++) { - if (((Card)get(i)).getSuit() == suit) { - members++; - } - } - return members; - } - - /** - * Get an array of the cards in this hand. - */ - public Card[] getCards () - { - Card[] cards = new Card[size()]; - toArray(cards); - return cards; - } -} diff --git a/src/java/com/threerings/parlor/card/data/PlayerCard.java b/src/java/com/threerings/parlor/card/data/PlayerCard.java deleted file mode 100644 index 75abebed3..000000000 --- a/src/java/com/threerings/parlor/card/data/PlayerCard.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// $Id: TrickCardGameObject.java 3382 2005-03-03 19:55:35Z 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.parlor.card.data; - -import com.threerings.io.Streamable; - -/** - * Pairs a player index with the card that the player played in the trick. - */ -public class PlayerCard implements Streamable -{ - /** The index of the player. */ - public int pidx; - - /** The card that the player played. */ - public Card card; - - /** - * No-argument constructor for deserialization. - */ - public PlayerCard () - {} - - /** - * Creates a new player card. - * - * @param pidx the index of the player - * @param card the card played - */ - public PlayerCard (int pidx, Card card) - { - this.pidx = pidx; - this.card = card; - } -} diff --git a/src/java/com/threerings/parlor/card/server/CardGameManager.java b/src/java/com/threerings/parlor/card/server/CardGameManager.java deleted file mode 100644 index a6a5b6d06..000000000 --- a/src/java/com/threerings/parlor/card/server/CardGameManager.java +++ /dev/null @@ -1,268 +0,0 @@ -// -// $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.parlor.card.server; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.OccupantInfo; -import com.threerings.crowd.server.OccupantOp; - -import com.threerings.parlor.card.Log; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.CardCodes; -import com.threerings.parlor.card.data.CardGameObject; -import com.threerings.parlor.card.data.Deck; -import com.threerings.parlor.card.data.Hand; -import com.threerings.parlor.game.server.GameManager; -import com.threerings.parlor.turn.server.TurnGameManager; - -import com.threerings.presents.client.InvocationService.ConfirmListener; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.dobj.MessageEvent; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.PresentsServer; - -/** - * A manager class for card games. Handles common functions like dealing - * hands of cards to all players. - */ -public class CardGameManager extends GameManager - implements TurnGameManager, CardCodes -{ - // Documentation inherited. - protected void didStartup () - { - super.didStartup(); - _cardgameobj = (CardGameObject)_gameobj; - } - - // Documentation inherited. - public void turnWillStart () - {} - - // Documentation inherited. - public void turnDidStart () - {} - - // Documentation inherited. - public void turnDidEnd () - {} - - /** - * This should be called to start a rematched game. It just starts the - * current game anew, but provides a mechanism for derived classes to - * do special things when there is a rematch. - */ - public void rematchGame () - { - if (gameWillRematch()) { - startGame(); - } - } - - /** - * Derived classes can override this method and take any action needed - * prior to a game rematch. If the rematch needs to be vetoed for any - * reason, they can return false from this method and the rematch will - * be aborted. - */ - protected boolean gameWillRematch () - { - return true; - } - - /** - * Deals a hand of cards to the player at the specified index from - * the given Deck. - * - * @param deck the deck from which to deal - * @param size the size of the hand to deal - * @param playerIndex the index of the target player - * @return the hand dealt to the player, or null if the deal - * was canceled because the deck did not contain enough cards - */ - public Hand dealHand (Deck deck, int size, int playerIndex) - { - if (deck.size() < size) { - return null; - - } else { - Hand hand = deck.dealHand(size); - if (!isAI(playerIndex)) { - ClientObject clobj = (ClientObject) - PresentsServer.omgr.getObject(_playerOids[playerIndex]); - if (clobj != null) { - CardGameSender.sendHand(clobj, _cardgameobj.getOid(), hand); - } - } - return hand; - } - } - - /** - * Deals a hand of cards to each player from the specified - * Deck. - * - * @param deck the deck from which to deal - * @param size the size of the hands to deal - * @return the array of hands dealt to each player, or null if - * the deal was canceled because the deck did not contain enough - * cards - */ - public Hand[] dealHands (Deck deck, int size) - { - if (deck.size() < size * _playerCount) { - return null; - - } else { - Hand[] hands = new Hand[_playerCount]; - - for (int i=0;i<_playerCount;i++) { - hands[i] = dealHand(deck, size, i); - } - - return hands; - } - } - - /** - * Gets the player index of the specified client object, or -1 - * if the client object does not represent a player. - */ - public int getPlayerIndex (ClientObject client) - { - int oid = client.getOid(); - for (int i=0;i<_playerOids.length;i++) { - if (_playerOids[i] == oid) { - return i; - } - } - return -1; - } - - /** - * Returns the client object corresponding to the specified player index, - * or null if the position is not occupied by a player. - */ - public ClientObject getClientObject (int pidx) - { - if (_playerOids[pidx] != 0) { - return (ClientObject)PresentsServer.omgr.getObject( - _playerOids[pidx]); - - } else { - return null; - } - } - - /** - * Sends a set of cards from one player to another. - * - * @param fromPlayerIdx the index of the player sending the cards - * @param toPlayerIdx the index of the player receiving the cards - * @param cards the cards to be exchanged - */ - public void transferCardsBetweenPlayers (int fromPlayerIdx, - int toPlayerIdx, Card[] cards) - { - // Notify the sender that the cards have been taken - ClientObject fromClient = getClientObject(fromPlayerIdx); - if (fromClient != null) { - CardGameSender.sentCardsToPlayer(fromClient, toPlayerIdx, cards); - } - - // Notify the receiver with the cards - ClientObject toClient = getClientObject(toPlayerIdx); - if (toClient != null) { - CardGameSender.sendCardsFromPlayer(toClient, fromPlayerIdx, - cards); - } - - // and everybody else in the room other than the sender and the - // receiver with the number of cards sent - notifyCardsTransferred(fromPlayerIdx, toPlayerIdx, cards.length); - } - - /** - * Sends sets of cards between players simultaneously. Each player is - * guaranteed to receive the notification of cards received after the - * notification of cards sent. The length of the arrays passed must - * be equal to the player count. - * - * @param toPlayerIndices for each player, the index of the player to - * transfer cards to - * @param cards for each player, the cards to transfer - */ - public void transferCardsBetweenPlayers (int[] toPlayerIndices, - Card[][] cards) - { - // Send all removal notices - for (int i = 0; i < _playerCount; i++) { - ClientObject fromClient = getClientObject(i); - if (fromClient != null) { - CardGameSender.sentCardsToPlayer(fromClient, - toPlayerIndices[i], cards[i]); - } - } - - // Send all addition notices and notify everyone else - for (int i = 0; i < _playerCount; i++) { - ClientObject toClient = getClientObject(toPlayerIndices[i]); - if (toClient != null) { - CardGameSender.sendCardsFromPlayer(toClient, i, cards[i]); - } - notifyCardsTransferred(i, toPlayerIndices[i], cards[i].length); - } - } - - /** - * Notifies everyone in the room (other than the sender and the receiver) - * that a set of cards have been transferred. - * - * @param fromPlayerIdx the index of the player sending the cards - * @param toPlayerIdx the index of the player receiving the cards - * @param cards the number of cards sent - */ - protected void notifyCardsTransferred (final int fromPlayerIdx, - final int toPlayerIdx, final int cards) - { - final int senderOid = _playerOids[fromPlayerIdx], - receiverOid = _playerOids[toPlayerIdx]; - OccupantOp op = new OccupantOp() { - public void apply (OccupantInfo info) { - int oid = info.getBodyOid(); - if (oid != senderOid && oid != receiverOid) { - ClientObject client = - (ClientObject)PresentsServer.omgr.getObject(oid); - if (client != null) { - CardGameSender.cardsTransferredBetweenPlayers(client, - fromPlayerIdx, toPlayerIdx, cards); - } - } - } - }; - applyToOccupants(op); - } - - /** The card game object. */ - protected CardGameObject _cardgameobj; -} diff --git a/src/java/com/threerings/parlor/card/server/CardGameSender.java b/src/java/com/threerings/parlor/card/server/CardGameSender.java deleted file mode 100644 index 6ad718b6a..000000000 --- a/src/java/com/threerings/parlor/card/server/CardGameSender.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $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.parlor.card.server; - -import com.threerings.parlor.card.client.CardGameDecoder; -import com.threerings.parlor.card.client.CardGameReceiver; -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.Hand; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationSender; - -/** - * Used to issue notifications to a {@link CardGameReceiver} instance on a - * client. - */ -public class CardGameSender extends InvocationSender -{ - /** - * Issues a notification that will result in a call to {@link - * CardGameReceiver#cardsTransferredBetweenPlayers} on a client. - */ - public static void cardsTransferredBetweenPlayers ( - ClientObject target, int arg1, int arg2, int arg3) - { - sendNotification( - target, CardGameDecoder.RECEIVER_CODE, CardGameDecoder.CARDS_TRANSFERRED_BETWEEN_PLAYERS, - new Object[] { Integer.valueOf(arg1), Integer.valueOf(arg2), Integer.valueOf(arg3) }); - } - - /** - * Issues a notification that will result in a call to {@link - * CardGameReceiver#receivedCardsFromPlayer} on a client. - */ - public static void sendCardsFromPlayer ( - ClientObject target, int arg1, Card[] arg2) - { - sendNotification( - target, CardGameDecoder.RECEIVER_CODE, CardGameDecoder.RECEIVED_CARDS_FROM_PLAYER, - new Object[] { Integer.valueOf(arg1), arg2 }); - } - - /** - * Issues a notification that will result in a call to {@link - * CardGameReceiver#receivedHand} on a client. - */ - public static void sendHand ( - ClientObject target, int arg1, Hand arg2) - { - sendNotification( - target, CardGameDecoder.RECEIVER_CODE, CardGameDecoder.RECEIVED_HAND, - new Object[] { Integer.valueOf(arg1), arg2 }); - } - - /** - * Issues a notification that will result in a call to {@link - * CardGameReceiver#sentCardsToPlayer} on a client. - */ - public static void sentCardsToPlayer ( - ClientObject target, int arg1, Card[] arg2) - { - sendNotification( - target, CardGameDecoder.RECEIVER_CODE, CardGameDecoder.SENT_CARDS_TO_PLAYER, - new Object[] { Integer.valueOf(arg1), arg2 }); - } - -} diff --git a/src/java/com/threerings/parlor/card/trick/client/TrickCardGameControllerDelegate.java b/src/java/com/threerings/parlor/card/trick/client/TrickCardGameControllerDelegate.java deleted file mode 100644 index f04ffc6e0..000000000 --- a/src/java/com/threerings/parlor/card/trick/client/TrickCardGameControllerDelegate.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.parlor.card.trick.client; - -import com.threerings.parlor.turn.client.TurnGameControllerDelegate; - -import com.threerings.parlor.card.client.CardGameController; - -/** - * A card game controller delegate for trick-based card games, such as - * Spades and Hearts. - */ -public class TrickCardGameControllerDelegate - extends TurnGameControllerDelegate -{ - /** - * Constructor. - * - * @param controller the game controller - */ - public TrickCardGameControllerDelegate (CardGameController - controller) - { - super(controller); - _cgctrl = controller; - } - - /** The card game controller. */ - protected CardGameController _cgctrl; -} diff --git a/src/java/com/threerings/parlor/card/trick/client/TrickCardGameService.java b/src/java/com/threerings/parlor/card/trick/client/TrickCardGameService.java deleted file mode 100644 index 1cc9a7583..000000000 --- a/src/java/com/threerings/parlor/card/trick/client/TrickCardGameService.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// $Id: RoisterService.java 17829 2004-11-12 20:24:43Z mdb $ - -package com.threerings.parlor.card.trick.client; - -import com.threerings.parlor.card.data.Card; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -/** - * Service calls related to trick card games. - */ -public interface TrickCardGameService extends InvocationService -{ - /** - * Sends a group of cards to the player at the specified index. - * - * @param client the client object - * @param toidx the index of the player to send the cards to - * @param cards the cards to send - */ - public void sendCardsToPlayer (Client client, int toidx, Card[] cards); - - /** - * Plays a card in the trick. - * - * @param client the client object - * @param card the card to play - * @param handSize the size of the player's hand, which is used to verify - * that the request is for the current trick - */ - public void playCard (Client client, Card card, int handSize); - - /** - * A request for a rematch. - * - * @param client the client object - */ - public void requestRematch (Client client); -} diff --git a/src/java/com/threerings/parlor/card/trick/data/TrickCardCodes.java b/src/java/com/threerings/parlor/card/trick/data/TrickCardCodes.java deleted file mode 100644 index 66535ecf9..000000000 --- a/src/java/com/threerings/parlor/card/trick/data/TrickCardCodes.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $Id: CardCodes.java 3224 2004-11-19 19:04: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.parlor.card.trick.data; - -import com.threerings.parlor.card.data.CardCodes; - -/** - * Constants relating to trick-based card games. - */ -public interface TrickCardCodes extends CardCodes -{ - /** For four-player games, the bottom (own) player. */ - public static final int BOTTOM = 0; - - /** For four-player games, the player on the left. */ - public static final int LEFT = 1; - - /** For four-player games, the top (opposite) player. */ - public static final int TOP = 2; - - /** For four-player games, the player on the right. */ - public static final int RIGHT = 3; -} diff --git a/src/java/com/threerings/parlor/card/trick/data/TrickCardGameMarshaller.java b/src/java/com/threerings/parlor/card/trick/data/TrickCardGameMarshaller.java deleted file mode 100644 index d03a8fed5..000000000 --- a/src/java/com/threerings/parlor/card/trick/data/TrickCardGameMarshaller.java +++ /dev/null @@ -1,73 +0,0 @@ -// -// $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.parlor.card.trick.data; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.trick.client.TrickCardGameService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; - -/** - * Provides the implementation of the {@link TrickCardGameService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class TrickCardGameMarshaller extends InvocationMarshaller - implements TrickCardGameService -{ - /** The method id used to dispatch {@link #playCard} requests. */ - public static final int PLAY_CARD = 1; - - // documentation inherited from interface - public void playCard (Client arg1, Card arg2, int arg3) - { - sendRequest(arg1, PLAY_CARD, new Object[] { - arg2, Integer.valueOf(arg3) - }); - } - - /** The method id used to dispatch {@link #requestRematch} requests. */ - public static final int REQUEST_REMATCH = 2; - - // documentation inherited from interface - public void requestRematch (Client arg1) - { - sendRequest(arg1, REQUEST_REMATCH, new Object[] { - - }); - } - - /** The method id used to dispatch {@link #sendCardsToPlayer} requests. */ - public static final int SEND_CARDS_TO_PLAYER = 3; - - // documentation inherited from interface - public void sendCardsToPlayer (Client arg1, int arg2, Card[] arg3) - { - sendRequest(arg1, SEND_CARDS_TO_PLAYER, new Object[] { - Integer.valueOf(arg2), arg3 - }); - } - -} diff --git a/src/java/com/threerings/parlor/card/trick/data/TrickCardGameObject.java b/src/java/com/threerings/parlor/card/trick/data/TrickCardGameObject.java deleted file mode 100644 index 28b3466ad..000000000 --- a/src/java/com/threerings/parlor/card/trick/data/TrickCardGameObject.java +++ /dev/null @@ -1,210 +0,0 @@ -// -// $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.parlor.card.trick.data; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.Hand; -import com.threerings.parlor.card.data.PlayerCard; -import com.threerings.parlor.turn.data.TurnGameObject; - -/** - * Game objects for trick-based card games must implement this interface. - */ -public interface TrickCardGameObject extends TurnGameObject -{ - /** The state that indicates the game is currently between hands. */ - public static final int BETWEEN_HANDS = 0; - - /** The state that indicates the game is currently playing a hand. */ - public static final int PLAYING_HAND = 1; - - /** The state that indicates the game is currently playing a trick. */ - public static final int PLAYING_TRICK = 2; - - /** The number of states defined for the base trick card game object. */ - public static final int TRICK_STATE_COUNT = 3; - - /** Indicates that the player has not requested or accepted a rematch. */ - public static final int NO_REQUEST = 0; - - /** Indicates that the player has requested a rematch. */ - public static final int REQUESTS_REMATCH = 1; - - /** Indicates that the player has accepted the rematch request. */ - public static final int ACCEPTS_REMATCH = 2; - - /** - * Returns a reference to the trick card game service used to make - * requests to the server. - * - * @return a reference to the trick card game service - */ - public TrickCardGameMarshaller getTrickCardGameService (); - - /** - * Sets the reference to the trick card game service. - * - * @param trickCardGameService the trick card game service - */ - public void setTrickCardGameService (TrickCardGameMarshaller - trickCardGameService); - - /** - * Returns the name of the field that contains the trick state: between - * hands, playing a hand, or playing a trick. - * - * @return the name of the trickState field - */ - public String getTrickStateFieldName (); - - /** - * Returns the trick state: between hands, playing a hand, or playing a - * trick. - * - * @return the trick state - */ - public int getTrickState (); - - /** - * Sets the trick state. - * - * @param trickState the trick state - */ - public void setTrickState (int trickState); - - /** - * Returns an array containing the turn duration scales for each player. - * Turn duration scales decrease each time players time out. - * - * @return the array of turn duration scales - */ - public float[] getTurnDurationScales (); - - /** - * Sets the array of turn duration scales. - * - * @param turnDurationScales the array of turn duration scales - */ - public void setTurnDurationScales (float[] turnDurationScales); - - /** - * Sets an element of the array of turn duration scales. - * - * @param turnDurationScale the turn duration scale - * @param index the index of the turn duration scale - */ - public void setTurnDurationScalesAt (float turnDurationScale, int index); - - /** - * Returns the duration of the current turn, which may depend on the state - * of the game as well as the duration scale of the active player. - */ - public long getTurnDuration (); - - /** - * Returns the name of the field that contains the history of the trick - * in terms of the cards played by each player. - * - * @return the name of the cardsPlayed field - */ - public String getCardsPlayedFieldName (); - - /** - * Returns an array containing the history of the trick in terms of the - * cards played by each player. - * - * @return the cards played so far in the trick - */ - public PlayerCard[] getCardsPlayed (); - - /** - * Sets the array of cards played by each player. - * - * @param cardsPlayed the array of cards played - */ - public void setCardsPlayed (PlayerCard[] cardsPlayed); - - /** - * Returns the name of the field that contains the history of the last - * trick in terms of the cards played by each player. - * - * @return the name of the lastCardsPlayed field - */ - public String getLastCardsPlayedFieldName (); - - /** - * Returns an array containing the history of the last trick in terms of - * the cards played by each player. - * - * @return the cards played in the last trick - */ - public PlayerCard[] getLastCardsPlayed (); - - /** - * Sets the last array of cards played by each player. - * - * @param lastCardsPlayed the last array of cards played - */ - public void setLastCardsPlayed (PlayerCard[] lastCardsPlayed); - - /** - * Returns the name of the field that contains the rematch requests. - * - * @return the name of the rematchRequests field - */ - public String getRematchRequestsFieldName (); - - /** - * Returns the array of rematch requests. - * - * @return the array of rematch requests - */ - public int[] getRematchRequests (); - - /** - * Sets the array of rematch requests. - * - * @param rematchRequests the array of rematch requests - */ - public void setRematchRequests (int[] rematchRequests); - - /** - * Sets an element of the rematch request array. - * - * @param rematchRequest the rematch request value - * @param index the index at which to set the value - */ - public void setRematchRequestsAt (int rematchRequest, int index); - - /** - * Checks whether a user can play the specified card at this time. - * - * @param hand the player's hand - * @param card the card that the user would like to play - */ - public boolean isCardPlayable (Hand hand, Card card); - - /** - * Returns the card of the player who took the current trick. - */ - public PlayerCard getTrickTaker (); -} diff --git a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameDispatcher.java b/src/java/com/threerings/parlor/card/trick/server/TrickCardGameDispatcher.java deleted file mode 100644 index 17655c839..000000000 --- a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameDispatcher.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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.parlor.card.trick.server; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.trick.client.TrickCardGameService; -import com.threerings.parlor.card.trick.data.TrickCardGameMarshaller; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; - -/** - * Dispatches requests to the {@link TrickCardGameProvider}. - */ -public class TrickCardGameDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public TrickCardGameDispatcher (TrickCardGameProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new TrickCardGameMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case TrickCardGameMarshaller.PLAY_CARD: - ((TrickCardGameProvider)provider).playCard( - source, - (Card)args[0], ((Integer)args[1]).intValue() - ); - return; - - case TrickCardGameMarshaller.REQUEST_REMATCH: - ((TrickCardGameProvider)provider).requestRematch( - source - ); - return; - - case TrickCardGameMarshaller.SEND_CARDS_TO_PLAYER: - ((TrickCardGameProvider)provider).sendCardsToPlayer( - source, - ((Integer)args[0]).intValue(), (Card[])args[1] - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameManagerDelegate.java b/src/java/com/threerings/parlor/card/trick/server/TrickCardGameManagerDelegate.java deleted file mode 100644 index 7e3e1e77e..000000000 --- a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameManagerDelegate.java +++ /dev/null @@ -1,643 +0,0 @@ -// -// $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.parlor.card.trick.server; - -import java.util.ArrayList; -import java.util.Arrays; - -import com.samskivert.util.ArrayUtil; -import com.samskivert.util.Interval; -import com.samskivert.util.RandomUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.util.Name; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.dobj.DObject; -import com.threerings.presents.server.PresentsServer; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.parlor.game.server.GameManager; -import com.threerings.parlor.turn.server.TurnGameManagerDelegate; - -import com.threerings.parlor.card.Log; -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.CardGameObject; -import com.threerings.parlor.card.data.Deck; -import com.threerings.parlor.card.data.Hand; -import com.threerings.parlor.card.data.PlayerCard; -import com.threerings.parlor.card.server.CardGameManager; -import com.threerings.parlor.card.trick.data.TrickCardGameMarshaller; -import com.threerings.parlor.card.trick.data.TrickCardGameObject; - -/** - * A card game manager delegate for trick-based card games, such as - * Spades and Hearts. - */ -public class TrickCardGameManagerDelegate extends TurnGameManagerDelegate - implements TrickCardGameProvider -{ - /** - * Constructor. - * - * @param manager the game manager - */ - public TrickCardGameManagerDelegate (CardGameManager manager) - { - super(manager); - - _cgmgr = manager; - _deck = new Deck(); - } - - // Documentation inherited. - public void didStartup (PlaceObject plobj) - { - super.didStartup(plobj); - - _trickCardGame = (TrickCardGameObject)plobj; - - _cardGame = (CardGameObject)plobj; - - _trickCardGame.setTrickCardGameService( - (TrickCardGameMarshaller)PresentsServer.invmgr.registerDispatcher( - new TrickCardGameDispatcher(this), false)); - } - - // Documentation inherited. - public void didShutdown () - { - super.didShutdown(); - - PresentsServer.invmgr.clearDispatcher( - _trickCardGame.getTrickCardGameService()); - } - - // Documentation inherited. - public void gameWillStart () - { - super.gameWillStart(); - - // clear out the last cards played - _trickCardGame.setLastCardsPlayed(null); - - // initialize the turn duration scales - float[] scales = new float[_cardGame.getPlayerCount()]; - Arrays.fill(scales, 1.0f); - _trickCardGame.setTurnDurationScales(scales); - } - - /** - * Called when the game has started. Default implementation starts the - * first hand. - */ - public void gameDidStart () - { - super.gameDidStart(); - - // start the first hand - startHand(); - } - - // Documentation inherited. - public void gameDidEnd () - { - super.gameDidEnd(); - - // make sure all intervals are cancelled - _turnTimeoutInterval.cancel(); - _endTrickInterval.cancel(); - - // make sure trick state is back to between hands - if (_trickCardGame.getTrickState() != - TrickCardGameObject.BETWEEN_HANDS) { - _trickCardGame.setTrickState(TrickCardGameObject.BETWEEN_HANDS); - } - - // initialize the array of rematch requests - _trickCardGame.setRematchRequests( - new int[_cardGame.getPlayerCount()]); - } - - // Documentation inherited. - public void startTurn () - { - super.startTurn(); - - // initialize the timeout flag and schedule the timeout interval - _turnTimedOut = false; - _turnTimeoutInterval.schedule(_trickCardGame.getTurnDuration()); - } - - // Documentation inherited. - public void endTurn () - { - // cancel the timeout interval - _turnTimeoutInterval.cancel(); - - // reduce or increase the turn duration scale - if (_turnTimedOut) { - reduceTurnDurationScale(_turnIdx); - - } else { - increaseTurnDurationScale(_turnIdx); - } - - super.endTurn(); - } - - /** - * Starts a hand of cards. Calls {@link #handWillStart}, sets the trick - * state to PLAYING_HAND, and calls {@link #handDidStart}. - */ - public void startHand () - { - handWillStart(); - _trickCardGame.setTrickState(TrickCardGameObject.PLAYING_HAND); - handDidStart(); - } - - /** - * Ends the hand of cards. Calls {@link #handWillEnd}, sets the trick - * state to BETWEEN_HANDS, and calls {@link #handDidEnd}. - */ - public void endHand () - { - handWillEnd(); - _trickCardGame.setTrickState(TrickCardGameObject.BETWEEN_HANDS); - handDidEnd(); - } - - /** - * Starts a trick. Calls {@link #trickWillStart}, sets the trick - * state to PLAYING_TRICK, and calls {@link #trickDidStart}. - */ - public void startTrick () - { - trickWillStart(); - _trickCardGame.setTrickState(TrickCardGameObject.PLAYING_TRICK); - trickDidStart(); - } - - /** - * Ends the trick. Calls {@link #trickWillEnd}, sets the trick - * state to PLAYING_HAND, and calls {@link #trickDidEnd}. - */ - public void endTrick () - { - trickWillEnd(); - _trickCardGame.setTrickState(TrickCardGameObject.PLAYING_HAND); - trickDidEnd(); - } - - /** - * Processes a request to transfer a group of cards between players. - * Default implementation verifies that the user's hand contains the - * specified cards, then calls {@link #sendCardsToPlayer(int, int, - * Card[])}. - */ - public void sendCardsToPlayer (ClientObject client, int toidx, - Card[] cards) - { - // make sure they're actually a player - int fromidx = _cgmgr.getPlayerIndex(client); - if (fromidx == -1) { - Log.warning("Send request from non-player [username=" + - ((BodyObject)client).who() + ", cards=" + - StringUtil.toString(cards) + "]."); - return; - } - - // make sure they have the cards - if (!_hands[fromidx].containsAll(cards)) { - Log.warning("Tried to send cards not held [username=" + - ((BodyObject)client).who() + ", cards=" + - StringUtil.toString(cards) + "]."); - return; - } - - // send the cards - sendCardsToPlayer(fromidx, toidx, cards); - } - - /** - * Sends cards between players without error checking. Default - * implementation transfers the cards between hands and notifies - * everyone of the transfer using {@link - * CardGameManager#transferCardsBetweenPlayers(int, int, Card[])}. - */ - protected void sendCardsToPlayer (int fromidx, int toidx, Card[] cards) - { - // remove from sending player's hand - _hands[fromidx].removeAll(cards); - - // add to receiving player's hand - _hands[toidx].addAll(cards); - - // notify everyone of the transfer - _cgmgr.transferCardsBetweenPlayers(fromidx, toidx, cards); - } - - // Documentation inherited. - public void playCard (ClientObject client, Card card, int handSize) - { - // make sure we're playing a trick - if (_trickCardGame.getTrickState() != - TrickCardGameObject.PLAYING_TRICK) { - return; // silently ignore play attempts after timeouts - } - - // make sure it's their turn - Name username = ((BodyObject)client).getVisibleName(); - if (!username.equals(_trickCardGame.getTurnHolder())) { - return; - } - - // make sure they're on the right trick - int pidx = _cardGame.getPlayerIndex(username); - if (_hands[pidx].size() != handSize) { - return; - } - - // make sure their hand contains the specified card - if (!_hands[pidx].contains(card)) { - Log.warning("Tried to play card not held [username=" + username + - ", card=" + card + "]."); - return; - } - - // make sure the card is legal to play - if (!_trickCardGame.isCardPlayable(_hands[pidx], card)) { - Log.warning("Tried to play illegal card [username=" + username + - ", card=" + card + "]."); - return; - } - - // play the card - playCard(pidx, card); - } - - /** - * Plays a card for a player without error checking. - */ - protected void playCard (int pidx, Card card) - { - ((DObject) _trickCardGame).startTransaction(); - try { - // play the card by removing it from the hand and adding it - // to the end of the cards played array - _hands[pidx].remove(card); - PlayerCard[] cards = (PlayerCard[])ArrayUtil.append( - _trickCardGame.getCardsPlayed(), new PlayerCard(pidx, card)); - _trickCardGame.setCardsPlayed(cards); - - // end the user's turn - endTurn(); - - // end the trick if everyone has played a card - if (_turnIdx == -1) { - if (_endTrickDelay == 0) { - endTrick(); - - } else { - _endTrickInterval.schedule(_endTrickDelay); - } - } - } finally { - ((DObject) _trickCardGame).commitTransaction(); - } - } - - // Documentation inherited. - public void requestRematch (ClientObject client) - { - // make sure the game is over - if (_cardGame.state != CardGameObject.GAME_OVER) { - Log.warning("Tried to request rematch when game wasn't over " + - "[username=" + ((BodyObject)client).who() + "]."); - return; - } - - // make sure the requester is one of the players - int pidx = _cgmgr.getPlayerIndex(client); - if (pidx == -1) { - Log.warning("Rematch request from non-player [username=" + - ((BodyObject)client).who() + "]."); - return; - } - - // make sure the player hasn't already requested - if (_trickCardGame.getRematchRequests()[pidx] != - TrickCardGameObject.NO_REQUEST) { - Log.warning("Repeated rematch request [username=" + - ((BodyObject)client).who() + "]."); - return; - } - - // if player is first requesting, set to request; else set - // to accept - int req = (getRematchRequestCount() == 0 ? - TrickCardGameObject.REQUESTS_REMATCH : - TrickCardGameObject.ACCEPTS_REMATCH); - _trickCardGame.setRematchRequestsAt(req, pidx); - - // if all players accept the rematch, restart the game - if (getRematchRequestCount() == _cardGame.getPlayerCount()) { - _cgmgr.rematchGame(); - } - } - - /** - * Returns the number of players currently requesting or accepting - * a rematch. - */ - protected int getRematchRequestCount () - { - int[] rematchRequests = _trickCardGame.getRematchRequests(); - int count = 0; - for (int i = 0; i < rematchRequests.length; i++) { - if (rematchRequests[i] != TrickCardGameObject.NO_REQUEST) { - count++; - } - } - return count; - } - - /** - * Checks whether the trick is complete--that is, whether each player has - * played a card. - */ - protected boolean isTrickComplete () - { - return _trickCardGame.getCardsPlayed().length == - _cardGame.getPlayerCount(); - } - - // Documentation inherited. - protected void setFirstTurnHolder () - { - if (_trickCardGame.getTrickState() == - TrickCardGameObject.PLAYING_TRICK) { - super.setFirstTurnHolder(); - - } else { - _turnIdx = -1; - } - } - - // Documentation inherited. - protected void setNextTurnHolder () - { - if (_trickCardGame.getTrickState() == - TrickCardGameObject.PLAYING_TRICK && - !isTrickComplete()) { - super.setNextTurnHolder(); - - } else { - _turnIdx = -1; - } - } - - /** - * Called when the current turn times out. Default implementation - * plays a random playable card if in the trick-playing state. - */ - protected void turnTimedOut () - { - if (_trickCardGame.getTrickState() == - TrickCardGameObject.PLAYING_TRICK) { - playCard(_turnIdx, pickRandomPlayableCard(_hands[_turnIdx])); - } - } - - /** - * Reduces the specified player's turn duration due to a time-out. - */ - protected void reduceTurnDurationScale (int pidx) - { - float oldScale = _trickCardGame.getTurnDurationScales()[pidx], - newScale = Math.max(oldScale - TURN_DURATION_SCALE_REDUCTION, - MINIMUM_TURN_DURATION_SCALE); - if (newScale != oldScale) { - _trickCardGame.setTurnDurationScalesAt(newScale, pidx); - } - } - - /** - * Increases the specified player's turn duration due to avoiding a - * time-out. - */ - protected void increaseTurnDurationScale (int pidx) - { - float oldScale = _trickCardGame.getTurnDurationScales()[pidx], - newScale = Math.min(oldScale + TURN_DURATION_SCALE_INCREASE, - 1.0f); - if (newScale != oldScale) { - _trickCardGame.setTurnDurationScalesAt(newScale, pidx); - } - } - - /** - * Returns a random playable card from the specified hand. - */ - protected Card pickRandomPlayableCard (Hand hand) - { - ArrayList playableCards = new ArrayList(); - for (int i = 0; i < hand.size(); i++) { - Card card = (Card)hand.get(i); - if (_trickCardGame.isCardPlayable(hand, card)) { - playableCards.add(card); - } - } - return (Card)RandomUtil.pickRandom(playableCards); - } - - /** - * Notifies the object that a new hand is about to start. - */ - protected void handWillStart () - {} - - /** - * Notifies the object that a new hand has just started. Default - * implementation prepares the deck, deals the hands, and starts the - * first trick. - */ - protected void handDidStart () - { - // prepare the deck - prepareDeck(); - - // deal cards to players - dealHands(); - - // start the first trick - startTrick(); - } - - /** - * Prepares the deck for a new hand of cards. Default implementation - * resets to a full deck without jokers and shuffles. - */ - protected void prepareDeck () - { - _deck.reset(false); - _deck.shuffle(); - } - - /** - * Deals hands to the players. Default implementation deals the entire - * deck to the players in equal-sized hands. - */ - protected void dealHands () - { - _hands = _cgmgr.dealHands(_deck, _deck.size() / - _cardGame.getPlayerCount()); - } - - /** - * Notifies the object that the hand is about to end. - */ - protected void handWillEnd () - {} - - /** - * Notifies the object that the hand has ended. Default implementation - * starts the next hand. - */ - protected void handDidEnd () - { - startHand(); - } - - /** - * Notifies the object that a new trick is about to start. Default - * implementation resets the array of cards played. - */ - protected void trickWillStart () - { - _trickCardGame.setCardsPlayed(new PlayerCard[0]); - } - - /** - * Notifies the object that a new trick has started. Default - * implementation sets the first turn holder and starts the - * turn. - */ - protected void trickDidStart () - { - setFirstTurnHolder(); - startTurn(); - } - - /** - * Notifies the object that the trick is about to end. - */ - protected void trickWillEnd () - {} - - /** - * Notifies the object that the trick has ended. Default implementation - * records the last cards played and starts the next trick, unless a - * player has run out of cards, in which case it ends the hand. - */ - protected void trickDidEnd () - { - // store the trick results for late-joiners - _trickCardGame.setLastCardsPlayed(_trickCardGame.getCardsPlayed()); - - // clear out the cards played in the trick - _trickCardGame.setCardsPlayed(null); - - // verify that each player has at least one card - if (anyHandsEmpty()) { - endHand(); - return; - } - - // everyone has cards; let's play another trick - startTrick(); - } - - /** - * Checks whether any hands are empty. - */ - protected boolean anyHandsEmpty () - { - for (int i = 0; i < _hands.length; i++) { - if (_hands[i].isEmpty()) { - return true; - } - } - return false; - } - - /** The card game manager. */ - protected CardGameManager _cgmgr; - - /** The game object as trick card game. */ - protected TrickCardGameObject _trickCardGame; - - /** The game object as card game. */ - protected CardGameObject _cardGame; - - /** The amount of time to wait before ending the trick. */ - protected long _endTrickDelay; - - /** The deck from which cards are dealt. */ - protected Deck _deck; - - /** The hands of each player. */ - protected Hand[] _hands; - - /** Whether or not the turn timed out. */ - protected boolean _turnTimedOut; - - /** The all-purpose turn timeout interval. */ - protected Interval _turnTimeoutInterval = - new Interval(PresentsServer.omgr) { - public void expired () { - _turnTimedOut = true; - turnTimedOut(); - } - }; - - /** Calls {@link #endTrick} upon expiration. */ - protected Interval _endTrickInterval = new Interval(PresentsServer.omgr) { - public void expired () { - endTrick(); - } - }; - - /** Reduce turn duration scales by this amount each time the player times - * out. */ - protected static final float TURN_DURATION_SCALE_REDUCTION = 0.25f; - - /** - * Increase turn duration scales by this amount each time the player - * manages not to time out. */ - protected static final float TURN_DURATION_SCALE_INCREASE = 0.5f; - - /** Don't let turn duration scales get below this level. */ - protected static final float MINIMUM_TURN_DURATION_SCALE = 0.1f; -} diff --git a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameProvider.java b/src/java/com/threerings/parlor/card/trick/server/TrickCardGameProvider.java deleted file mode 100644 index 783f8ccc8..000000000 --- a/src/java/com/threerings/parlor/card/trick/server/TrickCardGameProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.parlor.card.trick.server; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.trick.client.TrickCardGameService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; - -/** - * Defines the server-side of the {@link TrickCardGameService}. - */ -public interface TrickCardGameProvider extends InvocationProvider -{ - /** - * Handles a {@link TrickCardGameService#playCard} request. - */ - public void playCard (ClientObject caller, Card arg1, int arg2); - - /** - * Handles a {@link TrickCardGameService#requestRematch} request. - */ - public void requestRematch (ClientObject caller); - - /** - * Handles a {@link TrickCardGameService#sendCardsToPlayer} request. - */ - public void sendCardsToPlayer (ClientObject caller, int arg1, Card[] arg2); -} diff --git a/src/java/com/threerings/parlor/card/trick/util/TrickCardGameUtil.java b/src/java/com/threerings/parlor/card/trick/util/TrickCardGameUtil.java deleted file mode 100644 index 962bad509..000000000 --- a/src/java/com/threerings/parlor/card/trick/util/TrickCardGameUtil.java +++ /dev/null @@ -1,195 +0,0 @@ -// -// $Id: TrickCardGameObject.java 3382 2005-03-03 19:55:35Z 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.parlor.card.trick.util; - -import com.threerings.parlor.card.data.Card; -import com.threerings.parlor.card.data.Hand; -import com.threerings.parlor.card.data.PlayerCard; -import com.threerings.parlor.card.trick.data.TrickCardCodes; - -/** - * Methods of general utility to trick-taking card games. - */ -public class TrickCardGameUtil - implements TrickCardCodes -{ - /** - * For four-player games with fixed partnerships, this returns the index - * of the player's team. - * - * @param pidx the player index - */ - public static int getTeamIndex (int pidx) - { - return pidx & 1; - } - - /** - * For four-player games with fixed partnerships, this returns the index - * of the other team. - * - * @param tidx the index of the team - */ - public static int getOtherTeamIndex (int tidx) - { - return tidx ^ 1; - } - - /** - * For four-player games with fixed partnerships, this returns the index - * of the player's partner. - */ - public static int getPartnerIndex (int pidx) - { - return pidx ^ 2; - } - - /** - * For four-player games with fixed partnerships, this returns the index - * of one of the members of a team. - * - * @param tidx the index of the team - * @param midx the index of the player within the team - */ - public static int getTeamMemberIndex (int tidx, int midx) - { - return (midx << 1) | tidx; - } - - /** - * For four-player games, this returns the index of the player after the - * specified player going clockwise around the table. - */ - public static int getNextInClockwiseSequence (int pidx) - { - // 2 - // 1 3 - // 0 - return (pidx + 1) & 3; - } - - /** - * For four-player games with fixed partnerships, this returns the - * relative location of one player from the point of view of another. - * - * @param pidx1 the index of the player to whom the location is relative - * @param pidx2 the index of the player whose location is desired - * @return the relative location (TOP, BOTTOM, LEFT, or RIGHT) - */ - public static int getRelativeLocation (int pidx1, int pidx2) - { - return (pidx2 - pidx1) & 3; - } - - /** - * For four-player games, returns the index of the player to the left of - * the specified player. - */ - public static int getLeftIndex (int pidx) - { - return (pidx + 1) & 3; - } - - /** - * For four-player games, returns the index of the player to the right of - * the specified player. - */ - public static int getRightIndex (int pidx) - { - return (pidx + 3) & 3; - } - - /** - * For four-player games, returns the index of the player across from the - * specified player. - */ - public static int getOppositeIndex (int pidx) - { - return pidx ^ 2; - } - - /** - * Checks whether the player can follow the suit lead with the hand given. - */ - public static boolean canFollowSuit (PlayerCard[] cardsPlayed, Hand hand) - { - return hand.getSuitMemberCount(cardsPlayed[0].card.getSuit()) > 0; - } - - /** - * Checks whether the specified array contains the given card. - */ - public static boolean containsCard (PlayerCard[] cards, Card card) - { - for (int i = 0; i < cards.length; i++) { - if (cards[i].card.equals(card)) { - return true; - } - } - return false; - } - - /** - * Determines the number of cards that belong to the specified suit within - * the array given. - */ - public static int countSuitMembers (PlayerCard[] cards, int suit) - { - int count = 0; - for (int i = 0; i < cards.length; i++) { - if (cards[i].card.getSuit() == suit) { - count++; - } - } - return count; - } - - /** - * Checks whether the proposed card follows the suit lead. - */ - public static boolean followsSuit (PlayerCard[] cardsPlayed, Card card) - { - return cardsPlayed[0].card.getSuit() == card.getSuit(); - } - - /** - * Returns the highest card (according to the standard A,K,...,2 ordering) - * in the suit lead, with an optional trump suit. - * - * @param trumpSuit the trump suit, or -1 for none - */ - public static PlayerCard getHighestInLeadSuit (PlayerCard[] cardsPlayed, - int trumpSuit) - { - PlayerCard highest = cardsPlayed[0]; - for (int i = 1; i < cardsPlayed.length; i++) { - PlayerCard other = cardsPlayed[i]; - if ((other.card.getSuit() == highest.card.getSuit() && - other.card.compareTo(highest.card) > 0) || - (other.card.getSuit() == trumpSuit && - highest.card.getSuit() != trumpSuit)) { - highest = other; - } - } - return highest; - } -} diff --git a/src/java/com/threerings/parlor/client/DefaultSwingTableConfigurator.java b/src/java/com/threerings/parlor/client/DefaultSwingTableConfigurator.java deleted file mode 100644 index 408eff86c..000000000 --- a/src/java/com/threerings/parlor/client/DefaultSwingTableConfigurator.java +++ /dev/null @@ -1,129 +0,0 @@ -// -// $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.parlor.client; - -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import com.samskivert.swing.SimpleSlider; -import com.samskivert.swing.VGroupLayout; - -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.parlor.game.client.SwingGameConfigurator; -import com.threerings.parlor.game.data.GameConfig; - -/** - * Provides a default implementation of a TableConfigurator for - * a Swing interface. - */ -public class DefaultSwingTableConfigurator extends TableConfigurator -{ - /** - * Create a TableConfigurator that allows only the specified number - * of players and lets the configuring user enable private games - * only if the number of players is greater than 2. - */ - public DefaultSwingTableConfigurator (int players) - { - this(players, (players > 2)); - } - - /** - * Create a TableConfigurator that allows only the specified number - * of players and lets the user configure a private table, or not. - */ - public DefaultSwingTableConfigurator (int players, boolean allowPrivate) - { - this(players, players, players, allowPrivate); - } - - /** - * Create a TableConfigurator that allows for the specified configuration - * parameters. - */ - public DefaultSwingTableConfigurator (int minPlayers, - int desiredPlayers, int maxPlayers, boolean allowPrivate) - { - _config.minimumPlayerCount = minPlayers; - - // create a slider for players, if applicable - if (minPlayers != maxPlayers) { - _playerSlider = new SimpleSlider( - "", minPlayers, maxPlayers, desiredPlayers); - - } else { - _config.desiredPlayerCount = desiredPlayers; - } - - // create up the checkbox for private games, if applicable - if (allowPrivate) { - _privateCheck = new JCheckBox(); - } - } - - // documentation inherited - protected void createConfigInterface () - { - super.createConfigInterface(); - - SwingGameConfigurator gconf = (SwingGameConfigurator) _gameConfigurator; - - if (_playerSlider != null) { - // TODO: proper translation - gconf.addControl(new JLabel("Players:"), _playerSlider); - } - - if (_privateCheck != null) { - // TODO: proper translation - gconf.addControl(new JLabel("Private:"), _privateCheck); - } - } - - // documentation inherited - public boolean isEmpty () - { - return (_playerSlider == null) && (_privateCheck == null); - } - - // documentation inherited - protected void flushTableConfig() - { - super.flushTableConfig(); - - if (_playerSlider != null) { - _config.desiredPlayerCount = _playerSlider.getValue(); - } - if (_privateCheck != null) { - _config.privateTable = _privateCheck.isSelected(); - } - } - - /** A slider for configuring the number of players at the table. */ - protected SimpleSlider _playerSlider; - - /** A checkbox to allow the table creator to specify if the table is - * private. */ - protected JCheckBox _privateCheck; -} diff --git a/src/java/com/threerings/parlor/client/GameReadyObserver.java b/src/java/com/threerings/parlor/client/GameReadyObserver.java deleted file mode 100644 index c0541a7ed..000000000 --- a/src/java/com/threerings/parlor/client/GameReadyObserver.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// $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.parlor.client; - -/** - * Used to inform interested parties when the {@link ParlorDirector} - * receives a game ready notification. The observers can ratify the - * decision to head directly into the game or can take responsibility - * themselves for doing so. - */ -public interface GameReadyObserver -{ - /** - * Called when a game ready notification is received. - * - * @param gameOid the place oid of the ready game. - * - * @return if the observer returns true from this method, the parlor - * director assumes they will take care of entering the game room - * after performing processing of their own. If all observers return - * false, the director will enter the game room automatically. - */ - public boolean receivedGameReady (int gameOid); -} diff --git a/src/java/com/threerings/parlor/client/Invitation.java b/src/java/com/threerings/parlor/client/Invitation.java deleted file mode 100644 index 53941d4fc..000000000 --- a/src/java/com/threerings/parlor/client/Invitation.java +++ /dev/null @@ -1,211 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.util.Name; - -import com.threerings.parlor.Log; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * The invitation class is used to track information related to - * outstanding invitations generated by or targeted to this client. - */ -public class Invitation - implements ParlorCodes, ParlorService.InviteListener -{ - /** The unique id for this invitation (as assigned by the - * server). This is -1 until we receive an acknowledgement from - * the server that our invitation was delivered. */ - public int inviteId = -1; - - /** The name of the other user involved in this invitation. */ - public Name opponent; - - /** The configuration of the game to be created. */ - public GameConfig config; - - /** Constructs a new invitation record. */ - public Invitation (ParlorContext ctx, ParlorService pservice, - Name opponent, GameConfig config, - InvitationResponseObserver observer) - { - _ctx = ctx; - _pservice = pservice; - _observer = observer; - this.opponent = opponent; - this.config = config; - } - - /** - * Accepts this invitation. - */ - public void accept () - { - // generate the invocation service request - _pservice.respond(_ctx.getClient(), inviteId, - INVITATION_ACCEPTED, null, this); - } - - /** - * Refuses this invitation. - * - * @param message the message to deliver to the inviting user - * explaining the reason for the refusal or null if no message is to - * be provided. - */ - public void refuse (String message) - { - // generate the invocation service request - _pservice.respond(_ctx.getClient(), inviteId, - INVITATION_REFUSED, message, this); - } - - /** - * Cancels this invitation. - */ - public void cancel () - { - // if the invitation has not yet been acknowleged by the - // server, we make a note that it should be cancelled when we - // do receive the acknowlegement - if (inviteId == -1) { - _cancelled = true; - - } else { - // otherwise, generate the invocation service request - _pservice.cancel(_ctx.getClient(), inviteId, this); - // and remove it from the pending table - _ctx.getParlorDirector().clearInvitation(this); - } - } - - /** - * Counters this invitation with an invitation with different game - * configuration parameters. - * - * @param config the updated game configuration. - * @param observer the entity that will be notified if this - * counter-invitation is accepted, refused or countered. - */ - public void counter (GameConfig config, InvitationResponseObserver observer) - { - // update our observer (who will eventually be hearing back from - // the other client about their counter-invitation) - _observer = observer; - - // generate the invocation service request - _pservice.respond(_ctx.getClient(), inviteId, - INVITATION_COUNTERED, config, this); - } - - // documentation inherited from interface - public void inviteReceived (int inviteId) - { - // fill in our invitation id - this.inviteId = inviteId; - - // if the invitation was cancelled before we heard back about - // it, we need to send off a cancellation request now - if (_cancelled) { - _pservice.cancel(_ctx.getClient(), inviteId, this); - } else { - // otherwise, put it in the pending invites table - _ctx.getParlorDirector().registerInvitation(this); - } - } - - // documentation inherited from interface - public void requestFailed (String reason) - { - // let the observer know what's up - _observer.invitationRefused(this, reason); - } - - /** - * Called by the parlor director when we receive a response to an - * invitation initiated by this client. - */ - protected void receivedResponse (int code, Object arg) - { - // make sure we have an observer to notify - if (_observer == null) { - Log.warning("No observer registered for invitation " + - this + "."); - return; - } - - // notify the observer - try { - switch (code) { - case INVITATION_ACCEPTED: - _observer.invitationAccepted(this); - break; - - case INVITATION_REFUSED: - _observer.invitationRefused(this, (String)arg); - break; - - case INVITATION_COUNTERED: - _observer.invitationCountered(this, (GameConfig)arg); - break; - } - - } catch (Exception e) { - Log.warning("Invitation response observer choked on response " + - "[code=" + code + ", arg=" + arg + - ", invite=" + this + "]."); - Log.logStackTrace(e); - } - - // unless the invitation was countered, we can remove it from the - // pending table because it's resolved - if (code != INVITATION_COUNTERED) { - _ctx.getParlorDirector().clearInvitation(this); - } - } - - /** Returns a string representation of this invitation record. */ - public String toString () - { - return "[inviteId=" + inviteId + ", opponent=" + opponent + - ", config=" + config + ", observer=" + _observer + - ", cancelled=" + _cancelled + "]"; - } - - /** Provides access to client services. */ - protected ParlorContext _ctx; - - /** Provides access to parlor services. */ - protected ParlorService _pservice; - - /** The entity to notify when we receive a response for this - * invitation. */ - protected InvitationResponseObserver _observer; - - /** A flag indicating that we were requested to cancel this - * invitation before we even heard back with an acknowledgement - * that it was received by the server. */ - protected boolean _cancelled = false; -} diff --git a/src/java/com/threerings/parlor/client/InvitationHandler.java b/src/java/com/threerings/parlor/client/InvitationHandler.java deleted file mode 100644 index 9b3371407..000000000 --- a/src/java/com/threerings/parlor/client/InvitationHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// $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.parlor.client; - -/** - * A client entity that wishes to handle invitations received by other - * clients should implement this interface and register itself with the - * parlor director. It will subsequently be notified of any incoming - * invitations. It is also responsible for handling cancelled invitations. - */ -public interface InvitationHandler -{ - /** - * Called when an invitation is received from another player. - * - * @param invite the received invitation. - */ - public void invitationReceived (Invitation invite); - - /** - * Called when an invitation is cancelled by the inviting player. - * - * @param invite the cancelled invitation. - */ - public void invitationCancelled (Invitation invite); -} diff --git a/src/java/com/threerings/parlor/client/InvitationResponseObserver.java b/src/java/com/threerings/parlor/client/InvitationResponseObserver.java deleted file mode 100644 index 72b825896..000000000 --- a/src/java/com/threerings/parlor/client/InvitationResponseObserver.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.parlor.game.data.GameConfig; - -/** - * A client entity that wishes to generate invitations for games must - * implement this interface. An invitation can be accepted, refused or - * countered. A countered invitation is one where the game configuration - * is adjusted by the invited player and proposed back to the inviting - * player. - */ -public interface InvitationResponseObserver -{ - /** - * Called if the invitation was accepted. - * - * @param invite the invitation for which we received a response. - */ - public void invitationAccepted (Invitation invite); - - /** - * Called if the invitation was refused. - * - * @param invite the invitation for which we received a response. - * @param message a message provided by the invited user explaining - * the reason for their refusal, or the empty string if no message was - * provided. - */ - public void invitationRefused (Invitation invite, String message); - - /** - * Called if the invitation was countered with an alternate game - * configuration. - * - * @param invite the invitation for which we received a response. - * @param config the game configuration proposed by the invited - * player. - */ - public void invitationCountered (Invitation invite, GameConfig config); -} diff --git a/src/java/com/threerings/parlor/client/ParlorDecoder.java b/src/java/com/threerings/parlor/client/ParlorDecoder.java deleted file mode 100644 index e06ce4f77..000000000 --- a/src/java/com/threerings/parlor/client/ParlorDecoder.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.parlor.client.ParlorReceiver; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.client.InvocationDecoder; -import com.threerings.util.Name; - -/** - * Dispatches calls to a {@link ParlorReceiver} instance. - */ -public class ParlorDecoder extends InvocationDecoder -{ - /** The generated hash code used to identify this receiver class. */ - public static final String RECEIVER_CODE = "5ef9ee0d359c42a9024498ee9aad119a"; - - /** The method id used to dispatch {@link ParlorReceiver#gameIsReady} - * notifications. */ - public static final int GAME_IS_READY = 1; - - /** The method id used to dispatch {@link ParlorReceiver#receivedInvite} - * notifications. */ - public static final int RECEIVED_INVITE = 2; - - /** The method id used to dispatch {@link ParlorReceiver#receivedInviteCancellation} - * notifications. */ - public static final int RECEIVED_INVITE_CANCELLATION = 3; - - /** The method id used to dispatch {@link ParlorReceiver#receivedInviteResponse} - * notifications. */ - public static final int RECEIVED_INVITE_RESPONSE = 4; - - /** - * Creates a decoder that may be registered to dispatch invocation - * service notifications to the specified receiver. - */ - public ParlorDecoder (ParlorReceiver receiver) - { - this.receiver = receiver; - } - - // documentation inherited - public String getReceiverCode () - { - return RECEIVER_CODE; - } - - // documentation inherited - public void dispatchNotification (int methodId, Object[] args) - { - switch (methodId) { - case GAME_IS_READY: - ((ParlorReceiver)receiver).gameIsReady( - ((Integer)args[0]).intValue() - ); - return; - - case RECEIVED_INVITE: - ((ParlorReceiver)receiver).receivedInvite( - ((Integer)args[0]).intValue(), (Name)args[1], (GameConfig)args[2] - ); - return; - - case RECEIVED_INVITE_CANCELLATION: - ((ParlorReceiver)receiver).receivedInviteCancellation( - ((Integer)args[0]).intValue() - ); - return; - - case RECEIVED_INVITE_RESPONSE: - ((ParlorReceiver)receiver).receivedInviteResponse( - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (Object)args[2] - ); - return; - - default: - super.dispatchNotification(methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/parlor/client/ParlorDirector.java b/src/java/com/threerings/parlor/client/ParlorDirector.java deleted file mode 100644 index e43c07a33..000000000 --- a/src/java/com/threerings/parlor/client/ParlorDirector.java +++ /dev/null @@ -1,250 +0,0 @@ -// -// $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.parlor.client; - -import java.util.ArrayList; - -import com.samskivert.util.HashIntMap; -import com.threerings.util.Name; - -import com.threerings.presents.client.BasicDirector; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -import com.threerings.parlor.Log; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * The parlor director manages the client side of the game configuration - * and matchmaking processes. It is also the entity that is listening for - * game start notifications which it then dispatches the client entity - * that will actually create and display the user interface for the game - * that started. - */ -public class ParlorDirector extends BasicDirector - implements ParlorCodes, ParlorReceiver -{ - /** - * Constructs a parlor director and provides it with the parlor - * context that it can use to access the client services that it needs - * to provide its own services. Only one parlor director should be - * active in the client at one time and it should be made available - * via the parlor context. - * - * @param ctx the parlor context in use by the client. - */ - public ParlorDirector (ParlorContext ctx) - { - super(ctx); - _ctx = ctx; - - // register ourselves with the invocation director as a parlor - // notification receiver - _ctx.getClient().getInvocationDirector().registerReceiver( - new ParlorDecoder(this)); - } - - /** - * Sets the invitation handler, which is the entity that will be - * notified when we receive incoming invitation notifications and when - * invitations have been cancelled. - * - * @param handler our new invitation handler. - */ - public void setInvitationHandler (InvitationHandler handler) - { - _handler = handler; - } - - /** - * Adds the specified observer to the list of entities that are - * notified when we receive a game ready notification. - */ - public void addGameReadyObserver (GameReadyObserver observer) - { - _grobs.add(observer); - } - - /** - * Removes the specified observer from the list of entities that are - * notified when we receive a game ready notification. - */ - public void removeGameReadyObserver (GameReadyObserver observer) - { - _grobs.remove(observer); - } - - /** - * Requests that the named user be invited to a game described by the - * supplied game config. - * - * @param invitee the user to invite. - * @param config the configuration of the game to which the user is - * being invited. - * @param observer the entity that will be notified if this invitation - * is accepted, refused or countered. - * - * @return an invitation object that can be used to manage the - * outstanding invitation. - */ - public Invitation invite (Name invitee, GameConfig config, - InvitationResponseObserver observer) - { - // create the invitation record - Invitation invite = new Invitation( - _ctx, _pservice, invitee, config, observer); - // submit the invitation request to the server - _pservice.invite(_ctx.getClient(), invitee, config, invite); - // and return the invitation to the caller - return invite; - } - - /** - * Requests that the specified single player game be started. - * - * @param config the configuration of the single player game to be - * started. - * @param listener a listener to be informed of failure if the game - * cannot be started. - */ - public void startSolitaire ( - GameConfig config, InvocationService.ConfirmListener listener) - { - _pservice.startSolitaire(_ctx.getClient(), config, listener); - } - - // documentation inherited - public void clientDidLogoff (Client client) - { - super.clientDidLogoff(client); - _pservice = null; - _pendingInvites.clear(); - } - - // documentation inherited - protected void fetchServices (Client client) - { - // get a handle on our parlor services - _pservice = (ParlorService)client.requireService(ParlorService.class); - } - - // documentation inherited from interface - public void gameIsReady (int gameOid) - { - Log.info("Handling game ready [goid=" + gameOid + "]."); - - // see what our observers have to say about it - boolean handled = false; - for (int i = 0; i < _grobs.size(); i++) { - GameReadyObserver grob = (GameReadyObserver)_grobs.get(i); - handled = grob.receivedGameReady(gameOid) || handled; - } - - // if none of the observers took matters into their own hands, - // then we'll head on over to the game room ourselves - if (!handled) { - _ctx.getLocationDirector().moveTo(gameOid); - } - } - - // documentation inherited from interface - public void receivedInvite (int remoteId, Name inviter, GameConfig config) - { - // create an invitation record for this invitation - Invitation invite = new Invitation( - _ctx, _pservice, inviter, config, null); - invite.inviteId = remoteId; - - // put it in the pending invitations table - _pendingInvites.put(remoteId, invite); - - try { - // notify the invitation handler of the incoming invitation - _handler.invitationReceived(invite); - - } catch (Exception e) { - Log.warning("Invitation handler choked on invite " + - "notification " + invite + "."); - Log.logStackTrace(e); - } - } - - // documentation inherited from interface - public void receivedInviteResponse ( - int remoteId, int code, Object arg) - { - // look up the invitation record for this invitation - Invitation invite = (Invitation)_pendingInvites.get(remoteId); - if (invite == null) { - Log.warning("Have no record of invitation for which we " + - "received a response?! [remoteId=" + remoteId + - ", code=" + code + ", arg=" + arg + "]."); - - } else { - invite.receivedResponse(code, arg); - } - } - - // documentation inherited from interface - public void receivedInviteCancellation (int remoteId) - { - // TBD - } - - /** - * Register a new invitation in our pending invitations table. The - * invitation will call this when it knows its invitation id. - */ - protected void registerInvitation (Invitation invite) - { - _pendingInvites.put(invite.inviteId, invite); - } - - /** - * Called by an invitation when it knows it is no longer and can be - * cleared from the pending invitations table. - */ - protected void clearInvitation (Invitation invite) - { - _pendingInvites.remove(invite.inviteId); - } - - /** An active parlor context. */ - protected ParlorContext _ctx; - - /** Provides access to parlor server side services. */ - protected ParlorService _pservice; - - /** The entity that has registered itself to handle incoming - * invitation notifications. */ - protected InvitationHandler _handler; - - /** A table of acknowledged (but not yet accepted or refused) - * invitation requests, keyed on invitation id. */ - protected HashIntMap _pendingInvites = new HashIntMap(); - - /** We notify the entities on this list when we get a game ready - * notification. */ - protected ArrayList _grobs = new ArrayList(); -} diff --git a/src/java/com/threerings/parlor/client/ParlorReceiver.java b/src/java/com/threerings/parlor/client/ParlorReceiver.java deleted file mode 100644 index 41573c6d2..000000000 --- a/src/java/com/threerings/parlor/client/ParlorReceiver.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.util.Name; - -import com.threerings.presents.client.InvocationReceiver; - -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameConfig; - -/** - * Defines, for the parlor services, a set of notifications delivered - * asynchronously by the server to the client. These are handled by the - * {@link ParlorDirector}. - */ -public interface ParlorReceiver extends InvocationReceiver -{ - /** - * Dispatched to the client when a game in which they are a - * participant is ready for play. The client will then enter the game - * room which will trigger the loading of the appropriate game UI code - * and generally get things started. - * - * @param gameOid the object id of the game object. - */ - public void gameIsReady (int gameOid); - - /** - * Called by the invocation services when another user has invited us - * to play a game. - * - * @param remoteId the unique indentifier for this invitation (used - * when countering or responding). - * @param inviter the username of the inviting user. - * @param config the configuration information for the game to which - * we've been invited. - */ - public void receivedInvite (int remoteId, Name inviter, GameConfig config); - - /** - * Called by the invocation services when another user has responded - * to our invitation by either accepting, refusing or countering it. - * - * @param remoteId the indentifier for the invitation on question. - * @param code the response code, either {@link - * ParlorCodes#INVITATION_ACCEPTED} or {@link - * ParlorCodes#INVITATION_REFUSED} or {@link - * ParlorCodes#INVITATION_COUNTERED}. - * @param arg in the case of a refused invitation, a string - * containing a message provided by the invited user explaining the - * reason for refusal (the empty string if no explanation was - * provided). In the case of a countered invitation, a new game config - * object with the modified game configuration. - */ - public void receivedInviteResponse (int remoteId, int code, Object arg); - - /** - * Called by the invocation services when an outstanding invitation - * has been cancelled by the inviting user. - * - * @param remoteId the indentifier of the cancelled invitation. - */ - public void receivedInviteCancellation (int remoteId); -} diff --git a/src/java/com/threerings/parlor/client/ParlorService.java b/src/java/com/threerings/parlor/client/ParlorService.java deleted file mode 100644 index f8510c007..000000000 --- a/src/java/com/threerings/parlor/client/ParlorService.java +++ /dev/null @@ -1,164 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -import com.threerings.parlor.data.TableConfig; - -import com.threerings.parlor.game.data.GameConfig; - -/** - * Provides an interface to the various parlor invocation services. - * Presently these services are limited to the various matchmaking - * mechanisms. It is unlikely that client code will want to make direct - * use of this class, instead they would make use of the programmatic - * interface provided by the {@link ParlorDirector}. - */ -public interface ParlorService extends InvocationService -{ - /** - * Used to communicate responses to {@link #invite} requests. - */ - public static interface InviteListener extends InvocationListener - { - /** - * Called in response to a successful {@link #invite} request. - */ - public void inviteReceived (int inviteId); - } - - /** - * You probably don't want to call this directly, but want to generate - * your invitation request via {@link ParlorDirector#invite}. Requests - * that an invitation be delivered to the named user, requesting that - * they join the inviting user in a game, the details of which are - * specified in the supplied game config object. - * - * @param client a connected, operational client instance. - * @param invitee the username of the user to be invited. - * @param config a game config object detailing the type and - * configuration of the game to be created. - * @param listener will receive and process the response. - */ - public void invite (Client client, Name invitee, GameConfig config, - InviteListener listener); - - /** - * You probably don't want to call this directly, but want to call one - * of {@link Invitation#accept}, {@link Invitation#refuse}, or {@link - * Invitation#counter}. Requests that an invitation response be - * delivered with the specified parameters. - * - * @param client a connected, operational client instance. - * @param inviteId the unique id previously assigned by the server to - * this invitation. - * @param code the response code to use in responding to the - * invitation. - * @param arg the argument associated with the response (a string - * message from the player explaining why the response was refused in - * the case of an invitation refusal or an updated game configuration - * object in the case of a counter-invitation, or null in the case of - * an accepted invitation). - * @param listener will receive and process the response. - */ - public void respond (Client client, int inviteId, int code, Object arg, - InvocationListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link Invitation#cancel}. Requests that an outstanding - * invitation be cancelled. - * - * @param client a connected, operational client instance. - * @param inviteId the unique id previously assigned by the server to - * this invitation. - * @param listener will receive and process the response. - */ - public void cancel (Client client, int inviteId, - InvocationListener listener); - - /** - * Used to communicate responses to {@link #createTable}, {@link - * #joinTable}, and {@link #leaveTable} requests. - */ - public static interface TableListener extends InvocationListener - { - public void tableCreated (int tableId); - } - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#createTable}. Requests that a new table be - * created. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that will contain the newly - * created table. - * @param tableConfig the table configuration parameters. - * @param config the game config for the game to be matchmade by the - * table. - * @param listener will receive and process the response. - */ - public void createTable (Client client, int lobbyOid, - TableConfig tableConfig, GameConfig config, TableListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#joinTable}. Requests that the current user - * be added to the specified table at the specified position. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that contains the table. - * @param tableId the unique id of the table to which this user wishes - * to be added. - * @param position the position at the table to which this user desires - * to be added. - * @param listener will receive and process the response. - */ - public void joinTable (Client client, int lobbyOid, int tableId, - int position, InvocationListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#leaveTable}. Requests that the current user be - * removed from the specified table. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that contains the table. - * @param tableId the unique id of the table from which this user - * wishes to be removed. - * @param listener will receive and process the response. - */ - public void leaveTable (Client client, int lobbyOid, int tableId, - InvocationListener listener); - - /** - * Requests to start a single player game with the specified game - * configuration. - */ - public void startSolitaire (Client client, GameConfig config, - ConfirmListener listener); -} diff --git a/src/java/com/threerings/parlor/client/SeatednessObserver.java b/src/java/com/threerings/parlor/client/SeatednessObserver.java deleted file mode 100644 index 414f710c7..000000000 --- a/src/java/com/threerings/parlor/client/SeatednessObserver.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $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.parlor.client; - -/** - * Entites that wish to hear about when we sit down at a table or stand up - * from a table can implement this interface and register themselves with - * the {@link TableDirector}. - */ -public interface SeatednessObserver -{ - /** - * Called when this client sits down at or stands up from a table. - * - * @param isSeated true if the client is now seated at a table, false - * if they are now no longer seated at a table. - */ - public void seatednessDidChange (boolean isSeated); -} diff --git a/src/java/com/threerings/parlor/client/TableConfigurator.java b/src/java/com/threerings/parlor/client/TableConfigurator.java deleted file mode 100644 index c1259d877..000000000 --- a/src/java/com/threerings/parlor/client/TableConfigurator.java +++ /dev/null @@ -1,120 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.parlor.data.TableConfig; - -import com.threerings.parlor.game.client.GameConfigurator; - -/** - * This should be implemented some user-interface element that allows - * the user to configure whichever TableConfig options are relevant. - */ -public abstract class TableConfigurator -{ - /** - * Create a TableConfigurator. - */ - public TableConfigurator () - { - _config = createTableConfig(); - } - - /** - * Optionally, you can set a pre-configured TableConfig - * that will be used to initialize the display parameters (if possible). - * This should be called prior to init(). - */ - public void setTableConfig (TableConfig config) - { - if (config != null) { - _config = config; - } - } - - /** - * Initialize the TableConfigurator. - * - * At the time this is called, the GameConfigurator should have - * already been initialized. - */ - public void init (ParlorContext ctx, GameConfigurator gameConfigurator) - { - _ctx = ctx; - _gameConfigurator = gameConfigurator; - createConfigInterface(); - } - - /** - * Create the table config object that will be used. - */ - protected TableConfig createTableConfig () - { - return new TableConfig(); - } - - /** - * Create the config interface. - */ - protected void createConfigInterface () - { - // nothing by default - } - - /** - * If true, the TableConfigurator is empty, which doesn't mean that - * it will not return a TableConfig object (for it must), but rather - * that there are no user-editable options being presented in the - * config interface. - */ - public abstract boolean isEmpty (); - - /** - * Return the fully configured table config according to the currently - * configured user interface elements. - */ - public TableConfig getTableConfig () - { - flushTableConfig(); - return _config; - } - - /** - * Derived classes will want to override this method, flushing - * values from the user interface to the table config object. - */ - protected void flushTableConfig () - { - // nothing by default - } - - /** Provides access to client services. */ - protected ParlorContext _ctx; - - /** The config we're configurating. */ - protected TableConfig _config; - - /** The game configurator, which we may wish to reference. */ - protected GameConfigurator _gameConfigurator; -} diff --git a/src/java/com/threerings/parlor/client/TableDirector.java b/src/java/com/threerings/parlor/client/TableDirector.java deleted file mode 100644 index 2363c5c4c..000000000 --- a/src/java/com/threerings/parlor/client/TableDirector.java +++ /dev/null @@ -1,363 +0,0 @@ -// -// $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.parlor.client; - -import java.util.ArrayList; - -import com.threerings.presents.client.BasicDirector; -import com.threerings.presents.client.Client; - -import com.threerings.presents.dobj.EntryAddedEvent; -import com.threerings.presents.dobj.EntryRemovedEvent; -import com.threerings.presents.dobj.EntryUpdatedEvent; -import com.threerings.presents.dobj.SetListener; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.Log; -import com.threerings.parlor.data.Table; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.data.TableLobbyObject; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * As tables are created and managed within the scope of a place (a - * lobby), we want to fold the table management functionality into the - * standard hierarchy of place controllers that deal with place-related - * functionality on the client. Thus, instead of forcing places that - * expect to have tables to extend a TableLobbyController or - * something similar, we instead provide the table director which can be - * instantiated by the place controller (or specific table related views) - * to handle the table matchmaking services. - * - *

Entites that do so, will need to implement the {@link - * TableObserver} interface so that the table director can notify them - * when table related things happen. - * - *

The table services expect that the place object being used as a - * lobby in which the table matchmaking takes place implements the {@link - * TableLobbyObject} interface. - */ -public class TableDirector extends BasicDirector - implements SetListener, ParlorService.TableListener -{ - /** - * Creates a new table director to manage tables with the specified - * observer which will receive callbacks when interesting table - * related things happen. - * - * @param ctx the parlor context in use by the client. - * @param tableField the field name of the distributed set that - * contains the tables we will be managing. - * @param observer the entity that will receive callbacks when things - * happen to the tables. - */ - public TableDirector ( - ParlorContext ctx, String tableField, TableObserver observer) - { - super(ctx); - - // keep track of this stuff - _ctx = ctx; - _tableField = tableField; - _observer = observer; - } - - /** - * This must be called by the entity that uses the table director when - * the using entity prepares to enter and display a place. It is - * assumed that the client is already subscribed to the provided place - * object. - */ - public void willEnterPlace (PlaceObject place) - { - // add ourselves as a listener to the place object - place.addListener(this); - - // and remember this for later - _lobby = place; - } - - /** - * This must be called by the entity that uses the table director when - * the using entity has left and is done displaying a place. - */ - public void didLeavePlace (PlaceObject place) - { - // remove our listenership - place.removeListener(this); - - // clear out our lobby reference - _lobby = null; - } - - /** - * Requests that the specified observer be added to the list of - * observers that are notified when this client sits down at or stands - * up from a table. - */ - public void addSeatednessObserver (SeatednessObserver observer) - { - _seatedObservers.add(observer); - } - - /** - * Requests that the specified observer be removed from to the list of - * observers that are notified when this client sits down at or stands - * up from a table. - */ - public void removeSeatednessObserver (SeatednessObserver observer) - { - _seatedObservers.remove(observer); - } - - /** - * Returns true if this client is currently seated at a table, false - * if they are not. - */ - public boolean isSeated () - { - return (_ourTable != null); - } - - /** - * Sends a request to create a table with the specified game - * configuration. This user will become the owner of this table and - * will be added to the first position in the table. The response will - * be communicated via the {@link TableObserver} interface. - */ - public void createTable (TableConfig tableConfig, GameConfig config) - { - // if we're already in a table, refuse the request - if (_ourTable != null) { - Log.warning("Ignoring request to create table as we're " + - "already in a table [table=" + _ourTable + "]."); - return; - } - - // make sure we're currently in a place - if (_lobby == null) { - Log.warning("Requested to create a table but we're not " + - "currently in a place [config=" + config + "]."); - return; - } - - // go ahead and issue the create request - _pservice.createTable(_ctx.getClient(), _lobby.getOid(), tableConfig, - config, this); - } - - /** - * Sends a request to join the specified table at the specified - * position. The response will be communicated via the {@link - * TableObserver} interface. - */ - public void joinTable (int tableId, int position) - { - // if we're already in a table, refuse the request - if (_ourTable != null) { - Log.warning("Ignoring request to join table as we're " + - "already in a table [table=" + _ourTable + "]."); - return; - } - - // make sure we're currently in a place - if (_lobby == null) { - Log.warning("Requested to join a table but we're not " + - "currently in a place [tableId=" + tableId + "]."); - return; - } - - // issue the join request - _pservice.joinTable(_ctx.getClient(), _lobby.getOid(), tableId, - position, this); - } - - /** - * Sends a request to leave the specified table at which we are - * presumably seated. The response will be communicated via the {@link - * TableObserver} interface. - */ - public void leaveTable (int tableId) - { - // make sure we're currently in a place - if (_lobby == null) { - Log.warning("Requested to leave a table but we're not " + - "currently in a place [tableId=" + tableId + "]."); - return; - } - - // issue the leave request - _pservice.leaveTable(_ctx.getClient(), _lobby.getOid(), tableId, this); - } - - // documentation inherited - public void clientDidLogoff (Client client) - { - super.clientDidLogoff(client); - _pservice = null; - _lobby = null; - _ourTable = null; - } - - // documentation inherited - protected void fetchServices (Client client) - { - // get a handle on our parlor services - _pservice = (ParlorService)client.requireService(ParlorService.class); - } - - // documentation inherited - public void entryAdded (EntryAddedEvent event) - { - if (event.getName().equals(_tableField)) { - Table table = (Table)event.getEntry(); - - // check to see if we just joined a table - checkSeatedness(table); - - // now let the observer know what's up - _observer.tableAdded(table); - } - } - - // documentation inherited - public void entryUpdated (EntryUpdatedEvent event) - { - if (event.getName().equals(_tableField)) { - Table table = (Table)event.getEntry(); - - // check to see if we just joined or left a table - checkSeatedness(table); - - // now let the observer know what's up - _observer.tableUpdated(table); - } - } - - // documentation inherited - public void entryRemoved (EntryRemovedEvent event) - { - if (event.getName().equals(_tableField)) { - Integer tableId = (Integer)event.getKey(); - - // check to see if our table just disappeared - if (_ourTable != null && tableId.equals(_ourTable.tableId)) { - _ourTable = null; - notifySeatedness(false); - } - - // now let the observer know what's up - _observer.tableRemoved(tableId.intValue()); - } - } - - // documentation inherited from interface - public void tableCreated (int tableId) - { - // nothing much to do here - Log.info("Table creation succeeded [tableId=" + tableId + "]."); - } - - // documentation inherited from interface - public void requestFailed (String reason) - { - Log.warning("Table creation failed [reason=" + reason + "]."); - } - - /** - * Checks to see if we're a member of this table and notes it as our - * table, if so. - */ - protected void checkSeatedness (Table table) - { - Table oldTable = _ourTable; - - // if this is the same table as our table, clear out our table - // reference and allow it to be added back if we are still in the - // table - if (table.equals(_ourTable)) { - _ourTable = null; - } - - // look for our username in the occupants array - BodyObject self = (BodyObject)_ctx.getClient().getClientObject(); - for (int i = 0; i < table.occupants.length; i++) { - if (self.getVisibleName().equals(table.occupants[i])) { - _ourTable = table; - break; - } - } - - // if nothing changed, bail now - if (oldTable == _ourTable || - (oldTable != null && oldTable.equals(_ourTable))) { - return; - } - - // otherwise notify the observers - notifySeatedness(_ourTable != null); - } - - /** - * Notifies the seatedness observers of a seatedness change. - */ - protected void notifySeatedness (boolean isSeated) - { - int slength = _seatedObservers.size(); - for (int i = 0; i < slength; i++) { - SeatednessObserver observer = (SeatednessObserver) - _seatedObservers.get(i); - try { - observer.seatednessDidChange(isSeated); - } catch (Exception e) { - Log.warning("Observer choked in seatednessDidChange() " + - "[observer=" + observer + "]."); - Log.logStackTrace(e); - } - } - } - - /** A context by which we can access necessary client services. */ - protected ParlorContext _ctx; - - /** Parlor server-side services. */ - protected ParlorService _pservice; - - /** The place object in which we're currently managing tables. */ - protected PlaceObject _lobby; - - /** The field name of the distributed set that contains our tables. */ - protected String _tableField; - - /** The entity that we talk to when table stuff happens. */ - protected TableObserver _observer; - - /** The table of which we are a member if any. */ - protected Table _ourTable; - - /** An array of entities that want to hear about when we stand up or - * sit down. */ - protected ArrayList _seatedObservers = new ArrayList(); -} diff --git a/src/java/com/threerings/parlor/client/TableObserver.java b/src/java/com/threerings/parlor/client/TableObserver.java deleted file mode 100644 index 9aacbf9b7..000000000 --- a/src/java/com/threerings/parlor/client/TableObserver.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// $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.parlor.client; - -import com.threerings.parlor.data.Table; - -/** - * The {@link TableDirector} converts distributed object events into - * higher level callbacks to implementers of this interface, which are - * expected to render these events sensically in a user interface. - */ -public interface TableObserver -{ - /** - * Called when a new table is created. - */ - public void tableAdded (Table table); - - /** - * Called when something has changed about a table (occupant list - * updated, state changed from matchmaking to in-play, etc.). - */ - public void tableUpdated (Table table); - - /** - * Called when a table goes away. - */ - public void tableRemoved (int tableId); -} diff --git a/src/java/com/threerings/parlor/data/ParlorCodes.java b/src/java/com/threerings/parlor/data/ParlorCodes.java deleted file mode 100644 index 405e0cc77..000000000 --- a/src/java/com/threerings/parlor/data/ParlorCodes.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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.parlor.data; - -import com.threerings.presents.data.InvocationCodes; - -/** - * Contains codes used by the parlor invocation services. - */ -public interface ParlorCodes extends InvocationCodes -{ - /** The response code for an accepted invitation. */ - public static final int INVITATION_ACCEPTED = 0; - - /** The response code for a refused invitation. */ - public static final int INVITATION_REFUSED = 1; - - /** The response code for a countered invitation. */ - public static final int INVITATION_COUNTERED = 2; - - /** An error code explaining that an invitation was rejected because - * the invited user was not online at the time the invitation was - * received. */ - public static final String INVITEE_NOT_ONLINE = "m.invitee_not_online"; - - /** An error code returned when a user requests to join a table that - * doesn't exist. */ - public static final String NO_SUCH_TABLE = "m.no_such_table"; - - /** An error code returned when a user requests to join a table at a - * position that is not valid. */ - public static final String INVALID_TABLE_POSITION = - "m.invalid_table_position"; - - /** An error code returned when a user requests to join a table in a - * position that is already occupied. */ - public static final String TABLE_POSITION_OCCUPIED = - "m.table_position_occupied"; - - /** An error code returned when a user requests to leave a table that - * they were not sitting at in the first place. */ - public static final String NOT_AT_TABLE = "m.not_at_table"; -} diff --git a/src/java/com/threerings/parlor/data/ParlorMarshaller.java b/src/java/com/threerings/parlor/data/ParlorMarshaller.java deleted file mode 100644 index 31dc51a6a..000000000 --- a/src/java/com/threerings/parlor/data/ParlorMarshaller.java +++ /dev/null @@ -1,200 +0,0 @@ -// -// $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.parlor.data; - -import com.threerings.parlor.client.ParlorService; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; -import com.threerings.util.Name; - -/** - * Provides the implementation of the {@link ParlorService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class ParlorMarshaller extends InvocationMarshaller - implements ParlorService -{ - // documentation inherited - public static class InviteMarshaller extends ListenerMarshaller - implements InviteListener - { - /** The method id used to dispatch {@link #inviteReceived} - * responses. */ - public static final int INVITE_RECEIVED = 1; - - // documentation inherited from interface - public void inviteReceived (int arg1) - { - _invId = null; - omgr.postEvent(new InvocationResponseEvent( - callerOid, requestId, INVITE_RECEIVED, - new Object[] { Integer.valueOf(arg1) })); - } - - // documentation inherited - public void dispatchResponse (int methodId, Object[] args) - { - switch (methodId) { - case INVITE_RECEIVED: - ((InviteListener)listener).inviteReceived( - ((Integer)args[0]).intValue()); - return; - - default: - super.dispatchResponse(methodId, args); - return; - } - } - } - - // documentation inherited - public static class TableMarshaller extends ListenerMarshaller - implements TableListener - { - /** The method id used to dispatch {@link #tableCreated} - * responses. */ - public static final int TABLE_CREATED = 1; - - // documentation inherited from interface - public void tableCreated (int arg1) - { - _invId = null; - omgr.postEvent(new InvocationResponseEvent( - callerOid, requestId, TABLE_CREATED, - new Object[] { Integer.valueOf(arg1) })); - } - - // documentation inherited - public void dispatchResponse (int methodId, Object[] args) - { - switch (methodId) { - case TABLE_CREATED: - ((TableListener)listener).tableCreated( - ((Integer)args[0]).intValue()); - return; - - default: - super.dispatchResponse(methodId, args); - return; - } - } - } - - /** The method id used to dispatch {@link #cancel} requests. */ - public static final int CANCEL = 1; - - // documentation inherited from interface - public void cancel (Client arg1, int arg2, InvocationService.InvocationListener arg3) - { - ListenerMarshaller listener3 = new ListenerMarshaller(); - listener3.listener = arg3; - sendRequest(arg1, CANCEL, new Object[] { - Integer.valueOf(arg2), listener3 - }); - } - - /** The method id used to dispatch {@link #createTable} requests. */ - public static final int CREATE_TABLE = 2; - - // documentation inherited from interface - public void createTable (Client arg1, int arg2, TableConfig arg3, GameConfig arg4, ParlorService.TableListener arg5) - { - ParlorMarshaller.TableMarshaller listener5 = new ParlorMarshaller.TableMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, CREATE_TABLE, new Object[] { - Integer.valueOf(arg2), arg3, arg4, listener5 - }); - } - - /** The method id used to dispatch {@link #invite} requests. */ - public static final int INVITE = 3; - - // documentation inherited from interface - public void invite (Client arg1, Name arg2, GameConfig arg3, ParlorService.InviteListener arg4) - { - ParlorMarshaller.InviteMarshaller listener4 = new ParlorMarshaller.InviteMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, INVITE, new Object[] { - arg2, arg3, listener4 - }); - } - - /** The method id used to dispatch {@link #joinTable} requests. */ - public static final int JOIN_TABLE = 4; - - // documentation inherited from interface - public void joinTable (Client arg1, int arg2, int arg3, int arg4, InvocationService.InvocationListener arg5) - { - ListenerMarshaller listener5 = new ListenerMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, JOIN_TABLE, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), Integer.valueOf(arg4), listener5 - }); - } - - /** The method id used to dispatch {@link #leaveTable} requests. */ - public static final int LEAVE_TABLE = 5; - - // documentation inherited from interface - public void leaveTable (Client arg1, int arg2, int arg3, InvocationService.InvocationListener arg4) - { - ListenerMarshaller listener4 = new ListenerMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, LEAVE_TABLE, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 - }); - } - - /** The method id used to dispatch {@link #respond} requests. */ - public static final int RESPOND = 6; - - // documentation inherited from interface - public void respond (Client arg1, int arg2, int arg3, Object arg4, InvocationService.InvocationListener arg5) - { - ListenerMarshaller listener5 = new ListenerMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, RESPOND, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), arg4, listener5 - }); - } - - /** The method id used to dispatch {@link #startSolitaire} requests. */ - public static final int START_SOLITAIRE = 7; - - // documentation inherited from interface - public void startSolitaire (Client arg1, GameConfig arg2, InvocationService.ConfirmListener arg3) - { - InvocationMarshaller.ConfirmMarshaller listener3 = new InvocationMarshaller.ConfirmMarshaller(); - listener3.listener = arg3; - sendRequest(arg1, START_SOLITAIRE, new Object[] { - arg2, listener3 - }); - } - -} diff --git a/src/java/com/threerings/parlor/data/Table.java b/src/java/com/threerings/parlor/data/Table.java deleted file mode 100644 index 9751273b8..000000000 --- a/src/java/com/threerings/parlor/data/Table.java +++ /dev/null @@ -1,402 +0,0 @@ -// -// $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.parlor.data; - -import com.samskivert.util.ArrayIntSet; -import com.samskivert.util.ListUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.util.Name; - -import com.threerings.presents.dobj.DSet; - -import com.threerings.crowd.data.BodyObject; - -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.data.PartyGameConfig; - -/** - * This class represents a table that is being used to matchmake a game by - * the Parlor services. - */ -public class Table - implements DSet.Entry, ParlorCodes -{ - /** The unique identifier for this table. */ - public Integer tableId; - - /** The object id of the lobby object with which this table is - * associated. */ - public int lobbyOid; - - /** The oid of the game that was created from this table or -1 if the - * table is still in matchmaking mode. */ - public int gameOid = -1; - - /** An array of the usernames of the occupants of this table (some - * slots may not be filled), or null if a party game. */ - public Name[] occupants; - - /** The body oids of the occupants of this table, or null if a party game. - * (This is not propagated to remote instances.) */ - public transient int[] bodyOids; - - /** The game config for the game that is being matchmade. */ - public GameConfig config; - - /** The table configuration object. */ - public TableConfig tconfig; - - /** - * Creates a new table instance, and assigns it the next monotonically - * increasing table id. - * - * @param lobbyOid the object id of the lobby in which this table is - * to live. - * @param tconfig the table configuration for this table. - * @param config the configuration of the game being matchmade by this - * table. - */ - public Table (int lobbyOid, TableConfig tconfig, GameConfig config) - { - // assign a unique table id - tableId = Integer.valueOf(++_tableIdCounter); - - // keep track of our lobby oid - this.lobbyOid = lobbyOid; - - // keep a casted reference around - this.tconfig = tconfig; - this.config = config; - - // make room for the maximum number of players - if (tconfig.desiredPlayerCount != -1) { - occupants = new Name[tconfig.desiredPlayerCount]; - bodyOids = new int[occupants.length]; - - // fill in information on the AIs - int acount = (config.ais == null) ? 0 : config.ais.length; - for (int ii = 0; ii < acount; ii++) { - // TODO: handle this naming business better - occupants[ii] = new Name("AI " + (ii+1)); - } - } - } - - /** - * Constructs a blank table instance, suitable for unserialization. - */ - public Table () - { - } - - /** - * A convenience function for accessing the table id as an int. - */ - public int getTableId () - { - return tableId.intValue(); - } - - /** - * Returns true if there is no one sitting at this table. - */ - public boolean isEmpty () - { - for (int i = 0; i < bodyOids.length; i++) { - if (bodyOids[i] != 0) { - return false; - } - } - return true; - } - - /** - * Count the number of players currently occupying this table. - */ - public int getOccupiedCount () - { - int count = 0; - for (int ii = 0; ii < occupants.length; ii++) { - if (occupants[ii] != null) { - count++; - } - } - return count; - } - - /** - * Once a table is ready to play (see {@link #mayBeStarted} and {@link - * #shouldBeStarted}), the players array can be fetched using this - * method. It will return an array containing the usernames of all of - * the players in the game, sized properly and with each player in the - * appropriate position. - */ - public Name[] getPlayers () - { - if (isPartyGame()) { - return occupants; - } - - // create and populate the players array - Name[] players = new Name[getOccupiedCount()]; - for (int ii = 0, dex = 0; ii < occupants.length; ii++) { - if (occupants[ii] != null) { - players[dex++] = occupants[ii]; - } - } - - return players; - } - - /** - * For a team game, get the team member indices of the compressed - * players array returned by getPlayers(). - */ - public int[][] getTeamMemberIndices () - { - int[][] teams = tconfig.teamMemberIndices; - if (teams == null) { - return null; - } - - // compress the team indexes down - ArrayIntSet set = new ArrayIntSet(); - int[][] newTeams = new int[teams.length][]; - Name[] players = getPlayers(); - for (int ii=0; ii < teams.length; ii++) { - set.clear(); - for (int jj=0; jj < teams[ii].length; jj++) { - Name occ = occupants[teams[ii][jj]]; - if (occ != null) { - set.add(ListUtil.indexOf(players, occ)); - } - } - newTeams[ii] = set.toIntArray(); - } - - return newTeams; - } - - /** - * Return true if the game is a party game. - */ - public boolean isPartyGame () - { - return (PartyGameConfig.NOT_PARTY_GAME != getPartyGameType()); - } - - /** - * Get the type of party game being played at this table, or - * PartyGameConfig.NOT_PARTY_GAME. - */ - public byte getPartyGameType () - { - if (config instanceof PartyGameConfig) { - return ((PartyGameConfig) config).getPartyGameType(); - - } else { - return PartyGameConfig.NOT_PARTY_GAME; - } - } - - /** - * Requests to seat the specified user at the specified position in - * this table. - * - * @param position the position in which to seat the user. - * @param occupant the occupant to set. - * - * @return null if the user was successfully seated, a string error - * code explaining the failure if the user was not able to be seated - * at that position. - */ - public String setOccupant (int position, BodyObject occupant) - { - // make sure the requested position is a valid one - if (position >= tconfig.desiredPlayerCount || position < 0) { - return INVALID_TABLE_POSITION; - } - - // make sure the requested position is not already occupied - if (occupants[position] != null) { - return TABLE_POSITION_OCCUPIED; - } - - // otherwise all is well, stick 'em in - setOccupantPos(position, occupant); - return null; - } - - /** - * This method is used for party games, it does no bounds checking - * or verification of the player's ability to join, if you are unsure - * you should call 'setOccupant'. - */ - public void setOccupantPos (int position, BodyObject occupant) - { - occupants[position] = occupant.getVisibleName(); - bodyOids[position] = occupant.getOid(); - } - - /** - * Requests that the specified user be removed from their seat at this - * table. - * - * @return true if the user was seated at the table and has now been - * removed, false if the user was never seated at the table in the - * first place. - */ - public boolean clearOccupant (Name username) - { - for (int i = 0; i < occupants.length; i++) { - if (username.equals(occupants[i])) { - clearOccupantPos(i); - return true; - } - } - return false; - } - - /** - * Requests that the user identified by the specified body object id - * be removed from their seat at this table. - * - * @return true if the user was seated at the table and has now been - * removed, false if the user was never seated at the table in the - * first place. - */ - public boolean clearOccupant (int bodyOid) - { - for (int i = 0; i < bodyOids.length; i++) { - if (bodyOid == bodyOids[i]) { - clearOccupantPos(i); - return true; - } - } - return false; - } - - /** - * Called to clear an occupant at the specified position. - * Only call this method if you know what you're doing. - */ - public void clearOccupantPos (int position) - { - occupants[position] = null; - bodyOids[position] = 0; - } - - /** - * Returns true if this table has a sufficient number of occupants - * that the game can be started. - */ - public boolean mayBeStarted () - { - if (tconfig.teamMemberIndices == null) { - // for a normal game, just check to see if we're past the minimum - return tconfig.minimumPlayerCount <= getOccupiedCount(); - - } else { - // for a team game, make sure each team has the minimum players - int[][] teams = tconfig.teamMemberIndices; - for (int ii=0; ii < teams.length; ii++) { - int teamCount = 0; - for (int jj=0; jj < teams[ii].length; jj++) { - if (occupants[teams[ii][jj]] != null) { - teamCount++; - } - } - if (teamCount < tconfig.minimumPlayerCount) { - return false; - } - } - return true; - } - } - - /** - * Returns true if sufficient seats are occupied that the game should - * be automatically started. - */ - public boolean shouldBeStarted () - { - return tconfig.desiredPlayerCount <= getOccupiedCount(); - } - - /** - * Returns true if this table is in play, false if it is still being - * matchmade. - */ - public boolean inPlay () - { - return gameOid != -1; - } - - // documentation inherited - public Comparable getKey () - { - return tableId; - } - - // documentation inherited - public boolean equals (Object other) - { - return (other instanceof Table) && - tableId.equals(((Table) other).tableId); - } - - // documentation inherited - public int hashCode () - { - return tableId.intValue(); - } - - /** - * Generates a string representation of this table instance. - */ - public String toString () - { - StringBuilder buf = new StringBuilder(); - buf.append(StringUtil.shortClassName(this)); - buf.append(" ["); - toString(buf); - buf.append("]"); - return buf.toString(); - } - - /** - * Helper method for toString, ripe for overrideability. - */ - protected void toString (StringBuilder buf) - { - buf.append("tableId=").append(tableId); - buf.append(", lobbyOid=").append(lobbyOid); - buf.append(", gameOid=").append(gameOid); - buf.append(", occupants=").append(StringUtil.toString(occupants)); - buf.append(", config=").append(config); - } - - /** A counter for assigning table ids. */ - protected static int _tableIdCounter = 0; -} diff --git a/src/java/com/threerings/parlor/data/TableConfig.java b/src/java/com/threerings/parlor/data/TableConfig.java deleted file mode 100644 index d6d1355a9..000000000 --- a/src/java/com/threerings/parlor/data/TableConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.parlor.data; - -import com.threerings.io.SimpleStreamableObject; - -/** - * Table configuration parameters for a game that is to be matchmade - * using the table services. - */ -public class TableConfig extends SimpleStreamableObject -{ - /** The total number of players that are desired for the table, - * or -1 for a party game. For team games, this should be set to the - * total number of players overall, as teams may be unequal. */ - public int desiredPlayerCount; - - /** The minimum number of players needed overall (or per-team if a - * team-based game) for the game to start at the creator's discretion. */ - public int minimumPlayerCount; - - /** If non-null, indicates that this is a team-based game and contains - * the team assignments for each player. For example, a game with - * three players in two teams- players 0 and 2 versus player 1- would - * have { {0, 2}, {1} }; */ - public int[][] teamMemberIndices; - - /** Whether the table is "private". */ - public boolean privateTable; -} diff --git a/src/java/com/threerings/parlor/data/TableLobbyObject.java b/src/java/com/threerings/parlor/data/TableLobbyObject.java deleted file mode 100644 index f2d58824a..000000000 --- a/src/java/com/threerings/parlor/data/TableLobbyObject.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.parlor.data; - -import com.threerings.presents.dobj.DSet; - -/** - * This interface must be implemented by the place object used by a lobby - * that wishes to make use of the table services. - */ -public interface TableLobbyObject -{ - /** - * Returns a reference to the distributed set instance that will be - * holding the tables. - */ - public DSet getTables (); - - /** - * Adds the supplied table instance to the tables set (using the - * appropriate distributed object mechanisms). - */ - public void addToTables (Table table); - - /** - * Updates the value of the specified table instance in the tables - * distributed set (using the appropriate distributed object - * mechanisms). - */ - public void updateTables (Table table); - - /** - * Removes the table instance that matches the specified key from the - * tables set (using the appropriate distributed object mechanisms). - */ - public void removeFromTables (Comparable key); -} diff --git a/src/java/com/threerings/parlor/game/client/GameConfigurator.java b/src/java/com/threerings/parlor/game/client/GameConfigurator.java deleted file mode 100644 index 4936b9f64..000000000 --- a/src/java/com/threerings/parlor/game/client/GameConfigurator.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// $Id: GameConfigurator.java 3590 2005-06-08 23:20: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.parlor.game.client; - -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * Provides the base from which interfaces can be built to configure games - * prior to starting them. Derived classes would extend the base - * configurator adding interface elements and wiring them up properly to - * allow the user to configure an instance of their game. - * - *

Clients that use the game configurator will want to instantiate one - * based on the class returned from the {@link GameConfig} and then - * initialize it with a call to {@link #init}. - */ -public abstract class GameConfigurator -{ - /** - * Initializes this game configurator, creates its user interface - * elements and prepares it for display. - */ - public void init (ParlorContext ctx) - { - // save this for later - _ctx = ctx; - - // create our interface elements - createConfigInterface(); - } - - /** - * The default implementation creates nothing. - */ - protected void createConfigInterface () - { - } - - /** - * Provides this configurator with its configuration. It should set up - * all of its user interface elements to reflect the configuration. - */ - public void setGameConfig (GameConfig config) - { - _config = config; - // set up the user interface - gotGameConfig(); - } - - /** - * Derived classes will likely want to override this method and - * configure their user interface elements accordingly. - */ - protected void gotGameConfig () - { - } - - /** - * Obtains a configured game configuration. - */ - public GameConfig getGameConfig () - { - // flush our changes to the config object - flushGameConfig(); - return _config; - } - - /** - * Derived classes will want to override this method, flushing values - * from the user interface to the game config object so that it is - * properly configured prior to being returned to the {@link - * #getGameConfig} caller. - */ - protected void flushGameConfig () - { - } - - /** Provides access to client services. */ - protected ParlorContext _ctx; - - /** Our game configuration. */ - protected GameConfig _config; -} diff --git a/src/java/com/threerings/parlor/game/client/GameController.java b/src/java/com/threerings/parlor/game/client/GameController.java deleted file mode 100644 index a7231b56c..000000000 --- a/src/java/com/threerings/parlor/game/client/GameController.java +++ /dev/null @@ -1,331 +0,0 @@ -// -// $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.parlor.game.client; - -import java.awt.event.ActionEvent; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; - -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.client.PlaceControllerDelegate; -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.parlor.Log; -import com.threerings.parlor.game.data.GameCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.game.data.PartyGameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * The game controller manages the flow and control of a game on the - * client side. This class serves as the root of a hierarchy of controller - * classes that aim to provide functionality shared between various - * similar games. The base controller provides functionality for starting - * and ending the game and for calculating ratings adjustements when a - * game ends normally. It also handles the basic house keeping like - * subscription to the game object and dispatch of commands and - * distributed object events. - */ -public abstract class GameController extends PlaceController - implements AttributeChangeListener -{ - /** - * Initializes this game controller with the game configuration that - * was established during the match making process. Derived classes - * may want to override this method to initialize themselves with - * game-specific configuration parameters but they should be sure to - * call super.init in such cases. - * - * @param ctx the client context. - * @param config the configuration of the game we are intended to - * control. - */ - public void init (CrowdContext ctx, PlaceConfig config) - { - // cast our references before we call super.init() so that when - // super.init() calls createPlaceView(), we have our casted - // references already in place - _ctx = (ParlorContext)ctx; - _config = (GameConfig)config; - - super.init(ctx, config); - } - - /** - * Adds this controller as a listener to the game object (thus derived - * classes need not do so) and lets the game manager know that we are - * now ready to go. - */ - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - // obtain a casted reference - _gobj = (GameObject)plobj; - - // if this place object is not our current location we'll need to - // add it as an auxiliary chat source - BodyObject bobj = (BodyObject)_ctx.getClient().getClientObject(); - if (bobj.location != plobj.getOid()) { - _ctx.getChatDirector().addAuxiliarySource( - _gobj, GameCodes.GAME_CHAT_TYPE); - } - - // and add ourselves as a listener - _gobj.addListener(this); - - // we don't want to claim to be finished until any derived classes - // that overrode this method have executed, so we'll queue up a - // runnable here that will let the game manager know that we're - // ready on the next pass through the distributed event loop - Log.info("Entering game " + _gobj.which() + "."); - if (_gobj.getPlayerIndex(bobj.getVisibleName()) != -1) { - _ctx.getClient().getRunQueue().postRunnable(new Runnable() { - public void run () { - // finally let the game manager know that we're ready - // to roll - playerReady(); - } - }); - } - } - - /** - * Removes our listener registration from the game object and cleans - * house. - */ - public void didLeavePlace (PlaceObject plobj) - { - super.didLeavePlace(plobj); - - _ctx.getChatDirector().removeAuxiliarySource(_gobj); - - // unlisten to the game object - _gobj.removeListener(this); - _gobj = null; - } - - /** - * Returns whether the game is over. - */ - public boolean isGameOver () - { - boolean gameOver = - ((_gobj != null) ? (_gobj.state != GameObject.IN_PLAY) : true); - return (_gameOver || gameOver); - } - - /** - * Sets the client game over override. This is used in situations - * where we determine that the game is over before the server has - * informed us of such. - */ - public void setGameOver (boolean gameOver) - { - _gameOver = gameOver; - } - - /** - * Calls {@link #gameWillReset}, ends the current game (locally, it - * does not tell the server to end the game), and waits to receive a - * reset notification (which is simply an event setting the game state - * to IN_PLAY even though it's already set to - * IN_PLAY) from the server which will start up a new - * game. Derived classes should override {@link #gameWillReset} to - * perform any game-specific animations. - */ - public void resetGame () - { - // let derived classes do their thing - gameWillReset(); - - // end the game until we receive a new board - setGameOver(true); - } - - /** - * Returns the unique round identifier for the current round. - */ - public int getRoundId () - { - return (_gobj == null) ? -1 : _gobj.roundId; - } - - /** - * Handles basic game controller action events. Derived classes should - * be sure to call super.handleAction for events they - * don't specifically handle. - */ - public boolean handleAction (ActionEvent action) - { - return super.handleAction(action); - } - - /** - * A way for controllers to display a game-related system message. - */ - public void systemMessage (String bundle, String msg) - { - _ctx.getChatDirector().displayInfo( - bundle, msg, GameCodes.GAME_CHAT_TYPE); - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - // deal with game state changes - if (event.getName().equals(GameObject.STATE)) { - if (!stateDidChange(event.getIntValue())) { - Log.warning("Game transitioned to unknown state " + - "[gobj=" + _gobj + - ", state=" + event.getIntValue() + "]."); - } - } - } - - /** - * Derived classes can override this method if they add additional game - * states and should handle transitions to those states, returning true to - * indicate they were handled and calling super for the normal game states. - */ - protected boolean stateDidChange (int state) - { - switch (state) { - case GameObject.IN_PLAY: - gameDidStart(); - return true; - case GameObject.GAME_OVER: - gameDidEnd(); - return true; - case GameObject.CANCELLED: - gameWasCancelled(); - return true; - } - return false; - } - - /** - * Called after we've entered the game and everything has initialized - * to notify the server that we, as a player, are ready to play. - */ - protected void playerReady () - { - Log.info("Reporting ready " + _gobj.which() + "."); - _gobj.gameService.playerReady(_ctx.getClient()); - } - - /** - * Called when the game transitions to the IN_PLAY - * state. This happens when all of the players have arrived and the - * server starts the game. - */ - protected void gameDidStart () - { - if (_gobj == null) { - Log.info("Received gameDidStart() after leaving game room."); - return; - } - - // clear out our game over flag - setGameOver(false); - - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((GameControllerDelegate)delegate).gameDidStart(); - } - }); - } - - /** - * Called when the game transitions to the GAME_OVER - * state. This happens when the game reaches some end condition by - * normal means (is not cancelled or aborted). - */ - protected void gameDidEnd () - { - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((GameControllerDelegate)delegate).gameDidEnd(); - } - }); - } - - /** - * Called when the game was cancelled for some reason. - */ - protected void gameWasCancelled () - { - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((GameControllerDelegate)delegate).gameWasCancelled(); - } - }); - } - - /** - * Called to give derived classes a chance to display animations, send - * a final packet, or do any other business they care to do when the - * game is about to reset. - */ - protected void gameWillReset () - { - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((GameControllerDelegate)delegate).gameWillReset(); - } - }); - } - - /** - * Used to determine if this game is a party game. - */ - protected boolean isPartyGame () - { - return (_config instanceof PartyGameConfig) && - (((PartyGameConfig)_config).getPartyGameType() != - PartyGameConfig.NOT_PARTY_GAME); - } - - /** A reference to the active parlor context. */ - protected ParlorContext _ctx; - - /** Our game configuration information. */ - protected GameConfig _config; - - /** A reference to the game object for the game that we're - * controlling. */ - protected GameObject _gobj; - - /** A local flag overriding the game over state for situations where - * the client knows the game is over before the server has - * transitioned the game object accordingly. */ - protected boolean _gameOver; -} diff --git a/src/java/com/threerings/parlor/game/client/GameControllerDelegate.java b/src/java/com/threerings/parlor/game/client/GameControllerDelegate.java deleted file mode 100644 index 9b680a421..000000000 --- a/src/java/com/threerings/parlor/game/client/GameControllerDelegate.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.parlor.game.client; - -import com.threerings.crowd.client.PlaceControllerDelegate; - -/** - * Extends the {@link PlaceControllerDelegate} mechanism with game - * controller specific methods. - */ -public class GameControllerDelegate extends PlaceControllerDelegate -{ - /** - * Provides the delegate with a reference to the game controller for - * which it is delegating. - */ - public GameControllerDelegate (GameController ctrl) - { - super(ctrl); - } - - /** - * Called when the game transitions to the IN_PLAY - * state. This happens when all of the players have arrived and the - * server starts the game. - */ - public void gameDidStart () - { - } - - /** - * Called when the game transitions to the GAME_OVER - * state. This happens when the game reaches some end condition by - * normal means (is not cancelled or aborted). - */ - public void gameDidEnd () - { - } - - /** - * Called when the game was cancelled for some reason. - */ - public void gameWasCancelled () - { - } - - /** - * Called to give derived classes a chance to display animations, send - * a final packet, or do any other business they care to do when the - * game is about to reset. - */ - public void gameWillReset () - { - } -} diff --git a/src/java/com/threerings/parlor/game/client/GameService.java b/src/java/com/threerings/parlor/game/client/GameService.java deleted file mode 100644 index d77a791d7..000000000 --- a/src/java/com/threerings/parlor/game/client/GameService.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $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.parlor.game.client; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -/** - * Provides services used by game clients to request that actions be taken - * by the game manager. - */ -public interface GameService extends InvocationService -{ - /** - * Lets the game manager know that the calling player is in the game - * room and ready to play. - */ - public void playerReady (Client client); -} diff --git a/src/java/com/threerings/parlor/game/client/SwingGameConfigurator.java b/src/java/com/threerings/parlor/game/client/SwingGameConfigurator.java deleted file mode 100644 index ba10e40e6..000000000 --- a/src/java/com/threerings/parlor/game/client/SwingGameConfigurator.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $Id: GameConfigurator.java 3590 2005-06-08 23:20: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.parlor.game.client; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; - -import javax.swing.JComponent; -import javax.swing.JPanel; - -import com.samskivert.swing.VGroupLayout; - -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.util.ParlorContext; - -/** - * Provides the base from which interfaces can be built to configure games - * prior to starting them. Derived classes would extend the base - * configurator adding interface elements and wiring them up properly to - * allow the user to configure an instance of their game. - * - *

Clients that use the game configurator will want to instantiate one - * based on the class returned from the {@link GameConfig} and then - * initialize it with a call to {@link #init}. - */ -public abstract class SwingGameConfigurator extends GameConfigurator -{ - /** - * Get the Swing JPanel that contains the UI elements for this configurator. - */ - public JPanel getPanel () - { - return _panel; - } - - /** - * Add a control to the interface. This should be the standard way - * that configurator controls are added, but note also that external - * entities may add their own controls that are related to the game, - * but do not directly alter the game config, so that all the controls - * are added in a uniform manner and are well aligned. - */ - public void addControl (JComponent label, JComponent control) - { - // Set up the constraints. There's really no point in saving - // these somewhere, as they're cloned anyway with every component - // insertion. - GridBagConstraints lc = new GridBagConstraints(); - lc.gridx = 0; - lc.anchor = GridBagConstraints.NORTHWEST; - lc.insets = _labelInsets; - - GridBagConstraints cc = new GridBagConstraints(); - cc.gridx = 1; - cc.anchor = GridBagConstraints.NORTHWEST; - cc.insets = _controlInsets; - cc.gridwidth = GridBagConstraints.REMAINDER; - - // add the components - _panel.add(label, lc); - _panel.add(control, cc); - } - - /** The panel on which the config options are placed. */ - protected JPanel _panel = new JPanel(new GridBagLayout()); - - /** Insets for configuration labels. */ - protected Insets _labelInsets = new Insets(1, 0, 1, 4); - - /** Insets for configuration controls. */ - protected Insets _controlInsets = new Insets(1, 4, 1, 0); -} diff --git a/src/java/com/threerings/parlor/game/data/GameAI.java b/src/java/com/threerings/parlor/game/data/GameAI.java deleted file mode 100644 index 5d61897b6..000000000 --- a/src/java/com/threerings/parlor/game/data/GameAI.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// $Id$ - -package com.threerings.parlor.game.data; - -import com.threerings.io.SimpleStreamableObject; - -/** - * Represents attributes of an AI player. - */ -public class GameAI extends SimpleStreamableObject -{ - /** The "personality" of the AI, which can be interpreted by - * each puzzle. */ - public int personality; - - /** The skill level of the AI. */ - public int skill; - - /** A blank constructor for serialization. */ - public GameAI () - { - } - - /** - * Constructs an AI with the specified (game-interpreted) skill and - * personality. - */ - public GameAI (int personality, int skill) - { - this.personality = personality; - this.skill = skill; - } -} diff --git a/src/java/com/threerings/parlor/game/data/GameCodes.java b/src/java/com/threerings/parlor/game/data/GameCodes.java deleted file mode 100644 index e137455e9..000000000 --- a/src/java/com/threerings/parlor/game/data/GameCodes.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $Id: PuzzleCodes.java 3184 2004-10-28 19:20:27Z 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.parlor.game.data; - -import com.threerings.presents.data.InvocationCodes; - -/** - * Constants relating to the game services. - */ -public interface GameCodes extends InvocationCodes -{ - /** The message bundle identifier for general game messages. */ - public static final String GAME_MESSAGE_BUNDLE = "game.general"; - - /** The name of the message event to a placeObject that a player - * was knocked out of a puzzle. */ - public static final String PLAYER_KNOCKED_OUT = "playerKnocked"; - - /** The name of the message event to a placeObject that reports - * the winners and losers of a game. */ - public static final String WINNERS_AND_LOSERS = "winnersAndLosers"; - - /** A chat type for chatting on the game object. */ - public static final String GAME_CHAT_TYPE = "gameChat"; -} diff --git a/src/java/com/threerings/parlor/game/data/GameConfig.java b/src/java/com/threerings/parlor/game/data/GameConfig.java deleted file mode 100644 index cbcf52437..000000000 --- a/src/java/com/threerings/parlor/game/data/GameConfig.java +++ /dev/null @@ -1,152 +0,0 @@ -// -// $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.parlor.game.data; - -import java.util.ArrayList; -import java.util.List; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.util.Name; - -import com.threerings.parlor.client.TableConfigurator; -import com.threerings.parlor.game.client.GameConfigurator; - -/** - * The game config class encapsulates the configuration information for a - * particular type of game. The hierarchy of game config objects mimics the - * hierarchy of game managers and controllers. Both the game manager and game - * controller are provided with the game config object when the game is - * created. - * - *

The game config object is also the mechanism used to instantiate the - * appropriate game manager and controller. Every game must have an associated - * game config derived class that overrides {@link #createController} and - * {@link #getManagerClassName}, returning the appropriate game controller and - * manager class for that game. Thus the entire chain of events that causes a - * particular game to be created is the construction of the appropriate game - * config instance which is provided to the server as part of an invitation or - * via some other matchmaking mechanism. - */ -public abstract class GameConfig extends PlaceConfig implements Cloneable -{ - /** The usernames of the players involved in this game, or an empty - * array if such information is not needed by this particular game. */ - public Name[] players = new Name[0]; - - /** Indicates whether or not this game is rated. */ - public boolean rated = true; - - /** Configurations for AIs to be used in this game. Slots with real - * players should be null and slots with AIs should contain - * configuration for those AIs. A null array indicates no use of AIs - * at all. */ - public GameAI[] ais = new GameAI[0]; - - /** - * Returns the message bundle identifier for the bundle that should be - * used to translate the translatable strings used to describe the - * game config parameters. - */ - public abstract String getBundleName (); - - /** - * Creates a configurator that can be used to create a user interface - * for configuring this instance prior to starting the game. If no - * configuration is necessary, this method should return null. - */ - public abstract GameConfigurator createConfigurator (); - - /** - * Creates a table configurator for initializing 'table' properties - * of the game. The default implementation returns null. - */ - public TableConfigurator createTableConfigurator () - { - return null; - } - - /** - * Returns a translatable label describing this game. - */ - public String getGameName () - { - // the whole getRatingTypeId(), getGameName(), getBundleName() - // business should be cleaned up. we should have getGameIdent() - // and everything should have a default implementation using that - return "m." + getBundleName(); - } - - /** - * Returns the game rating type, if the system uses such things. - */ - public byte getRatingTypeId () - { - return (byte)-1; - } - - /** - * Returns a List of strings that describe the configuration of this - * game. Default implementation returns an empty list. - */ - public List getDescription () - { - return new ArrayList(); // nothing by default - } - - /** - * Returns true if this game config object is equal to the supplied - * object (meaning it is also a game config object and its - * configuration settings are the same as ours). - */ - public boolean equals (Object other) - { - // make sure they're of the same class - if (other.getClass() == this.getClass()) { - GameConfig that = (GameConfig) other; - return this.rated == that.rated; - - } else { - return false; - } - } - - /** - * Computes a hashcode for this game config object that supports our - * {@link #equals} implementation. Objects that are equal should have - * the same hashcode. - */ - public int hashCode () - { - // look ma, it's so sophisticated! - return getClass().hashCode() + (rated ? 1 : 0); - } - - // documentation inherited - public Object clone () - { - try { - return super.clone(); - } catch (CloneNotSupportedException cnse) { - throw new RuntimeException("clone() failed: " + cnse); - } - } -} diff --git a/src/java/com/threerings/parlor/game/data/GameMarshaller.java b/src/java/com/threerings/parlor/game/data/GameMarshaller.java deleted file mode 100644 index f4ebb76be..000000000 --- a/src/java/com/threerings/parlor/game/data/GameMarshaller.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.parlor.game.data; - -import com.threerings.parlor.game.client.GameService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; - -/** - * Provides the implementation of the {@link GameService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class GameMarshaller extends InvocationMarshaller - implements GameService -{ - /** The method id used to dispatch {@link #playerReady} requests. */ - public static final int PLAYER_READY = 1; - - // documentation inherited from interface - public void playerReady (Client arg1) - { - sendRequest(arg1, PLAYER_READY, new Object[] { - - }); - } - -} diff --git a/src/java/com/threerings/parlor/game/data/GameObject.java b/src/java/com/threerings/parlor/game/data/GameObject.java deleted file mode 100644 index ec4096c1a..000000000 --- a/src/java/com/threerings/parlor/game/data/GameObject.java +++ /dev/null @@ -1,448 +0,0 @@ -// -// $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.parlor.game.data; - -import com.samskivert.util.ListUtil; -import com.samskivert.util.StringUtil; -import com.threerings.util.Name; - -import com.threerings.crowd.data.PlaceObject; - -/** - * A game object hosts the shared data associated with a game played by - * one or more players. The game object extends the place object so that - * the game can act as a place where players actually go when playing the - * game. Only very basic information is maintained in the base game - * object. It serves as the base for a hierarchy of game object - * derivatives that handle basic gameplay for a suite of different game - * types (ie. turn based games, party games, board games, card games, - * etc.). - */ -public class GameObject extends PlaceObject -{ - // AUTO-GENERATED: FIELDS START - /** The field name of the gameService field. */ - public static final String GAME_SERVICE = "gameService"; - - /** The field name of the state field. */ - public static final String STATE = "state"; - - /** The field name of the isRated field. */ - public static final String IS_RATED = "isRated"; - - /** The field name of the isPrivate field. */ - public static final String IS_PRIVATE = "isPrivate"; - - /** The field name of the players field. */ - public static final String PLAYERS = "players"; - - /** The field name of the winners field. */ - public static final String WINNERS = "winners"; - - /** The field name of the roundId field. */ - public static final String ROUND_ID = "roundId"; - - /** The field name of the playerStatus field. */ - public static final String PLAYER_STATUS = "playerStatus"; - // AUTO-GENERATED: FIELDS END - - /** A game state constant indicating that the game has not yet started - * and is still awaiting the arrival of all of the players. */ - public static final int PRE_GAME = 0; - - /** A game state constant indicating that the game is in play. */ - public static final int IN_PLAY = 1; - - /** A game state constant indicating that the game ended normally. */ - public static final int GAME_OVER = 2; - - /** A game state constant indicating that the game was cancelled. */ - public static final int CANCELLED = 3; - - /** The player status constant for a player whose game is in play. */ - public static final int PLAYER_IN_PLAY = 0; - - /** The player status constant for a player whose has been knocked out - * of the game. NOTE: This can include a player choosing to leave a - * game prematurely. */ - public static final int PLAYER_LEFT_GAME = 1; - - /** Provides general game invocation services. */ - public GameMarshaller gameService; - - /** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY}, - * {@link #GAME_OVER}, or {@link #CANCELLED}. */ - public int state = PRE_GAME; - - /** Indicates whether or not this game is rated. */ - public boolean isRated; - - /** Indicates whether the game is "private". */ - public boolean isPrivate; - - /** The usernames of the players involved in this game. */ - public Name[] players; - - /** Whether each player in the game is a winner, or null - * if the game is not yet over. */ - public boolean[] winners; - - /** The unique round identifier for the current round. */ - public int roundId; - - /** If null, indicates that all present players are active, or for - * more complex games can be non-null to indicate the current status - * of each player in the game. The status value is one of - * {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}. */ - public int[] playerStatus; - - /** - * Returns the number of players in the game. - */ - public int getPlayerCount () - { - int count = 0; - int size = players.length; - for (int ii = 0; ii < size; ii++) { - if (players[ii] != null) { - count++; - } - } - return count; - } - - /** - * Returns the number of active players in the game. - */ - public int getActivePlayerCount () - { - int count = 0; - int size = players.length; - for (int ii = 0; ii < size; ii++) { - if (isActivePlayer(ii)) { - count++; - } - } - return count; - } - - /** - * Returns whether the given player is still an active player in - * the game. (Ie. whether or not they are still participating.) - */ - public boolean isActivePlayer (int pidx) - { - return isOccupiedPlayer(pidx) && - (playerStatus == null || isActivePlayerStatus(playerStatus[pidx])); - } - - - /** - * Returns the player index of the given user in the game, or - * -1 if the player is not involved in the game. - */ - public int getPlayerIndex (Name username) - { - int size = (players == null) ? 0 : players.length; - for (int ii = 0; ii < size; ii++) { - if (players[ii] != null && players[ii].equals(username)) { - return ii; - } - } - return -1; - } - - /** - * Returns whether the game is in play. A game that is not in play - * could either be awaiting players, ended, or cancelled. - */ - public boolean isInPlay () - { - return (state == IN_PLAY); - } - - /** - * Returns whether the given player index in the game is occupied. - */ - public boolean isOccupiedPlayer (int pidx) - { - return (pidx >= 0 && pidx < players.length) && (players[pidx] != null); - } - - /** - * Returns whether the given player index is a winner, or false if the - * winners are not yet assigned. - */ - public boolean isWinner (int pidx) - { - return (winners == null) ? false : winners[pidx]; - } - - /** - * Returns the number of winners for this game, or 0 if - * the winners array is not populated, e.g., the game is not yet over. - */ - public int getWinnerCount () - { - int count = 0; - int size = (winners == null) ? 0 : winners.length; - for (int ii = 0; ii < size; ii++) { - if (winners[ii]) { - count++; - } - } - return count; - } - - /** - * Returns true if the game is ended in a draw. - */ - public boolean isDraw () - { - return getWinnerCount() == getPlayerCount(); - } - - /** - * Returns the winner index of the first winning player for this game, - * or -1 if there are no winners or the winners array is - * not yet assigned. This is only likely to be useful for games that - * are known to have a single winner. - */ - public int getWinnerIndex () - { - int size = (winners == null) ? 0 : winners.length; - for (int ii = 0; ii < size; ii++) { - if (winners[ii]) { - return ii; - } - } - return -1; - } - - /** - * Returns the type of party game being played or NOT_PARTY_GAME. - * {@link PartyGameConfig}. - */ - public byte getPartyGameType () - { - return PartyGameConfig.NOT_PARTY_GAME; - } - - /** - * Used by {@link #isActivePlayer} to determine if the supplied status is - * associated with an active player (one that has not resigned from the - * game and/or left the game room). - */ - protected boolean isActivePlayerStatus (int playerStatus) - { - return playerStatus == PLAYER_IN_PLAY; - } - - // documentation inherited - protected void which (StringBuilder buf) - { - super.which(buf); - StringUtil.toString(buf, players); - buf.append(":").append(state); - } - - // AUTO-GENERATED: METHODS START - /** - * Requests that the gameService field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setGameService (GameMarshaller value) - { - GameMarshaller ovalue = this.gameService; - requestAttributeChange( - GAME_SERVICE, value, ovalue); - this.gameService = value; - } - - /** - * Requests that the state field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setState (int value) - { - int ovalue = this.state; - requestAttributeChange( - STATE, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.state = value; - } - - /** - * Requests that the isRated field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setIsRated (boolean value) - { - boolean ovalue = this.isRated; - requestAttributeChange( - IS_RATED, Boolean.valueOf(value), Boolean.valueOf(ovalue)); - this.isRated = value; - } - - /** - * Requests that the isPrivate field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setIsPrivate (boolean value) - { - boolean ovalue = this.isPrivate; - requestAttributeChange( - IS_PRIVATE, Boolean.valueOf(value), Boolean.valueOf(ovalue)); - this.isPrivate = value; - } - - /** - * Requests that the players field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setPlayers (Name[] value) - { - Name[] ovalue = this.players; - requestAttributeChange( - PLAYERS, value, ovalue); - this.players = (value == null) ? null : (Name[])value.clone(); - } - - /** - * Requests that the indexth element of - * players field be set to the specified value. - * The local value will be updated immediately and an event will be - * propagated through the system to notify all listeners that the - * attribute did change. Proxied copies of this object (on clients) - * will apply the value change when they received the attribute - * changed notification. - */ - public void setPlayersAt (Name value, int index) - { - Name ovalue = this.players[index]; - requestElementUpdate( - PLAYERS, index, value, ovalue); - this.players[index] = value; - } - - /** - * Requests that the winners field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setWinners (boolean[] value) - { - boolean[] ovalue = this.winners; - requestAttributeChange( - WINNERS, value, ovalue); - this.winners = (value == null) ? null : (boolean[])value.clone(); - } - - /** - * Requests that the indexth element of - * winners field be set to the specified value. - * The local value will be updated immediately and an event will be - * propagated through the system to notify all listeners that the - * attribute did change. Proxied copies of this object (on clients) - * will apply the value change when they received the attribute - * changed notification. - */ - public void setWinnersAt (boolean value, int index) - { - boolean ovalue = this.winners[index]; - requestElementUpdate( - WINNERS, index, Boolean.valueOf(value), Boolean.valueOf(ovalue)); - this.winners[index] = value; - } - - /** - * Requests that the roundId field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setRoundId (int value) - { - int ovalue = this.roundId; - requestAttributeChange( - ROUND_ID, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.roundId = value; - } - - /** - * Requests that the playerStatus field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setPlayerStatus (int[] value) - { - int[] ovalue = this.playerStatus; - requestAttributeChange( - PLAYER_STATUS, value, ovalue); - this.playerStatus = (value == null) ? null : (int[])value.clone(); - } - - /** - * Requests that the indexth element of - * playerStatus field be set to the specified value. - * The local value will be updated immediately and an event will be - * propagated through the system to notify all listeners that the - * attribute did change. Proxied copies of this object (on clients) - * will apply the value change when they received the attribute - * changed notification. - */ - public void setPlayerStatusAt (int value, int index) - { - int ovalue = this.playerStatus[index]; - requestElementUpdate( - PLAYER_STATUS, index, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.playerStatus[index] = value; - } - // AUTO-GENERATED: METHODS END -} diff --git a/src/java/com/threerings/parlor/game/data/PartyGameConfig.java b/src/java/com/threerings/parlor/game/data/PartyGameConfig.java deleted file mode 100644 index 10debf328..000000000 --- a/src/java/com/threerings/parlor/game/data/PartyGameConfig.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $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.parlor.game.data; - -/** - * Provides additional information for party games. - * A party game is a game in which the players are not set prior to starting, - * but players can come and go at will during the normal progression of - * the game. - */ -public interface PartyGameConfig -{ - /** Party game constant indicating that this game, while it does - * implement PartyGameConfig, is not currently being played in party - * mode. */ - public static final byte NOT_PARTY_GAME = 0; - - /** Party game constant indicating that we're in a party game in which - * players must sit at an available seat to play, otherwise they're - * an observer. */ - public static final byte SEATED_PARTY_GAME = 1; - - /** Party game constant indicating that everyone in the game place is - * a "player", meaning that they do not need to claim a seat to play. */ - public static final byte FREE_FOR_ALL_PARTY_GAME = 2; - - /** - * Get the type of party game being played. - */ - public byte getPartyGameType (); -} diff --git a/src/java/com/threerings/parlor/game/server/AIGameTicker.java b/src/java/com/threerings/parlor/game/server/AIGameTicker.java deleted file mode 100644 index 4410779f9..000000000 --- a/src/java/com/threerings/parlor/game/server/AIGameTicker.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $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.parlor.game.server; - -import java.util.Iterator; -import java.util.HashSet; - -import com.samskivert.util.Interval; - -import com.threerings.crowd.server.CrowdServer; - -/** - * Handles ticking all the GameManagers that are hosting games with AIs. - */ -public class AIGameTicker extends Interval -{ - /** The frequency with which we dispatch AI game ticks. */ - public static final long TICK_FREQUENCY = 3333L; // every 3 1/3 seconds - - /** - * Register the specified GameManager to receive AI ticks. - */ - public static synchronized void registerAIGame (GameManager mgr) - { - if (_ticker == null) { - _ticker = new AIGameTicker(); - } - _ticker.addAIGame(mgr); - } - - /** - * Take the specified GameManager off the AI tick list. - */ - public static synchronized void unregisterAIGame (GameManager mgr) - { - if (_ticker != null) { - _ticker.removeAIGame(mgr); - } - } - - /** - * Construct an AIGameTicker and start it ticking. - */ - private AIGameTicker () - { - super(CrowdServer.omgr); - _games = new HashSet(); - - schedule(TICK_FREQUENCY, true); - } - - /** - * Add the specified manager to the list of those receiving AI ticks. - */ - protected void addAIGame (GameManager mgr) - { - _games.add(mgr); - } - - /** - * Remove the specified manager from receiving AI ticks. - */ - protected void removeAIGame (GameManager mgr) - { - _games.remove(mgr); - - // if there aren't any AIs, let's stop running - if (_games.isEmpty()) { - cancel(); - _ticker = null; - } - } - - /** - * Tick all the game AIs while on the dobj thread. - */ - public void expired () - { - Iterator iter = _games.iterator(); - while (iter.hasNext()) { - ((GameManager) iter.next()).tickAIs(); - } - } - - /** Our set of ai games. */ - protected HashSet _games; - - /** Our single ticker for all AI games. */ - protected static AIGameTicker _ticker; -} diff --git a/src/java/com/threerings/parlor/game/server/GameDispatcher.java b/src/java/com/threerings/parlor/game/server/GameDispatcher.java deleted file mode 100644 index c2bdd4053..000000000 --- a/src/java/com/threerings/parlor/game/server/GameDispatcher.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// $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.parlor.game.server; - -import com.threerings.parlor.game.client.GameService; -import com.threerings.parlor.game.data.GameMarshaller; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; - -/** - * Dispatches requests to the {@link GameProvider}. - */ -public class GameDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public GameDispatcher (GameProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new GameMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case GameMarshaller.PLAYER_READY: - ((GameProvider)provider).playerReady( - source - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/parlor/game/server/GameManager.java b/src/java/com/threerings/parlor/game/server/GameManager.java deleted file mode 100644 index bb0fc74db..000000000 --- a/src/java/com/threerings/parlor/game/server/GameManager.java +++ /dev/null @@ -1,1329 +0,0 @@ -// -// $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.parlor.game.server; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; - -import com.samskivert.util.ArrayIntSet; -import com.samskivert.util.IntListUtil; -import com.samskivert.util.Interval; -import com.samskivert.util.RepeatCallTracker; -import com.samskivert.util.StringUtil; -import com.samskivert.util.Tuple; -import com.threerings.util.Name; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.DObject; - -import com.threerings.crowd.chat.server.SpeakProvider; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.CrowdServer; -import com.threerings.crowd.server.PlaceManager; -import com.threerings.crowd.server.PlaceManagerDelegate; - -import com.threerings.parlor.Log; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameAI; -import com.threerings.parlor.game.data.GameCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.data.GameMarshaller; -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.game.data.PartyGameConfig; -import com.threerings.parlor.server.ParlorSender; - -import com.threerings.util.MessageBundle; - -/** - * The game manager handles the server side management of a game. It - * manipulates the game state in accordance with the logic of the game - * flow and generally manages the whole game playing process. - * - *

The game manager extends the place manager because games are - * implicitly played in a location, the players of the game implicitly - * bodies in that location. - */ -public class GameManager extends PlaceManager - implements ParlorCodes, GameCodes, GameProvider, AttributeChangeListener -{ - // documentation inherited - protected void didInit () - { - super.didInit(); - - // save off a casted reference to our config - _gameconfig = (GameConfig)_config; - - // register this game manager - _managers.add(this); - - // and start up a tick interval if we've not already got one - if (_tickInterval == null) { - _tickInterval = new Interval(CrowdServer.omgr) { - public void expired () { - tickAllGames(); - } - }; - _tickInterval.schedule(TICK_DELAY, true); - } - - // configure our AIs - for (int ii = 0; ii < _gameconfig.ais.length; ii++) { - if (_gameconfig.ais[ii] != null) { - setAI(ii, _gameconfig.ais[ii]); - } - } - } - - /** - * Returns the configuration object for the game being managed by this - * manager. - */ - public GameConfig getGameConfig () - { - return _gameconfig; - } - - /** - * Used to determine if this game is a party game. - */ - public boolean isPartyGame () - { - return (_gameconfig instanceof PartyGameConfig) && - (((PartyGameConfig)_gameconfig).getPartyGameType() != - PartyGameConfig.NOT_PARTY_GAME); - } - - /** - * Adds the given player to the game at the first available player - * index. This should only be called before the game is started, and - * is most likely to be used to add players to party games. - * - * @param player the username of the player to add to this game. - * @return the player index at which the player was added, or - * -1 if the player could not be added to the game. - */ - public int addPlayer (Name player) - { - // determine the first available player index - int pidx = -1; - for (int ii = 0; ii < getPlayerSlots(); ii++) { - if (!_gameobj.isOccupiedPlayer(ii)) { - pidx = ii; - break; - } - } - - // sanity-check the player index - if (pidx == -1) { - Log.warning("Couldn't find free player index for player " + - "[game=" + _gameobj.which() + ", player=" + player + - ", players=" + StringUtil.toString(_gameobj.players) + - "]."); - return -1; - } - - // proceed with the rest of the adding business - return (!addPlayerAt(player, pidx)) ? -1 : pidx; - } - - /** - * Adds the given player to the game at the specified player index. - * This should only be called before the game is started, and is most - * likely to be used to add players to party games. - * - * @param player the username of the player to add to this game. - * @param pidx the player index at which the player is to be added. - * @return true if the player was added successfully, false if not. - */ - public boolean addPlayerAt (Name player, int pidx) - { - // make sure the specified player index is valid - if (pidx < 0 || pidx >= getPlayerSlots()) { - Log.warning("Attempt to add player at an invalid index " + - "[game=" + _gameobj.which() + ", player=" + player + - ", pidx=" + pidx + "]."); - return false; - } - - // make sure the player index is available - if (_gameobj.players[pidx] != null) { - Log.warning("Attempt to add player at occupied index " + - "[game=" + _gameobj.which() + ", player=" + player + - ", pidx=" + pidx + "]."); - return false; - } - - // make sure the player isn't already somehow a part of the game - // to avoid any potential badness that might ensue if we added - // them more than once - if (_gameobj.getPlayerIndex(player) != -1) { - Log.warning("Attempt to add player to game that they're already " + - "playing [game=" + _gameobj.which() + - ", player=" + player + "]."); - return false; - } - - // get the player's body object - BodyObject bobj = CrowdServer.lookupBody(player); - if (bobj == null) { - Log.warning("Unable to get body object while adding player " + - "[game=" + _gameobj.which() + - ", player=" + player + "]."); - return false; - } - - // fill in the player's information - _gameobj.setPlayersAt(player, pidx); - - // increment the number of players in the game - _playerCount++; - - // save off their oid - _playerOids[pidx] = bobj.getOid(); - - // let derived classes do what they like - playerWasAdded(player, pidx); - - return true; - } - - /** - * Called when a player was added to the game. Derived classes may - * override this method to perform any game-specific actions they - * desire, but should be sure to call - * super.playerWasAdded(). - * - * @param player the username of the player added to the game. - * @param pidx the player index of the player added to the game. - */ - protected void playerWasAdded (Name player, int pidx) - { - } - - /** - * Removes the given player from the game. This is most likely to be - * used to allow players involved in a party game to leave the game - * early-on if they realize they'd rather not play for some reason. - * - * @param player the username of the player to remove from this game. - * @return true if the player was successfully removed, false if not. - */ - public boolean removePlayer (Name player) - { - // get the player's index in the player list - int pidx = _gameobj.getPlayerIndex(player); - - // sanity-check the player index - if (pidx == -1) { - Log.warning("Attempt to remove non-player from players list " + - "[game=" + _gameobj.which() + - ", player=" + player + - ", players=" + StringUtil.toString(_gameobj.players) + - "]."); - return false; - } - - // remove the player from the players list - _gameobj.setPlayersAt(null, pidx); - - // clear out the player's entry in the player oid list - _playerOids[pidx] = 0; - - if (_AIs != null) { - // clear out the player's entry in the AI list - _AIs[pidx] = null; - } - - // decrement the number of players in the game - _playerCount--; - - // let derived classes do what they like - playerWasRemoved(player, pidx); - - return true; - } - - /** - * Called when a player was removed from the game. Derived classes - * may override this method to perform any game-specific actions they - * desire, but should be sure to call - * super.playerWasRemoved(). - * - * @param player the username of the player removed from the game. - * @param pidx the player index of the player before they were removed - * from the game. - */ - protected void playerWasRemoved (Name player, int pidx) - { - } - - /** - * Replaces the player at the specified index and calls {@link - * #playerWasReplaced} to let derived classes and delegates know - * what's going on. - */ - public void replacePlayer (final int pidx, final Name player) - { - final Name oplayer = _gameobj.players[pidx]; - _gameobj.setPlayersAt(player, pidx); - - // allow derived classes to respond - playerWasReplaced(pidx, oplayer, player); - - // notify our delegates - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).playerWasReplaced( - pidx, oplayer, player); - } - }); - } - - /** - * Called when a player has been replaced via a call to {@link - * #replacePlayer}. - */ - protected void playerWasReplaced (int pidx, Name oldPlayer, Name newPlayer) - { - } - - /** - * Returns the user object for the player with the specified index or - * null if the player at that index is not online. - */ - public BodyObject getPlayer (int playerIdx) - { - // if we have their oid, use that - int ploid = _playerOids[playerIdx]; - if (ploid > 0) { - return (BodyObject)CrowdServer.omgr.getObject(ploid); - } - // otherwise look them up by name - Name name = getPlayerName(playerIdx); - return (name == null) ? null : CrowdServer.lookupBody(name); - } - - /** - * Sets the specified player as an AI with the specified - * configuration. It is assumed that this will be set soon after the - * player names for all AIs present in the game. (It should be done - * before human players start trickling into the game.) - * - * @param pidx the player index of the AI. - * @param ai the AI configuration. - */ - public void setAI (final int pidx, final GameAI ai) - { - if (_AIs == null) { - // create and initialize the AI configuration array - _AIs = new GameAI[getPlayerSlots()]; - // set up a delegate op for AI ticking - _tickAIOp = new TickAIDelegateOp(); - } - - // save off the AI's configuration - _AIs[pidx] = ai; - - // let the delegates know that the player's been made an AI - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).setAI(pidx, ai); - } - }); - } - - /** - * Returns the name of the player with the specified index or null if - * no player exists at that index. - */ - public Name getPlayerName (int index) - { - return (_gameobj == null) ? null : _gameobj.players[index]; - } - - /** - * Returns the player index of the given user in the game, or - * -1 if the player is not involved in the game. - */ - public int getPlayerIndex (Name username) - { - return (_gameobj == null) ? -1 : _gameobj.getPlayerIndex(username); - } - - /** - * Returns the user object oid of the player with the specified index. - */ - public int getPlayerOid (int index) - { - return (_playerOids == null) ? -1 : _playerOids[index]; - } - - /** - * Returns the number of players in the game. - */ - public int getPlayerCount () - { - return _playerCount; - } - - /** - * Returns the number of players allowed in this game. - */ - public int getPlayerSlots () - { - return _gameconfig.players.length; - } - - /** - * Returns whether the player at the specified player index is an AI. - */ - public boolean isAI (int pidx) - { - return (_AIs != null && _AIs[pidx] != null); - } - - /** - * Returns whether the player at the specified player index is actively - * playing the game - */ - public boolean isActivePlayer (int pidx) - { - return _gameobj.isActivePlayer(pidx) && - (getPlayerOid(pidx) > 0 || isAI(pidx)); - } - - /** - * Returns the unique round identifier for the current round. - */ - public int getRoundId () - { - return _gameobj.roundId; - } - - /** - * Sends a system message to the players in the game room. - */ - public void systemMessage (String msgbundle, String msg) - { - systemMessage(msgbundle, msg, false); - } - - /** - * Sends a system message to the players in the game room. - * - * @param waitForStart if true, the message will not be sent until the - * game has started. - */ - public void systemMessage ( - String msgbundle, String msg, boolean waitForStart) - { - if (waitForStart && - ((_gameobj == null) || (_gameobj.state == GameObject.PRE_GAME))) { - // queue up the message. - if (_startmsgs == null) { - _startmsgs = new ArrayList>(); - } - _startmsgs.add(new Tuple(msgbundle, msg)); - return; - } - - // otherwise, just deliver the message - SpeakProvider.sendInfo(_gameobj, msgbundle, msg); - } - - /** - * Report to the knocked-out player's room that they were knocked out. - */ - protected void reportPlayerKnockedOut (int pidx) - { - BodyObject user = getPlayer(pidx); - if (user == null) { - // body object can be null for ai players - return; - } - - DObject place = CrowdServer.omgr.getObject(user.location); - if (place != null) { - place.postMessage(PLAYER_KNOCKED_OUT, - new Object[] { new int[] { user.getOid() } }); - } - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return GameObject.class; - } - - // documentation inherited - protected void didStartup () - { - // obtain a casted reference to our game object - _gameobj = (GameObject)_plobj; - - // stick the players into the game object - _gameobj.setPlayers(_gameconfig.players); - - // set up an initial player status array - _gameobj.setPlayerStatus(new int[getPlayerSlots()]); - - // save off the number of players so that we needn't repeatedly - // iterate through the player name array server-side unnecessarily - _playerCount = _gameobj.getPlayerCount(); - - // instantiate a player oid array which we'll fill in later - _playerOids = new int[getPlayerSlots()]; - - // create and fill in our game service object - GameMarshaller service = (GameMarshaller) - _invmgr.registerDispatcher(new GameDispatcher(this), false); - _gameobj.setGameService(service); - - // give delegates a chance to do their thing - super.didStartup(); - - // let the players of this game know that we're ready to roll (if - // we have a specific set of players) - for (int ii = 0; ii < getPlayerSlots(); ii++) { - // skip non-existent players and AIs - if (!_gameobj.isOccupiedPlayer(ii) || isAI(ii)) { - continue; - } - - BodyObject bobj = CrowdServer.lookupBody(_gameobj.players[ii]); - if (bobj == null) { - Log.warning("Unable to deliver game ready to non-existent " + - "player [game=" + _gameobj.which() + - ", player=" + _gameobj.players[ii] + "]."); - continue; - } - - // deliver a game ready notification to the player - ParlorSender.gameIsReady(bobj, _gameobj.getOid()); - } - - // start up a no-show timer if needed - if (needsNoShowTimer()) { - new Interval(CrowdServer.omgr) { - public void expired () { - checkForNoShows(); - } - }.schedule(NOSHOW_DELAY); - } - } - - /** - * Returns true if this game requires a no-show timer. The default - * implementation returns true for non-party games and false for party - * games. Derived classes may wish to change or augment this behavior. - */ - protected boolean needsNoShowTimer () - { - return !isPartyGame(); - } - - /** - * Derived classes that need their AIs to be ticked periodically - * should override this method and return true. Many AIs can act - * entirely in reaction to game state changes and need no periodic - * ticking which is why ticking is disabled by default. - * - * @see #tickAIs - */ - protected boolean needsAITick () - { - return false; - } - - // documentation inherited - protected void didShutdown () - { - super.didShutdown(); - - // unregister this game manager - _managers.remove(this); - - // remove the tick interval if there are no remaining managers - if (_managers.size() == 0) { - _tickInterval.cancel(); - _tickInterval = null; - } - - // clear out our service registration - _invmgr.clearDispatcher(_gameobj.gameService); - } - - // documentation inherited - protected void bodyLeft (int bodyOid) - { - // first resign the player from the game - int pidx = IntListUtil.indexOf(_playerOids, bodyOid); - if (pidx != -1 && _gameobj.isInPlay() && - _gameobj.isActivePlayer(pidx)) { - // end the player's game if they bail on an in-progress game - endPlayerGame(pidx); - } - - // then complete the bodyLeft() processing which may result in a call - // to placeBecameEmpty() which will shut the game down - super.bodyLeft(bodyOid); - } - - /** - * When a game room becomes empty, we cancel the game if it's still in - * progress and close down the game room. - */ - protected void placeBecameEmpty () - { -// Log.info("Game room empty. Going away. " + -// "[game=" + _gameobj.which() + "]."); - - // if we're in play then move to game over - if (_gameobj.state != GameObject.PRE_GAME && - _gameobj.state != GameObject.GAME_OVER && - _gameobj.state != GameObject.CANCELLED) { - _gameobj.setState(GameObject.GAME_OVER); - // and shutdown directly - shutdown(); - - // cancel the game; which will shut us down - } else if (!cancelGame()) { - // or shut down directly if the game is already over - shutdown(); - } - } - - /** - * Called when all players have arrived in the game room. By default, - * this starts up the game, but a manager may wish to override this - * and start the game according to different criterion. - */ - protected void playersAllHere () - { - // start up the game if we're not a party game and if we haven't - // already done so - if (!isPartyGame() && _gameobj.state == GameObject.PRE_GAME) { - startGame(); - } - } - - /** - * Called after the no-show delay has expired following the delivery - * of notifications to all players that the game is ready. - * Note: this is not called for party games. Those games have - * a human who decides when to start the game. - */ - protected void checkForNoShows () - { - // nothing to worry about if we're already started - if (_gameobj.state != GameObject.PRE_GAME) { - return; - } - - // if there's no one in the room, go ahead and clear it out - if (_plobj.occupants.size() == 0) { - Log.info("Cancelling total no-show " + - "[game=" + _gameobj.which() + - ", players=" + StringUtil.toString(_gameobj.players) + - ", poids=" + StringUtil.toString(_playerOids) + "]."); - placeBecameEmpty(); - - } else { - // do the right thing if we have any no-show players - for (int ii = 0; ii < getPlayerSlots(); ii++) { - if (!playerIsReady(ii)) { - handlePartialNoShow(); - return; - } - } - } - } - - /** - * This is called when some, but not all, players failed to show up - * for a game. The default implementation simply cancels the game. - */ - protected void handlePartialNoShow () - { - // mark the no-show players; this will cause allPlayersReady() to - // think that everyone has arrived, but still allow us to tell who - // has not shown up in gameDidStart() - int humansHere = 0; - for (int ii = 0; ii < _playerOids.length; ii++) { - if (_playerOids[ii] == 0) { - _playerOids[ii] = -1; - } else if (!isAI(ii)) { - humansHere++; - } - } - - if ((humansHere == 0) && !startWithoutHumans()) { - // if there are no human players in the game, just cancel it - Log.info("Canceling no-show game [game=" + _gameobj.which() + - ", players=" + StringUtil.toString(_playerOids) + "]."); - cancelGame(); - - } else { - // go ahead and report that everyone is ready (which will start the - // game); gameDidStart() will take care of giving the boot to - // anyone who isn't around - Log.info("Forcing start of partial no-show game " + - "[game=" + _gameobj.which() + - ", poids=" + StringUtil.toString(_playerOids) + "]."); - playersAllHere(); - } - } - - /** - * This is called when the game is ready to start (all players - * involved have delivered their "am ready" notifications). It calls - * {@link #gameWillStart}, sets the necessary wheels in motion and - * then calls {@link #gameDidStart}. Derived classes should override - * one or both of the calldown functions (rather than this function) - * if they need to do things before or after the game starts. - * - * @return true if the game was started, false if it could not be - * started because it was already in play or because all players have - * not yet reported in. - */ - public boolean startGame () - { - // complain if we're already started - if (_gameobj.state == GameObject.IN_PLAY) { - Log.warning("Requested to start an already in-play game " + - "[game=" + _gameobj.which() + "]."); - Thread.dumpStack(); - return false; - } - - // TEMP: clear out our game end tracker - _gameEndTracker.clear(); - - // make sure everyone has turned up - if (!allPlayersReady()) { - Log.warning("Requested to start a game that is still " + - "awaiting players [game=" + _gameobj.which() + - ", pnames=" + StringUtil.toString(_gameobj.players) + - ", poids=" + StringUtil.toString(_playerOids) + "]."); - return false; - } - - // if we're still waiting for a call to endGame() to propagate, - // queue up a runnable to start the game which will allow the - // endGame() to propagate before we start things up - if (_committedState == GameObject.IN_PLAY) { - Log.info("Postponing start of still-ending game " + - "[which=" + _gameobj.which() + "]."); - CrowdServer.omgr.postRunnable(new Runnable() { - public void run () { - startGame(); - } - }); - return true; - } - - // let the derived class do its pre-start stuff - gameWillStart(); - - // transition the game to started - _gameobj.setState(GameObject.IN_PLAY); - - // when our events are applied, we'll call gameDidStart() - return true; - } - - /** - * @return true if we should start the game even without any humans. - * Default implementation always returns false. - */ - protected boolean startWithoutHumans () - { - return false; - } - - /** - * Called when the game is about to start, but before the game start - * notification has been delivered to the players. Derived classes - * should override this if they need to perform some pre-start - * activities, but should be sure to call - * super.gameWillStart(). - */ - protected void gameWillStart () - { - // increment the round identifier - _gameobj.setRoundId(_gameobj.roundId + 1); - - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).gameWillStart(); - } - }); - } - - /** - * Called when the game state changes. This happens after the attribute - * change event has propagated. - * - * @param state the new game state. - * @param oldState the previous game state. - */ - protected void stateDidChange (int state, int oldState) - { - switch (state) { - case GameObject.IN_PLAY: - gameDidStart(); - break; - - case GameObject.GAME_OVER: - // we do some jiggery pokery to allow derived game objects to have - // different notions of what it means to be in play - _gameobj.state = oldState; - boolean wasInPlay = _gameobj.isInPlay(); - _gameobj.state = state; - - // now call gameDidEnd() only if the game was previously in play - if (wasInPlay) { - gameDidEnd(); - } - break; - - case GameObject.CANCELLED: - // let the manager do anything it cares to - gameWasCancelled(); - - // and shutdown if there's no one here - if (_plobj.occupants.size() == 0) { - shutdown(); - } - break; - } - } - - /** - * Called after the game start notification was dispatched. Derived - * classes can override this to put whatever wheels they might need - * into motion now that the game is started (if anything other than - * transitioning the game to {@link GameObject#IN_PLAY} is necessary), - * but should be sure to call super.gameDidStart(). - */ - protected void gameDidStart () - { - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).gameDidStart(); - } - }); - - // inform the players of any pending messages. - if (_startmsgs != null) { - for (Tuple mtup : _startmsgs) { - systemMessage(mtup.left, // bundle - mtup.right); // message - } - _startmsgs = null; - } - - // and register ourselves to receive AI ticks - if (_AIs != null && needsAITick()) { - AIGameTicker.registerAIGame(this); - } - - // any players who have not claimed that they are ready should now - // be given le boote royale - for (int ii = 0; ii < _playerOids.length; ii++) { - if (_playerOids[ii] == -1) { - Log.info("Booting no-show player [game=" + _gameobj.which() + - ", player=" + getPlayerName(ii) + "]."); - _playerOids[ii] = 0; // unfiddle the blank oid - endPlayerGame(ii); - } - } - } - - /** - * Called by the {@link AIGameTicker} if we're registered as an AI - * game. - */ - protected void tickAIs () - { - for (int ii = 0; ii < _AIs.length; ii++) { - if (_AIs[ii] != null) { - tickAI(ii, _AIs[ii]); - } - } - } - - /** - * Called by tickAIs to tick each AI in the game. - */ - protected void tickAI (int pidx, GameAI ai) - { - _tickAIOp.setAI(pidx, ai); - applyToDelegates(_tickAIOp); - } - - /** - * Ends the game for the given player. - */ - public void endPlayerGame (int pidx) - { - // go for a little transactional efficiency - _gameobj.startTransaction(); - try { - // end the player's game - if (_gameobj.playerStatus != null) { - _gameobj.setPlayerStatusAt(GameObject.PLAYER_LEFT_GAME, pidx); - } - - // let derived classes do some business - playerGameDidEnd(pidx); - - announcePlayerGameOver(pidx); - - } finally { - _gameobj.commitTransaction(); - } - - // if it's time to end the game, then do so - if (shouldEndGame()) { - endGame(); - } else { - // otherwise report that the player was knocked out to other - // people in his/her room - reportPlayerKnockedOut(pidx); - } - } - - /** - * Announce to everyone in the game that a player's game has ended. - */ - protected void announcePlayerGameOver (int pidx) - { - String message = MessageBundle.tcompose( - "m.player_game_over", getPlayerName(pidx)); - systemMessage(GAME_MESSAGE_BUNDLE, message); - } - - /** - * Called when a player has been marked as knocked out but before the - * knock-out status update has been sent to the players. Any status - * information that needs be updated in light of the knocked out - * player can be updated here. - */ - protected void playerGameDidEnd (int pidx) - { - } - - /** - * Called when a player leaves the game in order to determine whether - * the game should be ended based on its current state, which will - * include updated player status for the player in question. The - * default implementation returns true if the game is in play and - * there is only one player left. Derived classes may wish to - * override this method in order to customize the required end-game - * conditions. - */ - protected boolean shouldEndGame () - { - return (_gameobj.isInPlay() && _gameobj.getActivePlayerCount() == 1); - } - - /** - * Called when the game is known to be over. This will call some - * calldown functions to determine the winner of the game and then - * transition the game to the {@link GameObject#GAME_OVER} state. - */ - public void endGame () - { - // TEMP: debug pending rating repeat bug - if (_gameEndTracker.checkCall( - "Requested to end already ended game " + - "[game=" + _gameobj.which() + "].")) { - return; - } - // END TEMP - - if (!_gameobj.isInPlay()) { - Log.info("Refusing to end game that was not in play " + - "[game=" + _gameobj.which() + "]."); - return; - } - - _gameobj.startTransaction(); - try { - // let the derived class do its pre-end stuff - gameWillEnd(); - - // determine winners and set them in the game object - boolean[] winners = new boolean[getPlayerSlots()]; - assignWinners(winners); - _gameobj.setWinners(winners); - - // transition to the game over state - _gameobj.setState(GameObject.GAME_OVER); - - } finally { - _gameobj.commitTransaction(); - } - - // wait until we hear the game state transition on the game object - // to invoke our game over code so that we can be sure that any - // final events dispatched on the game object prior to the call to - // endGame() have been dispatched - } - - /** - * Sets the state of the game to {@link GameObject#CANCELLED}. - * - * @return true if the game was cancelled, false if it was already over or - * cancelled. - */ - public boolean cancelGame () - { - if (_gameobj.state != GameObject.GAME_OVER && - _gameobj.state != GameObject.CANCELLED) { - _gameobj.setState(GameObject.CANCELLED); - return true; - } - return false; - } - - /** - * Assigns the final winning status for each player to their respect - * player index in the supplied array. This will be called by {@link - * #endGame} when the game is over. The default implementation marks - * no players as winners. Derived classes should override this method - * in order to customize the winning conditions. - */ - protected void assignWinners (boolean[] winners) - { - Arrays.fill(winners, false); - } - - /** - * Returns whether game conclusion antics such as rating updates - * should be performed when an in-play game is ended. Derived classes - * may wish to override this method to customize the conditions under - * which the game is concluded. - */ - public boolean shouldConcludeGame () - { - return (_gameobj.state == GameObject.GAME_OVER); - } - - /** - * Called when the game is about to end, but before the game end - * notification has been delivered to the players. Derived classes - * should override this if they need to perform some pre-end - * activities, but should be sure to call - * super.gameWillEnd(). - */ - protected void gameWillEnd () - { - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).gameWillEnd(); - } - }); - } - - /** - * Called after the game has transitioned to the {@link - * GameObject#GAME_OVER} state. Derived classes should override this - * to perform any post-game activities, but should be sure to call - * super.gameDidEnd(). - */ - protected void gameDidEnd () - { - // remove ourselves from the AI ticker, if applicable - if (_AIs != null && needsAITick()) { - AIGameTicker.unregisterAIGame(this); - } - - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).gameDidEnd(); - } - }); - - // report the winners and losers if appropriate - int winnerCount = _gameobj.getWinnerCount(); - if (shouldConcludeGame() && winnerCount > 0 && !_gameobj.isDraw()) { - reportWinnersAndLosers(); - } - - // calculate ratings and all that... - } - - /** - * Called to let the manager know that the game was cancelled (and may be - * about to be shutdown if there's no one in the room). In the base - * framework a game will only be canceled if no one shows up, so {@link - * #gameWillStart}, etc. will never have been called and thus {@link - * #gameWillEnd}, etc. will not be called. However, if a game chooses to - * cancel itself for whatever reason, no effort will be made to call {@link - * #endGame} and the game ending call backs so that game can override this - * method to do anything it needs. Note that {@link #didShutdown} will be - * called in every case and that's generally the best place to free - * resources so this method may not be needed. - */ - protected void gameWasCancelled () - { - // nothing to do by default - } - - /** - * Report winner and loser oids to each room that any of the - * winners/losers is in. - */ - protected void reportWinnersAndLosers () - { - int numPlayers = _playerOids.length; - - // set up 3 sets that will not need internal expanding - ArrayIntSet winners = new ArrayIntSet(numPlayers); - ArrayIntSet losers = new ArrayIntSet(numPlayers); - ArrayIntSet places = new ArrayIntSet(numPlayers); - - for (int ii=0; ii < numPlayers; ii++) { - BodyObject user = getPlayer(ii); - if (user != null) { - places.add(user.location); - (_gameobj.isWinner(ii) ? winners : losers).add(user.getOid()); - } - } - - Object[] args = - new Object[] { winners.toIntArray(), losers.toIntArray() }; - - // now send a message event to each room - for (int ii=0, nn = places.size(); ii < nn; ii++) { - DObject place = CrowdServer.omgr.getObject(places.get(ii)); - if (place != null) { - place.postMessage(WINNERS_AND_LOSERS, args); - } - } - } - - /** - * Called when the game is to be reset to its starting state in - * preparation for a new game without actually ending the current - * game. It calls {@link #gameWillReset} followed by the standard game - * start processing ({@link #gameWillStart} and {@link - * #gameDidStart}). Derived classes should override these calldown - * functions (rather than this function) if they need to do things - * before or after the game resets. - */ - public void resetGame () - { - // let the derived class do its pre-reset stuff - gameWillReset(); - // do the standard game start processing - gameWillStart(); - // transition to in-play which will trigger a call to gameDidStart() - _gameobj.setState(GameObject.IN_PLAY); - } - - /** - * Called when the game is about to reset, but before the board has - * been re-initialized or any other clearing out of game data has - * taken place. Derived classes should override this if they need to - * perform some pre-reset activities. - */ - protected void gameWillReset () - { - // reinitialize the player status - _gameobj.setPlayerStatus(new int[getPlayerSlots()]); - - // let our delegates do their business - applyToDelegates(new DelegateOp() { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate)delegate).gameWillReset(); - } - }); - } - - // documentation inherited from interface - public void playerReady (ClientObject caller) - { - BodyObject plobj = (BodyObject)caller; - - // get the user's player index - int pidx = _gameobj.getPlayerIndex(plobj.getVisibleName()); - if (pidx == -1) { - // only complain if this is not a party game, since it's - // perfectly normal to receive a player ready notification - // from a user entering a party game in which they're not yet - // a participant - if (!isPartyGame()) { - Log.warning("Received playerReady() from non-player? " + - "[caller=" + caller + "]."); - } - return; - } - - // make a note of this player's oid - _playerOids[pidx] = plobj.getOid(); - - // if everyone is now ready to go, get things underway - if (allPlayersReady()) { - playersAllHere(); - } - } - - /** - * Returns true if all (non-AI) players have delivered their {@link - * #playerReady} notifications, false if they have not. - */ - public boolean allPlayersReady () - { - for (int ii = 0; ii < getPlayerSlots(); ii++) { - if (!playerIsReady(ii)) { - return false; - } - } - return true; - } - - /** - * Returns true if the player at the specified slot is ready (or if - * there is meant to be no player in that slot), false if there is - * meant to be a player in the specified slot and they have not yet - * reported that they are ready. - */ - public boolean playerIsReady (int pidx) - { - return (!_gameobj.isOccupiedPlayer(pidx) || // unoccupied slot - _playerOids[pidx] != 0 || // player is ready - isAI(pidx)); // player is AI - } - - /** - * Gives game managers an opportunity to perform periodic processing - * that is not driven by events generated by the player. - */ - protected void tick (long tickStamp) - { - // nothing for now - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - if (event.getName().equals(GameObject.STATE)) { - stateDidChange(_committedState = event.getIntValue(), - ((Integer)event.getOldValue()).intValue()); - } - } - - /** - * Called periodically to call {@link #tick} on all registered game - * managers. - */ - protected static void tickAllGames () - { - long now = System.currentTimeMillis(); - int size = _managers.size(); - for (int ii = 0; ii < size; ii++) { - GameManager gmgr = _managers.get(ii); - try { - gmgr.tick(now); - } catch (Exception e) { - Log.warning("Game manager choked during tick " + - "[gmgr=" + gmgr + "]."); - Log.logStackTrace(e); - } - } - } - - /** - * A helper operation to distribute AI ticks to our delegates. - */ - protected class TickAIDelegateOp implements DelegateOp - { - public void apply (PlaceManagerDelegate delegate) { - ((GameManagerDelegate) delegate).tickAI(_pidx, _ai); - } - - public void setAI (int pidx, GameAI ai) - { - _pidx = pidx; - _ai = ai; - } - - protected int _pidx; - protected GameAI _ai; - } - - /** A reference to our game config. */ - protected GameConfig _gameconfig; - - /** A reference to our game object. */ - protected GameObject _gameobj; - - /** The number of players in the game. */ - protected int _playerCount; - - /** The oids of our player and AI body objects. */ - protected int[] _playerOids; - - /** If AIs are present, contains their configuration, or null at human - * player indexes. */ - protected GameAI[] _AIs; - - /** If non-null, contains bundles and messages that should be sent as - * system messages once the game has started. */ - protected ArrayList> _startmsgs; - - /** Our delegate operator to tick AIs. */ - protected TickAIDelegateOp _tickAIOp; - - /** The state of the game that has been propagated to our - * subscribers. */ - protected int _committedState; - - /** TEMP: debugging the pending rating double release bug. */ - protected RepeatCallTracker _gameEndTracker = new RepeatCallTracker(); - - /** A list of all currently active game managers. */ - protected static ArrayList _managers = - new ArrayList(); - - /** The interval for the game manager tick. */ - protected static Interval _tickInterval; - - /** We give players 30 seconds to turn up in a game; after that, - * they're considered a no show. */ - protected static final long NOSHOW_DELAY = 30 * 1000L; - - /** The delay in milliseconds between ticking of all game managers. */ - protected static final long TICK_DELAY = 5L * 1000L; -} diff --git a/src/java/com/threerings/parlor/game/server/GameManagerDelegate.java b/src/java/com/threerings/parlor/game/server/GameManagerDelegate.java deleted file mode 100644 index 85fe16433..000000000 --- a/src/java/com/threerings/parlor/game/server/GameManagerDelegate.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// $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.parlor.game.server; - -import com.threerings.util.Name; - -import com.threerings.crowd.server.PlaceManagerDelegate; - -import com.threerings.parlor.game.data.GameAI; - -/** - * Extends the {@link PlaceManagerDelegate} mechanism with game manager - * specific methods. - */ -public class GameManagerDelegate extends PlaceManagerDelegate -{ - /** - * Provides the delegate with a reference to the game manager for - * which it is delegating. - */ - public GameManagerDelegate (GameManager gmgr) - { - super(gmgr); - } - - /** - * Called by the game manager when the game is about to start. - */ - public void gameWillStart () - { - } - - /** - * Called by the game manager after the game was started. - */ - public void gameDidStart () - { - } - - /** - * Called when a player in the game has been replaced by a call to - * {@link GameManager#replacePlayer}. - */ - public void playerWasReplaced (int pidx, Name oldPlayer, Name newPlayer) - { - } - - /** - * Called by the manager when we should do some AI. Only called while - * the game is IN_PLAY. - * - * @param pidx the player index to fake some gameplay for. - * @param ai a record indicating the AI's configuration. - */ - public void tickAI (int pidx, GameAI ai) - { - } - - /** - * Called by the game manager when the game is about to end. - */ - public void gameWillEnd () - { - } - - /** - * Called by the game manager after the game ended. - */ - public void gameDidEnd () - { - } - - /** - * Called when the game is about to reset, but before any other - * clearing out of game data has taken place. Derived classes should - * override this if they need to perform some pre-reset activities. - */ - public void gameWillReset () - { - } - - /** - * Called when the specified player has been set as an AI with the - * supplied AI configuration. - */ - public void setAI (int pidx, GameAI ai) - { - } -} diff --git a/src/java/com/threerings/parlor/game/server/GameProvider.java b/src/java/com/threerings/parlor/game/server/GameProvider.java deleted file mode 100644 index 94ed70969..000000000 --- a/src/java/com/threerings/parlor/game/server/GameProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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.parlor.game.server; - -import com.threerings.parlor.game.client.GameService; -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; - -/** - * Defines the server-side of the {@link GameService}. - */ -public interface GameProvider extends InvocationProvider -{ - /** - * Handles a {@link GameService#playerReady} request. - */ - public void playerReady (ClientObject caller); -} diff --git a/src/java/com/threerings/parlor/game/server/GameWatcher.java b/src/java/com/threerings/parlor/game/server/GameWatcher.java deleted file mode 100644 index 167f94119..000000000 --- a/src/java/com/threerings/parlor/game/server/GameWatcher.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// $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.parlor.game.server; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; - -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.server.PlaceManager; -import com.threerings.crowd.server.PlaceRegistry; - -import com.threerings.parlor.game.data.GameObject; - -/** - * An abstract convenience class used server-side to keep an eye on a game - * and perform a one-time game-over activity when the game ends. Classes - * that care to make use of the game watcher should create an instance, - * implement {@link #gameDidEnd}, and pass the instance to the place - * registry in the call to {@link PlaceRegistry#createPlace} when the - * puzzle is created. - */ -public abstract class GameWatcher - implements PlaceRegistry.CreationObserver, AttributeChangeListener -{ - // documentation inherited - public void placeCreated (PlaceObject place, PlaceManager pmgr) - { - _gameobj = (GameObject)place; - _gameobj.addListener(this); - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - if (event.getName().equals(GameObject.STATE)) { - // if we transitioned to a non-in-play state, the game has - // completed - if (!_gameobj.isInPlay()) { - try { - gameDidEnd(_gameobj); - } finally { - _gameobj.removeListener(this); - _gameobj = null; - } - } - } - } - - /** - * Called when the game ends to give derived classes a chance to - * engage in their game-over antics. - */ - protected abstract void gameDidEnd (GameObject gameobj); - - /** The game object we're observing. */ - protected GameObject _gameobj; -} diff --git a/src/java/com/threerings/parlor/game/server/TeamGameManager.java b/src/java/com/threerings/parlor/game/server/TeamGameManager.java deleted file mode 100644 index 91edbe7d4..000000000 --- a/src/java/com/threerings/parlor/game/server/TeamGameManager.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// $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.parlor.game.server; - -/** - * An interface to be implemented by a game if it wants to hear about - * the team indices that were configured during matchmaking. - */ -public interface TeamGameManager -{ - /** - * Set the team member indices. For example, a game with - * three players in two teams- players 0 and 2 versus player 1- would - * have { {0, 2}, {1} } set. - */ - public void setTeamMemberIndices (int[][] teams); -} diff --git a/src/java/com/threerings/parlor/media/ScoreAnimation.java b/src/java/com/threerings/parlor/media/ScoreAnimation.java deleted file mode 100644 index de2ca8fa4..000000000 --- a/src/java/com/threerings/parlor/media/ScoreAnimation.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $Id: ScoreAnimation.java 3479 2005-04-13 19:06: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.parlor.media; - -import java.awt.Color; -import java.awt.Font; - -import com.samskivert.swing.Label; - -import com.threerings.media.MediaPanel; -import com.threerings.media.animation.FloatingTextAnimation; - -public class ScoreAnimation extends FloatingTextAnimation -{ - { // initializer, run automatically with every constructor - setRenderOrder(Integer.MAX_VALUE); - } - - /** - * Constructs a score animation for the given score value centered at - * the given coordinates. - */ - public ScoreAnimation (Label label, int x, int y) - { - super(label, x, y); - } - - /** - * Constructs a score animation for the given score value centered at - * the given coordinates. The animation will float up the screen for - * 30 pixels. - */ - public ScoreAnimation (Label label, int x, int y, long floatPeriod) - { - super(label, x, y, floatPeriod); - } - - /** - * Constructs a score animation for the given score value starting at - * the given coordinates and floating toward the specified - * coordinates. - */ - public ScoreAnimation (Label label, int sx, int sy, - int destx, int desty, long floatPeriod) - { - super(label, sx, sy, destx, desty, floatPeriod); - } - - /** - * Create and configure a Label suitable for a ScoreAnimation with - * all the most common options. - */ - public static Label createLabel (String score, Color c, Font font, - MediaPanel host) - { - Label label = new Label(score); - label.setTargetWidth(host.getWidth()); - label.setStyle(Label.OUTLINE); - label.setTextColor(c); - label.setAlternateColor(Color.BLACK); - label.setFont(font); - label.setAlignment(Label.CENTER); - label.layout(host); - - return label; - } -} diff --git a/src/java/com/threerings/parlor/server/ParlorDispatcher.java b/src/java/com/threerings/parlor/server/ParlorDispatcher.java deleted file mode 100644 index d3378ba60..000000000 --- a/src/java/com/threerings/parlor/server/ParlorDispatcher.java +++ /dev/null @@ -1,116 +0,0 @@ -// -// $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.parlor.server; - -import com.threerings.parlor.client.ParlorService; -import com.threerings.parlor.data.ParlorMarshaller; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; -import com.threerings.util.Name; - -/** - * Dispatches requests to the {@link ParlorProvider}. - */ -public class ParlorDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public ParlorDispatcher (ParlorProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new ParlorMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case ParlorMarshaller.CANCEL: - ((ParlorProvider)provider).cancel( - source, - ((Integer)args[0]).intValue(), (InvocationService.InvocationListener)args[1] - ); - return; - - case ParlorMarshaller.CREATE_TABLE: - ((ParlorProvider)provider).createTable( - source, - ((Integer)args[0]).intValue(), (TableConfig)args[1], (GameConfig)args[2], (ParlorService.TableListener)args[3] - ); - return; - - case ParlorMarshaller.INVITE: - ((ParlorProvider)provider).invite( - source, - (Name)args[0], (GameConfig)args[1], (ParlorService.InviteListener)args[2] - ); - return; - - case ParlorMarshaller.JOIN_TABLE: - ((ParlorProvider)provider).joinTable( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (InvocationService.InvocationListener)args[3] - ); - return; - - case ParlorMarshaller.LEAVE_TABLE: - ((ParlorProvider)provider).leaveTable( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (InvocationService.InvocationListener)args[2] - ); - return; - - case ParlorMarshaller.RESPOND: - ((ParlorProvider)provider).respond( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (Object)args[2], (InvocationService.InvocationListener)args[3] - ); - return; - - case ParlorMarshaller.START_SOLITAIRE: - ((ParlorProvider)provider).startSolitaire( - source, - (GameConfig)args[0], (InvocationService.ConfirmListener)args[1] - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/parlor/server/ParlorManager.java b/src/java/com/threerings/parlor/server/ParlorManager.java deleted file mode 100644 index 6c8a083d1..000000000 --- a/src/java/com/threerings/parlor/server/ParlorManager.java +++ /dev/null @@ -1,274 +0,0 @@ -// -// $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.parlor.server; - -import com.samskivert.util.HashIntMap; -import com.threerings.util.Name; - -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationManager; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.PlaceRegistry; - -import com.threerings.parlor.Log; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.server.GameManager; - -/** - * The parlor manager is responsible for the parlor services in - * aggregate. This includes maintaining the registry of active games, - * handling the necessary coordination for the matchmaking services and - * anything else that falls outside the scope of an actual in-progress - * game. - */ -public class ParlorManager - implements ParlorCodes -{ - /** Provides the server-side implementation of the parlor services. */ - public ParlorProvider parprov; - - /** - * Initializes the parlor manager. This should be called by the server - * that is making use of the parlor services on the single instance of - * parlor manager that it has created. - * - * @param invmgr a reference to the invocation manager in use by this - * server. - * @param plreg a reference to the place registry to be used by the - * parlor manager when creating game places. - */ - public void init (InvocationManager invmgr, PlaceRegistry plreg) - { - // create and register our invocation provider - parprov = new ParlorProvider(this); - invmgr.registerDispatcher(new ParlorDispatcher(parprov), true); - - // keep this for later - _plreg = plreg; - } - - /** - * Issues an invitation from the inviter to the - * invitee for a game as described by the supplied config - * object. - * - * @param inviter the player initiating the invitation. - * @param invitee the player being invited. - * @param config the configuration of the game being proposed. - * - * @return the invitation identifier for the newly created invitation - * record. - * - * @exception InvocationException thrown if the invitation was not - * able to be processed for some reason (like the invited player has - * requested not to be disturbed). The explanation will be provided in - * the message data of the exception. - */ - public int invite (BodyObject inviter, BodyObject invitee, - GameConfig config) - throws InvocationException - { -// Log.info("Received invitation request [inviter=" + inviter + -// ", invitee=" + invitee + ", config=" + config + "]."); - - // here we should check to make sure the invitee hasn't muted the - // inviter, and that the inviter isn't shunned and all that other - // access control type stuff - - // create a new invitation record for this invitation - Invitation invite = new Invitation(inviter, invitee, config); - - // stick it in the pending invites table - _invites.put(invite.inviteId, invite); - - // deliver an invite notification to the invitee - ParlorSender.sendInvite( - invitee, invite.inviteId, inviter.getVisibleName(), config); - - // and let the caller know the invite id we assigned - return invite.inviteId; - } - - /** - * Effects a response to an invitation (accept, refuse or counter), - * made by the specified source user with the specified arguments. - * - * @param source the body object of the user that is issuing this - * response. - * @param inviteId the identifier of the invitation to which we are - * responding. - * @param code the response code (either {@link - * #INVITATION_ACCEPTED}, {@link #INVITATION_REFUSED} or {@link - * #INVITATION_COUNTERED}). - * @param arg the argument that goes along with the response: an - * explanatory message in the case of a refusal (the empty string, not - * null, if no message was provided) or the new game configuration in - * the case of a counter-invitation. - */ - public void respondToInvite (BodyObject source, int inviteId, int code, - Object arg) - { - // look up the invitation - Invitation invite = (Invitation)_invites.get(inviteId); - if (invite == null) { - Log.warning("Requested to respond to non-existent invitation " + - "[source=" + source + ", inviteId=" + inviteId + - ", code=" + code + ", arg=" + arg + "]."); - return; - } - - // make sure this response came from the proper person - if (source != invite.invitee) { - Log.warning("Got response from non-invitee [source=" + source + - ", invite=" + invite + ", code=" + code + - ", arg=" + arg + "]."); - return; - } - - // let the other user know that a response was made to this - // invitation - ParlorSender.sendInviteResponse( - invite.inviter, invite.inviteId, code, arg); - - switch (code) { - case INVITATION_ACCEPTED: - // the invitation was accepted, so we'll need to start up the - // game and get the necessary balls rolling - processAcceptedInvitation(invite); - // and remove the invitation from the pending table - _invites.remove(inviteId); - break; - - case INVITATION_REFUSED: - // remove the invitation record from the pending table as it - // is no longer pending - _invites.remove(inviteId); - break; - - case INVITATION_COUNTERED: - // swap control of the invitation to the invitee - invite.swapControl(); - break; - - default: - Log.warning("Requested to respond to invitation with " + - "unknown response code [source=" + source + - ", invite=" + invite + ", code=" + code + - ", arg=" + arg + "]."); - break; - } - } - - /** - * Requests that an outstanding invitation be cancelled. - * - * @param source the body object of the user that is making the - * request. - * @param inviteId the unique id of the invitation to be cancelled. - */ - public void cancelInvite (BodyObject source, int inviteId) - { - // TBD - } - - /** - * Starts up and configures the game manager for an accepted - * invitation. - */ - protected void processAcceptedInvitation (Invitation invite) - { - try { - Log.info("Creating game manager [invite=" + invite + "]."); - - // configure the game config with the player info - invite.config.players = new Name[] { - invite.invitee.username, invite.inviter.username }; - - // create the game manager and begin it's initialization - // process. the game manager will take care of notifying the - // players that the game has been created once it has been - // started up (which is done by the place registry once the - // game object creation has completed) - GameManager gmgr = (GameManager) - _plreg.createPlace(invite.config, null); - - } catch (Exception e) { - Log.warning("Unable to create game manager [invite=" + invite + - ", error=" + e + "]."); - Log.logStackTrace(e); - } - } - - /** - * The invitation record is used by the parlor manager to keep track - * of pending invitations. - */ - protected static class Invitation - { - /** The unique identifier for this invitation. */ - public int inviteId = _nextInviteId++; - - /** The person proposing the invitation. */ - public BodyObject inviter; - - /** The person to whom the invitation is proposed. */ - public BodyObject invitee; - - /** The configuration of the game being proposed. */ - public GameConfig config; - - /** - * Constructs a new invitation with the specified participants and - * configuration. - */ - public Invitation (BodyObject inviter, BodyObject invitee, - GameConfig config) - { - this.inviter = inviter; - this.invitee = invitee; - this.config = config; - } - - /** - * Swaps the inviter and invitee which is necessary when the - * invitee responds with a counter-invitation. - */ - public void swapControl () - { - BodyObject tmp = inviter; - inviter = invitee; - invitee = tmp; - } - } - - /** The place registry with which we operate. */ - protected PlaceRegistry _plreg; - - /** The table of pending invitations. */ - protected HashIntMap _invites = new HashIntMap(); - - /** A counter used to generate unique identifiers for invitation - * records. */ - protected static int _nextInviteId = 0; -} diff --git a/src/java/com/threerings/parlor/server/ParlorProvider.java b/src/java/com/threerings/parlor/server/ParlorProvider.java deleted file mode 100644 index 2c8514743..000000000 --- a/src/java/com/threerings/parlor/server/ParlorProvider.java +++ /dev/null @@ -1,233 +0,0 @@ -// -// $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.parlor.server; - -import com.threerings.util.Name; - -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.client.InvocationService.InvocationListener; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.CrowdServer; -import com.threerings.crowd.server.PlaceManager; - -import com.threerings.parlor.Log; -import com.threerings.parlor.client.ParlorService; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.server.GameManager; - -/** - * The parlor provider handles the server side of the various Parlor - * services that are made available for direct invocation by the client. - * Primarily these are the matchmaking mechanisms. - */ -public class ParlorProvider - implements InvocationProvider, ParlorCodes -{ - /** - * Constructs a parlor provider instance which will be used to handle - * all parlor-related invocation service requests. This is - * automatically taken care of by the parlor manager, so no other - * entity need instantiate and register a parlor provider. - * - * @param pmgr a reference to the parlor manager active in this - * server. - */ - public ParlorProvider (ParlorManager pmgr) - { - _pmgr = pmgr; - } - - /** - * Processes a request from the client to invite another user to play - * a game. - */ - public void invite (ClientObject caller, Name invitee, GameConfig config, - ParlorService.InviteListener listener) - throws InvocationException - { -// Log.info("Handling invite request [source=" + source + -// ", invitee=" + invitee + ", config=" + config + "]."); - - BodyObject source = (BodyObject)caller; - String rsp = null; - - // ensure that the invitee is online at present - BodyObject target = CrowdServer.lookupBody(invitee); - if (target == null) { - throw new InvocationException(INVITEE_NOT_ONLINE); - } - - // submit the invite request to the parlor manager - int inviteId = _pmgr.invite(source, target, config); - listener.inviteReceived(inviteId); - } - - /** - * Processes a request from the client to respond to an outstanding - * invitation by accepting, refusing, or countering it. - */ - public void respond (ClientObject caller, int inviteId, int code, - Object arg, InvocationListener listener) - { - // pass this on to the parlor manager - _pmgr.respondToInvite((BodyObject)caller, inviteId, code, arg); - } - - /** - * Processes a request from the client to cancel an outstanding - * invitation. - */ - public void cancel (ClientObject caller, int inviteId, - InvocationListener listener) - { - // pass this on to the parlor manager - _pmgr.cancelInvite((BodyObject)caller, inviteId); - } - - /** - * Processes a request from the client to create a new table. - */ - public void createTable ( - ClientObject caller, int lobbyOid, TableConfig tableConfig, - GameConfig config, ParlorService.TableListener listener) - throws InvocationException - { - Log.info("Handling create table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", config=" + config + "]."); - - // pass the creation request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - int tableId = tmgr.createTable((BodyObject)caller, tableConfig, config); - listener.tableCreated(tableId); - } - - /** - * Processes a request from the client to join an existing table. - */ - public void joinTable (ClientObject caller, int lobbyOid, int tableId, - int position, InvocationListener listener) - throws InvocationException - { - Log.info("Handling join table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", tableId=" + tableId + - ", position=" + position + "]."); - - // pass the join request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - tmgr.joinTable((BodyObject)caller, tableId, position); - - // there is normally no success response. the client will see - // themselves show up in the table that they joined - } - - /** - * Processes a request from the client to leave an existing table. - */ - public void leaveTable (ClientObject caller, int lobbyOid, int tableId, - InvocationListener listener) - throws InvocationException - { - Log.info("Handling leave table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", tableId=" + tableId + "]."); - - // pass the join request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - tmgr.leaveTable((BodyObject)caller, tableId); - - // there is normally no success response. the client will see - // themselves removed from the table they just left - } - - /** - * Handles a {@link ParlorService#startSolitaire} request. - */ - public void startSolitaire (ClientObject caller, GameConfig config, - InvocationService.ConfirmListener listener) - throws InvocationException - { - BodyObject user = (BodyObject)caller; - - Log.debug("Processing start puzzle [caller=" + user.who() + - ", config=" + config + "]."); - - try { - // just this fellow will be playing - if (config.players == null || config.players.length == 0) { - config.players = new Name[] { user.getVisibleName() }; - } - - // create the game manager and begin its initialization - // process - GameManager gmgr = (GameManager) - CrowdServer.plreg.createPlace(config, null); - - // the game manager will take care of notifying the player - // that the game has been created once it has been started up; - // but we let the caller know that we processed their request - listener.requestProcessed(); - - } catch (InstantiationException ie) { - Log.warning("Error instantiating game manager " + - "[for=" + caller.who() + ", config=" + config + "]."); - Log.logStackTrace(ie); - throw new InvocationException(INTERNAL_ERROR); - } - } - - /** - * Looks up the place manager associated with the supplied lobby oid, - * casts it to a table lobby manager and obtains the associated table - * manager reference. - * - * @exception InvocationException thrown if something goes wrong - * along the way like no place manager exists or the place manager - * that does exist doesn't implement table lobby manager. - */ - protected TableManager getTableManager (int lobbyOid) - throws InvocationException - { - PlaceManager plmgr = CrowdServer.plreg.getPlaceManager(lobbyOid); - if (plmgr == null) { - Log.warning("No place manager exists from which to obtain " + - "table manager reference [ploid=" + lobbyOid + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - // sanity check - if (!(plmgr instanceof TableManagerProvider)) { - Log.warning("Place manager not a table lobby manager " + - "[plmgr=" + plmgr + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - return ((TableManagerProvider)plmgr).getTableManager(); - } - - /** A reference to the parlor manager we're working with. */ - protected ParlorManager _pmgr; -} diff --git a/src/java/com/threerings/parlor/server/ParlorSender.java b/src/java/com/threerings/parlor/server/ParlorSender.java deleted file mode 100644 index 23dff9ffb..000000000 --- a/src/java/com/threerings/parlor/server/ParlorSender.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $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.parlor.server; - -import com.threerings.parlor.client.ParlorDecoder; -import com.threerings.parlor.client.ParlorReceiver; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationSender; -import com.threerings.util.Name; - -/** - * Used to issue notifications to a {@link ParlorReceiver} instance on a - * client. - */ -public class ParlorSender extends InvocationSender -{ - /** - * Issues a notification that will result in a call to {@link - * ParlorReceiver#gameIsReady} on a client. - */ - public static void gameIsReady ( - ClientObject target, int arg1) - { - sendNotification( - target, ParlorDecoder.RECEIVER_CODE, ParlorDecoder.GAME_IS_READY, - new Object[] { Integer.valueOf(arg1) }); - } - - /** - * Issues a notification that will result in a call to {@link - * ParlorReceiver#receivedInvite} on a client. - */ - public static void sendInvite ( - ClientObject target, int arg1, Name arg2, GameConfig arg3) - { - sendNotification( - target, ParlorDecoder.RECEIVER_CODE, ParlorDecoder.RECEIVED_INVITE, - new Object[] { Integer.valueOf(arg1), arg2, arg3 }); - } - - /** - * Issues a notification that will result in a call to {@link - * ParlorReceiver#receivedInviteCancellation} on a client. - */ - public static void sendInviteCancellation ( - ClientObject target, int arg1) - { - sendNotification( - target, ParlorDecoder.RECEIVER_CODE, ParlorDecoder.RECEIVED_INVITE_CANCELLATION, - new Object[] { Integer.valueOf(arg1) }); - } - - /** - * Issues a notification that will result in a call to {@link - * ParlorReceiver#receivedInviteResponse} on a client. - */ - public static void sendInviteResponse ( - ClientObject target, int arg1, int arg2, Object arg3) - { - sendNotification( - target, ParlorDecoder.RECEIVER_CODE, ParlorDecoder.RECEIVED_INVITE_RESPONSE, - new Object[] { Integer.valueOf(arg1), Integer.valueOf(arg2), arg3 }); - } - -} diff --git a/src/java/com/threerings/parlor/server/TableManager.java b/src/java/com/threerings/parlor/server/TableManager.java deleted file mode 100644 index 3ed2fbab2..000000000 --- a/src/java/com/threerings/parlor/server/TableManager.java +++ /dev/null @@ -1,379 +0,0 @@ -// -// $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.parlor.server; - -import java.util.HashMap; -import java.util.Iterator; - -import com.samskivert.util.HashIntMap; -import com.samskivert.util.StringUtil; -import com.threerings.util.Name; - -import com.threerings.presents.dobj.ChangeListener; -import com.threerings.presents.dobj.ObjectAddedEvent; -import com.threerings.presents.dobj.ObjectDeathListener; -import com.threerings.presents.dobj.ObjectDestroyedEvent; -import com.threerings.presents.dobj.ObjectRemovedEvent; -import com.threerings.presents.dobj.OidListListener; -import com.threerings.presents.server.InvocationException; - -import com.threerings.crowd.data.BodyObject; -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.parlor.Log; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.data.Table; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.data.TableLobbyObject; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.game.server.GameManager; - -/** - * A table manager can be used by a place manager to take care of the - * management of a table matchmaking service in the place managed by the - * place manager. The place manager need instantiate a table manager and - * implement the {@link TableManagerProvider} interface to provide access - * to the table manager for the associated invocation services. - */ -public class TableManager - implements ParlorCodes, OidListListener -{ - /** - * Creates a table manager that will work in tandem with the specified - * place manager to manage a table matchmaking service in this place. - */ - public TableManager (PlaceManager plmgr) - { - // get a reference to our place object - _plobj = plmgr.getPlaceObject(); - - // add ourselves as an oidlist listener to this lobby so that we - // can tell if a user leaves the lobby without leaving their table - _plobj.addListener(this); - - // make sure it implements table lobby object - _tlobj = (TableLobbyObject)_plobj; - } - - /** - * Requests that a new table be created to matchmake the game - * described by the supplied game config instance. The config instance - * provided must implement the {@link TableConfig} interface so that - * the parlor services can determine how to configure the table that - * will be created. - * - * @param creator the body object that will own the new table. - * @param tableConfig the configuration parameters for the table. - * @param config the configuration of the game to be created. - * - * @return the id of the newly created table. - * - * @exception InvocationException thrown if the table creation was - * not able processed for some reason. The explanation will be - * provided in the message data of the exception. - */ - public int createTable (BodyObject creator, TableConfig tableConfig, - GameConfig config) - throws InvocationException - { - // make sure the creator is an occupant of the lobby in which - // they are requesting to create a table - if (!_plobj.occupants.contains(creator.getOid())) { - Log.warning("Requested to create a table in a lobby not " + - "occupied by the creator [creator=" + creator + - ", loboid=" + _plobj.getOid() + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - // create a brand spanking new table - Table table = new Table(_plobj.getOid(), tableConfig, config); - - // stick the creator into the first non-AI position - int cpos = (config.ais == null) ? 0 : config.ais.length; - String error = table.setOccupant(cpos, creator); - if (error != null) { - Log.warning("Unable to add creator to position zero of " + - "table!? [table=" + table + ", creator=" + creator + - ", error=" + error + "]."); - // bail out now and abort the table creation process - throw new InvocationException(error); - } - - // stick the table into the table lobby object - _tlobj.addToTables(table); - - // make a mapping from the creator to this table - _boidMap.put(creator.getOid(), table); - - // also stick it into our tables tables - _tables.put(table.getTableId(), table); - - // if the table has only one seat, start the game immediately - if (table.shouldBeStarted()) { - createGame(table); - } - - // finally let the caller know what the new table id is - return table.getTableId(); - } - - /** - * Requests that the specified user be added to the specified table at - * the specified position. If the user successfully joins the table, - * the function will return normally. If they are not able to join for - * some reason (the slot is already full, etc.), a {@link - * InvocationException} will be thrown with a message code that - * describes the reason for failure. If the user does successfully - * join, they will be added to the table entry in the tables set in - * the place object that is hosting the table. - * - * @param joiner the body object of the user that wishes to join the - * table. - * @param tableId the id of the table to be joined. - * @param position the position at which to join the table. - * - * @exception InvocationException thrown if the joining was not able - * processed for some reason. The explanation will be provided in the - * message data of the exception. - */ - public void joinTable (BodyObject joiner, int tableId, int position) - throws InvocationException - { - // look the table up - Table table = (Table)_tables.get(tableId); - if (table == null) { - throw new InvocationException(NO_SUCH_TABLE); - } - - // request that the user be added to the table at that position - String error = table.setOccupant(position, joiner); - // if that failed, report the error - if (error != null) { - throw new InvocationException(error); - } - - // if the table is sufficiently full, start the game automatically - if (table.shouldBeStarted()) { - createGame(table); - } else { - // make a mapping from this occupant to this table - _boidMap.put(joiner.getOid(), table); - } - - // update the table in the lobby - _tlobj.updateTables(table); - } - - /** - * Requests that the specified user be removed from the specified - * table. If the user successfully leaves the table, the function will - * return normally. If they are not able to leave for some reason - * (they aren't sitting at the table, etc.), a {@link - * InvocationException} will be thrown with a message code that - * describes the reason for failure. - * - * @param leaver the body object of the user that wishes to leave the - * table. - * @param tableId the id of the table to be left. - * - * @exception InvocationException thrown if the leaving was not able - * processed for some reason. The explanation will be provided in the - * message data of the exception. - */ - public void leaveTable (BodyObject leaver, int tableId) - throws InvocationException - { - // look the table up - Table table = (Table)_tables.get(tableId); - if (table == null) { - throw new InvocationException(NO_SUCH_TABLE); - } - - // request that the user be removed from the table - if (!table.clearOccupant(leaver.getVisibleName())) { - throw new InvocationException(NOT_AT_TABLE); - } - - // remove the mapping from this user to the table - if (_boidMap.remove(leaver.getOid()) == null) { - Log.warning("No body to table mapping to clear? " + - "[leaver=" + leaver + ", table=" + table + "]."); - } - - // either update or delete the table depending on whether or not - // we just removed the last occupant - if (table.isEmpty()) { - purgeTable(table); - } else { - _tlobj.updateTables(table); - } - } - - /** - * Removes the table from all of our internal tables and from its - * lobby's distributed object. - */ - protected void purgeTable (Table table) - { - // remove the table from our tables table - _tables.remove(table.getTableId()); - - // clear out all matching entries in the boid map - for (int i = 0; i < table.bodyOids.length; i++) { - _boidMap.remove(table.bodyOids[i]); - } - - // remove the table from the lobby object - _tlobj.removeFromTables(table.tableId); - } - - /** - * Called when we're ready to create a game (either an invitation has - * been accepted or a table is ready to start. If there is a problem - * creating the game manager, it should be reported in the logs. - */ - protected void createGame (final Table table) - throws InvocationException - { - // fill the players array into the game config - table.config.players = table.getPlayers(); - - PlaceRegistry.CreationObserver obs = - new PlaceRegistry.CreationObserver() { - public void placeCreated (PlaceObject plobj, PlaceManager pmgr) { - gameCreated(table, plobj); - } - }; - try { - CrowdServer.plreg.createPlace(table.config, obs); - } catch (Throwable t) { - Log.warning("Failed to create manager for game " + - "[config=" + table.config + "]: " + t); - throw new InvocationException(INTERNAL_ERROR); - } - } - - /** - * Called when our game has been created, we take this opportunity to - * clean up the table and transition it to "in play" mode. - */ - protected void gameCreated (Table table, PlaceObject plobj) - { - // update the table with the newly created game object - table.gameOid = plobj.getOid(); - - // configure the privacy of the game - ((GameObject) plobj).setIsPrivate(table.tconfig.privateTable); - - // clear the occupant to table mappings as this game is underway - for (int i = 0; i < table.bodyOids.length; i++) { - _boidMap.remove(table.bodyOids[i]); - } - - // add an object death listener to unmap the table when the game - // finally goes away - plobj.addListener(_gameDeathListener); - - // and then update the lobby object that contains the table - _tlobj.updateTables(table); - } - - /** - * Called when a game created from a table managed by this table - * manager was destroyed. We remove the associated table. - */ - protected void unmapTable (int gameOid) - { - // look through our tables table for a table with a matching game - Iterator iter = _tables.values().iterator(); - while (iter.hasNext()) { - Table table = (Table)iter.next(); - if (table.gameOid == gameOid) { - purgeTable(table); - return; // all done - } - } - - Log.warning("Requested to unmap table that wasn't mapped " + - "[gameOid=" + gameOid + "]."); - } - - // documentation inherited - public void objectAdded (ObjectAddedEvent event) - { - // nothing doing - } - - // documentation inherited - public void objectRemoved (ObjectRemovedEvent event) - { - // if an occupant departed, see if they are in a pending table - if (!event.getName().equals(PlaceObject.OCCUPANTS)) { - return; - } - - // look up the table to which this occupant is mapped - int bodyOid = event.getOid(); - Table pender = (Table)_boidMap.remove(bodyOid); - if (pender == null) { - return; - } - - // remove this occupant from the table - if (!pender.clearOccupant(bodyOid)) { - Log.warning("Attempt to remove body from mapped table failed " + - "[table=" + pender + ", bodyOid=" + bodyOid + "]."); - return; - } - - // either update or delete the table depending on whether or not - // we just removed the last occupant - if (pender.isEmpty()) { - purgeTable(pender); - } else { - _tlobj.updateTables(pender); - } - } - - /** A reference to the place object in which we're managing tables. */ - protected PlaceObject _plobj; - - /** A reference to our place object casted to a table lobby object. */ - protected TableLobbyObject _tlobj; - - /** The table of pending tables. */ - protected HashIntMap _tables = new HashIntMap(); - - /** A mapping from body oid to table. */ - protected HashIntMap _boidMap = new HashIntMap(); - - /** A listener that prunes tables after the game dies. */ - protected ChangeListener _gameDeathListener = new ObjectDeathListener() { - public void objectDestroyed (ObjectDestroyedEvent event) { - unmapTable(event.getTargetOid()); - } - }; -} diff --git a/src/java/com/threerings/parlor/server/TableManagerProvider.java b/src/java/com/threerings/parlor/server/TableManagerProvider.java deleted file mode 100644 index 2bc72d86c..000000000 --- a/src/java/com/threerings/parlor/server/TableManagerProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// $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.parlor.server; - -/** - * A place manager that wishes to provide table matchmaking services in - * its place needs to create a table manager and make it available by - * implementing this interface. The table invocation services and the - * table manager will take care of the rest. - */ -public interface TableManagerProvider -{ - /** - * Returns a reference to the table manager that is responsible for - * table management in this lobby. - */ - public TableManager getTableManager (); -} diff --git a/src/java/com/threerings/parlor/turn/client/TurnDisplay.java b/src/java/com/threerings/parlor/turn/client/TurnDisplay.java deleted file mode 100644 index 2e9297c91..000000000 --- a/src/java/com/threerings/parlor/turn/client/TurnDisplay.java +++ /dev/null @@ -1,217 +0,0 @@ -// -// $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.parlor.turn.client; - -import java.awt.Color; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; - -import java.util.HashMap; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.Icon; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.VGroupLayout; -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.util.Name; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.turn.data.TurnGameObject; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.ElementUpdateListener; -import com.threerings.presents.dobj.ElementUpdatedEvent; -import com.threerings.presents.dobj.DObject; - -/** - * Automatically display a list of players and turn change information - * in a turn-based game. - */ -// TODO -// - adapt this to be able to display scores in some generic way as well. -// - allow configuring of turn / winner labels from prototypes, -// rather than forcing one to be an icon, the other a string, and -// examine the prototype to determine how to highlight the turnholder. -public class TurnDisplay extends JPanel - implements PlaceView, AttributeChangeListener, ElementUpdateListener -{ - /** - * Create a TurnDisplay. - */ - public TurnDisplay () - { - } - - /** - * Create a TurnDisplay for a game using the specified Icon to denote - * whose turn it is. - */ - public TurnDisplay (Icon turnIcon) - { - setTurnIcon(turnIcon); - } - - /** - * Set the icon to use. - */ - public void setTurnIcon (Icon turnIcon) - { - _turnIcon = turnIcon; - if (_turnObj != null) { - createList(); - } - } - - /** - * Set the text to be displayed next to the winner's name. - */ - public void setWinnerText (String winnerText) - { - _winnerText = winnerText; - } - - /** - * Set optional icons to use for identifying each player in the game. - */ - public void setPlayerIcons (Icon[] icons) - { - _playerIcons = icons; - if (_turnObj != null) { - createList(); - } - } - - /** - * Create the list of names and highlight as appropriate. - */ - protected void createList () - { - removeAll(); - _labels.clear(); - - GridBagLayout gridbag = new GridBagLayout(); - setLayout(gridbag); - - GridBagConstraints iconC = new GridBagConstraints(); - GridBagConstraints labelC = new GridBagConstraints(); - iconC.fill = labelC.fill = GridBagConstraints.BOTH; - labelC.weightx = 1.0; - labelC.insets.left = 10; - labelC.gridwidth = GridBagConstraints.REMAINDER; - - Name[] names = _turnObj.getPlayers(); - boolean[] winners = ((GameObject) _turnObj).winners; - Name holder = _turnObj.getTurnHolder(); - for (int ii=0, jj=0; ii < names.length; ii++, jj++) { - if (names[ii] == null) continue; - - JLabel iconLabel = new JLabel(); - if (winners == null) { - if (names[ii].equals(holder)) { - iconLabel.setIcon(_turnIcon); - } - } else if (winners[ii]) { - iconLabel.setText(_winnerText); - iconLabel.setForeground(Color.GREEN); - } - _labels.put(names[ii], iconLabel); - add(iconLabel, iconC); - - JLabel label = new JLabel(names[ii].toString()); - if (_playerIcons != null) { - label.setIcon(_playerIcons[jj]); - } - add(label, labelC); - } - - SwingUtil.refresh(this); - } - - // documentation inherited from interface PlaceView - public void willEnterPlace (PlaceObject plobj) - { - _turnObj = (TurnGameObject) plobj; - plobj.addListener(this); - createList(); - } - - // documentation inherited from interface PlaceView - public void didLeavePlace (PlaceObject plobj) - { - plobj.removeListener(this); - _turnObj = null; - removeAll(); - } - - // documentation inherited from interface AttributeChangeListener - public void attributeChanged (AttributeChangedEvent event) - { - String name = event.getName(); - if (name.equals(_turnObj.getTurnHolderFieldName())) { - JLabel oldLabel = (JLabel) _labels.get((Name) event.getOldValue()); - if (oldLabel != null) { - oldLabel.setIcon(null); - } - JLabel newLabel = (JLabel) _labels.get((Name) event.getValue()); - if (newLabel != null) { - newLabel.setIcon(_turnIcon); - } - - } else if (name.equals(GameObject.PLAYERS)) { - createList(); - - } else if (name.equals(GameObject.WINNERS)) { - createList(); - } - } - - // documentation inherited from interface ElementUpdateListener - public void elementUpdated (ElementUpdatedEvent event) - { - String name = event.getName(); - if (name.equals(GameObject.PLAYERS)) { - createList(); - } - } - - /** The TurnGameObject we're displaying. */ - protected TurnGameObject _turnObj; - - /** A mapping of the labels currently associated with each player. */ - protected HashMap _labels = new HashMap(); - - /** The game-specified player icons. */ - protected Icon[] _playerIcons; - - /** The text to display next to a winner's name. */ - protected String _winnerText; - - /** The Icon we use for indicating the turn. */ - protected Icon _turnIcon; -} diff --git a/src/java/com/threerings/parlor/turn/client/TurnGameController.java b/src/java/com/threerings/parlor/turn/client/TurnGameController.java deleted file mode 100644 index c82ac6841..000000000 --- a/src/java/com/threerings/parlor/turn/client/TurnGameController.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $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.parlor.turn.client; - -import com.threerings.util.Name; - -import com.threerings.parlor.game.client.GameController; - -/** - * Games that wish to make use of the turn game services should have their - * controller implement this interface and create an instance of {@link - * TurnGameControllerDelegate} which should be passed to {@link - * GameController#addDelegate}. - */ -public interface TurnGameController -{ - /** - * Called when the turn changed. This indicates the start of a turn - * and the user interface should adjust itself accordingly (activating - * controls if it is our turn and deactivating them if it is not). - * - * @param turnHolder the username of the new holder of the turn. - */ - public void turnDidChange (Name turnHolder); -} diff --git a/src/java/com/threerings/parlor/turn/client/TurnGameControllerDelegate.java b/src/java/com/threerings/parlor/turn/client/TurnGameControllerDelegate.java deleted file mode 100644 index 10096b46f..000000000 --- a/src/java/com/threerings/parlor/turn/client/TurnGameControllerDelegate.java +++ /dev/null @@ -1,149 +0,0 @@ -// -// $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.parlor.turn.client; - -import com.threerings.util.Name; - -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.AttributeChangeListener; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.parlor.game.client.GameController; -import com.threerings.parlor.game.client.GameControllerDelegate; -import com.threerings.parlor.game.data.GameObject; - -import com.threerings.parlor.turn.data.TurnGameObject; - -/** - * Performs the client-side processing for a turn-based game. Games which - * wish to make use of these services must construct a delegate and call - * out to it at the appropriate times (see the method documentation for - * which methods should be called when). The game's controller must also - * implement the {@link TurnGameController} interface so that it can be - * notified when turn-based game events take place. - */ -public class TurnGameControllerDelegate extends GameControllerDelegate - implements AttributeChangeListener -{ - /** - * Constructs a delegate which will call back to the supplied {@link - * TurnGameController} implementation wen turn-based game related - * things happen. - */ - public TurnGameControllerDelegate (TurnGameController tgctrl) - { - super((GameController)tgctrl); - - // keep this around for later - _tgctrl = tgctrl; - } - - /** - * Returns true if the game is in progress and it is our turn; false - * otherwise. - */ - public boolean isOurTurn () - { - BodyObject self = (BodyObject)_ctx.getClient().getClientObject(); - return (_gameObj.state == GameObject.IN_PLAY && - self.getVisibleName().equals(_turnGame.getTurnHolder())); - } - - /** - * Returns the index of the current turn holder as configured in the - * game object. - * - * @return the index into the players array of the current turn holder - * or -1 if there is no current turn holder. - */ - public int getTurnHolderIndex () - { - return _gameObj.getPlayerIndex(_turnGame.getTurnHolder()); - } - - // documentation inherited - public void init (CrowdContext ctx, PlaceConfig config) - { - _ctx = ctx; - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - // get a casted reference to the object - _gameObj = (GameObject)plobj; - _turnGame = (TurnGameObject)plobj; - _thfield = _turnGame.getTurnHolderFieldName(); - - // and add ourselves as a listener - plobj.addListener(this); - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - // remove our listenership - plobj.removeListener(this); - - // clean up - _turnGame = null; - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - // handle turn changes - if (event.getName().equals(_thfield)) { - Name name = (Name)event.getValue(); - Name oname = (Name)event.getOldValue(); - if (TurnGameObject.TURN_HOLDER_REPLACED.equals(name) || - TurnGameObject.TURN_HOLDER_REPLACED.equals(oname)) { - // small hackery: ignore the turn holder being set to - // TURN_HOLDER_REPLACED as it means that we're replacing - // the current turn holder rather than switching turns; - // also ignore the new turn holder when we switch from THR - // to a real name again - } else { - _tgctrl.turnDidChange(name); - } - } - } - - /** The turn game controller for whom we are delegating. */ - protected TurnGameController _tgctrl; - - /** A reference to our client context. */ - protected CrowdContext _ctx; - - /** A reference to our game object. */ - protected GameObject _gameObj; - - /** A casted reference to our game object as a turn game. */ - protected TurnGameObject _turnGame; - - /** The name of the turn holder field. */ - protected String _thfield; -} diff --git a/src/java/com/threerings/parlor/turn/data/TurnGameObject.java b/src/java/com/threerings/parlor/turn/data/TurnGameObject.java deleted file mode 100644 index fdd640471..000000000 --- a/src/java/com/threerings/parlor/turn/data/TurnGameObject.java +++ /dev/null @@ -1,64 +0,0 @@ -// -// $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.parlor.turn.data; - -import com.threerings.util.Name; - -import com.threerings.parlor.game.data.GameObject; - -/** - * Games that wish to support turn-based play must implement this - * interface with their {@link GameObject}. - */ -public interface TurnGameObject -{ - /** A special value used to communicate to the client that the current - * turn holder was replaced (perhaps due to disconnection or departure - * and being replaced by an AI). */ - public static final Name TURN_HOLDER_REPLACED = - new Name("__TURN_HOLDER_REPLACED__"); - - /** - * Returns the distributed object field name of the - * turnHolder field in the object that implements this - * interface. - */ - public String getTurnHolderFieldName (); - - /** - * Returns the username of the player who is currently taking their - * turn in this turn-based game or null if no user - * currently holds the turn. - */ - public Name getTurnHolder (); - - /** - * Requests that the turnHolder field be set to the specified - * value. - */ - public void setTurnHolder (Name turnHolder); - - /** - * Returns the array of player names involved in the game. - */ - public Name[] getPlayers (); -} diff --git a/src/java/com/threerings/parlor/turn/server/TurnGameManager.java b/src/java/com/threerings/parlor/turn/server/TurnGameManager.java deleted file mode 100644 index 12b28be22..000000000 --- a/src/java/com/threerings/parlor/turn/server/TurnGameManager.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $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.parlor.turn.server; - -import com.threerings.util.Name; - -import com.threerings.parlor.game.server.GameManager; - -/** - * A game manager that wishes to make use of the turn game services should - * implement this interface and create a {@link TurnGameManagerDelegate} - * which will perform the basic turn game processing and call back to the - * main manager via this interface. - * - *

The basic flow of a turn-based game is as follows: - *

- * GameManager.gameWillStart()
- * GameManager.gameDidStart()
- *   TurnGameManagerDelegate.setFirstTurnHolder()
- *   TurnGameManagerDelegate.startTurn()
- *     TurnGameManager.turnWillStart()
- *   TurnGameManagerDelegate.endTurn()
- *     TurnGameManager.turnDidEnd()
- *   TurnGameManagerDelegate.setNextTurnHolder()
- *   TurnGameManagerDelegate.startTurn()
- *     ...
- * GameManager.endGame()
- * 
- */ -public interface TurnGameManager -{ - /** - * Extending {@link GameManager} should automatically handle - * implementing this method. - */ - public Name getPlayerName (int index); - - /** - * Extending {@link GameManager} should automatically handle - * implementing this method. - */ - public int getPlayerIndex (Name username); - - /** - * Extending {@link GameManager} should automatically handle - * implementing this method. - */ - public int getPlayerCount (); - - /** - * Extending {@link GameManager} should automatically handle - * implementing this method. - */ - public boolean isActivePlayer (int pidx); - - /** - * Called when we are about to start the next turn. Implementations - * can do whatever pre-start turn activities need to be done. - */ - public void turnWillStart (); - - /** - * Called when we have started the next turn. Implementations can do - * whatever post-start turn activities need to be done. - */ - public void turnDidStart (); - - /** - * Called when the turn was ended. Implementations can perform any - * post-turn processing (like updating scores, etc.). - */ - public void turnDidEnd (); -} diff --git a/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java b/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java deleted file mode 100644 index 8eee2003c..000000000 --- a/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java +++ /dev/null @@ -1,246 +0,0 @@ -// -// $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.parlor.turn.server; - -import com.samskivert.util.RandomUtil; -import com.threerings.util.Name; - -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.Log; -import com.threerings.parlor.game.server.GameManager; -import com.threerings.parlor.game.server.GameManagerDelegate; - -import com.threerings.parlor.turn.data.TurnGameObject; - -/** - * Performs the server-side turn-based game processing for a turn based - * game. Game managers which wish to make use of the turn services must - * implement {@link TurnGameManager} and either create an instance of this - * class, or an instance of a derivation which customizes the behavior, - * either of which would be passed to {@link GameManager#addDelegate} to - * be activated. - */ -public class TurnGameManagerDelegate extends GameManagerDelegate -{ - /** - * Constructs a delegate that will manage the turn game state and call - * back to the supplied {@link TurnGameManager} implementation to let - * it in on the progression of the game. - */ - public TurnGameManagerDelegate (TurnGameManager tgmgr) - { - super((GameManager)tgmgr); - _tgmgr = tgmgr; - } - - /** - * Returns the index of the current turn holder as configured in the - * game object. - * - * @return the index into the players array of the current turn holder - * or -1 if there is no current turn holder. - */ - public int getTurnHolderIndex () - { - return _tgmgr.getPlayerIndex(_turnGame.getTurnHolder()); - } - - /** Test if it's the inputted player's turn. */ - public boolean isPlayersTurn (int playerIndex) - { - // Don't accidently match a visitor's id of -1 with the "no one's - // turn" state of turn -1. - int turnHolder = getTurnHolderIndex(); - if (turnHolder < 0) { - return false; - } - - // It's this player's turn if the ids match - return (turnHolder == playerIndex); - } - - /** - * Called to start the next turn. It calls {@link - * TurnGameManager#turnWillStart} to allow our owning manager to - * perform any pre-start turn processing, sets the turn holder that - * was configured either when the game started or when finishing up - * the last turn, and then calls {@link TurnGameManager#turnDidStart} - * to allow the manager to perform any post-start turn - * processing. This assumes that a valid turn holder has been - * assigned. If some pre-game preparation needs to take place in a - * non-turn-based manner, this function should not be called until it - * is time to start the first turn. - */ - public void startTurn () - { - // sanity check - if (_turnIdx < 0 || _turnIdx >= _turnGame.getPlayers().length) { - Log.warning("startTurn() called with invalid turn index " + - "[game=" + where() + ", turnIdx=" + _turnIdx + "]."); - // abort, abort - return; - } - - // get the player name and sanity-check again - Name name = _tgmgr.getPlayerName(_turnIdx); - if (name == null) { - Log.warning("startTurn() called with invalid player " + - "[game=" + where() + ", turnIdx=" + _turnIdx + "]."); - return; - } - - // do pre-start processing - _tgmgr.turnWillStart(); - - // and set the turn indicator accordingly - _turnGame.setTurnHolder(name); - - // do post-start processing - _tgmgr.turnDidStart(); - } - - /** - * Called to end the turn. Whatever indication a game manager has that - * the turn has ended (probably the submission of a valid move of some - * sort by the turn holding player), it should call this function to - * cause this turn to end and the next to begin. - * - *

If the next turn should not be started immediately after this - * turn, the game manager should arrange for {@link - * #setNextTurnHolder} to set the {@link #_turnIdx} field to - * -1 which will cause us not to start the next turn. It - * can then call {@link GameManager#endGame} if the game is over or do - * whatever else it needs to do outside the context of the turn flow. - * To start things back up again it would set {@link #_turnIdx} to the - * next turn holder and call {@link #startTurn} itself. - */ - public void endTurn () - { - // let the manager know that the turn is over - _tgmgr.turnDidEnd(); - - // figure out who's up next - setNextTurnHolder(); - - // and start the next turn if desired - if (_turnIdx != -1) { - startTurn(); - - } else { - // otherwise, clear out the turn holder - _turnGame.setTurnHolder(null); - } - } - - // documentation inherited - public void didStartup (PlaceObject plobj) - { - _turnGame = (TurnGameObject)plobj; - } - - // documentation inherited - public void playerWasReplaced (int pidx, Name oplayer, Name nplayer) - { - // we need to update the turn holder if the current turn holder - // was the player that was replaced and we need to do so in a way - // that doesn't make everyone think that the turn just changed - if (oplayer != null && oplayer.equals(_turnGame.getTurnHolder())) { - // small hackery: this will indicate to the client that we are - // replacing the turn holder rather than changing the turn - _turnGame.setTurnHolder(TurnGameObject.TURN_HOLDER_REPLACED); - _turnGame.setTurnHolder(nplayer); - } - } - - /** - * This should be called from {@link GameManager#gameDidStart} to let - * the turn delegate perform start of game processing. - */ - public void gameDidStart () - { - // figure out who will be first - setFirstTurnHolder(); - - // and start the first turn if we should apparently do so - if (_turnIdx != -1) { - startTurn(); - } - } - - /** - * This is called to determine which player will take the first - * turn. The default implementation chooses a player at random. - */ - protected void setFirstTurnHolder () - { - int size = _turnGame.getPlayers().length; - int firstPick = _turnIdx = RandomUtil.getInt(size); - while (!_tgmgr.isActivePlayer(_turnIdx)) { - _turnIdx = (_turnIdx + 1) % size; - if (_turnIdx == firstPick) { - Log.warning("No players eligible for first turn. Choking. " + - "[game=" + where() + "]."); - return; - } - } - } - - /** - * This is called to determine which player will next hold the turn. - * The default implementation simply rotates through the players in - * order, but some games may need to mess with the turn from time to - * time. This should update the _turnIdx field, not set - * the turn holder field in the game object directly. - */ - protected void setNextTurnHolder () - { - // stick with the current player if they're the only participant - if (_tgmgr.getPlayerCount() == 1) { - return; - } - - // find the next occupied active player slot - int size = _turnGame.getPlayers().length; - int oturnIdx = _turnIdx; - do { - _turnIdx = (_turnIdx + 1) % size; - if (_turnIdx == oturnIdx) { - // if we've wrapped all the way around, stop where we are - // even if the current player is not active. - Log.warning("1 or less active players. Unable to properly " + - "change turn. [game=" + where() + "]."); - break; - } - } while (!_tgmgr.isActivePlayer(_turnIdx)); - } - - /** The game manager for which we are delegating. */ - protected TurnGameManager _tgmgr; - - /** A reference to our game object. */ - protected TurnGameObject _turnGame; - - /** The player index of the current turn holder or -1 if - * it's no one's turn. */ - protected int _turnIdx = -1; -} diff --git a/src/java/com/threerings/parlor/util/ParlorContext.java b/src/java/com/threerings/parlor/util/ParlorContext.java deleted file mode 100644 index c693b6b7c..000000000 --- a/src/java/com/threerings/parlor/util/ParlorContext.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// $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.parlor.util; - -import com.threerings.crowd.util.CrowdContext; -import com.threerings.parlor.client.ParlorDirector; - -/** - * The parlor context provides access to the various managers, etc. that - * are needed by the parlor client code. - */ -public interface ParlorContext extends CrowdContext -{ - /** - * Returns a reference to the parlor director. - */ - public ParlorDirector getParlorDirector (); -} diff --git a/src/java/com/threerings/presents/dobj/DSet.java b/src/java/com/threerings/presents/dobj/DSet.java index 0010a1af5..66f773400 100644 --- a/src/java/com/threerings/presents/dobj/DSet.java +++ b/src/java/com/threerings/presents/dobj/DSet.java @@ -235,7 +235,7 @@ public class DSet } /** - * @deprecated use {@link #toArray(E[])}. + * @deprecated use {@link #toArray(Entry[])}. */ public Object[] toArray (Object[] array) { diff --git a/src/java/com/threerings/puzzle/Log.java b/src/java/com/threerings/puzzle/Log.java deleted file mode 100644 index 7e6997aac..000000000 --- a/src/java/com/threerings/puzzle/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.puzzle; - -/** - * 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("puzzle"); - - /** 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/puzzle/client/PlayerStatusView.java b/src/java/com/threerings/puzzle/client/PlayerStatusView.java deleted file mode 100644 index 923134e20..000000000 --- a/src/java/com/threerings/puzzle/client/PlayerStatusView.java +++ /dev/null @@ -1,124 +0,0 @@ -// -// $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.puzzle.client; - -import javax.swing.JPanel; - -import com.threerings.util.Name; - -import com.threerings.parlor.game.data.GameObject; - -import com.threerings.puzzle.data.BoardSummary; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.data.PuzzleObject; - -/** - * The player status view displays a player's current status in the game. - */ -public class PlayerStatusView extends JPanel -{ - /** - * Constructs a player status view. - */ - public PlayerStatusView (GameObject gameobj, int pidx) - { - // save off references - _gameobj = gameobj; - _username = _gameobj.players[pidx]; - _pidx = pidx; - - // configure the panel - setOpaque(false); - } - - /** - * Initializes the player status view with the puzzle config. - */ - public void init (PuzzleConfig config) - { - // nothing for now - } - - /** - * Get the player index of the player represented by this view. - */ - public int getPlayerIndex () - { - return _pidx; - } - - /** - * Sets the player board summary. - */ - public void setBoardSummary (BoardSummary summary) - { - _summary = summary; - repaint(); - } - - /** - * Sets the player status. - */ - public void setStatus (int status) - { - if (_status != status) { - _status = status; - repaint(); - } - } - - /** - * Sets whether to highlight the player status display when rendered. - */ - public void setHighlighted (boolean highlight) - { - if (_highlight != highlight) { - _highlight = highlight; - repaint(); - } - } - - /** Returns a string representation of this instance. */ - public String toString () - { - return "[user=" + _username + ", pidx=" + _pidx + - ", status=" + _status + "]"; - } - - /** The game object associated with this view. */ - protected GameObject _gameobj; - - /** The player name. */ - protected Name _username; - - /** The player index. */ - protected int _pidx; - - /** Whether this display is highlighted. */ - protected boolean _highlight; - - /** The player board summary. */ - protected BoardSummary _summary; - - /** The player game status. */ - protected int _status = PuzzleObject.PLAYER_IN_PLAY; -} diff --git a/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java b/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java deleted file mode 100644 index 9b1a7645d..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.puzzle.client; - -import com.threerings.media.animation.AnimationWaiter; - -import com.threerings.puzzle.data.PuzzleObject; - -/** - * An animation waiter to be used with puzzles that want to modify the - * game object or board in some way after the animations end, and would - * like to do so in a safe fashion such that their changes aren't - * unwittingly performed on game data for a subsequent round of the - * puzzle. - */ -public abstract class PuzzleAnimationWaiter extends AnimationWaiter -{ - /** - * Constructs a puzzle animation waiter. - */ - public PuzzleAnimationWaiter (PuzzleObject puzobj) - { - _puzobj = puzobj; - _roundId = puzobj.roundId; - } - - /** - * Returns whether the puzzle associated with this puzzle animation - * waiter is still valid. - */ - public boolean puzzleStillValid () - { - return (_puzobj.isInPlay() && (_roundId == _puzobj.roundId)); - } - - // documentation inherited - protected final void allAnimationsFinished () - { - allAnimationsFinished(puzzleStillValid()); - } - - /** - * Replacement for {@link AnimationWaiter#allAnimationsFinished} that - * also reports whether the puzzle associated with this animation - * waiter is still valid. - */ - protected abstract void allAnimationsFinished (boolean puzStillValid); - - /** The initial round id. */ - protected int _roundId; - - /** The puzzle object that the animations we're observering want to - * modify. */ - protected PuzzleObject _puzobj; -} diff --git a/src/java/com/threerings/puzzle/client/PuzzleBoardView.java b/src/java/com/threerings/puzzle/client/PuzzleBoardView.java deleted file mode 100644 index 4f40baa81..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzleBoardView.java +++ /dev/null @@ -1,420 +0,0 @@ -// -// $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.puzzle.client; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.util.ArrayList; - -import javax.swing.UIManager; - -import com.samskivert.swing.Label; -import com.samskivert.swing.util.SwingUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.media.VirtualMediaPanel; -import com.threerings.media.animation.Animation; -import com.threerings.media.animation.AnimationAdapter; -import com.threerings.media.animation.AnimationArranger; -import com.threerings.media.image.Mirage; -import com.threerings.media.sprite.Sprite; - -import com.threerings.parlor.media.ScoreAnimation; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.util.PuzzleContext; - -/** - * The puzzle board view displays a view of a puzzle game. - */ -public abstract class PuzzleBoardView extends VirtualMediaPanel -{ - /** - * Constructs a puzzle board view. - */ - public PuzzleBoardView (PuzzleContext ctx) - { - super(ctx.getFrameManager()); - - // keep this for later - _ctx = ctx; - } - - /** - * Initializes the board with the board dimensions. - */ - public void init (PuzzleConfig config) - { - // save off our bounds - Dimension bounds = getPreferredSize(); - _bounds = new Rectangle(0, 0, bounds.width, bounds.height); - } - - /** - * Sets the board to be displayed. - */ - public void setBoard (Board board) - { - _board = board; - } - - /** - * Provides the board view with a reference to its controller so that - * it may communicate directly rather than by posting actions up the - * interface hierarchy which sometimes fails if the puzzle board view - * is hidden before we get a chance to post our actions. - */ - public void setController (PuzzleController pctrl) - { - _pctrl = pctrl; - } - - /** - * Sets the background image displayed by the board view. - */ - public void setBackgroundImage (Mirage image) - { - _background = image; - } - - /** - * Set whether this puzzle is paused or not. - * If paused, a label will be displayed with the component's font, - * which may be set with setFont(). - */ - public void setPaused (boolean paused) - { - if (paused) { - String pmsg = _pctrl.getPauseString(); - pmsg = _ctx.getMessageManager().getBundle( - PuzzleCodes.PUZZLE_MESSAGE_BUNDLE).xlate(pmsg); - // create a label using our component's standard font - _pauseLabel = new Label(pmsg, Label.BOLD | Label.OUTLINE, - Color.WHITE, Color.BLACK, - getFont()); - _pauseLabel.setTargetWidth(_bounds.width); - _pauseLabel.layout(this); - } else { - _pauseLabel = null; - } - repaint(); - } - - /** - * Adds the given animation to the set of animations currently present - * on the board. The animation will be added to a list of action - * animations whose count can be queried with {@link - * #getActionAnimationCount}. The animation will automatically be - * removed from the action list when it completes. - */ - public void addActionAnimation (Animation anim) - { - super.addAnimation(anim); - - // remember the animation's existence - _actionAnims.add(anim); - - // and listen for it to finish so that we can clear it out - anim.addAnimationObserver(_actionAnimObs); - } - - // documentation inherited - public void abortAnimation (Animation anim) - { - super.abortAnimation(anim); - - // always check to see if it was action-y - animationFinished(anim); - } - - /** - * Called when a potential action animation is finished. - */ - protected void animationFinished (Animation anim) - { - if (DEBUG_ACTION) { - Log.info("Animation cleared " + StringUtil.shortClassName(anim) + - ":" + _actionAnims.contains(anim)); - } - - // if it WAS an action animation, check for a clear - if (_actionAnims.remove(anim)) { - maybeFireCleared(); - } - } - - /** - * Adds the given sprite to the set of sprites currently present on - * the board. The sprite will be added to a list of action sprites - * whose count can be queried with {@link #getActionSpriteCount}. Callers - * should be sure to remove the sprite when their work with it is done - * via {@link #removeSprite}. - */ - public void addActionSprite (Sprite sprite) - { - // add the piece to the sprite manager - addSprite(sprite); - - // note that this piece is interesting - _actionSprites.add(sprite); - } - - /** - * Removes the given sprite from the board. - */ - public void removeSprite (Sprite sprite) - { - super.removeSprite(sprite); - - if (DEBUG_ACTION) { - Log.info("Sprite cleared " + StringUtil.shortClassName(sprite) + - ":" + _actionSprites.contains(sprite)); - } - - // we just always check to see if it was action-y - if (_actionSprites.remove(sprite)) { - maybeFireCleared(); - } - } - - // documentation inherited - public void clearSprites () - { - super.clearSprites(); - _actionSprites.clear(); - } - - // documentation inherited - public void clearAnimations () - { - super.clearAnimations(); - _actionAnims.clear(); - } - - /** - * Returns the number of action animations on the board. - */ - public int getActionAnimationCount () - { - return _actionAnims.size(); - } - - /** - * Returns the number of action sprites on the board. - */ - public int getActionSpriteCount () - { - return _actionSprites.size(); - } - - /** - * Returns the count of action sprites and animations on the board. - */ - public int getActionCount () - { - return _actionSprites.size() + _actionAnims.size(); - } - - /** - * Dumps to the logs, a list of interesting sprites and animations - * currently active on the puzzle board. - */ - public void dumpActors () - { - StringUtil.Formatter fmt = new StringUtil.Formatter() { - public String toString (Object obj) { - return StringUtil.shortClassName(obj); - } - }; - Log.info("Board contents [board=" + StringUtil.shortClassName(this) + - ", sprites=" + StringUtil.listToString(_actionSprites, fmt) + - ", anims=" + StringUtil.listToString(_actionAnims, fmt) + - "]."); - } - - /** - * Creates and returns an animation displaying the given string with - * the specified parameters, floating it a short distance up the view. - * - * @param score the score text to display. - * @param color the color of the text. - * @param font the font whith which to create the score animation. - * @param x the x-position at which the score is to be placed. - * @param y the y-position at which the score is to be placed. - */ - public ScoreAnimation createScoreAnimation ( - String score, Color color, Font font, int x, int y) - { - return createScoreAnimation( - ScoreAnimation.createLabel(score, color, font, this), x, y); - } - - /** - * Creates a score animation, allowing derived classes to use custom - * animations that are customized following a call to - * {@link #createScoreAnimation}. - */ - protected ScoreAnimation createScoreAnimation (Label label, int x, int y) - { - return new ScoreAnimation(label, x, y); - } - - /** - * Positions the supplied animation so as to avoid any active - * animations previously registered with this method, and adds the - * animation to the list of animations to be avoided by any future - * avoid animations. - */ - public void trackAvoidAnimation (Animation anim) - { - // lazy init the arranger - if (_avoidArranger == null) { - _avoidArranger = new AnimationArranger(); - } - _avoidArranger.positionAvoidAnimation(anim, _vbounds); - } - - // documentation inherited - public void paintBehind (Graphics2D gfx, Rectangle dirty) - { - super.paintBehind(gfx, dirty); - - // render the background - renderBackground(gfx, dirty); - } - - /** - * Fills the background of the board with the background color. - */ - protected void renderBackground (Graphics2D gfx, Rectangle dirty) - { - gfx.setColor(getBackground()); - gfx.fill(dirty); - } - - // documentation inherited - public void paintBetween (Graphics2D gfx, Rectangle dirty) - { - super.paintBetween(gfx, dirty); -// PerformanceMonitor.tick(this, "paint"); - renderBoard(gfx, dirty); - } - - // documentation inherited - protected void paintInFront (Graphics2D gfx, Rectangle dirty) - { - super.paintInFront(gfx, dirty); - - // if the action is paused, indicate as much - if (_pauseLabel != null) { - Dimension d = _pauseLabel.getSize(); - _pauseLabel.render(gfx, - _vbounds.x + (_vbounds.width - d.width) / 2, - _vbounds.y + (_vbounds.height - d.height) / 2); - } - } - - /** - * Fires a {@link #ACTION_CLEARED} command iff we have no remaining - * interesting sprites or animations. - */ - protected void maybeFireCleared () - { - if (DEBUG_ACTION) { - Log.info("Maybe firing cleared " + - getActionCount() + ":" + isShowing()); - } - if (getActionCount() == 0) { - // we're probably in the middle of a tick() in an - // animationDidFinish() call and we want everyone to finish - // processing their business before we go clearing the action, - // so we queue this up to be run after the tick is complete - _ctx.getClient().getRunQueue().postRunnable(new Runnable() { - public void run () { - _pctrl.boardActionCleared(); - } - }); - } - } - - /** - * Renders the board contents to the given graphics context. - * Sub-classes should implement this method to draw all of their - * game-specific business. - */ - protected abstract void renderBoard (Graphics2D gfx, Rectangle dirty); - - /** Our client context. */ - protected PuzzleContext _ctx; - - /** Our puzzle controller. */ - protected PuzzleController _pctrl; - - /** The board data to be displayed. */ - protected Board _board; - - /** The board's bounding rectangle. */ - protected Rectangle _bounds; - - /** The action animations on the board. */ - protected ArrayList _actionAnims = new ArrayList(); - - /** The action sprites on the board. */ - protected ArrayList _actionSprites = new ArrayList(); - - /** Prevents certain animations from overlapping others. */ - protected AnimationArranger _avoidArranger; - - /** Our background image. */ - protected Mirage _background; - - /** A label to show when the puzzle is paused. */ - protected Label _pauseLabel; - - /** The distance in pixels that score animations float. */ - protected int _scoreDist = DEFAULT_SCORE_DISTANCE; - - /** Listens to our action animations and clears them when they're done. */ - protected AnimationAdapter _actionAnimObs = new AnimationAdapter() { - public void animationCompleted (Animation anim, long when) { - animationFinished(anim); - } - }; - - /** Temporary action debugging. */ - protected static boolean DEBUG_ACTION = false; - - // action state constants - protected static final int ACTION_GOING = 0; - protected static final int CLEAR_PENDING = 1; - protected static final int ACTION_CLEARED = 2; - - /** The default vertical distance to float score animations. */ - protected static final int DEFAULT_SCORE_DISTANCE = 30; -} diff --git a/src/java/com/threerings/puzzle/client/PuzzleController.java b/src/java/com/threerings/puzzle/client/PuzzleController.java deleted file mode 100644 index 05a60019f..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzleController.java +++ /dev/null @@ -1,978 +0,0 @@ -// -// $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.puzzle.client; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.KeyAdapter; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - -import java.util.ArrayList; - -import com.samskivert.swing.util.MouseHijacker; - -import com.samskivert.util.CollectionUtil; -import com.samskivert.util.ObserverList; -import com.samskivert.util.StringUtil; - -import com.threerings.media.FrameParticipant; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.ElementUpdateListener; -import com.threerings.presents.dobj.ElementUpdatedEvent; - -import com.threerings.crowd.client.PlaceControllerDelegate; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.game.client.GameController; -import com.threerings.parlor.game.data.GameObject; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.data.PuzzleObject; -import com.threerings.puzzle.util.PuzzleContext; - -/** - * The puzzle game controller handles logical actions for a puzzle game. - */ -public abstract class PuzzleController extends GameController - implements PuzzleCodes -{ - /** The action command to toggle chatting mode. */ - public static final String TOGGLE_CHATTING = "toggle_chat"; - - /** Used by {@link PuzzleController#fireWhenActionCleared}. */ - public static interface ClearPender - { - /** {@link #actionCleared} return code. */ - public static final int RESTART_ACTION = -1; - - /** {@link #actionCleared} return code. */ - public static final int CARE_NOT = 0; - - /** {@link #actionCleared} return code. */ - public static final int NO_RESTART_ACTION = 1; - - /** - * Called when the action is fully cleared. - * - * @return One of {@link #RESTART_ACTION}, {@link #CARE_NOT} or - * {@link #NO_RESTART_ACTION}. - */ - public int actionCleared (); - } - - // documentation inherited - protected void didInit () - { - super.didInit(); - - _panel = (PuzzlePanel)_view; - _pctx = (PuzzleContext)_ctx; - - // initialize the puzzle panel - _puzconfig = (PuzzleConfig)_config; - _panel.init(_puzconfig); - - // initialize the board view - _pview = _panel.getBoardView(); - _pview.setController(this); - } - - /** - * Creates and returns a new board model. - */ - protected abstract Board newBoard (); - - /** - * Returns the board associated with the puzzle. - */ - public Board getBoard () - { - return _pboard; - } - - /** - * Returns the player's index in the list of players for the game. - */ - public int getPlayerIndex () - { - return _pidx; - } - - // documentation inherited - public void setGameOver (boolean gameOver) - { - super.setGameOver(gameOver); - - // clear the action if we're informed that the game is over early - // by the client - if (gameOver) { - clearAction(); - } - } - - /** - * Returns true if the puzzle has action, false if the action is - * cleared or it is suspended. - */ - public boolean hasAction () - { - return (_astate == ACTION_GOING); - } - - /** - * Sets whether we're focusing on the chat window rather than the puzzle. - */ - public void setChatting (boolean chatting) - { - // ignore the request if we're already there - if ((isChatting() == chatting) || - // ..or if we want to initiate chatting and.. - // we either can't right now or we don't have action - (chatting && (!canStartChatting() || !hasAction()))) { - return; - } - - // update the panel - _panel.setPuzzleGrabsKeys(!chatting); - - // if we're moving focus to chat.. - if (chatting) { - if (_unpauser != null) { - Log.warning("Huh? Already have a mouse unpauser?"); - _unpauser.release(); - } - _unpauser = new Unpauser(_panel); - - } else { - if (_unpauser != null) { - _unpauser.release(); - _unpauser = null; - } - } - - // update the chatting state - _chatting = chatting; - - // dispatch the change to our delegates - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((PuzzleControllerDelegate)delegate).setChatting(_chatting); - } - }); - - // and check if we should be suspending the action during this pause - if (supportsActionPause()) { - // clear the action if we're pausing, resume it if we're - // unpausing - if (chatting) { - clearAction(); - } else { - safeStartAction(); - } - _pview.setPaused(chatting); - } - } - - /** - * Get the (untranslated) string to display when the puzzle is paused. - */ - public String getPauseString () - { - return "m.paused"; - } - - /** - * Derived classes should override this and return false if their - * action should not be paused when the user switches control to the - * chat area. - */ - protected boolean supportsActionPause () - { - return true; - } - - /** - * Can we start chatting at this juncture? - */ - protected boolean canStartChatting () - { - // check with the delegates - final boolean[] canChatNow = new boolean[] { true }; - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - canChatNow[0] = - ((PuzzleControllerDelegate)delegate).canStartChatting() && - canChatNow[0]; - } - }); - return canChatNow[0]; - } - - /** - * Returns true if the puzzle has been defocused because the player - * is doing some chatting. - */ - public boolean isChatting () - { - return _chatting; - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - // get a casted reference to our puzzle object - _puzobj = (PuzzleObject)plobj; - _puzobj.addListener(_kolist); - _puzobj.addListener(_mlist); - - // listen to key events.. - _pctx.getKeyDispatcher().addGlobalKeyListener(_globalKeyListener); - - // save off our player index - _pidx = _puzobj.getPlayerIndex(_pctx.getUsername()); - - // generate the starting board - generateNewBoard(); - - // if the game is already in play, start up the action - if (_puzobj.isInPlay() && _puzobj.isActivePlayer(_pidx)) { - startAction(); - } - } - - // documentation inherited - public void mayLeavePlace (PlaceObject plobj) - { - super.mayLeavePlace(plobj); - - // flush any pending progress events - sendProgressUpdate(); - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - super.didLeavePlace(plobj); - - // clean up and clear out - clearAction(); - - // stop listening to key events.. - _pctx.getKeyDispatcher().removeGlobalKeyListener(_globalKeyListener); - - // clear out the puzzle object - if (_puzobj != null) { - _puzobj.removeListener(_mlist); - _puzobj.removeListener(_kolist); - _puzobj = null; - } - } - - /** - * Puzzles that do not have "action" that starts and stops (via {@link - * #startAction} and {@link #clearAction}) when the puzzle starts and - * stops can override this method and return false. - */ - protected boolean isActionPuzzle () - { - return true; - } - - /** - * Indicates whether the action should start immediately as a result - * of {@link #gameDidStart} being called. If a puzzle wishes to do - * some beginning of the game fun stuff, like display a tutorial - * screen, they can veto the action start and then start it themselves - * later. - */ - protected boolean startActionImmediately () - { - return true; - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - String name = event.getName(); - - // deal with game state changes - if (name.equals(PuzzleObject.STATE)) { - switch (event.getIntValue()) { - case PuzzleObject.IN_PLAY: - // we have to postpone all game starting activity until the - // current action has ended; only after all the animations have - // been completed will everything be in a state fit for - // starting back up again - fireWhenActionCleared(new ClearPender() { - public int actionCleared () { - // do the standard game did start business - gameDidStart(); - // we don't always start the action immediately - return startActionImmediately() ? - RESTART_ACTION : NO_RESTART_ACTION; - } - }); - break; - - case PuzzleObject.GAME_OVER: - // similarly we haev to postpone game ending activity until - // the current action has ended - // clean up and clear out - clearAction(); - // wait until the action is cleared before we roll down to our - // delegates and do all that business - fireWhenActionCleared(new ClearPender() { - public int actionCleared () { - gameDidEnd(); - return CARE_NOT; - } - }); - break; - - default: - super.attributeChanged(event); - break; - } - - } else if (name.equals(PuzzleObject.ROUND_ID)) { - // Need to clear out stale events. If we don't, we could send - // events that claim to be from the new round that are actually - // from the old round. - _events.clear(); - } - } - - // documentation inherited - protected void gameWillReset () - { - super.gameWillReset(); - - // stop the old action - clearAction(); - - // when the server gets around to resetting the game, we'll get a - // 'state => IN_PLAY' message which will result in gameDidStart() - // being called and starting the action back up - } - - /** - * Called when a new board is set. - */ - public void setBoard (Board board) - { - // we don't need to do anything by default - } - - /** - * Derived classes should override this method and do whatever is - * necessary to start up the action for their puzzle. This could be - * called when the user is already in the "room" and the game starts, - * or immediately upon entering the room if the game is already - * started (for example if they disconnected and reconnected to a game - * already in progress). - */ - protected void startAction () - { - // do nothing if we're not an action puzzle - if (!isActionPuzzle()) { - return; - } - - // refuse to start the action if our puzzle view is hidden - if (_pidx != -1 && !_panel.getBoardView().isShowing()) { - Log.warning("Refusing to start action on hidden puzzle."); - Thread.dumpStack(); - return; - } - - // refuse to start the action if it's already going - if (_astate != ACTION_CLEARED) { - Log.warning("Action state inappropriate for startAction() " + - "[astate=" + _astate + "]."); - Thread.dumpStack(); - return; - } - - if (isChatting() && supportsActionPause()) { - Log.info("Not starting action, player is chatting in a puzzle " + - "that supports pausing the action."); - return; - } - - Log.debug("Starting puzzle action."); - - // register the game progress updater; it may already be updated - // because we can cycle through clearing the action and starting - // it again before the updater gets a chance to unregister itself - if (!_pctx.getFrameManager().isRegisteredFrameParticipant(_updater)) { - _pctx.getFrameManager().registerFrameParticipant(_updater); - } - - // make a note that we've started the action - _astate = ACTION_GOING; - - // let our panel know what's up - _panel.startAction(); - - // and if we're not currently chatting, set the puzzle to grab - // keys and for the chatbox to look disabled - if (!isChatting()) { - _panel.setPuzzleGrabsKeys(true); - } - - // let our delegates do their business - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((PuzzleControllerDelegate)delegate).startAction(); - } - }); - } - - /** - * If it is not known whether the puzzle board view has finished - * animating its final bits after a previous call to {@link - * #clearAction}, this method should be used instead of {@link - * #startAction} as it will wait until the action is confirmedly over - * before starting it anew. - */ - protected void safeStartAction () - { - // do nothing if we're not an action puzzle - if (!isActionPuzzle()) { - return; - } - - fireWhenActionCleared(new ClearPender() { - public int actionCleared () { - return RESTART_ACTION; - } - }); - } - - /** - * Called when the game has ended or when it is going to reset and - * when the client leaves the game "room". This method does not always - * immediately clear the action, but may mark the clear as pending if - * the action cannot yet be cleared (as indicated by {@link - * #canClearAction}). The action will eventually be cleared which will - * result in a call to {@link #actuallyClearAction} which is what - * derived classes should override to do their action clearing - * business. - */ - protected void clearAction () - { - // do nothing if we're not an action puzzle - if (!isActionPuzzle()) { - return; - } - - // no need to clear if we're already cleared or clearing - if (_astate == CLEAR_PENDING || _astate == ACTION_CLEARED) { - return; - } - - Log.debug("Attempting to clear puzzle action."); - - // put ourselves into a pending clear state and attempt to clear - // the action - _astate = CLEAR_PENDING; - maybeClearAction(); - } - - /** - * This method is called by the {@link PuzzleBoardView} when all - * action on the board has finished. - */ - protected void boardActionCleared () - { - // if we have a clear pending, this could be the trigger that - // allows us to clear our action - maybeClearAction(); - } - - /** - * Queues up code to be invoked when the action is completely cleared - * (including all remaining interesting sprites and animations on the - * puzzle board). - */ - protected void fireWhenActionCleared (ClearPender pender) - { - // if the action is already ended, fire this pender immediately - if (_astate == ACTION_CLEARED) { - if (pender.actionCleared() == ClearPender.RESTART_ACTION) { - Log.debug("Restarting action at behest of pender " + - pender + "."); - startAction(); - } - - } else { - Log.debug("Queueing action pender " + pender + "."); - _clearPenders.add(pender); - } - } - - /** - * Returns whether or not it is safe to clear the action. The default - * behavior is to not allow the action to be cleared until all - * interesting sprites and animations in the board view have finished. - * If derived classes or delegates wish to postpone the clearing of - * the action, they can return false from this method, but they must - * then be sure to call {@link #maybeClearAction} when whatever - * condition that caused them to desire to postpone action clearing - * has finally been satisfied. - */ - protected boolean canClearAction () - { - final boolean[] canClear = new boolean[1]; - canClear[0] = (_pview.getActionCount() == 0); -// if (!canClear[0]) { -// _pview.dumpActors(); -// PuzzleBoardView.DEBUG_ACTION = true; -// } - - // let our delegates do their business - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - canClear[0] = canClear[0] && - ((PuzzleControllerDelegate)delegate).canClearAction(); - } - }); - - return canClear[0]; - } - - /** - * Called to effect the actual clearing of our action if we've - * received some asynchronous trigger that indicates that it may well - * be safe now to clear the action. - */ - protected void maybeClearAction () - { - if (_astate == CLEAR_PENDING && canClearAction()) { - actuallyClearAction(); -// } else { -// Log.info("Not clearing action [astate=" + _astate + -// ", canClear=" + canClearAction() + "]."); - } - } - - /** - * Performs the actual process of clearing the action for this puzzle. - * This is only called after it is known to be safe to clear the - * action. Derived classes can override this method and clear out - * anything that is not needed while the puzzle's "action" is not - * going (timers, etc.). Anything that is cleared out here should be - * recreated in {@link #startAction}. - */ - protected void actuallyClearAction () - { - Log.debug("Actually clearing action."); - - // make a note that we've cleared the action - _astate = ACTION_CLEARED; -// PuzzleBoardView.DEBUG_ACTION = false; - - // let our delegates do their business - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((PuzzleControllerDelegate)delegate).clearAction(); - } - }); - - // let our panel know what's up - _panel.clearAction(); - _panel.setPuzzleGrabsKeys(false); // let the user chat - - // deliver one final update to the server - sendProgressUpdate(); - - // let derived classes do things - try { - actionWasCleared(); - } catch (Exception e) { - Log.warning("Choked in actionWasCleared"); - Log.logStackTrace(e); - } - - // notify any penders that the action has cleared - final int[] results = new int[2]; - _clearPenders.apply(new ObserverList.ObserverOp() { - public boolean apply (Object observer) { - switch (((ClearPender)observer).actionCleared()) { - case ClearPender.RESTART_ACTION: results[0]++; break; - case ClearPender.NO_RESTART_ACTION: results[1]++; break; - } - return true; - } - }); - _clearPenders.clear(); - - // if there are no refusals and at least one restart request, go - // ahead and restart the action now - if (results[1] == 0 && results[0] > 0) { - startAction(); - } - } - - /** - * Called when the action was actually cleared, but before the action - * obsevers are notified. - */ - protected void actionWasCleared () - { - } - - // documentation inherited - public boolean handleAction (ActionEvent action) - { - String cmd = action.getActionCommand(); - if (cmd.equals(TOGGLE_CHATTING)) { - setChatting(!isChatting()); - - } else { - return super.handleAction(action); - } - - return true; - } - - /** - * Returns the delay in milliseconds between sending each progress - * update event to the server. Derived classes may wish to override - * this to send their progress updates more or less frequently than - * the default. - */ - protected long getProgressInterval () - { - return DEFAULT_PROGRESS_INTERVAL; - } - - /** - * Signal the game to generate and distribute a new board. - */ - protected void generateNewBoard () - { - // wait for any animations or sprites in the board to finish their - // business before setting the board into place - fireWhenActionCleared(new ClearPender() { - public int actionCleared () { - // update the player board - _pboard = newBoard(); - if (_puzobj.seed != 0) { - _pboard.initializeSeed(_puzobj.seed); - } - setBoard(_pboard); - _pview.setBoard(_pboard); - - // and repaint things - _pview.repaint(); - - // let our delegates do their business - DelegateOp dop = new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((PuzzleControllerDelegate)delegate).setBoard(_pboard); - } - }; - applyToDelegates(PuzzleControllerDelegate.class, dop); - - return CARE_NOT; - } - }); - } - - /** - * Returns the number of progress events currently queued up for - * sending to the server with the next progress update. - */ - public int getEventCount () - { - return _events.size(); - } - - /** - * Are we syncing boards for this puzzle? - * By default, we defer to the PuzzlePanel and its runtime config. - */ - protected boolean isSyncingBoards () - { - return PuzzlePanel.isSyncingBoards(); - } - - /** - * Adds the given progress event and a snapshot of the supplied board - * state to the set of progress events and associated board states for - * later transmission to the server. - */ - public void addProgressEvent (int event, Board board) - { - // make sure they don't queue things up at strange times - if (_puzobj.state != PuzzleObject.IN_PLAY) { - Log.warning("Rejecting progress event; game not in play " + - "[puzobj=" + _puzobj.which() + - ", event=" + event + "]."); - return; - } - - _events.add(Integer.valueOf(event)); - if (isSyncingBoards()) { - _states.add((board == null) ? null : board.clone()); - if (board == null) { - Log.warning("Added progress event with no associated board " + - "state, server will not be able to ensure " + - "board state synchronization."); - } - } - } - - /** - * Sends the server a game progress update with the list of events, as - * well as board states if {@link PuzzlePanel#isSyncingBoards} is true. - */ - public void sendProgressUpdate () - { - // make sure we have our puzzle object and events to send - int size = _events.size(); - if (size == 0 || _puzobj == null) { - return; - } - - // create an array of the events we're sending to the server - int[] events = CollectionUtil.toIntArray(_events); - _events.clear(); - -// Log.info("Sending progress [round=" + _puzobj.roundId + -// ", events=" + StringUtil.toString(events) + "]."); - - // create an array of the board states that correspond with those - // events (if state syncing is enabled) - int numStates = _states.size(); - if (numStates == size) { // ie, if we have a board to match every event - Board[] states = new Board[numStates]; - _states.toArray(states); - _states.clear(); - - // send the update progress request - _puzobj.puzzleGameService.updateProgressSync( - _ctx.getClient(), _puzobj.roundId, events, states); - - } else { - // send the update progress request - _puzobj.puzzleGameService.updateProgress( - _ctx.getClient(), _puzobj.roundId, events); - } - } - - /** - * Called when a player is knocked out of the game to give the puzzle - * a chance to perform any post-knockout actions that may be desired. - * Derived classes may wish to override this method but should be sure - * to call super.playerKnockedOut(). - */ - protected void playerKnockedOut (final int pidx) - { - // dispatch this to our delegates - applyToDelegates(PuzzleControllerDelegate.class, new DelegateOp() { - public void apply (PlaceControllerDelegate delegate) { - ((PuzzleControllerDelegate)delegate).playerKnockedOut(pidx); - } - }); - } - - /** - * Catches clicks an unpauses, without passing the click through - * to the puzzle. - */ - class Unpauser extends MouseHijacker - { - public Unpauser (PuzzlePanel panel) - { - super(panel.getBoardView()); - _panel = panel; - panel.addMouseListener(_clicker); - panel.getBoardView().addMouseListener(_clicker); - } - - public Component release () - { - _panel.removeMouseListener(_clicker); - _panel.getBoardView().removeMouseListener(_clicker); - return super.release(); - } - - protected MouseAdapter _clicker = new MouseAdapter() { - public void mousePressed (MouseEvent event) { - setChatting(false); // this will call release - } - }; - - protected PuzzlePanel _panel; - } - - /** A special frame participant that handles the sending of puzzle - * progress updates. We can't just - * register an interval for this because sometimes the clock goes - * backwards in time in windows and our intervals don't get called for - * a long period of time which causes the server to think the client - * is disconnected or cheating and resign them from the puzzle. God - * bless you, Microsoft. */ - protected class Updater implements FrameParticipant - { - public void tick (long tickStamp) { - if (_astate == ACTION_CLEARED) { - // remove ourselves as the action is now cleared; we can't - // do this in actuallyClearAction() because that might get - // called during the PuzzlePanel's frame tick and it's - // only safe to remove yourself during a tick(), not - // another frame participant - _pctx.getFrameManager().removeFrameParticipant(_updater); - - } else if (tickStamp - _lastProgressTick > getProgressInterval()) { - _lastProgressTick = tickStamp; - sendProgressUpdate(); - } - } - - public boolean needsPaint () { - return false; - } - - public Component getComponent () { - return null; - } - - public long _lastProgressTick; - } - - /** - * Create the updater to be used in this puzzle. - */ - protected Updater createUpdater () - { - return new Updater(); - } - - /** The mouse jockey for unpausing our puzzles. */ - protected Unpauser _unpauser; - - /** Handles the sending of puzzle progress updates. */ - protected Updater _updater = createUpdater(); - - /** Listens for players being knocked out. */ - protected ElementUpdateListener _kolist = new ElementUpdateListener() { - public void elementUpdated (ElementUpdatedEvent event) { - String name = event.getName(); - if (name.equals(PuzzleObject.PLAYER_STATUS)) { - if (event.getIntValue() == GameObject.PLAYER_LEFT_GAME) { - playerKnockedOut(event.getIndex()); - } - } - } - }; - - /** Listens for various attribute changes. */ - protected AttributeChangeListener _mlist = new AttributeChangeListener() { - public void attributeChanged (AttributeChangedEvent event) { - String name = event.getName(); - if (name.equals(PuzzleObject.SEED)) { - generateNewBoard(); - } - } - }; - - /** A casted reference to the client context. */ - protected PuzzleContext _pctx; - - /** Our player index in the game. */ - protected int _pidx; - - /** The puzzle panel. */ - protected PuzzlePanel _panel; - - /** The puzzle config. */ - protected PuzzleConfig _puzconfig; - - /** A reference to our puzzle game object. */ - protected PuzzleObject _puzobj; - - /** The puzzle board view. */ - protected PuzzleBoardView _pview; - - /** The puzzle board data. */ - protected Board _pboard; - - /** The list of relevant game events since the last progress update. */ - protected ArrayList _events = new ArrayList(); - - /** Board snapshots that correspond to our board state after each of - * our events has been applied. */ - protected ArrayList _states = new ArrayList(); - - /** A flag indicating that we're in chatting mode. */ - protected boolean _chatting = false; - - /** The current action state of the puzzle. */ - protected int _astate = ACTION_CLEARED; - - /** The action cleared penders. */ - protected ObserverList _clearPenders = new ObserverList( - ObserverList.SAFE_IN_ORDER_NOTIFY); - - /** A key listener that currently just toggles pause in the puzzle. */ - protected KeyListener _globalKeyListener = new KeyAdapter() { - public void keyReleased (KeyEvent e) - { - int keycode = e.getKeyCode(); - // toggle chatting (pause) - if (keycode == KeyEvent.VK_ESCAPE || keycode == KeyEvent.VK_PAUSE) { - setChatting(!isChatting()); - - // pressing P also to pause (but not unpause), - // and only if it has not been reassigned - } else if (keycode == KeyEvent.VK_P && !isChatting() && - !_panel._xlate.hasCommand(KeyEvent.VK_P)) { - setChatting(true); - } - } - }; - - /** The delay in milliseconds between progress update intervals. */ - protected static final long DEFAULT_PROGRESS_INTERVAL = 6000L; - - /** A {@link #_astate} constant. */ - protected static final int ACTION_CLEARED = 0; - - /** A {@link #_astate} constant. */ - protected static final int CLEAR_PENDING = 1; - - /** A {@link #_astate} constant. */ - protected static final int ACTION_GOING = 2; -} diff --git a/src/java/com/threerings/puzzle/client/PuzzleControllerDelegate.java b/src/java/com/threerings/puzzle/client/PuzzleControllerDelegate.java deleted file mode 100644 index 54f462762..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzleControllerDelegate.java +++ /dev/null @@ -1,153 +0,0 @@ -// -// $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.puzzle.client; - -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.parlor.game.client.GameControllerDelegate; - -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.data.PuzzleGameCodes; -import com.threerings.puzzle.data.PuzzleObject; - -/** - * A base class for puzzle controller delegates. Provides access to some - * delegated puzzle controller methods ({@link #startAction}, {@link - * #clearAction}, etc.) and provides a casted reference to the puzzle - * object. - */ -public class PuzzleControllerDelegate extends GameControllerDelegate - implements PuzzleCodes, PuzzleGameCodes -{ - /** - * Constructs a puzzle controller delegate. - */ - public PuzzleControllerDelegate (PuzzleController ctrl) - { - super(ctrl); - - // keep around a casted reference to our controller - _ctrl = ctrl; - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - // get a casted reference to our game object - _puzobj = (PuzzleObject)plobj; - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - super.didLeavePlace(plobj); - - _puzobj = null; - } - - /** - * Called when a player is knocked out of the game. - */ - public void playerKnockedOut (int pidx) - { - } - - /** - * Called when the user toggles chatting mode. - */ - public void setChatting (boolean chatting) - { - } - - /** - * Can we start chatting at the instant that this method is called? - */ - protected boolean canStartChatting () - { - return true; - } - - /** - * Derived classes should override this method and do whatever is - * necessary to start up the action for their puzzle. This could be - * called when the user is already in the "room" and the game starts, - * or immediately upon entering the room if the game is already - * started (for example if they disconnected and reconnected to a game - * already in progress). - */ - protected void startAction () - { - } - - /** - * Delegates that wish to postpone action clearing can override this - * method to return false until such time as the action can be - * cleared. They must, however, call {@link #maybeClearAction} when - * conditions become such that they would once again allow action to - * be cleared. - */ - protected boolean canClearAction () - { - return true; - } - - /** - * Calls {@link PuzzleController#maybeClearAction}, preserving its - * protected access but making the method available to all - * PuzzleControllerDelegate derivations. - */ - protected void maybeClearAction () - { - _ctrl.maybeClearAction(); - } - - /** - * Puzzles should override this method and clear out any action on the - * board and generally clean up anything that was going on because the - * game was in play. This is called when the game has ended or when it - * is going to reset and when the client leaves the game "room". - * Anything that is cleared out here should be recreated in {@link - * #startAction}. - */ - protected void clearAction () - { - } - - /** - * Called when the puzzle controller sets up a new board for the - * player. - * - * @param board the newly initialized and ready-to-go board. - */ - public void setBoard (Board board) - { - } - - /** Our puzzle controller. */ - protected PuzzleController _ctrl; - - /** The puzzle distributed object. */ - protected PuzzleObject _puzobj; -} diff --git a/src/java/com/threerings/puzzle/client/PuzzleGameService.java b/src/java/com/threerings/puzzle/client/PuzzleGameService.java deleted file mode 100644 index 4f8a6ce6e..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzleGameService.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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.puzzle.client; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleCodes; - -/** - * Provides services used by puzzle game clients to request that actions - * be taken by the puzzle manager. - */ -public interface PuzzleGameService extends InvocationService, PuzzleCodes -{ - /** - * Asks the puzzle manager to apply the supplied progress events for - * the specified puzzle round to the player's state. - */ - public void updateProgress (Client client, int roundId, int[] events); - - /** - * Debug variant of {@link #updateProgress} that is only used when - * {@link PuzzlePanel#isSyncingBoards} is true and which includes the - * board states associated with each event. - */ - public void updateProgressSync ( - Client client, int roundId, int[] events, Board[] states); -} diff --git a/src/java/com/threerings/puzzle/client/PuzzlePanel.java b/src/java/com/threerings/puzzle/client/PuzzlePanel.java deleted file mode 100644 index 6764a009c..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzlePanel.java +++ /dev/null @@ -1,318 +0,0 @@ -// -// $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.puzzle.client; - -import java.awt.BorderLayout; -import javax.swing.JPanel; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.ControllerProvider; -import com.samskivert.swing.RuntimeAdjust; -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.util.KeyTranslator; -import com.threerings.util.RobotPlayer; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.data.PuzzleGameCodes; -import com.threerings.puzzle.util.PuzzleContext; - -/** - * The puzzle panel class should be extended by classes that provide a - * view for a puzzle game. The {@link PuzzleController} calls these - * methods as necessary to perform its duties in managing the logical - * actions of a puzzle game. - */ -public abstract class PuzzlePanel extends JPanel - implements PlaceView, ControllerProvider, PuzzleCodes, PuzzleGameCodes -{ - /** - * Constructs a puzzle panel. - */ - public PuzzlePanel (PuzzleContext ctx, PuzzleController controller) - { - _ctx = ctx; - _controller = controller; - - // set up the keyboard manager - _xlate = getKeyTranslator(); - _ctx.getKeyboardManager().setTarget(this, _xlate); - - // configure the puzzle panel - setLayout(new BorderLayout()); - - // create the puzzle board view - _bview = createBoardView(ctx); - - // create the puzzle board panel - _bpanel = createBoardPanel(ctx); - - // add the board panel - add(_bpanel, BorderLayout.CENTER); - } - - // documentation inherited - public void addNotify () - { - super.addNotify(); - - // leave the keyboard manager disabled to start, and set things up - // for chatting - setPuzzleGrabsKeys(false); - } - - // documentation inherited - public void removeNotify () - { - super.removeNotify(); - - // don't ever leave with the keys grabbed - setPuzzleGrabsKeys(false); - } - - /** - * Temporarily replaces the puzzle board display with the supplied - * overlay panel. The panel can be removed and the board display - * restored by calling {@link #popOverlayPanel}. - * - * @return true if the specified panel will be displayed, false if it - * was not able to be pushed because another overlay panel is already - * pushed onto the primary panel. - */ - public boolean pushOverlayPanel (JPanel opanel) - { - // bail if we've already got an overlay - if (_opanel != null) { - Log.info("Refusing to push overlay panel, we've already got one " + - "[opanel=" + _opanel + ", npanel=" + opanel + "]."); - return false; - } - - // swap in the overlay panel - _opanel = opanel; - remove(_bpanel); - add(_opanel); - - // make sure the UI updates - SwingUtil.refresh(this); - - return true; - } - - /** - * Pops the overlay panel off of the main puzzle board display. - */ - public void popOverlayPanel () - { - if (_opanel != null) { - remove(_opanel); - _opanel = null; - add(_bpanel); - - // make sure the UI updates - SwingUtil.refresh(this); - } - } - - /** - * Returns true if an overlay panel is currently being displayed. - */ - public boolean hasOverlay () - { - return _opanel != null; - } - - /** - * Initializes the puzzle panel with the puzzle config of the puzzle - * whose user interface is being displayed by the panel - */ - public void init (PuzzleConfig config) - { - _config = config; - _bview.init(config); - } - - /** - * Sets whether this panel receives events periodically from a robot - * player. - */ - public void setRobotPlayer (boolean isrobot) - { - // create a robot player if necessary - if (_robot == null) { - _robot = createRobotPlayer(); - } - setPuzzleGrabsKeys(!isrobot); - _robot.setRobotDelay(200L); - _robot.setActive(isrobot); - } - - /** - * Sets whether the puzzle grabs keys or if they should go to the chat - * window. - */ - public void setPuzzleGrabsKeys (boolean puzgrabs) - { - // enable or disable the key manager appropriately - _ctx.getKeyboardManager().setEnabled(puzgrabs); - if (puzgrabs) { - getBoardView().requestFocusInWindow(); - } - } - - /** - * Called by the controller when the action starts. - */ - public void startAction () - { - // make the first player a robot player - - if (isRobotTesting() && _controller.getPlayerIndex() == 0) { - setRobotPlayer(true); - } - } - - /** - * Called by the controller when the action stops. - */ - public void clearAction () - { - // deactivate the robot player - if (isRobotTesting() && _controller.getPlayerIndex() == 0) { - setRobotPlayer(false); - } - } - - /** - * Creates a robot player using the default RobotPlayer. Derived - * classes can override to make use of more advanced robots adapted to - * specific puzzles. - */ - protected RobotPlayer createRobotPlayer () - { - return new RobotPlayer(this, _xlate); - } - - /** - * Creates the puzzle board view that will be used to display the main - * puzzle interface. This is called when the puzzle panel is - * constructed. The derived panel will still be responsible for adding - * the board to the interface hierarchy. - */ - protected abstract PuzzleBoardView createBoardView (PuzzleContext ctx); - - /** - * Creates the main panel used to display the puzzle and its various - * in-game accoutrements (next block views, player status displays, - * etc.) This is called when the puzzle panel is constructed. The - * derived panel is responsible for making sure that the board view is - * present in the board panel. - */ - protected abstract JPanel createBoardPanel (PuzzleContext ctx); - - /** - * Returns a key translator with the desired key to controller command - * mappings desired for this puzzle. - */ - protected abstract KeyTranslator getKeyTranslator (); - - // documentation inherited from interface - public void willEnterPlace (PlaceObject plobj) - { - } - - // documentation inherited from interface - public void didLeavePlace (PlaceObject plobj) - { - // disable the keyboard manager when we leave - _ctx.getKeyboardManager().reset(); - } - - /** - * Returns a reference to the {@link PuzzleBoardView} in use. - */ - public PuzzleBoardView getBoardView () - { - return _bview; - } - - // documentation inherited - public Controller getController () - { - return _controller; - } - - /** Returns true if the robot tester is activated. */ - public static boolean isRobotTesting () - { - return _robotTest.getValue(); - } - - /** Returns true if board syncing is activated. */ - public static boolean isSyncingBoards () - { - return _syncBoardState.getValue(); - } - - /** Our puzzle context. */ - protected PuzzleContext _ctx; - - /** The board view on which the primary puzzle interface is displayed. */ - protected PuzzleBoardView _bview; - - /** The board panel displayed while the puzzle is in progress. */ - protected JPanel _bpanel; - - /** The board overlay panel displayed as requested. */ - protected JPanel _opanel; - - /** The puzzle config. */ - protected PuzzleConfig _config; - - /** The robot player. */ - protected RobotPlayer _robot; - - /** Our key translations. */ - protected KeyTranslator _xlate; - - /** The puzzle game controller. */ - protected PuzzleController _controller; - - /** A debug hook that toggles activation of the robot test player. */ - protected static RuntimeAdjust.BooleanAdjust _robotTest = - new RuntimeAdjust.BooleanAdjust( - "Activates the robot test player which will make random moves " + - "in any activated puzzle.", "narya.puzzle.robot_tester", - PuzzlePrefs.config, false); - - /** A debug hook that toggles activation of board syncing. */ - protected static RuntimeAdjust.BooleanAdjust _syncBoardState = - new RuntimeAdjust.BooleanAdjust( - "Sends a snapshot of the puzzle board with every event to aid " + - "in debugging.", "narya.puzzle.sync_board_state", - PuzzlePrefs.config, false); -} diff --git a/src/java/com/threerings/puzzle/client/PuzzlePrefs.java b/src/java/com/threerings/puzzle/client/PuzzlePrefs.java deleted file mode 100644 index 3d112c146..000000000 --- a/src/java/com/threerings/puzzle/client/PuzzlePrefs.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.puzzle.client; - -import com.samskivert.util.Config; - -/** - * Provides access to runtime configuration parameters for this package - * and its subpackages. - */ -public class PuzzlePrefs -{ - /** 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/puzzle"); -} diff --git a/src/java/com/threerings/puzzle/data/Board.java b/src/java/com/threerings/puzzle/data/Board.java deleted file mode 100644 index 996c5fef6..000000000 --- a/src/java/com/threerings/puzzle/data/Board.java +++ /dev/null @@ -1,205 +0,0 @@ -// -// $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.puzzle.data; - -import java.util.Random; - -import com.threerings.io.Streamable; - -/** - * An abstract base class for generating and storing puzzle board data. - */ -public abstract class Board - implements Cloneable, Streamable -{ - /** - * Outputs a string representation of the board contents. - */ - public abstract void dump (); - - /** - * Outputs a string representation of the board contents, interlaced - * with the supplied comparison board. - */ - public abstract void dumpAndCompare (Board other); - - /** - * Returns whether this board is equal to the given comparison board. - */ - public abstract boolean equals (Board other); - - // documentation inherited - public Object clone () - { - try { - Board board = (Board)super.clone(); - board._rando = (BoardRandom)_rando.clone(); - return board; - } catch (CloneNotSupportedException cnse) { - throw new RuntimeException("All is wrong with universe."); - } - } - - /** - * Sets the seed in the board's random number generator and calls - * {@link #populate}. - */ - public void initializeSeed (long seed) - { - _rando = new BoardRandom(seed); - populate(); - } - - /** - * Returns the random number generator used by the board to generate - * random numbers for our puzzles. - */ - public Random getRandom () - { - return _rando; - } - - /** - * Called after the seed is set in the board to give derived classes a - * chance to do things like populating the board with random pieces. - */ - protected void populate () - { - } - - /** Used to generate random numbers. */ - protected static class BoardRandom extends Random - implements Cloneable - { - public BoardRandom (long seed) - { - super(0L); - setSeed(seed); - } - - // documentation inherited - public synchronized void setSeed (long seed) - { - _seed = (seed ^ multiplier) & mask; - } - - // documentation inherited - synchronized protected int next (int bits) - { - long nextseed = (_seed * multiplier + addend) & mask; - _seed = nextseed; - return (int)(nextseed >>> (48 - bits)); - } - - // documentation inherited - public void nextBytes (byte[] bytes) - { - unimplemented(); - } - - // not overridden: (They seemed innocent enough) - // nextInt() - // nextLong() - // nextBoolean() - // nextFloat() - - // documentation inherited - public int nextInt (int n) - { - if (n <= 0) { - throw new IllegalArgumentException("n must be positive"); - } - - if ((n & -n) == n) { // i.e., n is a power of 2 - return (int)((n * (long)next(31)) >> 31); - } - - int bits, val; - do { - bits = next(31); - val = bits % n; - } while (bits - val + (n-1) < 0); - return val; - } - - // documentation inherited - public double nextDouble () - { - long l = ((long)(next(26)) << 27) + next(27); - return l / (double)(1L << 53); - } - - // documentation inherited - public synchronized double nextGaussian () - { - if (_haveNextNextGaussian) { - _haveNextNextGaussian = false; - return _nextNextGaussian; - - } else { - double v1, v2, s; - do { - v1 = 2 * nextDouble() - 1; - v2 = 2 * nextDouble() - 1; - s = v1 * v1 + v2 * v2; - } while (s >= 1 || s == 0); - double multiplier = Math.sqrt(-2 * Math.log(s)/s); - _nextNextGaussian = v2 * multiplier; - _haveNextNextGaussian = true; - return v1 * multiplier; - } - } - - // documentation inherited - public Object clone () - { - try { - return super.clone(); - } catch (CloneNotSupportedException cnse) { - throw new RuntimeException("All is wrong with universe."); - } - } - - /** - * I suppose I could copy all the methods from Random, then we - * wouldn't need this.. - */ - private final void unimplemented () - { - throw new RuntimeException( - "The Random method you attempted to call " + - "has not been implemented by BoardRandom."); - } - - /** The internal state related to generating random numbers. */ - protected long _seed; - protected double _nextNextGaussian; - protected boolean _haveNextNextGaussian = false; - - private final static long multiplier = 0x5DEECE66DL; - private final static long addend = 0xBL; - private final static long mask = (1L << 48) - 1; - } - - /** The object we use to generate our random numbers. */ - protected transient BoardRandom _rando; -} diff --git a/src/java/com/threerings/puzzle/data/BoardSummary.java b/src/java/com/threerings/puzzle/data/BoardSummary.java deleted file mode 100644 index 472b13184..000000000 --- a/src/java/com/threerings/puzzle/data/BoardSummary.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// $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.puzzle.data; - -import com.threerings.io.SimpleStreamableObject; - -/** - * Provides summarized data representing a player's board in a puzzle - * game. Board summaries are maintained by the puzzle server and are - * periodically sent to the clients to give them a view into how well - * their opponent(s) are doing. The data required to marshal a board - * summary object should be notably smaller in size than what would be - * required to marshal the entire associated {@link Board}. - * - *

Note all non-transient members of this and derived classes will - * automatically be serialized when the summary is sent over the wire. - */ -public abstract class BoardSummary extends SimpleStreamableObject -{ - /** - * Constructs an empty board summary for use when un-serializing. - */ - public BoardSummary () - { - // nothing for now - } - - /** - * Constructs a board summary that retrieves full board information - * from the supplied board when summarizing. - */ - public BoardSummary (Board board) - { - setBoard(board); - } - - /** - * Sets the board associated with this board summary, causing - * an immediate update to this summary. - */ - public void setBoard (Board board) - { - _board = board; - summarize(); // immediately summarize the new board - } - - /** - * Called by the {@link - * com.threerings.puzzle.server.PuzzleManager} to refresh the - * board summary information by studying the associated board - * contents. - */ - public abstract void summarize (); - - /** The board that we're summarizing. This is only valid on the - * server, and on the client only for the actual player's board. */ - protected transient Board _board; -} diff --git a/src/java/com/threerings/puzzle/data/PuzzleCodes.java b/src/java/com/threerings/puzzle/data/PuzzleCodes.java deleted file mode 100644 index aa9cf0a34..000000000 --- a/src/java/com/threerings/puzzle/data/PuzzleCodes.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// $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.puzzle.data; - -import com.threerings.presents.data.InvocationCodes; - -/** - * Constants relating to the puzzle services. - */ -public interface PuzzleCodes extends InvocationCodes -{ - /** The message bundle identifier for general puzzle messages. */ - public static final String PUZZLE_MESSAGE_BUNDLE = "puzzle.general"; - - /** The default puzzle difficulty level. */ - public static final int DEFAULT_DIFFICULTY = 2; - - /** Whether to enable debug logging and assertions for puzzles. Note - * that enabling this may result in the server or client exiting - * unexpectedly if certain error conditions arise in order to - * facilitate debugging, and so this should never be enabled in any - * environment even remotely resembling production. */ - public static final boolean DEBUG_PUZZLE = false; -} diff --git a/src/java/com/threerings/puzzle/data/PuzzleConfig.java b/src/java/com/threerings/puzzle/data/PuzzleConfig.java deleted file mode 100644 index 54aca3819..000000000 --- a/src/java/com/threerings/puzzle/data/PuzzleConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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.puzzle.data; - -import com.threerings.parlor.game.data.GameConfig; - -/** - * Encapsulates the basic configuration information for a puzzle game. - */ -public abstract class PuzzleConfig extends GameConfig - implements Cloneable -{ - /** - * Constructs a blank puzzle config. - */ - public PuzzleConfig () - { - } - - /** - * Returns the message bundle identifier for the bundle that should be - * used to translate the translatable strings used to describe the - * puzzle config parameters. The default implementation returns the - * base puzzle message bundle, but puzzles that have their own message - * bundle should override this method and return their puzzle-specific - * bundle identifier. - */ - public String getBundleName () - { - return PuzzleCodes.PUZZLE_MESSAGE_BUNDLE; - } -} diff --git a/src/java/com/threerings/puzzle/data/PuzzleGameCodes.java b/src/java/com/threerings/puzzle/data/PuzzleGameCodes.java deleted file mode 100644 index 27a949964..000000000 --- a/src/java/com/threerings/puzzle/data/PuzzleGameCodes.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// $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.puzzle.data; - -/** - * Contains codes used by the puzzle game client implementations. This - * differs from {@link PuzzleCodes} as that is related to the puzzle - * services which span the client and the server. - */ -public interface PuzzleGameCodes -{ - // Nothing at the moment. -} diff --git a/src/java/com/threerings/puzzle/data/PuzzleGameMarshaller.java b/src/java/com/threerings/puzzle/data/PuzzleGameMarshaller.java deleted file mode 100644 index 809d90081..000000000 --- a/src/java/com/threerings/puzzle/data/PuzzleGameMarshaller.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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.puzzle.data; - -import com.threerings.presents.client.Client; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; -import com.threerings.puzzle.client.PuzzleGameService; -import com.threerings.puzzle.data.Board; - -/** - * Provides the implementation of the {@link PuzzleGameService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class PuzzleGameMarshaller extends InvocationMarshaller - implements PuzzleGameService -{ - /** The method id used to dispatch {@link #updateProgress} requests. */ - public static final int UPDATE_PROGRESS = 1; - - // documentation inherited from interface - public void updateProgress (Client arg1, int arg2, int[] arg3) - { - sendRequest(arg1, UPDATE_PROGRESS, new Object[] { - Integer.valueOf(arg2), arg3 - }); - } - - /** The method id used to dispatch {@link #updateProgressSync} requests. */ - public static final int UPDATE_PROGRESS_SYNC = 2; - - // documentation inherited from interface - public void updateProgressSync (Client arg1, int arg2, int[] arg3, Board[] arg4) - { - sendRequest(arg1, UPDATE_PROGRESS_SYNC, new Object[] { - Integer.valueOf(arg2), arg3, arg4 - }); - } - -} diff --git a/src/java/com/threerings/puzzle/data/PuzzleObject.java b/src/java/com/threerings/puzzle/data/PuzzleObject.java deleted file mode 100644 index fa6270dfe..000000000 --- a/src/java/com/threerings/puzzle/data/PuzzleObject.java +++ /dev/null @@ -1,144 +0,0 @@ -// -// $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.puzzle.data; - -import com.threerings.parlor.game.data.GameObject; - -/** - * Extends the basic {@link GameObject} to add individual player - * status. Puzzle games typically contain numerous players that may be - * knocked out of the game while the overall game continues on, thereby - * necessitating this second level of game status. - */ -public class PuzzleObject extends GameObject - implements PuzzleCodes -{ - // AUTO-GENERATED: FIELDS START - /** The field name of the puzzleGameService field. */ - public static final String PUZZLE_GAME_SERVICE = "puzzleGameService"; - - /** The field name of the difficulty field. */ - public static final String DIFFICULTY = "difficulty"; - - /** The field name of the summaries field. */ - public static final String SUMMARIES = "summaries"; - - /** The field name of the seed field. */ - public static final String SEED = "seed"; - // AUTO-GENERATED: FIELDS END - - /** Provides general puzzle game invocation services. */ - public PuzzleGameMarshaller puzzleGameService; - - /** The puzzle difficulty level. */ - public int difficulty; - - /** Summaries of the boards of all players in this puzzle (may be null - * if the puzzle doesn't support individual player boards). */ - public BoardSummary[] summaries; - - /** The seed used to germinate the boards. */ - public long seed; - - // AUTO-GENERATED: METHODS START - /** - * Requests that the puzzleGameService field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setPuzzleGameService (PuzzleGameMarshaller value) - { - PuzzleGameMarshaller ovalue = this.puzzleGameService; - requestAttributeChange( - PUZZLE_GAME_SERVICE, value, ovalue); - this.puzzleGameService = value; - } - - /** - * Requests that the difficulty field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setDifficulty (int value) - { - int ovalue = this.difficulty; - requestAttributeChange( - DIFFICULTY, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.difficulty = value; - } - - /** - * Requests that the summaries field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setSummaries (BoardSummary[] value) - { - BoardSummary[] ovalue = this.summaries; - requestAttributeChange( - SUMMARIES, value, ovalue); - this.summaries = (value == null) ? null : (BoardSummary[])value.clone(); - } - - /** - * Requests that the indexth element of - * summaries field be set to the specified value. - * The local value will be updated immediately and an event will be - * propagated through the system to notify all listeners that the - * attribute did change. Proxied copies of this object (on clients) - * will apply the value change when they received the attribute - * changed notification. - */ - public void setSummariesAt (BoardSummary value, int index) - { - BoardSummary ovalue = this.summaries[index]; - requestElementUpdate( - SUMMARIES, index, value, ovalue); - this.summaries[index] = value; - } - - /** - * Requests that the seed field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setSeed (long value) - { - long ovalue = this.seed; - requestAttributeChange( - SEED, Long.valueOf(value), Long.valueOf(ovalue)); - this.seed = value; - } - // AUTO-GENERATED: METHODS END -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropBlockSprite.java b/src/java/com/threerings/puzzle/drop/client/DropBlockSprite.java deleted file mode 100644 index 7fc12a26e..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropBlockSprite.java +++ /dev/null @@ -1,273 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Rectangle; - -/** - * The drop block sprite represents a block of multiple pieces that can be - * rotated to any of the four cardinal compass directions. As such, it - * may span multiple columns or rows depending on its orientation. The - * block has a "central" piece around which it rotates, with the other - * pieces referred to as "external" pieces. - */ -public class DropBlockSprite extends DropSprite -{ - /** - * Constructs a drop block sprite and starts it dropping. - * - * @param view the board view upon which this sprite will be displayed. - * @param col the column of the central piece. - * @param row the row of the central piece. - * @param orient the orientation of the sprite. - * @param pieces the pieces displayed by the sprite. - */ - public DropBlockSprite ( - DropBoardView view, int col, int row, int orient, int[] pieces) - { - super(view, col, row, pieces, 0); - - _orient = orient; - } - - /** - * Constructs a drop block sprite and starts it dropping. - * - * @param view the board view upon which this sprite will be displayed. - * @param col the column of the central piece. - * @param row the row of the central piece. - * @param orient the orientation of the sprite. - * @param pieces the pieces displayed by the sprite. - * @param renderOrder the rendering order of the sprite. - */ - public DropBlockSprite ( - DropBoardView view, int col, int row, int orient, int[] pieces, - int renderOrder) - { - super(view, col, row, pieces, 0, renderOrder); - - _orient = orient; - } - - // documentation inherited - protected void init () - { - super.init(); - - setOrientation(_orient); - } - - /** - * Returns an array of the row numbers containing the block pieces. - * The first index is the row of the central piece. The array is - * cached and re-used internally and so the caller should make their - * own copy if they care to modify it. - */ - public int[] getRows () - { - return _rows; - } - - /** - * Returns an array of the column numbers containing the block pieces. - * The first index is the column of the central piece. The array is - * cached and re-used internally and so the caller should make their - * own copy if they care to modify it. - */ - public int[] getColumns () - { - return _cols; - } - - /** - * Returns the bounds of the block in board piece coordinates. The - * bounds rectangle is cached and re-used internally and so the caller - * should make their own copy if they care to modify it. - */ - public Rectangle getBoardBounds () - { - return _dbounds; - } - - /** - * Returns the row the external piece is located in. - */ - public int getExternalRow () - { - return _erow; - } - - /** - * Returns the column the external piece is located in. - */ - public int getExternalColumn () - { - return _ecol; - } - - // documentation inherited - public void setColumn (int col) - { - super.setColumn(col); - updateDropInfo(); - } - - // documentation inherited - public void setRow (int row) - { - super.setRow(row); - updateDropInfo(); - } - - // documentation inherited - public void setBoardLocation (int row, int col) - { - super.setBoardLocation(row, col); - updateDropInfo(); - } - - /** - * Updates the sprite image offset to reflect the direction in which - * the external piece is hanging. - */ - public void setOrientation (int orient) - { - super.setOrientation(orient); - - int edx = 0, edy = 0; - if (orient == NORTH) { - edy = -1; - } else if (orient == WEST) { - edx = -1; - } - - // update the sprite image offset - setRowOffset(edy); - setColumnOffset(edx); - - // update the external piece position and drop block bounds - updateDropInfo(); - } - - // documentation inherited - public void toString (StringBuilder buf) - { - super.toString(buf); - buf.append(", erow=").append(_erow); - buf.append(", ecol=").append(_ecol); - } - - /** - * Can this sprite pop-up a row on a forgiving rotation? - */ - public boolean canPopup () - { - return (_popups > 0); - } - - /** - * Called if we pop up to decrement the remaining popups we have. - */ - public void didPopup () - { - _popups--; - } - - /** - * Re-calculates the external piece position and bounds of the drop - * block. - */ - protected void updateDropInfo () - { - // update the external piece location - _erow = calculateExternalRow(); - _ecol = calculateExternalColumn(); - - // update the piece row and column arrays - _rows[0] = _row; - _rows[1] = _erow; - _cols[0] = _col; - _cols[1] = _ecol; - - // calculate the drop block board bounds - int maxrow = Math.max(_row, _erow); - int mincol = Math.min(_col, _ecol); - - int bpwid, bphei; - if (_orient == NORTH || _orient == SOUTH) { - bpwid = 1; - bphei = 2; - } else { - bpwid = 2; - bphei = 1; - } - - // create the bounds rectangle if necessary - _dbounds.setBounds(mincol, maxrow, bpwid, bphei); - } - - /** - * Returns the row the external piece is located in based on the - * current central piece location and sprite orientation. - */ - protected int calculateExternalRow () - { - if (_orient == NORTH) { - return (_row - 1); - } else if (_orient == SOUTH) { - return (_row + 1); - } else { - return _row; - } - } - - /** - * Returns the column the external piece is located in based on the - * current central piece location and sprite orientation. - */ - protected int calculateExternalColumn () - { - if (_orient == WEST) { - return (_col - 1); - } else if (_orient == EAST) { - return (_col + 1); - } else { - return _col; - } - } - - /** How many times this sprite can be popped-up a row in a forgiving - * rotation. */ - protected byte _popups = 2; - - /** The drop block bounds in board coordinates. */ - protected Rectangle _dbounds = new Rectangle(); - - /** The drop block piece rows. */ - protected int[] _rows = new int[2]; - - /** The drop block piece columns. */ - protected int[] _cols = new int[2]; - - /** The external piece location in board coordinates. */ - protected int _ecol, _erow; -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropBoardView.java b/src/java/com/threerings/puzzle/drop/client/DropBoardView.java deleted file mode 100644 index 40b7afe4d..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropBoardView.java +++ /dev/null @@ -1,585 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; - -import java.util.Iterator; - -import com.threerings.media.image.Mirage; -import com.threerings.media.sprite.ImageSprite; -import com.threerings.media.sprite.PathAdapter; -import com.threerings.media.sprite.Sprite; -import com.threerings.media.util.LinePath; -import com.threerings.media.util.Path; - -import com.threerings.parlor.media.ScoreAnimation; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.client.PuzzleBoardView; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.util.PuzzleContext; - -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropConfig; -import com.threerings.puzzle.drop.data.DropPieceCodes; - -/** - * The drop board view displays a drop puzzle game in progress for a - * single player. - */ -public abstract class DropBoardView extends PuzzleBoardView - implements DropPieceCodes -{ - /** The color used to render normal scoring text. */ - public static final Color SCORE_COLOR = Color.white; - - /** The color used to render chain reward scoring text. */ - public static final Color CHAIN_COLOR = Color.yellow; - - /** - * Constructs a drop board view. - */ - public DropBoardView (PuzzleContext ctx, int pwid, int phei) - { - super(ctx); - - // save off piece dimensions - _pwid = pwid; - _phei = phei; - - // determine distance to float score animations - _scoreDist = 2 * _phei; - } - - /** - * Initializes the board with the board dimensions. - */ - public void init (PuzzleConfig config) - { - DropConfig dconfig = (DropConfig)config; - - // save off the board dimensions in pieces - _bwid = dconfig.getBoardWidth(); - _bhei = dconfig.getBoardHeight(); - - super.init(config); - } - - /** - * Returns the width in pixels of a single board piece. - */ - public int getPieceWidth () - { - return _pwid; - } - - /** - * Returns the height in pixels of a single board piece. - */ - public int getPieceHeight () - { - return _phei; - } - - /** - * Called by the {@link DropSprite} to populate pos with - * the screen coordinates in pixels at which a piece at (col, - * row) in the board should be drawn. Derived classes may wish - * to override this method to allow specialised positioning of - * sprites. - */ - public void getPiecePosition (int col, int row, Point pos) - { - pos.setLocation(col * _pwid, (row * _phei) - _roff); - } - - /** - * Called by the {@link DropSprite} to get the dimensions of the area - * that will be occupied by rendering a piece segment of the given - * orientation and length whose bottom-leftmost corner is at - * (col, row). - */ - public Dimension getPieceSegmentSize (int col, int row, int orient, int len) - { - if (orient == NORTH || orient == SOUTH) { - return new Dimension(_pwid, len * _phei); - } else { - return new Dimension(len * _pwid, _phei); - } - } - - /** - * Creates a new piece sprite and places it directly in it's correct - * position. - */ - public void createPiece (int piece, int sx, int sy) - { - if (sx < 0 || sy < 0 || sx >= _bwid || sy >= _bhei) { - Log.warning("Requested to create piece in invalid location " + - "[sx=" + sx + ", sy=" + sy + "]."); - Thread.dumpStack(); - return; - } - createPiece(piece, sx, sy, sx, sy, 0L); - } - - /** - * Refreshes the piece sprite at the specified location, if no sprite - * exists at the location, one will be created. Note: this - * method assumes the default {@link ImageSprite} is being used to - * display pieces. If {@link #createPieceSprite} is overridden to - * return a non-ImageSprite, this method must also be customized. - */ - public void updatePiece (int sx, int sy) - { - updatePiece(_dboard.getPiece(sx, sy), sx, sy); - } - - /** - * Updates the piece sprite at the specified location, if no sprite - * exists at the location, one will be created. Note: this - * method assumes the default {@link ImageSprite} is being used to - * display pieces. If {@link #createPieceSprite} is overridden to - * return a non-ImageSprite, this method must also be customized. - */ - public void updatePiece (int piece, int sx, int sy) - { - if (sx < 0 || sy < 0 || sx >= _bwid || sy >= _bhei) { - Log.warning("Requested to update piece in invalid location " + - "[sx=" + sx + ", sy=" + sy + "]."); - Thread.dumpStack(); - return; - } - int spos = sy * _bwid + sx; - if (_pieces[spos] != null) { - ((ImageSprite)_pieces[spos]).setMirage( - getPieceImage(piece, sx, sy, NORTH)); - } else { - createPiece(piece, sx, sy); - } - } - - /** - * Creates a new piece sprite and moves it into position on the board. - */ - public void createPiece (int piece, int sx, int sy, int tx, int ty, - long duration) - { - if (tx < 0 || ty < 0 || tx >= _bwid || ty >= _bhei) { - Log.warning("Requested to create and move piece to invalid " + - "location [tx=" + tx + ", ty=" + ty + "]."); - Thread.dumpStack(); - return; - } - Sprite sprite = createPieceSprite(piece, sx, sy); - if (sprite != null) { - // position the piece properly to start - Point start = new Point(); - getPiecePosition(sx, sy, start); - sprite.setLocation(start.x, start.y); - // now add it to the view - addSprite(sprite); - // and potentially move it into place - movePiece(sprite, sx, sy, tx, ty, duration); - } - } - - /** - * Instructs the view to move the piece at the specified starting - * position to the specified destination position. There must be a - * sprite at the starting position, if there is a sprite at the - * destination position, it must also be moved immediately following - * this call (as in the case of a swap) to avoid badness. - * - * @return the piece sprite that is being moved. - */ - public Sprite movePiece (int sx, int sy, int tx, int ty, long duration) - { - int spos = sy * _bwid + sx; - Sprite piece = _pieces[spos]; - if (piece == null) { - Log.warning("Missing source sprite for drop [sx=" + sx + - ", sy=" + sy + ", tx=" + tx + ", ty=" + ty + "]."); - return null; - } - _pieces[spos] = null; - movePiece(piece, sx, sy, tx, ty, duration); - return piece; - } - - /** - * A helper function for moving pieces into place. - */ - protected void movePiece (Sprite piece, final int sx, final int sy, - final int tx, final int ty, long duration) - { - final Exception where = new Exception(); - - // if the sprite needn't move, then just position it and be done - Point start = new Point(); - getPiecePosition(sx, sy, start); - if (sx == tx && sy == ty) { - int tpos = ty * _bwid + tx; - if (_pieces[tpos] != null) { - Log.warning("Zoiks! Asked to add a piece where we already " + - "have one [sx=" + sx + ", sy=" + sy + - ", tx=" + tx + ", ty=" + ty + "]."); - Log.logStackTrace(where); - return; - } - _pieces[tpos] = piece; - piece.setLocation(start.x, start.y); - return; - } - - // note that this piece is moving toward its destination - final int tpos = ty * _bwid + tx; - _moving[tpos] = true; - - // then create a path and do some bits - Point end = new Point(); - getPiecePosition(tx, ty, end); - piece.addSpriteObserver(new PathAdapter() { - public void pathCompleted (Sprite sprite, Path path, long when) { - sprite.removeSpriteObserver(this); - if (_pieces[tpos] != null) { - Log.warning("Oh god, we're dropping onto another piece " + - "[sx=" + sx + ", sy=" + sy + - ", tx=" + tx + ", ty=" + ty + "]."); - Log.logStackTrace(where); - return; - } - _pieces[tpos] = sprite; - if (_actionSprites.remove(sprite)) { - maybeFireCleared(); - } - pieceArrived(when, sprite, tx, ty); - } - }); - _actionSprites.add(piece); - piece.move(new LinePath(start, end, duration)); - } - - /** - * Called when a piece is finished moving into its requested position. - * Derived classes may wish to take this opportunity to play a sound - * or whatnot. - */ - protected void pieceArrived (long tickStamp, Sprite sprite, int px, int py) - { - _moving[py * _bwid + px] = false; - } - - /** - * Returns true if the piece that is supposed to be at the specified - * coordinates is not yet there but is actually en route to that - * location (due to a call to {@link #movePiece}). - */ - protected boolean isMoving (int px, int py) - { - return _moving[py * _bwid + px]; - } - - /** - * Returns the image used to display the given piece at coordinates - * (0, 0) with an orientation of {@link #NORTH}. This - * serves as a convenience routine for those puzzles that don't bother - * rendering their pieces differently when placed at different board - * coordinates or in different orientations. - */ - public Mirage getPieceImage (int piece) - { - return getPieceImage(piece, 0, 0, NORTH); - } - - /** - * Returns the image used to display the given piece at the specified - * column and row with the given orientation. - */ - public abstract Mirage getPieceImage ( - int piece, int col, int row, int orient); - - // documentation inherited - public void setBoard (Board board) - { - // when a new board arrives, we want to remove all drop sprites - // so that they don't modify the new board with their old ideas - for (Iterator iter = _actionSprites.iterator(); iter.hasNext(); ) { - Sprite s = (Sprite) iter.next(); - if (s instanceof DropSprite) { - // remove it from _sprites safely - iter.remove(); - // but then use the standard removal method - removeSprite(s); - } - } - - // remove all of this board's piece sprites - int pcount = (_pieces == null) ? 0 : _pieces.length; - for (int ii = 0; ii < pcount; ii++) { - if (_pieces[ii] != null) { - removeSprite(_pieces[ii]); - } - } - - super.setBoard(board); - - _dboard = (DropBoard)board; - - // create the pieces for the new board - Point spos = new Point(); - int width = _dboard.getWidth(), height = _dboard.getHeight(); - _pieces = new Sprite[width * height]; - for (int yy = 0; yy < height; yy++) { - for (int xx = 0; xx < width; xx++) { - Sprite piece = createPieceSprite( - _dboard.getPiece(xx, yy), xx, yy); - if (piece != null) { - int ppos = yy * width + xx; - getPiecePosition(xx, yy, spos); - piece.setLocation(spos.x, spos.y); - addSprite(piece); - _pieces[ppos] = piece; - } - } - } - - // we use this to track when pieces are animating toward their new - // position and are not yet in place - _moving = new boolean[width * height]; - } - - /** - * Returns the piece sprite at the specified location. - */ - public Sprite getPieceSprite (int xx, int yy) - { - return _pieces[yy * _dboard.getWidth() + xx]; - } - - /** - * Clears the specified piece from the board. - */ - public void clearPieceSprite (int xx, int yy) - { - int ppos = yy * _dboard.getWidth() + xx; - if (_pieces[ppos] != null) { - removeSprite(_pieces[ppos]); - _pieces[ppos] = null; - } - } - - /** - * Clears out a piece from the board along with its piece sprite. - */ - public void clearPiece (int xx, int yy) - { - _dboard.setPiece(xx, yy, PIECE_NONE); - clearPieceSprite(xx, yy); - } - - /** - * Creates a new drop sprite used to animate the given pieces falling - * in the specified column. - */ - public DropSprite createPieces (int col, int row, int[] pieces, int dist) - { - return new DropSprite(this, col, row, pieces, dist); - } - - /** - * Dirties the rectangle encompassing the segment with the given - * direction and length whose bottom-leftmost corner is at (col, - * row). - */ - public void dirtySegment (int dir, int col, int row, int len) - { - int x = _pwid * col, y = (_phei * row) - _roff; - int wid = (dir == VERTICAL) ? _pwid : len * _pwid; - int hei = (dir == VERTICAL) ? _phei * len : _phei; - _remgr.invalidateRegion(x, y, wid, hei); - } - - /** - * Creates and returns an animation showing the specified score - * floating up the view, with the label initially centered within the - * view. - * - * @param score the score text to display. - * @param color the color of the text. - * @param font the font. - */ - public ScoreAnimation createScoreAnimation ( - String score, Color color, Font font) - { - return createScoreAnimation( - score, color, font, 0, _bhei - 1, _bwid, _bhei); - } - - /** - * Creates and returns an animation showing the specified score - * floating up the view. - * - * @param score the score text to display. - * @param color the color of the text. - * @param font the font to use. - * @param x the left coordinate in board coordinates of the rectangle - * within which the score is to be centered. - * @param y the bottom coordinate in board coordinates of the - * rectangle within which the score is to be centered. - * @param width the width in board coordinates of the rectangle within - * which the score is to be centered. - * @param height the height in board coordinates of the rectangle - * within which the score is to be centered. - */ - public ScoreAnimation createScoreAnimation (String score, Color color, - Font font, int x, int y, - int width, int height) - { - // create the score animation - ScoreAnimation anim = - createScoreAnimation(score, color, font, x, y); - - // position the label within the specified rectangle - Dimension lsize = anim.getLabel().getSize(); - Point pos = new Point(); - centerRectInBoardRect( - x, y, width, height, lsize.width, lsize.height, pos); - anim.setLocation(pos.x, pos.y); - - return anim; - } - - /** - * Creates the sprite that is used to display the specified piece. If - * the piece represents no piece, this method should return null. - */ - protected Sprite createPieceSprite (int piece, int px, int py) - { - if (piece == PIECE_NONE) { - return null; - } - ImageSprite sprite = new ImageSprite( - getPieceImage(piece, px, py, NORTH)); - sprite.setRenderOrder(-1); - return sprite; - } - - /** - * Populates pos with the most appropriate screen - * coordinates to center a rectangle of the given width and height (in - * pixels) within the specified rectangle (in board coordinates). - * - * @param bx the bounding rectangle's left board coordinate. - * @param by the bounding rectangle's bottom board coordinate. - * @param bwid the bounding rectangle's width in board coordinates. - * @param bhei the bounding rectangle's height in board coordinates. - * @param rwid the width of the rectangle to position in pixels. - * @param rhei the height of the rectangle to position in pixels. - * @param pos the point to populate with the rectangle's final - * position. - */ - protected void centerRectInBoardRect ( - int bx, int by, int bwid, int bhei, int rwid, int rhei, Point pos) - { - getPiecePosition(bx, by + 1, pos); - pos.x += (((bwid * _pwid) - rwid) / 2); - pos.y -= ((((bhei * _phei) - rhei) / 2) + rhei); - - // constrain to fit wholly within the board bounds - pos.x = Math.max(Math.min(pos.x, _bounds.width - rwid), 0); - } - - /** - * Rotates the given drop block sprite to the specified orientation, - * updating the image as necessary. Derived classes that make use of - * block dropping functionality should override this method to do the - * right thing. - */ - public void rotateDropBlock (DropBlockSprite sprite, int orient) - { - // nothing for now - } - - // documentation inherited - public void paintBetween (Graphics2D gfx, Rectangle dirtyRect) - { - gfx.translate(0, -_roff); - renderBoard(gfx, dirtyRect); - renderRisingPieces(gfx, dirtyRect); - gfx.translate(0, _roff); - } - - // documentation inherited - public Dimension getPreferredSize () - { - int wid = _bwid * _pwid; - int hei = _bhei * _phei; - return new Dimension(wid, hei); - } - - /** - * Renders the row of rising pieces to the given graphics context. - * Sub-classes that make use of board rising functionality should - * override this method to draw the rising piece row. - */ - protected void renderRisingPieces (Graphics2D gfx, Rectangle dirtyRect) - { - // nothing for now - } - - /** - * Sets the board rising offset to the given y-position. - */ - protected void setRiseOffset (int y) - { - if (y != _roff) { - _roff = y; - _remgr.invalidateRegion(_bounds); - } - } - - /** The drop board. */ - protected DropBoard _dboard; - - /** A sprite for every piece displayed in the drop board. */ - protected Sprite[] _pieces; - - /** Indicates whether a piece is en route to its destination. */ - protected boolean[] _moving; - - /** The piece dimensions in pixels. */ - protected int _pwid, _phei; - - /** The board rising offset. */ - protected int _roff; - - /** The board dimensions in pieces. */ - protected int _bwid, _bhei; -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropControllerDelegate.java b/src/java/com/threerings/puzzle/drop/client/DropControllerDelegate.java deleted file mode 100644 index d3b73a02b..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropControllerDelegate.java +++ /dev/null @@ -1,1213 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Component; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; - -import java.util.List; - -import com.samskivert.util.IntListUtil; - -import com.threerings.media.FrameParticipant; -import com.threerings.media.animation.Animation; -import com.threerings.media.animation.AnimationAdapter; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.puzzle.util.PuzzleContext; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.client.PuzzleController; -import com.threerings.puzzle.client.PuzzleControllerDelegate; -import com.threerings.puzzle.client.PuzzlePanel; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.BoardSummary; - -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropCodes; -import com.threerings.puzzle.drop.data.DropConfig; -import com.threerings.puzzle.drop.data.DropLogic; -import com.threerings.puzzle.drop.data.DropPieceCodes; -import com.threerings.puzzle.drop.util.PieceDropLogic; -import com.threerings.puzzle.drop.util.PieceDropper.PieceDropInfo; -import com.threerings.puzzle.drop.util.PieceDropper; - -/** - * Games that wish to make use of the drop puzzle services will need to - * create an extension of this delegate class, customizing it for their - * particular game and then adding it via {@link - * PuzzleController#addDelegate}. - * - *

It handles logical actions for a puzzle game that generally - * consists of a two-dimensional board containing pieces, with new pieces - * either falling into the board as a "drop block", or rising into the - * bottom of the board in new piece rows. - * - *

Derived classes must implement {@link #getPieceVelocity} and {@link - * #evolveBoard}. - * - *

Block-dropping puzzles will likely want to override {@link - * #createNextBlock}, {@link #blockDidLand}, and {@link - * #getPieceDropLogic}. - * - *

Board-rising puzzles will likely want to override {@link - * #getRiseVelocity}, {@link #getRiseDistance}, {@link - * #getPieceDropLogic}, and {@link #boardDidRise}. - */ -public abstract class DropControllerDelegate extends PuzzleControllerDelegate - implements DropCodes, DropPieceCodes, FrameParticipant -{ - /** The action command for moving the block to the left. */ - public static final String MOVE_BLOCK_LEFT = "move_block_left"; - - /** The action command for moving the block to the right. */ - public static final String MOVE_BLOCK_RIGHT = "move_block_right"; - - /** The action command for rotating the block counter-clockwise. */ - public static final String ROTATE_BLOCK_CCW = "rotate_block_ccw"; - - /** The action command for rotating the block clockwise. */ - public static final String ROTATE_BLOCK_CW = "rotate_block_cw"; - - /** The action command for starting to dropping the block. */ - public static final String START_DROP_BLOCK = "start_drop_block"; - - /** The action command for ending dropping the block. */ - public static final String END_DROP_BLOCK = "end_drop_block"; - - /** The action command for raising the next rising row. */ - public static final String RAISE_ROW = "raise_row"; - - /** - * Creates a delegate with the specified drop game logic and - * controller. - */ - public DropControllerDelegate (PuzzleController ctrl, DropLogic logic) - { - super(ctrl); - - // keep this for later - _ctrl = ctrl; - - // obtain the drop logic parameters - DropLogic dlogic = (DropLogic)logic; - _usedrop = dlogic.useBlockDropping(); - _userise = dlogic.useBoardRising(); - - if (_userise) { - // prepare for board rising - _risevel = getRiseVelocity(); - _risedist = getRiseDistance(); - } - } - - // documentation inherited - public void init (CrowdContext ctx, PlaceConfig config) - { - super.init(ctx, config); - - // save things off - PuzzlePanel panel = (PuzzlePanel)_ctrl.getPlaceView(); - _ctx = (PuzzleContext)ctx; - _dview = (DropBoardView)panel.getBoardView(); - _dpanel = (DropPanel)panel; - _dboard = (DropBoard)_ctrl.getBoard(); - - // obtain the board dimensions - DropConfig dconfig = (DropConfig)config; - _bwid = dconfig.getBoardWidth(); - _bhei = dconfig.getBoardHeight(); - - // create the piece dropper if appropriate - PieceDropLogic pdl = getPieceDropLogic(); - if (pdl != null) { - _dropper = new PieceDropper(pdl); - } - } - - /** - * Returns the speed with which the next board row should rise into - * place, in pixels per millisecond. - */ - protected float getRiseVelocity () - { - return DEFAULT_RISE_VELOCITY; - } - - /** - * Returns the distance in pixels that each board row will traverse - * when rising into place. - */ - protected int getRiseDistance () - { - return DEFAULT_RISE_DISTANCE; - } - - /** - * Starts up the action; tries evolving the board to get things going. - */ - protected void startAction () - { - super.startAction(); - -// Log.info("Starting drop action"); - - // add ourselves as a frame participant - _ctx.getFrameManager().registerFrameParticipant(this); - -// if (_userise) { -// // make sure the board has its next row of pieces -// advanceRisingPieces(); -// // we'll set up the risestamp on the first rise tick -// } - - // if we've a drop block left over from our previous action, set - // it on its merry way once more - if (_blocksprite != null) { - long delta = _dview.getTimeStamp() - _blockStamp; - Log.info("Restarting drop sprite [delta=" + delta + "]."); - _blocksprite.fastForward(delta); - _blockStamp = 0L; - _dview.addSprite(_blocksprite); - - // if we cleared the action while the drop sprite was - // bouncing, we need to land the block to get things going - // again - if (_blocksprite.isBouncing()) { - Log.info("Ended on a bounce, landing the block and " + - "starting things up."); - checkBlockLanded("bounced", true, true); - } - } - - // evolve the board to kick-start the game into action - unstabilizeBoard(); - } - - // documentation inherited - protected boolean canClearAction () - { - if (!_stable) { - Log.info("Rejecting canClear() request because not stable."); - } - return _stable && super.canClearAction(); - } - - /** - * Clears out all of the action in the board; removes any drop block - * sprites, any pieces rising in the board, and resets the animation - * timestamps. - */ - protected void clearAction () - { - super.clearAction(); - -// Log.info("Clearing drop action."); - - // do away with the bounce interval - _bounceStamp = 0; - _bounceRow = Integer.MIN_VALUE; - - // kill any active drop block - if (_blocksprite != null) { - _dview.removeSprite(_blocksprite); - _blockStamp = _dview.getTimeStamp(); - } - - // reset intermediate rising timestamps - _rpstamp = 0; - _zipstamp = 0; - _fastDrop = false; - - // remove ourselves as a frame participant - _ctx.getFrameManager().removeFrameParticipant(this); - } - - // documentation inherited - public void gameDidEnd () - { - super.gameDidEnd(); - - // clear out the drop block sprite - _blocksprite = null; - - // reset ourselves back to pre-game conditions - _risestamp = 0; -// _dview.setRisingPieces(null); - } - - // documentation inherited - public boolean handleAction (ActionEvent action) - { - // handle any block-related movement actions - if (handleBlockAction(action)) { - return true; - } - - String cmd = action.getActionCommand(); - if (cmd.equals(START_DROP_BLOCK)) { - handleDropBlock(true); - - } else if (cmd.equals(END_DROP_BLOCK)) { - handleDropBlock(false); - - } else { - return super.handleAction(action); - } - - return true; - } - - // documentation inherited - public void setBoard (Board board) - { - super.setBoard(board); - - // update the casted board reference - _dboard = (DropBoard)board; - // and update our self-summary - updateSelfSummary(); - } - - // documentation inherited - protected boolean handleBlockAction (ActionEvent action) - { - String cmd = action.getActionCommand(); - boolean handled = false; - - if (cmd.equals(MOVE_BLOCK_LEFT)) { - handleMoveBlock(LEFT); - handled = true; - - } else if (cmd.equals(MOVE_BLOCK_RIGHT)) { - handleMoveBlock(RIGHT); - handled = true; - - } else if (cmd.equals(ROTATE_BLOCK_CCW)) { - handleRotateBlock(CCW); - handled = true; - - } else if (cmd.equals(ROTATE_BLOCK_CW)) { - handleRotateBlock(CW); - handled = true; - } - - if (handled && _blocksprite != null) { - // land the block if it's been placed on something solid as a - // result of one of the above actions - String source = "fiddled [cmd=" + cmd + "]"; - if (checkBlockLanded(source, false, false)) { - startBounceTimer(source); - } - } - - return handled; - } - - /** - * Handles block moved events. - */ - protected void handleMoveBlock (int dir) - { - if (_blocksprite == null) { - return; - } - - // gather information regarding the attempted move - Rectangle bb = _blocksprite.getBoardBounds(); - int row = _blocksprite.getRow(), col = _blocksprite.getColumn(); - int dx = (dir == LEFT) ? -1 : 1; - - // if the sprite has made it to the bottom of the board then we - // don't want to allow it to "virtually" fall any further because - // of the bounce interval - float pctdone = (row >= (_bhei - 1)) ? 0 : - _blocksprite.getPercentDone(_dview.getTimeStamp()); - - // get the drop block position resulting from the move - Point pos = _dboard.getForgivingMove( - bb.x, bb.y, bb.width, bb.height, dx, 0, pctdone); - if (pos != null) { - int frow = row + (pos.y - bb.y); - int fcol = col + (pos.x - bb.x); - // Log.info("Valid move [row=" + frow + ", col=" + col + "]."); - _blocksprite.setBoardLocation(frow, fcol); - } - } - - /** - * Handles block rotation events. - */ - protected void handleRotateBlock (int dir) - { - if (_blocksprite == null) { - return; - } - - // gather information regarding the attempted rotation - int[] rows = _blocksprite.getRows(); - int[] cols = _blocksprite.getColumns(); - // if the sprite has made it to the bottom of the board then we - // don't want to allow it to "virtually" fall any further because - // of the bounce interval - float pctdone = (rows[0] >= (_bhei - 1)) ? 0 : - _blocksprite.getPercentDone(_dview.getTimeStamp()); - - // get the drop block position resulting from the rotation - int[] info = _dboard.getForgivingRotation( - rows, cols, _blocksprite.getOrientation(), dir, - getRotationType(), pctdone, _blocksprite.canPopup()); - if (info != null) { -// Log.info("Found valid rotation " + -// "[orient=" + DirectionUtil.toShortString(info[0]) + -// ", col=" + info[1] + ", row=" + info[2] + -// ", blocksprite=" + _blocksprite + "]."); - - // update the piece image - _dview.rotateDropBlock(_blocksprite, info[0]); - - // place the block in its newly rotated location - _blocksprite.setBoardLocation(info[2], info[1]); - - if (info[3] != 0) { - _blocksprite.didPopup(); - } - - // let derived classes do what they will - blockDidRotate(dir); - } - } - - /** - * Called when the drop block has rotated in the specified direction - * to allow derived classes to engage in any game-specific antics. - */ - protected void blockDidRotate (int dir) - { - } - - /** - * Returns the rotation type used by this drop game. Either {@link - * DropBoard#RADIAL_ROTATION} or {@link DropBoard#INPLACE_ROTATION}. - */ - protected int getRotationType () - { - return DropBoard.RADIAL_ROTATION; - } - - /** - * Handles drop block events. - */ - protected void handleDropBlock (boolean fast) - { - _fastDrop = fast; - - // only allow changing the piece velocity if we're not bouncing - if (_blocksprite != null && _bounceStamp == 0) { - // Log.info("Updating drop block velocity [fast=" + fast + "]."); - _blocksprite.setVelocity(getPieceVelocity(fast)); - } - } - - /** - * Returns the drop sprite velocity to assign to a new drop sprite. - */ - protected abstract float getPieceVelocity (boolean fast); - - /** - * Handles creation and dropping of the next dropping block. - */ - protected void dropNextBlock () - { - if (_blocksprite != null || !_ctrl.hasAction()) { - Log.info("Not dropping block [bs=" + (_blocksprite != null) + - ", action=" + _ctrl.hasAction() + "]."); - return; - } - - // determine whether or not the game should be ended because we - // can't drop the next block - if (checkDropEndsGame()) { - return; - } - - int pidx = _ctrl.getPlayerIndex(); - if (pidx != -1 && !_ctrl.isGameOver() && _puzobj.isActivePlayer(pidx)) { - // create the next block - _blocksprite = createNextBlock(); - if (_blocksprite != null) { - // reset the drop block fast-drop state - _fastDrop = false; - - // configure and add the drop block sprite - _blocksprite.setVelocity(getPieceVelocity(_fastDrop)); - _blocksprite.addSpriteObserver(_dropMovedHandler); - _dview.addSprite(_blocksprite); - - // update the next block display - _dpanel.setNextBlock(peekNextPieces()); - - // make sure the block has somewhere to go - if (checkBlockLanded("next-block", false, true)) { - startBounceTimer("next-block"); - } - } - - // clear out our last bounce row - _bounceRow = Integer.MIN_VALUE; - } - } - - /** - * Called by {@link #dropNextBlock} to determine whether the game - * should be ended rather than dropping the next block because the - * board is filled and a new block cannot enter. If true is returned, - * the drop controller assumes that the derived class will have ended - * or reset the game as appropriate and will simply abandon its - * attempt to drop the next block. - */ - protected boolean checkDropEndsGame () - { - return false; - } - - /** - * Called only for block-dropping puzzles when it's time to create the - * next drop block. Returns the drop block sprite if it was - * successfully created, or null if it was not. - */ - protected DropBlockSprite createNextBlock () - { - // nothing for now - return null; - } - - /** - * Take a peek at the next pieces. - */ - protected int[] peekNextPieces () - { - return null; - } - - /** - * Called when a drop sprite posts a piece moved event. - */ - protected void handleDropSpriteMoved ( - DropSprite sprite, long when, int col, int row) - { - if (sprite instanceof DropBlockSprite) { - if (checkBlockLanded("piece-moved", false, true)) { - startBounceTimer("piece-moved"); - } - // keep dropping the drop block - sprite.drop(); - return; - } - - if (sprite.getDistance() > 0) { - sprite.drop(); - - } else { - // remove the sprite - _dview.removeSprite(sprite); - - // apply the pieces to the board - applyDropSprite(sprite, col, row); - - // perform any new destruction and falling - unstabilizeBoard(); - } - } - - /** - * Applies the pieces in the given sprite to the specified column and - * row in the board. Called when a drop sprite has finished - * traversing its entire distance. - */ - protected void applyDropSprite (DropSprite sprite, int col, int row) - { - // set the pieces in the board - int[] pieces = sprite.getPieces(); - _dboard.setSegment(VERTICAL, col, row, pieces); - // create the updated board pieces - for (int dy = 0; dy < pieces.length; dy++) { - // pieces outside the board are discarded - if (row - dy >= 0) { - // note: vertical segments are applied counting downwards - // from the starting row toward row zero - _dview.createPiece(pieces[dy], col, row - dy); - } - } - } - - /** - * Called to determine whether it is safe to evolve the board. The - * default implementation does not allow board evolution if there are - * sprites or animations active on the board. - */ - protected boolean canEvolveBoard () - { - return (_dview.getActionCount() == 0); - } - - /** - * Evolves the board to an unchanging state. If the board is in a - * state where pieces should react with one another to cause changes - * to the board state (such as piece dropping via {@link #dropPieces}, - * piece destruction, and/or piece joining), this is where that - * process should be effected. - * - *

When no further evolution is possible and the board has - * stabilized this method should return false to indicate that such - * action should be taken. That will result in a follow-up call to - * {@link #boardDidStabilize} (assuming that the action was not - * cleared prior to the final stabilization of the board). - */ - protected abstract boolean evolveBoard (); - - /** - * Derived classes should call this method whenever they change some - * board state that will require board evolution to restabilize the - * board. - */ - protected void unstabilizeBoard () - { - _stable = false; - } - - /** - * Called when the board has been fully evolved and is once again - * stable. The default implementation updates the player's local board - * summary and drops the next block into the board, but derived - * classes may wish to perform custom actions if they don't use drop - * blocks or have other requirements. - */ - protected void boardDidStabilize () - { - updateSelfSummary(); - dropNextBlock(); - } - - /** - * Updates the player's own local board summary to reflect the local - * copy of the player's board which is likely to be more up to date - * than the server-side board from which all other player board - * summaries originate. - */ - public void updateSelfSummary () - { - int pidx = _ctrl.getPlayerIndex(); - if (pidx != -1 && _puzobj != null && _puzobj.summaries != null) { - BoardSummary bsum = _puzobj.summaries[pidx]; - bsum.setBoard(_dboard); - bsum.summarize(); - _dpanel.setSummary(pidx, bsum); - } - } - - /** - * Called when an animation finishes doing its business. Derived - * classes may wish to override this method but should be sure to call - * super.animationDidFinish(). - */ - protected void animationDidFinish (Animation anim) - { - unstabilizeBoard(); - } - - /** - * Checks whether the drop block can continue dropping and lands its - * pieces if not. Returns whether at least one piece of the block has - * landed; note that the other piece may need subsequent dropping. - * - * @param commit if true, the block landing is committed, if false, it - * is only checked, not committed. - * @param atTop whether the block sprite is to be treated as being at - * the top of its current row. - */ - protected boolean checkBlockLanded ( - String source, boolean commit, boolean atTop) - { - if (_blocksprite == null) { - return true; - } - - // check to see that both pieces can continue dropping - int[] rows = _blocksprite.getRows(); - int[] cols = _blocksprite.getColumns(); - - // TODO: we may need to limit pctdone here to account for landing - // on the bottom of the board. - float pctdone = (atTop) ? 0.0f : - _blocksprite.getPercentDone(_dview.getTimeStamp()); - -// Log.info("Checking landed [source=" + source + -// ", bounceRow=" + _bounceRow + -// ", rows=" + StringUtil.toString(rows) + -// ", cols=" + StringUtil.toString(cols) + -// ", orient=" + DirectionUtil.toShortString( -// _blocksprite.getOrientation()) + -// ", commit=" + commit + ", pctdone=" + pctdone + "]."); - - if (_dboard.isValidDrop(rows, cols, pctdone)) { - if (commit) { - Log.info("Not valid drop [source=" + source + - ", commit=" + commit + ", atTop=" + atTop + - ", pctdone=" + pctdone + "]."); - } - return false; - } - - // if we're committing the landing, remove the sprite and update - // the board and all that - if (commit) { - // give sub-classes a chance to do any pre-landing business - blockWillLand(); - - // stamp the pieces into the board - int[] pieces = _blocksprite.getPieces(); - boolean error = false; - for (int ii = 0; ii < pieces.length; ii++) { - if (rows[ii] >= 0) { - int col = cols[ii], row = rows[ii]; - - // sanity-check the block to make sure it's located in - // a valid position, and that we aren't somehow - // overwriting an existing piece - if (col < 0 || col >= _bwid || row >= _bhei) { - Log.warning("Placing drop block piece outside board " + - "bounds!? [x=" + col + ", y=" + row + - ", pidx=" + ii + - ", blocksprite=" + _blocksprite + "]."); - error = true; - - } else { - int cpiece = _dboard.getPiece(col, row); - if (cpiece != PIECE_NONE) { - Log.warning("Placing drop block piece onto " + - "occupied board position!? [x=" + col + - ", y=" + row + ", pidx=" + ii + - ", blocksprite=" + _blocksprite + "]."); - error = true; - } - } - - if (!error) { - // stuff the piece into the board - _dboard.setPiece(col, row, pieces[ii]); - _dview.createPiece(pieces[ii], col, row); - } - } - - if (DEBUG_PUZZLE && error) { - _dboard.dump(); - Log.warning("Bailing out in a flaming pyre of glory."); - System.exit(0); - } - } - - // remove the drop block sprite - _dview.removeSprite(_blocksprite); - _blocksprite = null; - - // give sub-classes a chance to do any post-landing business - blockDidLand(); - } - - return true; - } - - /** - * Called only for block-dropping puzzles when the drop block is about - * to land on something. Derived classes may wish to override this - * method to perform game-specific actions such as queueing up a - * "block placed" progress event. - */ - protected void blockWillLand () - { - // nothing for now - } - - /** - * Called only for block-dropping puzzles when the drop block lands on - * something. Derived classes may wish to override this method to - * perform any game-specific actions. - */ - protected void blockDidLand () - { - // nothing for now - } - - /** - * Called when a block lands. We give the user a smidgen of time to - * continue to fiddle with the block before we actually land it. If - * the block is still landed when the bounce timer expires, we commit - * the landing, otherwise we let the block keep falling. - */ - protected void startBounceTimer (String source) - { - int bounceRow = IntListUtil.getMaxValue(_blocksprite.getRows()); -// Log.info("startBounceTimer [source=" + source + -// ", bounceStamp=" + _bounceStamp + -// ", time=" + _dview.getTimeStamp() + -// ", bounceRow=" + _bounceRow + -// ", nbounceRow=" + bounceRow + "]."); - - // forcibly land the block if we bounce twice at the same row - if (_bounceStamp == 0 && _bounceRow == bounceRow) { - if (checkBlockLanded("double-bounced", true, true)) { - unstabilizeBoard(); - } - return; - } - - // if the bounce "timer" is already started, the user probably did - // something like rotate the piece while it was bouncing (which is - // why we give them the bounce interval), so we don't reset - if (_bounceStamp == 0) { - // slow the piece down so that it doesn't fly past the - // coordinates at which it's potentially landing; we have to - // do this before we tell the sprite that it's bouncing - // because changing the velocity fiddles with the rowstamp and - // we're going to reset the rowstamp when we tell the sprite - // that it's bouncing - _blocksprite.setVelocity(getPieceVelocity(false)); - - // set up our bounce interval (it depends on the current piece - // velocity and so must be set at the time we bounce) - _bounceInterval = (int) - ((_dview.getPieceHeight() * BOUNCE_FRACTION) / - getPieceVelocity(false)); -// Log.info("bounceInterval=" + _bounceInterval + -// ", phei=" + _dview.getPieceHeight() + -// ", vel=" + getPieceVelocity(false)); - - // make a note of the time we started bouncing - _bounceStamp = _dview.getTimeStamp(); - - // and the row at which we're bouncing - _bounceRow = bounceRow; - - // put the block sprite into bouncing mode - _blocksprite.setBouncing(true); - } - } - - /** - * Called when the bounce timer expires. Herein we either commit the - * landing of a block if it is still landed or let it keep falling if - * it is no longer landed. - */ - protected void bounceTimerExpired () - { -// Log.info("bounceTimerExpired [bounceStamp=" + _bounceStamp + -// ", time=" + _dview.getTimeStamp() + -// ", bounceRow=" + _bounceRow + "]."); - - // make sure we weren't cancelled for some reason - if (_bounceStamp != 0) { - if (checkBlockLanded("bounced", true, true)) { - unstabilizeBoard(); - - } else if (_blocksprite != null) { - // take the block sprite out of bouncing mode - _blocksprite.setBouncing(false); - } - _bounceStamp = 0; - } - } - - /** - * Drops any pieces that need dropping and returns whether any pieces - * were dropped. Derived classes that would like to drop their pieces - * should include a call to this method in their {@link #evolveBoard} - * implementation, and must also override {@link #getPieceDropLogic} - * to provide their game-specific piece dropper implementation. - */ - protected boolean dropPieces () - { - PieceDropper.DropObserver drobs = new PieceDropper.DropObserver() { - public void pieceDropped ( - int piece, int sx, int sy, int dx, int dy) { - float vel = getPieceVelocity(true) * 1.5f; - long duration = (long)(_dview.getPieceHeight() * - Math.abs(dy-sy) / vel); - if (sy < 0) { - _dview.createPiece(piece, sx, sy, dx, dy, duration); - } else { - _dview.movePiece(sx, sy, dx, dy, duration); - } - } - }; - return (_dropper.dropPieces(_dboard, drobs) > 0); - } - - /** - * Returns the piece dropper used to drop any pieces that need - * dropping in the board. Derived classes that intend to make use of - * {@link #dropPieces} must implement this method and return a - * reference to their game-specific piece dropper implementation. - */ - protected PieceDropLogic getPieceDropLogic () - { - return null; - } - - // documentation inherited - public void tick (long tickStamp) - { -// if (_userise && (tickStamp >= _risesent + RISE_INTERVAL)) { -// _risesent += RISE_INTERVAL; -// raiseBoard(tickStamp); -// } - - // check the bounce timer - if ((_bounceStamp != 0) && - ((tickStamp - _bounceStamp) >= _bounceInterval)) { - bounceTimerExpired(); - } - - // if we can't evolve the board because it doesn't need evolving - // or things are going on, we stop here - if (_stable || !canEvolveBoard()) { - return; - } - - // if we do not evolve the board in any way, let the derived class - // know that the board stabilized so that they can drop in a new - // piece if they like or take whatever other action is appropriate - boolean evolving = evolveBoard(); - boolean debug = false; - if (debug) { - Log.info("Evolved board [evolving=" + evolving + "]."); - } - - // if we're no longer evolving and the action has not ended, go - // ahead and let our derived class know that the board has - // stabilized so that it can drop in the next piece or somesuch - if (!evolving) { - // no evolving again until someone destabilizes the board - _stable = true; - - // this will trigger further puzzle activity - if (debug) { - Log.info("Board did stabilize"); - } - boardDidStabilize(); - - // ensure that if we have been postponing action due to board - // evolution, that it will now be cleared - if (!_ctrl.hasAction()) { - if (debug) { - Log.info("Maybe clearing action."); - } - maybeClearAction(); - } - } - } - - // documentation inherited - public Component getComponent () - { - return null; - } - - // documentation inherited - public boolean needsPaint () - { - return false; - } - - /** - * Sets whether the board rising is paused. - */ - public void setRisingPaused (boolean paused) - { - if (paused && _rpstamp == 0) { - // pause the board - _rpstamp = _dview.getTimeStamp(); - - } else if (!paused && _rpstamp != 0) { - // un-pause the board - long delta = _dview.getTimeStamp() - _rpstamp; - _risestamp += delta; - if (_zipstamp != 0) { - _zipstamp += delta; - } - _rpstamp = 0; - } - } - - /** - * Causes the board to zip quickly to the next row. - */ - public void zipToNextRow () - { - // don't overwrite an existing zip - if (_zipstamp == 0) { - // if we're paused, inherit the pause time, otherwise use the - // current time - if (_rpstamp != 0) { - _zipstamp = _rpstamp; - } else { - _zipstamp = _dview.getTimeStamp(); - } - } - } - - /** - * Called periodically on the frame tick. Raises the board row based - * on the time since the current row traversal began. - */ - /* - protected void raiseBoard (long tickStamp) - { - // don't raise if rising is paused or the action is cleared - if (_rpstamp != 0 || !_ctrl.hasAction()) { - return; - } - - // initialize the rise stamp the first time we're risen - if (_risestamp == 0) { - _risestamp = tickStamp; - _risesent = _risestamp; - } - - // determine how far we've risen - long msecs = tickStamp - _risestamp; - float travpix = msecs * _risevel; - - // account for any zipping effect - long zipsecs = 0; - if (_zipstamp > 0) { - zipsecs = tickStamp - _zipstamp; - // make sure we don't zip past the top - float zippix = (zipsecs * _risevel * 15); - if (travpix < _risedist) { - travpix += zippix; - travpix = Math.min(travpix, _risedist); - } - } - - float pctdone = travpix / _risedist; - - boolean rose = false; - if (pctdone >= 1.0f) { - rose = true; - if (_zipstamp > 0) { - // clear out any zip stamp - _zipstamp = 0; - _risestamp = tickStamp; - pctdone = 1f; - - } else { - long used = (long)(_risedist / _risevel); - _risestamp += used; - } - - // give sub-classes a chance to do their thing - boardWillRise(); - } - - // update the board display - int ypos = ((int)(_risedist * pctdone)) % _risedist; - _dview.setRiseOffset(ypos); - - if (rose) { - // check to see if this means doom and defeat (even though the - // game might be over, we still want to advance the piece - // packet one last time and do the last rise so that the - // server can tell that we kicked the proverbial bucket) - boolean canRise = checkCanRise(); - - // apply the rising row pieces to the board - int[] pieces = _dview.getRisingPieces(); - _dboard.applyRisingPieces(pieces); - - // set up the next row of rising pieces - _dview.setRisingPieces(null); - advanceRisingPieces(); - - // give sub-classes a chance to do their thing - boardDidRise(); - - if (canRise) { - // evolve the board - unstabilizeBoard(); - - } else { - Log.debug("Sticking fork in it [risers=" + - StringUtil.toString(pieces) + "."); - - // let the controller know that we're done for - _ctrl.resetGame(); - } - } - -// Log.info("Board rise [msecs=" + msecs + ", roff=" + ypos + -// ", pctdone=" + pctdone + ", zipsecs=" + zipsecs + "]."); - } - */ - - /** - * Called to determine whether or not rising a new row into the board - * is legal. The default implementation will return false if the top - * row of the board contains any pieces. - */ - protected boolean checkCanRise () - { - return !_dboard.rowContainsPieces(0, PIECE_NONE); - } - - /** - * Called only for board-rising puzzles before effecting the rising of - * the board by one row. Derived classes may wish to override this - * method to add any desired behaviour, but should be sure to call - * super.boardWillRise(). - */ - protected void boardWillRise () - { - // nothing for now - } - - /** - * Called only for board-rising puzzles when the board has finished - * rising one row. Derived classes may wish to override this method - * to add any desired behaviour, but should be sure to call - * super.boardDidRise(). - */ - protected void boardDidRise () - { - // nothing for now - } - - /** The yohoho context. */ - protected PuzzleContext _ctx; - - /** Our puzzle controller. */ - protected PuzzleController _ctrl; - - /** The drop panel. */ - protected DropPanel _dpanel; - - /** The drop board view. */ - protected DropBoardView _dview; - - /** The drop board. */ - protected DropBoard _dboard; - - /** Whether the game is using drop block functionality. */ - protected boolean _usedrop; - - /** Whether the game is using board rising functionality. */ - protected boolean _userise; - - /** Whether or not the board is currently stable. */ - protected boolean _stable; - - /** The board dimensions in pieces. */ - protected int _bwid, _bhei; - - /** The distance the board row travels in pixels. */ - protected int _risedist; - - /** The speed with which the board rises in pixels per millisecond. */ - protected float _risevel; - - /** The drop block sprite associated with the landing block, if any. */ - protected DropBlockSprite _blocksprite; - - /** The piece dropper used to drop pieces in the board if the puzzle - * chooses to make use of piece dropping functionality. */ - protected PieceDropper _dropper; - - /** The time at which the board rise was paused. */ - protected long _rpstamp; - - /** The time at which the last board rise began. */ - protected long _risestamp; - - /** The time at which we last fired off a board rising event. */ - protected long _risesent; - - /** The time at which we were requested to start zipping. */ - protected long _zipstamp; - - /** The duration of the bounce interval. */ - protected int _bounceInterval; - - /** The time at which we last started bouncing, or 0. */ - protected long _bounceStamp; - - /** The row at which we last bounced, or {@link Integer#MIN_VALUE}. */ - protected int _bounceRow; - - /** The timestamp used to keep track of when the drop block was - * removed so that we can fast-forward it when restored. */ - protected long _blockStamp; - - /** Whether the drop blocks are currently dropping quickly. */ - protected boolean _fastDrop; - - /** Used to evolve the board following the completion of animations. */ - protected AnimationAdapter _evolveObserver = new AnimationAdapter() { - public void animationCompleted (Animation anim, long when) { - animationDidFinish(anim); - } - }; - - /** Used to listen to drop sprites and react to their move events. */ - protected DropSpriteObserver _dropMovedHandler = new DropSpriteObserver() { - public void pieceMoved ( - DropSprite sprite, long when, int col, int row) { - handleDropSpriteMoved(sprite, when, col, row); - } - }; - - /** A piece operation that will update piece sprites as board - * positions are updated. */ - protected DropBoard.PieceOperation _updateBoardOp = - new DropBoard.PieceOperation() { - public boolean execute (DropBoard board, int col, int row) { - _dview.updatePiece(col, row); - return true; - } - }; - - /** The default board row rising velocity. */ - protected static final float DEFAULT_RISE_VELOCITY = 100f / 1000f; - - /** The default board row rising distance. */ - protected static final int DEFAULT_RISE_DISTANCE = 20; - - /** The delay in milliseconds between board rising intervals. */ - protected static final long RISE_INTERVAL = 50L; - - /** Defines the distance of a piece that we allow to bounce before we - * land it. */ - protected static final float BOUNCE_FRACTION = 0.125f; -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropPanel.java b/src/java/com/threerings/puzzle/drop/client/DropPanel.java deleted file mode 100644 index 6d90ddac4..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropPanel.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// $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.puzzle.drop.client; - -import com.threerings.puzzle.data.BoardSummary; - -/** - * Puzzles using the drop services need implement this interface to - * display drop puzzle related information. - */ -public interface DropPanel -{ - /** - * Sets the next block to be displayed. - */ - public void setNextBlock (int[] pieces); - - /** - * Updates the board summary display for the given player. - */ - public void setSummary (int pidx, BoardSummary summary); -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropSprite.java b/src/java/com/threerings/puzzle/drop/client/DropSprite.java deleted file mode 100644 index 7ea67c087..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropSprite.java +++ /dev/null @@ -1,584 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Shape; - -import com.samskivert.util.ObserverList; -import com.threerings.util.DirectionUtil; - -import com.threerings.media.image.Mirage; -import com.threerings.media.sprite.Sprite; - -import com.threerings.puzzle.Log; - -/** - * The drop sprite is a sprite that displays one or more pieces falling - * toward the bottom of the board. - */ -public class DropSprite extends Sprite -{ - /** - * Constructs a drop sprite and starts it dropping. - * - * @param view the board view upon which this sprite will be displayed. - * @param col the column of the sprite. - * @param row the row of the bottom-most piece. - * @param pieces the pieces displayed by the sprite. - * @param dist the distance the sprite is to drop in rows. - */ - public DropSprite ( - DropBoardView view, int col, int row, int[] pieces, int dist) - { - this(view, col, row, pieces, dist, -1); - } - - /** - * Constructs a drop sprite and starts it dropping. - * - * @param view the board view upon which this sprite will be displayed. - * @param col the column of the sprite. - * @param row the row of the bottom-most piece. - * @param pieces the pieces displayed by the sprite. - * @param dist the distance the sprite is to drop in rows. - * @param renderOrder the render order. - */ - public DropSprite ( - DropBoardView view, int col, int row, int[] pieces, int dist, - int renderOrder) - { - _view = view; - _col = col; - _row = row; - _pieces = pieces; - _dist = (dist == 0) ? 1 : dist; - _orient = NORTH; - _unit = _view.getPieceHeight(); - setRenderOrder(renderOrder); - } - - // documentation inherited - protected void init () - { - super.init(); - - // size the bounds to fit our pieces - updateBounds(); - // set up the piece location - setBoardLocation(_row, _col); - // calculate vertical render offset based on the number of pieces - setRowOffset(-(_pieces.length - 1)); - } - - /** - * Returns the remaining number of columns to drop. - */ - public int getDistance () - { - return _dist; - } - - /** - * Returns the column the piece is located in. - */ - public int getColumn () - { - return _col; - } - - /** - * Returns the row the piece is located in. - */ - public int getRow () - { - return _row; - } - - /** - * Returns the pieces the sprite is displaying. - */ - public int[] getPieces () - { - return _pieces; - } - - /** - * Returns the velocity of this sprite. - */ - public float getVelocity () - { - return _vel; - } - - /** - * Sets the row and column the piece is located in. - */ - public void setBoardLocation (int row, int col) - { - _row = row; - _col = col; - updatePosition(); - } - - /** - * Sets the column the piece is located in. - */ - public void setColumn (int col) - { - _col = col; - updatePosition(); - } - - /** - * Set the row the piece is located in. - */ - public void setRow (int row) - { - _row = row; - updatePosition(); - } - - /** - * Sets the column offset of the sprite image. - */ - public void setColumnOffset (int count) - { - _offx = count; - updateRenderOffset(); - updateRenderOrigin(); - } - - /** - * Sets the row offset of the sprite image. - */ - public void setRowOffset (int count) - { - _offy = count; - updateRenderOffset(); - updateRenderOrigin(); - } - - /** - * Sets the pieces the sprite is displaying. - */ - public void setPieces (int[] pieces) - { - _pieces = pieces; - } - - /** - * Sets the velocity of this sprite. The time at which the current - * row was entered is modified so that the sprite position will remain - * the same when calculated using the new velocity since the piece - * sprite may have its velocity modified in the middle of a row - * traversal. - */ - public void setVelocity (float velocity) - { - // bail if we've already got the requested velocity - if (_vel == velocity) { - return; - } - - if (_rowstamp > 0) { - // get our current distance along the row - long now = _view.getTimeStamp(); - float pctdone = getPercentDone(now); - - // revise the current row entry time to account for the new velocity - float travpix = pctdone * _unit; - long msecs = (long)(travpix / velocity); - _rowstamp = now - msecs; - } - - // update the velocity - _vel = velocity; - } - - /** - * Starts the piece dropping toward the next row. - */ - public void drop () - { - // Log.info("Dropping piece [piece=" + this + "]."); - - // drop one row by default - if (_dist <= 0) { - _dist = 1; - } - - if (_stopstamp > 0) { - // we're dropping from a stand-still - long delta = _view.getTimeStamp() - _stopstamp; - _rowstamp += delta; - _stopstamp = 0; - - } else { - // we're continuing a previous drop, so make use of any - // previously existing time - _rowstamp = _endstamp; - } - } - - /** - * Returns true if this drop sprite is dropping, false if it has been - * {@link #stop}ped or has not yet been {@link #drop}ped. - */ - public boolean isDropping () - { - return (_stopstamp == 0) && (_rowstamp != 0); - } - - /** - * Stops the piece from dropping. - */ - public void stop () - { - if (_stopstamp == 0) { - _stopstamp = _view.getTimeStamp(); - // Log.info("Stopped piece [piece=" + this + "]."); - } - } - - /** - * Puts the drop sprite into (or takes it out of) bouncing - * mode. Bouncing mode is used to put the sprite into limbo after it - * lands but before we commit the landing, giving the user a last - * moment change move or rotate the piece. While the sprite is - * "bouncing" it will be rendered one pixel below it's at rest state. - */ - public void setBouncing (boolean bouncing) - { - if (_bouncing = bouncing) { - // if we've activated bouncing, shift the sprite slightly to - // illustrate its new state - shiftForBounce(); - - // to prevent funny business in the event that we were a long - // ways past the end of the row when we landed, we warp the - // sprite back to the exact point of landing for the purposes - // of the bounce and any subsequent antics - _endstamp = _rowstamp = _view.getTimeStamp(); - -// Log.info("Adjusted rowstap due to bounce " + -// "[time=" + _endstamp + "]."); - } - } - - /** - * Returns true if this sprite is bouncing. - */ - public boolean isBouncing () - { - return _bouncing; - } - - /** - * Updates the sprite's location to illustrate that it is currently in - * the "bouncing" state. - */ - protected void shiftForBounce () - { - setLocation(_ox, _srcPos.y+1); - } - - // documentation inherited - public boolean inside (Shape shape) - { - return shape.contains(_bounds); - } - - /** - * Returns a value between 0.0 and 1.0 - * representing how far the piece has moved toward the next row - * as of the given time stamp. - */ - public float getPercentDone (long timestamp) - { - // if we've never been ticked and so haven't yet initialized our - // row start timestamp, just let the caller know that we've not - // traversed our row at all - if (_rowstamp == 0) { - return 0.0f; - } - - long msecs = Math.max(0, timestamp - _rowstamp); - float travpix = msecs * _vel; - float pctdone = (travpix / _unit); - -// Log.info("getPercentDone [timestamp=" + timestamp + -// ", rowstamp=" + _rowstamp + ", msecs=" + msecs + -// ", travpix=" + travpix + ", pctdone=" + pctdone + -// ", vel=" + _vel + "]."); - - return pctdone; - } - - // documentation inherited - public void paint (Graphics2D gfx) - { - // get the column and row increment based on the sprite's orientation - int oidx = _orient/2; - int incx = ORIENT_DX[oidx]; - int incy = ORIENT_DY[oidx]; - - // determine offset from the start of each actual row and column - int dx = _ox - _srcPos.x, dy = _oy - _srcPos.y; - - int pcol = _col, prow = _row; - for (int ii = 0; ii < _pieces.length; ii++) { - // ask the board for the render position of this piece - _view.getPiecePosition(pcol, prow, _renderPos); - // draw the piece image - paintPieceImage(gfx, ii, pcol, prow, _orient, - _renderPos.x + dx, _renderPos.y + dy); - // increment the target column and row - pcol += incx; - prow += incy; - } - } - - /** - * Paints the specified piece with the supplied parameters. - */ - protected void paintPieceImage (Graphics2D gfx, int pieceidx, - int col, int row, int orient, int x, int y) - { - Mirage image = _view.getPieceImage(_pieces[pieceidx], col, row, orient); - image.paint(gfx, x, y); - } - - // documentation inherited - public void tick (long timestamp) - { - super.tick(timestamp); - - // initialize our rowstamp if we haven't done so already - if (_rowstamp == 0) { - _rowstamp = timestamp; - } - - // if we're bouncing or paused, do nothing here - if (_bouncing || _stopstamp > 0) { - return; - } - - PieceMovedOp pmop = null; - - // figure out how far along the current board coordinate we should be - float pctdone = getPercentDone(timestamp); - if (pctdone >= 1.0f) { - // note that we've reached the next row - advancePosition(); - - // update remaining drop distance - _dist--; - - // calculate any remaining time to be used - long used = (long)(_unit / _vel); - _endstamp = _rowstamp + used; - _rowstamp = _endstamp; - - // update our percent done because we've moved down a row - pctdone -= 1.0; - - // inform observers that we've reached our destination - pmop = new PieceMovedOp(this, timestamp, _col, _row); - } - - // constrain the sprite's position to the destination row - pctdone = Math.min(pctdone, 1.0f); - - // calculate the latest sprite position - int nx = _srcPos.x + (int)((_destPos.x - _srcPos.x) * pctdone); - int ny = _srcPos.y + (int)((_destPos.y - _srcPos.y) * pctdone); - -// Log.info("Drop sprite tick [dist=" + _dist + ", pctdone=" + pctdone + -// ", row=" + _row + ", col=" + _col + -// ", nx=" + nx + ", ny=" + ny + "]."); - - // only update the sprite's location if it actually moved - if (_ox != nx || _oy != ny) { - setLocation(nx, ny); - } - - // lastly notify our observers if we made it to the next row - if (pmop != null) { - _observers.apply(pmop); - } - } - - /** - * Called when the sprite has finished traversing its current row to - * advance its board coordinates to the next row. - */ - protected void advancePosition () - { - setRow(_row + 1); - // Log.info("Moved to row " + _row); - } - - // documentation inherited - public void fastForward (long timeDelta) - { - if (_rowstamp > 0) { - _rowstamp += timeDelta; - } - } - - // documentation inherited - public void toString (StringBuilder buf) - { - super.toString(buf); - buf.append(", orient=").append(DirectionUtil.toShortString(_orient)); - buf.append(", row=").append(_row); - buf.append(", col=").append(_col); - buf.append(", offx=").append(_offx); - buf.append(", offy=").append(_offy); - buf.append(", dist=").append(_dist); - } - - /** - * Updates internal pixel coordinates used when the piece is moving. - */ - protected void updatePosition () - { - _view.getPiecePosition(_col, _row, _srcPos); - _view.getPiecePosition(_col, _row+1, _destPos); - setLocation(_srcPos.x, _srcPos.y); - } - - // documentation inherited - public void setOrientation (int orient) - { - invalidate(); - super.setOrientation(orient); - updateBounds(); - invalidate(); - } - - /** - * Updates the bounds for this sprite based on the sprite display - * dimensions in the view. - */ - protected void updateBounds () - { - Dimension size = _view.getPieceSegmentSize( - _col, _row, _orient, _pieces.length); - _bounds.width = size.width; - _bounds.height = size.height; - } - - /** - * Adjusts our render origin such that our location is not in the - * upper left of the sprite's rendered image but is in fact offset by - * some number of rows and columns. - */ - protected void updateRenderOffset () - { - _oxoff = -(_view.getPieceWidth() * _offx); - _oyoff = -(_view.getPieceHeight() * _offy); - } - - /** Used to dispatch {@link DropSpriteObserver#pieceMoved}. */ - protected static class PieceMovedOp implements ObserverList.ObserverOp - { - public PieceMovedOp (DropSprite sprite, long when, int col, int row) - { - _sprite = sprite; - _when = when; - _col = col; - _row = row; - } - - public boolean apply (Object observer) - { - if (observer instanceof DropSpriteObserver) { - ((DropSpriteObserver)observer).pieceMoved( - _sprite, _when, _col, _row); - } - return true; - } - - protected DropSprite _sprite; - protected long _when; - protected int _col, _row; - } - - /** The default piece velocity. */ - protected static final float DEFAULT_VELOCITY = 30f/1000f; - - /** The time at which we started the current row. */ - protected long _rowstamp; - - /** The time at which we reached the end of the previous row. */ - protected long _endstamp; - - /** The time at which we were stopped en route to our next row. */ - protected long _stopstamp; - - /** The board view upon which this sprite is displayed. */ - protected DropBoardView _view; - - /** The unit distance the sprite moves to reach the next row. */ - protected int _unit; - - /** The screen coordinates of the top-left of the row currently - * occupied by the sprite. */ - protected Point _srcPos = new Point(); - - /** The screen coordinates of the top-left of the row toward which the - * sprite is falling. */ - protected Point _destPos = new Point(); - - /** The piece render position; used as working data when determining - * where to render each piece in the sprite. */ - protected Point _renderPos = new Point(); - - /** The number of rows remaining to drop. */ - protected int _dist; - - /** The piece velocity. */ - protected float _vel = DEFAULT_VELOCITY; - - /** The offsets in columns or rows at which the piece is rendered. */ - protected int _offx, _offy; - - /** The current piece location in the board. */ - protected int _row, _col; - - /** The pieces this sprite is displaying. */ - protected int[] _pieces; - - /** Indicates that the drop sprite is bouncing; see {@link - * #setBouncing}. */ - protected boolean _bouncing; - - // used to compute the column and row increment while rendering the - // sprite's pieces based on its orientation - // W N E S - protected static final int[] ORIENT_DX = { -1, 0, 1, 0 }; - protected static final int[] ORIENT_DY = { 0, -1, 0, 1 }; -} diff --git a/src/java/com/threerings/puzzle/drop/client/DropSpriteObserver.java b/src/java/com/threerings/puzzle/drop/client/DropSpriteObserver.java deleted file mode 100644 index 45e90c401..000000000 --- a/src/java/com/threerings/puzzle/drop/client/DropSpriteObserver.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// $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.puzzle.drop.client; - -/** - * Provides notifications for drop puzzle specific stuff. - */ -public interface DropSpriteObserver -{ - /** - * Called when the drop sprite has moved completely to the specified - * board coordinates. - */ - public void pieceMoved (DropSprite sprite, long when, int col, int row); -} diff --git a/src/java/com/threerings/puzzle/drop/client/NextBlockView.java b/src/java/com/threerings/puzzle/drop/client/NextBlockView.java deleted file mode 100644 index 68abe47d3..000000000 --- a/src/java/com/threerings/puzzle/drop/client/NextBlockView.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; - -import javax.swing.JComponent; - -import com.threerings.media.image.Mirage; -import com.threerings.util.DirectionCodes; - -/** - * The next block view displays an image representing the next drop block - * to appear in the game. - */ -public class NextBlockView extends JComponent - implements DirectionCodes -{ - /** - * Constructs a next block view. - */ - public NextBlockView (DropBoardView view, int pwid, int phei, int orient) - { - // save things off - _view = view; - _pwid = pwid; - _phei = phei; - _orient = orient; - - // configure the component - setOpaque(false); - } - - /** - * Sets the pieces displayed by the view. - */ - public void setPieces (int[] pieces) - { - _pieces = pieces; - repaint(); - } - - // documentation inherited - public void paintComponent (Graphics g) - { - super.paintComponent(g); - - // draw the pieces - Graphics2D gfx = (Graphics2D)g; - if (_pieces != null) { - Dimension size = getSize(); - int xpos = (_orient == VERTICAL) ? 0 : (size.width - _pwid); - int ypos = (_orient == VERTICAL) ? (size.height - _phei) : 0; - - for (int ii = 0; ii < _pieces.length; ii++) { - Mirage image = _view.getPieceImage(_pieces[ii]); - image.paint(gfx, xpos, ypos); - if (_orient == VERTICAL) { - ypos -= _phei; - } else { - xpos -= _pwid; - } - } - } - } - - // documentation inherited - public Dimension getPreferredSize () - { - int wid = (_orient == VERTICAL) ? _pwid : (2 * _pwid); - int hei = (_orient == VERTICAL) ? (2 * _phei) : _phei; - return new Dimension(wid, hei); - } - - /** The drop board view from which we obtain piece images. */ - protected DropBoardView _view; - - /** The pieces displayed by this view. */ - protected int[] _pieces; - - /** The piece dimensions in pixels. */ - protected int _pwid, _phei; - - /** The view orientation; one of {@link #HORIZONTAL} or {@link - * #VERTICAL}. */ - protected int _orient; -} diff --git a/src/java/com/threerings/puzzle/drop/client/PieceGroupAnimation.java b/src/java/com/threerings/puzzle/drop/client/PieceGroupAnimation.java deleted file mode 100644 index 3b8e6ccbc..000000000 --- a/src/java/com/threerings/puzzle/drop/client/PieceGroupAnimation.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// $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.puzzle.drop.client; - -import java.awt.Graphics2D; -import java.awt.Rectangle; - -import com.threerings.media.animation.Animation; -import com.threerings.media.sprite.ImageSprite; -import com.threerings.media.sprite.PathObserver; -import com.threerings.media.sprite.Sprite; -import com.threerings.media.util.Path; - -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropPieceCodes; - -/** - * Animates all the pieces on a puzzle board doing some sort of global - * effect like all flying into place or out into the ether. - */ -public abstract class PieceGroupAnimation extends Animation - implements PathObserver -{ - /** - * Creates a piece group animation which must be initialized with a - * subsequent call to {@link #init}. - */ - public PieceGroupAnimation (DropBoardView view, DropBoard board) - { - super(new Rectangle(0, 0, 0, 0)); // we don't render ourselves - _view = view; - _board = board; - } - - // documentation inherited - public void tick (long tickStamp) - { - // nothing doing - } - - // documentation inherited - public void paint (Graphics2D gfx) - { - // nothing doing - } - - // documentation inherited from interface - public void pathCancelled (Sprite sprite, Path path) - { - _finished = (--_penders == 0); - } - - // documentation inherited from interface - public void pathCompleted (Sprite sprite, Path path, long when) - { - _finished = (--_penders == 0); - } - - // documentation inherited - protected void willStart (long tickStamp) - { - super.willStart(tickStamp); - - // create an image sprite for every piece on the board and set - // them on their paths - int width = _board.getWidth(), height = _board.getHeight(); - _sprites = new Sprite[width * height]; - for (int yy = 0; yy < height; yy++) { - for (int xx = 0; xx < width; xx++) { - int spos = yy*width+xx; - _sprites[spos] = _view.getPieceSprite(xx, yy); - if (_sprites[spos] != null) { - configureSprite(_sprites[spos], xx, yy); - _sprites[spos].addSpriteObserver(this); - _penders++; - } - } - } - } - - /** - * An animation must override this method to configure each sprite - * with a path, potentially a render order, and whatever other - * configurations are needed. - */ - protected abstract void configureSprite (Sprite sprite, int xx, int yy); - - protected DropBoardView _view; - protected DropBoard _board; - protected Sprite[] _sprites; - protected int _penders; -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropBoard.java b/src/java/com/threerings/puzzle/drop/data/DropBoard.java deleted file mode 100644 index e912e4052..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropBoard.java +++ /dev/null @@ -1,887 +0,0 @@ -// -// $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.puzzle.drop.data; - -import java.awt.Point; -import java.awt.Rectangle; -import java.util.Arrays; - -import org.apache.commons.lang.StringUtils; - -import com.threerings.util.DirectionUtil; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.drop.client.DropControllerDelegate; -import com.threerings.puzzle.drop.util.DropBoardUtil; - -/** - * A class that provides for various useful logical operations to be - * enacted on a two-dimensional board and provides an easier mechanism for - * referencing pieces by position. - */ -public class DropBoard extends Board - implements DropPieceCodes -{ - /** The rotation constant for rotation around a central piece. */ - public static final int RADIAL_ROTATION = 0; - - /** The rotation constant for rotation wherein the block occupies the - * same columns when rotating. */ - public static final int INPLACE_ROTATION = 1; - - /** An operation that does naught but clear pieces, which proves to be - * generally useful. */ - public static final PieceOperation CLEAR_OP = new PieceOperation () { - public boolean execute (DropBoard board, int col, int row) { - board.setPiece(col, row, PIECE_NONE); - return true; - } - }; - - /** - * An interface to be implemented by classes that would like to apply - * some operation to each piece in a column or row segment in the - * board. - */ - public interface PieceOperation - { - /** - * Called for each piece in the board segment the operation is - * being applied to. - * - * @return true if the operation should continue to be applied if - * being applied to multiple pieces, or false if it should - * terminate after this application. - */ - public boolean execute (DropBoard board, int col, int row); - } - - /** - * Constructs an empty drop board for use when unserializing. - */ - public DropBoard () - { - this(null, 0, 0); - } - - /** - * Constructs a drop board of the given dimensions with its - * pieces initialized to PIECE_NONE. - */ - public DropBoard (int bwid, int bhei) - { - this(new int[bwid*bhei], bwid, bhei); - fill(PIECE_NONE); - } - - /** - * Constructs a drop board of the given dimensions with its - * pieces initialized to the given piece. - */ - public DropBoard (int bwid, int bhei, int piece) - { - this(new int[bwid*bhei], bwid, bhei); - fill(piece); - } - - /** - * Constructs a drop board with the given board and dimensions. - */ - public DropBoard (int[] board, int bwid, int bhei) - { - _board = board; - _bwid = bwid; - _bhei = bhei; - } - - /** - * Returns the width of the board in columns. - */ - public int getWidth() - { - return _bwid; - } - - /** - * Returns the height of the board in rows. - */ - public int getHeight() - { - return _bhei; - } - - /** - * Returns the piece at the given column and row in the board. - */ - public int getPiece (int col, int row) - { - try { - return _board[(row*_bwid) + col]; - } catch (Exception e) { - Log.warning("Failed getting piece [col=" + col + - ", row=" + row + ", error=" + e + "]."); - Log.logStackTrace(e); - return -1; - } - } - - /** - * For boards that are always filled, this method is called to obtain - * pieces to fill the board. - */ - public int getNextPiece () - { - return PIECE_NONE; - } - - /** - * Returns the distance the piece at the given column and row can drop - * until it hits a non-empty piece (defined as {@link #PIECE_NONE}). - */ - public int getDropDistance (int col, int row) - { - int dist = 0; - for (int yy = row + 1; yy < _bhei; yy++) { - if (getPiece(col, yy) != PIECE_NONE) { - return dist; - } - dist++; - } - return dist; - } - - /** - * Returns whether the given row in the board is empty. - */ - public boolean isRowEmpty (int row) - { - for (int col = 0; col < _bwid; col++) { - if (getPiece(col, row) != PIECE_NONE) { - return false; - } - } - return true; - } - - /** - * Returns whether all of the pieces at the given coordinates can be - * dropped one row. - */ - public boolean isValidDrop (int[] rows, int[] cols, float pctdone) - { - int bottom = _bhei - 1; - for (int ii = 0; ii < rows.length; ii++) { - // pieces at bottom can't be dropped - if (rows[ii] >= bottom) { - return false; - } - - // pieces with pieces below them can't be dropped - int row = rows[ii] + 1; - if (row >= 0 && getPiece(cols[ii], row) != PIECE_NONE) { - return false; - } - } - - return true; - } - - /** - * Returns true if the specified coordinate is within the bounds of - * the board, false if it is not. - */ - public boolean inBounds (int col, int row) - { - return (col >= 0 && row >= 0 && col < getWidth() && row < getHeight()); - } - - /** - * Returns whether the specified block in the board is empty. The - * block is allowed to occupy space off the top of the board as long - * as it is within the horizontal board bounds. - * - * @param col the left coordinate of the block. - * @param row the bottom coordinate of the block. - * @param wid the width of the block. - * @param hei the height of the block. - */ - public boolean isBlockEmpty (int col, int row, int wid, int hei) - { - for (int ypos = row; ypos > (row - hei); ypos--) { - for (int xpos = col; xpos < (col + wid); xpos++) { - // only allow movement off the top of the board that's - // within the horizontal screen bounds and in a column - // that's not topped out - if (ypos < 0) { - if ((xpos < 0 || xpos >= _bwid) || - (getPiece(xpos, 0) != PIECE_NONE)) { - return false; - } else { - continue; - } - } - - // don't allow movement outside the side or bottom bounds - if (xpos < 0 || - xpos >= _bwid || - ypos >= _bhei) { - return false; - } - - // make sure no piece is present - if (getPiece(xpos, ypos) != PIECE_NONE) { - return false; - } - } - } - - return true; - } - - /** - * Rotates the given block in the given direction and returns its - * final state as (orient, col, row, popped), where - * orient is the final orientation of the drop block; - * col and row are the final column and row - * coordinates, respectively, of the central drop block piece. - * popped will be set to 1 if the piece was popped up, 0 - * otherwise. - */ - public int[] getForgivingRotation ( - int[] rows, int[] cols, int orient, int dir, int rtype, float pctdone, - boolean canPopup) - { - int px = cols[0], py = rows[0]; - -// Log.info("Starting rotation [px=" + px + ", py=" + py + -// ", orient=" + orient + ", pctdone=" + pctdone + "]."); - - // try rotating the block in the given direction through all four - // possible orientations - for (int ii = 0; ii < 4; ii++) { - int oidx = orient/2; - - // adjust the position of the central piece - px += ROTATE_DX[rtype][dir][oidx]; - py += ROTATE_DY[rtype][dir][oidx]; - - // update the orientation - orient = DropBoardUtil.getRotatedOrientation(orient, dir); - oidx = orient/2; - - // because isBlockEmpty() always assumes the origin of the - // block is in the lower-left, we need to adjust the - // coordinates of the drop block's "central" piece accordingly - int ox = px + ORIENT_ORIGIN_DX[oidx]; - int oy = py + ORIENT_ORIGIN_DY[oidx]; - - // if we're less than 50 percent through with our fall, we - // want to check our current coordinates for validity; if - // we're more, we want to check the row below our current - // coordinates - if (pctdone > 0.5) { - oy += 1; - } - - // try each of three coercions: nothing, one left, one right - for (int c = 0; c < COERCE_DX.length; c++) { - int cx = COERCE_DX[c]; - // check if our hypothetical new coordinates are empty - if (isBlockEmpty(ox + cx, oy, - ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) { -// Log.info( -// "Block is empty [ox=" + ox + ", cx=" + cx + -// ", oy=" + oy + ", oidx=" + oidx + -// ", orient=" + DirectionUtil.toShortString(orient) + -// ", owid=" + ORIENT_WIDTHS[oidx] + -// ", ohei=" + ORIENT_HEIGHTS[oidx] + "]."); - return new int[] { orient, px + cx, py, 0 }; - } - } - - // if our piece is facing south and we're using radial - // rotation then we need to try popping the piece up a row to - // check for a fit - if (canPopup && rtype == RADIAL_ROTATION && orient == SOUTH) { - // check if our hypothetical new coordinates are empty - if (isBlockEmpty(ox, oy - 1, - ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) { -// Log.info( -// "Popped-up block is empty [ox=" + ox + -// ", oy=" + (oy - 1) + ", oidx=" + oidx + -// ", orient=" + DirectionUtil.toShortString(orient) + -// ", owid=" + ORIENT_WIDTHS[oidx] + -// ", ohei=" + ORIENT_HEIGHTS[oidx] + -// ", bhei=" + _bhei + "]."); - return new int[] { orient, px, py - 1, 1 }; - } - } - } - - // this should never happen since even in the most tightly - // constrained case where the block is entirely surrounded by - // other pieces there are always two valid orientations. - Log.warning("**** We're horked and couldn't rotate at all!"); -// System.exit(0); - return null; - } - - /** - * Returns a {@link Point} object containing the coordinates to place - * the bottom-left of the given block at after moving it the given - * distance on the x- and y-axes, or null if the move is - * not valid. Note that only the final block position is checked. - * - * @param col the leftmost column of the block. - * @param row the bottommost row of the block. - * @param wid the width of the block. - * @param hei the height of the block. - * @param dx the distance to move the block in columns. - * @param dy the distance to move the block in rows. - * @param pctdone the percentage of the inter-block distance that the - * piece has fallen thus far. - */ - public Point getForgivingMove ( - int col, int row, int wid, int hei, int dx, int dy, float pctdone) - { - // try placing the block in the desired position and, failing - // that, at the same horizontal position but one row farther down - int xpos = col + dx, ypos = row + dy; - - // if we're above the halfway mark, we check our current neighbors - // to see if we can move there; if we're below the halfway mark we - // check the next row down - if (pctdone >= 0.5) { - ypos += 1; - } - - // if the block we wish to occupy is empty, we're all good - return (isBlockEmpty(xpos, ypos, wid, hei)) ? - new Point(xpos, row + dy) : null; - } - - /** - * Populates the given array with the column levels for this board. - */ - public void getColumnLevels (byte[] columns) - { - int bwid = getWidth(), bhei = getHeight(); - for (int col = 0; col < bwid; col++) { - int dist = getDropDistance(col, -1); - columns[col] = (byte)(bhei - dist); - } - } - - /** - * Called by the {@link DropControllerDelegate} when it's time to - * apply a rising row of pieces to the board. Shifts all of the - * pieces in the given board up one row and places the given row of - * pieces at the bottom of the board. - */ - public void applyRisingPieces (int[] pieces) - { - // shift all pieces up one row - int end = _bhei - 1; - for (int yy = 0; yy < end; yy++) { - for (int xx = 0; xx < _bwid; xx++) { - setPiece(xx, yy, getPiece(xx, yy + 1)); - } - } - - // apply the row pieces to the board - int ypos = _bhei - 1; - for (int xx = 0; xx < _bwid; xx++) { - setPiece(xx, ypos, pieces[xx]); - } - } - - /** - * Returns true if the specified row (which count down, with zero at - * the top of the board) contains any pieces. - * - * @param row the row to check for pieces. - * @param blankPiece the blank piece value, non-instances of which - * will be sought. - */ - public boolean rowContainsPieces (int row, int blankPiece) - { - for (int x = 0; x < _bwid; x++) { - if (getPiece(x, row) != blankPiece) { - return true; - } - } - return false; - } - - /** - * Fills the board contents with the given piece. - */ - public void fill (int piece) - { - Arrays.fill(_board, (int)piece); - } - - /** - * Sets the piece at the given coordinates. - * - * @return true if the piece was set, false if it was invalid. - */ - public boolean setPiece (int col, int row, int piece) - { - if (col >= 0 && row >= 0 && col < _bwid && row < _bhei) { - _board[(row*_bwid) + col] = (int)piece; - return true; - - } else { - Log.warning("Attempt to set piece outside board bounds " + - "[col=" + col + ", row=" + row + ", p=" + piece + "]."); - return false; - } - } - - /** - * Sets the pieces within the specified rectangle to the given piece. - */ - public void setRect (int x, int y, int width, int height, int piece) - { - for (int yy = y; yy > (y - height); yy--) { - for (int xx = x; xx < (x + width); xx++) { - setPiece(xx, yy, piece); - } - } - } - - /** - * Sets the pieces in the given board segment to the specified piece. - * - * @param dir the direction of the segment; one of {@link #HORIZONTAL} - * or {@link #VERTICAL}. - * @param col the starting column of the segment. - * @param row the starting row of the segment. - * @param len the length of the segment in pieces. - * @param piece the piece to set in the segment. - * - * @return false if the segment was only partially applied because - * some pieces were outside the bounds of the board, true if it was - * completely applied. - */ - public boolean setSegment (int dir, int col, int row, int len, int piece) - { - _setPieceOp.init(piece); - applyOp(dir, col, row, len, _setPieceOp); - return !_setPieceOp.getError(); - } - - /** - * Sets the pieces in the given board segment to the specified pieces. - * - * @param dir the direction of the segment; one of {@link #HORIZONTAL} - * or {@link #VERTICAL}. - * @param col the starting column of the segment. - * @param row the starting row of the segment. - * @param pieces the pieces to set in the segment. - */ - public void setSegment (int dir, int col, int row, int[] pieces) - { - _setSegmentOp.init(dir, pieces); - applyOp(dir, col, row, pieces.length, _setSegmentOp); - } - - /** - * Applies a specified {@link PieceOperation} to all pieces in the - * specified row or column starting at the specified coordinates and - * spanning the remainder of the row or column (depending on the - * application direction) in the board. - * - * @param dir the direction to iterate in; one of {@link #HORIZONTAL} - * or {@link #VERTICAL}. - * @param col the starting column of the segment. - * @param row the starting row of the segment. - * @param op the piece operation to apply to each piece. - */ - public void applyOp (int dir, int col, int row, PieceOperation op) - { - int len = (dir == HORIZONTAL) ? _bwid - col : row + 1; - applyOp(dir, col, row, len, op); - } - - /** - * Applies a specified {@link PieceOperation} to all pieces in a row - * or column segment starting at the specified coordinates and of the - * specified length in the board. - * - * @param dir the direction to iterate in; one of {@link #HORIZONTAL} - * or {@link #VERTICAL}. - * @param col the starting leftmost column of the segment. - * @param row the starting bottommost row of the segment. - * @param len the number of pieces in the segment. - * @param op the piece operation to apply to each piece. - */ - public void applyOp (int dir, int col, int row, int len, PieceOperation op) - { - if (dir == HORIZONTAL) { - int end = Math.min(col + len, _bwid); - for (int ii = col; ii < end; ii++) { - if (!op.execute(this, ii, row)) { - break; - } - } - - } else { - int end = Math.max(row - len, -1); - for (int ii = row; ii > end; ii--) { - if (!op.execute(this, col, ii)) { - break; - } - } - } - } - - /** - * Applies a specified {@link PieceOperation} to the specified piece - * in the board. - * - * @param col the column of the piece. - * @param row the row of the piece. - * @param op the piece operation to apply to the piece. - */ - public void applyOp (int col, int row, PieceOperation op) - { - op.execute(this, col, row); - } - - // documentation inherited from interface - public void dump () - { - dumpAndCompare(null); - } - - // documentation inherited from interface - public void dumpAndCompare (Board other) - { - if (other != null && !(other instanceof DropBoard)) { - throw new IllegalArgumentException( - "Can't compare drop board to non-drop-board."); - } - - DropBoard dother = (DropBoard)other; - int padwid = getPadWidth(); - if (other != null) { - // padwid = (padwid * 2) + 1; - padwid *= 2; - } - - for (int y = 0; y < _bhei; y++) { - StringBuilder buf = new StringBuilder(); - for (int x = 0; x < _bwid; x++) { - int piece = getPiece(x, y); - String str = formatPiece(piece); - if (dother != null) { - int opiece = dother.getPiece(x, y); - if (opiece != piece) { - str += "|" + formatPiece(opiece); - } - } - buf.append(StringUtils.rightPad(str, padwid)); - } - System.err.println(buf.toString()); - } - } - - /** Returns a string representation of this instance. */ - public String toString () - { - StringBuilder buf = new StringBuilder(); - buf.append("[wid=").append(_bwid); - buf.append(", hei=").append(_bhei); - return buf.append("]").toString(); - } - - // documentation inherited from interface - public boolean equals (Board other) - { - // make sure we're comparing the same class type - if (!this.getClass().getName().equals(other.getClass().getName())) { - throw new IllegalArgumentException( - "Can't compare board of different class types " + - "[src=" + this.getClass().getName() + - ", other=" + other.getClass().getName() + "]."); - } - - // we're certainly not equal if our dimensions differ - DropBoard dother = (DropBoard)other; - if (dother.getWidth() != _bwid || - dother.getHeight() != _bhei) { - return false; - } - - // check each board piece - for (int xx = 0; xx < _bwid; xx++) { - for (int yy = 0; yy < _bhei; yy++) { - if (getPiece(xx, yy) != dother.getPiece(xx, yy)) { - return false; - } - } - } - - // we're equal - return true; - } - - /** - * Returns whether the given coordinates are within the board bounds. - */ - public boolean isValidPosition (int x, int y) - { - return (x >= 0 && - y >= 0 && - x < _bwid && - y < _bhei); - } - - /** - * Returns the bounds of this board. Note that a single rectangle is - * re-used internally and so the caller should not modify the - * returned rectangle. - */ - public Rectangle getBounds () - { - if (_bounds == null) { - _bounds = new Rectangle(0, 0, _bwid, _bhei); - } - return _bounds; - } - - /** - * Returns the size of the board in pieces. - */ - public int size () - { - return (_bwid*_bhei); - } - - /** - * Copies the contents of this board directly into the supplied board, - * overwriting the destination board in its entirety. - */ - public void copyInto (DropBoard board) - { - // make sure the target board is a valid target - if (board.getWidth() != _bwid || board.getHeight() != _bhei) { - Log.warning("Can't copy board into destination board with " + - "different dimensions [src=" + this + - ", dest=" + board + "]."); - return; - } - - // copy our pieces directly into the board, avoiding any unsightly - // object allocation which is largely the point of this method, - // after all. - int[] dest = ((DropBoard)board).getBoard(); - System.arraycopy(_board, 0, dest, 0, (_bwid*_bhei)); - } - - /** - * Returns the raw board data associated with this board. One - * shouldn't fiddle about with this unless one knows what one is - * doing. - */ - public int[] getBoard () - { - return _board; - } - - /** - * Sets the board data and board dimensions. - */ - public void setBoard (int[] board, int bwid, int bhei) - { - _board = board; - _bwid = bwid; - _bhei = bhei; - } - - /** - * Sets the board pieces. - */ - public void setBoard (int[] board) - { - int size = (_bwid*_bhei); - if (board.length < size) { - Log.warning("Attempt to set board with invalid data size " + - "[len=" + board.length + ", expected=" + size + "]."); - return; - } - - _board = board; - } - - // documentation inherited - public Object clone () - { - DropBoard board = (DropBoard)super.clone(); - board._board = (int[])_board.clone(); - return board; - } - - /** - * Returns the number of characters to which a single piece should be - * padded when dumping the board for debugging purposes. - */ - protected int getPadWidth () - { - return DEFAULT_PAD_WIDTH; - } - - /** - * Returns a string representation of the given piece for use when - * dumping the board. - */ - protected String formatPiece (int piece) - { - return (piece == PIECE_NONE) ? "." : String.valueOf(piece); - } - - /** An operation that sets the pieces in a board segment to a - * specified array of pieces. */ - protected static class SetSegmentOperation implements PieceOperation - { - /** - * Sets the array of pieces to be placed in the board segment. - */ - public void init (int dir, int[] pieces) - { - _dir = dir; - _pieces = pieces; - _idx = (dir == HORIZONTAL) ? _pieces.length - 1 : 0; - } - - // documentation inherited - public boolean execute (DropBoard board, int col, int row) - { - if (_dir == HORIZONTAL) { - board.setPiece(col, row, _pieces[_idx--]); - } else { - board.setPiece(col, row, _pieces[_idx++]); - } - return true; - } - - /** The orientation in which the pieces are to be placed. */ - protected int _dir; - - /** The current piece index. */ - protected int _idx; - - /** The pieces to set in the board. */ - protected int[] _pieces; - } - - /** An operation that sets all pieces to a specified piece. */ - protected static class SetPieceOperation implements PieceOperation - { - /** - * Sets the piece to be placed in the board segment. - */ - public void init (int piece) - { - _piece = piece; - _error = false; - } - - /** - * Returns true if we attempted to set a piece outside the bounds - * of the board during the course of our operation. - */ - public boolean getError () - { - return _error; - } - - // documentation inherited - public boolean execute (DropBoard board, int col, int row) - { - if (!board.setPiece(col, row, _piece)) { - _error = true; - } - return true; - } - - /** The piece to set in the board. */ - protected int _piece; - - /** Set to true if an error occurred setting a piece. */ - protected boolean _error; - } - - /** The board data. */ - protected int[] _board; - - /** The board dimensions in pieces. */ - protected int _bwid, _bhei; - - /** The bounds of this board. */ - protected transient Rectangle _bounds; - - // used to reconfigure the block when rotating it - protected static final int[][][] ROTATE_DX = { - // W N E S W N E S - {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }}, // RADIAL - {{ -1, 1, 0, 0 }, { -1, 0, 0, 1 }}, // INPLACE - // CCW CW - }; - - // used to reconfigure the block when rotating it - protected static final int[][][] ROTATE_DY = { - // W N E S W N E S - {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }}, // RADIAL - {{ -1, 0, 0, 1 }, { 0, 0, -1, 1 }}, // INPLACE - // CCW CW - }; - - // used to compute the bounds of the isBlockEmpty() block based on the - // drop block's orientation and "root" block position - protected static final int[] ORIENT_WIDTHS = { 2, 1, 2, 1 }; - protected static final int[] ORIENT_HEIGHTS = { 1, 2, 1, 2 }; - - // used to compute the origin of the isBlockEmpty() block based on the - // drop block's orientation and "root" block position - protected static final int[] ORIENT_ORIGIN_DX = { -1, 0, 0, 0 }; - protected static final int[] ORIENT_ORIGIN_DY = { 0, 0, 0, 1 }; - - // used to coerce the block when rotating either a space to the left - // or right (or not at all) - protected static final int[] COERCE_DX = { 0, 1, -1 }; - - /** The operation used to set the pieces in a board segment. */ - protected static final SetSegmentOperation _setSegmentOp = - new SetSegmentOperation(); - - /** The operation used to set a piece in a board segment. */ - protected static final SetPieceOperation _setPieceOp = - new SetPieceOperation(); - - /** The number of characters to which each board piece should be - * padded when outputting for debug purposes. */ - protected static final int DEFAULT_PAD_WIDTH = 3; -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropBoardSummary.java b/src/java/com/threerings/puzzle/drop/data/DropBoardSummary.java deleted file mode 100644 index 390ee30ef..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropBoardSummary.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// $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.puzzle.drop.data; - -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.BoardSummary; - -/** - * Provides a summary of a {@link DropBoard}. - */ -public class DropBoardSummary extends BoardSummary -{ - /** The row levels for each column. */ - public byte[] columns; - - /** - * Constructs an empty drop board summary for use when un-serializing. - */ - public DropBoardSummary () - { - // nothing for now - } - - /** - * Constructs a drop board summary that retrieves board information - * from the supplied board when summarizing. - */ - public DropBoardSummary (Board board) - { - super(board); - } - - /** - * Returns the column number of the column within the given column - * range that contains the most pieces. - */ - public int getHighestColumn (int startx, int endx) - { - byte value = columns[startx]; - int idx = startx; - for (int xx = startx + 1; xx <= endx; xx++) { - if (columns[xx] > value) { - value = columns[xx]; - idx = xx; - } - } - return idx; - } - - // documentation inherited - public void setBoard (Board board) - { - _dboard = (DropBoard)board; - // create the columns array - columns = new byte[_dboard.getWidth()]; - - super.setBoard(board); - } - - // documentation inherited - public void summarize () - { - // update the board column levels - _dboard.getColumnLevels(columns); - } - - /** The drop board we're summarizing. */ - protected transient DropBoard _dboard; -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropCodes.java b/src/java/com/threerings/puzzle/drop/data/DropCodes.java deleted file mode 100644 index f07689135..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropCodes.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $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.puzzle.drop.data; - -import com.threerings.puzzle.data.PuzzleGameCodes; - -/** - * Contains codes used by the drop game services. - */ -public interface DropCodes extends PuzzleGameCodes -{ - /** The message bundle identifier for drop puzzle messages. */ - public static final String DROP_MESSAGE_BUNDLE = "puzzle.drop"; - - /** The name of the control stream that provides drop pieces. */ - public static final String DROP_STREAM = "drop"; - - /** The name of the control stream that provides rise pieces. */ - public static final String RISE_STREAM = "rise"; -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropConfig.java b/src/java/com/threerings/puzzle/drop/data/DropConfig.java deleted file mode 100644 index 1592589d6..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.puzzle.drop.data; - -/** - * Provides access to the configuration information for a drop puzzle - * game. - */ -public interface DropConfig -{ - /** Returns the board width in pieces. */ - public int getBoardWidth (); - - /** Returns the board height in pieces. */ - public int getBoardHeight (); -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropLogic.java b/src/java/com/threerings/puzzle/drop/data/DropLogic.java deleted file mode 100644 index bde1de2ef..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropLogic.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// $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.puzzle.drop.data; - -/** - * Describes the features and configuration desired for a given drop - * puzzle game. - */ -public interface DropLogic -{ - /** - * Returns whether the puzzle game would like to make use of the - * manipulable block dropping functionality. - */ - public boolean useBlockDropping (); - - /** - * Returns whether the puzzle game would like to make use of the - * rising board functionality. - */ - public boolean useBoardRising (); -} diff --git a/src/java/com/threerings/puzzle/drop/data/DropPieceCodes.java b/src/java/com/threerings/puzzle/drop/data/DropPieceCodes.java deleted file mode 100644 index 87db82a39..000000000 --- a/src/java/com/threerings/puzzle/drop/data/DropPieceCodes.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// $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.puzzle.drop.data; - -import com.threerings.util.DirectionCodes; - -/** - * The drop piece codes interface contains constants common to the drop - * game package. - */ -public interface DropPieceCodes extends DirectionCodes -{ - /** The piece constant denoting an empty board piece. */ - public static final byte PIECE_NONE = -1; - - /** The number of pieces in a drop block. */ - public static final int DROP_BLOCK_PIECE_COUNT = 2; -} diff --git a/src/java/com/threerings/puzzle/drop/data/SegmentInfo.java b/src/java/com/threerings/puzzle/drop/data/SegmentInfo.java deleted file mode 100644 index 18788ec22..000000000 --- a/src/java/com/threerings/puzzle/drop/data/SegmentInfo.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $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.puzzle.drop.data; - -import com.samskivert.util.StringUtil; -import com.threerings.util.DirectionCodes; - -/** - * Describes a segment of pieces in a {@link DropBoard}. - */ -public class SegmentInfo -{ - /** The segment's direction; one of {@link DirectionCodes#HORIZONTAL} - * or {@link DirectionCodes#VERTICAL}. */ - public int dir; - - /** The segment's lower-left board coordinates. */ - public int x, y; - - /** The segment's length in pieces. */ - public int len; - - /** - * Constructs a segment info object. - */ - public SegmentInfo (int dir, int x, int y, int len) - { - this.dir = dir; - this.x = x; - this.y = y; - this.len = len; - } - - /** - * Returns a string representation of this instance. - */ - public String toString () - { - return StringUtil.fieldsToString(this); - } -} diff --git a/src/java/com/threerings/puzzle/drop/server/DropManagerDelegate.java b/src/java/com/threerings/puzzle/drop/server/DropManagerDelegate.java deleted file mode 100644 index caa47277b..000000000 --- a/src/java/com/threerings/puzzle/drop/server/DropManagerDelegate.java +++ /dev/null @@ -1,174 +0,0 @@ -// -// $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.puzzle.drop.server; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.server.PuzzleManager; -import com.threerings.puzzle.server.PuzzleManagerDelegate; - -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropCodes; -import com.threerings.puzzle.drop.data.DropConfig; -import com.threerings.puzzle.drop.data.DropLogic; -import com.threerings.puzzle.drop.util.PieceDropLogic; -import com.threerings.puzzle.drop.util.PieceDropper; - -/** - * Provides the necessary support for a puzzle game that involves a - * two-dimensional board containing pieces, with new pieces either falling - * into the board as a "drop block", or rising into the bottom of the - * board in new piece rows, groups of blocks can be "broken" and garbage - * can be sent to other players' boards as a result. This is implemented - * as a delegate so that the natural hierarchy need not be twisted to - * differentiate between puzzles that use piece dropping and those that - * don't. Because we have need to structure our hierarchy around things - * like whether a puzzle is a duty puzzle, this becomes necessary. - * - *

A puzzle game using these services will then need to extend this - * delegate, implementing the necessary methods to customize it for the - * particulars of their game and then register it with their game manager - * via {@link PuzzleManager#addDelegate}. - * - *

It also keeps track of, for each player, board level information, - * and player game status. Miscellaneous utility routines are provided - * for checking things like whether the game is over, whether a player is - * still active in the game, and so forth. - * - *

Derived classes are likely to want to override {@link - * #getPieceDropLogic}. - */ -public abstract class DropManagerDelegate extends PuzzleManagerDelegate - implements PuzzleCodes, DropCodes -{ - /** - * Provides the delegate with a reference to the manager for which it - * is delegating as well as the logic object that it uses to determine - * how to manage the drop puzzle. - */ - public DropManagerDelegate (PuzzleManager puzmgr, DropLogic logic) - { - super(puzmgr); - - // configure the game-specific settings - _usedrop = logic.useBlockDropping(); - _userise = logic.useBoardRising(); - if (_usedrop && _userise) { - Log.warning("Can't use dropping blocks and board rising "+ - "functionality simultaneously in a drop puzzle game! " + - "Falling back to straight dropping."); - _userise = false; - } - } - - // documentation inherited - public void didInit (PlaceConfig config) - { - _dconfig = (DropConfig)config; - - // save things off - _bwid = _dconfig.getBoardWidth(); - _bhei = _dconfig.getBoardHeight(); - - super.didInit(config); - } - - // documentation inherited - public void didStartup (PlaceObject plobj) - { - super.didStartup(plobj); - - // initialize the drop board array - _dboards = new DropBoard[_puzmgr.getPlayerCount()]; - - // create the piece dropper if appropriate - PieceDropLogic pdl = getPieceDropLogic(); - if (pdl != null) { - _dropper = new PieceDropper(pdl); - } - } - - // documentation inherited - public void gameWillStart () - { - super.gameWillStart(); - - // get casted references to all player drop boards - Board[] board = _puzmgr.getBoards(); - for (int ii = 0; ii < _puzmgr.getPlayerCount(); ii++) { - _dboards[ii] = (DropBoard)board[ii]; - } - } - - /** - * Drops any pieces that need dropping on the given player's board and - * returns whether any pieces were dropped. - */ - protected boolean dropPieces (DropBoard board) - { - return (_dropper.dropPieces(board, null) > 0); - } - - /** - * Returns the piece drop logic used to drop any pieces that need - * dropping in the board. - */ - protected PieceDropLogic getPieceDropLogic () - { - return null; - } - - /** - * This method should be called by derived classes whenever the player - * successfully places a drop block. - */ - protected void placedBlock (int pidx) - { - } - - /** The drop game board for each player. */ - protected DropBoard[] _dboards; - - /** The drop game config object. */ - protected DropConfig _dconfig; - - /** Whether the game is using drop block functionality. */ - protected boolean _usedrop; - - /** Whether the game is using board rising functionality. */ - protected boolean _userise; - - /** The board dimensions in pieces. */ - protected int _bwid, _bhei; - - /** The piece dropper used to drop pieces in the board if the puzzle - * chooses to make use of piece dropping functionality. */ - protected PieceDropper _dropper; - - /** Used to limit the maximum number of board update loops permitted - * before assuming something's gone horribly awry and aborting. */ - protected static final int MAX_UPDATE_LOOPS = 100; -} diff --git a/src/java/com/threerings/puzzle/drop/util/DropBoardUtil.java b/src/java/com/threerings/puzzle/drop/util/DropBoardUtil.java deleted file mode 100644 index b29a8bfff..000000000 --- a/src/java/com/threerings/puzzle/drop/util/DropBoardUtil.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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.puzzle.drop.util; - -import com.threerings.util.DirectionCodes; - -public class DropBoardUtil - implements DirectionCodes -{ - /** - * Returns the orientation resulting from rotating the block in the - * given direction the specified number of times. - * - * @param orient the current orientation. - * @param dir the direction to rotate in; one of CW or - * CCW. - * @param count the number of rotations to perform. - * - * @return the rotated orientation. - */ - public static int getRotatedOrientation (int orient, int dir, int count) - { - for (int ii = 0; ii < (count % 4); ii++) { - orient = getRotatedOrientation(orient, dir); - } - return orient; - } - - /** - * Returns the orientation resulting from rotating the block in - * the given direction. - * - * @param orient the current orientation. - * @param dir the direction to rotate in; one of CW or - * CCW. - * - * @return the rotated orientation. - */ - public static int getRotatedOrientation (int orient, int dir) - { - return (orient + ((dir == CW) ? 2 : 6)) % DIRECTION_COUNT; - } -} diff --git a/src/java/com/threerings/puzzle/drop/util/DropGameUtil.java b/src/java/com/threerings/puzzle/drop/util/DropGameUtil.java deleted file mode 100644 index cabee520c..000000000 --- a/src/java/com/threerings/puzzle/drop/util/DropGameUtil.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// $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.puzzle.drop.util; - -import java.awt.event.KeyEvent; - -import com.threerings.util.KeyTranslatorImpl; - -import com.threerings.puzzle.drop.client.DropControllerDelegate; -import com.threerings.puzzle.util.PuzzleGameUtil; - -/** - * Drop puzzle game related utilities. - */ -public class DropGameUtil -{ - /** - * Returns a key translator configured with mappings suitable for a - * drop puzzle game. - */ - public static KeyTranslatorImpl getKeyTranslator () - { - // start with the standard puzzle key mappings - KeyTranslatorImpl xlate = PuzzleGameUtil.getKeyTranslator(); - - // add all press key mappings - xlate.addPressCommand(KeyEvent.VK_LEFT, - DropControllerDelegate.MOVE_BLOCK_LEFT, - MOVE_RATE, MOVE_DELAY); - xlate.addPressCommand(KeyEvent.VK_RIGHT, - DropControllerDelegate.MOVE_BLOCK_RIGHT, - MOVE_RATE, MOVE_DELAY); - xlate.addPressCommand(KeyEvent.VK_UP, - DropControllerDelegate.ROTATE_BLOCK_CCW, 0); - xlate.addPressCommand(KeyEvent.VK_DOWN, - DropControllerDelegate.ROTATE_BLOCK_CW, 0); - xlate.addPressCommand(KeyEvent.VK_SPACE, - DropControllerDelegate.START_DROP_BLOCK, 0); - - // add all release key mappings - xlate.addReleaseCommand(KeyEvent.VK_SPACE, - DropControllerDelegate.END_DROP_BLOCK); - - return xlate; - } - - /** The move key repeat rate in moves per second. */ - protected static final int MOVE_RATE = 7; - - /** The delay in milliseconds before the move keys begin to repeat. */ - protected static final long MOVE_DELAY = 300L; -} diff --git a/src/java/com/threerings/puzzle/drop/util/PieceDestroyer.java b/src/java/com/threerings/puzzle/drop/util/PieceDestroyer.java deleted file mode 100644 index 50954ecc8..000000000 --- a/src/java/com/threerings/puzzle/drop/util/PieceDestroyer.java +++ /dev/null @@ -1,181 +0,0 @@ -// -// $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.puzzle.drop.util; - -import java.util.ArrayList; -import java.util.List; - -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropBoard.PieceOperation; -import com.threerings.puzzle.drop.data.DropPieceCodes; -import com.threerings.puzzle.drop.data.SegmentInfo; - -/** - * Handles destroying contiguous piece segments in a drop board. - */ -public class PieceDestroyer - implements DropPieceCodes -{ - /** - * An interface to be implemented by specific puzzles to detail the - * parameters and methodology by which pieces are destroyed in the - * puzzle board. - */ - public interface DestroyLogic - { - /** - * Returns the minimum length of a contiguously piece segment that - * should be destroyed. - */ - public int getMinimumLength (); - - /** - * Returns whether piece a is equivalent to piece - * b for the purposes of including it in a contiguous - * piece segment to be destroyed. - */ - public boolean isEquivalent (int a, int b); - } - - /** - * Constructs a piece destroyer that destroys pieces as specified by - * the supplied destroy logic. - */ - public PieceDestroyer (DestroyLogic logic) - { - _logic = logic; - } - - /** - * Destroys all pieces in the given board that are in contiguous rows - * or columns of pieces, returning a list of {@link SegmentInfo} - * objects detailing the destroyed piece segments. Note that a single - * list is used internally to gather the segment info, and so callers - * that care to modify the list should create their own copy; also, - * the pieces in the segments may overlap, i.e., two segments may - * contain the same piece. - */ - public List destroyPieces (DropBoard board, PieceOperation destroyOp) - { - // find all horizontally-oriented destroyed segments - int bwid = board.getWidth(), bhei = board.getHeight(); - _destroyed.clear(); - int end = bwid - _logic.getMinimumLength() + 1; - for (int yy = (bhei - 1); yy >= 0; yy--) { - int xx = 0; - while (xx < end) { - xx += findSegment(board, HORIZONTAL, xx, yy); - } - } - - // find all vertically-oriented destroyed segments - end = _logic.getMinimumLength() - 2; - for (int xx = 0; xx < bwid; xx++) { - int yy = bhei - 1; - while (yy > end) { - yy -= findSegment(board, VERTICAL, xx, yy); - } - } - - // destroy the pieces - int size = _destroyed.size(); - for (int ii = 0; ii < size; ii++) { - SegmentInfo si = (SegmentInfo)_destroyed.get(ii); - board.applyOp(si.dir, si.x, si.y, si.len, destroyOp); - } - - return _destroyed; - } - - /** - * Searches for a contiguously colored piece segment with the - * specified orientation and root coordinates in the supplied board - * and returns the length of the segment traversed. - */ - protected int findSegment (DropBoard board, int dir, int x, int y) - { - _lengthOp.reset(); - board.applyOp(dir, x, y, _lengthOp); - int len = _lengthOp.getLength(); - if (len >= _logic.getMinimumLength()) { - _destroyed.add(new SegmentInfo(dir, x, y, len)); - } - return len; - } - - /** - * A piece operation that calculates the length of the contiguous - * piece segment to which it is applied. - */ - protected class SegmentLengthOperation - implements PieceOperation - { - /** - * Resets the operation for application to a new piece segment. - */ - public void reset () - { - _len = 0; - } - - /** - * Returns the length of the contiguous piece segment. - */ - public int getLength () - { - return _len; - } - - // documentation inherited - public boolean execute (DropBoard board, int col, int row) - { - int piece = board.getPiece(col, row); - if (_len == 0) { - _len = 1; - _piece = piece; - return (piece != PIECE_NONE); - - } else if (_logic.isEquivalent(piece, _piece)) { - _len++; - return true; - - } else { - return false; - } - } - - /** The root segment piece. */ - protected int _piece; - - /** The segment length in pieces. */ - protected int _len; - } - - /** The puzzle-specific destroy logic with which we do our business. */ - protected DestroyLogic _logic; - - /** The piece operation used to determine segment length. */ - protected SegmentLengthOperation _lengthOp = new SegmentLengthOperation(); - - /** The list of destroyed piece segments. */ - protected ArrayList _destroyed = new ArrayList(); -} diff --git a/src/java/com/threerings/puzzle/drop/util/PieceDropLogic.java b/src/java/com/threerings/puzzle/drop/util/PieceDropLogic.java deleted file mode 100644 index 16d8802f0..000000000 --- a/src/java/com/threerings/puzzle/drop/util/PieceDropLogic.java +++ /dev/null @@ -1,80 +0,0 @@ -// -// $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.puzzle.drop.util; - -import com.threerings.util.DirectionCodes; - -import com.threerings.puzzle.drop.data.DropBoard; - -/** - * An interface to be implemented by games that would like to be able to - * drop their pieces during game play. - */ -public interface PieceDropLogic -{ - /** - * Should the board always be filled? - * - * @return false for normal behavior. - */ - public boolean boardAlwaysFilled (); - - /** - * Returns whether the given piece is potentially droppable. - */ - public boolean isDroppablePiece (int piece); - - /** - * Returns whether the given piece has constraints upon it that - * impact its droppability. - */ - public boolean isConstrainedPiece (int piece); - - /** - * Returns whether the given piece terminates a column climb when - * determining the height of a piece column to be dropped. - * - * @param allowConst whether to allow dropping constrained pieces - * (though only in the first encountered constrained block.) - * @param piece the piece to consider. - * @param pre whether the climbability check is being performed - * before the height is incremented, or after. - */ - public boolean isClimbablePiece ( - boolean allowConst, int piece, boolean pre); - - /** - * Returns the x-axis coordinate of the specified edge of the - * given constrained piece. - * - *

TODO: This should go away once the sword and sail games - * have standardized on WEST/EAST or BLOCK_LEFT/BLOCK_RIGHT to - * reference block edges. - * - * @param board the board to search. - * @param col the column of the constrained piece. - * @param row the row of the constrained piece. - * @param dir the edge direction to find; one of {@link - * DirectionCodes#LEFT} or {@link DirectionCodes#RIGHT}. - */ - public int getConstrainedEdge (DropBoard board, int col, int row, int dir); -} diff --git a/src/java/com/threerings/puzzle/drop/util/PieceDropper.java b/src/java/com/threerings/puzzle/drop/util/PieceDropper.java deleted file mode 100644 index 09d8f5a6c..000000000 --- a/src/java/com/threerings/puzzle/drop/util/PieceDropper.java +++ /dev/null @@ -1,203 +0,0 @@ -// -// $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.puzzle.drop.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.samskivert.util.StringUtil; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.drop.data.DropBoard; -import com.threerings.puzzle.drop.data.DropPieceCodes; - -/** - * Handles dropping pieces in a board. - */ -public class PieceDropper - implements DropPieceCodes -{ - /** - * A class to hold information detailing the pieces to be dropped - * in a particular column. - */ - public static class PieceDropInfo - { - /** The starting row of the bottom piece being dropped. */ - public int row; - - /** The column number. */ - public int col; - - /** The distance to drop the pieces. */ - public int dist; - - /** The pieces to be dropped. */ - public int[] pieces; - - /** - * Constructs a piece drop info object. - */ - public PieceDropInfo (int col, int row, int dist) - { - this.col = col; - this.row = row; - this.dist = dist; - } - - /** Returns a string representation of this instance. */ - public String toString () - { - return StringUtil.fieldsToString(this); - } - } - - /** - * Called to inform a drop observer that a piece has been dropped. - */ - public static interface DropObserver - { - /** Indicates that the specified piece was dropped. */ - public void pieceDropped (int piece, int sx, int sy, int dx, int dy); - } - - /** - * Constructs a piece dropper that uses the supplied piece drop logic - * to specialise itself for a particular puzzle. - */ - public PieceDropper (PieceDropLogic logic) - { - _logic = logic; - } - - /** - * Effects any drops possible on the supplied board (modifying the - * board in the progress) and notifying the supplied drop observer of - * those drops. - * - * @return the number of pieces dropped. - */ - public int dropPieces (DropBoard board, DropObserver drobs) - { - int dropped = 0, bhei = board.getHeight(), bwid = board.getWidth(); - for (int yy = bhei - 1; yy >= 0; yy--) { - for (int xx = 0; xx < bwid; xx++) { - dropped += dropPieces(board, xx, yy, drobs); - } - } - - // if the board wants pieces to be dropped in to fill the gaps, do - // that now - if (_logic.boardAlwaysFilled()) { - for (int xx = 0; xx < bwid; xx++) { - int dist = board.getDropDistance(xx, -1); - for (int ii = 0; ii < dist; ii++) { - int yy = (-1 - ii); - int piece = board.getNextPiece(); - if (piece != PIECE_NONE) { - drop(board, piece, xx, yy, yy + dist, drobs); - dropped++; - } - } - } - } - - return dropped; - } - - /** - * Computes and effects the drop for the specified piece and any - * associated attached pieces. The supplied observer is notified of - * all drops. - */ - protected int dropPieces ( - DropBoard board, int xx, int yy, DropObserver drobs) - { - // skip empty or fixed pieces - int piece = board.getPiece(xx, yy); - if (!_logic.isDroppablePiece(piece)) { - return 0; - } - - int dropped = 0; - if (_logic.isConstrainedPiece(piece)) { - // find out where this constrained block starts and ends - int start = _logic.getConstrainedEdge(board, xx, yy, LEFT); - int end = _logic.getConstrainedEdge(board, xx, yy, RIGHT); - int bwid = board.getWidth(); - if (start < 0 || end >= bwid) { - Log.warning("Board reported bogus constrained edge " + - "[x=" + xx + ", y=" + yy + - ", start=" + start + ", end=" + end + "]."); - board.dump(); - start = Math.max(start, 0); - end = Math.min(end, bwid); - } - - // get the smallest drop distance across all of the block columns - int dist = board.getHeight() - 1; - for (int xpos = start; xpos <= end; xpos++) { - dist = Math.min(dist, board.getDropDistance(xpos, yy)); - } - if (dist == 0) { - return 0; - } - - // scoot along the bottom edge of the block, noting the drop - // for each column - for (int xpos = start; xpos <= end; xpos++) { - piece = board.getPiece(xpos, yy); - drop(board, piece, xpos, yy, yy + dist, drobs); - dropped++; - } - - } else { - // get the distance to drop the pieces - int dist = board.getDropDistance(xx, yy); - if (dist == 0) { - return 0; - } - drop(board, piece, xx, yy, yy + dist, drobs); - dropped++; - } - - return dropped; - } - - /** Helpy helper function. */ - protected final void drop (DropBoard board, int piece, - int xx, int yy, int ty, DropObserver drobs) - { - // don't try to clear things out if we're filling in from off-board - if (yy >= 0) { - board.setPiece(xx, yy, PIECE_NONE); - } - board.setPiece(xx, ty, piece); - if (drobs != null) { - drobs.pieceDropped(piece, xx, yy, xx, ty); - } - } - - /** Allows puzzle-specific customizations. */ - protected PieceDropLogic _logic; -} diff --git a/src/java/com/threerings/puzzle/server/PuzzleGameDispatcher.java b/src/java/com/threerings/puzzle/server/PuzzleGameDispatcher.java deleted file mode 100644 index 77cfcb687..000000000 --- a/src/java/com/threerings/puzzle/server/PuzzleGameDispatcher.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// $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.puzzle.server; - -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; -import com.threerings.puzzle.client.PuzzleGameService; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.PuzzleGameMarshaller; - -/** - * Dispatches requests to the {@link PuzzleGameProvider}. - */ -public class PuzzleGameDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public PuzzleGameDispatcher (PuzzleGameProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new PuzzleGameMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case PuzzleGameMarshaller.UPDATE_PROGRESS: - ((PuzzleGameProvider)provider).updateProgress( - source, - ((Integer)args[0]).intValue(), (int[])args[1] - ); - return; - - case PuzzleGameMarshaller.UPDATE_PROGRESS_SYNC: - ((PuzzleGameProvider)provider).updateProgressSync( - source, - ((Integer)args[0]).intValue(), (int[])args[1], (Board[])args[2] - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/puzzle/server/PuzzleGameProvider.java b/src/java/com/threerings/puzzle/server/PuzzleGameProvider.java deleted file mode 100644 index f55b2d746..000000000 --- a/src/java/com/threerings/puzzle/server/PuzzleGameProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// $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.puzzle.server; - -import com.threerings.presents.client.Client; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; -import com.threerings.puzzle.client.PuzzleGameService; -import com.threerings.puzzle.data.Board; - -/** - * Defines the server-side of the {@link PuzzleGameService}. - */ -public interface PuzzleGameProvider extends InvocationProvider -{ - /** - * Handles a {@link PuzzleGameService#updateProgress} request. - */ - public void updateProgress (ClientObject caller, int arg1, int[] arg2); - - /** - * Handles a {@link PuzzleGameService#updateProgressSync} request. - */ - public void updateProgressSync (ClientObject caller, int arg1, int[] arg2, Board[] arg3); -} diff --git a/src/java/com/threerings/puzzle/server/PuzzleManager.java b/src/java/com/threerings/puzzle/server/PuzzleManager.java deleted file mode 100644 index b357fd8c5..000000000 --- a/src/java/com/threerings/puzzle/server/PuzzleManager.java +++ /dev/null @@ -1,632 +0,0 @@ -// -// $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.puzzle.server; - -import java.util.Arrays; - -import com.samskivert.util.IntListUtil; -import com.samskivert.util.Interval; -import com.samskivert.util.RandomUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.dobj.DObject; -import com.threerings.presents.dobj.OidList; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.CrowdServer; - -import com.threerings.parlor.game.data.GameObject; -import com.threerings.parlor.game.server.GameManager; - -import com.threerings.util.MessageBundle; -import com.threerings.util.Name; - -import com.threerings.puzzle.Log; -import com.threerings.puzzle.data.Board; -import com.threerings.puzzle.data.BoardSummary; -import com.threerings.puzzle.data.PuzzleCodes; -import com.threerings.puzzle.data.PuzzleConfig; -import com.threerings.puzzle.data.PuzzleGameMarshaller; -import com.threerings.puzzle.data.PuzzleObject; - -/** - * Extends the {@link GameManager} with facilities for the puzzle games - * that are used in Yohoho. Only features generic to all of our games are - * in this base class and additional features are supported both through - * the inheritance hierarchy and through delegating helpers (because Java - * conveniently doesn't support multiple inheritance). - */ -public abstract class PuzzleManager extends GameManager - implements PuzzleCodes, PuzzleGameProvider -{ - /** - * Returns the boards for all players. - */ - public Board[] getBoards () - { - return _boards; - } - - /** - * Returns the board summary for the given player index. - */ - public BoardSummary getBoardSummary (int pidx) - { - return (_puzobj == null || _puzobj.summaries == null) ? null : - _puzobj.summaries[pidx]; - } - - /** - * Returns whether this puzzle cares to make use of per-player board - * summaries that are sent periodically to all users in the puzzle via - * {@link #sendStatusUpdate}. The default implementation returns - * false. - */ - public boolean needsBoardSummaries () - { - return false; - } - - /** - * Returns whether this puzzle compares board states before it applies - * progress events, or after. The default implementation returns - * true. - */ - protected boolean compareBeforeApply () - { - return true; - } - - /** - * Handles the server and client states being out of sync when in - * debug mode. The default implementation halts the server. - */ - protected void handleBoardNotEqual () - { - // bail out so that we know something's royally borked - System.exit(0); - } - - /** - * Calls {@link BoardSummary#summarize} on the given player's board - * summary to refresh the summary information in preparation for - * sending along to the client(s). - * - * @param pidx the player index of the player whose board is to be - * summarized. - */ - public void updateBoardSummary (int pidx) - { - if (_puzobj.summaries != null && _puzobj.summaries[pidx] != null) { - _puzobj.summaries[pidx].summarize(); - } - } - - /** - * Applies updateBoardSummary on all the players' boards. AI board - * summaries should be updated by the AI logic. - */ - public void updateBoardSummaries () - { - if (_puzobj.summaries != null) { - for (int ii = 0; ii < _puzobj.summaries.length; ii++) { - if (!isAI(ii) || summarizeAIBoard()) { - updateBoardSummary(ii); - } - } - } - } - - // documentation inherited - protected void playerGameDidEnd (int pidx) - { - super.playerGameDidEnd(pidx); - - updateSummaryOnDeath(pidx); - } - - /** - * Updates the board summary for a player who has been eliminated and - * performs an update to communicate this change. - */ - protected void updateSummaryOnDeath (int pidx) - { - if (!isAI(pidx)) { - // update the board summary with the player's final board - updateBoardSummary(pidx); - } - - // force a status update - updateStatus(); - } - - /** - * Override to have board summaries for AIs automatically generated. - */ - protected boolean summarizeAIBoard () - { - return false; - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return PuzzleObject.class; - } - - // documentation inherited - protected void didInit () - { - super.didInit(); - - // save off a casted reference to our puzzle config - _puzconfig = (PuzzleConfig)_config; - } - - // documentation inherited - protected void didStartup () - { - super.didStartup(); - - // grab the puzzle object - _puzobj = (PuzzleObject)_gameobj; - - // create and fill in our game service object - PuzzleGameMarshaller service = (PuzzleGameMarshaller) - _invmgr.registerDispatcher(new PuzzleGameDispatcher(this), false); - _puzobj.setPuzzleGameService(service); - } - - // documentation inherited - protected void gameWillStart () - { - int size = getPlayerSlots(); - if (_boards == null) { - // create our arrays - _boards = new Board[size]; - _lastProgress = new long[size]; - } else { - Arrays.fill(_boards, null); - } - - // start everyone out with reasonable last progress stamps - Arrays.fill(_lastProgress, System.currentTimeMillis()); - - // compute the starting difficulty (this has to happen before we - // set the seed because that triggers the generation of the boards - // on the client) - _puzobj.setDifficulty(computeDifficulty()); - - // initialize the seed that goes out with this round - _puzobj.setSeed(RandomUtil.rand.nextLong()); - - // initialize the player boards - initBoards(); - - // let the game manager start up its business - super.gameWillStart(); - - // send along an initial status update before we start up the - // status update interval - sendStatusUpdate(); - - long statusInterval = getStatusInterval(); - if (_statusInterval == null && statusInterval > 0) { - // register the status update interval to address subsequent - // periodic updates - _statusInterval = new Interval(CrowdServer.omgr) { - public void expired () { - sendStatusUpdate(); - } - }; - _statusInterval.schedule(statusInterval, true); - } - } - - /** - * Returns the frequency with which puzzle status updates are - * broadcast to the players (which is accomplished via a call to - * {@link #sendStatusUpdate} which in turn calls {@link #updateStatus} - * wherein derived classes can participate in the status update). - * Returning O (the default) indicates that a periodic - * status update is not desired. - */ - protected long getStatusInterval () - { - return 0L; - } - - /** - * When a puzzle game starts, the manager is given the opportunity to - * configure the puzzle difficulty based on information known about - * the player. Additionally, when the game resets due to the player - * clearing the board, etc. this will be called again, so the - * difficulty can be ramped up as the player progresses. In situations - * where ratings and experience are tracked, the difficulty can be - * seeded based on the players prior performance. - */ - protected int computeDifficulty () - { - return DEFAULT_DIFFICULTY; - } - - // documentation inherited - protected void gameDidStart () - { - super.gameDidStart(); - - // log the AI skill levels for games involving AIs as it's useful - // when tuning AI algorithms - if (_AIs != null) { - Log.info("AIs on the job [game=" + _puzobj.which() + - ", skillz=" + StringUtil.toString(_AIs) + "]."); - } - } - - /** - * Updates (in one puzzle object transaction) all periodically updated - * status information. - */ - protected void sendStatusUpdate () - { - _puzobj.startTransaction(); - try { - // Log.info("Updating status [game=" + _puzobj.which() + "]."); - updateStatus(); - } finally { - _puzobj.commitTransaction(); - } - } - - /** - * A puzzle periodically (default of once every 5 seconds but - * configurable by puzzle) updates status information that is visible - * to the user. Derived classes can override this method and effect - * their updates by generating events on the puzzle object and they - * will be packaged into the update transaction. - */ - protected void updateStatus () - { - // if we're a board summary updating kind of puzzle, do that - if (needsBoardSummaries()) { - // generate the latest summaries - updateBoardSummaries(); - // then broadcast them to the clients - _puzobj.setSummaries(_puzobj.summaries); - } - } - - /** - * Send a system message with the puzzle bundle. - */ - protected void systemMessage (String msg) - { - systemMessage(msg, false); - } - - /** - * Send a system message with the puzzle bundle. - * - * @param waitForStart if true, the message will not be sent until the - * game has started. - */ - protected void systemMessage (String msg, boolean waitForStart) - { - systemMessage(PUZZLE_MESSAGE_BUNDLE, msg, waitForStart); - } - - /** - * Creates and initializes boards and board summaries (if desired per - * {@link #needsBoardSummaries}) for each player. - */ - protected void initBoards () - { - long seed = _puzobj.seed; - BoardSummary[] summaries = needsBoardSummaries() ? - new BoardSummary[getPlayerSlots()] : null; - - // set up game information for each player - for (int ii = 0, nn = getPlayerSlots(); ii < nn; ii++) { - boolean needsPlayerBoard = needsPlayerBoard(ii); - if (needsPlayerBoard) { - // create the game board - _boards[ii] = newBoard(ii); - _boards[ii].initializeSeed(seed); - if (summaries != null) { - summaries[ii] = newBoardSummary(_boards[ii]); - } - } - } - - _puzobj.setSummaries(summaries); - } - - /** - * Returns whether this puzzle needs a board for the given player - * index. The default implementation only creates boards for occupied - * player slots. Derived classes may wish to override this method if - * they have specialized board needs, e.g., they need only a single - * board for all players. - */ - protected boolean needsPlayerBoard (int pidx) - { - return (_puzobj.isOccupiedPlayer(pidx)); - } - - // documentation inherited - protected void gameDidEnd () - { - if (_statusInterval != null) { - // remove the client update interval - _statusInterval.cancel(); - _statusInterval = null; - } - - // send along one final status update - sendStatusUpdate(); - - super.gameDidEnd(); - } - - // documentation inherited - protected void didShutdown () - { - super.didShutdown(); - - // make sure our update interval is unregistered - if (_statusInterval != null) { - // remove the client update interval - _statusInterval.cancel(); - _statusInterval = null; - } - - // clear out our service registration - _invmgr.clearDispatcher(_puzobj.puzzleGameService); - } - - /** - * Applies progress updates received from the client. If puzzle - * debugging is enabled, this also compares the client board dumps - * provided along with each puzzle event. - */ - protected void applyProgressEvents (int pidx, int[] gevents, Board[] states) - { - int size = gevents.length; - boolean before = compareBeforeApply(); - - for (int ii = 0, pos = 0; ii < size; ii++) { - int gevent = gevents[ii]; - Board cboard = (states == null) ? null : states[ii]; - - // if we have state syncing enabled, make sure the board is - // correct before applying the event - if (before && (cboard != null)) { - compareBoards(pidx, cboard, gevent, before); - } - - // apply the event to the player's board - if (!applyProgressEvent(pidx, gevent, cboard)) { - Log.warning("Unknown event [puzzle=" + where() + - ", pidx=" + pidx + ", event=" + gevent + "]."); - } - - // maybe we are comparing boards afterwards - if (!before && (cboard != null)) { - compareBoards(pidx, cboard, gevent, before); - } - } - } - - /** - * Compare our server board to the specified sent-back user board. - */ - protected void compareBoards (int pidx, Board boardstate, - int gevent, boolean before) - { - if (DEBUG_PUZZLE) { - Log.info((before ? "About to apply " : "Just applied ") + - "[game=" + _puzobj.which() + ", pidx=" + pidx + - ", event=" + gevent + "]."); - } - if (boardstate == null) { - if (DEBUG_PUZZLE) { - Log.info("No board state provided. Can't compare."); - } - return; - } - boolean equal = _boards[pidx].equals(boardstate); - if (!equal) { - Log.warning("Client and server board states not equal! " + - "[game=" + _puzobj.which() + - ", type=" + _puzobj.getClass().getName() + "]."); - } - if (DEBUG_PUZZLE) { - // if we're debugging, dump the board state every time - // we're about to apply an event - _boards[pidx].dumpAndCompare(boardstate); - } - if (!equal) { - if (DEBUG_PUZZLE) { - handleBoardNotEqual(); - } else { - // dump the board state since we're not debugging and - // didn't just do it above - _boards[pidx].dumpAndCompare(boardstate); - } - } - } - - /** - * Called by {@link #updateProgress} to give the server a chance to - * apply each game event received from the client to the respective - * player's server-side board and, someday, confirm their validity. - * Derived classes that make use of the progress updating - * functionality should be sure to override this method to perform - * their game-specific event application antics. They should first - * perform a call to super() to see if the event is handled there. - * - * @param pidx the player index that submitted the progress event. - * @param gevent the progress event itself. - * @param cboard a snapshot of the board on the client iff the client has - * board syncing enabled (which is only enabled when debugging). - * - * @return true to indicate that the event was handled. - */ - protected boolean applyProgressEvent (int pidx, int gevent, Board cboard) - { - return false; - } - - /** - * Overrides the game manager implementation to mark all active - * players as winners. Derived classes may wish to override this - * method in order to customize the winning conditions. - */ - protected void assignWinners (boolean[] winners) - { - for (int ii = 0; ii < winners.length; ii++) { - winners[ii] = _puzobj.isActivePlayer(ii); - } - } - - /** - * Creates and returns a new starting board for the given player. - */ - protected abstract Board newBoard (int pidx); - - /** - * Creates and returns a new board summary for the given board. - * Puzzles that do not make use of board summaries should implement - * this method and return null. - */ - protected abstract BoardSummary newBoardSummary (Board board); - - // documentation inherited from interface PuzzleGameProvider - public void updateProgress (ClientObject caller, int roundId, int[] events) - { - updateProgressSync(caller, roundId, events, null); - } - - /** - * Called when the puzzle manager receives a progress update. It - * checks to make sure that the progress update is valid and the - * puzzle is still in play and then applies the updates via {@link - * #applyProgressEvents}. - */ - public void updateProgressSync ( - ClientObject caller, int roundId, int[] events, Board[] states) - { - // determine the caller's player index in the game - int pidx = IntListUtil.indexOf(_playerOids, caller.getOid()); - if (pidx == -1) { - Log.warning("Received progress update for non-player?! " + - "[game=" + _puzobj.which() + ", who=" + caller.who() + - ", ploids=" + StringUtil.toString(_playerOids) + "]."); - return; - } - - // bail if the progress update isn't for the current round - if (roundId != _puzobj.roundId) { - // only warn if this isn't a straggling update from the - // previous round - if (roundId != _puzobj.roundId-1) { - Log.warning("Received progress update for invalid round, " + - "not applying [game=" + _puzobj.which() + - ", invalidRoundId=" + roundId + - ", roundId=" + _puzobj.roundId + "]."); - } - return; - } - - // if the game is over, we wing straggling updates - if (!_puzobj.isInPlay()) { - Log.debug("Ignoring straggling events " + - "[game=" + _puzobj.which() + - ", user=" + getPlayerName(pidx) + - ", events=" + StringUtil.toString(events) + "]."); - return; - } - -// Log.info("Handling progress events [game=" + _puzobj.which() + -// ", pidx=" + pidx + ", roundId=" + roundId + -// ", count=" + events.length + "]."); - - // note that we received a progress update from this player - _lastProgress[pidx] = System.currentTimeMillis(); - - // apply the progress events to the player's puzzle state - applyProgressEvents(pidx, events, states); - } - - // documentation inherited - protected void tick (long tickStamp) - { - super.tick(tickStamp); - - // every five seconds, we call the inactivity checking code - if (_puzobj != null && _puzobj.isInPlay() && checkForInactivity()) { - int pcount = getPlayerSlots(); - for (int ii = 0; ii < pcount && _puzobj.isInPlay(); ii++) { - if (!isAI(ii)) { - checkPlayerActivity(tickStamp, ii); - } - } - } - } - - /** - * Returns whether {@link #checkPlayerActivity} should be called - * periodically while the game is in play to make sure players are - * still active. - */ - protected boolean checkForInactivity () - { - return false; - } - - /** - * Called periodically for each human player to give puzzles a chance - * to make sure all such players are engaging in reasonable levels of - * activity. The default implementation does naught. - */ - protected void checkPlayerActivity (long tickStamp, int pidx) - { - // nothing for now - } - - /** A casted reference to our puzzle config object. */ - protected PuzzleConfig _puzconfig; - - /** A casted reference to our puzzle game object. */ - protected PuzzleObject _puzobj; - - /** The player boards. */ - protected Board[] _boards; - - /** The client update interval. */ - protected Interval _statusInterval; - - /** Used to track the last time we received a progress event from each - * player in this puzzle. */ - protected long[] _lastProgress; -} diff --git a/src/java/com/threerings/puzzle/server/PuzzleManagerDelegate.java b/src/java/com/threerings/puzzle/server/PuzzleManagerDelegate.java deleted file mode 100644 index 3c5a4607c..000000000 --- a/src/java/com/threerings/puzzle/server/PuzzleManagerDelegate.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $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.puzzle.server; - -import com.threerings.parlor.game.server.GameManagerDelegate; - -/** - * Extends the {@link GameManagerDelegate} mechanism with puzzle manager - * specific methods (of which there are currently none). - */ -public class PuzzleManagerDelegate extends GameManagerDelegate -{ - /** - * Constructs a puzzle manager delegate. - */ - public PuzzleManagerDelegate (PuzzleManager puzmgr) - { - super(puzmgr); - _puzmgr = puzmgr; - } - - protected PuzzleManager _puzmgr; -} diff --git a/src/java/com/threerings/puzzle/util/PointSet.java b/src/java/com/threerings/puzzle/util/PointSet.java deleted file mode 100644 index 44f0b1fd0..000000000 --- a/src/java/com/threerings/puzzle/util/PointSet.java +++ /dev/null @@ -1,245 +0,0 @@ -// -// $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.puzzle.util; - -import java.awt.Point; -import java.util.Iterator; - -import com.threerings.puzzle.Log; - -/** - * The point set class provides an efficient implementation of a set - * containing two-dimensional point values as (x, y). - */ -public class PointSet -{ - /** - * Creates a point set that can contain points within the given range - * of values. - * - * @param rangeX the maximum x-axis range. - * @param rangeY the maximum y-axis range. - */ - public PointSet (int rangeX, int rangeY) - { - _rangeX = rangeX; - _rangeY = rangeY; - _points = new boolean[rangeX][rangeY]; - } - - /** - * Adds a point to the set and returns whether the point was already - * present in the set. - * - * @param x the point x-coordinate. - * @param y the point y-coordinate. - * - * @return true if the point was already present, false if not. - */ - public boolean add (int x, int y) - { - boolean present = _points[x][y]; - _points[x][y] = true; - if (!present) { - _count++; - } - return present; - } - - /** - * Adds all points in the given set to this set. - * - * @param set the set containing points to add. - */ - public void addAll (PointSet set) - { - Iterator iter = set.iterator(); - Point pt; - while ((pt = (Point)iter.next()) != null) { - add(pt.x, pt.y); - } - } - - /** - * Clears all points from this set. - */ - public void clear () - { - if (_count == 0) { - // no need to clear anything - return; - } - - for (int xx = 0; xx < _rangeX; xx++) { - for (int yy = 0; yy < _rangeY; yy++) { - _points[xx][yy] = false; - } - } - _count = 0; - } - - /** - * Returns whether this set contains the given point. - * - * @param x the point x-coordinate. - * @param y the point y-coordinate. - * - * @return true if the set contains the point, false if not. - */ - public boolean contains (int x, int y) - { - return (_points[x][y]); - } - - /** - * Returns whether this set is empty. - * - * @return true if the set is empty, false if not. - */ - public boolean isEmpty () - { - return (_count == 0); - } - - /** - * Returns an iterator that iterates over the points in this set, - * returning them as {@link Point} objects. Note that the iterator - * uses a single point object internally, and so callers should create - * their own copy of the point if they plan to do something fancy with - * it. - * - * @return the iterator over the set's points. - */ - public Iterator iterator () - { - return new PointIterator(); - } - - /** - * Removes the given point from the set and returns whether the point - * was present in the set. - * - * @param x the point x-coordinate. - * @param y the point y-coordinate. - * - * @return true if the point was present, false if not. - */ - public boolean remove (int x, int y) - { - boolean present = _points[x][y]; - _points[x][y] = false; - if (present) { - _count--; - } - return present; - } - - /** - * Returns the number of points in the set. - * - * @return the number of points. - */ - public int size () - { - return _count; - } - - /** - * Returns a string representation of the point set. - */ - public String toString () - { - StringBuilder buf = new StringBuilder(); - buf.append("["); - Iterator iter = iterator(); - Point val; - while ((val = (Point)iter.next()) != null) { - buf.append("(").append(val.x); - buf.append(",").append(val.y); - buf.append(")"); - - if (iter.hasNext()) { - buf.append(", "); - } - } - return buf.append("]").toString(); - } - - protected class PointIterator implements Iterator - { - public boolean hasNext () - { - return (_curCount < _count); - } - - public Object next () - { - if (_curCount == _count) { - return null; - } - - while (!_points[_curX][_curY]) { - advance(); - } - - _curCount++; - _point.setLocation(_curX, _curY); - - if (_curCount < _count) { - advance(); - } - - return _point; - } - - public void remove () - { - throw new UnsupportedOperationException(); - } - - protected void advance () - { - if ((++_curX) >= _rangeX) { - _curX = 0; - _curY++; - } - - if (_curY >= _rangeY) { - Log.warning("Advanced past point range."); - _curY = 0; - } - } - - protected int _curCount = 0; - protected int _curX = 0, _curY = 0; - protected Point _point = new Point(); - } - - /** The dimensions of the point array. */ - protected int _rangeX, _rangeY; - - /** The points in the set. */ - protected boolean _points[][]; - - /** The number of points in the set. */ - protected int _count; -} diff --git a/src/java/com/threerings/puzzle/util/PuzzleContext.java b/src/java/com/threerings/puzzle/util/PuzzleContext.java deleted file mode 100644 index 7132b8678..000000000 --- a/src/java/com/threerings/puzzle/util/PuzzleContext.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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.puzzle.util; - -import com.threerings.util.KeyDispatcher; -import com.threerings.util.KeyboardManager; -import com.threerings.util.MessageManager; -import com.threerings.util.Name; - -import com.threerings.media.FrameManager; - -import com.threerings.parlor.util.ParlorContext; - -/** - * Provides access to entities needed by the puzzle services. - */ -public interface PuzzleContext extends ParlorContext -{ - /** - * Returns the username of the local user. - */ - public Name getUsername (); - - /** - * Returns a reference to the message manager used by the client. - */ - public MessageManager getMessageManager (); - - /** - * Provides access to the frame manager. - */ - public FrameManager getFrameManager (); - - /** - * Provides access to the keyboard manager. - */ - public KeyboardManager getKeyboardManager (); - - /** - * Provides access to the key dispatcher. - */ - public KeyDispatcher getKeyDispatcher (); -} diff --git a/src/java/com/threerings/puzzle/util/PuzzleGameUtil.java b/src/java/com/threerings/puzzle/util/PuzzleGameUtil.java deleted file mode 100644 index 33086d378..000000000 --- a/src/java/com/threerings/puzzle/util/PuzzleGameUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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.puzzle.util; - -import java.awt.event.KeyEvent; - -import com.threerings.util.KeyTranslatorImpl; -import com.threerings.puzzle.client.PuzzleController; -import com.threerings.puzzle.client.PuzzlePanel; - -/** - * Puzzle game related utilities. - */ -public class PuzzleGameUtil -{ - /** - * Returns a key translator configured with basic puzzle game - * mappings. - */ - public static KeyTranslatorImpl getKeyTranslator () - { - KeyTranslatorImpl xlate = new KeyTranslatorImpl(); - - if (!PuzzlePanel.isRobotTesting()) { - // add the standard pause keys - xlate.addPressCommand( - KeyEvent.VK_P, PuzzleController.TOGGLE_CHATTING); - } - - return xlate; - } -} diff --git a/src/java/com/threerings/resource/Handler.java b/src/java/com/threerings/resource/Handler.java deleted file mode 100644 index cee0d0552..000000000 --- a/src/java/com/threerings/resource/Handler.java +++ /dev/null @@ -1,194 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 90382dd68..000000000 --- a/src/java/com/threerings/resource/Log.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.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 deleted file mode 100644 index b1133d1fc..000000000 --- a/src/java/com/threerings/resource/ResourceBundle.java +++ /dev/null @@ -1,418 +0,0 @@ -// -// $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.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 deleted file mode 100644 index f6862ef45..000000000 --- a/src/java/com/threerings/resource/ResourceManager.java +++ /dev/null @@ -1,691 +0,0 @@ -// -// $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.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/stage/Log.java b/src/java/com/threerings/stage/Log.java deleted file mode 100644 index 81a155a03..000000000 --- a/src/java/com/threerings/stage/Log.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $Id: Log.java 49 2001-08-09 00:32:53Z mdb $ - -package com.threerings.stage; - -/** - * 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("stage"); - - /** 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/stage/client/SceneColorizer.java b/src/java/com/threerings/stage/client/SceneColorizer.java deleted file mode 100644 index c52233867..000000000 --- a/src/java/com/threerings/stage/client/SceneColorizer.java +++ /dev/null @@ -1,130 +0,0 @@ -// -// $Id: SceneColorizer.java 17027 2004-09-10 00:10:46Z ray $ - -package com.threerings.stage.client; - -import java.util.HashMap; -import java.util.Iterator; - -import com.threerings.media.image.ColorPository; -import com.threerings.media.image.Colorization; -import com.threerings.media.tile.TileSet; - -import com.threerings.miso.data.ObjectInfo; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageScene; - -/** - * Handles colorization of object tiles in a scene. - */ -public class SceneColorizer implements TileSet.Colorizer -{ - /** - * Creates a scene colorizer for the supplied scene. - */ - public SceneColorizer (ColorPository cpos, StageScene scene) - { - _cpos = cpos; - _scene = scene; - - // enumerate the color ids for all possible colorization classes - for (Iterator iter = _cpos.enumerateClasses(); iter.hasNext(); ) { - String cname = ((ColorPository.ClassRecord)iter.next()).name; - _cids.put(cname, _cpos.enumerateColorIds(cname)); - } - } - - /** - * Set an auxiliary colorizer that overrides our colorizations. - */ - public void setAuxiliary (TileSet.Colorizer aux) - { - _aux = aux; - } - - /** - * Obtains a colorizer for the supplied scene object. - */ - public TileSet.Colorizer getColorizer (final ObjectInfo oinfo) - { - // if the object has no custom colorizations, return the default - // colorizer - if (oinfo.zations == 0) { - return this; - } - - // otherwise create a custom colorizer that returns this object's - // custom colorization assignments - return new TileSet.Colorizer() { - public Colorization getColorization (int index, String zation) { - int colorId = 0; - switch (index) { - case 0: colorId = oinfo.getPrimaryZation(); break; - case 1: colorId = oinfo.getSecondaryZation(); break; - } - if (colorId == 0) { - return SceneColorizer.this.getColorization(index, zation); - } else { - return _cpos.getColorization(zation, colorId); - } - } - }; - } - - // documentation inherited from interface TileSet.Colorizer - public Colorization getColorization (int index, String zation) - { - // This method is called when an object in the scene has no colorization - // of its own defined for a particular color class. - if (_aux != null) { - Colorization c = _aux.getColorization(index, zation); - if (c != null) { - return c; - } - } - return _cpos.getColorization(zation, getColorId(zation)); - } - - /** - * Get the colorId to use for the specified colorization. - */ - public int getColorId (String zation) - { - // 1. We see if the scene contains a default color we should use. - ColorPository.ClassRecord rec = _cpos.getClassRecord(zation); - int colorId = _scene.getDefaultColor(rec.classId); - if (colorId == -1) { - // 2. If the scene does not contain a color, see if a default - // is defined for that color class. - ColorPository.ColorRecord def = rec.getDefault(); - if (def != null) { - return def.colorId; - } - - // 3. If there are no defaults whatsoever, just hash on the sceneId. - int[] cids = (int[])_cids.get(zation); - if (cids == null) { - Log.warning("Zoiks, have no colorizations for '" + - zation + "'."); - return -1; - } else { - colorId = cids[_scene.getZoneId() % cids.length]; - } - } - return colorId; - } - - /** An auxiliary colorizer which may temporarily return - * non-standard colorizations. */ - protected TileSet.Colorizer _aux; - - /** The entity from which we obtain colorization info. */ - protected ColorPository _cpos; - - /** The scene for which we're providing zations. */ - protected StageScene _scene; - - /** Contains our colorization class information. */ - protected HashMap _cids = new HashMap(); -} diff --git a/src/java/com/threerings/stage/client/StageSceneController.java b/src/java/com/threerings/stage/client/StageSceneController.java deleted file mode 100644 index 227be9154..000000000 --- a/src/java/com/threerings/stage/client/StageSceneController.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// $Id: WorldSceneController.java 9625 2003-06-11 04:17:18Z mdb $ - -package com.threerings.stage.client; - -import com.samskivert.util.Tuple; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.whirled.data.SceneUpdate; -import com.threerings.whirled.spot.client.SpotSceneController; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.util.StageContext; - -/** - * Extends the {@link SpotSceneController} with functionality specific to - * displaying Stage scenes. - */ -public class StageSceneController extends SpotSceneController -{ - /** - * Called when the user clicks on a location within the scene. - */ - public void handleLocationClicked (Object source, StageLocation loc) - { - Log.warning("handleLocationClicked(" + source + ", " + loc + ")"); - } - - /** - * Handles a cluster clicked event. - * - * @param tuple a Tuple containing (Cluster, Point) with the Cluster - * that was clicked and the Point being the screen coords of the click. - */ - public void handleClusterClicked (Object source, Tuple tuple) - { - Log.warning("handleClusterClicked(" + source + ", " + tuple + ")"); - } - - // documentation inherited - protected PlaceView createPlaceView (CrowdContext ctx) - { - return new StageScenePanel((StageContext)ctx, this); - } - - // documentation inherited - protected void sceneUpdated (SceneUpdate update) - { - super.sceneUpdated(update); - - // let the scene panel know to rethink everything - ((StageScenePanel)_view).sceneUpdated(update); - } -} diff --git a/src/java/com/threerings/stage/client/StageScenePanel.java b/src/java/com/threerings/stage/client/StageScenePanel.java deleted file mode 100644 index 3f4b1d4e4..000000000 --- a/src/java/com/threerings/stage/client/StageScenePanel.java +++ /dev/null @@ -1,659 +0,0 @@ -// -// $Id: WorldScenePanel.java 18366 2004-12-15 22:56:58Z ray $ - -package com.threerings.stage.client; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.geom.Ellipse2D; - -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.ControllerProvider; -import com.samskivert.swing.RuntimeAdjust; -import com.samskivert.swing.util.SwingUtil; - -import com.samskivert.util.Tuple; -import com.threerings.util.StreamableArrayList; - -import com.threerings.media.tile.ObjectTile; -import com.threerings.media.tile.TileSet; -import com.threerings.media.tile.UniformTileSet; - -import com.threerings.miso.client.MisoScenePanel; -import com.threerings.miso.client.SceneObject; -import com.threerings.miso.client.SceneObjectTip; -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.util.MisoUtil; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.whirled.data.SceneUpdate; - -import com.threerings.whirled.spot.data.Cluster; -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.spot.data.Portal; -import com.threerings.whirled.spot.data.SceneLocation; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageMisoSceneModel; -import com.threerings.stage.data.StageScene; -import com.threerings.stage.data.StageSceneModel; -import com.threerings.stage.util.StageContext; -import com.threerings.stage.util.StageSceneUtil; - -/** - * Extends the basic Miso scene panel with Stage fun stuff like portals, - * clusters and locations. - */ -public class StageScenePanel extends MisoScenePanel - implements ControllerProvider, KeyListener, PlaceView -{ - /** An action command generated when the user clicks on a location - * within the scene. */ - public static final String LOCATION_CLICKED = "LocationClicked"; - - /** An action command generated when a cluster is clicked. */ - public static final String CLUSTER_CLICKED = "ClusterClicked"; - - /** Show flag that indicates we should show all clusters. */ - public static final int SHOW_CLUSTERS = (1 << 1); - - /** Show flag that indicates we should render known land plots - * (expensive, don't turn this on willy nilly). */ - public static final int SHOW_PLOTS = (1 << 2); - - /** - * Constructs a stage scene view panel. - */ - public StageScenePanel (StageContext ctx, Controller ctrl) - { - super(ctx, StageSceneUtil.getMetrics()); - - // keep these around for later - _ctx = ctx; - _ctrl = ctrl; - _ctrl.setControlledPanel(this); - - // no layout manager - setLayout(null); - } - - /** - * Get the tileset colorizer in use in this scene. - */ - public SceneColorizer getColorizer () - { - return _rizer; - } - - // documentation inherited - protected TileSet.Colorizer getColorizer (ObjectInfo oinfo) - { - return _rizer.getColorizer(oinfo); - } - - /** - * Returns the scene being displayed by this panel. Do not modify it. - */ - public StageScene getScene () - { - return _scene; - } - - /** - * Sets the scene managed by the panel. - */ - public void setScene (StageScene scene) - { - _scene = scene; - if (_scene != null) { - _rizer = new SceneColorizer(_ctx.getColorPository(), scene); - recomputePortals(); - setSceneModel(StageMisoSceneModel.getSceneModel( - scene.getSceneModel())); - } else { - Log.warning("Zoiks! We can't display a null scene!"); - // TODO: display something to the user letting them know that - // we're so hosed that we don't even know what time it is - } - } - - /** - * Called when we have received a scene update from the server. - */ - public void sceneUpdated (SceneUpdate update) - { - // recompute the portals as those may well have changed - recomputePortals(); - - // we go aheand and completely replace our scene model which will - // reload the whole good goddamned business; it is a little - // shocking to the user, but it's guaranteed to work - refreshScene(); - } - - /** - * Computes a set of display objects for the portals in this scene. - */ - protected void recomputePortals () - { - // create scene objects for our portals - UniformTileSet ots = loadPortalTileSet(); - - _portobjs.clear(); - for (Iterator iter = _scene.getPortals(); iter.hasNext(); ) { - Portal portal = (Portal) iter.next(); - StageLocation loc = (StageLocation) portal.loc; - Point p = getScreenCoords(loc.x, loc.y); - int tx = MisoUtil.fullToTile(loc.x); - int ty = MisoUtil.fullToTile(loc.y); - Point ts = MisoUtil.tileToScreen(_metrics, tx, ty, new Point()); - -// Log.info("Added portal " + portal + -// " [screen=" + StringUtil.toString(p) + -// ", tile=" + StringUtil.coordsToString(tx, ty) + -// ", tscreen=" + StringUtil.toString(ts) + "]."); - - ObjectInfo info = new ObjectInfo(0, tx, ty); - info.action = "portal:" + portal.portalId; - - // TODO: cache me - ObjectTile tile = new PortalObjectTile( - ts.x + _metrics.tilehwid - p.x + (PORTAL_ICON_WIDTH / 2), - ts.y + _metrics.tilehei - p.y + (PORTAL_ICON_HEIGHT / 2)); - tile.setImage(ots.getTileMirage(loc.orient)); - - _portobjs.add(new SceneObject(this, info, tile) { - public boolean setHovered (boolean hovered) { - ((PortalObjectTile)this.tile).hovered = hovered; - return isResponsive(); - } - }); - } - } - - // documentation inherited - protected void recomputeVisible () - { - super.recomputeVisible(); - - // add our visible portal objects to the list of visible objects - for (int ii = 0, ll = _portobjs.size(); ii < ll; ii++) { - SceneObject pobj = (SceneObject)_portobjs.get(ii); - if (pobj.bounds != null && _vbounds.intersects(pobj.bounds)) { - _vizobjs.add(pobj); - } - } - } - - // documentation inherited from interface ControllerProvider - public Controller getController () - { - return _ctrl; - } - - // documentation inherited from interface KeyListener - public void keyPressed (KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_ALT) { - // display all tooltips - setShowFlags(SHOW_TIPS, true); - } - } - - // documentation inherited from interface KeyListener - public void keyReleased (KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_ALT) { - // stop displaying all tooltips - setShowFlags(SHOW_TIPS, defaultShowTips()); - } - } - - // documentation inherited from interface PlaceView - public void willEnterPlace (PlaceObject plobj) - { - } - - // documentation inherited from interface PlaceView - public void didLeavePlace (PlaceObject plobj) - { - } - - /** - * Returns true if we should always show the object tooltips by - * default, false if they should only be shown while the 'Alt' key is - * depressed. - */ - protected boolean defaultShowTips () - { - return false; - } - - // documentation inherited - public void keyTyped (KeyEvent e) - { - // nothing - } - - // documentation inherited - protected boolean handleMousePressed (Object hobject, MouseEvent event) - { - // let our parent have a crack at the old mouse press - if (super.handleMousePressed(hobject, event)) { - return true; - } - - // if the hover object is a cluster, we clicked it! - if (event.getButton() == MouseEvent.BUTTON1) { - if (hobject instanceof Cluster) { - Object actarg = new Tuple(hobject, event.getPoint()); - Controller.postAction(this, CLUSTER_CLICKED, actarg); - } else { - // post an action indicating that we've clicked on a location - Point lc = MisoUtil.screenToFull( - _metrics, event.getX(), event.getY(), new Point()); - Controller.postAction(this, LOCATION_CLICKED, - new StageLocation(lc.x, lc.y, (byte)0)); - } - return true; - } - return false; - } - - /** - * Called when our show flags have changed. - */ - protected void showFlagsDidChange (int oldflags) - { - super.showFlagsDidChange(oldflags); - - if ((oldflags & SHOW_CLUSTERS) != (_showFlags & SHOW_CLUSTERS)) { - // dirty every cluster rectangle - Iterator iter = _clusters.values().iterator(); - while (iter.hasNext()) { - dirtyCluster((Shape)iter.next()); - } - } - } - - /** - * Called when a real cluster is created or updated in the scene. - */ - protected void clusterUpdated (Cluster cluster) - { - // compute a screen rectangle that contains all possible "spots" - // in this cluster - ArrayList spots = StageSceneUtil.getClusterLocs(cluster); - Rectangle cbounds = null; - for (int ii = 0, ll = spots.size(); ii < ll; ii++) { - StageLocation loc = ((StageLocation) spots.get(ii).loc); - Point sp = getScreenCoords(loc.x, loc.y); - if (cbounds == null) { - cbounds = new Rectangle(sp.x, sp.y, 0, 0); - } else { - cbounds.add(sp.x, sp.y); - } - } - - if (cbounds == null) { - // if we found no one actually in this cluster, nix it - removeCluster(cluster.clusterOid); - } else { - // otherwise have the view update the cluster - updateCluster(cluster, cbounds); - } - } - - /** - * Adds or updates the specified cluster in the view. Metrics will be - * created that allow the cluster to be rendered and hovered over. - * - * @param cluster the cluster record to be added. - * @param bounds the screen coordinates that bound the occupants of - * the cluster. - */ - public void updateCluster (Cluster cluster, Rectangle bounds) - { - // dirty any old bounds - dirtyCluster(cluster); - - // compute the screen coordinate bounds of this cluster - Shape shape = new Ellipse2D.Float( - bounds.x, bounds.y, bounds.width, bounds.height); - _clusters.put(cluster, shape); - - // if the mouse is inside these bounds, we highlight this cluster - Shape mshape = new Ellipse2D.Float( - bounds.x-CLUSTER_SLOP, bounds.y-CLUSTER_SLOP, - bounds.width+2*CLUSTER_SLOP, bounds.height+2*CLUSTER_SLOP); - _clusterWells.put(cluster, mshape); - - // dirty our new bounds - dirtyCluster(shape); - } - - /** - * Removes the specified cluster from the view. - * - * @return true if such a cluster existed and was removed. - */ - public boolean removeCluster (int clusterOid) - { - Cluster key = new Cluster(); - key.clusterOid = clusterOid; - _clusterWells.remove(key); - Shape shape = (Shape)_clusters.remove(key); - if (shape == null) { - return false; - } - - dirtyCluster(shape); - // clear out the hover object if this cluster was it - if (_hobject instanceof Cluster && - ((Cluster)_hobject).clusterOid == clusterOid) { - _hobject = null; - } - return true; - } - - /** - * 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) - { - super.hoverObjectChanged(oldHover, newHover); - - if (oldHover instanceof Cluster) { - dirtyCluster((Cluster)oldHover); - } - if (newHover instanceof Cluster) { - dirtyCluster((Cluster)newHover); - } - } - - /** - * 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) - { - if (!isResponsive()) { - return null; - } - - // if the current hover object is a cluster, see if we're still in - // that cluster - if (_hobject instanceof Cluster) { - Cluster cluster = (Cluster)_hobject; - if (containsPoint(cluster, mx, my)) { - return cluster; - } - } - - // otherwise, check to see if the mouse is in some new cluster - Iterator iter = _clusters.keySet().iterator(); - while (iter.hasNext()) { - Cluster cclust = (Cluster)iter.next(); - if (containsPoint(cclust, mx, my)) { - return cclust; - } - } - - return null; - } - - /** - * Returns true if the specified cluster contains the supplied screen - * coordinate. - */ - protected boolean containsPoint (Cluster cluster, int mx, int my) - { - Shape shape = (Shape)_clusterWells.get(cluster); - return (shape == null) ? false : shape.contains(mx, my); - } - - /** - * Dirties the supplied cluster. - */ - protected void dirtyCluster (Cluster cluster) - { - if (cluster != null) { - dirtyCluster((Shape)_clusters.get(cluster)); - } - } - - /** - * Dirties the supplied cluster rectangle. - */ - protected void dirtyCluster (Shape shape) - { - if (shape != null) { - Rectangle r = shape.getBounds(); - _remgr.invalidateRegion( - r.x - (CLUSTER_PAD / 2), - r.y - (CLUSTER_PAD / 2), - r.width + (CLUSTER_PAD * 3 / 2), - r.height + (CLUSTER_PAD * 3 / 2)); - } - } - - /** - * Returns the portal at the specified full coordinates or null if no - * portal exists at said coordinates. - */ - public Portal getPortal (int fullX, int fullY) - { - Iterator iter = _scene.getPortals(); - while (iter.hasNext()) { - Portal portal = (Portal)iter.next(); - StageLocation loc = (StageLocation) portal.loc; - if (loc.x == fullX && loc.y == fullY) { - return portal; - } - } - return null; - } - - // documentation inherited - protected void paintBaseDecorations (Graphics2D gfx, Rectangle clip) - { - super.paintBaseDecorations(gfx, clip); - - paintClusters(gfx, clip); - } - - /** - * Paints any visible clusters. - */ - protected void paintClusters (Graphics2D gfx, Rectangle clip) - { - // remember how daddy's things were arranged - Object oalias = SwingUtil.activateAntiAliasing(gfx); - Composite ocomp = gfx.getComposite(); - Stroke ostroke = gfx.getStroke(); - - // get ready to draw clusters - gfx.setStroke(CLUSTER_STROKE); - gfx.setColor(CLUSTER_COLOR); - - if (checkShowFlag(SHOW_CLUSTERS) - /* || // _alwaysShowClusters.getValue() */) { - // draw all clusters - Iterator iter = _clusters.keySet().iterator(); - while (iter.hasNext()) { - drawCluster(gfx, clip, (Cluster)iter.next()); - } - - } else if (_hobject instanceof Cluster) { - // or just draw the active cluster - drawCluster(gfx, clip, (Cluster)_hobject); - } - - // put back daddy's things - gfx.setComposite(ocomp); - gfx.setStroke(ostroke); - SwingUtil.restoreAntiAliasing(gfx, oalias); - } - - /** - * Draw the cluster specified by the rectangle. - */ - protected void drawCluster (Graphics2D gfx, Rectangle clip, Cluster cluster) - { - Shape shape = (Shape)_clusters.get(cluster); - if ((shape != null) && shape.intersects(clip)) { - if (_hobject == cluster) { - gfx.setComposite(HIGHLIGHT_ALPHA); - } else { - gfx.setComposite(SHOWN_ALPHA); - } - gfx.draw(shape); - } - } - - /** - * Returns true if the specified location is associated with a portal. - */ - protected boolean isPortal (Location loc) - { - if (_scene == null) { - return false; - } - Iterator iter = _scene.getPortals(); - while (iter.hasNext()) { - Portal p = (Portal)iter.next(); - if (loc.equals(p.loc)) { - return true; - } - } - return false; - } - - /** - * Loads up the tileset used to render the portal arrows. - */ - protected UniformTileSet loadPortalTileSet () - { - return _ctx.getTileManager().loadTileSet( - "media/stage/portal_arrows.png", - PORTAL_ICON_WIDTH, PORTAL_ICON_HEIGHT); - } - - /** Used to render portals as objects in a scene. */ - protected class PortalObjectTile extends ObjectTile - { - public boolean hovered = false; - - public PortalObjectTile (int ox, int oy) - { - setOrigin(ox, oy); - } - - public void paint (Graphics2D gfx, int x, int y) - { - Composite ocomp = gfx.getComposite(); - if (!isResponsive() || !hovered) { - gfx.setComposite(INACTIVE_PORTAL_ALPHA); - } - super.paint(gfx, x, y); - gfx.setComposite(ocomp); - } - } - - /** A reference to our client context. */ - protected StageContext _ctx; - - /** The controller with which we work in tandem. */ - protected Controller _ctrl; - - /** Our currently displayed scene. */ - protected StageScene _scene; - - /** Contains scene objects for our portals. */ - protected ArrayList _portobjs = new ArrayList(); - - /** Shapes describing the clusters, indexed by cluster. */ - protected HashMap _clusters = new HashMap(); - - /** Shapes describing the clusters, indexed by cluster. */ - protected HashMap _clusterWells = new HashMap(); - - /** Handles scene object colorization. */ - protected SceneColorizer _rizer; - -// /** A debug hook that toggles always-on rendering of clusters. */ -// protected static RuntimeAdjust.BooleanAdjust _alwaysShowClusters = -// new RuntimeAdjust.BooleanAdjust( -// "Causes all clusters to always be rendered.", -// "yohoho.miso.always_show_clusters", -// ClientPrefs.config, false); - - /** The width of the portal icons. */ - protected static final int PORTAL_ICON_WIDTH = 48; - - /** The height of the portal icons. */ - protected static final int PORTAL_ICON_HEIGHT = 48; - - /** The distance within which the mouse must be from a location - * in order to highlight it. */ - protected static final int MAX_LOCATION_DIST = 25; - - /** The amount the stroke a cluster. */ - protected static final int CLUSTER_PAD = 4; - - /** The width with which to draw the cluster. */ - protected static final Stroke CLUSTER_STROKE = new BasicStroke(CLUSTER_PAD); - - /** The color used to render clusters. */ - protected static final Color CLUSTER_COLOR = Color.ORANGE; - - /** Alpha level used to hightlight locations or clusters. */ - protected static final Composite HIGHLIGHT_ALPHA = - AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); - - /** Alpha level used to render clusters when they're not selected. */ - protected static final Composite SHOWN_ALPHA = - AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.15f); - - /** The alpha with which to render inactive portals. */ - protected static final Composite INACTIVE_PORTAL_ALPHA = HIGHLIGHT_ALPHA; - - /** The number of pixels outside a cluster when we assume the mouse is - * "over" that cluster. */ - protected static final int CLUSTER_SLOP = 25; -} diff --git a/src/java/com/threerings/stage/client/StageSceneService.java b/src/java/com/threerings/stage/client/StageSceneService.java deleted file mode 100644 index 8516d086a..000000000 --- a/src/java/com/threerings/stage/client/StageSceneService.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// $Id: WorldSceneService.java 14426 2004-03-12 12:12:32Z mdb $ - -package com.threerings.stage.client; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; - -import com.threerings.miso.data.ObjectInfo; - -/** - * Provides services relating to Stage scenes. - */ -public interface StageSceneService extends InvocationService -{ - /** - * Requests to add the supplied object to the current scene. - */ - public void addObject (Client client, ObjectInfo info, - ConfirmListener listener); - - /** - * Requests to remove the supplied objects from the current scene. - */ - public void removeObjects (Client client, ObjectInfo[] info, - ConfirmListener listener); -} diff --git a/src/java/com/threerings/stage/data/DefaultColorUpdate.java b/src/java/com/threerings/stage/data/DefaultColorUpdate.java deleted file mode 100644 index 81bd91b9c..000000000 --- a/src/java/com/threerings/stage/data/DefaultColorUpdate.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $Id: DefaultColorUpdate.java 16551 2004-07-27 20:53:28Z ray $ - -package com.threerings.stage.data; - -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.data.SceneUpdate; - -/** - * Update to change the default colorization for objects in a scene which - * do not define their own colorization. - */ -public class DefaultColorUpdate extends SceneUpdate -{ - /** The class id of the colorization we're changing. */ - public int classId; - - /** The color id to set as the new default, or -1 to remove the default. */ - public int colorId; - - /** - * Initializes this update. - */ - public void init (int targetId, int targetVersion, int classId, int colorId) - { - init(targetId, targetVersion); - this.classId = classId; - this.colorId = colorId; - } - - // documentation inherited - public void apply (SceneModel model) - { - super.apply(model); - - StageSceneModel smodel = (StageSceneModel)model; - smodel.setDefaultColor(classId, colorId); - } -} diff --git a/src/java/com/threerings/stage/data/ModifyObjectsUpdate.java b/src/java/com/threerings/stage/data/ModifyObjectsUpdate.java deleted file mode 100644 index 861a414e6..000000000 --- a/src/java/com/threerings/stage/data/ModifyObjectsUpdate.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $Id: AddObjectUpdate.java 15953 2004-06-11 23:40:47Z ray $ - -package com.threerings.stage.data; - -import com.threerings.miso.data.ObjectInfo; - -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.data.SceneUpdate; - -/** - * A scene update that is broadcast when objects have been added to or removed - * from the scene. - */ -public class ModifyObjectsUpdate extends SceneUpdate -{ - /** The objects added to the scene (or null for none). */ - public ObjectInfo[] added; - - /** The objects removed from the scene (or null for none). */ - public ObjectInfo[] removed; - - /** - * Initializes this update with all necessary data. - * - * @param added the objects added to the scene, or null for - * none - * @param removed the objects removed from the scene, or null - * for none - */ - public void init (int targetId, int targetVersion, ObjectInfo[] added, - ObjectInfo[] removed) - { - init(targetId, targetVersion); - this.added = added; - this.removed = removed; - } - - // documentation inherited - public void apply (SceneModel model) - { - super.apply(model); - - StageMisoSceneModel mmodel = StageMisoSceneModel.getSceneModel(model); - - // wipe out the objects that need to go - if (removed != null) { - for (int ii = 0; ii < removed.length; ii++) { - mmodel.removeObject(removed[ii]); - } - } - - // add the new objects - if (added != null) { - for (int ii = 0; ii < added.length; ii++) { - mmodel.addObject(added[ii]); - } - } - } -} diff --git a/src/java/com/threerings/stage/data/StageCodes.java b/src/java/com/threerings/stage/data/StageCodes.java deleted file mode 100644 index cb1320fbc..000000000 --- a/src/java/com/threerings/stage/data/StageCodes.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $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.stage.data; - -import com.threerings.util.MessageBundle; - -import com.threerings.presents.data.InvocationCodes; - -import com.threerings.crowd.data.BodyObject; - -/** - * Codes and constants relating to the Stage system. - */ -public interface StageCodes extends InvocationCodes -{ - /** The i18n bundle identifier for the Stage system. */ - public static final String STAGE_MESSAGE_BUNDLE = "stage.general"; - - /** The resource set that contains our tileset bundles. */ - public static final String TILESET_RSRC_SET = "tilesets"; - - /** The access control identifier for scene modification privileges. - * See {@link BodyObject#checkAccess}. */ - public static final String MODIFY_SCENE_ACCESS = "stage.modify_scene"; - - /** The access control identifier for potentially damaging scene - * modification privileges. See {@link BodyObject#checkAccess}. */ - public static final String MUTILATE_SCENE_ACCESS = "stage.mutilate_scene"; - - /** An error delivered when adding objects to scenes. */ - public static final String ERR_NO_OVERLAP = MessageBundle.qualify( - STAGE_MESSAGE_BUNDLE, "m.addobj_no_overlap"); - - /** An error delivered when adding objects to scenes. */ - public static final String ERR_CANNOT_CLUSTER = MessageBundle.qualify( - STAGE_MESSAGE_BUNDLE, "m.cannot_cluster"); -} diff --git a/src/java/com/threerings/stage/data/StageLocation.java b/src/java/com/threerings/stage/data/StageLocation.java deleted file mode 100644 index 5c7c6d523..000000000 --- a/src/java/com/threerings/stage/data/StageLocation.java +++ /dev/null @@ -1,133 +0,0 @@ -// -// $Id: Location.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.stage.data; - -import com.threerings.io.SimpleStreamableObject; - -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; - -import com.threerings.whirled.spot.data.Location; - -/** - * Contains information on a scene occupant's position and orientation. - */ -public class StageLocation extends SimpleStreamableObject - implements Location -{ - /** The user's x position (interpreted by the display system). */ - public int x; - - /** The user's y position (interpreted by the display system). */ - public int y; - - /** The user's orientation (defined by {@link DirectionCodes}). */ - public byte orient; - - /** {@link #toString} helper function. */ - public String orientToString () - { - return DirectionUtil.toShortString(orient); - } - - /** - * A zero-argument constructor used when unserializing instances. - */ - public StageLocation () - { - } - - /** - * Constructs a location with the specified coordinates and - * orientation. - */ - public StageLocation (int x, int y, byte orient) - { - this.x = x; - this.y = y; - this.orient = orient; - - if (orient == -1) { - Thread.dumpStack(); - } - } - - // documentation inherited from interface Location - public Location getOpposite () - { - StageLocation opp = (StageLocation) clone(); - opp.orient = (byte) DirectionUtil.getOpposite(orient); - return opp; - } - - /** - * Location equivalence means that the coordinates and orientation are - * the same. - */ - public boolean equivalent (Location oloc) - { - return equals(oloc) && (orient == ((StageLocation) oloc).orient); - } - - /** - * Location equality is determined by coordinates. - */ - public boolean equals (Object other) - { - // TEMP - if (other instanceof com.threerings.whirled.spot.data.SceneLocation) { - com.threerings.stage.Log.warning( - "Illegal compare of SceneLocation and Location!!!"); - Thread.dumpStack(); // this will help us find logic errors, - // as a SceneLocation and a Location shouldn't be compared.. - } - // END: temp - - if (other instanceof StageLocation) { - StageLocation that = (StageLocation) other; - return (this.x == that.x) && (this.y == that.y); - - } else { - return false; - } - } - - /** - * Computes a reasonable hashcode for location instances. - */ - public int hashCode () - { - return x ^ y; - } - - /** - * Creates a clone of this instance. - */ - public Object clone () - { - try { - return (StageLocation)super.clone(); - } catch (CloneNotSupportedException cnse) { - throw new RuntimeException("StageLocation.clone() failed " + cnse); - } - } -} diff --git a/src/java/com/threerings/stage/data/StageMisoSceneModel.java b/src/java/com/threerings/stage/data/StageMisoSceneModel.java deleted file mode 100644 index f6ea348e5..000000000 --- a/src/java/com/threerings/stage/data/StageMisoSceneModel.java +++ /dev/null @@ -1,64 +0,0 @@ -// -// $Id: YoMisoSceneModel.java 9680 2003-06-13 02:16:00Z mdb $ - -package com.threerings.stage.data; - -import com.threerings.miso.data.SparseMisoSceneModel; - -import com.threerings.whirled.data.AuxModel; -import com.threerings.whirled.data.SceneModel; - -/** - * Extends the {@link SparseMisoSceneModel} with the necessary interface - * to wire it up to the Whirled auxiliary model system. - */ -public class StageMisoSceneModel extends SparseMisoSceneModel - implements AuxModel -{ - /** The width (in tiles) of a scene section. */ - public static final int SECTION_WIDTH = 9; - - /** The height (in tiles) of a scene section. */ - public static final int SECTION_HEIGHT = 9; - - /** - * Creates a completely uninitialized scene model. - */ - public StageMisoSceneModel () - { - super(SECTION_WIDTH, SECTION_HEIGHT); - } - - /** - * Locates and returns the {@link StageMisoSceneModel} among the - * auxiliary scene models associated with the supplied scene model. - * null is returned if no miso scene model could be - * found. - */ - public static StageMisoSceneModel getSceneModel (SceneModel model) - { - for (int ii = 0; ii < model.auxModels.length; ii++) { - if (model.auxModels[ii] instanceof StageMisoSceneModel) { - return (StageMisoSceneModel)model.auxModels[ii]; - } - } - return null; - } - - /** - * Returns the section key for the specified tile coordinate. - */ - public int getSectionKey (int x, int y) - { - return key(x, y); - } - - /** - * Returns the section identified by the specified key, or null if no - * section exists for that key. - */ - public Section getSection (int key) - { - return (Section)_sections.get(key); - } -} diff --git a/src/java/com/threerings/stage/data/StageOccupantInfo.java b/src/java/com/threerings/stage/data/StageOccupantInfo.java deleted file mode 100644 index c2c5d9868..000000000 --- a/src/java/com/threerings/stage/data/StageOccupantInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// $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.stage.data; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.OccupantInfo; - -/** - * Extends the standard occupant info with stage specific business. - */ -public class StageOccupantInfo extends OccupantInfo -{ - /** Creates a new instance for the specified body. */ - public StageOccupantInfo (BodyObject body) - { - super(body); - } - - /** Creates a blank instance for unserialization. */ - public StageOccupantInfo () - { - } - - /** - * Should return true if the occupant in question is available to be - * clustered with, false if they are "busy". This means that a user - * can click on them and start a chat circle. - */ - public boolean isClusterable () - { - return true; - } -} diff --git a/src/java/com/threerings/stage/data/StageScene.java b/src/java/com/threerings/stage/data/StageScene.java deleted file mode 100644 index c4ff4de5c..000000000 --- a/src/java/com/threerings/stage/data/StageScene.java +++ /dev/null @@ -1,211 +0,0 @@ -// -// $Id: YoScene.java 17013 2004-09-08 02:39:09Z ray $ - -package com.threerings.stage.data; - -import java.util.ArrayList; -import java.util.Iterator; - -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.util.MisoUtil; - -import com.threerings.crowd.data.PlaceConfig; - -import com.threerings.whirled.data.Scene; -import com.threerings.whirled.data.SceneImpl; -import com.threerings.whirled.data.SceneUpdate; - -import com.threerings.whirled.spot.data.Portal; -import com.threerings.whirled.spot.data.SpotScene; -import com.threerings.whirled.spot.data.SpotSceneImpl; -import com.threerings.whirled.spot.data.SpotSceneModel; - -import com.threerings.stage.Log; - -/** - * The implementation of the Stage scene interface. - */ -public class StageScene extends SceneImpl - implements Scene, SpotScene, Cloneable -{ - /** - * Creates an instance that will obtain data from the supplied scene - * model and place config. - */ - public StageScene (StageSceneModel model, PlaceConfig config) - { - super(model, config); - _model = model; - _sdelegate = new SpotSceneImpl(SpotSceneModel.getSceneModel(_model)); - readInterestingObjects(); - } - - /** - * Returns the scene type (e.g. "world", "port", "bank", etc.). - */ - public String getType () - { - return _model.type; - } - - /** - * Returns the zone id to which this scene belongs. - */ - public int getZoneId () - { - return _model.zoneId; - } - - /** - * Sets the type of this scene. - */ - public void setType (String type) - { - _model.type = type; - } - - /** - * Get the default color id to use for the specified colorization class, - * or -1 if no default is set. - */ - public int getDefaultColor (int classId) - { - return _model.getDefaultColor(classId); - } - - /** - * Set the default color to use for the specified colorization class id. - * Setting the colorId to -1 disables the default. - */ - public void setDefaultColor (int classId, int colorId) - { - _model.setDefaultColor(classId, colorId); - } - - /** - * Iterates over all of the interesting objects in this scene. - */ - public Iterator enumerateObjects () - { - return _objects.iterator(); - } - - /** - * Adds a new object to this scene. - */ - public void addObject (ObjectInfo info) - { - _objects.add(info); - - // add it to the underlying scene model - StageMisoSceneModel mmodel = StageMisoSceneModel.getSceneModel(_model); - if (mmodel != null) { - if (!mmodel.addObject(info)) { - Log.warning("Scene model rejected object add " + - "[scene=" + this + ", object=" + info + "]."); - } - } - } - - /** - * Removes an object from this scene. - */ - public boolean removeObject (ObjectInfo info) - { - boolean removed = _objects.remove(info); - - // remove it from the underlying scene model - StageMisoSceneModel mmodel = StageMisoSceneModel.getSceneModel(_model); - if (mmodel != null) { - removed = mmodel.removeObject(info) || removed; - } - - return removed; - } - - // documentation inherited - public void updateReceived (SceneUpdate update) - { - super.updateReceived(update); - - // update our spot scene delegate - _sdelegate.updateReceived(); - - // re-read our interesting objects - readInterestingObjects(); - } - - // documentation inherited - public Object clone () - throws CloneNotSupportedException - { - // create a new scene with a clone of our model - return new StageScene((StageSceneModel)_model.clone(), _config); - } - - // documentation inherited from interface - public Portal getPortal (int portalId) - { - return _sdelegate.getPortal(portalId); - } - - // documentation inherited from interface - public int getPortalCount () - { - return _sdelegate.getPortalCount(); - } - - // documentation inherited from interface - public Iterator getPortals () - { - return _sdelegate.getPortals(); - } - - // documentation inherited from interface - public short getNextPortalId () - { - return _sdelegate.getNextPortalId(); - } - - // documentation inherited from interface - public Portal getDefaultEntrance () - { - return _sdelegate.getDefaultEntrance(); - } - - // documentation inherited from interface - public void addPortal (Portal portal) - { - _sdelegate.addPortal(portal); - } - - // documentation inherited from interface - public void removePortal (Portal portal) - { - _sdelegate.removePortal(portal); - } - - // documentation inherited from interface - public void setDefaultEntrance (Portal portal) - { - _sdelegate.setDefaultEntrance(portal); - } - - protected void readInterestingObjects () - { - _objects.clear(); - StageMisoSceneModel mmodel = StageMisoSceneModel.getSceneModel(_model); - if (mmodel != null) { - mmodel.getInterestingObjects(_objects); - } - } - - /** A reference to our scene model. */ - protected StageSceneModel _model; - - /** Our spot scene delegate. */ - protected SpotSceneImpl _sdelegate; - - /** A list of all interesting scene objects. */ - protected ArrayList _objects = new ArrayList(); -} diff --git a/src/java/com/threerings/stage/data/StageSceneConfig.java b/src/java/com/threerings/stage/data/StageSceneConfig.java deleted file mode 100644 index 8dbc4793b..000000000 --- a/src/java/com/threerings/stage/data/StageSceneConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// $Id: StageSceneConfig.java 8478 2003-05-07 05:12:26Z mdb $ - -package com.threerings.stage.data; - -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.data.PlaceConfig; - -import com.threerings.stage.client.StageSceneController; - -/** - * Place configuration for the main isometric scenes in Stage. - */ -public class StageSceneConfig extends PlaceConfig -{ - // documentation inherited - public PlaceController createController () - { - return new StageSceneController(); - } - - // documentation inherited - public String getManagerClassName () - { - return "com.threerings.stage.server.StageSceneManager"; - } -} diff --git a/src/java/com/threerings/stage/data/StageSceneMarshaller.java b/src/java/com/threerings/stage/data/StageSceneMarshaller.java deleted file mode 100644 index 5e85b9a68..000000000 --- a/src/java/com/threerings/stage/data/StageSceneMarshaller.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $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.stage.data; - -import com.threerings.miso.data.ObjectInfo; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.dobj.InvocationResponseEvent; -import com.threerings.stage.client.StageSceneService; - -/** - * Provides the implementation of the {@link StageSceneService} interface - * that marshalls the arguments and delivers the request to the provider - * on the server. Also provides an implementation of the response listener - * interfaces that marshall the response arguments and deliver them back - * to the requesting client. - */ -public class StageSceneMarshaller extends InvocationMarshaller - implements StageSceneService -{ - /** The method id used to dispatch {@link #addObject} requests. */ - public static final int ADD_OBJECT = 1; - - // documentation inherited from interface - public void addObject (Client arg1, ObjectInfo arg2, InvocationService.ConfirmListener arg3) - { - InvocationMarshaller.ConfirmMarshaller listener3 = new InvocationMarshaller.ConfirmMarshaller(); - listener3.listener = arg3; - sendRequest(arg1, ADD_OBJECT, new Object[] { - arg2, listener3 - }); - } - - /** The method id used to dispatch {@link #removeObjects} requests. */ - public static final int REMOVE_OBJECTS = 2; - - // documentation inherited from interface - public void removeObjects (Client arg1, ObjectInfo[] arg2, InvocationService.ConfirmListener arg3) - { - InvocationMarshaller.ConfirmMarshaller listener3 = new InvocationMarshaller.ConfirmMarshaller(); - listener3.listener = arg3; - sendRequest(arg1, REMOVE_OBJECTS, new Object[] { - arg2, listener3 - }); - } - -} diff --git a/src/java/com/threerings/stage/data/StageSceneModel.java b/src/java/com/threerings/stage/data/StageSceneModel.java deleted file mode 100644 index 12f3c6b8a..000000000 --- a/src/java/com/threerings/stage/data/StageSceneModel.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $Id: YoSceneModel.java 17643 2004-10-28 22:58:30Z mdb $ - -package com.threerings.stage.data; - -import com.threerings.util.StreamableArrayList; -import com.threerings.util.StreamableIntIntMap; - -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.spot.data.SpotSceneModel; - -/** - * Extends the basic scene model with the notion of a scene type and - * incorporates the necessary auxiliary models used by the Stage system. - */ -public class StageSceneModel extends SceneModel -{ - /** A scene type code. */ - public static final String WORLD = "world"; - - /** This scene's type which is a string identifier used to later - * construct a specific controller to handle this scene. */ - public String type; - - /** The zone id to which this scene belongs. */ - public int zoneId; - - /** If non-null, contains default colorizations to use for objects - * that do not have colorizations defined. */ - public StreamableIntIntMap defaultColors; - - /** - * Get the default color to use for the specified colorization - * classId, or -1 if no default is set for that colorization. - */ - public int getDefaultColor (int classId) - { - if (defaultColors != null) { - return defaultColors.get(classId); - } - return -1; - } - - /** - * Set the default colorId to use for a specified colorization - * classId, or -1 to clear the default for that colorization. - */ - public void setDefaultColor (int classId, int colorId) - { - if (colorId == -1) { - if (defaultColors != null) { - defaultColors.remove(classId); - if (defaultColors.size() == 0) { - defaultColors = null; - } - } - - } else { - if (defaultColors == null) { - defaultColors = new StreamableIntIntMap(); - } - defaultColors.put(classId, colorId); - } - } - - /** - * Creates and returns a blank scene model. - */ - public static StageSceneModel blankStageSceneModel () - { - StageSceneModel model = new StageSceneModel(); - populateBlankStageSceneModel(model); - return model; - } - - /** - * Populates a blank scene model with blank values. - */ - protected static void populateBlankStageSceneModel (StageSceneModel model) - { - populateBlankSceneModel(model); - model.addAuxModel(new SpotSceneModel()); - model.addAuxModel(new StageMisoSceneModel()); - } -} diff --git a/src/java/com/threerings/stage/data/StageSceneObject.java b/src/java/com/threerings/stage/data/StageSceneObject.java deleted file mode 100644 index 45056486e..000000000 --- a/src/java/com/threerings/stage/data/StageSceneObject.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $Id: StageSceneObject.java 18473 2004-12-28 03:52:57Z mdb $ - -package com.threerings.stage.data; - -import com.threerings.whirled.spot.data.SpotSceneObject; - -/** - * Extends the basic {@link SpotSceneObject} with data and services - * specific to isometric stage scenes. - */ -public class StageSceneObject extends SpotSceneObject -{ - // AUTO-GENERATED: FIELDS START - /** The field name of the stageSceneService field. */ - public static final String STAGE_SCENE_SERVICE = "stageSceneService"; - - /** The field name of the lightLevel field. */ - public static final String LIGHT_LEVEL = "lightLevel"; - - /** The field name of the lightShade field. */ - public static final String LIGHT_SHADE = "lightShade"; - // AUTO-GENERATED: FIELDS END - - /** Provides stage scene services. */ - public StageSceneMarshaller stageSceneService; - - /** The light level in this scene. 0f being fully on, 1f fully shaded. */ - public float lightLevel = 0f; - - /** The color of the light. */ - public int lightShade = 0xFFFFFF; - - // AUTO-GENERATED: METHODS START - /** - * Requests that the stageSceneService field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setStageSceneService (StageSceneMarshaller value) - { - StageSceneMarshaller ovalue = this.stageSceneService; - requestAttributeChange( - STAGE_SCENE_SERVICE, value, ovalue); - this.stageSceneService = value; - } - - /** - * Requests that the lightLevel field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setLightLevel (float value) - { - float ovalue = this.lightLevel; - requestAttributeChange( - LIGHT_LEVEL, Float.valueOf(value), Float.valueOf(ovalue)); - this.lightLevel = value; - } - - /** - * Requests that the lightShade field be set to the - * specified value. The local value will be updated immediately and an - * event will be propagated through the system to notify all listeners - * that the attribute did change. Proxied copies of this object (on - * clients) will apply the value change when they received the - * attribute changed notification. - */ - public void setLightShade (int value) - { - int ovalue = this.lightShade; - requestAttributeChange( - LIGHT_SHADE, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.lightShade = value; - } - // AUTO-GENERATED: METHODS END -} diff --git a/src/java/com/threerings/stage/server/StageSceneDispatcher.java b/src/java/com/threerings/stage/server/StageSceneDispatcher.java deleted file mode 100644 index bfe10799d..000000000 --- a/src/java/com/threerings/stage/server/StageSceneDispatcher.java +++ /dev/null @@ -1,79 +0,0 @@ -// -// $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.stage.server; - -import com.threerings.miso.data.ObjectInfo; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.data.InvocationMarshaller; -import com.threerings.presents.server.InvocationDispatcher; -import com.threerings.presents.server.InvocationException; -import com.threerings.stage.client.StageSceneService; -import com.threerings.stage.data.StageSceneMarshaller; - -/** - * Dispatches requests to the {@link StageSceneProvider}. - */ -public class StageSceneDispatcher extends InvocationDispatcher -{ - /** - * Creates a dispatcher that may be registered to dispatch invocation - * service requests for the specified provider. - */ - public StageSceneDispatcher (StageSceneProvider provider) - { - this.provider = provider; - } - - // documentation inherited - public InvocationMarshaller createMarshaller () - { - return new StageSceneMarshaller(); - } - - // documentation inherited - public void dispatchRequest ( - ClientObject source, int methodId, Object[] args) - throws InvocationException - { - switch (methodId) { - case StageSceneMarshaller.ADD_OBJECT: - ((StageSceneProvider)provider).addObject( - source, - (ObjectInfo)args[0], (InvocationService.ConfirmListener)args[1] - ); - return; - - case StageSceneMarshaller.REMOVE_OBJECTS: - ((StageSceneProvider)provider).removeObjects( - source, - (ObjectInfo[])args[0], (InvocationService.ConfirmListener)args[1] - ); - return; - - default: - super.dispatchRequest(source, methodId, args); - return; - } - } -} diff --git a/src/java/com/threerings/stage/server/StageSceneManager.java b/src/java/com/threerings/stage/server/StageSceneManager.java deleted file mode 100644 index fb36ad65c..000000000 --- a/src/java/com/threerings/stage/server/StageSceneManager.java +++ /dev/null @@ -1,847 +0,0 @@ -// -// $Id: WorldSceneManager.java 19769 2005-03-17 07:38:31Z mdb $ - -package com.threerings.stage.server; - -import java.awt.Point; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; - -import com.samskivert.io.PersistenceException; -import com.samskivert.util.HashIntMap; -import com.samskivert.util.Invoker; -import com.samskivert.util.StringUtil; - -import com.threerings.media.util.AStarPathUtil; -import com.threerings.media.util.MathUtil; -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.util.MisoSceneMetrics; -import com.threerings.miso.util.MisoUtil; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; - -import com.threerings.whirled.data.SceneUpdate; -import com.threerings.whirled.spot.data.Cluster; -import com.threerings.whirled.spot.data.ClusterObject; -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.spot.data.Portal; -import com.threerings.whirled.spot.data.SceneLocation; -import com.threerings.whirled.spot.server.SpotSceneManager; - -import com.threerings.stage.Log; -import com.threerings.stage.client.StageSceneService; -import com.threerings.stage.data.DefaultColorUpdate; -import com.threerings.stage.data.ModifyObjectsUpdate; -import com.threerings.stage.data.StageCodes; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageMisoSceneModel; -import com.threerings.stage.data.StageOccupantInfo; -import com.threerings.stage.data.StageScene; -import com.threerings.stage.data.StageSceneMarshaller; -import com.threerings.stage.data.StageSceneModel; -import com.threerings.stage.data.StageSceneObject; -import com.threerings.stage.util.StageSceneUtil; - -/** - * Defines extensions to the basic Stage scene manager specific to - * displaying isometric "stage" scenes (these may be indoor, outdoor or - * aboard a vessel). - */ -public class StageSceneManager extends SpotSceneManager - implements StageSceneProvider -{ - /** - * Returns a traversal predicate for use with {@link - * StageSceneUtil#findStandingSpot} that validates whether a player can - * stand in the searched spots. - */ - public AStarPathUtil.TraversalPred getCanStandPred () - { - // this checks to see if we can stand at a particular tile coord - return new AStarPathUtil.TraversalPred() { - public boolean canTraverse (Object traverser, int x, int y) { - _tloc.x = MisoUtil.toFull(x, 2); - _tloc.y = MisoUtil.toFull(y, 2); - return mayStandAtLocation((BodyObject)traverser, _tloc); - } - protected StageLocation _tloc = new StageLocation(); - }; - } - - /** - * Adds the supplied object to this scene. A persistent update is - * generated and broadcast to all scene occupants. The update is - * stored in the repository for communication to future occupants of - * the scene and then entire complex process of changing our virtual - * game world is effected at the simple call of this single method. - * - * @param killOverlap if true, overlapping object will be removed, and - * the allowOverlap argument will be ignored. - * @param allowOverlap if true, overlapping objects will be allowed - * but one must be *very* careful to ensure that they know what they - * are doing (ie. the objects have render priorities that correctly - * handle the overlap). - * - * @return true if the object was added, false if the add was rejected - * because the object overlaps an existing scene object. - */ - public boolean addObject (ObjectInfo info, boolean killOverlap, - boolean allowOverlap) - { - // determine whether or not any object overlap our footprint - Rectangle foot = StageSceneUtil.getObjectFootprint( - StageServer.tilemgr, info.tileId, info.x, info.y); - if (foot == null) { - Log.warning("Aiya! Unable to compute object footprint! " + - "[where=" + where() + ", info=" + info + "]."); - return false; - } - - ObjectInfo[] lappers = StageSceneUtil.getIntersectedObjects( - StageServer.tilemgr, (StageSceneModel)_sscene.getSceneModel(), - foot); - if (!killOverlap && lappers.length > 0 && !allowOverlap) { - // no overlapping allowed - return false; - } - - // create our scene update which will be stored in the database - // and used to efficiently update clients - final ModifyObjectsUpdate update = new ModifyObjectsUpdate(); - update.init(_sscene.getId(), _sscene.getVersion(), - new ObjectInfo[] { info }, killOverlap ? lappers : null); - - Log.info("Modifying objects '" + update + "."); - recordUpdate(update, true); - - return true; - } - - /** - * Changes the default colorization for the specified color class. - * A persistent update is generated and broadcast to all scene - * occupants. The update is stored in the repository for communication - * to future occupants of the scene and then entire complex process - * of changing our virtual game world is effected at the simple call - * of this single method. - */ - public void setColor (int classId, int colorId) - { - DefaultColorUpdate update = new DefaultColorUpdate(); - update.init(_sscene.getId(), _sscene.getVersion(), classId, colorId); - recordUpdate(update, false); - } - - /** - * Returns true if the specified tile coordinate is passable (the base - * tile is passable and it is not in the footprint of an object). - */ - public boolean isPassable (int tx, int ty) - { - return (StageSceneUtil.isPassable( - StageServer.tilemgr, _mmodel.getBaseTileId(tx, ty)) && - !checkContains(_footprints.iterator(), tx, ty)); - } - - /** - * Called by NPPs to determine whether or not they can stand at the - * specified location. - */ - public boolean mayStandAtLocation (BodyObject source, StageLocation loc) - { - return validateLocation(source, loc, false); - } - - // documentation inherited from interface - public void addObject (ClientObject caller, ObjectInfo info, - StageSceneService.ConfirmListener listener) - throws InvocationException - { - BodyObject user = (BodyObject)caller; - String err = user.checkAccess(StageCodes.MODIFY_SCENE_ACCESS, _sscene); - if (err != null) { - throw new InvocationException(err); - } - - if (addObject(info, false, true)) { - listener.requestProcessed(); - } else { - listener.requestFailed(StageCodes.ERR_NO_OVERLAP); - } - } - - // documentation inherited from interface - public void removeObjects (ClientObject caller, ObjectInfo[] info, - StageSceneService.ConfirmListener listener) - throws InvocationException - { - BodyObject user = (BodyObject)caller; - String err = user.checkAccess(StageCodes.MODIFY_SCENE_ACCESS, _sscene); - if (err != null) { - throw new InvocationException(err); - } - - // create our scene update which will be stored in the database - // and used to efficiently update clients - ModifyObjectsUpdate update = new ModifyObjectsUpdate(); - update.init(_sscene.getId(), _sscene.getVersion(), null, info); - - Log.info("Modifying objects '" + update + "."); - recordUpdate(update, true); - - listener.requestProcessed(); - } - - // documentation inherited - protected void gotSceneData () - { - super.gotSceneData(); - - // cast some scene related bits - _sscene = (StageScene)_scene; - _mmodel = StageMisoSceneModel.getSceneModel(_scene.getSceneModel()); - - // note the footprints of all objects and portals in this scene - computeFootprints(); - } - - /** - * Applies the supplied scene update to our runtime scene and then - * fires off an invocation unit to apply the update to the scene - * database. Finally the update is "recorded" which broadcasts the - * update to all occupants of the scene and stores the update so that - * it can be provided as a patch to future scene visitors. - */ - protected void recordUpdate (SceneUpdate update, boolean tilesModified) - { - // do the standard update processing - recordUpdate(update); - - // then recompute some internal structures if need be - if (tilesModified) { - sceneTilesModified(); - } - } - - /** - * Called when any change is made to a scene's base or object tiles - * (resulting in a change in the way the scene looks). If any sneaky - * business need be done to deal with said addition, it can be handled - * here. - */ - protected void sceneTilesModified () - { - // compute the object footprints of all objects in this scene - computeFootprints(); - } - - // documentation inherited - protected void didStartup () - { - super.didStartup(); - _ssobj = (StageSceneObject)_plobj; - - // register and fill in our stage scene service - StageSceneMarshaller service = (StageSceneMarshaller) - StageServer.invmgr.registerDispatcher( - new StageSceneDispatcher(this), false); - _ssobj.setStageSceneService(service); - } - - // documentation inherited - protected void didShutdown () - { - super.didShutdown(); - StageServer.invmgr.clearDispatcher(_ssobj.stageSceneService); - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return StageSceneObject.class; - } - - // documentation inherited - protected void bodyLeft (int bodyOid) - { - super.bodyLeft(bodyOid); - - // out ye go! - _loners.remove(bodyOid); - } - - // documentation inherited - protected void updateLocation (BodyObject source, Location loc) - { - super.updateLocation(source, loc); - - // keep a rectangle around for each un-clustered occupant - StageLocation sloc = (StageLocation) loc; - int tx = MisoUtil.fullToTile(sloc.x), ty = MisoUtil.fullToTile(sloc.y); - _loners.put(source.getOid(), new Rectangle(tx, ty, 1, 1)); - } - - /** - * Computes the footprints of all objects and portals in this scene. - * This is done when we are first resolved and following any - * modifications to the scene's tile data. - */ - protected void computeFootprints () - { - _footprints.clear(); - _mmodel.visitObjects(new StageMisoSceneModel.ObjectVisitor() { - public void visit (ObjectInfo info) { - Rectangle foot = StageSceneUtil.getObjectFootprint( - StageServer.tilemgr, info.tileId, info.x, info.y); - _footprints.add(foot); - } - }); - -// Log.info("Computed footprints [where=" + where () + -// ", rects=" + StringUtil.toString(_footprints) + "]."); - - // place the tile coordinates of our portals into a set for - // efficient comparison with location coordinates - _plocs.clear(); - for (Iterator iter = _sscene.getPortals(); iter.hasNext(); ) { - Portal port = (Portal)iter.next(); - StageLocation loc = (StageLocation) port.loc; - _plocs.add(new Point(MisoUtil.fullToTile(loc.x), - MisoUtil.fullToTile(loc.y))); - } - } - - /** - * Helper function for {@link #mayStandAtLocation} and {@link - * #validateLocation(BodyObject,Location)}. - */ - protected boolean validateLocation (BodyObject source, StageLocation loc, - boolean allowPortals) - { - int tx = MisoUtil.fullToTile(loc.x), ty = MisoUtil.fullToTile(loc.y); - - // make sure the tile at that location is passable - if (!StageSceneUtil.isPassable(StageServer.tilemgr, - _mmodel.getBaseTileId(tx, ty))) { -// Log.info("Rejecting non-passable loc [who=" + source.who() + -// ", loc=" + loc + "]."); - return false; - } - - // if they're moving to stand on a portal, let them do it - if (allowPortals && _plocs.contains(new Point(tx, ty))) { - return true; - } - - // if they are already standing on this tile, allow it - SceneLocation cloc = (SceneLocation) - _ssobj.occupantLocs.get(Integer.valueOf(source.getOid())); - if (cloc != null) { - StageLocation sloc = (StageLocation) cloc.loc; - if (MisoUtil.fullToTile(sloc.x) == tx && - MisoUtil.fullToTile(sloc.y) == ty) { -// Log.info("Allowing adjust [who=" + source.who () + -// ", cloc=" + cloc + ", nloc=" + loc + "]."); - return true; - } - } - - // make sure they're not standing in a cluster footprint, an - // object footprint, or in the same tile as another scene occupant - if (checkContains(_ssobj.clusters.iterator(), tx, ty) || - checkContains(_footprints.iterator(), tx, ty) || - checkContains(_loners.values().iterator(), tx, ty)) { -// Log.info("Rejecting loc [who=" + source.who() + -// ", loc=" + loc + ", inCluster=" + -// checkContains(_ssobj.clusters.iterator(), tx, ty) + -// ", inFootprint=" + -// checkContains(_footprints.iterator(), tx, ty) + -// ", onLoner=" + -// checkContains(_loners.values().iterator(), tx, ty) + -// "]."); - return false; - } - - return true; - } - - /** Helper function for {@link #validateLocation}. */ - protected boolean checkContains (Iterator iter, int tx, int ty) - { - while (iter.hasNext()) { - Rectangle rect = (Rectangle)iter.next(); - if (rect.contains(tx, ty)) { -// Log.info(StringUtil.toString(rect) + " contains " + -// StringUtil.coordsToString(tx, ty) + "."); - return true; - } - } - return false; - } - - // documentation inherited - protected SceneLocation computeEnteringLocation ( - BodyObject body, Portal entry) - { - // sanity check - if (entry == null) { - Log.warning("Requested to compute entering location for " + - "non-existent portal [where=" + where() + - ", who=" + body.who() + "]."); - entry = _sscene.getDefaultEntrance(); - } - - MisoSceneMetrics metrics = StageSceneUtil.getMetrics(); - SceneLocation loc = new SceneLocation( - entry.getOppLocation(), body.getOid()); - StageLocation sloc = (StageLocation) loc.loc; - int tx = MisoUtil.fullToTile(sloc.x), - ty = MisoUtil.fullToTile(sloc.y); - int oidx = sloc.orient/2; - int lidx = (oidx+3)%4; // rotate to the left - int ridx = (oidx+1)%4; // rotate to the right - - // start in the row in front of the portal and search forward, - // checking the center, then the spot(s) to the left, then the - // spot(s) to the right (fanning out by one tile each time) - final int MAX_FAN = 4; - LOC_SEARCH: - for (int fan = 1; fan < MAX_FAN; fan++) { - tx += PORTAL_DX[oidx]; - ty += PORTAL_DY[oidx]; - - // look in the center column - if (checkEntry(metrics, body, tx, ty, sloc)) { - break LOC_SEARCH; - } - - // look to the left - for (int lx = tx, ly = ty, ff = 0; ff < fan; ff++) { - lx += PORTAL_DX[lidx]; - ly += PORTAL_DY[lidx]; - if (checkEntry(metrics, body, lx, ly, sloc)) { - break LOC_SEARCH; - } - } - - // look to the right - for (int rx = tx, ry = ty, ff = 0; ff < fan; ff++) { - rx += PORTAL_DX[ridx]; - ry += PORTAL_DY[ridx]; - if (checkEntry(metrics, body, rx, ry, sloc)) { - break LOC_SEARCH; - } - } - - // if this is our last pass and we didn't find anything, - // revert back to the portal location - if (fan == MAX_FAN-1) { - sloc = (StageLocation) entry.getOppLocation(); - } - } - - tx = MisoUtil.fullToTile(sloc.x); - ty = MisoUtil.fullToTile(sloc.y); - _loners.put(body.getOid(), new Rectangle(tx, ty, 1, 1)); - - loc.loc = sloc; - return loc; - } - - /** Helper function for {@link #computeEnteringLocation}. */ - protected boolean checkEntry (MisoSceneMetrics metrics, BodyObject body, - int tx, int ty, StageLocation loc) - { - loc.x = MisoUtil.toFull(tx, metrics.finegran/2); - loc.y = MisoUtil.toFull(ty, metrics.finegran/2); - return validateLocation(body, loc, false); - } - - // documentation inherited - protected boolean validateLocation (BodyObject source, Location loc) - { - // TODO: make sure the user isn't warping to hell and gone (and if - // they are, make sure they're an admin) - return validateLocation(source, (StageLocation)loc, true); - } - - // documentation inherited - protected boolean canAddBody (ClusterRecord clrec, BodyObject body) - { - // make sure we have a setting for clusters of this size - if (clrec.size() >= TARGET_SIZE.length-2) { - return false; - } - - // if this is a brand new cluster, just make it 2x2 and be done - // with it - Cluster cl = clrec.getCluster(); - if (cl.width == 0) { - cl.width = 2; - cl.height = 2; -// Log.info("Created new cluster for " + body.who() + -// " (" + cl + ")."); - return true; - } - -// Log.info("Maybe adding " + body.who() + " to " + cl + "."); - - // if the cluster is already big enough, we're groovy - int target = TARGET_SIZE[clrec.size()+1]; - if (cl.width >= target) { - return true; - } - - // make an expanded footprint and try to fit it somewhere - int expand = target-cl.width; - Rectangle rect = null; - for (int ii = 0; ii < X_OFF.length; ii++) { - rect = new Rectangle(cl.x + expand*X_OFF[ii], - cl.y + expand*Y_OFF[ii], - cl.width+expand, cl.height+expand); - - // if this rect overlaps objects, other clusters, portals or - // impassable tiles, it's no good - if (checkIntersects(_ssobj.clusters.iterator(), rect, cl) || - checkIntersects(_footprints.iterator(), rect, cl) || - checkPortals(rect) || checkViolatesPassability(rect)) { - rect = null; - } else { - break; - } - } - - // if we couldn't expand in any direction, it's no go - if (rect == null) { -// Log.info("Couldn't expand cluster " + cl + "."); - return false; - } - - // now look to see if we just expanded our cluster over top of any - // unsuspecting standers by and if so, attempt to subsume them - for (Iterator iter = _loners.keySet().iterator(); - iter.hasNext(); ) { - int bodyOid = ((Integer)iter.next()).intValue(); - // skip ourselves - if (bodyOid == body.getOid()) { - continue; - } - - // do the right thing with a person standing right on the - // cluster (they're the person we're clustering with) - Rectangle trect = (Rectangle)_loners.get(bodyOid); - if (trect.equals(cl)) { - continue; - } - - if (trect.intersects(rect)) { - // make sure this person isn't already in our cluster - ClusterObject clobj = clrec.getClusterObject(); - if (clobj != null && clobj.occupants.contains(bodyOid)) { - Log.warning("Ignoring stale occupant [where=" + where() + - ", cluster=" + cl + ", occ=" + bodyOid + "]."); - continue; - } - - // make sure the subsumee exists - final BodyObject bobj = (BodyObject) - StageServer.omgr.getObject(bodyOid); - if (bobj == null) { - Log.warning("Can't subsume disappeared body " + - "[where=" + where() + ", cluster=" + cl + - ", boid=" + bodyOid + "]."); - continue; - } - - // we subsume nearby pirates by queueing up their addition - // to our cluster to be processed after we finish adding - // ourselves to this cluster - final ClusterRecord fclrec = clrec; - StageServer.omgr.postRunnable(new Runnable() { - public void run () { - try { - Log.info("Subsuming " + bobj.who() + - " into " + fclrec.getCluster() + "."); - fclrec.addBody(bobj); - - } catch (InvocationException ie) { - Log.info("Unable to subsume neighbor " + - "[cluster=" + fclrec.getCluster() + - ", neighbor=" + bobj.who() + - ", cause=" + ie.getMessage() + "]."); - } - } - }); - } - } - -// Log.info("Expanding cluster [cluster=" + cl + -// ", rect=" + rect + "]."); - cl.setBounds(rect); - - return true; - } - - /** Helper function for {@link #canAddBody}. */ - protected boolean checkIntersects (Iterator iter, Rectangle rect, - Rectangle ignore) - { - while (iter.hasNext()) { - Rectangle trect = (Rectangle)iter.next(); - if (ignore != null && trect.equals(ignore)) { - continue; - } - if (trect.intersects(rect)) { - return true; - } - } - return false; - } - - /** Helper function for {@link #canAddBody}. */ - protected boolean checkPortals (Rectangle rect) - { - for (Iterator iter = _plocs.iterator(); iter.hasNext(); ) { - Point ppoint = (Point)iter.next(); - if (rect.contains(ppoint)) { - return true; - } - } - return false; - } - - /** Helper function for {@link #canAddBody}. */ - protected boolean checkViolatesPassability (Rectangle rect) - { - // we just check the whole damned thing, but it's not really that - // expensive, so we're not going to worry about it - // Check the bounds + 1 in each direction, so we can see if a fringer - // blocks us. - for (int xx = rect.x-1, ex = rect.x+rect.width+1; xx < ex; xx++) { - for (int yy = rect.y-1, ey = rect.y+rect.height+1; yy < ey; yy++) { - int btid = _mmodel.getBaseTileId(xx, yy); - if ((btid == 0) && - ((xx == rect.x-1) || (xx == rect.x + rect.width) || - (yy == rect.y-1) || (yy == rect.y + rect.height))) { - // it's ok to have an unspecified base tile in the outer - // border - continue; - - } else if (!StageSceneUtil.isPassable( - StageServer.tilemgr, btid)) { -// Log.info("Cluster impassable " + -// "[rect=" + StringUtil.toString(rect) + -// ", spot=" + StringUtil.coordsToString(xx, yy) + -// "]."); - return true; - } - } - } - return false; - } - - // documentation inherited - protected void bodyAdded (ClusterRecord clrec, BodyObject body) - { - super.bodyAdded(clrec, body); - -// Log.info(body.who() + " added to " + clrec + "."); - - // remove them from the loners map if they were in it - int bodyOid = body.getOid(); - _loners.remove(bodyOid); - - Cluster cl = clrec.getCluster(); - if (clrec.size() == 1) { - // if we're adding our first player, assign initial dimensions - // to the cluster - cl.width = 1; cl.height = 1; - SceneLocation loc = locationForBody(bodyOid); - if (loc == null) { - Log.warning("Foreign body added to cluster [clrec=" + clrec + - ", body=" + body.who() + "]."); - cl.x = 10; cl.y = 10; - } else { - StageLocation sloc = (StageLocation) loc.loc; - cl.x = MisoUtil.fullToTile(sloc.x); - cl.y = MisoUtil.fullToTile(sloc.y); - } - // we'll do everything else when occupant two shows up - return; - } - - // generate a list of all valid locations for this cluster - ArrayList locs = StageSceneUtil.getClusterLocs(cl); - -// Log.info("Positioning " + clrec.size() + " bodies in " + -// StringUtil.toString(locs) + " for " + cl + "."); - - // make sure everyone is in their proper position - for (Iterator iter = clrec.keySet().iterator(); iter.hasNext(); ) { - int tbodyOid = ((Integer)iter.next()).intValue(); - // leave the newly added player to last - if (tbodyOid != bodyOid) { - positionBody(cl, tbodyOid, locs); - } - } - - // finally position the new guy - positionBody(cl, bodyOid, locs); - } - - /** Helper function for {@link #bodyAdded}. */ - protected void positionBody (Cluster cl, int bodyOid, ArrayList locs) - { - SceneLocation sloc = (SceneLocation) - _ssobj.occupantLocs.get(Integer.valueOf(bodyOid)); - if (sloc == null) { - BodyObject user = (BodyObject)StageServer.omgr.getObject(bodyOid); - String who = (user == null) ? ("" + bodyOid) : user.who(); - Log.warning("Can't position locationless user " + - "[where=" + where() + ", cluster=" + cl + - ", boid=" + who + "]."); - return; - } - - SceneLocation cloc = getClosestLoc(locs, sloc); -// Log.info("Maybe moving " + bodyOid + " from " + sloc + -// " to " + cloc + -// " (avail=" + StringUtil.toString(locs) + ")."); - if (cloc != null && !cloc.loc.equivalent(sloc.loc)) { - cloc.bodyOid = bodyOid; -// Log.info("Moving " + bodyOid + " to " + cloc + -// " for " + cl + "."); - _ssobj.updateOccupantLocs(cloc); - } - } - - // documentation inherited - protected void bodyRemoved (ClusterRecord clrec, BodyObject body) - { - super.bodyRemoved(clrec, body); - - // if we've been reduced to a zero person cluster, we can skip all - // this because the cluster will be destroyed when we return - if (clrec.size() < 1) { - return; - } - - // reduce the bounds of the cluster if necessary - int target = TARGET_SIZE[clrec.size()]; - Cluster cl = clrec.getCluster(); - // allow a cluster to remain one size larger than it needs to be - // as long as there's more than one person in it - if (cl.width <= (target + ((clrec.size() > 1) ? 1 : 0))) { - return; - } - - // otherwise shrink the cluster - cl.width = target; - cl.height = target; - - // generate a list of all valid locations for this cluster - ArrayList locs = StageSceneUtil.getClusterLocs(cl); - - // make sure everyone is in their proper position - for (Iterator iter = clrec.keySet().iterator(); iter.hasNext(); ) { - int bodyOid = ((Integer)iter.next()).intValue(); - // leave the newly added player to last - if (bodyOid != body.getOid()) { - positionBody(cl, bodyOid, locs); - } - } - } - - // documentation inherited - protected void checkCanCluster (BodyObject initiator, BodyObject target) - throws InvocationException - { - StageOccupantInfo info = (StageOccupantInfo)_ssobj.occupantInfo.get( - Integer.valueOf(target.getOid())); - if (info == null) { - Log.warning("Have no occinfo for cluster target " + - "[where=" + where() + ", init=" + initiator.who() + - ", target=" + target.who() + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - if (!info.isClusterable()) { - throw new InvocationException(StageCodes.ERR_CANNOT_CLUSTER); - } - } - - /** - * Locates and removes the location in the list closest to the - * supplied location. - */ - protected static SceneLocation getClosestLoc ( - ArrayList locs, SceneLocation optimalLocation) - { - StageLocation loc = (StageLocation) optimalLocation.loc; - SceneLocation cloc = null; - float cdist = Integer.MAX_VALUE; - int cidx = -1; - for (int ii = 0, ll = locs.size(); ii < ll; ii++) { - SceneLocation tloc = (SceneLocation)locs.get(ii); - StageLocation sl = (StageLocation) tloc.loc; - float tdist = MathUtil.distance(loc.x, loc.y, sl.x, sl.y); - if (tdist < cdist) { - cloc = tloc; - cdist = tdist; - cidx = ii; - } - } - if (cidx != -1) { - locs.remove(cidx); - } - return cloc; - } - - /** A casted reference to our scene object. */ - protected StageSceneObject _ssobj; - - /** A casted reference to our scene data. */ - protected StageScene _sscene; - - /** Our miso scene data extracted for convenience and efficiency. */ - protected StageMisoSceneModel _mmodel; - - /** Rectangles describing the footprints (in tile coordinates) of all - * of our scene objects. */ - protected ArrayList _footprints = new ArrayList(); - - /** Rectangles containing a "footprint" for the users that aren't in - * any clusters. */ - protected HashIntMap _loners = new HashIntMap(); - - /** Contains the (tile) coordinates of all of our portals. */ - protected HashSet _plocs = new HashSet(); - - /** The dimensions of a cluster with the specified number of - * occupants. */ - protected static final int[] TARGET_SIZE = { - 1, 2, // one person cluster - 3, 3, 3, // two to four person cluster - 4, 4, 4, 4, // five to eight person cluster - 5, 5, 5, 5, // nine to twelve person cluster - 6, 6, 6, 6, // thirteen to sixteen person cluster - 7, 7, 7, 7, 7, 7, 7, 7, // seventeen to twenty four person cluster - 8 // needed though we'll never expand to this size - }; - - /** Used by {@link #canAddBody}. */ - protected static final int[] X_OFF = { 0, -1, 0, -1 }; - - /** Used by {@link #canAddBody}. */ - protected static final int[] Y_OFF = { 0, 0, -1, -1 }; - - /** Used by {@link #computeEnteringLocation}. */ - protected static final int[] PORTAL_DX = { 0, -1, 0, 1 }; // W N E S - - /** Used by {@link #computeEnteringLocation}. */ - protected static final int[] PORTAL_DY = { 1, 0, -1, 0 }; // W N E S -} diff --git a/src/java/com/threerings/stage/server/StageSceneProvider.java b/src/java/com/threerings/stage/server/StageSceneProvider.java deleted file mode 100644 index 4e4cc6b12..000000000 --- a/src/java/com/threerings/stage/server/StageSceneProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// $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.stage.server; - -import com.threerings.miso.data.ObjectInfo; -import com.threerings.presents.client.Client; -import com.threerings.presents.client.InvocationService; -import com.threerings.presents.data.ClientObject; -import com.threerings.presents.server.InvocationException; -import com.threerings.presents.server.InvocationProvider; -import com.threerings.stage.client.StageSceneService; - -/** - * Defines the server-side of the {@link StageSceneService}. - */ -public interface StageSceneProvider extends InvocationProvider -{ - /** - * Handles a {@link StageSceneService#addObject} request. - */ - public void addObject (ClientObject caller, ObjectInfo arg1, InvocationService.ConfirmListener arg2) - throws InvocationException; - - /** - * Handles a {@link StageSceneService#removeObjects} request. - */ - public void removeObjects (ClientObject caller, ObjectInfo[] arg1, InvocationService.ConfirmListener arg2) - throws InvocationException; -} diff --git a/src/java/com/threerings/stage/server/StageServer.java b/src/java/com/threerings/stage/server/StageServer.java deleted file mode 100644 index f7596d0b4..000000000 --- a/src/java/com/threerings/stage/server/StageServer.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $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.stage.server; - -import com.threerings.resource.ResourceManager; - -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.bundle.BundledTileSetRepository; - -import com.threerings.whirled.server.WhirledServer; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageCodes; - -/** - * Extends the Whirled server to provide services needed by the Stage - * system. - */ -public abstract class StageServer extends WhirledServer -{ - /** A resource manager with which we can load resources in the same - * manner that the client does (for resources that are used on both - * the server and client). */ - public ResourceManager rsrcmgr; - - /** Provides access to our tile repository. */ - public static TileManager tilemgr; - - // documentation inherited - public void init () - throws Exception - { - // do the base server initialization - super.init(); - - // create the resource manager - rsrcmgr = new ResourceManager("rsrc"); - rsrcmgr.initBundles(null, "config/resource/manager.properties", null); - - // create our tile manager and repository - tilemgr = new TileManager(null); - tilemgr.setTileSetRepository( - new BundledTileSetRepository(rsrcmgr, null, - StageCodes.TILESET_RSRC_SET)); - - Log.info("Stage server initialized."); - } -} diff --git a/src/java/com/threerings/stage/tools/editor/DirectionButton.java b/src/java/com/threerings/stage/tools/editor/DirectionButton.java deleted file mode 100644 index 42ffd7dd6..000000000 --- a/src/java/com/threerings/stage/tools/editor/DirectionButton.java +++ /dev/null @@ -1,192 +0,0 @@ -// -// $Id: DirectionButton.java 5784 2003-01-08 04:17:40Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import javax.swing.AbstractButton; -import javax.swing.DefaultButtonModel; - -import com.threerings.media.image.ColorUtil; - -import com.threerings.util.DirectionCodes; - -/** - * A button that allows for selection from the compass directions. - */ -public class DirectionButton extends AbstractButton -{ - /** - * Construct a 41x41 DirectionButton. - */ - public DirectionButton () - { - this(41); - } - - /** - * Construct a DirectionButton with the specified preferred diameter. - */ - public DirectionButton (int preferredDiameter) - { - _prefdia = preferredDiameter; - configSize(_prefdia); - - setModel(new DefaultButtonModel()); - - addMouseListener(new MouseAdapter() { - public void mousePressed (MouseEvent event) - { - if (isEnabled()) { - _armed = getDirection(event.getX(), event.getY()); - repaint(); - } - } - - public void mouseReleased (MouseEvent event) - { - if ((_armed != -1) && - isEnabled() && - (_armed == getDirection(event.getX(), event.getY())) && - (_direction != _armed)) { - - _direction = _armed; - fireStateChanged(); - } - _armed = -1; - repaint(); - } - - - }); - } - - /** - * Paint this component and the selected direction, - * dimmed if we're inactive. - */ - public void paintComponent (Graphics g) - { - super.paintComponent(g); - - // draw the selected direction circle - g.setColor(isEnabled() ? Color.red - : ColorUtil.blend(Color.red, getBackground())); - g.fillOval(_coords[_direction][0], _coords[_direction][1], - _cdia, _cdia); - - if (_armed != -1) { - g.setColor(ColorUtil.blend(Color.black, getBackground())); - g.fillOval(_coords[_armed][0], _coords[_armed][1], - _cdia, _cdia); - } - - // draw a circle around the various direction circles - g.setColor(isEnabled() ? Color.black - : ColorUtil.blend(Color.black, getBackground())); - g.drawOval(0, 0, _dia, _dia); - - // draw each direction circle - for (int ii=DirectionCodes.SOUTHWEST; - ii < DirectionCodes.DIRECTION_COUNT; - ii++) { - - g.drawOval(_coords[ii][0], _coords[ii][1], _cdia, _cdia); - } - } - - /** - * Get the direction that is currently selected. - */ - public int getDirection () - { - return _direction; - } - - /** - * Set the currently displayed direction - */ - public void setDirection (int direction) - { - if (direction != _direction) { - _direction = direction; - fireStateChanged(); - repaint(); - } - } - - /** - * Get the direction specified by the mouse coordinates - */ - protected int getDirection (int x, int y) - { - for (int ii=0; ii < DirectionCodes.DIRECTION_COUNT; ii++) { - if ((x > _coords[ii][0]) && (x < (_coords[ii][0] + _cdia)) && - (y > _coords[ii][1]) && (y < (_coords[ii][1] + _cdia))) { - return ii; - } - } - return -1; - } - - // documentation inherited - public void setSize (Dimension d) - { - super.setSize(d); - - configSize(Math.min(d.width, d.height)); - } - - /** - * Reconfigure the way we look for a new size - */ - protected void configSize (int diameter) - { - // recompute our sizes - _dia = diameter - 1; - _cdia = _dia / 4; - - int mid = (_dia - _cdia) / 2; - - int num = DirectionCodes.DIRECTION_COUNT; // oh we all know it's 8. - - for (int ii=0; ii < num; ii++) { - double rads = Math.PI * 2 * ii / num; - - // 0 radians specifies EAST, so we offset - int dir = (ii + DirectionCodes.EAST) % num; - - _coords[dir][0] = mid + ((int) (mid * Math.cos(rads))); - _coords[dir][1] = mid + ((int) (mid * Math.sin(rads))); - } - } - - // documentation inherited - public Dimension getPreferredSize () - { - return new Dimension(_prefdia, _prefdia); - } - - /** The current direction displayed by the button. */ - protected int _direction = DirectionCodes.SOUTH; - - // if we're "armed" for a possible state change, which direction is armed? - // (-1 for unarmed) - protected int _armed = -1; - - /** Diameter of the drawn enclosing circle. */ - protected int _dia; - - /** Diameter of selection circles. */ - protected int _cdia; - - /** Coordinates of each of the selection circles. */ - protected int[][] _coords = new int[DirectionCodes.DIRECTION_COUNT][2]; - - /** Our preferred diameter. */ - protected int _prefdia; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorApp.java b/src/java/com/threerings/stage/tools/editor/EditorApp.java deleted file mode 100644 index 5f4536f3b..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorApp.java +++ /dev/null @@ -1,351 +0,0 @@ -// -// $Id: EditorApp.java 19661 2005-03-09 02:40:29Z andrzej $ - -package com.threerings.stage.tools.editor; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.DisplayMode; -import java.awt.EventQueue; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JProgressBar; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.List; - -import com.samskivert.swing.RuntimeAdjust; -import com.samskivert.swing.util.SwingUtil; -import com.samskivert.util.DebugChords; -import com.samskivert.util.StringUtil; - -import com.threerings.util.KeyDispatcher; -import com.threerings.util.KeyboardManager; -import com.threerings.util.MessageBundle; -import com.threerings.util.MessageManager; - -import com.threerings.resource.ResourceManager; - -import com.threerings.media.FrameManager; -import com.threerings.media.image.ColorPository; -import com.threerings.media.image.ImageManager; -import com.threerings.media.util.ModeUtil; - -import com.threerings.media.tile.TileSetRepository; -import com.threerings.media.tile.bundle.BundledTileSetRepository; - -import com.threerings.cast.ComponentRepository; -import com.threerings.cast.bundle.BundledComponentRepository; -import com.threerings.miso.tile.MisoTileManager; - -import com.threerings.stage.data.StageSceneModel; -import com.threerings.stage.tools.editor.util.EditorContext; - -/** - * A scene editor application that provides facilities for viewing, - * editing, and saving the scene templates that comprise a game. - */ -public class EditorApp implements Runnable -{ - /** - * Construct and initialize the EditorApp object. - */ - public EditorApp (String[] args) - throws IOException - { - final String target = (args.length > 0) ? args[0] : null; - - if (System.getProperty("no_log_redir") != null) { - Log.info("Logging to console only."); - - } else { - String dlog = localDataDir("editor.log"); - try { - PrintStream logOut = new PrintStream( - new BufferedOutputStream(new FileOutputStream(dlog)), true); - System.setOut(logOut); - System.setErr(logOut); - Log.info("Opened debug log '" + dlog + "'."); - - } catch (IOException ioe) { - Log.warning("Failed to open debug log [path=" + dlog + - ", error=" + ioe + "]."); - } - } - - // we need to use heavy-weight popup menus so that they can overly - // our non-lightweight Miso view - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - - // create and size the main application frame - _frame = createEditorFrame(); - - // create our frame manager - _framemgr = FrameManager.newInstance(_frame, _frame); - - // create our myriad managers, repositories, etc. - _rmgr = new ResourceManager("rsrc"); - - // build up a simple ui for displaying progress - JPanel progressPanel = new JPanel(new BorderLayout()); - final JLabel progressLabel = new JLabel(); - final JProgressBar progress = new JProgressBar(0,100); - final JPanel spacer = new JPanel(); - - progressPanel.add(progressLabel, BorderLayout.CENTER); - progressPanel.add(progress, BorderLayout.SOUTH); - progressPanel.setPreferredSize(new Dimension(300,80)); - spacer.add(progressPanel); - - _frame.getContentPane().add(spacer); - - final EditorFrame frameRef = _frame; - - ResourceManager.InitObserver obs = new ResourceManager.InitObserver() { - public void progress (int percent, long remaining) { - String msg = "Unpacking..."; - if (remaining >= 0) { - msg += " " + remaining + " seconds remaining."; - } - progressLabel.setText(msg); - progress.setValue(percent); - - if (percent >= 100) { - frameRef.getContentPane().remove(spacer); - EditorApp.this.finishInit(target); - } - } - - public void initializationFailed (Exception e) { - Log.warning("Failed unpacking bundles [e=" + e + "]."); - Log.logStackTrace(e); - } - }; - // we want our methods called on the AWT thread - obs = new ResourceManager.AWTInitObserver(obs); - _rmgr.initBundles(null, "config/resource/editor.properties", obs); - } - - public void finishInit (String target) - { - _msgmgr = new MessageManager("rsrc.i18n"); - _imgr = new ImageManager(_rmgr, _frame); - _tilemgr = new MisoTileManager(_rmgr, _imgr); - - try { - _tsrepo = new BundledTileSetRepository(_rmgr, _imgr, "tilesets"); - _tilemgr.setTileSetRepository(_tsrepo); - _crepo = new BundledComponentRepository( - _rmgr, _imgr, "components"); - } catch (IOException e) { - Log.warning("Exception loading tilesets and and icon manager " + - "[Exception=" + e + "]."); - return; - } - - _colpos = ColorPository.loadColorPository(_rmgr); - _kbdmgr = new KeyboardManager(); - _keydisp = new KeyDispatcher(_frame); - - _ctx = new EditorContextImpl(); - - // initialize the frame with the now-prepared context - _frame.init(_ctx, target); - - // wire up our runtime adjustment editor - DebugChords.activate(); - - // if we have a target file, load it up - if (target != null) { - _frame.openScene(target); - } - } - - /** - * Given a subdirectory name (that should correspond to the calling - * service), returns a file path that can be used to store local data. - */ - public static String localDataDir (String subdir) - { - String appdir = System.getProperty("appdir"); - if (StringUtil.isBlank(appdir)) { - appdir = ".narya-editor"; - String home = System.getProperty("user.home"); - if (!StringUtil.isBlank(home)) { - appdir = home + File.separator + appdir; - } - } - return appdir + File.separator + subdir; - } - - /** - * Run the application. - */ - public void run () - { - // enter full-screen exclusive mode if available and if we have - // the right display mode - GraphicsEnvironment env = - GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice gd = env.getDefaultScreenDevice(); - DisplayMode pmode = null; - try { - DisplayMode cmode = gd.getDisplayMode(); - pmode = ModeUtil.getDisplayMode( - gd, cmode.getWidth(), cmode.getHeight(), 16, 15); - } catch (Throwable t) { - // Win98 seems to choke on it's own vomit when we attempt to - // enumerate the available display modes; yay! - Log.warning("Failed to probe display mode."); - Log.logStackTrace(t); - } - - if (_viewFullScreen.getValue() && gd.isFullScreenSupported() && - pmode != null) { - Log.info("Switching to screen mode " + - "[mode=" + ModeUtil.toString(pmode) + "]."); - // set the frame to undecorated, full-screen - _frame.setUndecorated(true); - gd.setFullScreenWindow(_frame); - // switch to our happy custom display mode - gd.setDisplayMode(pmode); - // lay the frame out properly (we can't do this before making - // it full screen because packing causes the window to become - // displayable which apparently prevents the window from - // subsequently being made a full-screen window) - _frame.pack(); - - } else { - _frame.setSize(1024, 768); - SwingUtil.centerWindow(_frame); - _frame.setVisible(true); - } - _framemgr.start(); - } - - protected EditorFrame createEditorFrame () - { - return new EditorFrame(); - } - - /** - * Derived classes can override this method and add additional scene - * types. - */ - protected void enumerateSceneTypes (List types) - { - types.add(StageSceneModel.WORLD); - } - - /** - * Instantiate the application object and start it running. - */ - public static void main (String[] args) - { - try { - EditorApp app = new EditorApp(args); - // start up the UI on the AWT thread to avoid deadlocks - EventQueue.invokeLater(app); - - } catch (IOException ioe) { - Log.warning("Unable to initialize editor."); - Log.logStackTrace(ioe); - } - } - - /** - * The implementation of the EditorContext interface that provides - * handles to the config and manager objects that offer commonly - * used services. - */ - protected class EditorContextImpl implements EditorContext - { - public MisoTileManager getTileManager () { - return _tilemgr; - } - - public FrameManager getFrameManager () { - return _framemgr; - } - - public ResourceManager getResourceManager () { - return _rmgr; - } - - public ImageManager getImageManager () { - return _imgr; - } - - public MessageManager getMessageManager () { - return _msgmgr; - } - - public KeyboardManager getKeyboardManager() { - return _kbdmgr; - } - - public ComponentRepository getComponentRepository () { - return _crepo; - } - - public KeyDispatcher getKeyDispatcher () { - return _keydisp; - } - - public String xlate (String message) { - return xlate("stage.editor", message); - } - - public String xlate (String bundle, String message) { - MessageBundle mbundle = _msgmgr.getBundle(bundle); - if (mbundle == null) { - Log.warning("Requested to translate message with " + - "non-existent bundle [bundle=" + bundle + - ", message=" + message + "]."); - return message; - } else { - return mbundle.xlate(message); - } - } - - public TileSetRepository getTileSetRepository () { - return _tsrepo; - } - - public ColorPository getColorPository () { - return _colpos; - } - - public void enumerateSceneTypes (List types) { - EditorApp.this.enumerateSceneTypes(types); - } - } - - protected EditorContext _ctx; - protected EditorFrame _frame; - protected FrameManager _framemgr; - - protected ResourceManager _rmgr; - protected ImageManager _imgr; - protected MisoTileManager _tilemgr; - protected TileSetRepository _tsrepo; - protected ColorPository _colpos; - protected MessageManager _msgmgr; - protected KeyboardManager _kbdmgr; - protected BundledComponentRepository _crepo; - protected KeyDispatcher _keydisp; - - /** A debug hook that toggles debug rendering of traversable tiles. */ - protected static RuntimeAdjust.BooleanAdjust _viewFullScreen = - new RuntimeAdjust.BooleanAdjust( - "Toggles whether or not the scene editor uses full screen mode.", - "stage.editor.full_screen", EditorConfig.config, false); -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorConfig.java b/src/java/com/threerings/stage/tools/editor/EditorConfig.java deleted file mode 100644 index 44e06dbf0..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorConfig.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// $Id: EditorConfig.java 1352 2002-03-28 23:55:21Z ray $ - -package com.threerings.stage.tools.editor; - -import com.samskivert.util.Config; - -/** - * Provides access to configuration data for the editor. - */ -public class EditorConfig -{ - /** Provides access to config data for this package. */ - public static Config config = new Config("rsrc/config/stage/tools/editor"); - - /** - * Accessor method for getting the test tile directory. - */ - public static String getTestTileDirectory () - { - return config.getValue(TESTTILE_KEY, TESTTILE_DEF); - } - - /** - * Accessor method for setting the test tile directory. - */ - public static void setTestTileDirectory (String newvalue) - { - config.setValue(TESTTILE_KEY, newvalue); - } - - private static final String TESTTILE_KEY = "testtiledir"; - private static final String TESTTILE_DEF = "."; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorFrame.java b/src/java/com/threerings/stage/tools/editor/EditorFrame.java deleted file mode 100644 index a6a588145..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorFrame.java +++ /dev/null @@ -1,563 +0,0 @@ -// -// $Id: EditorFrame.java 19411 2005-02-19 00:28:49Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.BorderLayout; -import java.awt.EventQueue; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -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 javax.swing.JComponent; -import javax.swing.JFileChooser; -import javax.swing.JInternalFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollBar; -import javax.swing.KeyStroke; -import javax.swing.filechooser.FileFilter; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.util.MenuUtil; -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.media.ManagedJFrame; - -import com.threerings.miso.tile.BaseTileSet; -import com.threerings.miso.util.MisoSceneMetrics; - -import com.threerings.stage.data.StageScene; -import com.threerings.stage.data.StageSceneModel; - -import com.threerings.stage.tools.editor.util.EditorContext; -import com.threerings.stage.tools.editor.util.EditorDialogUtil; -import com.threerings.stage.tools.xml.StageSceneParser; -import com.threerings.stage.tools.xml.StageSceneWriter; - -public class EditorFrame extends ManagedJFrame -{ - public EditorFrame () - { - // treat a closing window as a request to quit - addWindowListener(new WindowAdapter () { - public void windowClosing (WindowEvent e) { - handleQuit(null); - } - }); - - // set our initial window title - setFilePath(null); - } - - public void init (EditorContext ctx, String target) - { - _ctx = ctx; - - // create the editor data model for reference by the panels - _model = new EditorModel(_ctx.getTileManager()); - - // create the file chooser used for saving and loading scenes - if (target == null) { - target = EditorConfig.config.getValue( - "editor.last_dir", System.getProperty("user.dir")); - } - _chooser = (target == null) ? - new JFileChooser() : new JFileChooser(target); - _chooser.setFileFilter(new FileFilter () { - public boolean accept (File f) { - return (f.isDirectory() || f.getName().endsWith(".xml")); - } - public String getDescription () { - return "XML Files"; - } - }); - - // instead of using a popup, we slip the file chooser into the - // main interface (so the editor can run full-screen); thus we - // can't use the standard business and have to add an action - // listen to our file chooser - _chooser.addActionListener(_openListener); - - // set up the menu bar - createMenuBar(); - - // create a top-level panel to manage everything - JPanel top = new JPanel(new BorderLayout()); - - // create a sub-panel to contain the toolbar and scene view - _main = new JPanel(new BorderLayout()); - - // set up the scene view panel with a default scene - _svpanel = new EditorScenePanel(_ctx, this, _model); - _main.add(_svpanel, BorderLayout.CENTER); - - // create a toolbar for action selection and other options - JPanel upper = new JPanel( - new HGroupLayout(GroupLayout.NONE, GroupLayout.LEFT)); - upper.add(new EditorToolBarPanel(_ctx.getTileManager(), _model), - GroupLayout.FIXED); - _sceneInfoPanel = new SceneInfoPanel(_ctx, _model, _svpanel); - upper.add(_sceneInfoPanel, GroupLayout.FIXED); - _main.add(upper, BorderLayout.NORTH); - - // create a couple of scroll bars - JScrollBar horiz = new JScrollBar(JScrollBar.HORIZONTAL); - horiz.setBlockIncrement(500); - horiz.setModel(_svpanel.getHorizModel()); - _main.add(horiz, BorderLayout.SOUTH); - JScrollBar vert = new JScrollBar(JScrollBar.VERTICAL); - vert.setBlockIncrement(500); - vert.setModel(_svpanel.getVertModel()); - _main.add(vert, BorderLayout.EAST); - - // add the scene view and toolbar to the top-level panel - top.add(_main, BorderLayout.CENTER); - - // set up our left sidebar panel - JPanel west = GroupLayout.makeVStretchBox(5); - _tpanel = new TileInfoPanel(_ctx, _model); - west.add(_tpanel); - - JPanel boxPane = GroupLayout.makeHBox(); - boxPane.add(_scrollBox = new EditorScrollBox(_svpanel)); - west.add(boxPane, GroupLayout.FIXED); - - // add the sub-panel to the top panel - top.add(west, BorderLayout.WEST); - - // now add our top-level panel - getContentPane().add(top, BorderLayout.CENTER); - - // observe mouse-wheel events in the scene view panel to allow - // scrolling the wheel to select the tile to be placed - _svpanel.addMouseWheelListener(new MouseWheelListener() { - public void mouseWheelMoved (MouseWheelEvent e) { - if (e.getWheelRotation() < 0) { - _tpanel.selectPreviousTile(); - } else { - _tpanel.selectNextTile(); - } - } - }); - - // finally set a default scene - newScene(); - } - - /** - * Create the menu bar and menu items and add them to the frame. - */ - public void createMenuBar () - { - // create the "File" menu - JMenu menuFile = new JMenu("File"); - createFileMenu(menuFile); - - // create the "Edit" menu -// JMenu menuEdit = new JMenu("Edit"); -// MenuUtil.addMenuItem(menuEdit, "Undo", this, "handleUndo"); -// MenuUtil.addMenuItem(menuEdit, "Cut", this, "handleCut"); -// MenuUtil.addMenuItem(menuEdit, "Copy", this, "handleCopy"); -// MenuUtil.addMenuItem(menuEdit, "Paste", this, "handlePaste"); -// MenuUtil.addMenuItem(menuEdit, "Clear", this, "handleClear"); -// MenuUtil.addMenuItem(menuEdit, "Select All", this, "handleSelectAll"); -// menuEdit.setMnemonic(KeyEvent.VK_E); - - // create the "Actions" menu - JMenu menuActions = new JMenu("Actions"); - createActionsMenu(menuActions); - - // create the "Settings" menu - KeyStroke accel = null; - JMenu menuSettings = new JMenu("Settings"); - menuSettings.setMnemonic(KeyEvent.VK_S); - accel = KeyStroke.getKeyStroke( - KeyEvent.VK_SEMICOLON, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuSettings, "Preferences...", KeyEvent.VK_P, - accel, this, "handlePreferences"); - - // create the menu bar - JMenuBar bar = new JMenuBar(); - bar.add(menuFile); - // bar.add(menuEdit); - bar.add(menuActions); - bar.add(menuSettings); - - // add the menu bar to the frame - setJMenuBar(bar); - } - - protected void createFileMenu (JMenu menuFile) - { - KeyStroke accel = null; - menuFile.setMnemonic(KeyEvent.VK_F); - accel = KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuFile, "New", KeyEvent.VK_N, accel, - this, "handleNew"); - accel = KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuFile, "Open", KeyEvent.VK_O, accel, - this, "handleOpen"); - //addMenuItem(menuFile, "Close", KeyEvent.VK_C); - accel = KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuFile, "Save", KeyEvent.VK_S, accel, - this, "handleSave"); - MenuUtil.addMenuItem(menuFile, "Save As", KeyEvent.VK_A, null, - this, "handleSaveAs"); - accel = KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuFile, "Quit", KeyEvent.VK_Q, accel, - this, "handleQuit"); - } - - protected void createActionsMenu (JMenu menuActions) - { - KeyStroke accel = null; - MenuUtil.addMenuItem(menuActions, "Load (reload) test tiles", this, - "handleTestTiles"); - menuActions.setMnemonic(KeyEvent.VK_A); - - accel = KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuActions, "Make default base tile", - KeyEvent.VK_M, accel, this, "handleSetDefBase"); - - accel = KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuActions, "Update mini view", - KeyEvent.VK_M, accel, this, "updateMiniView"); - } - - protected void setScene (StageScene scene) - { - // save off the scene objects - _scene = scene; - - // display the name of the scene - _sceneInfoPanel.setScene(_scene); - - // set up the scene view panel with the new scene - _svpanel.setScene(_scene); - _svpanel.repaint(); - } - - protected void newScene () - { - try { - MisoSceneMetrics metrics = _svpanel.getSceneMetrics(); - StageSceneModel model = StageSceneModel.blankStageSceneModel(); - model.type = StageSceneModel.WORLD; - setScene(new StageScene(model, null)); - - } catch (Exception e) { - Log.warning("Unable to set blank scene."); - Log.logStackTrace(e); - } - } - - /** - * Creates a blank scene and configures the editor to begin editing - * it. Eventually this should make sure the user has a chance to save - * any scene for which editing is currently in progress. - */ - public void handleNew (ActionEvent evt) - { - // clear out the fiel path so that "Save" pops up "Save as" rather - // than overwriting whatever you were editing before - setFilePath(null); - - newScene(); - } - - /** - * Presents the user with an open file dialog and loads the scenes - * from the selected file. - */ - public void handleOpen (ActionEvent evt) - { - _chooser.setDialogType(JFileChooser.OPEN_DIALOG); - _main.remove(_svpanel); - _main.add(_chooser, BorderLayout.CENTER); - SwingUtil.refresh(_main); - } - - /** - * Loads the scene from the specified path. - */ - public void openScene (String path) - { - String errmsg = null; - - // attempt loading and installation of the scene - try { - StageSceneModel model = (StageSceneModel)_parser.parseScene(path); - if (model == null) { - errmsg = "No scene data found"; - } else { - setScene(new StageScene(model, null)); - // keep track of the path for later saving - setFilePath(path); - } - - } catch (Exception e) { - errmsg = "Parse error: " + e; - Log.logStackTrace(e); - } - - if (errmsg != null) { - errmsg = "Unable to load scene from " + path + ":\n" + errmsg; - JOptionPane.showMessageDialog( - this, errmsg, "Load error", JOptionPane.ERROR_MESSAGE); - } - } - - /** - * Save the scenes to the file they were last associated with. - */ - public void handleSave (ActionEvent evt) - { - if (_filepath == null) { - handleSaveAs(evt); - return; - } - - if (!checkSaveOk()) { - return; - } - - try { - // we don't write directly to the file in question, in case - // something craps out during the writing process - File tmpfile = new File(_filepath + ".tmp"); - _writer.writeScene(tmpfile, _scene.getSceneModel()); - - // now that we've successfully written the new file, delete - // the old file - File sfile = new File(_filepath); - if (!sfile.delete()) { - Log.warning("Aiya! Not able to remove " + _filepath + - " so that we can replace it with " + - tmpfile.getPath() + "."); - } - - // now rename the new save file into place - if (!tmpfile.renameTo(sfile)) { - Log.warning("Fork! Not able to rename " + tmpfile.getPath() + - " to " + _filepath + "."); - } - - } catch (Exception e) { - String errmsg = "Unable to save scene to " + _filepath + ":\n" + e; - JOptionPane.showMessageDialog( - this, errmsg, "Save error", JOptionPane.ERROR_MESSAGE); - Log.warning("Error writing scene " + - "[fname=" + _filepath + ", e=" + e + "]."); - Log.logStackTrace(e); - } - } - - /** - * Check to see if the save can proceed, and pop up errors if it - * can't. - */ - protected boolean checkSaveOk () - { - String name = _scene.getName(); - String type = _scene.getType(); - - String err = ""; - if (name.equals("") || name.indexOf("<") != -1 || - name.indexOf(">") != -1) { - err += "Invalid scene name.\n"; - } - - if (type.equals("")) { - err += "No scene type specified.\n"; - } - - if (_svpanel.getEntrance() == null) { - err += "No default entrance portal.\n"; - } - - if ("".equals(err)) { - return true; - } else { - JOptionPane.showMessageDialog( - this, err + "\nPlease fix and try again.", - "Won't save: scene is broken!", - JOptionPane.ERROR_MESSAGE); - return false; - } - } - - /** - * Present the user with a save file dialog and save the scenes to - * the selected file. - */ - public void handleSaveAs (ActionEvent evt) - { - _chooser.setDialogType(JFileChooser.SAVE_DIALOG); - _main.remove(_svpanel); - _main.add(_chooser, BorderLayout.CENTER); - SwingUtil.refresh(_main); - } - - /** - * Keeps our file path around and conveys that information in the - * window title. - */ - protected void setFilePath (String filepath) - { - _filepath = filepath; - setTitle("Narya Scene Editor: " + - (_filepath == null ? "" : _filepath)); - } - - /** - * Handles a request to quit. Presently this just quits, but - * eventually it should give the user the chance to save any edits in - * progress. - */ - public void handleQuit (ActionEvent evt) - { - System.exit(0); - } - - /** - * Handles a request to reload the test tiles. - */ - public void handleTestTiles (ActionEvent evt) - { - // don't instantiate a testLoader until we actually need one - if (_testLoader == null) { - _testLoader = new TestTileLoader(); - } - - _tpanel.insertTestTiles(_testLoader.loadTestTiles()); - } - - /** - * Update the mini view in the scrollbox. - */ - public void updateMiniView (ActionEvent evt) - { - _scrollBox.updateView(); - } - - /** - * Handles a request to open the preferences dialog. - */ - public void handlePreferences (ActionEvent evt) - { - PreferencesDialog pd = new PreferencesDialog(); - EditorDialogUtil.display(this, pd); - } - - /** - * Make the currently selected base tile into the scene's default - * tile. - */ - public void handleSetDefBase (ActionEvent evt) - { - if (_model.getTileSet() instanceof BaseTileSet) { - _svpanel.updateDefaultTileSet(_model.getTileSetId()); - } else { - Log.warning("Not making non-base tileset into default " + - _model.getTileSet() + "."); - } - } - - /** Handles JFileChooser responses when opening files. */ - protected ActionListener _openListener = new ActionListener() { - public void actionPerformed (ActionEvent event) { - String cmd = event.getActionCommand(); - - // restore the scene view - _main.remove(_chooser); - _main.add(_svpanel); - SwingUtil.refresh(_main); - - // load up the scene if they selected one - if (cmd.equals(JFileChooser.APPROVE_SELECTION)) { - File filescene = _chooser.getSelectedFile(); - switch (_chooser.getDialogType()) { - case JFileChooser.OPEN_DIALOG: - openScene(filescene.getPath()); - EditorConfig.config.setValue( - "editor.last_dir", filescene.getParent()); - break; - - case JFileChooser.SAVE_DIALOG: - setFilePath(filescene.getPath()); - handleSave(null); - break; - - default: - Log.warning("Wha? Weird dialog type " + - _chooser.getDialogType() + "."); - break; - } - } - - // oh god the hackery; on linux at least, the focus seems - // to be hosed after we hide the chooser and we can't just - // request to move it somewhere useful because it just - // ignores us; so instead we have to wait for the current - // event queue to flush before we can transfer focus - EventQueue.invokeLater(new Runnable() { - public void run () { - _sceneInfoPanel.requestFocusInWindow(); - } - }); - } - }; - - /** The scene currently undergoing edit. */ - protected StageScene _scene; - - /** The file last associated with the current scene. */ - protected String _filepath; - - /** Contains the scene view panel or other fun stuff. */ - protected JPanel _main; - - /** Used for displaying dialogs. */ - protected JInternalFrame _dialog; - - /** The file chooser used for loading and saving scenes. */ - protected JFileChooser _chooser; - - /** The panel that displays the scene view. */ - protected EditorScenePanel _svpanel; - - /** The panel that displays tile info. */ - protected TileInfoPanel _tpanel; - - /** The panel that displays scene info. */ - protected SceneInfoPanel _sceneInfoPanel; - - /** The scrollbox used to display the view position within the scene. */ - protected EditorScrollBox _scrollBox; - - /** The editor data model. */ - protected EditorModel _model; - - /** The editor context. */ - protected EditorContext _ctx; - - /** We use this to load scenes. */ - protected StageSceneParser _parser = new StageSceneParser(); - - /** We use this to save scenes. */ - protected StageSceneWriter _writer = new StageSceneWriter(); - - /** The test tileset loader. */ - protected TestTileLoader _testLoader; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorModel.java b/src/java/com/threerings/stage/tools/editor/EditorModel.java deleted file mode 100644 index 8936e7c57..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorModel.java +++ /dev/null @@ -1,262 +0,0 @@ -// -// $Id: EditorModel.java 17780 2004-11-10 23:00:07Z ray $ - -package com.threerings.stage.tools.editor; - -import java.util.ArrayList; - -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.util.DirectionCodes; - -/** - * The EditorModel class provides a holding place for storing, - * modifying and retrieving data that is shared across the Editor - * application and its myriad UI components. - */ -public class EditorModel -{ - /** Action mode constants. */ - public static final int ACTION_PLACE_TILE = 0; - public static final int ACTION_EDIT_TILE = 1; - public static final int ACTION_PLACE_PORTAL = 2; - - /** The number of actions. */ - public static final int NUM_ACTIONS = 3; - - /** Miso layer constants. */ - public static final int BASE_LAYER = 0; - public static final int OBJECT_LAYER = 1; - public static final String[] LAYER_NAMES = { "Base", "Object" }; - - /** Prose descriptions of actions suitable for tool tip display. */ - public static final String[] TIP_ACTIONS = { - "Place/Delete tiles.", "Edit object tiles.", - "Create/Edit/Delete portal." - }; - - /** String translations for action identifiers. */ - public static final String[] CMD_ACTIONS = { - "place_tile", "edit_tile", "place_portal" - }; - - public EditorModel (TileManager tilemgr) - { - _tilemgr = tilemgr; - _tileSetId = _tileIndex = -1; - _lnum = _mode = 0; - } - - /** - * Add an editor model listener. - * - * @param l the listener. - */ - public void addListener (EditorModelListener l) - { - if (!_listeners.contains(l)) { - _listeners.add(l); - } - } - - /** - * Notify all model listeners that the editor model has changed. - */ - protected void notifyListeners (int event) - { - int size = _listeners.size(); - for (int ii = 0; ii < size; ii++) { - ((EditorModelListener)_listeners.get(ii)).modelChanged(event); - } - } - - /** - * Returns whether the currently selected tile is valid. - */ - public boolean isTileValid () - { - return (_tile != null); - } - - /** - * Returns the current editor action mode. - */ - public int getActionMode () - { - return _mode; - } - - /** - * Returns the current scene layer index undergoing edit. - */ - public int getLayerIndex () - { - return _lnum; - } - - /** - * Returns the currently selected tile set. - */ - public TileSet getTileSet () - { - return _tileSet; - } - - /** - * Returns the currently selected tile set id. - */ - public int getTileSetId () - { - return _tileSetId; - } - - /** - * Returns the currently selected tile id within the selected tile - * set. - */ - public int getTileId () - { - return _tileIndex; - } - - /** - * Returns the currently selected tile for placement within the - * scene. - */ - public Tile getTile () - { - return _tile; - } - - /** - * Returns the fully qualified tile id of the currently selected tile. - */ - public int getFQTileId () - { - return _fqTileId; - } - - /** - * Marks the currently selected tile as invalid such that editing - * when no tiles are available can be properly effected. - */ - public void clearTile () - { - _tileSet = null; - _tileSetId = -1; - _tileIndex = -1; - _tile = null; - } - - /** - * Sets the editor action mode. The specified mode should be one - * of CMD_ACTIONS. - */ - public void setActionMode (String cmd) - { - for (int ii = 0; ii < CMD_ACTIONS.length; ii++) { - if (CMD_ACTIONS[ii].equals(cmd)) { - _mode = ii; - notifyListeners(EditorModelListener.ACTION_MODE_CHANGED); - return; - } - } - - Log.warning("Attempt to set to unknown mode [cmd=" + cmd + "]."); - } - - /** - * Sets the scene layer index undergoing edit. - */ - public void setLayerIndex (int lnum) - { - if (lnum != _lnum) { - _lnum = lnum; - notifyListeners(EditorModelListener.LAYER_INDEX_CHANGED); - } - } - - /** - * Sets the selected tile for placement within the scene. - */ - public void setTile (TileSet set, int tileSetId, int tileIndex) - { - _tile = set.getTile(tileIndex); - _tileSet = set; - _tileSetId = tileSetId; - _tileIndex = tileIndex; - _fqTileId = TileUtil.getFQTileId(tileSetId, tileIndex); - notifyListeners(EditorModelListener.TILE_CHANGED); - } - - /** - * Sets the tile id of the tile selected for placement within the - * scene. - */ - public void setTileId (int tileIndex) - { - setTile(_tileSet, _tileSetId, tileIndex); - } - - /** - * Sets the direction in which we should grip objects. - */ - public void setObjectGripDirection (int direction) - { - _objectGrip = direction; - } - - /** - * Gets the direction in which we should grip objects. - */ - public int getObjectGripDirection () - { - return _objectGrip; - } - - /** - * Returns a string representation of the editor model. - */ - public String toString () - { - StringBuilder buf = new StringBuilder(); - buf.append("[set=").append(_tileSet); - buf.append(", tid=").append(_tileIndex); - buf.append(", lnum=").append(_lnum); - buf.append(", tile=").append(_tile); - return buf.append("]").toString(); - } - - /** The currently selected action mode. */ - protected int _mode; - - /** The currently selected tileset. */ - protected TileSet _tileSet; - - /** The currently selected tileset id. */ - protected int _tileSetId; - - /** The currently selected tile id. */ - protected int _tileIndex; - - /** The fully qualified tile id of the currently selected tile. */ - protected int _fqTileId; - - /** The currently selected layer number. */ - protected int _lnum; - - /** The currently selected tile for placement in the scene. */ - protected Tile _tile; - - /** The model listeners. */ - protected ArrayList _listeners = new ArrayList(); - - /** The tile manager. */ - protected TileManager _tilemgr; - - /** Direction (which corner) we grip an object by. */ - protected int _objectGrip = DirectionCodes.SOUTH; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorModelListener.java b/src/java/com/threerings/stage/tools/editor/EditorModelListener.java deleted file mode 100644 index 3fc7cd347..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorModelListener.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// $Id: EditorModelListener.java 217 2001-11-29 00:29:31Z mdb $ - -package com.threerings.stage.tools.editor; - -/** - * The editor model listener interface should be implemented by - * classes that would like to be notified when the editor model is - * changed. - * - * @see EditorModel - */ -public interface EditorModelListener -{ - /** - * Called by the {@link EditorModel} when the model is changed. - */ - public void modelChanged (int event); - - /** Notification event constants. */ - public static final int ACTION_MODE_CHANGED = 0; - public static final int LAYER_INDEX_CHANGED = 1; - public static final int TILE_CHANGED = 2; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java b/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java deleted file mode 100644 index 72dada342..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java +++ /dev/null @@ -1,1145 +0,0 @@ -// -// $Id: EditorScenePanel.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -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 java.awt.Shape; -import java.awt.Stroke; - -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.geom.Ellipse2D; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.swing.BoundedRangeModel; -import javax.swing.DefaultBoundedRangeModel; -import javax.swing.JFrame; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.TGraphics2D; -import com.samskivert.swing.util.SwingUtil; -import com.samskivert.util.RandomUtil; -import com.samskivert.util.StringUtil; -import com.threerings.util.DirectionCodes; - -import com.threerings.media.tile.ObjectTile; -import com.threerings.media.tile.Tile; -import com.threerings.media.tile.TileUtil; - -import com.threerings.whirled.spot.tools.EditablePortal; -import com.threerings.whirled.spot.data.Portal; - -import com.threerings.miso.client.ObjectActionHandler; -import com.threerings.miso.client.SceneBlock; -import com.threerings.miso.client.SceneObject; -import com.threerings.miso.data.MisoSceneModel; -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.util.MisoUtil; - -import com.threerings.stage.client.StageScenePanel; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageMisoSceneModel; - -import com.threerings.stage.data.StageScene; -import com.threerings.stage.tools.editor.util.EditorContext; -import com.threerings.stage.tools.editor.util.EditorDialogUtil; -import com.threerings.stage.tools.editor.util.ExtrasPainter; - -/** - * Displays the scene view and handles UI events on the scene. Various - * actions may be performed on the scene depending on the selected action - * mode, including placing and deleting tiles or locations and creating - * portals. - */ -public class EditorScenePanel extends StageScenePanel - implements EditorModelListener, KeyListener, ChangeListener -{ - /** - * Constructs the editor scene view panel. - */ - public EditorScenePanel (EditorContext ctx, JFrame frame, EditorModel model) - { - super(ctx, new Controller() { - }); - - // keep these around for later - _ctx = ctx; - _frame = frame; - - // save off references to our objects - _emodel = model; - _emodel.addListener(this); - - // listen for alt keys - ctx.getKeyDispatcher().addGlobalKeyListener(this); - - // listen to our range models and scroll our badself - _horizRange.addChangeListener(this); - _vertRange.addChangeListener(this); - } - - /** - * Returns a range model that controls the scrollability of the scene - * in the horizontal direction. - */ - public BoundedRangeModel getHorizModel () - { - return _horizRange; - } - - /** - * Returns a range model that controls the scrollability of the scene - * in the vertical direction. - */ - public BoundedRangeModel getVertModel () - { - return _vertRange; - } - - // documentation inherited from interface - public void stateChanged (ChangeEvent e) - { - setViewLocation(_horizRange.getValue(), _vertRange.getValue()); - _refreshBox = true; - } - - // documentation inherited - public void setSceneModel (MisoSceneModel model) - { - super.setSceneModel(model); - - // compute the "area" in which we'll allow the view to scroll - computeScrollArea(); - } - - /** - * Updates the default tileset in the currently edited scene. - */ - public void updateDefaultTileSet (int tileSetId) - { - _model.setDefaultBaseTileSet(tileSetId); - _blocks.clear(); - rethink(); - } - - // documentation inherited - public void setBounds (int x, int y, int width, int height) - { - super.setBounds(x, y, width, height); - - updateScrollArea(_horizRange.getValue(), _vertRange.getValue()); - } - - /** - * Computes the area in which the view is allowed to scroll. - */ - protected void computeScrollArea () - { - StageMisoSceneModel ysmodel = (StageMisoSceneModel)_model; - _area = null; - for (Iterator iter = ysmodel.getSections(); iter.hasNext(); ) { - StageMisoSceneModel.Section sect = - (StageMisoSceneModel.Section)iter.next(); - Rectangle sbounds = MisoUtil.getFootprintPolygon( - _metrics, sect.x, sect.y, - ysmodel.swidth, ysmodel.sheight).getBounds(); - if (_area == null) { - _area = sbounds; - } else { - _area.add(sbounds); - } - } - - // if we have no blocks, fake something up to start - if (_area == null) { - _area = new Rectangle(-250, -250, 500, 500); - } - - updateScrollArea(_horizRange.getValue(), _vertRange.getValue()); - } - - /** - * Updates our bounded range models to reflect potential changes in - * the viewable area and the scrollable area. - */ - protected void updateScrollArea (int hval, int vval) - { - int hmax = _area.x+_area.width; - hval = Math.min(hval, hmax-_vbounds.width); - _horizRange.setRangeProperties( - hval, _vbounds.width, _area.x, hmax, false); - - int vmax = _area.y+_area.height; - vval = Math.min(vval, vmax-_vbounds.height); - _vertRange.setRangeProperties( - vval, _vbounds.height, _area.y, vmax, false); - -// Log.info("Updated extents area:" + StringUtil.toString(_area) + -// " vb:" + StringUtil.toString(_vbounds) + "."); - // update the dimensions of the scrollbox - - // possibly refresh the dimensions of the box - // and queue a repaint for it - SwingUtil.refresh(_box); - _refreshBox = true; - } - - /** - * Handle placing the currently selected tile at the given screen - * coordinates in the scene. - */ - protected void placeTile (int x, int y) - { - Rectangle drag = clearTileSelectRegion(x, y); - - // sanity check - if (!_emodel.isTileValid()) { - return; - } - - switch (_emodel.getLayerIndex()) { - case EditorModel.BASE_LAYER: - updateBaseTiles(x, y, drag, _emodel.getFQTileId(), - _emodel.getTileSetId(), - _emodel.getTileSet().getTileCount()); - break; - - case EditorModel.OBJECT_LAYER: - addObject((ObjectTile)_emodel.getTile(), - _emodel.getFQTileId(), x, y); - break; - } - - // potentially update our scrollable area - computeScrollArea(); - } - - /** - * Handle deleting the tile at the given screen coordinates from - * the scene. - */ - protected void deleteTile (int x, int y) - { - Rectangle drag = clearTileSelectRegion(x, y); - Log.info("Deleting " + drag); - - switch (_emodel.getLayerIndex()) { - case EditorModel.BASE_LAYER: - updateBaseTiles(x, y, drag, 0, 0, 1); - break; - - case EditorModel.OBJECT_LAYER: - if (drag != null) { - // locate any object that intersects this rectangle - ArrayList hits = new ArrayList(); - for (Iterator iter = _vizobjs.iterator(); iter.hasNext(); ) { - SceneObject scobj = (SceneObject)iter.next(); - if (scobj.objectFootprintOverlaps(drag)) { - hits.add(scobj); - } - } - // and delete 'em - for (int ii = 0; ii < hits.size(); ii++) { - deleteObject((SceneObject)hits.get(ii)); - } - - } else { - // delete the object tile over which the mouse is hovering - if (_hobject instanceof SceneObject) { - deleteObject((SceneObject)_hobject); - } - } - break; - } - } - - /** - * Used to place or delete base tiles. - */ - protected void updateBaseTiles (int x, int y, Rectangle drag, - int fqTileId, int tileSetId, int tileCount) - { - if (drag == null) { - setBaseTile(fqTileId, x, y); - } else { - setBaseTiles(drag, tileSetId, tileCount); - } - } - - /** - * Handle editing the tile at the given screen coordinates from the - * scene. If the tile is not an object tile, we don't do anything. - */ - protected void editTile (int x, int y) - { - // bail if we're not hovering over a scene object - if (_hobject == null || !(_hobject instanceof SceneObject)) { - return; - } - - // create our object editor dialog if we haven't yet - if (_objEditor == null) { - _objEditor = new ObjectEditorDialog(_ctx, this); - } - - // prepare and display our object editor dialog - _eobject = (SceneObject)_hobject; - _objEditor.prepare(_eobject); - EditorDialogUtil.display(_frame, _objEditor); - } - - /** - * Called by the {@link ObjectEditorDialog} when it is dismissed. - */ - protected void objectEditorDismissed () - { - recomputeVisible(); - _model.updateObject(_eobject.info); - _eobject = null; - } - - /** - * Pop up the portal dialog for the specified location. - */ - protected void editPortal (EditablePortal portal) - { - // create our portal dialog if we haven't yet - if (_dialogPortal == null) { - _dialogPortal = new PortalDialog(); - } - - // pass location information on to the dialog - _dialogPortal.prepare((StageScene)_scene, portal); - - // allow the user to edit the info - EditorDialogUtil.display(_frame, _dialogPortal); - - // this gets called when a portal is added, so go ahead and - // recompute them little buggers - recomputePortals(); - recomputeVisible(); - } - - // documentation inherited - public void modelChanged (int event) - { - switch (event) { - case ACTION_MODE_CHANGED: - switch (_emodel.getActionMode()) { - case EditorModel.ACTION_PLACE_TILE: - enableCoordHighlighting(false); - if (_emodel.isTileValid()) { - setPlacingTile(_emodel.getTile()); - } - break; - - case EditorModel.ACTION_EDIT_TILE: - setPlacingTile(null); - enableCoordHighlighting(false); - break; - - case EditorModel.ACTION_PLACE_PORTAL: - setPlacingTile(null); - enableCoordHighlighting(true); - break; - } - break; - - case TILE_CHANGED: - if (_emodel.isTileValid() && - _emodel.getActionMode() == EditorModel.ACTION_PLACE_TILE) { - setPlacingTile(_emodel.getTile()); - } - break; - } - - repaint(); - } - - // documentation inherited from interface - public void mousePressed (MouseEvent event) - { - int mx = event.getX(), my = event.getY(); - switch (_emodel.getActionMode()) { - case EditorModel.ACTION_PLACE_TILE: -// if (_emodel.getLayerIndex() == EditorModel.BASE_LAYER) { - setTileSelectRegion(getTileCoords(mx, my)); -// } - break; - - case EditorModel.ACTION_PLACE_PORTAL: - Point fcoords = getFullCoords(mx, my); - // mouse button three is delete - if (event.getButton() == MouseEvent.BUTTON3) { - deletePortal(fcoords.x, fcoords.y); - } else { - // if they clicked on an existing portal... - EditablePortal portal = (EditablePortal) - getPortal(fcoords.x, fcoords.y); - if (portal != null) { - // ...edit it... - editPortal(portal); - } else { - // ...otherwise create a new one - new PortalTool().init(this, mx, my); - } - } - break; - - default: - super.mousePressed(event); - break; - } - } - - // documentation inherited - protected boolean handleMousePressed (Object hobject, MouseEvent event) - { - // don't do the standard cluster and location stuff here - return false; - } - - // documentation inherited - public void mouseReleased (MouseEvent e) - { - super.mouseReleased(e); - - Point tc = getTileCoords(e.getX(), e.getY()); - switch (_emodel.getActionMode()) { - case EditorModel.ACTION_PLACE_TILE: - switch (e.getButton()) { - case MouseEvent.BUTTON1: - placeTile(tc.x, tc.y); - _refreshBox = true; - break; - - case MouseEvent.BUTTON2: - editTile(tc.x, tc.y); - break; - - case MouseEvent.BUTTON3: - deleteTile(tc.x, tc.y); - _refreshBox = true; - break; - } - break; - - case EditorModel.ACTION_EDIT_TILE: - editTile(tc.x, tc.y); - break; - - case EditorModel.ACTION_PLACE_PORTAL: - // nothing to do here; the portal tool handles all - break; - } - - repaint(); - } - - // documentation inherited - public void mouseMoved (MouseEvent e) - { - super.mouseMoved(e); - int x = e.getX(), y = e.getY(); - boolean repaint = false; - - // update the potential tile placement - if (_ptile != null) { - boolean changed; - - if (_ptile instanceof ObjectTile) { - if (changed = updateObjectTileCoords( - x, y, _ppos, (ObjectTile)_ptile)) { - _pscobj.relocateObject(_metrics, _ppos.x, _ppos.y); - } - } else { - changed = updateTileCoords(x, y, _ppos); - } - - if (changed) { - _validPlacement = - isTilePlacementValid(_ppos.x, _ppos.y, _ptile); - repaint = true; - } - } - - // update the highlighted portal's fine coordinates - if (_coordHighlighting) { - repaint = (updateCoordPos(x, y, _hfull) || repaint); - } - - // TODO: dirty things with a finer grain - if (repaint) { - repaint(); - } - } - - // documentation inherited - public void mouseDragged (MouseEvent e) - { - super.mouseDragged(e); - // do the same thing as when we move - mouseMoved(e); - } - - // documentation inherited - public void mouseExited (MouseEvent e) - { - super.mouseExited(e); - - // remove any highlighted tiles and placing tile - _ppos.setLocation(Integer.MIN_VALUE, 0); - _hfull.setLocation(Integer.MIN_VALUE, 0); - } - - // documentation inherited - public void keyPressed (KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_ALT) { - // enable scene view tooltips - setShowFlags(SHOW_TIPS, true); - } - } - - // documentation inherited - public void keyReleased (KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_ALT) { - // disable scene view tooltips - setShowFlags(SHOW_TIPS, false); - } - } - - // documentation inherited - public void keyTyped (KeyEvent e) - { - // nothing - } - - // documentation inherited - protected void fireObjectAction ( - ObjectActionHandler handler, SceneObject scobj, ActionEvent event) - { - // do nothing in the editor thanksverymuch - } - - /** - * 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) - { - super.hoverObjectChanged(oldHover, newHover); - - // we always repaint our objects when the hover changes - if (oldHover instanceof SceneObject) { - SceneObject oldhov = (SceneObject)oldHover; - _remgr.invalidateRegion(oldhov.getObjectFootprint().getBounds()); - } - if (newHover instanceof SceneObject) { - SceneObject newhov = (SceneObject)newHover; - _remgr.invalidateRegion(newhov.getObjectFootprint().getBounds()); - } - } - - /** - * Sets a base tile at the specified position in the scene (in tile - * coordinates). - */ - public void setBaseTile (int fqTileId, int x, int y) - { - if (!_model.setBaseTile(fqTileId, x, y)) { - return; - } - getBlock(x, y).updateBaseTile(fqTileId, x, y); - - // and recompute any surrounding fringe - for (int fx = x-1, xn = x+1; fx <= xn; fx++) { - for (int fy = y-1, yn = y+1; fy <= yn; fy++) { - getBlock(fx, fy).updateFringe(fx, fy); - } - } - } - - /** - * Set a region of tiles to a random selection from the supplied - * tileset. - */ - public void setBaseTiles (Rectangle r, int setId, int tileCount) - { - for (int x = r.x; x < r.x + r.width; x++) { - for (int y = r.y; y < r.y + r.height; y++) { - int index = RandomUtil.getInt(tileCount); - int fqTileId = TileUtil.getFQTileId(setId, index); - setBaseTile(fqTileId, x, y); - } - } - } - - /** - * Sets an object tile at the specified position in the scene (in tile - * coordinates). - */ - public void addObject (ObjectTile tile, int fqTileId, int x, int y) - { - Point p = new Point(x, y); - adjustObjectCoordsAccordingToGrip(p, tile); - - ObjectInfo oinfo = new ObjectInfo(fqTileId, x, y); - - // first attempt to add it to the appropriate scene block; this - // will fail if there's already a copy of the same object at this - // coordinate - if (getBlock(x, y).addObject(oinfo)) { - // create an object info and add it to the scene model - _model.addObject(oinfo); - // recompute our visible object set - recomputeVisible(); - } - } - - /** - * Deletes the object tile at the specified tile coordinates. - */ - public void deleteObject (SceneObject scobj) - { - // remove it from the scene model - if (_model.removeObject(scobj.info)) { - // clear the object out of its block - getBlock(scobj.info.x, scobj.info.y).deleteObject(scobj.info); - } else { - Log.warning("Requested to remove unknown object " + scobj + "."); - } - - // recompute our visible object set - recomputeVisible(); - - // make sure we clear the hover if that's what we're deleting - if (_hobject == scobj) { - _hobject = null; - } - } - - /** - * Sets the tile that is currently being placed. It will not be - * rendered until after a call to {@link #updateTileCoords} on the - * placing tile (which happens automatically when the mouse moves). - */ - public void setPlacingTile (Tile tile) - { - _ptile = tile; - - // if this is an object tile, create a temporary scene object we - // can use to perform calculations with the object while placing - if (_ptile instanceof ObjectTile) { - _pscobj = new SceneObject(this, new ObjectInfo(0, _ppos.x, _ppos.y), - (ObjectTile)tile); - } else { - _pscobj = null; - } - } - - /** - * Sets the start (in tile coords) of a mouse drag when placing - * a rectangular area of base tiles. - */ - public void setTileSelectRegion (Point drag) - { - _drag = drag; - } - - /** - * Clear and return the drag rectangle for selecting a rectangular - * region. - * - * @return null if the drag is the same as the supplied tile - * coordinates, a rectangle containing the selected region if it was - * different. - */ - public Rectangle clearTileSelectRegion (int x, int y) - { - Rectangle drect = null; - if (_drag != null && (x != _drag.x || y != _drag.y)) { - int w = 1 + ((x > _drag.x) ? (x - _drag.x) : (_drag.x - x)); - int h = 1 + ((y > _drag.y) ? (y - _drag.y) : (_drag.y - y)); - drect = new Rectangle( - Math.min(x, _drag.x), Math.min(y, _drag.y), w, h); - } - _drag = null; - return drect; - } - - /** - * Enables or disables highlighting of the tile over which the mouse - * is currently positioned. - */ - public void enableCoordHighlighting (boolean enabled) - { - _coordHighlighting = enabled; - } - - /** - * Deletes the portal at the specified full coordinates. - */ - public void deletePortal (int x, int y) - { - Portal port = getPortal(x, y); - if (port != null) { - _scene.removePortal(port); - recomputePortals(); - recomputeVisible(); - } - } - - /** - * Returns the portal that serves as the default entrance to this - * scene or null if no default is set. - */ - public Portal getEntrance () - { - return _scene.getDefaultEntrance(); - } - - /** - * Makes the specified portal the default entrance to this scene. - */ - public void setEntrance (Portal port) - { - _scene.setDefaultEntrance(port); - } - - // documentation inherited - protected void recomputeVisible () - { - super.recomputeVisible(); - - // see if any of our visible objects overlap and mark them as bad - // monkeys; we love N^2 algorithms - for (Iterator iter = _vizobjs.iterator(); iter.hasNext(); ) { - SceneObject scobj = (SceneObject)iter.next(); - scobj.setWarning(overlaps(scobj)); - } - } - - // documentation inherited - protected void warnVisible (SceneBlock block, Rectangle sbounds) - { - // nothing doing - } - - /** Helper function for {@link #recomputeVisible}. */ - protected boolean overlaps (SceneObject tobj) - { - for (Iterator iter = _vizobjs.iterator(); iter.hasNext(); ) { - SceneObject scobj = (SceneObject)iter.next(); - if (scobj != tobj && tobj.objectFootprintOverlaps(scobj) && - tobj.getPriority() == scobj.getPriority()) { - return true; - } - } - return false; - } - - // documentation inherited - protected void paintHighlights (Graphics2D gfx, Rectangle dirty) - { - Polygon hpoly = null; - - if (_hobject != null && _hobject instanceof SceneObject) { - SceneObject scobj = (SceneObject)_hobject; - hpoly = scobj.getObjectFootprint(); - - } - - if (_emodel.getActionMode() == EditorModel.ACTION_PLACE_TILE && - (hpoly == null || - _emodel.getLayerIndex() == EditorModel.BASE_LAYER)) { - hpoly = MisoUtil.getTilePolygon(_metrics, _hcoords.x, _hcoords.y); - } - - if (hpoly != null) { - gfx.setColor(Color.green); - gfx.draw(hpoly); - } - - // paint the highlighted full coordinate - if (_coordHighlighting && _hfull.x != Integer.MIN_VALUE) { - Point spos = new Point(); - MisoUtil.fullToScreen(_metrics, _hfull.x, _hfull.y, spos); - - // set the desired stroke and color - Stroke ostroke = gfx.getStroke(); - gfx.setStroke(HIGHLIGHT_STROKE); - - // draw a red circle at the coordinate - gfx.setColor(Color.red); - gfx.draw(new Ellipse2D.Float(spos.x - 1, spos.y - 1, 3, 3)); - - // restore the original stroke - gfx.setStroke(ostroke); - } - } - - // documentation inherited - protected void paintExtras (Graphics2D gfx, Rectangle dirty) - { - super.paintExtras(gfx, dirty); - - // we don't want to paint the 'extras' stuff to the copy.. - if (gfx instanceof TGraphics2D) { - gfx = ((TGraphics2D) gfx).getPrimary(); - } - - paintPortals(gfx); - paintHighlights(gfx, dirty); - paintPlacingTile(gfx); - - // and call into any extras painters - for (int ii = 0; ii < _extras.size(); ii++) { - ((ExtrasPainter)_extras.get(ii)).paintExtras(gfx); - } - } - - /** - * Add an extras painter. - */ - protected void addExtrasPainter (ExtrasPainter painter) - { - _extras.add(painter); - } - - /** - * Remove the specified extras painter. - */ - protected void removeExtrasPainter (ExtrasPainter painter) - { - _extras.remove(painter); - } - - /** - * Paints a transparent image of the tile being placed and draws a - * highlight around the bounds of the tile's current prospective - * position. The highlight is drawn in green if the tile placement is - * valid, or red if not. - * - * @param gfx the graphics context. - */ - protected void paintPlacingTile (Graphics2D gfx) - { - // bail if we've no placing tile - if (_ptile == null || _ppos.x == Integer.MIN_VALUE) { - return; - } - - // draw a transparent rendition of the placing tile image - Composite ocomp = gfx.getComposite(); - gfx.setComposite(ALPHA_PLACING); - Shape bpoly; - if (_pscobj != null) { - _pscobj.paint(gfx); - bpoly = _pscobj.getObjectFootprint(); - - } else { - bpoly = MisoUtil.getTilePolygon(_metrics, _ppos.x, _ppos.y); - Rectangle bounds = bpoly.getBounds(); - _ptile.paint(gfx, bounds.x, bounds.y); - } - gfx.setComposite(ocomp); - - // if we're dragging, grab that footprint - if (_drag != null) { - bpoly = MisoUtil.getMultiTilePolygon(_metrics, _ppos, _drag); - } - - // draw an outline around the tile footprint - gfx.setColor(_validPlacement ? Color.blue : Color.red); - gfx.draw(bpoly); - } - - /** - * Paint demarcations at all portals in the scene. - * - * @param gfx the graphics context. - */ - protected void paintPortals (Graphics2D gfx) - { - Iterator iter = _scene.getPortals(); - while (iter.hasNext()) { - paintPortal(gfx, (EditablePortal)iter.next()); - } - } - - /** - * Paint the specified portal. - */ - protected void paintPortal (Graphics2D gfx, EditablePortal port) - { - // get the portal's center coordinate - StageLocation loc = (StageLocation) port.loc; - Point spos = new Point(); - MisoUtil.fullToScreen(_metrics, loc.x, loc.y, spos); - int cx = spos.x, cy = spos.y; - - // translate the origin to center on the portal - gfx.translate(cx, cy); - - // rotate to reflect the portal orientation - double rot = (Math.PI / 4.0f) * loc.orient; - gfx.rotate(rot); - - // draw the triangle - gfx.setColor(Color.blue); - gfx.fill(_locTri); - - // outline the triangle in black - gfx.setColor(Color.black); - gfx.draw(_locTri); - - // draw the rectangle - gfx.setColor(Color.red); - gfx.fillRect(-1, 2, 3, 3); - - // restore the original transform - gfx.rotate(-rot); - gfx.translate(-cx, -cy); - - // highlight the portal if it's the default entrance - if (port.equals(_scene.getDefaultEntrance())) { - gfx.setColor(Color.cyan); - gfx.drawRect(spos.x - 5, spos.y - 5, 10, 10); - } - } - - /** - * Updates the coordinate position and returns true if it has changed. - */ - public boolean updateCoordPos (int x, int y, Point cpos) - { - Point npos = MisoUtil.screenToFull(_metrics, x, y, new Point()); - if (!cpos.equals(npos)) { - cpos.setLocation(npos.x, npos.y); - return true; - } else { - return false; - } - } - - /** - * Returns whether placing a tile at the given coordinates in the - * scene is valid. Makes sure placing an object fits within the scene - * and doesn't overlap any other objects. - */ - protected boolean isTilePlacementValid (int x, int y, Tile tile) - { - if (tile instanceof ObjectTile) { - // create a temporary scene object for this tile - SceneObject nobj = new SceneObject(this, new ObjectInfo(0, x, y), - (ObjectTile)tile); - // report invalidity if overlaps any existing objects - int ocount = _vizobjs.size(); - for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = (SceneObject)_vizobjs.get(ii); - if (scobj.objectFootprintOverlaps(nobj)) { - return false; - } - } - } - - return true; - } - - // documentation inherited - protected boolean skipHitObject (SceneObject scobj) - { - return false; // skip nothing - } - - /** - * Converts the supplied screen coordinates into tile coordinates for - * an object tile. (See {@link #updateTileCoords}.) - * - * @return true if the tile coordinates have changed. - */ - protected boolean updateObjectTileCoords (int sx, int sy, Point tpos, - ObjectTile otile) - { - Point npos = new Point(); - MisoUtil.screenToTile(_metrics, sx, sy, npos); - adjustObjectCoordsAccordingToGrip(npos, otile); - if (!tpos.equals(npos)) { - tpos.setLocation(npos.x, npos.y); - return true; - } else { - return false; - } - } - - /** - * Alter the position of the object according to which corner - * we are holding it by. - */ - protected void adjustObjectCoordsAccordingToGrip (Point p, ObjectTile tile) - { - int dy = Math.max(3, (tile.getHeight() / _metrics.tilehei)); - int dx = Math.max(3, (tile.getWidth() / _metrics.tilewid)); - - switch (_emodel.getObjectGripDirection()) { - case DirectionCodes.NORTH: - p.x += dy; - p.y += dy; - break; - - case DirectionCodes.WEST: - p.x += dx; - break; - - case DirectionCodes.EAST: - p.y += dx; - break; - - case DirectionCodes.NORTHWEST: - p.x += dy + (dx / 2); - p.y += dy - (dx / 2); - break; - - case DirectionCodes.NORTHEAST: - p.x += dy - (dx / 2); - p.y += dy + (dx / 2); - break; - - case DirectionCodes.SOUTHWEST: - p.x += (dx / 2); - p.y -= (dx / 2); - break; - - case DirectionCodes.SOUTHEAST: - p.x -= (dx / 2); - p.y += (dx / 2); - break; - } - } - - /** - * Sets the editor model. - */ - protected void setEditorModel (EditorModel model) - { - _emodel = model; - } - - /** - * Set the scroll box that tracks our view. - */ - public void setEditorScrollBox (EditorScrollBox box) - { - _box = box; - } - - // documentation inherited - protected void paint (Graphics2D gfx, Rectangle[] dirty) - { - // if we need to refresh the box and we have all the scene data, do it - if (_refreshBox && _visiBlocks.isEmpty()) { - _refreshBox = false; - Graphics2D mini = _box.getMiniGraphics(); - Graphics2D t = new TGraphics2D(gfx, mini); - super.paint(t, dirty); - mini.dispose(); - _box.repaint(); - - } else { - // otherwise, just do a normal fast paint - super.paint(gfx, dirty); - } - } - - /** Provides access to stuff. */ - protected EditorContext _ctx; - - /** Our editor model. */ - protected EditorModel _emodel; - - /** The scrollbox that tracks our view. */ - protected EditorScrollBox _box; - - /** Do we need to refresh the image being displayed in our scrollbox? */ - protected boolean _refreshBox; - - /** We need this to create our dialogs when they are needed. */ - protected JFrame _frame; - - /** Allows scrolling horizontally. */ - protected BoundedRangeModel _horizRange = new DefaultBoundedRangeModel(); - - /** Allows scrolling vertically. */ - protected BoundedRangeModel _vertRange = new DefaultBoundedRangeModel(); - - /** The virtual screen rectangle around which we scroll. */ - protected Rectangle _area; - - /** Whether or not coordinate highlighting is enabled. */ - protected boolean _coordHighlighting; - - /** The currently highlighted full coordinate. */ - protected Point _hfull = new Point(Integer.MIN_VALUE, 0); - - /** The location of the start of a tile drag in tile coords. */ - protected Point _drag = null; - - /** The position of the tile currently being placed. */ - protected Point _ppos = new Point(Integer.MIN_VALUE, 0); - - /** Used to track whether or not the current "placing" tile is in a - * valid position. */ - protected boolean _validPlacement = false; - - /** The tile currently being placed. */ - protected Tile _ptile; - - /** Metrics for the tile currently being placed if it is an object - * tile. */ - protected SceneObject _pscobj; - - /** A list of things that will do some extra painting for us. */ - protected ArrayList _extras = new ArrayList(); - - /** The dialog providing portal edit functionality. */ - protected PortalDialog _dialogPortal; - - /** The dialog providing object edit functionality. */ - protected ObjectEditorDialog _objEditor; - - /** The object currently being edited by the object editor dialog. */ - protected SceneObject _eobject; - - /** The triangle used to render a portal on-screen. */ - protected static Polygon _locTri; - - static { - _locTri = new Polygon(); - _locTri.addPoint(-3, -3); - _locTri.addPoint(3, -3); - _locTri.addPoint(0, 3); - }; - - /** The stroke object used to draw highlighted tiles and coordinates. */ - protected static final Stroke HIGHLIGHT_STROKE = new BasicStroke(2); - - /** Alpha level used to render transparent placing tile image. */ - protected static final Composite ALPHA_PLACING = - AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorScrollBox.java b/src/java/com/threerings/stage/tools/editor/EditorScrollBox.java deleted file mode 100644 index 36ddeabd5..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorScrollBox.java +++ /dev/null @@ -1,174 +0,0 @@ -// -// $Id: EditorScrollBox.java 19363 2005-02-17 21:36:41Z ray $ - -package com.threerings.stage.tools.editor; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.EventQueue; -import java.awt.Graphics; -import java.awt.Graphics2D; - -import java.awt.event.MouseEvent; - -import java.awt.geom.AffineTransform; - -import java.awt.image.BufferedImage; - -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; - -import com.samskivert.swing.ScrollBox; -import com.samskivert.swing.util.SwingUtil; - -/** - * A scrollbox that shows our position in the editor. - */ -public class EditorScrollBox extends ScrollBox -{ - /** - * Create the tightly-coupled EditorScrollBox. - */ - public EditorScrollBox (EditorScenePanel panel) - { - super(panel.getHorizModel(), panel.getVertModel()); - - _panel = panel; - _panel.setEditorScrollBox(this); - _panel.addComponentListener(new ComponentAdapter() { - public void componentResized (ComponentEvent e) - { - SwingUtil.refresh(EditorScrollBox.this); - } - }); - - createMiniMap(1, 1); - } - - /** - * Update the view of the editor map. - */ - public void updateView () - { - _updatingView = true; - _horz.setValue(_horz.getMinimum()); - _vert.setValue(_vert.getMinimum()); - } - - /** - * Get the graphics to draw into when rendering onto the minimap. - */ - public Graphics2D getMiniGraphics () - { - Graphics2D gfx = (Graphics2D) _miniMap.getGraphics(); - gfx.transform(AffineTransform.getTranslateInstance(_box.x, _box.y)); - gfx.transform(AffineTransform.getScaleInstance( - _hFactor, _vFactor)); - - if (_updatingView) { - EventQueue.invokeLater(new Runnable() { - public void run () - { - doNextPieceOfUpdate(); - } - }); - } - - return gfx; - } - - /** - * Do the next piece of the update of the view. - */ - protected void doNextPieceOfUpdate () - { - int x = _horz.getValue(); - int y = _vert.getValue(); - int lastX = _horz.getMaximum() - _horz.getExtent(); - if (x != lastX) { - x = Math.min(x + _horz.getExtent(), lastX); - } else { - x = _horz.getMinimum(); - - int lastY = _vert.getMaximum() - _vert.getExtent(); - if (y != lastY) { - y = Math.min(y + _vert.getExtent(), lastY); - } else { - // we're done - _updatingView = false; - return; - } - } - - _horz.setValue(x); - _vert.setValue(y); - } - - // documentation inherited - public Dimension getPreferredSize () - { - int horz = _horz.getMaximum() - _horz.getMinimum(); - int vert = _vert.getMaximum() - _vert.getMinimum(); - int height = MAX_HEIGHT; - int width = (int) Math.round(horz * (((float) height) / vert)); - - int maxwidth = getParent().getWidth(); - if (maxwidth > 0 && width > maxwidth) { - height = (int) Math.round(height * (((float) maxwidth) / width)); - width = maxwidth; - } - - return new Dimension(width, height); - } - - // documentation inherited - public void setBounds (int x, int y, int w, int h) - { - super.setBounds(x, y, w, h); - - if ((w != _miniMap.getWidth()) || (h != _miniMap.getHeight())) { - createMiniMap(w, h); - } - } - - // documentation inherited - protected void paintBackground (Graphics g) - { - g.drawImage(_miniMap, 0, 0, null); - } - - /** - * Create a mini map image of the correct dimensions. - */ - protected void createMiniMap (int w, int h) - { - BufferedImage newMini = new BufferedImage( - w, h, BufferedImage.TYPE_INT_ARGB); - - // TODO: copy stuff over? - _miniMap = newMini; - Graphics g = _miniMap.getGraphics(); - g.setColor(Color.black); - g.fillRect(0, 0, w, h); - g.dispose(); - } - - // documentation inherited - protected boolean isActiveButton (MouseEvent e) - { - // all buttons are ok. - return true; - } - - /** The minimap image. */ - protected BufferedImage _miniMap; - - /** The panel we box for. */ - protected EditorScenePanel _panel; - - /** Whether or not we're updating our little view. */ - protected boolean _updatingView; - - /** Our maximum height. */ - protected static final int MAX_HEIGHT = 200; -} diff --git a/src/java/com/threerings/stage/tools/editor/EditorToolBarPanel.java b/src/java/com/threerings/stage/tools/editor/EditorToolBarPanel.java deleted file mode 100644 index 6eae8ef47..000000000 --- a/src/java/com/threerings/stage/tools/editor/EditorToolBarPanel.java +++ /dev/null @@ -1,110 +0,0 @@ -// -// $Id: EditorToolBarPanel.java 17780 2004-11-10 23:00:07Z ray $ - -package com.threerings.stage.tools.editor; - -import java.awt.*; -import java.awt.event.*; -import java.util.ArrayList; -import javax.swing.*; -import com.samskivert.swing.*; - -import com.threerings.media.tile.Tile; -import com.threerings.media.tile.TileIcon; -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.UniformTileSet; - -public class EditorToolBarPanel extends JPanel implements ActionListener -{ - public EditorToolBarPanel (TileManager tilemgr, EditorModel model) - { - _model = model; - - // use of flowlayout positions the toolbar and floats properly - setLayout(new FlowLayout(FlowLayout.LEFT)); - - // get our toolbar icons - UniformTileSet tbset = tilemgr.loadTileSet(ICONS_PATH, 40, 40); - - // create the toolbar - JToolBar toolbar = new JToolBar(); - - // add all of the toolbar buttons - _buttons = new ArrayList(); - for (int ii = 0; ii < EditorModel.NUM_ACTIONS; ii++) { - // get the button icon images - Tile tile = tbset.getTile(ii); - if (tile != null) { - String cmd = EditorModel.CMD_ACTIONS[ii]; - String tip = EditorModel.TIP_ACTIONS[ii]; - - // create the button - JButton b = addButton(toolbar, cmd, tip, new TileIcon(tile)); - - // add it to the set of buttons we're managing - _buttons.add(b); - - } else { - Log.warning("Unable to load toolbar icon " + - "[index=" + ii + "]."); - } - } - - // default to the first button - setSelectedButton((JButton)_buttons.get(0)); - - // add the toolbar - add(toolbar); - } - - protected JButton addButton (JToolBar toolbar, String cmd, String tip, - TileIcon icon) - { - // create the button and configure accordingly - JButton button = new JButton(new DimmedIcon(icon)); - button.setSelectedIcon(icon); - button.addActionListener(this); - button.setActionCommand("tbar_" + cmd); - button.setToolTipText(tip); - - // add the button to the toolbar - toolbar.add(button); - - return button; - } - - protected void setSelectedButton (JButton button) - { - for (int ii = 0; ii < _buttons.size(); ii++) { - JButton tb = (JButton)_buttons.get(ii); - tb.setSelected(tb == button); - } - } - - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - - if (cmd.startsWith("tbar")) { - - // select the chosen mode in the toolbar - setSelectedButton((JButton)e.getSource()); - - // update the active mode in the model, stripping the - // "tbar_" prefix from the command string - _model.setActionMode(cmd.substring(5)); - - } else { - Log.warning("Unknown action command [cmd=" + cmd + "]."); - } - } - - /** The buttons in the tool bar. */ - protected ArrayList _buttons; - - /** The editor data model. */ - protected EditorModel _model; - - protected static final String ICONS_PATH = - "media/stage/tools/editor/toolbar_icons.png"; -} diff --git a/src/java/com/threerings/stage/tools/editor/Log.java b/src/java/com/threerings/stage/tools/editor/Log.java deleted file mode 100644 index dcfd0ae79..000000000 --- a/src/java/com/threerings/stage/tools/editor/Log.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $Id: Log.java 8859 2003-05-16 20:05:45Z mdb $ - -package com.threerings.stage.tools.editor; - -/** - * 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("stage.tools.editor"); - - /** 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/stage/tools/editor/ObjectEditorDialog.java b/src/java/com/threerings/stage/tools/editor/ObjectEditorDialog.java deleted file mode 100644 index 79e4144b8..000000000 --- a/src/java/com/threerings/stage/tools/editor/ObjectEditorDialog.java +++ /dev/null @@ -1,245 +0,0 @@ - -// $Id: ObjectEditorDialog.java 16959 2004-08-30 22:09:53Z ray $ - -package com.threerings.stage.tools.editor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Arrays; - -import javax.swing.BorderFactory; -import javax.swing.JComboBox; -import javax.swing.JInternalFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSlider; -import javax.swing.JTextField; - -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; -import com.samskivert.util.StringUtil; - -import com.threerings.media.image.ColorPository.ColorRecord; -import com.threerings.media.image.ColorPository; - -import com.threerings.media.tile.NoSuchTileSetException; -import com.threerings.media.tile.RecolorableTileSet; -import com.threerings.media.tile.TileSet; -import com.threerings.media.tile.TileUtil; - -import com.threerings.miso.client.SceneObject; - -import com.threerings.stage.tools.editor.util.EditorContext; -import com.threerings.stage.tools.editor.util.EditorDialogUtil; - -/** - * Used to edit object attributes. - */ -public class ObjectEditorDialog extends JInternalFrame - implements ActionListener -{ - public ObjectEditorDialog (EditorContext ctx, EditorScenePanel panel) - { - super("Edit object attributes", true); - _ctx = ctx; - _panel = panel; - - // get a handle on the top-level panel - JPanel top = (JPanel)getContentPane(); - - // set up a layout manager for the panel - VGroupLayout gl = new VGroupLayout( - VGroupLayout.STRETCH, VGroupLayout.STRETCH, 5, VGroupLayout.CENTER); - top.setLayout(gl); - top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - // object action editor elements - JPanel sub = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); - sub.add(new JLabel("Object action command:"), HGroupLayout.FIXED); - sub.add(_action = new JTextField()); - _action.addActionListener(this); - _action.setActionCommand("ok"); - top.add(sub); - - // create the priority slider - sub = new JPanel(new HGroupLayout(HGroupLayout.STRETCH)); - sub.add(new JLabel("Render priority:"), HGroupLayout.FIXED); - sub.add(_priority = new JSlider(-5, 5)); - _priority.setMajorTickSpacing(5); - _priority.setMinorTickSpacing(1); - _priority.setPaintTicks(true); - top.add(sub); - - // create colorization selectors - JPanel zations = HGroupLayout.makeButtonBox(HGroupLayout.LEFT); - zations.add(new JLabel("Colorizations:")); - zations.add(_primary = new JComboBox(NO_CHOICES)); - zations.add(_secondary = new JComboBox(NO_CHOICES)); - top.add(zations); - - // create our OK/Cancel buttons - sub = HGroupLayout.makeButtonBox(HGroupLayout.CENTER); - EditorDialogUtil.addButton(this, sub, "OK", "ok"); - EditorDialogUtil.addButton(this, sub, "Cancel", "cancel"); - top.add(sub); - - pack(); - } - - /** - * Prepare the dialog for display. This method should be called - * before display() is called. - * - * @param scobj the object to edit. - */ - public void prepare (SceneObject scobj) - { - _scobj = scobj; - - // set our title to the name of the tileset and the tile index - String title; - int tsid = TileUtil.getTileSetId(scobj.info.tileId); - int tidx = TileUtil.getTileIndex(scobj.info.tileId); - TileSet tset = null; - try { - tset = _ctx.getTileManager().getTileSet(tsid); - title = tset.getName() + ": " + tidx; - } catch (NoSuchTileSetException nstse) { - title = "Error(" + tsid + "): " + tidx; - } - title += " (" + StringUtil.coordsToString( - _scobj.info.x, _scobj.info.y) + ")"; - setTitle(title); - - // configure our elements - String atext = (scobj.info.action == null ? "" : scobj.info.action); - _action.setText(atext); - _priority.setValue(scobj.getPriority()); - - // if the object supports colorizations, configure those - boolean haveZations = false; - Object[] pzations = null; - Object[] szations = null; - if (tset != null) { - String[] zations = null; - if (tset instanceof RecolorableTileSet) { - zations = ((RecolorableTileSet)tset).getColorizations(); - } - if (zations != null) { - pzations = computeZations(zations, 0); - szations = computeZations(zations, 1); - } - } - configureZations(_primary, pzations, _scobj.info.getPrimaryZation()); - configureZations(_secondary, szations, - _scobj.info.getSecondaryZation()); - - // select the text edit field and focus it - _action.setCaretPosition(0); - _action.moveCaretPosition(atext.length()); - _action.requestFocusInWindow(); - } - - protected Object[] computeZations (String[] zations, int index) - { - if (zations.length <= index || StringUtil.isBlank(zations[index])) { - return null; - } - ColorPository cpos = _ctx.getColorPository(); - ColorRecord[] crecs = cpos.enumerateColors(zations[index]); - if (crecs == null) { - return null; - } - Object[] czations = new Object[crecs.length+1]; - czations[0] = new ZationChoice(0, "none"); - for (int ii = 0; ii < crecs.length; ii++) { - czations[ii+1] = - new ZationChoice(crecs[ii].colorId, crecs[ii].name); - } - Arrays.sort(czations); - return czations; - } - - protected void configureZations ( - JComboBox combo, Object[] zations, int colorId) - { - int selidx = 0; - combo.setEnabled(zations != null); - if (zations != null) { - combo.removeAllItems(); - for (int ii = 0; ii < zations.length; ii++) { - combo.addItem(zations[ii]); - if (((ZationChoice)zations[ii]).colorId == colorId) { - selidx = ii; - } - } - } - combo.setSelectedIndex(selidx); - } - - // documentation inherited from interface - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - - if (cmd.equals("ok")) { - _scobj.info.action = _action.getText(); - byte prio = (byte)_priority.getValue(); - if (prio != _scobj.getPriority()) { - _scobj.setPriority(prio); - } - - int ozations = _scobj.info.zations; - ZationChoice pchoice = (ZationChoice)_primary.getSelectedItem(); - ZationChoice schoice = (ZationChoice)_secondary.getSelectedItem(); - _scobj.info.setZations(pchoice.colorId, schoice.colorId); - if (ozations != _scobj.info.zations) { - _scobj.refreshObjectTile(_panel); - } - - _panel.objectEditorDismissed(); - - } else if (cmd.equals("cancel")) { - // do nothing except hide the dialog - _panel.objectEditorDismissed(); - - } else { - System.err.println("Received unknown action: " + e); - return; - } - - // hide the dialog - EditorDialogUtil.dismiss(this); - } - - /** Used to display colorization choices. */ - protected static class ZationChoice - implements Comparable - { - public short colorId; - public String name; - - public ZationChoice (int colorId, String name) { - this.colorId = (short)colorId; - this.name = name; - } - - public int compareTo (Object other) { - return colorId - ((ZationChoice)other).colorId; - } - - public String toString () { - return name; - } - } - - protected EditorContext _ctx; - protected EditorScenePanel _panel; - protected JTextField _action; - protected JSlider _priority; - protected SceneObject _scobj; - protected JComboBox _primary, _secondary; - - protected static final ZationChoice[] NO_CHOICES = new ZationChoice[] { - new ZationChoice(0, "none") }; -} diff --git a/src/java/com/threerings/stage/tools/editor/PortalDialog.java b/src/java/com/threerings/stage/tools/editor/PortalDialog.java deleted file mode 100644 index 357f3018c..000000000 --- a/src/java/com/threerings/stage/tools/editor/PortalDialog.java +++ /dev/null @@ -1,164 +0,0 @@ -// -// $Id: PortalDialog.java 9371 2003-06-02 20:28:21Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import com.samskivert.swing.*; - -import com.threerings.whirled.spot.data.Portal; -import com.threerings.whirled.spot.tools.EditablePortal; - -import com.threerings.stage.data.StageScene; -import com.threerings.stage.tools.editor.util.EditorDialogUtil; - -/** - * The PortalDialog is used to present the user with a dialog - * allowing them to enter the information associated with an - * EditablePortal. The dialog is used both to set up a new - * portal and to edit an existing portal. - */ -public class PortalDialog extends JInternalFrame - implements ActionListener -{ - /** - * Constructs the portal dialog. - */ - public PortalDialog () - { - super("Edit Portal", true); - - // get a handle on the top-level panel - JPanel top = (JPanel)getContentPane(); - - // set up a layout manager for the panel - GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - top.setLayout(gl); - top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - // add the dialog instruction text - top.add(new JLabel("Enter settings for this portal:")); - - // create a panel to contain the portal name info - JPanel sub = new JPanel(new HGroupLayout(GroupLayout.STRETCH)); - sub.add(new JLabel("Portal name:", SwingConstants.RIGHT)); - - // create and add the portal name text entry field - sub.add(_portalText = new JTextField()); - - // add the portal name info to the top-level panel - top.add(sub); - - // create a check box to allow making this the default - // entrance portal - _entrance = new JCheckBox("Default Entrance"); - _entrance.addActionListener(this); - _entrance.setActionCommand("entrance"); - top.add(_entrance); - - // create a panel to contain the OK/Cancel buttons - sub = new JPanel(new HGroupLayout()); - EditorDialogUtil.addButton(this, sub, "OK", "ok"); - - // add the buttons to the top-level panel - top.add(sub); - - pack(); - } - - /** - * Prepare the dialog for display. This method should be called - * before display() is called. - * - * @param port the portal to edit. - */ - public void prepare (StageScene scene, EditablePortal port) - { - _port = port; - _scene = scene; - - // if the location is already a portal, fill the text entry field - // with the current scene name, else clear it - String text = port.name; - _portalText.setText(text); - - // select the text edit field - _portalText.setCaretPosition(0); - _portalText.moveCaretPosition(text.length()); - - // select the default entrance check box appropriately - Portal entry = _scene.getDefaultEntrance(); - _entrance.setSelected(entry == null || - entry.portalId == _port.portalId); - - // request the keyboard focus so that the destination scene - // name can be typed immediately - _portalText.requestFocusInWindow(); - } - - /** - * Handle action events on the dialog user interface elements. - */ - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - - if (cmd.equals("entrance")) { - _entrance.setSelected(_entrance.isSelected()); - - } else if (cmd.equals("ok")) { - handleSubmit(); - - } else { - Log.warning("Unknown action command [cmd=" + cmd + "]."); - } - } - - /** - * Handles the user submitting the dialog via the "OK" button. - */ - protected void handleSubmit () - { - // get the destination scene name - _port.name = _portalText.getText(); - - // update the scene's default entrance - if (_entrance.isSelected()) { - _scene.setDefaultEntrance(_port); - - } else if (_scene.getDefaultEntrance() == _port) { - _scene.setDefaultEntrance(null); - } - - // hide the dialog - EditorDialogUtil.dismiss(this); - } - - // documentation inherited - protected void processKeyEvent (KeyEvent e) - { - switch (e.getKeyCode()) { - case KeyEvent.VK_ENTER: handleSubmit(); break; - case KeyEvent.VK_ESCAPE: setVisible(false); break; - } - } - - /** The scene. */ - protected StageScene _scene; - - /** The portal name text entry field. */ - protected JTextField _portalText; - - /** The portal default entrance check box. */ - protected JCheckBox _entrance; - - /** The location object denoting the portal location. */ - protected EditablePortal _port; - - /** The combo box listing the direction orientations. */ - protected JComboBox _orientcombo; -} diff --git a/src/java/com/threerings/stage/tools/editor/PortalTool.java b/src/java/com/threerings/stage/tools/editor/PortalTool.java deleted file mode 100644 index ce87e623e..000000000 --- a/src/java/com/threerings/stage/tools/editor/PortalTool.java +++ /dev/null @@ -1,165 +0,0 @@ -// -// $Id: PortalTool.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.event.MouseEvent; -import javax.swing.event.MouseInputAdapter; - -import java.util.Iterator; - -import com.threerings.miso.util.MisoUtil; -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; - -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.spot.tools.EditablePortal; - -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageScene; -import com.threerings.stage.tools.editor.util.ExtrasPainter; - -/** - * A tool for setting a portal. - */ -public class PortalTool extends MouseInputAdapter - implements ExtrasPainter -{ - public void init (EditorScenePanel panel, int centerx, int centery) - { - _panel = panel; - _scene = (StageScene)_panel.getScene(); - - // adjust the center screen coordinate so that it is positioned at - // the closest full coordinate where a portal may be placed - Point p = _panel.getFullCoords(centerx, centery); - - // configure the portal with these full coordinates - _portal = new EditablePortal(); - _portal.loc = new StageLocation(p.x, p.y, (byte)DirectionCodes.NORTH); - - // we want to listen to drags and clicks - _panel.addMouseListener(this); - _panel.addMouseMotionListener(this); - _panel.addExtrasPainter(this); - - // now map that back to a screen coordinate - _center = _panel.getScreenCoords(p.x, p.y); - - calculateOrientation(centerx, centery); - } - - /** - * When the mouse is dragged we update the current portal. - */ - public void mouseDragged (MouseEvent event) - { - calculateOrientation(event.getX(), event.getY()); - } - - /** - * If button1 is released, we store the new portal, if button3: we - * cancel. - */ - public void mouseReleased (MouseEvent event) - { - switch (event.getButton()) { - case MouseEvent.BUTTON1: - savePortal(); - // fall through to BUTTON3 - - case MouseEvent.BUTTON3: - dispose(); - break; - } - } - - /** - * Paint what the clusters would look like if we were to add them to - * the scene. - */ - public void paintExtras (Graphics2D gfx) - { - _panel.paintPortal(gfx, _portal); - } - - /** - * Updates the orientation of the portal based on the current mouse - * position and potentially repaints. - */ - protected void calculateOrientation (int x, int y) - { - // get the orientation towards the center from the current x/y - int norient = MisoUtil.getProjectedIsoDirection( - x, y, _center.x, _center.y); - norient = DirectionUtil.getOpposite(norient); - if (norient == DirectionCodes.NONE) { - norient = DirectionCodes.NORTH; - } - - // if our orientation changed, repaint - StageLocation loc = (StageLocation) _portal.loc; - if (norient != loc.orient) { - loc.orient = (byte)norient; - _panel.repaint(); - } - } - - /** - * Adds our portal to the scene. - */ - protected void savePortal () - { - // try to come up with a reasonable name - byte orient = ((StageLocation) _portal.loc).orient; - String dirname = DirectionUtil.toString(orient).toLowerCase(); - String name = dirname; - for (int ii=1; portalNameExists(name); ii++) { - name = dirname + ii; - } - _portal.name = name; - - // add the portal to the scene and pop up the editor dialog - _portal.portalId = _scene.getNextPortalId(); - _scene.addPortal(_portal); - _panel.editPortal(_portal); - } - - /** - * See if the portal name already exists. - */ - protected boolean portalNameExists (String name) - { - Iterator iter = _scene.getPortals(); - while (iter.hasNext()) { - if (((EditablePortal)iter.next()).name.equals(name)) { - return true; - } - } - return false; - } - - /** - * Get rid of ourselves. - */ - protected void dispose () - { - _panel.removeMouseListener(this); - _panel.removeMouseMotionListener(this); - _panel.removeExtrasPainter(this); - } - - /** The panel. */ - protected EditorScenePanel _panel; - - /** The scene. */ - protected StageScene _scene; - - /** Center coordinates. */ - protected Point _center; - - /** Our newly created portal. */ - protected EditablePortal _portal; -} diff --git a/src/java/com/threerings/stage/tools/editor/PreferencesDialog.java b/src/java/com/threerings/stage/tools/editor/PreferencesDialog.java deleted file mode 100644 index 5b6a11a09..000000000 --- a/src/java/com/threerings/stage/tools/editor/PreferencesDialog.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// $Id: PreferencesDialog.java 9938 2003-06-20 03:55:58Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JFileChooser; -import javax.swing.JInternalFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; - -import com.threerings.stage.tools.editor.util.EditorDialogUtil; - -/** - * A dialog for editing preferences. - */ -public class PreferencesDialog extends JInternalFrame - implements ActionListener -{ - /** - * Creates a preferences dialog. - */ - public PreferencesDialog () - { - super("Editor Preferences", true); - - // set up a layout manager for the panel - JPanel top = (JPanel)getContentPane(); - GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH); - gl.setOffAxisPolicy(GroupLayout.STRETCH); - top.setLayout(gl); - top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - // create the display for the test tile directory pref - JPanel sub = new JPanel(new HGroupLayout(GroupLayout.STRETCH)); - sub.add(new JLabel("Directory to search for test tiles:"), - GroupLayout.FIXED); - EditorDialogUtil.addButton(this, sub, - EditorConfig.getTestTileDirectory(), "testtiledir"); - top.add(sub); - - sub = new JPanel(new HGroupLayout()); - EditorDialogUtil.addButton(this, sub, "OK", "ok"); - top.add(sub); - - pack(); - } - - /** - * Handle action events. - */ - public void actionPerformed (ActionEvent e) - { - String cmd = e.getActionCommand(); - - if (cmd.equals("testtiledir")) { - changeTestTileDir((JButton) e.getSource()); - - } else if (cmd.equals("ok")) { - EditorDialogUtil.dispose(this); - - } else { - Log.warning("Unknown action command [cmd=" + cmd + "]."); - } - } - - /** - * Pop up a file selection box for specifying the directory to look - * in for test tiles. - */ - protected void changeTestTileDir (JButton button) - { - JFileChooser chooser; - - // figure out which - File f = new File(button.getText()); - if (!f.exists()) { - chooser = new JFileChooser(); - } else { - chooser = new JFileChooser(f); - } - - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setSelectedFile(f); - - int result = chooser.showDialog(this, "Select"); - if (JFileChooser.APPROVE_OPTION == result) { - f = chooser.getSelectedFile(); - String newdir = f.getPath(); - button.setText(newdir); - EditorConfig.setTestTileDirectory(newdir); - } - } -} diff --git a/src/java/com/threerings/stage/tools/editor/SceneInfoPanel.java b/src/java/com/threerings/stage/tools/editor/SceneInfoPanel.java deleted file mode 100644 index 35ffb6069..000000000 --- a/src/java/com/threerings/stage/tools/editor/SceneInfoPanel.java +++ /dev/null @@ -1,289 +0,0 @@ -// -// $Id: SceneInfoPanel.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; - -import java.util.HashSet; -import java.util.Iterator; - -import javax.swing.DefaultComboBoxModel; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.util.CollectionUtil; -import com.samskivert.util.Collections; -import com.samskivert.util.ComparableArrayList; - -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.data.SparseMisoSceneModel.ObjectVisitor; - -import com.threerings.media.image.ColorPository; - -import com.threerings.media.tile.NoSuchTileSetException; -import com.threerings.media.tile.RecolorableTileSet; -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.TileSet; -import com.threerings.media.tile.TileUtil; - -import com.threerings.stage.data.StageMisoSceneModel; -import com.threerings.stage.data.StageScene; - -import com.threerings.stage.tools.editor.util.EditorContext; - -/** - * The scene info panel presents the user with options to select the - * scene layer to edit, and whether to display tile coordinates and - * locations in the scene view. - */ -public class SceneInfoPanel extends JPanel - implements ActionListener -{ - /** - * Constructs the scene info panel. - */ - public SceneInfoPanel (EditorContext ctx, EditorModel model, - EditorScenePanel svpanel) - { - _ctx = ctx; - _svpanel = svpanel; - - // configure the panel - GroupLayout gl = new HGroupLayout(); - gl.setGap(12); - setLayout(gl); - - JPanel vert = GroupLayout.makeVStretchBox(5); - - JPanel hbox = GroupLayout.makeHBox(); - - // create a panel for the name label - hbox.add(createLabel("Scene name:", _scenename = new JTextField(10))); - _scenename.addActionListener(this); - _scenename.addFocusListener(new FocusAdapter() { - public void focusLost (FocusEvent e) { - _scenename.postActionEvent(); - } - }); - - // create a drop-down for selecting the scene type - ComparableArrayList types = new ComparableArrayList(); - ctx.enumerateSceneTypes(types); - types.sort(); - types.add(0, ""); - hbox.add(createLabel("Scene type:", - _scenetype = new JComboBox(types.toArray()))); - _scenetype.addActionListener(this); - - vert.add(hbox); - - // set up the scene colorization stuff - hbox = GroupLayout.makeButtonBox(GroupLayout.LEFT); - hbox.add(_colorClasses = new JComboBox()); - hbox.add(_colorIds = new JComboBox()); - vert.add(createLabel("Colorizations:", hbox), GroupLayout.FIXED); - _colorClasses.addActionListener(this); - _colorIds.addActionListener(this); - _colorClasses.addPopupMenuListener(new PopupMenuListener() { - public void popupMenuCanceled (PopupMenuEvent e) { } - public void popupMenuWillBecomeInvisible (PopupMenuEvent e) { } - public void popupMenuWillBecomeVisible (PopupMenuEvent e) { - recomputeColorClasses(); - } - }); - - add(vert, GroupLayout.FIXED); - } - - protected JPanel createLabel (String label, JComponent comp) - { - JPanel panel = GroupLayout.makeButtonBox(GroupLayout.CENTER); - panel.add(new JLabel(label), GroupLayout.FIXED); - panel.add(comp); - return panel; - } - - /** - * Called when the scene in the editor changes. - */ - public void setScene (StageScene scene) - { - _scene = scene; - _scenename.setText(scene.getName()); - _scenetype.setSelectedItem(scene.getType()); - - recomputeColorClasses(); - } - - // documentation inherited from interface ActionListener - public void actionPerformed (ActionEvent e) - { - Object src = e.getSource(); - if (src == _scenename) { - _scene.setName(_scenename.getText().trim()); - - } else if (src == _scenetype) { - _scene.setType((String) _scenetype.getSelectedItem()); - - } else if (src == _colorClasses) { - String cclass = (String) _colorClasses.getSelectedItem(); - configureColorIds(cclass); - - } else if (src == _colorIds) { - setNewDefaultColor(); - } - } - - /** - * Prior to the color classes popup popping up, recompute the possible - * values. - */ - protected void recomputeColorClasses () - { - // add all possible colorization names to the list - final TileManager tilemgr = _ctx.getTileManager(); - final HashSet set = new HashSet(); - StageMisoSceneModel msmodel = StageMisoSceneModel.getSceneModel( - _scene.getSceneModel()); - msmodel.visitObjects(new ObjectVisitor() { - public void visit (ObjectInfo info) { - int tsid = TileUtil.getTileSetId(info.tileId); - TileSet tset; - try { - tset = tilemgr.getTileSet(tsid); - } catch (NoSuchTileSetException nstse) { - return; - } - String[] zations; - if (tset instanceof RecolorableTileSet) { - zations = ((RecolorableTileSet) tset).getColorizations(); - } else { - return; - } - if (zations != null) { - for (int ii=0; ii < zations.length; ii++) { - set.add(zations[ii]); - } - } - } - }); - - Object selected = _colorClasses.getSelectedItem(); - DefaultComboBoxModel model = - (DefaultComboBoxModel) _colorClasses.getModel(); - model.removeAllElements(); - for (Iterator itr = Collections.getSortedIterator(set); - itr.hasNext(); ) { - model.addElement(itr.next()); - } - if (selected != null) { - _colorClasses.setSelectedItem(selected); - } - } - - /** - * Show which color Ids are available for the currently selected - * colorization class, and select the selected one. - */ - protected void configureColorIds (String cclass) - { - _colorIds.removeActionListener(this); - try { - DefaultComboBoxModel model = - (DefaultComboBoxModel) _colorIds.getModel(); - model.removeAllElements(); - if (cclass == null) { - return; - } - - ColorPository cpos = _ctx.getColorPository(); - - String noChoice = ""; - String choice = noChoice; - - ColorPository.ClassRecord classRec = cpos.getClassRecord(cclass); - int pick = _scene.getDefaultColor(classRec.classId); - - ColorPository.ColorRecord[] colors = cpos.enumerateColors(cclass); - ComparableArrayList list = new ComparableArrayList(); - for (int ii=0; ii < colors.length; ii++) { - list.insertSorted(colors[ii].name); - if (colors[ii].colorId == pick) { - choice = colors[ii].name; - } - } - - model.addElement(noChoice); - for (int ii=0; ii < list.size(); ii++) { - model.addElement(list.get(ii)); - } - _colorIds.setSelectedItem(choice); - - } finally { - _colorIds.addActionListener(this); - } - } - - /** - * Called when a _colorIds color is selected. - */ - protected void setNewDefaultColor () - { - String cclass = (String) _colorClasses.getSelectedItem(); - if (cclass == null) { - return; - } - - ColorPository cpos = _ctx.getColorPository(); - ColorPository.ClassRecord classRec = cpos.getClassRecord(cclass); - ColorPository.ColorRecord[] colors = cpos.enumerateColors(cclass); - Object selected = _colorIds.getSelectedItem(); - int pick = -1; - - for (int ii=0; ii < colors.length; ii++) { - if (colors[ii].name.equals(selected)) { - pick = colors[ii].colorId; - break; - } - } - - // only update the scene if our selection has actually changed - if (_scene.getDefaultColor(classRec.classId) != pick) { - _scene.setDefaultColor(classRec.classId, pick); - _svpanel.setScene(_scene); - _svpanel.repaint(); - } - } - - /** The giver of life. */ - protected EditorContext _ctx; - - /** The scene we're controlling. */ - protected StageScene _scene; - - /** The scene name entry field. */ - protected JTextField _scenename; - - /** The scene type selector. */ - protected JComboBox _scenetype, _colorClasses, _colorIds; - - /** The scene panel, which we hackily repaint when default colors change. */ - protected EditorScenePanel _svpanel; - - /** The object grip direction button. */ - protected DirectionButton _dirbutton; -} diff --git a/src/java/com/threerings/stage/tools/editor/TestTileLoader.java b/src/java/com/threerings/stage/tools/editor/TestTileLoader.java deleted file mode 100644 index 6c076ef34..000000000 --- a/src/java/com/threerings/stage/tools/editor/TestTileLoader.java +++ /dev/null @@ -1,173 +0,0 @@ -// -// $Id: TestTileLoader.java 9938 2003-06-20 03:55:58Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileFilter; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import javax.imageio.ImageIO; - -import com.samskivert.util.HashIntMap; - -import com.threerings.media.tile.ImageProvider; -import com.threerings.media.tile.SimpleCachingImageProvider; -import com.threerings.media.tile.TileSet; -import com.threerings.media.tile.TileSetIDBroker; - -import com.threerings.miso.tile.tools.xml.BaseTileSetRuleSet; -import com.threerings.media.tile.tools.xml.ObjectTileSetRuleSet; -import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet; -import com.threerings.media.tile.tools.xml.XMLTileSetParser; - -/** - * The TestTileLoader handles test tiles. Test tiles are tiles that an - * artist can load in on-the-fly to see how things look in the scene editor. - */ -public class TestTileLoader implements TileSetIDBroker -{ - /** - * Construct the TestTileLoader. - */ - public TestTileLoader () - { - // our xml parser - _parser = new XMLTileSetParser(); - // add some rulesets - _parser.addRuleSet("bundle/base", new BaseTileSetRuleSet()); - _parser.addRuleSet("bundle/object", new ObjectTileSetRuleSet()); - - // we used to parse fringes, but we don't anymore - //_parser.addRuleSet("bundle/fringe", new SwissArmyTileSetRuleSet()); - } - - /** - * Check the specified directory and all its subdirectories for xml files. - * Each directory should contain at most one xml file, each xml file - * should specify at most one tileset. That tileset specification - * will be used to create tilesets for all the .png files in the same - * directory. - * - * @return a HashIntMap containing a TileSetId -> TileSet mapping for - * all the tilesets we create. - */ - public HashIntMap loadTestTiles () - { - String directory = EditorConfig.getTestTileDirectory(); - HashIntMap map = new HashIntMap(); - - // recurse test directory, making a tileset from the xml file inside - // and cloning it for each image we find in there. - File testdir = new File(directory); - // make sure it's a directory - if (!testdir.isDirectory()) { - Log.warning("Test tileset directory is not actually a directory: " + - directory); - return map; - } - - // recursively load all the test tiles - loadTestTilesFromDir(testdir, map); - - return map; - } - - /** - * Load xml tile sets from a directory. - */ - protected void loadTestTilesFromDir (File directory, - HashIntMap sets) - { - // first recurse - File[] subdirs = directory.listFiles(new FileFilter() { - public boolean accept (File f) { - return f.isDirectory(); - } - }); - for (int ii=0; ii < subdirs.length; ii++) { - loadTestTilesFromDir(subdirs[ii], sets); - } - - // now look for the xml file - String[] xml = directory.list(new FilenameFilter() { - public boolean accept (File dir, String name) { - return name.endsWith(".xml"); - } - }); - - for (int ii=0; ii < xml.length; ii++) { - File xmlfile = new File(directory, xml[ii]); - - HashMap tiles = new HashMap(); - try { - _parser.loadTileSets(xmlfile, tiles); - } catch (IOException ioe) { - Log.warning("Error while parsing " + xmlfile.getPath()); - Log.logStackTrace(ioe); - continue; - } - - Iterator iter = tiles.values().iterator(); - while (iter.hasNext()) { - TileSet ts = (TileSet) iter.next(); - String path = new File(directory, ts.getImagePath()).getPath(); - - // before we insert, make sure we can load the image - if (null != _improv.getTileSetImage(path, null)) { - ts.setImageProvider(_improv); - ts.setImagePath(path); - sets.put(getTileSetID(path), ts); - } - } - } - } - - /** - * Generate unique and completely fake tileset IDs that will be stable - * even after a reload of test tiles. - */ - public int getTileSetID (String tileSetPath) - { - Integer id = (Integer) _idmap.get(tileSetPath); - if (null == id) { - id = Integer.valueOf(_fakeID--); - _idmap.put(tileSetPath, id); - } - return id.intValue(); - } - - // documentation inherited - public boolean tileSetMapped (String tilesetPath) - { - return _idmap.containsKey(tilesetPath); - } - - /** - * Since we're just testing, we don't save these crazy IDs. - */ - public void commit () - { - // this method does nothing. perhaps it should be called "committee". - } - - /** The value of the next fakeID we'll hand out. */ - protected int _fakeID = -1; - - /** A mapping of pathname -> tileset id. */ - protected HashMap _idmap = new HashMap(); - - /** Our xml parser. */ - protected XMLTileSetParser _parser; - - /** Our image provider. */ - protected ImageProvider _improv = new SimpleCachingImageProvider() { - protected BufferedImage loadImage (String path) - throws IOException { - return ImageIO.read(new File(path)); - } - }; -} diff --git a/src/java/com/threerings/stage/tools/editor/TileInfoPanel.java b/src/java/com/threerings/stage/tools/editor/TileInfoPanel.java deleted file mode 100644 index 1a98f795f..000000000 --- a/src/java/com/threerings/stage/tools/editor/TileInfoPanel.java +++ /dev/null @@ -1,707 +0,0 @@ -// -// $Id: TileInfoPanel.java 17625 2004-10-28 17:50:03Z mdb $ - -package com.threerings.stage.tools.editor; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Image; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.swing.BorderFactory; -import javax.swing.DefaultListCellRenderer; -import javax.swing.DefaultListModel; -import javax.swing.ImageIcon; -import javax.swing.JList; -import javax.swing.JSplitPane; -import javax.swing.JTable; -import javax.swing.JTree; -import javax.swing.ListSelectionModel; -import javax.swing.border.Border; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumn; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; - -import com.samskivert.util.HashIntMap; -import com.samskivert.util.QuickSort; -import com.samskivert.util.StringUtil; - -import com.threerings.media.SafeScrollPane; - -import com.threerings.media.tile.TileSet; -import com.threerings.media.tile.TileSetRepository; - -import com.threerings.stage.tools.editor.util.EditorContext; -import com.threerings.stage.tools.editor.util.TileSetUtil; - -/** - * The tile info panel presents the user with options to select the - * tile to be applied to the scene. - */ -public class TileInfoPanel extends JSplitPane - implements ListSelectionListener, TreeSelectionListener -{ - /** - * Constructs the tile info panel. - */ - public TileInfoPanel (EditorContext ctx, EditorModel model) - { - TileSetRepository tsrepo = ctx.getTileSetRepository(); - - // set up our key observers - registerKeyListener(ctx); - - _model = model; - - // we're going to sort all of the available tilesets into those - // which are applicable to each layer - try { - _layerSets = new ArrayList[2]; - _layerLengths = new int[2]; - for (int ii=0; ii < 2; ii++) { - _layerSets[ii] = new ArrayList(); - } - - Iterator tsids = tsrepo.enumerateTileSetIds(); - while (tsids.hasNext()) { - Integer tsid = (Integer)tsids.next(); - TileSet set = tsrepo.getTileSet(tsid.intValue()); - - // determine which layer to which this tileset applies - int lidx = TileSetUtil.getLayerIndex(set); - if (lidx != -1) { - _layerSets[lidx].add( - new TileSetRecord(lidx, tsid.intValue(), set)); - } - } - - for (int ii=0; ii < 2; ii++) { - _layerLengths[ii] = _layerSets[ii].size(); - } - - } catch (Exception e) { - Log.warning("Error enumerating tilesets."); - Log.logStackTrace(e); - } - - // set up a border denoting our contents - Border border = BorderFactory.createEtchedBorder(); - setBorder(BorderFactory.createTitledBorder(border, "Tile Info")); - - // create a tree for selecting tileset - DefaultMutableTreeNode root = new DefaultMutableTreeNode(""); - _tsettree = new JTree(root); - - // don't draw any funny little icons in the tree - DefaultTreeCellRenderer cellrend = - (DefaultTreeCellRenderer) _tsettree.getCellRenderer(); - cellrend.setLeafIcon(null); - cellrend.setOpenIcon(null); - cellrend.setClosedIcon(null); - - // tree- only let one thing be selected, and let us know when it haps - _tsettree.getSelectionModel().setSelectionMode( - TreeSelectionModel.SINGLE_TREE_SELECTION); - _tsettree.addTreeSelectionListener(this); - - // create a scrollpane to hold the tree - SafeScrollPane scrolly = new SafeScrollPane(_tsettree); - scrolly.setVerticalScrollBarPolicy( - SafeScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - - DefaultListModel qmodel = new DefaultListModel(); - for (int ii=0; ii < 10; ii++) { - qmodel.addElement(""); - } - _quickList = new JList(qmodel); - _quickList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - _quickList.addListSelectionListener(this); - _quickList.setCellRenderer(new DefaultListCellRenderer() { - public Component getListCellRendererComponent ( - JList list, Object value, int index, boolean isSelected, - boolean cellHasFocus) - { - // put the key number in front of each element - Component result = super.getListCellRendererComponent( - list, value, index, isSelected, cellHasFocus); - setText("" + ((index + 11) % 10) + ". " + getText()); - return result; - } - }); - JSplitPane leftSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT); - leftSplit.setTopComponent(new SafeScrollPane(_quickList)); - leftSplit.setBottomComponent(scrolly); - - // add the west side - setLeftComponent(leftSplit); - - // create a table to display the tiles in the selected tileset - _tiletable = new JTable(_tablemodel = new TileTableModel()); - _tiletable.getSelectionModel().addListSelectionListener(this); - _tiletable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - updateTileTable(); - - // wrap the table in a scrollpane for lengthy tilesets - _scroller = new SafeScrollPane(_tiletable); - _scroller.setVerticalScrollBarPolicy( - SafeScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - - // add the tile table as the entire east side - setRightComponent(_scroller); - - // add the tilesets and select the starting tile set - updateTileSetTree(); - - // The damn splitpane freaks out unless we do this - setDividerLocation(230); - } - - /** - * Register key listeners to do things with the quick list. - */ - protected void registerKeyListener (EditorContext ctx) - { - ctx.getKeyDispatcher().addGlobalKeyListener(new KeyAdapter() { - public void keyTyped (KeyEvent e) - { - char keychar = e.getKeyChar(); - if ((keychar < '0') || (keychar > '9')) { - return; - } - - // turn 1 into 0, and 0 into 9 - int index = (keychar - '0' + 9) % 10; - if (e.isControlDown() || e.isAltDown()) { - // add - if (_curTrec == null) { - return; - } - _quickList.clearSelection(); - DefaultListModel model = - (DefaultListModel) _quickList.getModel(); - int olddex = model.indexOf(_curTrec); - if (olddex != -1) { - model.set(olddex, ""); - } - model.set(index, _curTrec); - _quickList.setSelectedIndex(index); - - } else { - // select - _quickList.setSelectedIndex(index); - } - } - }); - } - - /** - * Selects the previous tile in the list of available tiles. - */ - public void selectPreviousTile () - { - int row = _tiletable.getSelectedRow(); - if (--row >= 0) { - _tiletable.setRowSelectionInterval(row, row); - } - } - - /** - * Selects the next tile in the list of available tiles. - */ - public void selectNextTile () - { - int row = _tiletable.getSelectedRow(); - if (++row < _tiletable.getRowCount()) { - _tiletable.setRowSelectionInterval(row, row); - } - } - - // documentation inherited - public Dimension getPreferredSize () - { - return new Dimension(WIDTH, HEIGHT); - } - - /** - * Display the tiles in a tileset when it is selected. - */ - public void valueChanged (TreeSelectionEvent e) - { - DefaultMutableTreeNode node = - (DefaultMutableTreeNode) _tsettree.getLastSelectedPathComponent(); - - // we only care when a leaf is selected - if ((node != null) && (node.isLeaf())) { - - _selected = node; - - Object uobj = node.getUserObject(); - if (!(uobj instanceof TileSetRecord)) { - Log.info("Eh? Non-TileSetRecord leaf [obj=" + uobj + - ", class=" + StringUtil.shortClassName(uobj) + "]."); - return; - } - - tileSetSelected((TileSetRecord) uobj); - _quickList.clearSelection(); - } - } - - /** - * Called when a tileset is selected, either via the tree - * or the recent list. - */ - protected void tileSetSelected (TileSetRecord trec) - { - // if they've selected something new, update our tile display - if (_model.getTileSet() != trec.tileSet) { - _curTrec = trec; - _model.setLayerIndex(trec.layer); - - // update the model to reflect new tile set and select tile - // zero by default - _model.setTile(trec.tileSet, trec.tileSetId, 0); - - // update the tile table to reflect the new tileset - updateTileTable(); - -// _quickList.removeListSelectionListener(this); -// // add it to the recent list -// DefaultListModel recentModel = (DefaultListModel) -// _quickList.getModel(); -// recentModel.removeElement(trec); -// recentModel.add(0, trec); -// _quickList.setSelectedIndex(0); -// _quickList.addListSelectionListener(this); - } - } - - /** - * Remove previous test tiles and insert the new batch. - */ - protected void insertTestTiles (HashIntMap tests) - { - // trim the tilesets back to remove any previous test tiles - for (int ii=0; ii < 2; ii++) { - for (int jj=_layerSets[ii].size() - 1; jj >= _layerLengths[ii]; - jj--) { - _layerSets[ii].remove(jj); - } - } - - // insert the new test tiles - Iterator iter = tests.keys(); - while (iter.hasNext()) { - Integer tsid = (Integer) iter.next(); - - TileSet set = (TileSet) tests.get(tsid); - - // determine which layer to which this tileset applies - int lidx = TileSetUtil.getLayerIndex(set); - if (lidx != -1) { - // make up a negative number to refer to this temporary tileset - _layerSets[lidx].add( - new TileSetRecord(lidx, tsid.intValue(), set)); - } - } - - updateTileSetTree(); - } - - /** - * The layer has changed, update the tree to reflect the tilesets - * now available. - */ - public void updateTileSetTree () - { - // first clear out the tree - DefaultTreeModel model = (DefaultTreeModel) _tsettree.getModel(); - DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); - root.removeAllChildren(); - - ArrayList expand = new ArrayList(); - - // add all the elements in the base layer - DefaultMutableTreeNode base = new DefaultMutableTreeNode("Base Layer"); - root.add(base); - addNodes(base, getSortedTileSets(EditorModel.BASE_LAYER), - "", 0, expand); - - // add all the elements in the object layer - DefaultMutableTreeNode obj = new DefaultMutableTreeNode("Object Layer"); - root.add(obj); - addNodes(obj, getSortedTileSets(EditorModel.OBJECT_LAYER), - "", 0, expand); - - // notify the JTree that we've put some brand new branches on it. - model.reload(); - - // expand our container categories - for (Iterator iter = expand.iterator(); iter.hasNext(); ) { - _tsettree.expandPath((TreePath)iter.next()); - } - - // now select the previously selected item, or the first... - if (_selected == null) { - _selected = (DefaultMutableTreeNode) root.getFirstLeaf(); - } - _tsettree.setSelectionPath(new TreePath(_selected.getPath())); - } - - /** - * Populate the tree with the available tilesets for the selected layer. - */ - protected TileSetRecord[] getSortedTileSets (int layer) - { - // get the list of tilesets we now want to show - ArrayList sets = _layerSets[layer]; - - // we don't want to sort the actual array since we have - // kept the test tiles at the end - TileSetRecord[] sorted = new TileSetRecord[sets.size()]; - sets.toArray(sorted); - QuickSort.sort(sorted); - - return sorted; - } - - /** - * Recursively add tilesets to the tree. - * - * @param prefix The portion of the full tileset name that we've - * already parsed, it corresponds to the node we're adding to. - * @param position The position in the array from whence to start adding. - * @return the number of elements added to 'node' from 'list'. - */ - protected int addNodes (DefaultMutableTreeNode node, - TileSetRecord[] list, String prefix, int position, - ArrayList expand) - { - int prefixlen = prefix.length(); - - for (int ii = position; ii < list.length; ) { - String name = list[ii].fullname(); - - // if the next name on the list doesn't start with the prefix, - // we have no business adding it to this node. - if (!name.startsWith(prefix)) { - return ii - position; - } - - // is there another category name? - int dex = name.indexOf('/', prefixlen); - if (dex == -1) { - // nope, just add this item to the node. - DefaultMutableTreeNode item = new DefaultMutableTreeNode( - list[ii]); - node.add(item); - - // oh, we're so sneaky! - // if the item we're adding has the same TileSetRecord - // as the previously selected item, we're going to want to - // select it.. - if ((_selected != null) && - (list[ii].equals(_selected.getUserObject()))) { - _selected = item; - } - - ii++; - - } else { - // new category! - String catname = name.substring(prefixlen, dex); - DefaultMutableTreeNode category = - new DefaultMutableTreeNode(catname); - node.add(category); - - // if we have further categories below, start expanded - if (name.indexOf('/', dex+1) != -1) { - expand.add(new TreePath(category.getPath())); - } - - // recurse.. - ii += addNodes(category, list, name.substring(0, dex + 1), - ii, expand); - } - } - - return list.length - position; - } - - /** - * Update the tile table to reflect the currently selected tile set. - */ - protected void updateTileTable () - { - // get the table width before we update the table model since - // updating the model seems to reset the table width to an - // incorrect default - TableColumn tcol = _tiletable.getColumnModel().getColumn(0); - _tablewid = tcol.getWidth() - (2 * EDGE_TILE_H); - - // clear out the old selection because we're going to change - // tilesets - _tiletable.clearSelection(); - - // update the table model with the new tile set tiles - _tablemodel.updateTileSet(); - - // if there are no tiles in the current tile set, we're done - if (!_model.isTileValid()) { - return; - } - - // set row heights to match the scaled tile image heights - int numTiles = getTileCount(); - TileSet set = _model.getTileSet(); - for (int ii = 0; ii < numTiles; ii++) { - Image img = set.getRawTileImage(ii); - int hei = getScaledTileImageHeight(img); - _tiletable.setRowHeight(ii, hei + (2 * EDGE_TILE_V)); - } - - // select the selected tile - int tid = _model.getTileId(); - _tiletable.setRowSelectionInterval(tid, tid); - - if (_scroller != null) { - // scroll to the selected tile - Rectangle r = _tiletable.getCellRect(tid, 0, true); - _scroller.getViewport().setViewPosition(new Point(r.x, r.y)); - } - } - - /** - * Handle tile table selections. - */ - public void valueChanged (ListSelectionEvent e) - { - // ignore extra messages - if (e.getValueIsAdjusting()) { - return; - } - - Object src = e.getSource(); - if (src == _quickList) { - Object o = _quickList.getSelectedValue(); - if (o instanceof TileSetRecord) { - tileSetSelected((TileSetRecord) o); - if (o != _selected.getUserObject()) { - _tsettree.clearSelection(); - } - } - } else { - // otherwise they clicked on the tile table. - ListSelectionModel lsm = (ListSelectionModel) src; - if (!lsm.isSelectionEmpty()) { - _model.setTileId(lsm.getMinSelectionIndex()); - } - } - } - - /** - * Returns the number of tiles in the currently selected tileset. - */ - protected int getTileCount () - { - if (!_model.isTileValid()) { - return 0; - - } else { - TileSet set = _model.getTileSet(); - return (set == null) ? 0 : set.getTileCount(); - } - } - - /** - * Returns the height of the given tile image after scaling to fit - * within the width of the tile table. - */ - protected int getScaledTileImageHeight (Image img) - { - int wid = img.getWidth(null), hei = img.getHeight(null); - if (wid > _tablewid) { - float frac = (float)wid / (float)_tablewid; - return (int)(hei / frac); - } - - return hei; - } - - /** - * Extends the {@link AbstractTableModel} to encapsulate the table - * layout and display options required when displaying the tiles in - * the currently selected tileset. - */ - protected class TileTableModel extends AbstractTableModel - { - /** - * Called when the tile set associated with the table has been - * changed. Clears the cached image icons used to display each - * cell and updates the number of rows in the table to properly - * deal with tile sets of varying sizes. - */ - public synchronized void updateTileSet () - { - int numTiles = getTileCount(); - _icons = new ImageIcon[numTiles]; - fireTableRowsInserted(0, numTiles); - } - - // documentation inherited - public int getColumnCount () - { - return 1; - } - - // documentation inherited - public String getColumnName (int columnIndex) - { - return null; - } - - // documentation inherited - public int getRowCount () - { - return getTileCount(); - } - - // documentation inherited - public Object getValueAt (int row, int col) - { - // return the icon immediately if it's already cached - if (_icons[row] != null) { - return _icons[row]; - } - - // generate and save off the tile image scaled to fit the table - TileSet set = _model.getTileSet(); - Image img = set.getRawTileImage(row); - int hei = getScaledTileImageHeight(img); - - if (hei != img.getHeight(null)) { - img = img.getScaledInstance( - _tablewid, hei, Image.SCALE_SMOOTH); - } - - return (_icons[row] = new ImageIcon(img)); - } - - // documentation inherited - public Class getColumnClass (int c) - { - // return the object associated with the column to force - // rendering of our icon images rather than straight text - return getValueAt(0, c).getClass(); - } - - /** The image icons used to display the table cell contents. */ - protected ImageIcon _icons[]; - } - - /** - * Used to manage tilesets in the tileset selection combobox. - */ - protected static class TileSetRecord implements Comparable - { - public int layer; - public int tileSetId; - public TileSet tileSet; - public String shortname; - - public TileSetRecord (int layer, int tileSetId, TileSet tileSet) - { - this.layer = layer; - this.tileSetId = tileSetId; - this.tileSet = tileSet; - - shortname = fullname(); - - // cut everything before the last slash for our shortname - int lastdex = shortname.lastIndexOf('/'); - if (lastdex != -1) { - shortname = shortname.substring(lastdex + 1); - } - } - - public String fullname () - { - return tileSet.getName(); - } - - public String toString () - { - return shortname; - } - - public int compareTo (Object o) - { - return fullname().compareToIgnoreCase( - ((TileSetRecord) o).fullname()); - } - - public boolean equals (Object o) - { - if (o instanceof TileSetRecord) { - TileSetRecord tsr = (TileSetRecord) o; - return ((tsr.layer == layer) && (tsr.tileSetId == tileSetId)); - } - return false; - } - } - - /** Default desired panel dimensions. */ - protected static final int WIDTH = 400; - protected static final int HEIGHT = 300; - - /** Buffer space surrounding each tile in the tile table. */ - protected static final int EDGE_TILE_H = 4; - protected static final int EDGE_TILE_V = 4; - - /** An ArrayList of TileSetRecords for each layer. */ - protected ArrayList[] _layerSets; - - /** The original number of TileSetRecords for each layer. */ - protected int[] _layerLengths; - - /** The tree listing available tilesets. */ - protected JTree _tsettree; - - /** The selected tree node. */ - protected DefaultMutableTreeNode _selected; - - /** The table listing all tiles in the selected tileset. */ - protected JTable _tiletable; - - /** The list of quickly-selectable tilesets. */ - protected JList _quickList; - - /** The currently selected tileset record. */ - protected TileSetRecord _curTrec; - - /** The width of the tile table column in pixels. */ - protected int _tablewid; - - /** The scroll pane containing the tile table. */ - protected SafeScrollPane _scroller; - - /** The editor model. */ - protected EditorModel _model; - - /** The tile table data model. */ - protected TileTableModel _tablemodel; -} diff --git a/src/java/com/threerings/stage/tools/editor/util/EditorContext.java b/src/java/com/threerings/stage/tools/editor/util/EditorContext.java deleted file mode 100644 index e19de94f3..000000000 --- a/src/java/com/threerings/stage/tools/editor/util/EditorContext.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// $Id: EditorContext.java 7429 2003-04-01 02:19:34Z mdb $ - -package com.threerings.stage.tools.editor.util; - -import java.util.List; - -import com.threerings.media.image.ColorPository; -import com.threerings.media.tile.TileSetRepository; - -import com.threerings.stage.util.StageContext; - -public interface EditorContext extends StageContext -{ - /** - * Return a reference to the tile set repository in use by the tile - * manager. This reference is valid for the lifetime of the - * application. - */ - public TileSetRepository getTileSetRepository (); - - /** - * Returns a colorization repository for use by the editor. - */ - public ColorPository getColorPository (); - - /** - * Inserts all known scene types into the supplied list. - */ - public void enumerateSceneTypes (List types); -} diff --git a/src/java/com/threerings/stage/tools/editor/util/EditorDialogUtil.java b/src/java/com/threerings/stage/tools/editor/util/EditorDialogUtil.java deleted file mode 100644 index beb35d43a..000000000 --- a/src/java/com/threerings/stage/tools/editor/util/EditorDialogUtil.java +++ /dev/null @@ -1,100 +0,0 @@ -// -// $Id: EditorDialogUtil.java 9223 2003-05-27 02:35:00Z mdb $ - -package com.threerings.stage.tools.editor.util; - -import java.awt.Container; -import java.awt.Dimension; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JInternalFrame; -import javax.swing.JLayeredPane; - -import com.threerings.util.DirectionUtil; - -public class EditorDialogUtil -{ - /** - * Add a button to a container with the given parameters and - * action listener. - * - * @param l the listener. - * @param container the container. - * @param name the button name. - * @param cmd the action command. - */ - public static void addButton (ActionListener l, Container container, - String name, String cmd) - { - JButton button = new JButton(name); - button.addActionListener(l); - button.setActionCommand(cmd); - container.add(button); - } - - /** - * Create and return a combo box seeded with the various possible - * orientation direction names. - * - * @param l the listener. - * - * @return the combo box. - */ - public static JComboBox getOrientationComboBox (ActionListener l) - { - JComboBox box = new JComboBox(DirectionUtil.getDirectionNames()); - box.addActionListener(l); - box.setActionCommand("orient"); - return box; - } - - /** - * Centers the supplied dialog in its parent's bounds. - */ - public static void center (JFrame parent, JInternalFrame dialog) - { - Dimension psize = parent.getSize(); - Dimension dsize = dialog.getSize(); - dialog.setLocation((psize.width-dsize.width)/2, - (psize.height-dsize.height)/2); - } - - /** - * Display a dialog centered within the given frame. - * - * @param parent the parent frame. - * @param dialog the dialog. - */ - public static void display (JFrame parent, JInternalFrame dialog) - { - center(parent, dialog); - parent.getLayeredPane().add(dialog, JLayeredPane.POPUP_LAYER); - dialog.setVisible(true); - } - - /** - * Removes the supplied dialog from its parent container, but does not - * dispose it. - */ - public static void dismiss (JInternalFrame dialog) - { - Container parent = dialog.getParent(); - if (parent != null) { - parent.remove(dialog); - parent.repaint(); - } - dialog.setVisible(false); - } - - /** - * Handles safely dismissing and disposing of the supplied dialog. - */ - public static void dispose (JInternalFrame dialog) - { - dismiss(dialog); - dialog.dispose(); - } -} diff --git a/src/java/com/threerings/stage/tools/editor/util/ExtrasPainter.java b/src/java/com/threerings/stage/tools/editor/util/ExtrasPainter.java deleted file mode 100644 index ffcc4eb35..000000000 --- a/src/java/com/threerings/stage/tools/editor/util/ExtrasPainter.java +++ /dev/null @@ -1,14 +0,0 @@ -// -// $Id: ExtrasPainter.java 7998 2003-04-18 18:34:41Z mdb $ - -package com.threerings.stage.tools.editor.util; - -import java.awt.Graphics2D; - -/** - * An interface for painting extra stuff. - */ -public interface ExtrasPainter -{ - public void paintExtras (Graphics2D gfx); -} diff --git a/src/java/com/threerings/stage/tools/editor/util/TileSetUtil.java b/src/java/com/threerings/stage/tools/editor/util/TileSetUtil.java deleted file mode 100644 index bafe1a327..000000000 --- a/src/java/com/threerings/stage/tools/editor/util/TileSetUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// $Id: TileSetUtil.java 9371 2003-06-02 20:28:21Z mdb $ - -package com.threerings.stage.tools.editor.util; - -import com.threerings.media.tile.TileSet; -import com.threerings.miso.tile.BaseTileSet; - -import com.threerings.stage.tools.editor.Log; -import com.threerings.stage.tools.editor.EditorModel; - -/** - * Miscellaneous useful routines for working with lists of {@link TileSet} - * and {@link BaseTileSet} objects. - */ -public class TileSetUtil -{ - /** - * Returns the layer index of the layer for which this tileset - * provides tiles. - */ - public static int getLayerIndex (TileSet set) - { - if (set instanceof BaseTileSet) { - return EditorModel.BASE_LAYER; - } else { - return EditorModel.OBJECT_LAYER; - } - } -} diff --git a/src/java/com/threerings/stage/tools/viewer/ViewerApp.java b/src/java/com/threerings/stage/tools/viewer/ViewerApp.java deleted file mode 100644 index e8b11e826..000000000 --- a/src/java/com/threerings/stage/tools/viewer/ViewerApp.java +++ /dev/null @@ -1,215 +0,0 @@ -// -// $Id: ViewerApp.java 19661 2005-03-09 02:40:29Z andrzej $ - -package com.threerings.stage.tools.viewer; - -import java.awt.DisplayMode; -import java.awt.EventQueue; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; - -import java.io.File; -import java.io.IOException; - -import com.samskivert.swing.RuntimeAdjust; -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.resource.ResourceManager; -import com.threerings.util.KeyDispatcher; -import com.threerings.util.KeyboardManager; -import com.threerings.util.MessageManager; - -import com.threerings.media.FrameManager; -import com.threerings.media.IconManager; -import com.threerings.media.image.ColorPository; -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.cast.ComponentRepository; - -import com.threerings.miso.tile.MisoTileManager; - -import com.threerings.stage.Log; -import com.threerings.stage.util.StageContext; - -/** - * The ViewerApp is a scene viewing application that allows for trying out - * Stage scenes in a pseudo-runtime environment. - */ -public class ViewerApp -{ - /** - * Construct and initialize the ViewerApp object. - */ - public ViewerApp (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() + "]."); - - _rmgr = new ResourceManager("rsrc"); - _rmgr.initBundles(null, "config/resource/manager.properties", null); - _imgr = new ImageManager(_rmgr, _frame); - _tilemgr = new MisoTileManager(_rmgr, _imgr); - _tilemgr.setTileSetRepository( - new BundledTileSetRepository(_rmgr, _imgr, "tilesets")); - _colpos = ColorPository.loadColorPository(_rmgr); - _crepo = new BundledComponentRepository(_rmgr, _imgr, "components"); - _mesgmgr = new MessageManager("rsrc.i18n"); - - _frame = new ViewerFrame(gc); - _framemgr = FrameManager.newInstance(_frame, _frame); - - StageContext ctx = new ContextImpl(); - _frame.init(ctx, new CharacterManager(_imgr, _crepo)); - - // grab our argument - _target = (args.length > 0) ? args[0] : null; - - // size and position the window, entering full-screen exclusive - // mode if available and desired - if (gd.isFullScreenSupported() /* && _viewFullScreen.getValue() */) { - Log.info("Entering full-screen exclusive mode."); - gd.setFullScreenWindow(_frame); - } else { - _frame.setSize(640, 575); - SwingUtil.centerWindow(_frame); - } - } - - /** - * The implementation of the {@link StageContext} interface that - * provides handles to the config and manager objects that offer - * commonly used services. - */ - protected class ContextImpl implements StageContext - { - public FrameManager getFrameManager () { - return _framemgr; - } - - public MisoTileManager getTileManager () { - return _tilemgr; - } - - // documentation inherited from interface - public ResourceManager getResourceManager () { - return _rmgr; - } - - // documentation inherited from interface - public ImageManager getImageManager () { - return _imgr; - } - - // documentation inherited from interface - public MessageManager getMessageManager () { - return _mesgmgr; - } - - // documentation inherited from interface - public IconManager getIconManager () { - return null; - } - - // documentation inherited from interface - public KeyboardManager getKeyboardManager() { - return null; - } - - // documentation inherited from interface - public ComponentRepository getComponentRepository () { - return _crepo; - } - - // documentation inherited from interface - public ColorPository getColorPository () { - return _colpos; - } - - // documentation inherited from interface - public KeyDispatcher getKeyDispatcher () { - return null; - } - - // documentation inherited from interface - public String xlate (String message) { - return message; - } - - // documentation inherited from interface - public String xlate (String bundle, String message) { - return message; - } - } - - /** - * Run the application. - */ - public void run () - { - // show the window - _frame.setVisible(true); - _framemgr.start(); - - // load up anything specified on the command line - EventQueue.invokeLater(new Runnable() { - public void run () { - if (_target != null) { - _frame.loadScene(_target); - } else { - _frame.openScene(null); - } - } - }); - } - - /** - * 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(); - } - } - - protected ResourceManager _rmgr; - protected MisoTileManager _tilemgr; - protected ImageManager _imgr; - protected BundledComponentRepository _crepo; - protected ColorPository _colpos; - protected MessageManager _mesgmgr; - - protected FrameManager _framemgr; - protected ViewerFrame _frame; - protected String _target; - -// /** A debug hook that toggles debug rendering of traversable tiles. */ -// protected static RuntimeAdjust.BooleanAdjust _viewFullScreen = -// new RuntimeAdjust.BooleanAdjust( -// "Toggles whether or not the scene viewer uses full screen mode.", -// "stage.viewer.full_screen", ToolPrefs.config, false); -} diff --git a/src/java/com/threerings/stage/tools/viewer/ViewerFrame.java b/src/java/com/threerings/stage/tools/viewer/ViewerFrame.java deleted file mode 100644 index 0094613a1..000000000 --- a/src/java/com/threerings/stage/tools/viewer/ViewerFrame.java +++ /dev/null @@ -1,170 +0,0 @@ -// -// $Id: ViewerFrame.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.viewer; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.GraphicsConfiguration; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; - -import java.io.File; - -import javax.swing.JFileChooser; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JOptionPane; -import javax.swing.KeyStroke; -import javax.swing.filechooser.FileFilter; - -import com.samskivert.swing.util.MenuUtil; - -import com.threerings.cast.CharacterManager; -import com.threerings.media.ManagedJFrame; - -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.spot.data.Portal; -import com.threerings.whirled.spot.data.SpotSceneModel; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageScene; -import com.threerings.stage.data.StageSceneModel; -import com.threerings.stage.tools.xml.StageSceneParser; -import com.threerings.stage.util.StageContext; - -/** - * The viewer frame is the main application window. - */ -public class ViewerFrame extends ManagedJFrame -{ - /** - * Creates a frame in which the viewer application can operate. - */ - public ViewerFrame (GraphicsConfiguration gc) - { - super(gc); - - // set up the frame options - setTitle("Scene Viewer"); - setDefaultCloseOperation(EXIT_ON_CLOSE); - - // set the frame and content panel background to black - setBackground(Color.black); - getContentPane().setBackground(Color.black); - - // create the "File" menu - KeyStroke accel = null; - JMenu menuSettings = new JMenu("File"); - - // open... - accel = KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuSettings, "Open scene...", KeyEvent.VK_O, - accel, this, "openScene"); - - // decoys! - MenuUtil.addMenuItem(menuSettings, "Decoys!", this, "getJiggy"); - - // quit - menuSettings.addSeparator(); - accel = KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK); - MenuUtil.addMenuItem(menuSettings, "Quit", KeyEvent.VK_Q, - accel, this, "handleQuit"); - - // create the menu bar - JMenuBar bar = new JMenuBar(); - bar.add(menuSettings); - - // add the menu bar to the frame - setJMenuBar(bar); - } - - /** - * Instructs us to create our scene panel. - */ - public void init (StageContext ctx, CharacterManager charmgr) - { - _panel = new ViewerScenePanel(ctx, charmgr); - getContentPane().add(_panel, BorderLayout.CENTER); - } - - /** - * Callback for opening a new scene. - */ - public void openScene (ActionEvent event) - { -// String where = ToolPrefs.config.getValue( -// "viewer.last_dir", System.getProperty("user.dir")); - String where = System.getProperty("user.dir"); - JFileChooser chooser = new JFileChooser(where); - chooser.setFileFilter(new FileFilter () { - public boolean accept (File f) { - return (f.isDirectory() || f.getName().endsWith(".xml")); - } - public String getDescription () { - return "XML Files"; - } - }); - int result = chooser.showOpenDialog(this); - if (result == JFileChooser.APPROVE_OPTION) { - File filescene = chooser.getSelectedFile(); - loadScene(filescene.getPath()); -// ToolPrefs.config.setValue("viewer.last_dir", filescene.getParent()); - } - } - - public void getJiggy (ActionEvent event) - { - _panel.createDecoys(); - } - - /** - * Handles a request to get the fuck out of dodge. - */ - public void handleQuit (ActionEvent evt) - { - System.exit(0); - } - - public void loadScene (String path) - { - String errmsg = null; - - try { - StageSceneParser parser = new StageSceneParser(); - StageSceneModel model = (StageSceneModel)parser.parseScene(path); - if (model == null) { - errmsg = "No scene found in scene file '" + path + "'."; - - } else { - SpotSceneModel ssmodel = SpotSceneModel.getSceneModel(model); - Location defloc = null; - // find the default entrance to this scene - for (int ii = 0; ii < ssmodel.portals.length; ii++) { - Portal port = ssmodel.portals[ii]; - if (port.portalId == ssmodel.defaultEntranceId) { - defloc = port.getOppLocation(); - break; - } - } - if (defloc == null) { - Log.warning("Scene has no def. entrance '" + path + "'."); - } - - _panel.setScene(new StageScene(model, null), defloc); - } - - } catch (Exception e) { - errmsg = "Error parsing scene file '" + path + "'."; - Log.logStackTrace(e); - } - - if (errmsg != null) { - JOptionPane.showMessageDialog( - this, errmsg, "Load error", JOptionPane.ERROR_MESSAGE); - } - } - - protected ViewerScenePanel _panel; -} diff --git a/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java b/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java deleted file mode 100644 index cff786c2f..000000000 --- a/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java +++ /dev/null @@ -1,240 +0,0 @@ -// -// $Id: ViewerScenePanel.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.viewer; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; - -import com.samskivert.swing.Controller; -import com.samskivert.util.RandomUtil; - -import com.threerings.media.util.PerformanceMonitor; -import com.threerings.media.util.PerformanceObserver; - -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.stage.client.StageScenePanel; -import com.threerings.whirled.spot.data.Location; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageScene; -import com.threerings.stage.util.StageContext; - -public class ViewerScenePanel extends StageScenePanel - implements PerformanceObserver, PathObserver -{ - /** - * Construct the panel and initialize it with a context. - */ - public ViewerScenePanel (StageContext ctx, CharacterManager charmgr) - { - super(ctx, new Controller() { - }); - - _charmgr = charmgr; - - // create the character descriptors - _descUser = CastUtil.getRandomDescriptor( - "female", ctx.getComponentRepository()); - _descDecoy = CastUtil.getRandomDescriptor( - "male", ctx.getComponentRepository()); - - // create the manipulable sprite - _sprite = createSprite(_descUser); - setFollowsPathable(_sprite, CENTER_ON_PATHABLE); - - PerformanceMonitor.register(this, "paint", 1000); - } - - // documentation inherited - public void setScene (StageScene scene, Location defloc) - { - setScene(scene); - - // move all of our sprites to the default entrance - _defloc = (StageLocation) defloc; - Point defpos = getScreenCoords(_defloc.x, _defloc.y); - _sprite.setLocation(defpos.x, defpos.y); - - if (_decoys != null) { - for (int ii = 0; ii < _decoys.length; ii++) { - _decoys[ii].setLocation(defpos.x, defpos.y); - } - createDecoyPaths(); - } - } - - /** - * Creates a new sprite. - */ - protected CharacterSprite createSprite (CharacterDescriptor desc) - { - CharacterSprite s = _charmgr.getCharacter(desc); - if (s != null) { - // start 'em out standing - s.setActionSequence(CharacterSprite.STANDING); - if (_defloc != null) { - Point defpos = getScreenCoords(_defloc.x, _defloc.y); - s.setLocation(defpos.x, defpos.y); - } else { - s.setLocation(300, 300); - } - s.addSpriteObserver(this); - _spritemgr.addSprite(s); - } - - return s; - } - - /** - * Creates the decoy sprites. - */ - public void createDecoys () - { - int decoys = DEFAULT_NUM_DECOYS; - try { - decoys = Integer.parseInt(System.getProperty("decoys")); - } catch (Exception e) { - } - - if (_decoys == null) { - _decoys = new CharacterSprite[decoys]; - for (int ii = 0; ii < decoys; ii++) { - _decoys[ii] = createSprite(_descDecoy); - } - } - - // if we have a scene, create paths for our decoys - createDecoyPaths(); - } - - /** - * Creates paths for the decoy sprites. - */ - protected void createDecoyPaths () - { - if (_decoys != null) { - for (int ii = 0; ii < _decoys.length; 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 + "]."); - } - - /** MouseListener interface methods */ - public void mousePressed (MouseEvent e) - { - int x = e.getX(), y = e.getY(); - - switch (e.getModifiers()) { - case MouseEvent.BUTTON1_MASK: - createPath(_sprite, x, y); - break; - - case MouseEvent.BUTTON2_MASK: - if (_decoys != null) { - for (int ii = 0; ii < _decoys.length; 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, false); - 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) - { - int x, y; - do { - x = _vbounds.x + RandomUtil.getInt(_vbounds.width); - y = _vbounds.y + RandomUtil.getInt(_vbounds.height); - } while (!createPath(s, x, y)); - } - - // documentation inherited from interface - public void pathCancelled (Sprite sprite, Path path) - { - // nothing doing - } - - // documentation inherited from interface - public void pathCompleted (Sprite sprite, Path path, long when) - { - if (sprite != _sprite) { - // move the decoy to a new random location - createRandomPath((CharacterSprite)sprite); - } - } - - /** The number of decoy characters milling about. */ - protected static final int DEFAULT_NUM_DECOYS = 10; - - /** The current scene's default entrance. */ - protected StageLocation _defloc; - - /** Provides character sprite data. */ - protected CharacterManager _charmgr; - - /** 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/src/java/com/threerings/stage/tools/xml/StageMisoSceneRuleSet.java b/src/java/com/threerings/stage/tools/xml/StageMisoSceneRuleSet.java deleted file mode 100644 index 8c3c0c0ee..000000000 --- a/src/java/com/threerings/stage/tools/xml/StageMisoSceneRuleSet.java +++ /dev/null @@ -1,21 +0,0 @@ -// -// $Id: StageMisoSceneRuleSet.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.xml; - -import com.threerings.miso.data.SparseMisoSceneModel; -import com.threerings.miso.tools.xml.SparseMisoSceneRuleSet; - -import com.threerings.stage.data.StageMisoSceneModel; - -/** - * Customizes the miso scene rule set such that it creates {@link - * StageMisoSceneModel} instances. - */ -public class StageMisoSceneRuleSet extends SparseMisoSceneRuleSet -{ - protected SparseMisoSceneModel createMisoSceneModel () - { - return new StageMisoSceneModel(); - } -} diff --git a/src/java/com/threerings/stage/tools/xml/StageSceneParser.java b/src/java/com/threerings/stage/tools/xml/StageSceneParser.java deleted file mode 100644 index 54fed8262..000000000 --- a/src/java/com/threerings/stage/tools/xml/StageSceneParser.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $Id: StageSceneParser.java 16546 2004-07-27 20:49:56Z ray $ - -package com.threerings.stage.tools.xml; - -import org.apache.commons.digester.Rule; - -import org.xml.sax.Attributes; - -import com.threerings.whirled.spot.tools.xml.SpotSceneRuleSet; -import com.threerings.whirled.tools.xml.SceneParser; -import com.threerings.whirled.tools.xml.SceneRuleSet; - -import com.threerings.whirled.spot.data.Location; - -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageSceneModel; - -/** - * Parses {@link StageSceneModel} instances from an XML description file. - */ -public class StageSceneParser extends SceneParser -{ - /** - * Constructs a parser that can be used to parse Stage scene models. - */ - public StageSceneParser () - { - super(""); - - // add a rule to parse scene colorizations - _digester.addRule("scene/zations/zation", new Rule() { - public void begin (String namespace, String name, - Attributes attrs) throws Exception { - StageSceneModel yoscene = (StageSceneModel) digester.peek(); - int classId = Integer.parseInt(attrs.getValue("classId")); - int colorId = Integer.parseInt(attrs.getValue("colorId")); - yoscene.setDefaultColor(classId, colorId); - } - }); - - // add rule sets for our aux scene models - registerAuxRuleSet(new SpotSceneRuleSet() { - protected Location createLocation () { - return new StageLocation(); - } - }); - registerAuxRuleSet(new StageMisoSceneRuleSet()); - } - - // documentation inherited from interface - protected SceneRuleSet createSceneRuleSet () - { - return new StageSceneRuleSet(); - } - - /** - * A simple hook for parsing a single scene from the command line. - */ - public static void main (String[] args) - { - if (args.length < 1) { - System.err.println("Usage: StageSceneParser scene.xml"); - System.exit(-1); - } - - try { - System.out.println( - "Parsed " + new StageSceneParser().parseScene(args[0])); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } -} diff --git a/src/java/com/threerings/stage/tools/xml/StageSceneRuleSet.java b/src/java/com/threerings/stage/tools/xml/StageSceneRuleSet.java deleted file mode 100644 index 965cd7e81..000000000 --- a/src/java/com/threerings/stage/tools/xml/StageSceneRuleSet.java +++ /dev/null @@ -1,21 +0,0 @@ -// -// $Id: StageSceneRuleSet.java 6370 2003-02-12 07:32:00Z mdb $ - -package com.threerings.stage.tools.xml; - -import com.threerings.whirled.tools.xml.SceneRuleSet; - -import com.threerings.stage.data.StageScene; -import com.threerings.stage.data.StageSceneModel; - -/** - * Used to parse an {@link StageScene} from XML. - */ -public class StageSceneRuleSet extends SceneRuleSet -{ - // documentation inherited - protected Class getSceneClass () - { - return StageSceneModel.class; - } -} diff --git a/src/java/com/threerings/stage/tools/xml/StageSceneWriter.java b/src/java/com/threerings/stage/tools/xml/StageSceneWriter.java deleted file mode 100644 index be74e5347..000000000 --- a/src/java/com/threerings/stage/tools/xml/StageSceneWriter.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $Id: StageSceneWriter.java 20143 2005-03-30 01:12:48Z mdb $ - -package com.threerings.stage.tools.xml; - -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -import com.megginson.sax.DataWriter; - -import com.threerings.miso.tools.xml.SparseMisoSceneWriter; - -import com.threerings.whirled.spot.data.SpotSceneModel; -import com.threerings.whirled.spot.tools.xml.SpotSceneWriter; - -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.tools.xml.SceneWriter; - -import com.threerings.stage.data.StageMisoSceneModel; - -import com.threerings.stage.data.StageSceneModel; - -/** - * Generates an XML representation of a {@link StageSceneModel}. - */ -public class StageSceneWriter extends SceneWriter -{ - public StageSceneWriter () - { - // register our auxiliary model writers - registerAuxWriter(SpotSceneModel.class, new SpotSceneWriter()); - registerAuxWriter(StageMisoSceneModel.class, - new SparseMisoSceneWriter()); - } - - // documentation inherited - protected void addSceneAttributes (SceneModel scene, AttributesImpl attrs) - { - super.addSceneAttributes(scene, attrs); - StageSceneModel sscene = (StageSceneModel)scene; - attrs.addAttribute("", "type", "", "", sscene.type); - } - - // documentation inherited - protected void writeSceneData (SceneModel scene, DataWriter writer) - throws SAXException - { - // write out any default colorizations - StageSceneModel sscene = (StageSceneModel)scene; - if (sscene.defaultColors != null) { - writer.startElement("zations"); - int[] keys = sscene.defaultColors.getKeys(); - for (int ii=0, nn=keys.length; ii < nn; ii++) { - int value = sscene.defaultColors.get(keys[ii]); - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "classId", "", "", - String.valueOf(keys[ii])); - attrs.addAttribute("", "colorId", "", "", - String.valueOf(value)); - writer.emptyElement("", "zation", "", attrs); - } - writer.endElement("zations"); - } - - super.writeSceneData(scene, writer); - } -} diff --git a/src/java/com/threerings/stage/util/PlacementConstraints.java b/src/java/com/threerings/stage/util/PlacementConstraints.java deleted file mode 100644 index 8e6115285..000000000 --- a/src/java/com/threerings/stage/util/PlacementConstraints.java +++ /dev/null @@ -1,559 +0,0 @@ -// -// $Id: YoSceneUtil.java 19769 2005-03-17 07:38:31Z mdb $ - -package com.threerings.stage.util; - -import java.awt.Rectangle; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; - -import com.samskivert.util.ListUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; -import com.threerings.util.MessageBundle; - -import com.threerings.media.tile.ObjectTile; -import com.threerings.media.tile.ObjectTileSet; -import com.threerings.media.tile.TileManager; - -import com.threerings.miso.data.ObjectInfo; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageCodes; -import com.threerings.stage.data.StageMisoSceneModel; -import com.threerings.stage.data.StageScene; - -/** - * Maintains extra information on objects in a scene and checks proposed - * placement operations for constraint violations. When the constraints - * object is in use, all placement operations (object additions and removals) - * must go through the constraints object so that the object's internal state - * remains consistent. - */ -public class PlacementConstraints - implements DirectionCodes, StageCodes -{ - /** - * Default constructor. - */ - public PlacementConstraints (TileManager tilemgr, StageScene scene) - { - _tilemgr = tilemgr; - _scene = scene; - _mmodel = StageMisoSceneModel.getSceneModel(scene.getSceneModel()); - - // add all the objects in the scene - StageMisoSceneModel.ObjectVisitor visitor = - new StageMisoSceneModel.ObjectVisitor() { - public void visit (ObjectInfo info) { - ObjectData data = createObjectData(info); - if (data != null) { - // clone the map key, as the visit method reuses a - // single ObjectInfo instance for uninteresting objects - // in a section - _objectData.put((ObjectInfo)info.clone(), data); - } - } - }; - _mmodel.visitObjects(visitor); - } - - /** - * Determines whether the constraints allow the specified object to be - * added to the scene. - * - * @return null if the constraints allow the operation, - * otherwise a translatable string explaining why the object can't be - * added - */ - public String allowAddObject (ObjectInfo info) - { - return allowModifyObjects(new ObjectInfo[] { info }, - new ObjectInfo[0]); - } - - /** - * Adds the specified object through the constraints. - */ - public void addObject (ObjectInfo info) - { - ObjectData data = createObjectData(info); - if (data != null) { - _scene.addObject(info); - _objectData.put(info, data); - } - } - - /** - * Determines whether the constraints allow the specified object to be - * removed from the scene. - * - * @return null if the constraints allow the operation, - * otherwise a translatable string explaining why the object can't be - * removed - */ - public String allowRemoveObject (ObjectInfo info) - { - return allowModifyObjects(new ObjectInfo[0], - new ObjectInfo[] { info }); - } - - /** - * Removes the specified object through the constraints. - */ - public void removeObject (ObjectInfo info) - { - _scene.removeObject(info); - _objectData.remove(info); - } - - /** - * Determines whether the constraints allow the specified objects to be - * added and removed simultaneously. - * - * @return null if the constraints allow the operation, - * otherwise a translatable string explaining why the objects can't be - * modified - */ - public String allowModifyObjects (ObjectInfo[] added, - ObjectInfo[] removed) - { - ObjectData[] addedData = new ObjectData[added.length]; - for (int i = 0; i < added.length; i++) { - addedData[i] = createObjectData(added[i]); - if (addedData[i] == null) { - return INTERNAL_ERROR; - } - } - - ObjectData[] removedData = getObjectDataFromInfo(removed); - if (removedData == null) { - return INTERNAL_ERROR; - } - - return allowModifyObjects(addedData, removedData); - } - - /** - * Returns an ObjectData array that corresponds to the supplied - * ObjectInfo array. Returns null on error. - */ - protected ObjectData[] getObjectDataFromInfo (ObjectInfo[] info) - { - if (info == null) { - return null; - } - ObjectData[] data = new ObjectData[info.length]; - for (int ii = 0; ii < info.length; ii++) { - data[ii] = (ObjectData)_objectData.get(info[ii]); - if (data[ii] == null) { - Log.warning("Couldn't match object info up to data [info=" + - info[ii] + "]."); - return null; - } - } - return data; - } - - /** - * Determines whether the constraints allow the specified objects to be - * added and removed simultaneously. Subclasses that wish to define - * additional constraints should override this method. - * - * @return null if the constraints allow the operation, - * otherwise a qualified translatable string explaining why the objects - * can't be modified - */ - protected String allowModifyObjects (ObjectData[] added, - ObjectData[] removed) - { - DirectionHeight dirheight = new DirectionHeight(); - - for (int i = 0; i < added.length; i++) { - if (added[i].tile.hasConstraint(ObjectTileSet.ON_SURFACE) && - !isOnSurface(added[i], added, removed)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.not_on_surface"); - } - - int dir = getConstraintDirection(added[i], ObjectTileSet.ON_WALL); - if (dir != NONE && !isOnWall(added[i], added, removed, dir)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.not_on_wall"); - } - - if (getConstraintDirectionHeight(added[i], ObjectTileSet.ATTACH, - dirheight) && !isAttached(added[i], added, removed, - dirheight.dir, dirheight.low)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.not_attached"); - } - - dir = getConstraintDirection(added[i], ObjectTileSet.SPACE); - if (dir != NONE && !hasSpace(added[i], added, removed, dir)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.no_space"); - } - - if (hasSpaceConstrainedAdjacent(added[i], added, removed)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.no_space_adj"); - } - } - - for (int i = 0; i < removed.length; i++) { - if (removed[i].tile.hasConstraint(ObjectTileSet.SURFACE) && - hasOnSurface(removed[i], added, removed)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.has_on_surface"); - } - - int dir = getConstraintDirection(removed[i], ObjectTileSet.WALL); - if (dir != NONE) { - if (hasOnWall(removed[i], added, removed, dir)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.has_on_wall"); - - } else if (hasAttached(removed[i], added, removed, dir)) { - return MessageBundle.qualify(STAGE_MESSAGE_BUNDLE, - "m.has_attached"); - } - } - } - - return null; - } - - /** - * Determines whether the specified surface has anything on it that won't - * be held up if the surface is removed. - */ - protected boolean hasOnSurface (ObjectData data, ObjectData[] added, - ObjectData[] removed) - { - ArrayList objects = getObjectData(data.bounds, added, removed); - for (int i = 0, size = objects.size(); i < size; i++) { - ObjectData odata = (ObjectData)objects.get(i); - if (odata.tile.hasConstraint(ObjectTileSet.ON_SURFACE) && - !isOnSurface(odata, added, removed)) { - return true; - } - } - return false; - } - - /** - * Determines whether the specified wall has anything on it that won't be - * held up if the wall is removed. - */ - protected boolean hasOnWall (ObjectData data, ObjectData[] added, - ObjectData[] removed, int dir) - { - ArrayList objects = getObjectData(data.bounds, added, removed); - for (int i = 0, size = objects.size(); i < size; i++) { - ObjectData odata = (ObjectData)objects.get(i); - if (getConstraintDirection(odata, ObjectTileSet.ON_WALL) == dir && - !isOnWall(odata, added, removed, dir)) { - return true; - } - } - return false; - } - - /** - * Determines whether the specified wall has anything attached to it that - * won't be held up if the wall is removed. - */ - protected boolean hasAttached (ObjectData data, ObjectData[] added, - ObjectData[] removed, int dir) - { - DirectionHeight dirheight = new DirectionHeight(); - - ArrayList objects = getObjectData(getAdjacentEdge(data.bounds, - DirectionUtil.getOpposite(dir)), added, removed); - for (int i = 0, size = objects.size(); i < size; i++) { - ObjectData odata = (ObjectData)objects.get(i); - if (getConstraintDirectionHeight(odata, ObjectTileSet.ATTACH, - dirheight) && !isAttached(odata, added, removed, - dirheight.dir, dirheight.low)) { - return true; - } - } - return false; - } - - /** - * Verifies that the objects adjacent to the given object will still have - * their space constraints met if the object is added. - */ - protected boolean hasSpaceConstrainedAdjacent (ObjectData data, - ObjectData[] added, ObjectData[] removed) - { - Rectangle r = data.bounds; - // grow the ObjectData bounds 1 square in each direction - _constrainRect.setBounds(r.x - 1, r.y - 1, r.width + 2, r.height + 2); - - ArrayList objects = getObjectData(_constrainRect, added, removed); - for (int i = 0, size = objects.size(); i < size; i++) { - ObjectData odata = (ObjectData)objects.get(i); - int dir = getConstraintDirection(odata, ObjectTileSet.SPACE); - if (dir != NONE && !hasSpace(odata, added, removed, dir)) { - return true; - } - } - return false; - } - - /** - * Determines whether the specified object has empty space in the specified - * direction. - */ - protected boolean hasSpace (ObjectData data, ObjectData[] added, - ObjectData[] removed, int dir) - { - return getObjectData(getAdjacentEdge(data.bounds, dir), added, - removed).size() == 0; - } - - /** - * Determines whether the specified object is on a surface. - */ - protected boolean isOnSurface (ObjectData data, ObjectData[] added, - ObjectData[] removed) - { - return isCovered(data.bounds, added, removed, ObjectTileSet.SURFACE, - null); - } - - /** - * Determines whether the specified object is on a wall facing the - * specified direction. - */ - protected boolean isOnWall (ObjectData data, ObjectData[] added, - ObjectData[] removed, int dir) - { - return isCovered(data.bounds, added, removed, - getDirectionalConstraint(ObjectTileSet.WALL, dir), null); - } - - /** - * Determines whether the specified object is attached to another object in - * the specified direction and at the specified height. - */ - protected boolean isAttached (ObjectData data, ObjectData[] added, - ObjectData[] removed, int dir, boolean low) - { - return isCovered(getAdjacentEdge(data.bounds, dir), added, removed, - getDirectionalConstraint(ObjectTileSet.WALL, dir), low ? - getDirectionalConstraint(ObjectTileSet.WALL, dir, true) : null); - } - - /** - * Given a rectangle, determines whether all of the tiles within - * the rectangle intersect an object. If the constraint parameter is - * non-null, the intersected objects must have that constraint (or the - * alternate constraint, if specified). - */ - protected boolean isCovered (Rectangle rect, ObjectData[] added, - ObjectData[] removed, String constraint, String altstraint) - { - ArrayList objects = getObjectData(rect, added, removed); - for (int y = rect.y, ymax = rect.y + rect.height; y < ymax; y++) { - for (int x = rect.x, xmax = rect.x + rect.width; x < xmax; x++) { - boolean covered = false; - for (int i = 0, size = objects.size(); i < size; i++) { - ObjectData data = (ObjectData)objects.get(i); - if (data.bounds.contains(x, y) && (constraint == null || - data.tile.hasConstraint(constraint) || - (altstraint != null && - data.tile.hasConstraint(altstraint)))) { - covered = true; - break; - } - } - if (!covered) { - return false; - } - } - } - return true; - } - - /** - * Creates and returns a rectangle that covers the specified rectangle's - * adjacent edge (the squares one tile beyond the bounds) in the specified - * direction. - */ - protected Rectangle getAdjacentEdge (Rectangle rect, int dir) - { - switch (dir) { - case NORTH: - return new Rectangle(rect.x - 1, rect.y, 1, rect.height); - - case EAST: - return new Rectangle(rect.x, rect.y - 1, rect.width, 1); - - case SOUTH: - return new Rectangle(rect.x + rect.width, rect.y, 1, - rect.height); - - case WEST: - return new Rectangle(rect.x, rect.y + rect.height, - rect.width, 1); - - default: - return null; - } - } - - /** - * Returns the direction in which the specified object is constrained by - * appending "[NESW]" to the given constraint prefix. Returns - * NONE if there is no such directional constraint. - */ - protected int getConstraintDirection (ObjectData data, String prefix) - { - DirectionHeight dirheight = new DirectionHeight(); - return getConstraintDirectionHeight(data, prefix, dirheight) ? - dirheight.dir : NONE; - } - - /** - * Populates the supplied {@link DirectionHeight} object with the direction - * and height of the constraint identified by the given prefix. - * - * @return true if the object was successfully populated, false if there is - * no such constraint - */ - protected boolean getConstraintDirectionHeight (ObjectData data, - String prefix, DirectionHeight dirheight) - { - String[] constraints = data.tile.getConstraints(); - if (constraints == null) { - return false; - } - - for (int i = 0; i < constraints.length; i++) { - if (constraints[i].startsWith(prefix)) { - int fromidx = prefix.length(), - toidx = constraints[i].indexOf('_', fromidx); - dirheight.dir = DirectionUtil.fromShortString(toidx == -1 ? - constraints[i].substring(fromidx) : - constraints[i].substring(fromidx, toidx)); - dirheight.low = constraints[i].endsWith(ObjectTileSet.LOW); - return true; - } - } - return false; - } - - /** - * Given a constraint prefix and a direction, returns the directional - * constraint. - */ - protected String getDirectionalConstraint (String prefix, int dir) - { - return getDirectionalConstraint(prefix, dir, false); - } - - /** - * Given a constraint prefix, direction, and height, returns the - * directional constraint. - */ - protected String getDirectionalConstraint (String prefix, int dir, - boolean low) - { - return prefix + DirectionUtil.toShortString(dir) + - (low ? ObjectTileSet.LOW : ""); - } - - /** - * Finds all objects whose bounds intersect the given rectangle and - * returns a list containing their {@link ObjectData} elements. - * - * @param added an array of objects to add to the search - * @param removed an array of objects to exclude from the search - */ - protected ArrayList getObjectData (Rectangle rect, ObjectData[] added, - ObjectData[] removed) - { - ArrayList list = new ArrayList(); - - for (Iterator it = _objectData.values().iterator(); it.hasNext(); ) { - ObjectData data = (ObjectData)it.next(); - if (rect.intersects(data.bounds) && !ListUtil.contains(removed, - data)) { - list.add(data); - } - } - - for (int i = 0; i < added.length; i++) { - if (rect.intersects(added[i].bounds)) { - list.add(added[i]); - } - } - - return list; - } - - /** - * Using the tile manager, computes and returns the specified object's - * data. - */ - protected ObjectData createObjectData (ObjectInfo info) - { - try { - ObjectTile tile = (ObjectTile)_tilemgr.getTile(info.tileId); - Rectangle bounds = new Rectangle(info.x, info.y, tile.getBaseWidth(), - tile.getBaseHeight()); - bounds.translate(1 - bounds.width, 1 - bounds.height); - return new ObjectData(bounds, tile); - - } catch (Exception e) { - Log.warning("Error retrieving tile for object [info=" + - info + ", error=" + e + "]."); - Log.logStackTrace(e); - return null; - } - } - - /** Contains information about an object used in checking constraints. */ - protected class ObjectData - { - public Rectangle bounds; - public ObjectTile tile; - - public ObjectData (Rectangle bounds, ObjectTile tile) - { - this.bounds = bounds; - this.tile = tile; - } - } - - /** Contains the direction and height of a constraint. */ - protected class DirectionHeight - { - public int dir; - public boolean low; - } - - /** The tile manager to use for object dimensions and constraints. */ - protected TileManager _tilemgr; - - /** The scene being checked for constraints. */ - protected StageScene _scene; - - /** The Miso scene model. */ - protected StageMisoSceneModel _mmodel; - - /** For all objects in the scene, maps {@link ObjectInfo}s to - * {@link ObjectData}s. */ - protected HashMap _objectData = new HashMap(); - - /** One rectangle we'll re-use for all constraints ops. */ - protected static final Rectangle _constrainRect = new Rectangle(); -} diff --git a/src/java/com/threerings/stage/util/StageContext.java b/src/java/com/threerings/stage/util/StageContext.java deleted file mode 100644 index 725510bf7..000000000 --- a/src/java/com/threerings/stage/util/StageContext.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// $Id: BasicYoContext.java 19661 2005-03-09 02:40:29Z andrzej $ - -package com.threerings.stage.util; - -import com.threerings.resource.ResourceManager; -import com.threerings.util.KeyDispatcher; -import com.threerings.util.KeyboardManager; -import com.threerings.util.MessageManager; - -import com.threerings.media.FrameManager; -import com.threerings.media.image.ColorPository; -import com.threerings.media.image.ImageManager; - -import com.threerings.cast.CharacterManager; -import com.threerings.cast.ComponentRepository; -import com.threerings.miso.util.MisoContext; - -/** - * A context that provides for the myriad requirements of the Stage - * system. - */ -public interface StageContext - extends MisoContext -{ - /** - * Returns the frame manager driving our interface. - */ - public FrameManager getFrameManager (); - - /** - * Returns the resource manager via which all client resources are - * loaded. - */ - public ResourceManager getResourceManager (); - - /** - * Access to the image manager. - */ - public ImageManager getImageManager (); - - /** - * Provides access to the key dispatcher. - */ - public KeyDispatcher getKeyDispatcher (); - - /** - * Returns a reference to the message manager used by the client. - */ - public MessageManager getMessageManager (); - - /** - * Returns a reference to the keyboard manager. - */ - public KeyboardManager getKeyboardManager(); - - /** - * Returns the component repository in use by this client. - */ - public ComponentRepository getComponentRepository (); - - /** - * Returns a reference to the colorization repository. - */ - public ColorPository getColorPository (); - - /** - * Translates the specified message using the default bundle. - */ - public String xlate (String message); - - /** - * Translates the specified message using the specified bundle. - */ - public String xlate (String bundle, String message); -} diff --git a/src/java/com/threerings/stage/util/StageSceneUtil.java b/src/java/com/threerings/stage/util/StageSceneUtil.java deleted file mode 100644 index 79ef83e02..000000000 --- a/src/java/com/threerings/stage/util/StageSceneUtil.java +++ /dev/null @@ -1,413 +0,0 @@ -// -// $Id: YoSceneUtil.java 19769 2005-03-17 07:38:31Z mdb $ - -package com.threerings.stage.util; - -import java.awt.Point; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Comparator; - -import com.samskivert.util.SortableArrayList; -import com.samskivert.util.StringUtil; -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; - -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.TileUtil; -import com.threerings.media.tile.TrimmedObjectTileSet; -import com.threerings.media.util.AStarPathUtil; -import com.threerings.media.util.MathUtil; - -import com.threerings.miso.MisoConfig; -import com.threerings.miso.data.ObjectInfo; -import com.threerings.miso.tile.BaseTileSet; -import com.threerings.miso.util.MisoSceneMetrics; -import com.threerings.miso.util.MisoUtil; -import com.threerings.miso.util.ObjectSet; - -import com.threerings.whirled.spot.data.Cluster; -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.spot.data.SceneLocation; - -import com.threerings.stage.Log; -import com.threerings.stage.data.StageLocation; -import com.threerings.stage.data.StageMisoSceneModel; -import com.threerings.stage.data.StageSceneModel; - -/** - * Provides scene related utility functions. - */ -public class StageSceneUtil -{ - /** - * Returns the scene metrics we use to do our calculations. - */ - public static MisoSceneMetrics getMetrics () - { - return _metrics; - } - - /** - * Does the necessary jiggery pokery to figure out where the specified - * object's associated location is. - */ - public static StageLocation locationForObject ( - TileManager tilemgr, ObjectInfo info) - { - return locationForObject(tilemgr, info.tileId, info.x, info.y); - } - - /** - * Does the necessary jiggery pokery to figure out where the specified - * object's associated location is. - * - * @param tilemgr a tile manager that can be used to look up the tile - * information. - * @param tileId the fully qualified tile id of the object tile. - * @param tx the object's x tile coordinate. - * @param ty the object's y tile coordinate. - */ - public static StageLocation locationForObject ( - TileManager tilemgr, int tileId, int tx, int ty) - { - try { - int tsid = TileUtil.getTileSetId(tileId); - int tidx = TileUtil.getTileIndex(tileId); - TrimmedObjectTileSet tset = (TrimmedObjectTileSet) - tilemgr.getTileSet(tsid); - if (tset == null || tset.getSpotOrient(tidx) < 0) { - return null; - } - - Point opos = MisoUtil.tilePlusFineToFull( - _metrics, tx, ty, tset.getXSpot(tidx), tset.getYSpot(tidx), - new Point()); - -// Log.info("Computed location [set=" + tset.getName() + -// ", tidx=" + tidx + ", tx=" + tx + ", ty=" + ty + -// ", sx=" + tset.getXSpot(tidx) + -// ", sy=" + tset.getYSpot(tidx) + -// ", lx=" + opos.x + ", ly=" + opos.y + -// ", fg=" + _metrics.finegran + "]."); - return new StageLocation(opos.x, opos.y, - (byte)tset.getSpotOrient(tidx)); - - } catch (Exception e) { - Log.warning("Unable to look up object tile for scene object " + - "[tileId=" + tileId + ", error=" + e + "]."); - } - return null; - } - - /** - * Converts full coordinates to Cartesian coordinates. - */ - public static void locationToCoords (int lx, int ly, Point coords) - { - int tx = MisoUtil.fullToTile(lx), fx = MisoUtil.fullToFine(lx); - int ty = MisoUtil.fullToTile(ly), fy = MisoUtil.fullToFine(ly); - coords.x = tx*_metrics.finegran+fx; - coords.y = ty*_metrics.finegran+fy; - } - - /** - * Converts Cartesian coordinates back to full coordinates. - */ - public static void coordsToLocation (int cx, int cy, Point loc) - { - loc.x = MisoUtil.toFull(cx/_metrics.finegran, cx%_metrics.finegran); - loc.y = MisoUtil.toFull(cy/_metrics.finegran, cy%_metrics.finegran); - } - - /** - * Returns the footprint, in absolute tile coordinates, for the - * specified object with origin as specified. - */ - public static Rectangle getObjectFootprint ( - TileManager tilemgr, int tileId, int ox, int oy) - { - Rectangle foot = new Rectangle(); - getObjectFootprint(tilemgr, tileId, ox, oy, foot); - return foot; - } - - /** - * Fills in the footprint, in absolute tile coordinates, for the - * specified object with origin as specified. - * - * @return true if the object was successfully looked up and the - * footprint filled in, false if an error occurred trying to look up - * the associated object tile. - */ - public static boolean getObjectFootprint ( - TileManager tilemgr, int tileId, int ox, int oy, Rectangle foot) - { - try { - int tsid = TileUtil.getTileSetId(tileId); - int tidx = TileUtil.getTileIndex(tileId); - TrimmedObjectTileSet tset = (TrimmedObjectTileSet) - tilemgr.getTileSet(tsid); - if (tset == null) { - return false; - } - - int bwidth = tset.getBaseWidth(tidx); - int bheight = tset.getBaseHeight(tidx); - foot.setBounds(ox - bwidth + 1, oy - bheight + 1, bwidth, bheight); - return true; - - } catch (Exception e) { - Log.warning("Unable to look up object tile for scene object " + - "[tileId=" + tileId + ", error=" + e + "]."); - return false; - } - } - - /** - * Looks up the base tile set for the specified fully qualified tile - * identifier and returns true if the associated tile is passable. - */ - public static boolean isPassable (TileManager tilemgr, int tileId) - { - // non-existent tiles are not passable - if (tileId <= 0) { - return false; - } - - try { - int tsid = TileUtil.getTileSetId(tileId); - int tidx = TileUtil.getTileIndex(tileId); - BaseTileSet tset = (BaseTileSet)tilemgr.getTileSet(tsid); - return tset.getPassability()[tidx]; - - } catch (Exception e) { - Log.warning("Unable to look up base tile [tileId=" + tileId + - ", error=" + e + "]."); - return true; - } - } - - /** - * Computes a list of the valid locations in this cluster. - */ - public static ArrayList getClusterLocs (Cluster cluster) - { - ArrayList list = new ArrayList(); - - // convert our tile coordinates into a cartesian coordinate system - // with units equal to one fine coordinate in size - int fx = cluster.x*_metrics.finegran+1, - fy = cluster.y*_metrics.finegran+1; - int fwid = cluster.width*_metrics.finegran-2, - fhei = cluster.height*_metrics.finegran-2; - int cx = fx + fwid/2, cy = fy + fhei/2; - - // if it's a 1x1 cluster, return one location in the center of the - // cluster - if (cluster.width == 1) { - StageLocation loc = new StageLocation( - MisoUtil.toFull(cluster.x, 2), MisoUtil.toFull(cluster.y, 2), - (byte)DirectionCodes.SOUTHWEST); - list.add(new SceneLocation(loc, 0)); - return list; - } - - double radius = (double)fwid/2; - int clidx = cluster.width-2; - if (clidx >= CLUSTER_METRICS.length/2 || clidx < 0) { - Log.warning("Requested locs from invalid cluster " + cluster + "."); - Thread.dumpStack(); - return list; - } - - for (double angle = CLUSTER_METRICS[clidx*2]; angle < Math.PI*2; - angle += CLUSTER_METRICS[clidx*2+1]) { - int sx = cx + (int)Math.round(Math.cos(angle) * radius); - int sy = cy + (int)Math.round(Math.sin(angle) * radius); - - // obtain the orientation facing toward the center - int orient = 2*(int)(Math.round(angle/(Math.PI/4))%8); - orient = DirectionUtil.rotateCW(DirectionCodes.SOUTH, orient); - orient = DirectionUtil.getOpposite(orient); - - // convert them back to full coordinates for the location - int tx = MathUtil.floorDiv(sx, _metrics.finegran); - sx = MisoUtil.toFull(tx, sx-(tx*_metrics.finegran)); - int ty = MathUtil.floorDiv(sy, _metrics.finegran); - sy = MisoUtil.toFull(ty, sy-(ty*_metrics.finegran)); - StageLocation loc = new StageLocation(sx, sy, (byte) orient); - list.add(new SceneLocation(loc, 0)); - } - - return list; - } - -// /** -// * Returns true if this user is available to be clustered with. -// */ -// public static boolean isClusterable (YoOccupantInfo info) -// { -// switch (info.activity) { -// case ActivityCodes.NONE: -// case ActivityCodes.READING: -// case ActivityCodes.IDLE: -// case ActivityCodes.DISCONNECTED: -// return true; -// default: -// return false; -// } -// } - - /** - * Locates a spot to stand near the supplied rectangular footprint. - * First a spot will be sought in a tile immediately next to the - * footprint, then one tile removed, then two, up to the maximum - * distance specified by dist. - * - * @param foot the tile coordinate footprint around which we are - * attempting to stand. - * @param dist the maximum number of tiles away from the footprint to - * search before giving up. - * @param pred a predicate that will be used to determine whether a - * particular spot can be stood upon (we're hijacking the meaning of - * "traverse" in this case, but the interface is otherwise so nice). - * @param traverser the object that will be passed to the traversal - * predicate. - * @param nearto a point (in tile coordinates) which will be used to - * select from among the valid standing spots, the one nearest to the - * supplied point will be returned. - * @param orient if not {@link DirectionCodes#NONE} this orientation - * will be used to override the "natural" orientation of the spot - * which is facing toward the footprint. - * - * @return the closest spot to the - */ - public static StageLocation findStandingSpot ( - Rectangle foot, int dist, AStarPathUtil.TraversalPred pred, - Object traverser, final Point nearto, int orient) - { - // generate a list of the tile coordinates of all squares around - // this footprint - SortableArrayList spots = new SortableArrayList(); - - for (int dd = 1; dd <= dist; dd++) { - int yy1 = foot.y-dd, yy2 = foot.y+foot.height+dd-1; - int xx1 = foot.x-dd, xx2 = foot.x+foot.width+dd-1; - - // get the corners - spots.add( - new StageLocation(xx1, yy1, (byte)DirectionCodes.SOUTHWEST)); - spots.add( - new StageLocation(xx1, yy2, (byte)DirectionCodes.SOUTHEAST)); - spots.add( - new StageLocation(xx2, yy1, (byte)DirectionCodes.NORTHWEST)); - spots.add( - new StageLocation(xx2, yy2, (byte)DirectionCodes.NORTHEAST)); - - // then the sides - for (int xx = xx1+1; xx < xx2; xx++) { - spots.add( - new StageLocation(xx, yy1, (byte)DirectionCodes.WEST)); - spots.add( - new StageLocation(xx, yy2, (byte)DirectionCodes.EAST)); - } - for (int yy = yy1+1; yy < yy2; yy++) { - spots.add( - new StageLocation(xx1, yy, (byte)DirectionCodes.SOUTH)); - spots.add( - new StageLocation(xx2, yy, (byte)DirectionCodes.NORTH)); - } - - // sort them in order of closeness to the players current - // coordinate - spots.sort(new Comparator() { - public int compare (Object o1, Object o2) { - return dist((StageLocation)o1) - dist((StageLocation)o2); - } - private final int dist (StageLocation l) { - return Math.round(100*MathUtil.distance( - l.x, l.y, nearto.x, nearto.y)); - } - }); - - // return the first spot that can be "traversed" which we're - // taking to mean "stood upon" - for (int ii = 0, ll = spots.size(); ii < ll; ii++) { - StageLocation loc = (StageLocation)spots.get(ii); - if (pred.canTraverse(traverser, loc.x, loc.y)) { - // convert to full coordinates - loc.x = MisoUtil.toFull(loc.x, 2); - loc.y = MisoUtil.toFull(loc.y, 2); - - // see if we need to override the orientation - if (DirectionCodes.NONE != orient) { - loc.orient = (byte) orient; - } - return loc; - } - } - - // clear this list and try one further out - spots.clear(); - } - - return null; - } - - /** - * Returns an array of the objects intersected by the supplied tile - * coordinate rectangle. - */ - public static ObjectInfo[] getIntersectedObjects ( - TileManager tmgr, StageSceneModel model, Rectangle rect) - { - // first get all objects whose origin is in an expanded version of - // our intersection rect, any object that is *so* large that its - // origin falls outside of this rectangle but that still - // intersects this rectangle can go to hell; it's either this or - // we iterate over every object in the whole goddamned scene which - // is so hairily inefficient i can't even bear to contemplate it - ObjectSet objs = new ObjectSet(); - Rectangle orect = new Rectangle(rect); - orect.grow(MAX_OBJECT_SIZE, MAX_OBJECT_SIZE); - StageMisoSceneModel mmodel = StageMisoSceneModel.getSceneModel(model); - mmodel.getObjects(orect, objs); - - // now prune from this set any and all objects that don't actually - // overlap the specified rectangle - Rectangle foot = new Rectangle(); - for (int ii = 0; ii < objs.size(); ii++) { - ObjectInfo info = objs.get(ii); - if (getObjectFootprint(tmgr, info.tileId, info.x, info.y, foot)) { - if (!foot.intersects(rect)) { - objs.remove(ii--); - } - } else { - Log.warning("Unknown potentially intersecting object?! " + - "[scene=" + model.name + " (" + model.sceneId + - "), info=" + info + "]."); - } - } - - return objs.toArray(); - } - - /** Our default scene metrics. */ - protected static MisoSceneMetrics _metrics = MisoConfig.getSceneMetrics(); - - /** Contains the starting offset from zero radians for the first - * occupant and the radial distance between occupants. */ - protected static final double[] CLUSTER_METRICS = { - Math.PI/4, Math.PI/2, // 2x - Math.PI/4, Math.PI/2, // 3x - 0, Math.PI/4, // 4x - Math.PI/12, Math.PI/6, // 5x - 0, Math.PI/8, // 6x - Math.PI/24, Math.PI/12, // 7x - }; - - /** The maximum footprint width or height for which we will account in - * {@link #getIntersectedObjects}. */ - protected static final int MAX_OBJECT_SIZE = 15; -} diff --git a/src/java/com/threerings/util/BrowserUtil.java b/src/java/com/threerings/util/BrowserUtil.java deleted file mode 100644 index 315cc51cc..000000000 --- a/src/java/com/threerings/util/BrowserUtil.java +++ /dev/null @@ -1,141 +0,0 @@ -// -// $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 deleted file mode 100644 index 7e43afc67..000000000 --- a/src/java/com/threerings/util/DirectionCodes.java +++ /dev/null @@ -1,104 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a0f29bdec..000000000 --- a/src/java/com/threerings/util/DirectionUtil.java +++ /dev/null @@ -1,338 +0,0 @@ -// -// $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.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 deleted file mode 100644 index dd59ff166..000000000 --- a/src/java/com/threerings/util/IdleTracker.java +++ /dev/null @@ -1,177 +0,0 @@ -// -// $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#getCurrentTimeMillis} 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 deleted file mode 100644 index 3714bc730..000000000 --- a/src/java/com/threerings/util/KeyDispatcher.java +++ /dev/null @@ -1,275 +0,0 @@ -// -// $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.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 deleted file mode 100644 index d87ed61e1..000000000 --- a/src/java/com/threerings/util/KeyTranslator.java +++ /dev/null @@ -1,79 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 84bf50038..000000000 --- a/src/java/com/threerings/util/KeyTranslatorImpl.java +++ /dev/null @@ -1,190 +0,0 @@ -// -// $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.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 deleted file mode 100644 index dde308b9b..000000000 --- a/src/java/com/threerings/util/KeyboardManager.java +++ /dev/null @@ -1,720 +0,0 @@ -// -// $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.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/RobotPlayer.java b/src/java/com/threerings/util/RobotPlayer.java deleted file mode 100644 index 68b81c328..000000000 --- a/src/java/com/threerings/util/RobotPlayer.java +++ /dev/null @@ -1,126 +0,0 @@ -// -// $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.util; - -import java.awt.Component; -import java.util.ArrayList; - -import com.samskivert.swing.Controller; -import com.samskivert.util.CollectionUtil; -import com.samskivert.util.Interval; -import com.samskivert.util.RandomUtil; - -/** - * The robot player is a computer player with truly rudimentary artificial - * intelligence that periodically posts random commands selected from the - * available key press and release commands to the target component. - * - * Note that {@link java.awt.Robot} could have been used to post key - * events to the target component rather than commands, but not all key - * events can be simulated in that fashion (e.g., a right shift key - * press), and this seemed somehow more proper in any case. - */ -public class RobotPlayer extends Interval -{ - /** - * Constructs a robot player. - */ - public RobotPlayer (Component target, KeyTranslator xlate) - { - // save off references - _target = target; - _xlate = xlate; - - // build the list of available commands - CollectionUtil.addAll(_press, _xlate.enumeratePressCommands()); - CollectionUtil.addAll(_release, _xlate.enumerateReleaseCommands()); - } - - /** - * Sets whether the robot player is actively posting action commands. - */ - public void setActive (boolean active) - { - if (active != _active) { - if (active) { - schedule(_robotDelay, true); - } else { - cancel(); // stop the robot player - } - _active = active; - } - } - - /** - * Sets the delay in milliseconds between posting each action command. - */ - public void setRobotDelay (long delay) - { - _robotDelay = delay; - - // if the robot is active, reset it with the new delay time - if (isActive()) { - setActive(false); - setActive(true); - } - } - - /** - * Returns whether the robot is currently active and periodically - * posting action commands. - */ - public boolean isActive () - { - return _active; - } - - // documentation inherited - public void expired () - { - // post a random key press command - int idx = RandomUtil.getInt(_press.size()); - String command = (String)_press.get(idx); - // Log.info("Posting artificial command [cmd=" + command + "]."); - Controller.postAction(_target, command); - } - - /** The default robot delay. */ - protected static final long DEFAULT_ROBOT_DELAY = 500L; - - /** Whether the robot is active or not. */ - protected boolean _active = false; - - /** The milliseconds between posting each action command. */ - protected long _robotDelay = DEFAULT_ROBOT_DELAY; - - /** The list of available key press action commands. */ - protected ArrayList _press = new ArrayList(); - - /** The list of available key release action commands. */ - protected ArrayList _release = new ArrayList(); - - /** The key translator that describes available keys and commands. */ - protected KeyTranslator _xlate; - - /** The target component associated with game action commands. */ - protected Component _target; -} diff --git a/src/java/com/threerings/util/keybd/Keyboard.java b/src/java/com/threerings/util/keybd/Keyboard.java deleted file mode 100644 index 3bec636cb..000000000 --- a/src/java/com/threerings/util/keybd/Keyboard.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $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.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 deleted file mode 100644 index a88b25992..000000000 --- a/src/java/com/threerings/util/keybd/Linux/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# $Id$ - -# -# 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 deleted file mode 100644 index 38cd43493..000000000 --- a/src/java/com/threerings/util/keybd/Linux/com_threerings_util_keybd_Keyboard.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * $Id$ - */ - -#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 deleted file mode 100755 index e43ea176c..000000000 Binary files a/src/java/com/threerings/util/keybd/Linux/libkeybd.so and /dev/null differ diff --git a/src/java/com/threerings/util/keybd/Mac OS X/Makefile b/src/java/com/threerings/util/keybd/Mac OS X/Makefile deleted file mode 100644 index 0fe6ecb04..000000000 --- a/src/java/com/threerings/util/keybd/Mac OS X/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# $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/keybd/Windows/.cvsignore b/src/java/com/threerings/util/keybd/Windows/.cvsignore deleted file mode 100644 index b71fffb48..000000000 --- a/src/java/com/threerings/util/keybd/Windows/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -keybd.dll diff --git a/src/java/com/threerings/util/keybd/Windows/Makefile b/src/java/com/threerings/util/keybd/Windows/Makefile deleted file mode 100644 index dcb7a0e91..000000000 --- a/src/java/com/threerings/util/keybd/Windows/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# $Id$ - -CROSSTOOLS_PATH=/usr/local/cross-tools -MINGW_PATH=${CROSSTOOLS_PATH}/i386-mingw32msvc -WIN32API_PATH=${CROSSTOOLS_PATH}/w32api - -CC=${MINGW_PATH}/bin/gcc -RM=rm - -INCLUDES=-I.. -I/usr/local/jdk1.4/include -I/usr/local/jdk1.4/include/linux \ - -I${CROSSTOOLS_PATH}/include -I${WIN32API_PATH}/include -LIBRARIES_PATH=-L${CROSSTOOLS_PATH}/lib -L${WIN32API_PATH}/lib -LIBRARIES= -TARGET=keybd.dll - -all: ${TARGET} - -${TARGET}: com_threerings_util_keybd_Keyboard.c - ${CC} ${INCLUDES} -c com_threerings_util_keybd_Keyboard.c \ - -o com_threerings_util_keybd_Keyboard.o - ${CC} -o ${TARGET} com_threerings_util_keybd_Keyboard.o \ - ${LIBRARIES} ${LIBRARIES_PATH} -shared - -clean: - -${RM} *.o - -${RM} ${TARGET} diff --git a/src/java/com/threerings/util/keybd/Windows/com_threerings_util_keybd_Keyboard.c b/src/java/com/threerings/util/keybd/Windows/com_threerings_util_keybd_Keyboard.c deleted file mode 100644 index aeb521c02..000000000 --- a/src/java/com/threerings/util/keybd/Windows/com_threerings_util_keybd_Keyboard.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * $Id$ - */ - -#include -#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 deleted file mode 100644 index 04f524d0b..000000000 --- a/src/java/com/threerings/util/keybd/com_threerings_util_keybd_Keyboard.h +++ /dev/null @@ -1,29 +0,0 @@ -/* 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 deleted file mode 100644 index 39a78063f..000000000 --- a/src/java/com/threerings/util/unsafe/FreeBSD/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# $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 deleted file mode 100644 index 04ac0526c..000000000 --- a/src/java/com/threerings/util/unsafe/FreeBSD/com_threerings_util_unsafe_Unsafe.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * $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 deleted file mode 100755 index 2a6a9e536..000000000 Binary files a/src/java/com/threerings/util/unsafe/FreeBSD/libunsafe.so and /dev/null differ diff --git a/src/java/com/threerings/util/unsafe/Linux/Makefile b/src/java/com/threerings/util/unsafe/Linux/Makefile deleted file mode 100644 index 7784242e9..000000000 --- a/src/java/com/threerings/util/unsafe/Linux/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# $Id$ - -# -# 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 deleted file mode 100644 index 683c55839..000000000 --- a/src/java/com/threerings/util/unsafe/Linux/com_threerings_util_unsafe_Unsafe.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * $Id$ - */ - -#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 deleted file mode 100755 index 59305842f..000000000 Binary files a/src/java/com/threerings/util/unsafe/Linux/libunsafe.so and /dev/null differ diff --git a/src/java/com/threerings/util/unsafe/Mac OS X/Makefile b/src/java/com/threerings/util/unsafe/Mac OS X/Makefile deleted file mode 100644 index 0fe6ecb04..000000000 --- a/src/java/com/threerings/util/unsafe/Mac OS X/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# $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 deleted file mode 100644 index b7b845942..000000000 --- a/src/java/com/threerings/util/unsafe/Unsafe.java +++ /dev/null @@ -1,144 +0,0 @@ -// -// $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.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 deleted file mode 100644 index c253038a1..000000000 --- a/src/java/com/threerings/util/unsafe/Windows/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.def diff --git a/src/java/com/threerings/util/unsafe/Windows/Makefile b/src/java/com/threerings/util/unsafe/Windows/Makefile deleted file mode 100644 index 9481edee6..000000000 --- a/src/java/com/threerings/util/unsafe/Windows/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# $Id$ - -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 deleted file mode 100644 index a377db92b..000000000 --- a/src/java/com/threerings/util/unsafe/Windows/com_threerings_util_unsafe_Unsafe.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * $Id$ - */ - -#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 deleted file mode 100644 index f439fed8e..000000000 --- a/src/java/com/threerings/util/unsafe/com_threerings_util_unsafe_Unsafe.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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/src/java/com/threerings/whirled/zone/data/SceneSummary.java b/src/java/com/threerings/whirled/zone/data/SceneSummary.java index f45cf704f..093417f58 100644 --- a/src/java/com/threerings/whirled/zone/data/SceneSummary.java +++ b/src/java/com/threerings/whirled/zone/data/SceneSummary.java @@ -24,8 +24,6 @@ package com.threerings.whirled.zone.data; import com.samskivert.util.StringUtil; import com.threerings.io.Streamable; -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; /** * The scene summary class is used to provide info about the connected @@ -45,8 +43,7 @@ public class SceneSummary implements Streamable * portals. */ public int[] neighbors; - /** The compass directions in which each of the neighbors lay. The - * direction constants are as defined in {@link DirectionCodes}. */ + /** The directions in which each of the neighbors lay. */ public int[] neighborDirs; /** @@ -56,6 +53,6 @@ public class SceneSummary implements Streamable { return "[sceneId=" + sceneId + ", name=" + name + ", neighbors=" + StringUtil.toString(neighbors) + - ", neighborDirs=" + DirectionUtil.toString(neighborDirs) + "]"; + ", neighborDirs=" + StringUtil.toString(neighborDirs) + "]"; } } diff --git a/tests/src/java/com/threerings/cast/CharSpriteViz.java b/tests/src/java/com/threerings/cast/CharSpriteViz.java deleted file mode 100644 index 48980e89b..000000000 --- a/tests/src/java/com/threerings/cast/CharSpriteViz.java +++ /dev/null @@ -1,153 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 7854adbe4..000000000 --- a/tests/src/java/com/threerings/cast/builder/TestApp.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 6665712f1..000000000 --- a/tests/src/java/com/threerings/cast/builder/TestFrame.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// $Id: TestFrame.java,v 1.7 2004/08/27 02:20:54 mdb Exp $ -// -// 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 deleted file mode 100644 index 5b3270901..000000000 --- a/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// $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.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/crowd/client/JabberPanel.java b/tests/src/java/com/threerings/crowd/client/JabberPanel.java index 0fb474ee2..97afc0712 100644 --- a/tests/src/java/com/threerings/crowd/client/JabberPanel.java +++ b/tests/src/java/com/threerings/crowd/client/JabberPanel.java @@ -9,8 +9,8 @@ import javax.swing.JPanel; import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.util.CrowdContext; -import com.threerings.micasa.client.ChatPanel; -import com.threerings.micasa.client.OccupantList; +// import com.threerings.micasa.client.ChatPanel; +// import com.threerings.micasa.client.OccupantList; /** * Displays a simple chat view. @@ -22,8 +22,8 @@ public class JabberPanel extends JPanel { _ctx = ctx; setLayout(new BorderLayout()); - add(new ChatPanel(ctx), BorderLayout.CENTER); - add(new OccupantList(ctx), BorderLayout.EAST); +// add(new ChatPanel(ctx), BorderLayout.CENTER); +// add(new OccupantList(ctx), BorderLayout.EAST); } // documentation inherited from interface PlaceView diff --git a/tests/src/java/com/threerings/geom/NearestViz.java b/tests/src/java/com/threerings/geom/NearestViz.java deleted file mode 100644 index a05943e0c..000000000 --- a/tests/src/java/com/threerings/geom/NearestViz.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// $Id: NearestViz.java,v 1.3 2004/08/27 02:20:56 mdb Exp $ -// -// 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 deleted file mode 100644 index aa19a64c6..000000000 --- a/tests/src/java/com/threerings/geom/WhichSideViz.java +++ /dev/null @@ -1,113 +0,0 @@ -// -// $Id: WhichSideViz.java,v 1.3 2004/08/27 02:20:56 mdb Exp $ -// -// 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 deleted file mode 100644 index 089778ddc..000000000 --- a/tests/src/java/com/threerings/jme/JmeCanvasTest.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $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 deleted file mode 100644 index 523ea4dbb..000000000 --- a/tests/src/java/com/threerings/jme/client/JabberApp.java +++ /dev/null @@ -1,160 +0,0 @@ -// -// $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 deleted file mode 100644 index 2fc854f94..000000000 --- a/tests/src/java/com/threerings/jme/client/JabberClient.java +++ /dev/null @@ -1,228 +0,0 @@ -// -// $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 deleted file mode 100644 index 329381b6a..000000000 --- a/tests/src/java/com/threerings/jme/client/JabberController.java +++ /dev/null @@ -1,19 +0,0 @@ -// -// $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 deleted file mode 100644 index c0c810fd2..000000000 --- a/tests/src/java/com/threerings/jme/client/JabberView.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $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 deleted file mode 100644 index 4f6400139..000000000 --- a/tests/src/java/com/threerings/jme/data/JabberConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// $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 deleted file mode 100644 index 8ff438702..000000000 --- a/tests/src/java/com/threerings/jme/server/JabberServer.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $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 deleted file mode 100644 index ee6d0273f..000000000 --- a/tests/src/java/com/threerings/jme/sprite/PathTest.java +++ /dev/null @@ -1,150 +0,0 @@ -// -// $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 deleted file mode 100644 index c772fd9bf..000000000 --- a/tests/src/java/com/threerings/media/ImageLoadingSpeed.java +++ /dev/null @@ -1,80 +0,0 @@ -// -// $Id: ImageLoadingSpeed.java,v 1.6 2004/08/27 02:20:57 mdb Exp $ -// -// 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 deleted file mode 100644 index 9b39a256d..000000000 --- a/tests/src/java/com/threerings/media/TestIconManager.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// $Id: TestIconManager.java,v 1.4 2004/08/27 02:20:57 mdb Exp $ -// -// 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 deleted file mode 100644 index 2dca37a26..000000000 --- a/tests/src/java/com/threerings/media/sound/SoundTestApp.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// $Id: SoundTestApp.java,v 1.7 2004/08/27 02:20:58 mdb Exp $ -// -// 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 deleted file mode 100644 index e029199bb..000000000 --- a/tests/src/java/com/threerings/media/sound/sounds.properties +++ /dev/null @@ -1,7 +0,0 @@ -# -# $Id: sounds.properties,v 1.1 2002/12/10 21:36:53 mdb Exp $ -# -# 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 deleted file mode 100644 index 150677cfc..000000000 --- a/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// $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.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 deleted file mode 100644 index acb8a8520..000000000 --- a/tests/src/java/com/threerings/media/tile/bundle/tools/BuildTestTileSetBundle.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// $Id: BuildTestTileSetBundle.java,v 1.8 2004/08/27 02:20:59 mdb Exp $ -// -// 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 deleted file mode 100644 index c72040104..000000000 --- a/tests/src/java/com/threerings/media/tile/tools/xml/XMLTileSetParserTest.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// $Id: XMLTileSetParserTest.java,v 1.5 2004/08/27 02:21:00 mdb Exp $ -// -// 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 deleted file mode 100644 index 8e667bf84..000000000 --- a/tests/src/java/com/threerings/media/util/PathViz.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 32f34004a..000000000 --- a/tests/src/java/com/threerings/media/util/TraceViz.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $Id: TraceViz.java,v 1.6 2004/08/27 02:21:00 mdb Exp $ -// -// 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 deleted file mode 100644 index c3d45ecbb..000000000 --- a/tests/src/java/com/threerings/miso/client/ScrollingFrame.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// $Id: ScrollingFrame.java,v 1.6 2004/08/27 02:21:01 mdb Exp $ -// -// 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 deleted file mode 100644 index 9057430d7..000000000 --- a/tests/src/java/com/threerings/miso/client/ScrollingScene.java +++ /dev/null @@ -1,124 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 54ca6329f..000000000 --- a/tests/src/java/com/threerings/miso/client/ScrollingTestApp.java +++ /dev/null @@ -1,234 +0,0 @@ -// -// $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.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 deleted file mode 100644 index 4d234ff04..000000000 --- a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java +++ /dev/null @@ -1,191 +0,0 @@ -// -// $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.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 deleted file mode 100644 index bc602fb91..000000000 --- a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// $Id: ViewerFrame.java,v 1.35 2004/08/27 02:21:01 mdb Exp $ -// -// 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 deleted file mode 100644 index 525f6798e..000000000 --- a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java +++ /dev/null @@ -1,237 +0,0 @@ -// -// $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.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 deleted file mode 100644 index caf3fdc60..000000000 --- a/tests/src/java/com/threerings/openal/TestSoundManager.java +++ /dev/null @@ -1,55 +0,0 @@ -// -// $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/parlor/TestClient.java b/tests/src/java/com/threerings/parlor/TestClient.java deleted file mode 100644 index 884db07ff..000000000 --- a/tests/src/java/com/threerings/parlor/TestClient.java +++ /dev/null @@ -1,127 +0,0 @@ -// -// $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.parlor; - -import com.threerings.util.Name; - -import com.threerings.presents.client.*; -import com.threerings.presents.net.*; - -import com.threerings.crowd.client.*; -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.parlor.Log; -import com.threerings.parlor.client.*; -import com.threerings.parlor.game.client.*; -import com.threerings.parlor.game.data.*; -import com.threerings.parlor.util.ParlorContext; - -public class TestClient extends com.threerings.crowd.client.TestClient - implements InvitationHandler, InvitationResponseObserver -{ - public TestClient (String username) - { - super(username); - - // create the handles on our various services - _pardtr = new ParlorDirector(_ctx); - - // register ourselves as the invitation handler - _pardtr.setInvitationHandler(this); - } - - public void clientDidLogon (Client client) - { - // we intentionally don't call super() - - Log.info("Client did logon [client=" + client + "]."); - - // get a casted reference to our body object - _body = (BodyObject)client.getClientObject(); - - // if we're the inviter, do some inviting - if (_body.username.equals("inviter")) { - // send the invitation - TestConfig config = new TestConfig(); - _pardtr.invite(new Name("invitee"), config, this); - } - } - - public void invitationReceived (Invitation invite) - { - Log.info("Invitation received [invite=" + invite + "]."); - - // accept the invitation. we're game... - invite.accept(); - } - - public void invitationCancelled (Invitation invite) - { - Log.info("Invitation cancelled [invite=" + invite + "]."); - } - - public void invitationAccepted (Invitation invite) - { - Log.info("Invitation accepted [invite=" + invite + "]."); - } - - public void invitationRefused (Invitation invite, String message) - { - Log.info("Invitation refused [invite=" + invite + - ", message=" + message + "]."); - } - - public void invitationCountered (Invitation invite, GameConfig config) - { - Log.info("Invitation countered [invite=" + invite + - ", config=" + config + "]."); - } - - protected CrowdContext createContext () - { - return (_ctx = new ParlorContextImpl()); - } - - public static void main (String[] args) - { - // create our test client - TestClient tclient = new TestClient( - System.getProperty("username", "test")); - // start it running - tclient.run(); - } - - protected class ParlorContextImpl - extends com.threerings.crowd.client.TestClient.CrowdContextImpl - implements ParlorContext - { - public ParlorDirector getParlorDirector () - { - return _pardtr; - } - } - - protected ParlorContext _ctx; - protected ParlorDirector _pardtr; - protected BodyObject _body; -} diff --git a/tests/src/java/com/threerings/parlor/TestConfig.java b/tests/src/java/com/threerings/parlor/TestConfig.java deleted file mode 100644 index 384306b4c..000000000 --- a/tests/src/java/com/threerings/parlor/TestConfig.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// $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.parlor; - -import com.threerings.parlor.game.client.GameConfigurator; -import com.threerings.parlor.game.data.GameConfig; - -public class TestConfig extends GameConfig -{ - /** The foozle parameter. */ - public int foozle; - - public GameConfigurator createConfigurator () - { - return null; - } - - public Class getControllerClass () - { - return TestController.class; - } - - public String getBundleName () - { - return "test"; - } - - public String getManagerClassName () - { - return "com.threerings.parlor.test.TestManager"; - } - - protected void toString (StringBuilder buf) - { - super.toString(buf); - buf.append(", foozle=").append(foozle); - } -} diff --git a/tests/src/java/com/threerings/parlor/TestController.java b/tests/src/java/com/threerings/parlor/TestController.java deleted file mode 100644 index 255688268..000000000 --- a/tests/src/java/com/threerings/parlor/TestController.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $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.parlor; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.util.CrowdContext; -import com.threerings.parlor.game.client.GameController; - -public class TestController extends GameController -{ - public PlaceView createPlaceView (CrowdContext ctx) - { - // nothing doing - return null; - } -} diff --git a/tests/src/java/com/threerings/parlor/TestManager.java b/tests/src/java/com/threerings/parlor/TestManager.java deleted file mode 100644 index 53f0d8559..000000000 --- a/tests/src/java/com/threerings/parlor/TestManager.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// $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.parlor; - -import com.threerings.parlor.game.server.GameManager; - -public class TestManager extends GameManager -{ - // nothing doing -} diff --git a/tests/src/java/com/threerings/parlor/TestServer.java b/tests/src/java/com/threerings/parlor/TestServer.java deleted file mode 100644 index bcaf6cf46..000000000 --- a/tests/src/java/com/threerings/parlor/TestServer.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// $Id: TestServer.java,v 1.6 2004/08/27 02:21:02 mdb Exp $ -// -// 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.parlor; - -import com.threerings.crowd.server.CrowdServer; - -import com.threerings.parlor.Log; -import com.threerings.parlor.server.ParlorManager; - -/** - * A test server for the Parlor services. - */ -public class TestServer extends CrowdServer -{ - /** The parlor manager in operation on this server. */ - public static ParlorManager parmgr = new ParlorManager(); - - /** Initializes the Parlor test server. */ - public void init () - throws Exception - { - super.init(); - - // initialize our parlor manager - parmgr.init(invmgr, plreg); - - Log.info("Parlor server initialized."); - } - - /** Main entry point for test server. */ - public static void main (String[] args) - { - TestServer server = new TestServer(); - try { - server.init(); - server.run(); - } catch (Exception e) { - Log.warning("Unable to initialize server."); - Log.logStackTrace(e); - } - } -} diff --git a/tests/src/java/com/threerings/util/DirectionTest.java b/tests/src/java/com/threerings/util/DirectionTest.java deleted file mode 100644 index 836575726..000000000 --- a/tests/src/java/com/threerings/util/DirectionTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -// $Id: DirectionTest.java,v 1.3 2004/08/27 02:21:05 mdb Exp $ -// -// 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 deleted file mode 100644 index 81356136b..000000000 --- a/tests/src/java/com/threerings/util/DirectionViz.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $Id: DirectionViz.java,v 1.2 2004/08/27 02:21:05 mdb Exp $ -// -// 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 deleted file mode 100644 index 793128a1a..000000000 --- a/tests/src/java/com/threerings/util/KeyTimerApp.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// $Id: KeyTimerApp.java,v 1.3 2004/08/27 02:21:05 mdb Exp $ -// -// 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 deleted file mode 100644 index 94252ae88..000000000 --- a/tests/src/java/com/threerings/util/KeyboardManagerApp.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// $Id: KeyboardManagerApp.java,v 1.6 2004/08/27 02:21:05 mdb Exp $ -// -// 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/UIDTest.java b/tests/src/java/com/threerings/util/UIDTest.java deleted file mode 100644 index cabc45b63..000000000 --- a/tests/src/java/com/threerings/util/UIDTest.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// $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) { - } - } -} diff --git a/tests/src/java/com/threerings/whirled/DummyClientSceneRepository.java b/tests/src/java/com/threerings/whirled/DummyClientSceneRepository.java deleted file mode 100644 index 2c8d6e490..000000000 --- a/tests/src/java/com/threerings/whirled/DummyClientSceneRepository.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// $Id: DummyClientSceneRepository.java,v 1.7 2004/08/27 02:21:05 mdb Exp $ -// -// 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.whirled; - -import java.io.IOException; - -import com.threerings.whirled.Log; -import com.threerings.whirled.client.persist.SceneRepository; -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.util.NoSuchSceneException; - -/** - * The dummy scene repository just pretends to load and store scenes, but - * in fact it just creates new blank scenes when requested to load a scene - * and does nothing when requested to save one. - */ -public class DummyClientSceneRepository implements SceneRepository -{ - // documentation inherited - public SceneModel loadSceneModel (int sceneId) - throws IOException, NoSuchSceneException - { - Log.info("Creating dummy scene model [id=" + sceneId + "]."); - return new SceneModel(); - } - - // documentation inherited - public void storeSceneModel (SceneModel model) - throws IOException - { - // nothing doing - } - - // documentation inherited - public void deleteSceneModel (int sceneId) - throws IOException - { - // nothing doing - } -} diff --git a/tests/src/java/com/threerings/whirled/TestClient.java b/tests/src/java/com/threerings/whirled/TestClient.java deleted file mode 100644 index 8d868c919..000000000 --- a/tests/src/java/com/threerings/whirled/TestClient.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $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.whirled; - -import com.threerings.presents.client.Client; - -import com.threerings.crowd.Log; -import com.threerings.crowd.client.*; -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.whirled.client.SceneDirector; -import com.threerings.whirled.client.persist.SceneRepository; -import com.threerings.whirled.data.Scene; -import com.threerings.whirled.data.SceneImpl; -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.util.SceneFactory; -import com.threerings.whirled.util.WhirledContext; - -public class TestClient extends com.threerings.crowd.client.TestClient - implements LocationObserver -{ - public TestClient (String username) - { - super(username); - - // create the handles for our various services - _screp = new DummyClientSceneRepository(); - - SceneFactory sfact = new SceneFactory() { - public Scene createScene (SceneModel model, PlaceConfig config) { - return new SceneImpl(model, config); - } - }; - _scdir = new SceneDirector(_ctx, _locdir, _screp, sfact); - - // we want to know about location changes - _locdir.addLocationObserver(this); - } - - public void clientDidLogon (Client client) - { - // we specifically do not call super() - - Log.info("Client did logon [client=" + client + "]."); - - // request to move to scene 0 - _ctx.getSceneDirector().moveTo(0); - } - - public boolean locationMayChange (int placeId) - { - // we're easy - return true; - } - - public void locationDidChange (PlaceObject place) - { - Log.info("At new location [plobj=" + place + - ", scene=" + _scdir.getScene() + "]."); - } - - public void locationChangeFailed (int placeId, String reason) - { - Log.warning("Location change failed [plid=" + placeId + - ", reason=" + reason + "]."); - } - - protected CrowdContext createContext () - { - return (_ctx = new WhirledContextImpl()); - } - - public static void main (String[] args) - { - // create our test client - TestClient tclient = new TestClient("test"); - // start it running - tclient.run(); - } - - protected class WhirledContextImpl - extends com.threerings.crowd.client.TestClient.CrowdContextImpl - implements WhirledContext - { - public SceneDirector getSceneDirector () - { - return _scdir; - } - } - - protected WhirledContext _ctx; - protected SceneDirector _scdir; - protected SceneRepository _screp; -} diff --git a/tests/src/java/com/threerings/whirled/TestConfig.java b/tests/src/java/com/threerings/whirled/TestConfig.java deleted file mode 100644 index efa8a0ba0..000000000 --- a/tests/src/java/com/threerings/whirled/TestConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// $Id: TestConfig.java,v 1.4 2004/08/27 02:21:05 mdb Exp $ -// -// 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.whirled; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.whirled.server.SceneManager; - -public class TestConfig extends PlaceConfig -{ - public Class getControllerClass () - { - return TestController.class; - } - - public String getManagerClassName () - { - return SceneManager.class.getName(); - } -} diff --git a/tests/src/java/com/threerings/whirled/TestController.java b/tests/src/java/com/threerings/whirled/TestController.java deleted file mode 100644 index 4734620bb..000000000 --- a/tests/src/java/com/threerings/whirled/TestController.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// $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.whirled; - -import com.threerings.crowd.client.*; -import com.threerings.crowd.util.CrowdContext; - -public class TestController extends PlaceController -{ - protected PlaceView createPlaceView (CrowdContext ctx) - { - // nothing doing - return null; - } -} diff --git a/tests/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneParserTest.java b/tests/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneParserTest.java deleted file mode 100644 index ac276115d..000000000 --- a/tests/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneParserTest.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// $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.whirled.spot.tools.xml; - -import com.samskivert.test.TestUtil; - -import junit.framework.Test; -import junit.framework.TestCase; - -import com.threerings.whirled.data.SceneModel; -import com.threerings.whirled.spot.data.Location; -import com.threerings.whirled.tools.xml.SceneParser; - -import com.threerings.stage.data.StageLocation; - -public class SpotSceneParserTest extends TestCase -{ - public SpotSceneParserTest () - { - super(SpotSceneParserTest.class.getName()); - } - - public void runTest () - { - try { - SceneParser parser = new SceneParser("scene"); - parser.registerAuxRuleSet(new SpotSceneRuleSet() { - protected Location createLocation () { - return new StageLocation(); // breaks package, but ok - } - }); - String tspath = TestUtil.getResourcePath(TEST_SCENE_PATH); - SceneModel scene = parser.parseScene(tspath); - System.out.println("Parsed " + scene + "."); - - } catch (Exception e) { - e.printStackTrace(); - fail("Test threw exception"); - } - } - - public static Test suite () - { - return new SpotSceneParserTest(); - } - - public static void main (String[] args) - { - SpotSceneParserTest test = new SpotSceneParserTest(); - test.runTest(); - } - - protected static final String TEST_SCENE_PATH = - "rsrc/whirled/spot/tools/xml/scene.xml"; -} diff --git a/tests/src/java/com/threerings/whirled/tools/xml/SceneParserTest.java b/tests/src/java/com/threerings/whirled/tools/xml/SceneParserTest.java deleted file mode 100644 index faa386703..000000000 --- a/tests/src/java/com/threerings/whirled/tools/xml/SceneParserTest.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// $Id: SceneParserTest.java,v 1.6 2004/08/27 02:21:06 mdb Exp $ -// -// 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.whirled.tools.xml; - -import com.samskivert.test.TestUtil; - -import junit.framework.Test; -import junit.framework.TestCase; - -import com.threerings.whirled.data.SceneModel; - -public class SceneParserTest extends TestCase -{ - public SceneParserTest () - { - super(SceneParserTest.class.getName()); - } - - public void runTest () - { - try { - SceneParser parser = new SceneParser("scene"); - String tspath = TestUtil.getResourcePath(TEST_SCENE_PATH); - SceneModel scene = parser.parseScene(tspath); - System.out.println("Parsed " + scene + "."); - - } catch (Exception e) { - e.printStackTrace(); - fail("Test threw exception"); - } - } - - public static Test suite () - { - return new SceneParserTest(); - } - - public static void main (String[] args) - { - SceneParserTest test = new SceneParserTest(); - test.runTest(); - } - - protected static final String TEST_SCENE_PATH = - "rsrc/whirled/tools/xml/scene.xml"; -}