diff --git a/src/java/com/threerings/cast/ActionSequence.java b/src/java/com/threerings/cast/ActionSequence.java new file mode 100644 index 000000000..95cf208a2 --- /dev/null +++ b/src/java/com/threerings/cast/ActionSequence.java @@ -0,0 +1,47 @@ +// +// $Id: ActionSequence.java,v 1.1 2001/11/01 01:40:42 shaper Exp $ + +package com.threerings.cast; + +import java.awt.Point; + +import com.threerings.media.tile.TileSet; + +/** + * The action sequence class describes a single character animation + * sequence. An animation sequence may consist of multiple frames of + * animation, renders at a particular frame rate, and has an origin + * point that specifies where the base of the character in the + * animation sequence is to be placed. + */ +public class ActionSequence +{ + /** The unique action sequence identifier. */ + public int asid; + + /** The action sequence name. */ + public String name; + + /** The file id specifier for the tile set image file name. */ + public String fileid; + + /** The tile set description for this sequence. Intended for + * cloning with an image path to reference an actual set of tile + * images suiting the action sequence. */ + public TileSet tileset; + + /** The number of frames per second to show when animating. */ + public int fps; + + /** The position of the character's base for this sequence. */ + public Point origin = new Point(); + + /** + * Returns a string representation of this action sequence. + */ + public String toString () + { + return "[asid=" + asid + ", name=" + name + + ", fps=" + fps + ", origin=" + origin + "]"; + } +} diff --git a/src/java/com/threerings/cast/CharacterComponent.java b/src/java/com/threerings/cast/CharacterComponent.java index 7cebb5627..1a2142fe3 100644 --- a/src/java/com/threerings/cast/CharacterComponent.java +++ b/src/java/com/threerings/cast/CharacterComponent.java @@ -1,8 +1,10 @@ // -// $Id: CharacterComponent.java,v 1.2 2001/10/30 16:16:01 shaper Exp $ +// $Id: CharacterComponent.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; +import com.samskivert.util.StringUtil; + import com.threerings.media.sprite.MultiFrameImage; import com.threerings.media.sprite.Sprite; @@ -19,13 +21,12 @@ public class CharacterComponent * Constructs a character component. */ public CharacterComponent ( - ComponentType type, ComponentClass cclass, int cid, - ComponentFrames frames) + int cid, String fileid, ActionSequence seqs[], ComponentClass cclass) { - _type = type; - _cclass = cclass; _cid = cid; - _frames = frames; + _fileid = fileid; + _seqs = seqs; + _cclass = cclass; } /** @@ -36,20 +37,28 @@ public class CharacterComponent return _cid; } + /** + * Returns the action sequences for this component. + */ + public ActionSequence[] getActionSequences () + { + return _seqs; + } + /** * Returns the display frames used to display this component. */ - public ComponentFrames getFrames () + public MultiFrameImage[][] getFrames () { return _frames; } /** - * Returns the component type associated with this component. + * Returns the file id. */ - public ComponentType getType () + public String getFileId () { - return _type; + return _fileid; } /** @@ -60,47 +69,35 @@ public class CharacterComponent return _cclass; } + /** + * Sets the frames used to render this component. + */ + public void setFrames (MultiFrameImage frames[][]) + { + _frames = frames; + } + /** * Returns a string representation of this character component. */ public String toString () { return "[cid=" + _cid + ", clid=" + _cclass.clid + - ", type=" + _type + "]"; - } - - /** - * A class to hold the standing and walking frames of animation - * that comprise a {@link CharacterComponent} object's various - * display images. - */ - public static class ComponentFrames - { - /** The standing animations in each orientation. */ - public MultiFrameImage stand[]; - - /** The walking animations in each orientation. */ - public MultiFrameImage walk[]; - - /** - * Constructs a component frames object. - */ - public ComponentFrames () - { - stand = new MultiFrameImage[Sprite.NUM_DIRECTIONS]; - walk = new MultiFrameImage[Sprite.NUM_DIRECTIONS]; - } + ", seqs=" + StringUtil.toString(_seqs) + "]"; } /** The unique character component identifier. */ protected int _cid; - /** The animation frames. */ - protected ComponentFrames _frames; + /** The file id specifier for the tile set image file name. */ + protected String _fileid; + + /** The animation frames for each action sequence and orientation. */ + protected MultiFrameImage _frames[][]; /** The component class. */ protected ComponentClass _cclass; - /** The character component type. */ - protected ComponentType _type; + /** The character action sequences. */ + protected ActionSequence _seqs[]; } diff --git a/src/java/com/threerings/cast/CharacterDescriptor.java b/src/java/com/threerings/cast/CharacterDescriptor.java index f326c06c1..2d18a20d2 100644 --- a/src/java/com/threerings/cast/CharacterDescriptor.java +++ b/src/java/com/threerings/cast/CharacterDescriptor.java @@ -1,5 +1,5 @@ // -// $Id: CharacterDescriptor.java,v 1.2 2001/10/30 16:16:01 shaper Exp $ +// $Id: CharacterDescriptor.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; @@ -14,14 +14,13 @@ public class CharacterDescriptor /** * Constructs the character descriptor. */ - public CharacterDescriptor (ComponentType type, int components[]) + public CharacterDescriptor (int components[]) { - _type = type; _components = components; } /** - * Returns a list of the component identifiers comprising the + * Returns an array of the component identifiers comprising the * character described by this descriptor. */ public int[] getComponents () @@ -29,28 +28,16 @@ public class CharacterDescriptor return _components; } - /** - * Returns the {@link ComponentType} of the character's components. - */ - public ComponentType getType () - { - return _type; - } - /** * Returns a string representation of this character descriptor. */ public String toString () { StringBuffer buf = new StringBuffer(); - buf.append("[type=").append(_type); - buf.append(StringUtil.toString(_components)); + buf.append("[").append(StringUtil.toString(_components)); return buf.append("]").toString(); } - /** The array of component identifiers. */ - protected int _components[]; - - /** The component type of the character's components. */ - protected ComponentType _type; + /** The component identifiers comprising the character. */ + protected int[] _components; } diff --git a/src/java/com/threerings/cast/CharacterManager.java b/src/java/com/threerings/cast/CharacterManager.java index 64f8de3dd..3cdc7ab7b 100644 --- a/src/java/com/threerings/cast/CharacterManager.java +++ b/src/java/com/threerings/cast/CharacterManager.java @@ -1,5 +1,5 @@ // -// $Id: CharacterManager.java,v 1.6 2001/10/30 16:16:01 shaper Exp $ +// $Id: CharacterManager.java,v 1.7 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; @@ -8,7 +8,9 @@ import java.util.*; import com.samskivert.util.CollectionUtil; import com.threerings.cast.Log; -import com.threerings.cast.CharacterComponent.ComponentFrames; + +import com.threerings.media.sprite.MultiFrameImage; +import com.threerings.media.sprite.Sprite; /** * The character manager provides facilities for constructing sprites @@ -40,16 +42,17 @@ public class CharacterManager long start = System.currentTimeMillis(); // get the array of component ids of each class - int components[] = desc.getComponents(); - + CharacterComponent components[] = getComponents(desc.getComponents()); if (components.length == 0) { - Log.warning("Invalid number of components " + - "[size=" + components.length + "]."); + Log.warning("No character components in descriptor."); return null; } + // assume all components support the same set of action sequences + ActionSequence seqs[] = components[0].getActionSequences(); // create the composite character image - ComponentFrames frames = createCompositeFrames(desc); + MultiFrameImage frames[][] = + createCompositeFrames(seqs.length, components); if (frames == null) { return null; } @@ -61,10 +64,7 @@ public class CharacterManager } // populate the character sprite with its attributes - ComponentType ctype = desc.getType(); - sprite.setFrames(frames); - sprite.setFrameRate(ctype.fps); - sprite.setOrigin(ctype.origin.x, ctype.origin.y); + sprite.setAnimations(seqs, frames); long end = System.currentTimeMillis(); Log.info("Generated character sprite [ms=" + (end - start) + "]."); @@ -72,30 +72,9 @@ public class CharacterManager return sprite; } - /** - * Returns an iterator over the {@link ComponentType} objects - * representing all available character component type - * identifiers. - */ - public Iterator enumerateComponentTypes () - { - return _repo.enumerateComponentTypes(); - } - - /** - * Returns an iterator over the Integer objects - * representing all available character component identifiers for - * the given character component type identifier. - */ - public Iterator enumerateComponentsByType (int ctid) - { - return _repo.enumerateComponentsByType(ctid); - } - /** * Returns an iterator over the {@link ComponentClass} objects - * representing all available character component class - * identifiers. + * representing all available character component classes. */ public Iterator enumerateComponentClasses () { @@ -105,11 +84,11 @@ public class CharacterManager /** * Returns an iterator over the Integer objects * representing all available character component identifiers for - * the given character component type and class identifiers. + * the given character component class identifier. */ - public Iterator enumerateComponentsByClass (int ctid, int clid) + public Iterator enumerateComponentsByClass (int clid) { - return _repo.enumerateComponentsByClass(ctid, clid); + return _repo.enumerateComponentsByClass(clid); } /** @@ -131,44 +110,52 @@ public class CharacterManager } /** - * Returns a {@link CharacterComponent.ComponentFrames} object - * containing the fully composited images detailed in the given - * character descriptor. + * Returns an array of the character component objects specified + * in the given array of component ids. */ - protected ComponentFrames createCompositeFrames (CharacterDescriptor desc) + protected CharacterComponent[] getComponents (int cids[]) { - int components[] = desc.getComponents(); - ComponentFrames frames = null; + int size = cids.length; + CharacterComponent components[] = new CharacterComponent[size]; - for (int ii = 0; ii < _renderRank.length; ii++) { - try { - int clidx = _renderRank[ii].clid; - - // get the component to render - CharacterComponent c = _repo.getComponent(components[clidx]); - - // TODO: fix this to deal with frames of varying dimensions - if (frames == null) { - int fcount = desc.getType().frameCount; - frames = TileUtil.createBlankFrames(c.getFrames(), fcount); - } - - // render the frames onto the composite frames - TileUtil.compositeFrames(frames, c.getFrames()); - - } catch (NoSuchComponentException nsce) { - Log.warning("Exception compositing character components " + - "[nsce=" + nsce + "]."); - return null; + try { + for (int ii = 0; ii < size; ii++) { + components[ii] = _repo.getComponent(cids[ii]); } + + } catch (NoSuchComponentException nsce) { + Log.warning("Exception retrieving character component " + + "[nsce=" + nsce + "]."); + return null; + } + + return components; + } + + /** + * Returns an array of multi frame images containing the fully + * composited images for the given action sequences and + * components. + */ + protected MultiFrameImage[][] createCompositeFrames ( + int seqCount, CharacterComponent components[]) + { + MultiFrameImage frames[][] = + new MultiFrameImage[seqCount][Sprite.NUM_DIRECTIONS]; + + // render all component frames one atop another + for (int ii = 0; ii < _renderRank.length; ii++) { + int clidx = _renderRank[ii].clid; + Log.info("Compositing component [c=" + components[clidx] + "]."); + TileUtil.compositeFrames(frames, components[clidx].getFrames()); } return frames; } /** - * Returns a new {@link CharacterSprite} of the character class - * specified for use by this character manager. + * Returns a new instance of the {@link CharacterSprite}-derived + * class specified for use by this character manager. */ protected CharacterSprite createSprite () { diff --git a/src/java/com/threerings/cast/CharacterSprite.java b/src/java/com/threerings/cast/CharacterSprite.java index 07643cc41..2be6087a5 100644 --- a/src/java/com/threerings/cast/CharacterSprite.java +++ b/src/java/com/threerings/cast/CharacterSprite.java @@ -1,5 +1,5 @@ // -// $Id: CharacterSprite.java,v 1.16 2001/10/26 01:17:21 shaper Exp $ +// $Id: CharacterSprite.java,v 1.17 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; @@ -8,7 +8,6 @@ import java.awt.Point; import com.threerings.media.sprite.*; import com.threerings.cast.Log; -import com.threerings.cast.CharacterComponent.ComponentFrames; /** * A character sprite is a sprite that animates itself while walking @@ -26,26 +25,41 @@ public class CharacterSprite extends Sprite } /** - * Sets the walking and standing frames of animation used to - * display this character. + * Sets the action sequences available for this character sprite + * and the animation frames that go along with each action. + * Resets the character's currently selected action sequence to + * the standing sequence. */ - public void setFrames (ComponentFrames frames) + public void setAnimations (ActionSequence[] seqs, + MultiFrameImage anims[][]) { - _anims = frames; - setFrames(_anims.walk[_orient]); + _seqs = seqs; + _anims = anims; + setActionSequence(WALKING); + } + + /** + * Sets the action sequence used when rendering the character, + * from the set of available sequences. + */ + public void setActionSequence (int seqidx) + { + // save off the action sequence index + _seqidx = seqidx; + + // update the sprite render attributes + ActionSequence seq = _seqs[_seqidx]; + setFrames(_anims[_seqidx][_orient]); + setFrameRate(seq.fps); + setOrigin(seq.origin.x, seq.origin.y); } // documentation inherited public void setOrientation (int orient) { super.setOrientation(orient); - // update the sprite frames to reflect the direction - if (_path == null) { - setFrames(_anims.stand[_orient]); - } else { - setFrames(_anims.walk[_orient]); - } + setActionSequence((_path == null) ? STANDING : WALKING); } /** @@ -104,14 +118,25 @@ public class CharacterSprite extends Sprite protected void halt () { // come to a halt looking settled and at peace - setFrames(_anims.stand[_orient]); - + setActionSequence(STANDING); // disable walking animation setAnimationMode(NO_ANIMATION); } - /** The standing and walking animations for the sprite. */ - protected ComponentFrames _anims; + /** The action sequence constant for standing. */ + protected static final int STANDING = 0; + + /** The action sequence constant for walking. */ + protected static final int WALKING = 1; + + /** The currently selected action sequence. */ + protected int _seqidx; + + /** The available action sequences. */ + protected ActionSequence _seqs[]; + + /** The animation frames for each action sequence and orientation. */ + protected MultiFrameImage _anims[][]; /** The origin of the sprite. */ protected int _xorigin, _yorigin; diff --git a/src/java/com/threerings/cast/ComponentRepository.java b/src/java/com/threerings/cast/ComponentRepository.java index f0be4736f..ca575a285 100644 --- a/src/java/com/threerings/cast/ComponentRepository.java +++ b/src/java/com/threerings/cast/ComponentRepository.java @@ -1,5 +1,5 @@ // -// $Id: ComponentRepository.java,v 1.2 2001/10/30 16:16:01 shaper Exp $ +// $Id: ComponentRepository.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; @@ -19,19 +19,6 @@ public interface ComponentRepository public CharacterComponent getComponent (int cid) throws NoSuchComponentException; - /** - * Returns an iterator over the {@link ComponentType} objects - * representing all available character component types. - */ - public Iterator enumerateComponentTypes (); - - /** - * Returns an iterator over the Integer objects - * representing all available character component identifiers for - * the given character component type identifier. - */ - public Iterator enumerateComponentsByType (int ctid); - /** * Returns an iterator over the {@link ComponentClass} objects * representing all available character component classes. @@ -41,7 +28,7 @@ public interface ComponentRepository /** * Returns an iterator over the Integer objects * representing all available character component identifiers for - * the given character component type and class identifiers. + * the given character component class identifier. */ - public Iterator enumerateComponentsByClass (int ctid, int clid); + public Iterator enumerateComponentsByClass (int clid); } diff --git a/src/java/com/threerings/cast/ComponentType.java b/src/java/com/threerings/cast/ComponentType.java deleted file mode 100644 index 65dab2798..000000000 --- a/src/java/com/threerings/cast/ComponentType.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// $Id: ComponentType.java,v 1.1 2001/10/26 01:17:21 shaper Exp $ - -package com.threerings.cast; - -import java.awt.Point; - -/** - * The component type class contains the base information necessary - * for a variety of {@link CharacterComponent} objects to be usefully - * composited into animation sequences representing a character. - */ -public class ComponentType -{ - /** The unique component type identifier. */ - public int ctid; - - /** The number of animation frames. */ - public int frameCount; - - /** The number of frames per second to show when animating. */ - public int fps; - - /** The origin of the component type's base. */ - public Point origin = new Point(); - - /** - * Returns a string representation of this component type. - */ - public String toString () - { - return "[ctid=" + ctid + ", frameCount=" + frameCount + - ", fps=" + fps + ", origin=" + origin + "]"; - } -} diff --git a/src/java/com/threerings/cast/TileUtil.java b/src/java/com/threerings/cast/TileUtil.java index c51a25b0d..3fa00e9a9 100644 --- a/src/java/com/threerings/cast/TileUtil.java +++ b/src/java/com/threerings/cast/TileUtil.java @@ -1,5 +1,5 @@ // -// $Id: TileUtil.java,v 1.3 2001/10/30 16:16:01 shaper Exp $ +// $Id: TileUtil.java,v 1.4 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; @@ -10,7 +10,6 @@ import com.threerings.media.sprite.*; import com.threerings.media.tile.*; import com.threerings.cast.Log; -import com.threerings.cast.CharacterComponent.ComponentFrames; /** * Miscellaneous tile-related utility functions. @@ -19,79 +18,84 @@ public class TileUtil { /** * Renders each of the given src component frames - * into the corresponding frames of dest. + * into the corresponding frames of dest, allocating + * blank image frames for dest if none yet exist. */ public static void compositeFrames ( - ComponentFrames dest, ComponentFrames src) + MultiFrameImage[][] dest, MultiFrameImage[][] src) { - for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) { - // composite the standing frames - compositeFrames(dest.stand[ii], src.stand[ii]); + for (int ii = 0; ii < dest.length; ii++) { + for (int orient = 0; orient < Sprite.NUM_DIRECTIONS; orient++) { + // create blank destination frames if needed + if (dest[ii][orient] == null) { + dest[ii][orient] = createBlankFrames(src[ii][orient]); + } - // composite the walking frames - compositeFrames(dest.walk[ii], src.walk[ii]); + // slap the images together + compositeFrames(dest[ii][orient], src[ii][orient]); + } } } /** - * Constructs and returns a new {@link - * CharacterComponent.ComponentFrames} object with empty images - * for all of its frames. + * Returns a new {@link MultiFrameImage} that has empty images in + * all frames. The number of frames in the resulting multi frame + * image is the same as the frame count for src. */ - public static ComponentFrames createBlankFrames ( - ComponentFrames src, int frameCount) + public static MultiFrameImage createBlankFrames (MultiFrameImage src) { - ComponentFrames frames = new ComponentFrames(); - - // for now, just use the first frame from the source image to - // get the width and height for all of the blank frames - Image img = src.walk[0].getFrame(0); + // TODO: for now, just use the first frame from the source to + // get the width and height for all of the blank frames. fix + // this hack soon. + Image img = src.getFrame(0); int wid = img.getWidth(null), hei = img.getHeight(null); - - // allocate the blank frame images - for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) { - frames.stand[ii] = new BlankFrameImage(wid, hei, 1); - frames.walk[ii] = new BlankFrameImage(wid, hei, frameCount); - } - - return frames; + return new BlankFrameImage(wid, hei, src.getFrameCount()); } /** - * Returns a {@link CharacterComponent.ComponentFrames} object - * containing the frames of animation used to render the sprite while - * standing or walking in each of the directions it may face. The - * tileset id referenced must contain - * Sprite.NUM_DIRECTIONS rows of tiles, with each row - * containing first the single standing tile, followed by - * frameCount tiles describing the walking animation. - * - * @param tilemgr the tile manager to retrieve tiles from. - * @param tsid the tileset id containing the sprite tiles. - * @param frameCount the number of walking frames of animation. + * Returns a two-dimensional array of multi frame images + * containing the frames of animation used to render the sprite + * while standing or walking in each of the directions it may + * face. */ - public static ComponentFrames getComponentFrames ( - TileManager tilemgr, int tsid, int frameCount) + public static MultiFrameImage[][] getComponentFrames ( + String imagedir, CharacterComponent c) { - ComponentFrames frames = new ComponentFrames(); + ActionSequence seqs[] = c.getActionSequences(); + MultiFrameImage frames[][] = + new MultiFrameImage[seqs.length][Sprite.NUM_DIRECTIONS]; try { - for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) { + for (int ii = 0; ii < seqs.length; ii++) { + ActionSequence as = seqs[ii]; - Image walkimgs[] = new Image[frameCount]; - int rowcount = frameCount + 1; - for (int jj = 0; jj < rowcount; jj++) { - int idx = (ii * rowcount) + jj; + // get the tile set containing the component tiles for + // this action sequence + String file = getImageFile(imagedir, as, c); + TileSet tset = null; - Image img = tilemgr.getTile(tsid, idx).img; - if (jj == 0) { - frames.stand[ii] = new SingleFrameImageImpl(img); - } else { - walkimgs[jj - 1] = img; + try { + tset = as.tileset.clone(file); + } catch (CloneNotSupportedException e) { + Log.warning("Failed to clone tile set " + + "[tset=" + as.tileset + "]."); + return null; + } + + // get the number of frames of animation + int frameCount = tset.getNumTiles() / Sprite.NUM_DIRECTIONS; + + for (int dir = 0; dir < Sprite.NUM_DIRECTIONS; dir++) { + // retrieve all images for the sequence and direction + Image imgs[] = new Image[frameCount]; + for (int jj = 0; jj < frameCount; jj++) { + int idx = (dir * frameCount) + jj; + imgs[jj] = tset.getTile(idx).img; } - } - frames.walk[ii] = new MultiFrameImageImpl(walkimgs); + // create the multi frame image + frames[ii][dir] = new MultiFrameImageImpl(imgs); + } } } catch (TileException te) { @@ -103,6 +107,15 @@ public class TileUtil return frames; } + /** + * Returns the file path for the given action sequence and component. + */ + protected static String getImageFile ( + String imagedir, ActionSequence as, CharacterComponent c) + { + return imagedir + as.fileid + "_" + c.getFileId() + IMAGE_SUFFIX; + } + /** * Renders each of the given src frames into the * corresponding frames of dest. @@ -112,9 +125,9 @@ public class TileUtil { int dsize = dest.getFrameCount(), ssize = src.getFrameCount(); if (dsize != ssize) { - Log.warning("Can't composite multi frame images " + - "with differing frame counts " + - "[dest=" + dsize + ", src=" + ssize + "]."); + Log.warning( + "Can't composite images with differing frame counts " + + "[dest=" + dsize + ", src=" + ssize + "]."); return; } @@ -159,4 +172,7 @@ public class TileUtil /** The frame images. */ protected Image _imgs[]; } + + /** The image file name suffix appended to component image file names. */ + protected static final String IMAGE_SUFFIX = ".png"; } diff --git a/src/java/com/threerings/cast/builder/BuilderPanel.java b/src/java/com/threerings/cast/builder/BuilderPanel.java index d9f48b342..727c26a3c 100644 --- a/src/java/com/threerings/cast/builder/BuilderPanel.java +++ b/src/java/com/threerings/cast/builder/BuilderPanel.java @@ -1,5 +1,5 @@ // -// $Id: BuilderPanel.java,v 1.1 2001/10/30 16:16:01 shaper Exp $ +// $Id: BuilderPanel.java,v 1.2 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast.builder; @@ -37,8 +37,7 @@ public class BuilderPanel extends JPanel implements ActionListener // create the component selection and sprite display panels JPanel sub = new JPanel(gl); - ComponentType ctype = getComponentType(); - sub.add(_comppanel = new ComponentPanel(_charmgr, ctype)); + sub.add(_comppanel = new ComponentPanel(_charmgr)); sub.add(_spritepanel = new SpritePanel()); add(sub); @@ -62,15 +61,6 @@ public class BuilderPanel extends JPanel implements ActionListener } } - protected ComponentType getComponentType () - { - ComponentType ctype = null; - Iterator types = _charmgr.enumerateComponentTypes(); - // for now, fixedly choose the first component type - // TODO: fix this hack - return (ComponentType)types.next(); - } - /** The component panel that displays components available for * selection. */ protected ComponentPanel _comppanel; diff --git a/src/java/com/threerings/cast/builder/ComponentPanel.java b/src/java/com/threerings/cast/builder/ComponentPanel.java index 4eabacd41..60d2c0c1f 100644 --- a/src/java/com/threerings/cast/builder/ComponentPanel.java +++ b/src/java/com/threerings/cast/builder/ComponentPanel.java @@ -1,5 +1,5 @@ // -// $Id: ComponentPanel.java,v 1.1 2001/10/30 16:16:01 shaper Exp $ +// $Id: ComponentPanel.java,v 1.2 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast.builder; @@ -27,11 +27,8 @@ public class ComponentPanel extends JPanel /** * Constructs the component panel. */ - public ComponentPanel (CharacterManager charmgr, ComponentType type) + public ComponentPanel (CharacterManager charmgr) { - // save off references - _type = type; - // retrieve component classes and relevant components gatherComponentInfo(charmgr); @@ -60,7 +57,7 @@ public class ComponentPanel extends JPanel comps[cclass.clid] = ce.getSelectedComponent(); } - return new CharacterDescriptor(_type, comps); + return new CharacterDescriptor(comps); } /** @@ -75,9 +72,8 @@ public class ComponentPanel extends JPanel for (int ii = 0; ii < _classes.size(); ii++) { // get the list of components available for this class - int ctid = _type.ctid; int clid = ((ComponentClass)_classes.get(ii)).clid; - Iterator comps = charmgr.enumerateComponentsByClass(ctid, clid); + Iterator comps = charmgr.enumerateComponentsByClass(clid); while (comps.hasNext()) { Integer cid = (Integer)comps.next(); @@ -112,9 +108,6 @@ public class ComponentPanel extends JPanel } } - /** The component type associated with the character components. */ - protected ComponentType _type; - /** The list of all available component classes. */ protected ArrayList _classes = new ArrayList(); diff --git a/src/java/com/threerings/cast/tools/xml/XMLComponentParser.java b/src/java/com/threerings/cast/tools/xml/XMLComponentParser.java index a405bae47..aa5f6c246 100644 --- a/src/java/com/threerings/cast/tools/xml/XMLComponentParser.java +++ b/src/java/com/threerings/cast/tools/xml/XMLComponentParser.java @@ -1,72 +1,65 @@ // -// $Id: XMLComponentParser.java,v 1.2 2001/10/30 16:16:01 shaper Exp $ +// $Id: XMLComponentParser.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast; import java.awt.Point; import java.io.IOException; +import java.util.Arrays; import org.xml.sax.*; -import com.samskivert.util.HashIntMap; -import com.samskivert.util.StringUtil; -import com.samskivert.util.Tuple; +import com.samskivert.util.*; import com.samskivert.xml.SimpleParser; +import com.threerings.media.ImageManager; +import com.threerings.media.tile.*; + +import com.threerings.cast.Log; + /** * Parses an XML character component description file and populates - * hashtables with component type, component class, and specific - * component information. Does not currently perform validation on - * the input XML stream, though the parsing code assumes the XML - * document is well-formed. + * hashtables with {@link ActionSequence}, {@link ComponentClass}, and + * the information necessary to construct {@link CharacterComponent} + * objects. + * + *

Does not currently perform validation on the input XML stream, + * though the parsing code assumes the XML document is well-formed. */ public class XMLComponentParser extends SimpleParser { - // documentation inherited - public void startElement (String uri, String localName, - String qName, Attributes attributes) + /** + * Constructs an xml component parser. + */ + public XMLComponentParser (ImageManager imgmgr) { - if (qName.equals("type")) { - // construct the component type object - ComponentType ct = new ComponentType(); + _imgmgr = imgmgr; + } - // retrieve character attributes - ct.ctid = parseInt(attributes.getValue("ctid")); - ct.frameCount = parseInt(attributes.getValue("frames")); - ct.fps = parseInt(attributes.getValue("fps")); - parsePoint(attributes.getValue("origin"), ct.origin); + // documentation inherited + public void startElement ( + String uri, String localName, String qName, Attributes attributes) + { + if (qName.equals("charactercomponents")) { + // save off the image directory + _imagedir = attributes.getValue("imagedir"); + // load the tile sets + loadTileSets(attributes.getValue("tilesets")); - // save the component type - _types.put(ct.ctid, ct); + } else if (qName.equals("action")) { + // construct and save off the action sequence object + ActionSequence as = getActionSequence(attributes); + _actions.put(as.asid, as); } else if (qName.equals("class")) { - // save off the component class info - ComponentClass cclass = new ComponentClass(); - cclass.clid = parseInt(attributes.getValue("clid")); - cclass.name = attributes.getValue("name"); - cclass.render = parseInt(attributes.getValue("render")); + // construct and save off the component class object + ComponentClass cclass = getComponentClass(attributes); _classes.put(cclass.clid, cclass); } else if (qName.equals("component")) { - // retrieve the component attributes - int cid = parseInt(attributes.getValue("cid")); - int ctid = parseInt(attributes.getValue("ctid")); - int clid = parseInt(attributes.getValue("clid")); - - // output a warning if the component references valid - // attributes - if (_types.get(ctid) == null) { - Log.warning("Component references non-existent type " + - "[cid=" + cid + ", ctid=" + ctid + "]."); - } - if (_classes.get(clid) == null) { - Log.warning("Component references non-existent class " + - "[cid=" + cid + ", clid=" + clid + "]."); - } - - // save off the component information - _components.put(cid, new Tuple( - new Integer(ctid), new Integer(clid))); + // construct and save off the character component + CharacterComponent component = getComponent(attributes); + _components.put(component.getId(), component); } } @@ -74,19 +67,161 @@ public class XMLComponentParser extends SimpleParser * Loads the component descriptions in the given file into the * given component data hashtables. */ - public void loadComponents ( - String file, HashIntMap types, HashIntMap classes, - HashIntMap components) + public void loadComponents (String file, HashIntMap actions, + HashIntMap classes, HashIntMap components) throws IOException { // save off hashtables for reference while parsing - _types = types; + _actions = actions; _classes = classes; _components = components; + // clear out remnants of any previous parsing antics + _imagedir = null; + _tilesets.clear(); + + // parse the file parseFile(file); } + /** + * Returns the image directory the component tile images reside + * within. + */ + public String getImageDir () + { + return _imagedir; + } + + /** + * Loads the tile sets in the XML file at the given path into the + * tile sets available for reference by the action sequences. + */ + protected void loadTileSets (String path) + { + // make sure we have a reasonable path + if (path == null) { + Log.warning("Null component tile set description file path."); + return; + } + + // parse the tile set description file + XMLTileSetParser p = new XMLTileSetParser(_imgmgr); + try { + p.loadTileSets(path, _tilesets); + } catch (IOException e) { + Log.warning("Exception loading component tile set descriptions " + + "[path=" + path + "]."); + } + } + + /** + * Returns a new action sequence object as described by the given + * attributes. + */ + protected ActionSequence getActionSequence (Attributes attrs) + { + ActionSequence as = new ActionSequence(); + + as.asid = parseInt(attrs.getValue("asid")); + as.name = attrs.getValue("name"); + as.fileid = attrs.getValue("fileid"); + + int tsid = parseInt(attrs.getValue("tsid")); + as.tileset = (TileSet)_tilesets.get(tsid); + if (as.tileset == null) { + Log.warning("Action sequence references non-existent " + + "tile set [asid=" + as.asid + ", tsid=" + tsid + "]."); + } + + as.fps = parseInt(attrs.getValue("fps")); + parsePoint(attrs.getValue("origin"), as.origin); + + return as; + } + + /** + * Returns a new component class object as described by the given + * attributes. + */ + protected ComponentClass getComponentClass (Attributes attrs) + { + ComponentClass cclass = new ComponentClass(); + cclass.clid = parseInt(attrs.getValue("clid")); + cclass.name = attrs.getValue("name"); + cclass.render = parseInt(attrs.getValue("render")); + return cclass; + } + + /** + * Returns a new character component object as described by the + * given attributes. + */ + protected CharacterComponent getComponent (Attributes attrs) + { + // retrieve the component attributes + int cid = parseInt(attrs.getValue("cid")); + String fileid = attrs.getValue("fileid"); + String val = attrs.getValue("asids"); + int asids[] = StringUtil.parseIntArray(val); + int clid = parseInt(attrs.getValue("clid")); + ComponentClass cclass = (ComponentClass)_classes.get(clid); + + // gather the array of relevant action sequences + ActionSequence seqs[] = getActionSequences(asids); + + // construct the component sans frames for now + CharacterComponent component = + new CharacterComponent(cid, fileid, seqs, cclass); + + // warn if the component has notably invalid attributes + validateComponent(cid, asids, clid); + + return component; + } + + /** + * Outputs a warning regarding the given component id if the given + * action sequence ids and component class id for that component + * don't exist. + */ + protected void validateComponent (int cid, int asids[], int clid) + { + // check the action sequence ids + for (int ii = 0; ii < asids.length; ii++) { + int asid = asids[ii]; + if (_actions.get(asid) == null) { + Log.warning( + "Component references non-existent action sequence " + + "[cid=" + cid + ", asid=" + asid + "]."); + } + } + + // check the class id + if (_classes.get(clid) == null) { + Log.warning("Component references non-existent class " + + "[cid=" + cid + ", clid=" + clid + "]."); + } + } + + /** + * Returns an array of action sequence objects corresponding to + * the action sequence ids in the given array. + */ + protected ActionSequence[] getActionSequences (int asids[]) + { + // sort the action sequence ids for better regularity + Arrays.sort(asids); + + // create and populate the array + ActionSequence[] seqs = new ActionSequence[asids.length]; + for (int ii = 0; ii < asids.length; ii++) { + seqs[ii] = (ActionSequence)_actions.get(asids[ii]); + } + + return seqs; + } + /** * Converts a string containing values as (x, y) into the * corresponding integer values and populates the given point @@ -101,12 +236,21 @@ public class XMLComponentParser extends SimpleParser point.setLocation(vals[0], vals[1]); } - /** The hashtable of component types gathered while parsing. */ - protected HashIntMap _types; + /** The image directory containing the component image files. */ + protected String _imagedir; + + /** The hashtable of component tile sets. */ + protected HashIntMap _tilesets = new HashIntMap(); + + /** The hashtable of action sequences gathered while parsing. */ + protected HashIntMap _actions; + + /** The hashtable of component classes gathered while parsing. */ + protected HashIntMap _classes; /** The hashtable of character components gathered while parsing. */ protected HashIntMap _components; - /** The hashtable of component classes gathered while parsing. */ - protected HashIntMap _classes; + /** The image manager. */ + protected ImageManager _imgmgr; } diff --git a/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java b/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java index b0735451b..6a04b6695 100644 --- a/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java +++ b/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java @@ -1,5 +1,5 @@ // -// $Id: XMLComponentRepository.java,v 1.2 2001/10/30 16:16:01 shaper Exp $ +// $Id: XMLComponentRepository.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.miso.scene.xml; @@ -12,8 +12,8 @@ import com.samskivert.util.HashIntMap; import com.samskivert.util.Tuple; import com.threerings.cast.*; -import com.threerings.cast.CharacterComponent.ComponentFrames; +import com.threerings.media.ImageManager; import com.threerings.media.tile.TileManager; import com.threerings.miso.Log; @@ -29,16 +29,15 @@ public class XMLFileComponentRepository implements ComponentRepository /** * Constructs an xml file component repository. */ - public XMLFileComponentRepository (Config config, TileManager tilemgr) + public XMLFileComponentRepository (Config config, ImageManager imgmgr) { - // save off our objects - _tilemgr = tilemgr; - // load component types and components - String file = config.getValue(COMPFILE_KEY, DEFAULT_COMPFILE); + String file = config.getValue(COMPONENTS_KEY, DEFAULT_COMPONENTS); try { - XMLComponentParser p = new XMLComponentParser(); - p.loadComponents(file, _types, _classes, _components); + XMLComponentParser p = new XMLComponentParser(imgmgr); + p.loadComponents(file, _actions, _classes, _components); + _imagedir = p.getImageDir(); + } catch (IOException ioe) { Log.warning("Exception loading component descriptions " + "[ioe=" + ioe + "]."); @@ -50,37 +49,15 @@ public class XMLFileComponentRepository implements ComponentRepository throws NoSuchComponentException { // get the component information - Tuple cinfo = (Tuple)_components.get(cid); - if (cinfo == null) { + CharacterComponent c = (CharacterComponent)_components.get(cid); + if (c == null) { throw new NoSuchComponentException(cid); } - // get the component type - int ctid = ((Integer)cinfo.left).intValue(); - ComponentType type = (ComponentType)_types.get(ctid); + // get the character animation frames + c.setFrames(TileUtil.getComponentFrames(_imagedir, c)); - // get the component class - int clid = ((Integer)cinfo.right).intValue(); - ComponentClass cclass = (ComponentClass)_classes.get(clid); - - // get the character animation images - ComponentFrames frames = TileUtil.getComponentFrames( - _tilemgr, cid, type.frameCount); - - // create the component - return new CharacterComponent(type, cclass, cid, frames); - } - - // documentation inherited - public Iterator enumerateComponentTypes () - { - return Collections.unmodifiableMap(_types).values().iterator(); - } - - // documentation inherited - public Iterator enumerateComponentsByType (int ctid) - { - return new ComponentIterator(ctid); + return c; } // documentation inherited @@ -90,9 +67,9 @@ public class XMLFileComponentRepository implements ComponentRepository } // documentation inherited - public Iterator enumerateComponentsByClass (int ctid, int clid) + public Iterator enumerateComponentsByClass (int clid) { - return new ComponentIterator(ctid, clid); + return new ComponentIterator(clid); } /** @@ -104,20 +81,13 @@ public class XMLFileComponentRepository implements ComponentRepository { /** * Constructs an iterator that iterates over all components of - * the specified component type. + * the specified component class. */ - public ComponentIterator (int ctid) + public ComponentIterator (int clid) { - init(ctid, -1); - } - - /** - * Constructs an iterator that iterates over all components of - * the specified component type and class. - */ - public ComponentIterator (int ctid, int clid) - { - init(ctid, clid); + _clid = clid; + _iter = _components.keys(); + advance(); } public boolean hasNext () @@ -137,24 +107,14 @@ public class XMLFileComponentRepository implements ComponentRepository throw new UnsupportedOperationException(); } - protected void init (int ctid, int clid) - { - _ctid = ctid; - _clid = clid; - _iter = _components.keys(); - advance(); - } - protected void advance () { while (_iter.hasNext()) { Integer cid = (Integer)_iter.next(); - Tuple c = (Tuple)_components.get(cid); - int ctid = ((Integer)c.left).intValue(); - int clid = ((Integer)c.right).intValue(); - if (ctid == _ctid && - (_clid == -1 || (clid == _clid))) { + CharacterComponent c = + (CharacterComponent)_components.get(cid); + if (c.getComponentClass().clid == _clid) { _next = cid; return; } @@ -162,15 +122,11 @@ public class XMLFileComponentRepository implements ComponentRepository _next = null; } - /** The component type id we're enumerating over. */ - protected int _ctid; - - /** The component class id required for inclusion in the - * iterator, or -1 for all classes. */ + /** The component class id for inclusion in the iterator. */ protected int _clid; - /** The next character component of the component type id - * associated with this iterator, or null if no more exist. */ + /** The next character component associated with this + * iterator, or null if no more exist. */ protected Object _next; /** The iterator over all components in the repository. */ @@ -178,22 +134,22 @@ public class XMLFileComponentRepository implements ComponentRepository } /** The config key for the character description file. */ - protected static final String COMPFILE_KEY = + protected static final String COMPONENTS_KEY = MisoUtil.CONFIG_KEY + ".components"; /** The default character description file. */ - protected static final String DEFAULT_COMPFILE = + protected static final String DEFAULT_COMPONENTS = "rsrc/config/miso/components.xml"; + /** The image directory containing the component image files. */ + protected String _imagedir; + /** The hashtable of component types. */ - protected HashIntMap _types = new HashIntMap(); + protected HashIntMap _actions = new HashIntMap(); /** The hashtable of component classes. */ protected HashIntMap _classes = new HashIntMap(); /** The hashtable of character components. */ protected HashIntMap _components = new HashIntMap(); - - /** The tile manager. */ - protected TileManager _tilemgr; } diff --git a/src/java/com/threerings/media/tile/ObjectTile.java b/src/java/com/threerings/media/tile/ObjectTile.java index 3853dd5f3..d3afd1fe8 100644 --- a/src/java/com/threerings/media/tile/ObjectTile.java +++ b/src/java/com/threerings/media/tile/ObjectTile.java @@ -1,5 +1,5 @@ // -// $Id: ObjectTile.java,v 1.2 2001/10/12 00:38:15 shaper Exp $ +// $Id: ObjectTile.java,v 1.3 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; @@ -27,4 +27,12 @@ public class ObjectTile extends Tile this.baseWidth = baseWidth; this.baseHeight = baseHeight; } + + // documentation inherited + public void toString (StringBuffer buf) + { + super.toString(buf); + buf.append(", baseWidth=").append(baseWidth); + buf.append(", baseHeight=").append(baseHeight); + } } diff --git a/src/java/com/threerings/media/tile/Tile.java b/src/java/com/threerings/media/tile/Tile.java index 7a8a27d97..767b11217 100644 --- a/src/java/com/threerings/media/tile/Tile.java +++ b/src/java/com/threerings/media/tile/Tile.java @@ -1,5 +1,5 @@ // -// $Id: Tile.java,v 1.16 2001/10/22 18:11:25 shaper Exp $ +// $Id: Tile.java,v 1.17 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; @@ -64,8 +64,19 @@ public class Tile public String toString () { StringBuffer buf = new StringBuffer(); - buf.append("[tsid=").append(tsid); - buf.append(", tid=").append(tid); + 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 tile information to the string buffer. + */ + public void toString (StringBuffer buf) + { + buf.append("tsid=").append(tsid); + buf.append(", tid=").append(tid); + } } diff --git a/src/java/com/threerings/media/tile/TileManager.java b/src/java/com/threerings/media/tile/TileManager.java index 58151094a..63ce618ea 100644 --- a/src/java/com/threerings/media/tile/TileManager.java +++ b/src/java/com/threerings/media/tile/TileManager.java @@ -1,5 +1,5 @@ // -// $Id: TileManager.java,v 1.18 2001/10/11 00:41:26 shaper Exp $ +// $Id: TileManager.java,v 1.19 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; @@ -14,19 +14,17 @@ import com.threerings.media.Log; /** * The tile manager provides a simplified interface for retrieving and * caching tiles. - * - * @see TileSetManager */ public class TileManager { /** - * Initialize the tile manager. + * Initializes the tile manager. * - * @param tilesetmgr the tileset manager. + * @param tilesetrepo the tile set repository. */ - public TileManager (TileSetManager tilesetmgr) + public TileManager (TileSetRepository tsrepo) { - _tilesetmgr = tilesetmgr; + _tsrepo = tsrepo; } /** @@ -53,7 +51,7 @@ public class TileManager } // retrieve the tile from the tileset - tile = _tilesetmgr.getTile(tsid, tid); + tile = _tsrepo.getTileSet(tsid).getTile(tid); if (tile != null) { // Log.info("Loaded tile into cache [tsid=" + tsid + // ", tid=" + tid + "]."); @@ -64,16 +62,16 @@ public class TileManager } /** - * Returns the tile set manager used by this tile manager. + * Returns the tile set repository used by this tile manager. */ - public TileSetManager getTileSetManager () + public TileSetRepository getTileSetRepository () { - return _tilesetmgr; + return _tsrepo; } /** Cache of tiles that have been requested thus far. */ protected HashIntMap _tiles = new HashIntMap(); - /** The tileset manager. */ - protected TileSetManager _tilesetmgr; + /** The tile set repository. */ + protected TileSetRepository _tsrepo; } diff --git a/src/java/com/threerings/media/tile/TileSet.java b/src/java/com/threerings/media/tile/TileSet.java index 4461da7b1..749967e09 100644 --- a/src/java/com/threerings/media/tile/TileSet.java +++ b/src/java/com/threerings/media/tile/TileSet.java @@ -1,48 +1,287 @@ // -// $Id: TileSet.java,v 1.17 2001/10/11 00:41:26 shaper Exp $ +// $Id: TileSet.java,v 1.18 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; +import java.awt.Image; +import java.awt.Point; +import java.awt.image.*; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +import com.threerings.media.Log; import com.threerings.media.ImageManager; /** - * A tileset stores information on a single logical set of tiles. It - * provides a clean interface for the {@link TileSetManager} to - * retrieve individual tiles from the tileset. + * A tile set stores information on a single logical set of tiles. It + * provides a clean interface for the {@link TileManager} to retrieve + * individual tiles from the tile set. * *

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 0 and tiles are numbered left to right, top to * bottom, in ascending order. */ -public interface TileSet +public class TileSet implements Cloneable { /** - * Return the tileset identifier. + * Constructs a tile set object with the given image manager as + * the source for retrieving tile images. */ - public int getId (); + public TileSet ( + ImageManager imgmgr, int tsid, String name, String imgFile, + int tileCount[], int rowWidth[], int rowHeight[], + int numTiles, Point offsetPos, Point gapDist, + boolean isObjectSet, HashIntMap objects) + { + _imgmgr = imgmgr; + _tsid = tsid; + _name = name; + _imgFile = imgFile; + _tileCount = tileCount; + _rowWidth = rowWidth; + _rowHeight = rowHeight; + _numTiles = numTiles; + _offsetPos = offsetPos; + _gapDist = gapDist; + _isObjectSet = isObjectSet; + _objects = objects; + } /** - * Return the tileset name. + * Returns a new tile set that is a clone of this tile set with + * the image file updated to reference the given file name. */ - public String getName (); + public TileSet clone (String imgFile) + throws CloneNotSupportedException + { + TileSet dup = (TileSet)clone(); + dup.setImageFile(imgFile); + return dup; + } /** - * Return the number of tiles in the tileset. + * Returns the tile set identifier. */ - public int getNumTiles (); + public int getId () + { + return _tsid; + } /** - * Returns the {@link Tile} object from this tileset corresponding - * to the specified tile id, or null if no such tile - * id exists. The tile image is retrieved from the given image - * manager. + * Returns the tile set name. + */ + public String getName () + { + return _name; + } + + /** + * Returns the number of tiles in the tile set. + */ + public int getNumTiles () + { + return _numTiles; + } + + /** + * Returns the {@link Tile} object from this tile set + * corresponding to the specified tile id, or null if an error + * occurred. * - * @param imgmgr the image manager. * @param tid the tile identifier. * - * @return the tile object, or null if no such tile exists. + * @return the tile object, or null if an error occurred. */ - public Tile getTile (ImageManager imgmgr, int tid) - throws NoSuchTileException; + public Tile getTile (int tid) + throws NoSuchTileException + { + if (_imgmgr == null) { + Log.warning("No default image manager [tsid=" + _tsid + + ", tid=" + tid + "]."); + return null; + } + + // bail if there's no such tile + if (tid < 0 || tid > (_numTiles - 1)) { + throw new NoSuchTileException(tid); + } + + // create and populate the tile object + Tile tile = createTile(tid); + + // retrieve the tile image + tile.img = getTileImage(_imgmgr, tile.tid); + if (tile.img == null) { + Log.warning("Null tile image [tile=" + tile + "]."); + } + + // populate the tile's dimensions + BufferedImage bimg = (BufferedImage)tile.img; + tile.height = (short)bimg.getHeight(); + tile.width = (short)bimg.getWidth(); + + // allow sub-classes to fill in their tile information + populateTile(tile); + + return tile; + } + + /** + * Sets the image file to be used as the source for the tile + * images produced by this tile set. + */ + public void setImageFile (String imgFile) + { + _imgFile = imgFile; + _imgTiles = null; + } + + /** + * Return a string representation of the tileset information. + */ + public String toString () + { + StringBuffer buf = new StringBuffer(); + buf.append("[name=").append(_name); + buf.append(", file=").append(_imgFile); + buf.append(", tsid=").append(_tsid); + buf.append(", numtiles=").append(_numTiles); + return buf.append("]").toString(); + } + + /** + * Construct and return a new tile object for further population + * with tile-specific information. Derived classes can override + * this method to create their own sub-class of Tile. + * + * @param tid the tile id for the new tile. + * + * @return the new tile object. + */ + protected Tile createTile (int tid) + { + // construct an object tile if the tile set was specified as such + if (_isObjectSet) { + // default object dimensions to (1, 1) + int wid = 1, hei = 1; + + // retrieve object dimensions if known + if (_objects != null) { + int size[] = (int[])_objects.get(tid); + if (size != null) { + wid = size[0]; + hei = size[1]; + } + } + + return new ObjectTile(_tsid, tid, wid, hei); + } + + // construct a basic tile + return new Tile(_tsid, tid); + } + + /** + * Populates the given tile object with its detailed tile + * information. Derived classes can override this method to add + * in their own tile information, but should be sure to call + * super.populateTile(). + * + * @param tile the tile to populate. + */ + protected void populateTile (Tile tile) + { + // nothing for now + } + + /** + * Returns the image corresponding to the specified tile id within + * this tile set. + * + * @param imgmgr the image manager. + * @param tid the tile id. + * + * @return the tile image. + */ + protected Image getTileImage (ImageManager imgmgr, int tid) + { + // load the full tile image if we don't already have it + if (_imgTiles == null) { + if ((_imgTiles = imgmgr.getImage(_imgFile)) == null) { + Log.warning("Failed to retrieve full tileset image " + + "[file=" + _imgFile + "]."); + return null; + } + } + + // 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 += _tileCount[ridx]) < tid + 1) { + // increment tile image position by row height and gap distance + ty += (_rowHeight[ridx++] + _gapDist.y); + } + + // determine the horizontal index of this tile in the row + int xidx = tid - (tcount - _tileCount[ridx]); + + // final image x-position is based on tile width and gap distance + tx += (xidx * (_rowWidth[ridx] + _gapDist.x)); + + // Log.info("Retrieving tile image [tid=" + tid + ", ridx=" + + // ridx + ", xidx=" + xidx + ", tx=" + tx + + // ", ty=" + ty + "]."); + + // crop the tile-sized image chunk from the full image + return imgmgr.getImageCropped( + _imgTiles, tx, ty, _rowWidth[ridx], _rowHeight[ridx]); + } + + /** The tileset name. */ + protected String _name; + + /** The tileset unique identifier. */ + protected int _tsid; + + /** The file containing the tile images. */ + protected String _imgFile; + + /** The width of the tiles in each row in pixels. */ + protected int[] _rowWidth; + + /** The height of the tiles in each row in pixels. */ + protected int[] _rowHeight; + + /** The number of tiles in each row. */ + protected int[] _tileCount; + + /** The number of tiles in the tileset. */ + protected int _numTiles; + + /** Whether this set produces object tiles. */ + protected boolean _isObjectSet = false; + + /** 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 Point _gapDist = new Point(); + + /** Mapping of object tile ids to object dimensions. */ + protected HashIntMap _objects; + + /** The image containing all tile images for this set. */ + protected Image _imgTiles; + + /** The default image manager for retrieving tile images. */ + protected ImageManager _imgmgr; } diff --git a/src/java/com/threerings/media/tile/TileSetImpl.java b/src/java/com/threerings/media/tile/TileSetImpl.java deleted file mode 100644 index 75b00a665..000000000 --- a/src/java/com/threerings/media/tile/TileSetImpl.java +++ /dev/null @@ -1,222 +0,0 @@ -// -// $Id: TileSetImpl.java,v 1.2 2001/10/12 16:36:58 shaper Exp $ - -package com.threerings.media.tile; - -import java.awt.Image; -import java.awt.Point; -import java.awt.image.*; - -import com.samskivert.util.HashIntMap; -import com.samskivert.util.StringUtil; - -import com.threerings.media.Log; -import com.threerings.media.ImageManager; - -// documentation inherited -public class TileSetImpl implements TileSet -{ - /** The tileset name. */ - public String name; - - /** The tileset unique identifier. */ - public int tsid; - - /** The file containing the tile images. */ - public String imgFile; - - /** The width of the tiles in each row in pixels. */ - public int[] rowWidth; - - /** The height of the tiles in each row in pixels. */ - public int[] rowHeight; - - /** The number of tiles in each row. */ - public int[] tileCount; - - /** The number of tiles in the tileset. */ - public int numTiles; - - /** Whether this set produces object tiles. */ - public boolean isObjectSet = false; - - /** - * The offset distance (x, y) in pixels from the top-left of the - * image to the start of the first tile image. - */ - public Point offsetPos = new Point(); - - /** - * The distance (x, y) in pixels between each tile in each row - * horizontally, and between each row of tiles vertically. - */ - public Point gapDist = new Point(); - - // documentation inherited - public int getId () - { - return tsid; - } - - // documentation inherited - public String getName () - { - return name; - } - - // documentation inherited - public int getNumTiles () - { - return numTiles; - } - - // documentation inherited - public Tile getTile (ImageManager imgmgr, int tid) - throws NoSuchTileException - { - // bail if there's no such tile - if (tid < 0 || tid > (numTiles - 1)) { - throw new NoSuchTileException(tid); - } - - // create and populate the tile object - Tile tile = createTile(tid); - - // retrieve the tile image - tile.img = getTileImage(imgmgr, tile.tid); - if (tile.img == null) { - Log.warning("Null tile image [tile=" + tile + "]."); - } - - // populate the tile's dimensions - BufferedImage bimg = (BufferedImage)tile.img; - tile.height = (short)bimg.getHeight(); - tile.width = (short)bimg.getWidth(); - - // allow sub-classes to fill in their tile information - populateTile(tile); - - return tile; - } - - /** - * Return a string representation of the tileset information. - */ - public String toString () - { - StringBuffer buf = new StringBuffer(); - buf.append("[name=").append(name); - buf.append(", file=").append(imgFile); - buf.append(", tsid=").append(tsid); - buf.append(", numtiles=").append(numTiles); - return buf.append("]").toString(); - } - - /** - * Construct and return a new tile object for further population - * with tile-specific information. Derived classes can override - * this method to create their own sub-class of Tile. - * - * @param tid the tile id for the new tile. - * - * @return the new tile object. - */ - protected Tile createTile (int tid) - { - // construct an object tile if the tile set was specified as such - if (isObjectSet) { - // default object dimensions to (1, 1) - int wid = 1, hei = 1; - - // retrieve object dimensions if known - if (_objects != null) { - int size[] = (int[])_objects.get(tid); - if (size != null) { - wid = size[0]; - hei = size[1]; - } - } - - return new ObjectTile(tsid, tid, wid, hei); - } - - // construct a basic tile - return new Tile(tsid, tid); - } - - /** - * Populates the given tile object with its detailed tile - * information. Derived classes can override this method to add - * in their own tile information, but should be sure to call - * super.populateTile(). - * - * @param tile the tile to populate. - */ - protected void populateTile (Tile tile) - { - // nothing for now - } - - /** - * Returns the image corresponding to the specified tile id within - * this tile set. - * - * @param imgmgr the image manager. - * @param tid the tile id. - * - * @return the tile image. - */ - protected Image getTileImage (ImageManager imgmgr, int tid) - { - // load the full tile image if we don't already have it - if (_imgTiles == null) { - if ((_imgTiles = imgmgr.getImage(imgFile)) == null) { - Log.warning("Failed to retrieve full tileset image " + - "[file=" + imgFile + "]."); - return null; - } - } - - // 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 += tileCount[ridx]) < tid + 1) { - // increment tile image position by row height and gap distance - ty += (rowHeight[ridx++] + gapDist.y); - } - - // determine the horizontal index of this tile in the row - int xidx = tid - (tcount - tileCount[ridx]); - - // final image x-position is based on tile width and gap distance - tx += (xidx * (rowWidth[ridx] + gapDist.x)); - - // Log.info("Retrieving tile image [tid=" + tid + ", ridx=" + - // ridx + ", xidx=" + xidx + ", tx=" + tx + - // ", ty=" + ty + "]."); - - // crop the tile-sized image chunk from the full image - return imgmgr.getImageCropped( - _imgTiles, tx, ty, rowWidth[ridx], rowHeight[ridx]); - } - - protected void addObjectInfo (int tid, int size[]) - { - if (_objects == null) { - _objects = new HashIntMap(); - } - - _objects.put(tid, size); - } - - /** Mapping of object tile ids to object dimensions. */ - protected HashIntMap _objects; - - /** The image containing all tile images for this set. */ - protected Image _imgTiles; -} diff --git a/src/java/com/threerings/media/tile/TileSetManager.java b/src/java/com/threerings/media/tile/TileSetManager.java deleted file mode 100644 index 990809664..000000000 --- a/src/java/com/threerings/media/tile/TileSetManager.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $Id: TileSetManager.java,v 1.14 2001/10/12 00:38:15 shaper Exp $ - -package com.threerings.media.tile; - -import com.threerings.media.ImageManager; - -import java.awt.Image; -import java.util.Iterator; - -/** - * The TileSetManager provides tileset management - * functionality intended for use by the TileManager. It - * provides facilities for obtaining information about individual - * tilesets, retrieving an list of all tilesets available, and - * retrieving the image associated with a particular tile in a set. - * - * @see TileManager - */ -public interface TileSetManager -{ - /** - * Return an Iterator over all TileSet - * objects available. - * - * @return the tileset iterator. - */ - public Iterator getTileSets (); - - /** - * Return the tileset object corresponding to the specified - * tileset id, or null if the tileset is not found. - * - * @param tsid the tileset identifier. - * @return the tileset object. - */ - public TileSet getTileSet (int tsid) - throws NoSuchTileSetException; - - /** - * Return the tile object corresponding to the specified tileset - * and tile id. - * - * @param tsid the tileset identifier. - * @param tid the tile identifier. - * - * @return the tile object. - */ - public Tile getTile (int tsid, int tid) - throws NoSuchTileSetException, NoSuchTileException; -} diff --git a/src/java/com/threerings/media/tile/TileSetManagerImpl.java b/src/java/com/threerings/media/tile/TileSetManagerImpl.java deleted file mode 100644 index 134d69275..000000000 --- a/src/java/com/threerings/media/tile/TileSetManagerImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// $Id: TileSetManagerImpl.java,v 1.14 2001/10/12 00:38:15 shaper Exp $ - -package com.threerings.media.tile; - -import java.awt.Image; -import java.io.*; -import java.util.Collections; -import java.util.Iterator; - -import com.samskivert.util.*; - -import com.threerings.media.ImageManager; -import com.threerings.media.Log; - -public abstract class TileSetManagerImpl implements TileSetManager -{ - /** - * Initialize the tile set manager. - * - * @param config the config object. - * @param imgmgr the image manager. - */ - public void init (Config config, ImageManager imgmgr) - { - _imgmgr = imgmgr; - _config = config; - } - - // documentation inherited - public TileSet getTileSet (int tsid) - throws NoSuchTileSetException - { - TileSet tset = (TileSet)_tilesets.get(tsid); - if (tset == null) { - throw new NoSuchTileSetException(tsid); - } - - return tset; - } - - // documentation inherited - public Iterator getTileSets () - { - return Collections.unmodifiableMap(_tilesets).values().iterator(); - } - - // documentation inherited - public Tile getTile (int tsid, int tid) - throws NoSuchTileSetException, NoSuchTileException - { - return getTileSet(tsid).getTile(_imgmgr, tid); - } - - /** The config object. */ - protected Config _config; - - /** The image manager. */ - protected ImageManager _imgmgr; - - /** The available tilesets keyed by tileset id. */ - protected HashIntMap _tilesets = new HashIntMap(); -} diff --git a/src/java/com/threerings/media/tile/TileSetParser.java b/src/java/com/threerings/media/tile/TileSetParser.java index 1647fda44..f9eb73d8b 100644 --- a/src/java/com/threerings/media/tile/TileSetParser.java +++ b/src/java/com/threerings/media/tile/TileSetParser.java @@ -1,10 +1,11 @@ // -// $Id: TileSetParser.java,v 1.7 2001/10/15 23:53:43 shaper Exp $ +// $Id: TileSetParser.java,v 1.8 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; import java.io.IOException; -import java.util.List; + +import com.samskivert.util.HashIntMap; /** * The tile set parser interface is intended to be implemented by @@ -13,9 +14,10 @@ import java.util.List; public interface TileSetParser { /** - * Read tileset description data from the specified file and - * append {@link TileSet} objects constructed from the data to the - * given list. + * Reads tileset description data from the specified file and + * populates the given hashtable with {@link TileSet} objects + * keyed on their tile set id. */ - public void loadTileSets (String fname, List tilesets) throws IOException; + public void loadTileSets (String fname, HashIntMap tilesets) + throws IOException; } diff --git a/src/java/com/threerings/media/tile/TileSetRepository.java b/src/java/com/threerings/media/tile/TileSetRepository.java new file mode 100644 index 000000000..78954f416 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileSetRepository.java @@ -0,0 +1,34 @@ +// +// $Id: TileSetRepository.java,v 1.1 2001/11/01 01:40:42 shaper Exp $ + +package com.threerings.media.tile; + +import java.util.Iterator; + +import com.samskivert.util.Config; +import com.threerings.media.ImageManager; + +/** + * The tile set repository interface should be implemented by classes + * that provide access to tile sets keyed on their unique tile set + * identifier. + */ +public interface TileSetRepository { + + /** + * Initializes the tile set repository. + */ + public void init (Config config, ImageManager imgmgr); + + /** + * Returns an iterator over all {@link TileSet} objects available. + */ + public Iterator enumerateTileSets (); + + /** + * Returns the {@link TileSet} with the specified unique tile set + * identifier. + */ + public TileSet getTileSet (int tsid) + throws NoSuchTileSetException; +} diff --git a/src/java/com/threerings/media/tile/XMLTileSetParser.java b/src/java/com/threerings/media/tile/XMLTileSetParser.java index 2c58126c5..111bb3b58 100644 --- a/src/java/com/threerings/media/tile/XMLTileSetParser.java +++ b/src/java/com/threerings/media/tile/XMLTileSetParser.java @@ -1,11 +1,10 @@ // -// $Id: XMLTileSetParser.java,v 1.19 2001/10/22 18:11:59 shaper Exp $ +// $Id: XMLTileSetParser.java,v 1.20 2001/11/01 01:40:42 shaper Exp $ package com.threerings.media.tile; import java.awt.Point; import java.io.*; -import java.util.List; import org.xml.sax.*; @@ -13,6 +12,7 @@ import com.samskivert.util.*; import com.samskivert.xml.SimpleParser; import com.threerings.media.Log; +import com.threerings.media.ImageManager; /** * Parse an XML tileset description file and construct tileset objects @@ -20,39 +20,45 @@ import com.threerings.media.Log; * on the input XML stream, though the parsing code assumes the XML * document is well-formed. */ -public class XMLTileSetParser extends SimpleParser +public class XMLTileSetParser + extends SimpleParser implements TileSetParser { + /** + * Constructs an xml tile set parser. + */ + public XMLTileSetParser (ImageManager imgmgr) + { + _imgmgr = imgmgr; + } // documentation inherited public void startElement ( String uri, String localName, String qName, Attributes attributes) { if (qName.equals("tileset")) { - // construct the new tile set - _tset = createTileSet(); - - // note whether it contains object tiles + // note whether the tile set contains object tiles String str = attributes.getValue("layer"); - _tset.isObjectSet = + _info.isObjectSet = (str != null && str.toLowerCase().equals(LAYER_OBJECT)); // get the tile set id - _tset.tsid = parseInt(attributes.getValue("tsid")); + _info.tsid = parseInt(attributes.getValue("tsid")); // get the tile set name str = attributes.getValue("name"); - _tset.name = (str == null) ? DEF_NAME : str; + _info.name = (str == null) ? DEF_NAME : str; } else if (qName.equals("object")) { - // TODO: should we bother checking to make sure we only - // see tags while within an tag? + // get the object info int tid = parseInt(attributes.getValue("tid")); int wid = parseInt(attributes.getValue("width")); int hei = parseInt(attributes.getValue("height")); - // add the object info to the tileset object hashtable - _tset.addObjectInfo(tid, new int[] { wid, hei }); + if (_info.objects == null) { + _info.objects = new HashIntMap(); + } + _info.objects.put(tid, new int[] { wid, hei }); } } @@ -61,38 +67,44 @@ public class XMLTileSetParser extends SimpleParser String uri, String localName, String qName, String data) { if (qName.equals("imagefile")) { - _tset.imgFile = data; + _info.imgFile = data; } else if (qName.equals("rowwidth")) { - _tset.rowWidth = StringUtil.parseIntArray(data); + _info.rowWidth = StringUtil.parseIntArray(data); } else if (qName.equals("rowheight")) { - _tset.rowHeight = StringUtil.parseIntArray(data); + _info.rowHeight = StringUtil.parseIntArray(data); } else if (qName.equals("tilecount")) { - _tset.tileCount = StringUtil.parseIntArray(data); + _info.tileCount = StringUtil.parseIntArray(data); // calculate the total number of tiles in the tileset - for (int ii = 0; ii < _tset.tileCount.length; ii++) { - _tset.numTiles += _tset.tileCount[ii]; + for (int ii = 0; ii < _info.tileCount.length; ii++) { + _info.numTiles += _info.tileCount[ii]; } } else if (qName.equals("offsetpos")) { - parsePoint(data, _tset.offsetPos); + parsePoint(data, _info.offsetPos); } else if (qName.equals("gapdist")) { - parsePoint(data, _tset.gapDist); + parsePoint(data, _info.gapDist); } else if (qName.equals("tileset")) { - // add the fully-read tileset to the list of tilesets - _tilesets.add(_tset); + // construct the tile set + TileSet tset = createTileSet(); + Log.info("Parsed tileset [tset=" + tset + "]."); + // clear the tile set info gathered while parsing + _info = new TileSetInfo(); + // add the tileset to the hashtable + _tilesets.put(tset.getId(), tset); } } // documentation inherited - public void loadTileSets (String fname, List tilesets) throws IOException + public void loadTileSets (String fname, HashIntMap tilesets) + throws IOException { - // save off tileset list for reference while parsing + // save off the tileset hashtable _tilesets = tilesets; try { @@ -100,6 +112,7 @@ public class XMLTileSetParser extends SimpleParser } catch (IOException ioe) { Log.warning("Exception parsing tile set descriptions " + "[ioe=" + ioe + "]."); + Log.logStackTrace(ioe); } } @@ -114,9 +127,12 @@ public class XMLTileSetParser extends SimpleParser * may override this method to create their own sub-classes of the * TileSet object. */ - protected TileSetImpl createTileSet () + protected TileSet createTileSet () { - return new TileSetImpl(); + return new TileSet( + _imgmgr, _info.tsid, _info.name, _info.imgFile, _info.tileCount, + _info.rowWidth, _info.rowHeight, _info.numTiles, _info.offsetPos, + _info.gapDist, _info.isObjectSet, _info.objects); } /** @@ -133,6 +149,24 @@ public class XMLTileSetParser extends SimpleParser point.setLocation(vals[0], vals[1]); } + /** + * A class to hold the tile set information gathered while + * parsing. See the {@link TileSet} class for documentation on + * the various parameters. + */ + protected static class TileSetInfo + { + public int tsid; + public String name; + public String imgFile; + public int tileCount[], rowWidth[], rowHeight[]; + public int numTiles; + public Point offsetPos = new Point(); + public Point gapDist = new Point(); + public boolean isObjectSet; + public HashIntMap objects; + } + /** Default tileset name. */ protected static final String DEF_NAME = "Untitled"; @@ -140,8 +174,11 @@ public class XMLTileSetParser extends SimpleParser protected static final String LAYER_OBJECT = "object"; /** The tilesets constructed thus far. */ - protected List _tilesets; + protected HashIntMap _tilesets; - /** The tile set populated while parsing. */ - protected TileSetImpl _tset; + /** The tile set info populated while parsing. */ + protected TileSetInfo _info = new TileSetInfo(); + + /** The image manager. */ + protected ImageManager _imgmgr; } diff --git a/src/java/com/threerings/miso/tile/BaseTileSet.java b/src/java/com/threerings/miso/tile/BaseTileSet.java index ce757acfa..ad1a2071b 100644 --- a/src/java/com/threerings/miso/tile/BaseTileSet.java +++ b/src/java/com/threerings/miso/tile/BaseTileSet.java @@ -1,9 +1,73 @@ // -// $Id: BaseTileSet.java,v 1.3 2001/10/12 00:43:04 shaper Exp $ +// $Id: BaseTileSet.java,v 1.4 2001/11/01 01:40:42 shaper Exp $ package com.threerings.miso.tile; -public interface MisoTileSet +import java.awt.Point; + +import com.samskivert.util.HashIntMap; + +import com.threerings.media.ImageManager; +import com.threerings.media.tile.*; + +import com.threerings.miso.scene.MisoScene; + +/** + * The miso tile set extends the base tile set to add support for tile + * passability. Passability is used to determine whether {@link + * com.threerings.miso.scene.Traverser} objects can traverse a + * particular tile in a {@link com.threerings.miso.scene.MisoScene}. + */ +public class MisoTileSet extends TileSet { - public int getLayerIndex (); + public MisoTileSet ( + ImageManager imgmgr, int tsid, String name, String imgFile, + int tileCount[], int rowWidth[], int rowHeight[], + int numTiles, Point offsetPos, Point gapDist, + boolean isObjectSet, HashIntMap objects, + int layer, int passable[]) + { + super(imgmgr, tsid, name, imgFile, tileCount, rowWidth, + rowHeight, numTiles, offsetPos, gapDist, + isObjectSet, objects); + + _layer = layer; + _passable = passable; + } + + // documentation inherited + public Tile createTile (int tid) + { + // only create miso tiles for the base layer + if (_layer != MisoScene.LAYER_BASE) { + return super.createTile(tid); + } + + return new MisoTile(_tsid, tid); + } + + // documentation inherited + protected void populateTile (Tile tile) + { + super.populateTile(tile); + + if (tile instanceof MisoTile) { + // set the tile's passability, defaulting to passable if this + // tileset has no passability specified + ((MisoTile)tile).passable = + (_passable == null || (_passable[tile.tid] == 1)); + } + } + + // documentation inherited + public int getLayerIndex () + { + return _layer; + } + + /** The miso scene layer the tiles are intended for. */ + protected int _layer; + + /** Whether each tile is passable. */ + protected int _passable[]; } diff --git a/src/java/com/threerings/miso/tile/CompiledTileSetManager.java b/src/java/com/threerings/miso/tile/CompiledTileSetManager.java deleted file mode 100644 index 6bdf5dd29..000000000 --- a/src/java/com/threerings/miso/tile/CompiledTileSetManager.java +++ /dev/null @@ -1,10 +0,0 @@ -// -// $Id: CompiledTileSetManager.java,v 1.8 2001/08/16 23:17:46 mdb Exp $ - -package com.threerings.miso.tile; - -import com.threerings.media.tile.TileSetManagerImpl; - -public class CompiledTileSetManager extends TileSetManagerImpl -{ -} diff --git a/src/java/com/threerings/miso/tile/EditableTileSetManager.java b/src/java/com/threerings/miso/tile/EditableTileSetManager.java deleted file mode 100644 index 5c1e30127..000000000 --- a/src/java/com/threerings/miso/tile/EditableTileSetManager.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// $Id: EditableTileSetManager.java,v 1.13 2001/10/15 23:53:43 shaper Exp $ - -package com.threerings.miso.tile; - -import java.io.IOException; -import java.util.ArrayList; - -import com.samskivert.util.Config; - -import com.threerings.media.ImageManager; -import com.threerings.media.tile.*; - -import com.threerings.miso.Log; -import com.threerings.miso.util.MisoUtil; - -/** - * Extends general tileset manager functionality to allow reading - * tileset information from XML files. The XML file format allows for - * improved version-control, and makes tilesets easier to view, edit, - * and re-use than might otherwise be the case. - */ -public class EditableTileSetManager extends TileSetManagerImpl -{ - public void init (Config config, ImageManager imgmgr) - { - super.init(config, imgmgr); - - // load the tilesets from the XML description file - String fname = config.getValue(TILESETS_KEY, (String)null); - ArrayList tilesets = new ArrayList(); - try { - new XMLMisoTileSetParser().loadTileSets(fname, tilesets); - } catch (IOException ioe) { - Log.warning("Exception loading tile sets [ioe=" + ioe + "]."); - return; - } - - // bail if we didn't find any tilesets - int size = tilesets.size(); - if (size == 0) { - Log.warning("No tilesets found [fname=" + fname + "]."); - return; - } - - // copy new tilesets into the main tileset hashtable - for (int ii = 0; ii < size; ii++) { - TileSet tset = (TileSet)tilesets.get(ii); - _tilesets.put(tset.getId(), tset); - Log.info("Adding tileset to cache [tset=" + tset + "]."); - } - } - - /** The config key for the tileset description file. */ - protected static final String TILESETS_KEY = - MisoUtil.CONFIG_KEY + ".tilesets"; -} diff --git a/src/java/com/threerings/miso/tile/MisoTileSetImpl.java b/src/java/com/threerings/miso/tile/MisoTileSetImpl.java deleted file mode 100644 index 27c7b3699..000000000 --- a/src/java/com/threerings/miso/tile/MisoTileSetImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// $Id: MisoTileSetImpl.java,v 1.1 2001/10/12 00:43:04 shaper Exp $ - -package com.threerings.miso.tile; - -import com.threerings.media.tile.*; - -import com.threerings.miso.scene.MisoScene; - -/** - * The miso tile set class extends the base tile set class to add - * support for tile passability. Passability is used to determine - * whether {@link com.threerings.miso.scene.Traverser} objects can - * traverse a particular tile in a {@link - * com.threerings.miso.scene.MisoScene}. - */ -public class MisoTileSetImpl - extends TileSetImpl - implements MisoTileSet -{ - /** The miso scene layer the tiles are intended for. */ - public int layer; - - /** Whether each tile is passable. */ - public int passable[]; - - // documentation inherited - public Tile createTile (int tid) - { - // only create miso tiles for the base layer - if (layer != MisoScene.LAYER_BASE) { - return super.createTile(tid); - } - - return new MisoTile(tsid, tid); - } - - // documentation inherited - protected void populateTile (Tile tile) - { - super.populateTile(tile); - - if (tile instanceof MisoTile) { - // set the tile's passability, defaulting to passable if this - // tileset has no passability specified - ((MisoTile)tile).passable = - (passable == null || (passable[tile.tid] == 1)); - } - } - - // documentation inherited - public int getLayerIndex () - { - return layer; - } -} diff --git a/src/java/com/threerings/miso/tile/tools/xml/XMLMisoTileSetParser.java b/src/java/com/threerings/miso/tile/tools/xml/XMLMisoTileSetParser.java index 0fd545f58..34ecc66d6 100644 --- a/src/java/com/threerings/miso/tile/tools/xml/XMLMisoTileSetParser.java +++ b/src/java/com/threerings/miso/tile/tools/xml/XMLMisoTileSetParser.java @@ -1,12 +1,15 @@ // -// $Id: XMLMisoTileSetParser.java,v 1.4 2001/10/15 23:53:43 shaper Exp $ +// $Id: XMLMisoTileSetParser.java,v 1.5 2001/11/01 01:40:42 shaper Exp $ package com.threerings.miso.tile; import org.xml.sax.*; import com.samskivert.util.StringUtil; + +import com.threerings.media.ImageManager; import com.threerings.media.tile.*; + import com.threerings.miso.scene.util.MisoSceneUtil; /** @@ -16,6 +19,12 @@ import com.threerings.miso.scene.util.MisoSceneUtil; */ public class XMLMisoTileSetParser extends XMLTileSetParser { + // documentation inherited + public XMLMisoTileSetParser (ImageManager imgmgr) + { + super(imgmgr); + } + // documentation inherited public void startElement ( String uri, String localName, String qName, Attributes attributes) @@ -24,7 +33,7 @@ public class XMLMisoTileSetParser extends XMLTileSetParser if (qName.equals("tileset")) { String val = attributes.getValue("layer"); - ((MisoTileSetImpl)_tset).layer = MisoSceneUtil.getLayerIndex(val); + _layer = MisoSceneUtil.getLayerIndex(val); } } @@ -35,13 +44,23 @@ public class XMLMisoTileSetParser extends XMLTileSetParser super.finishElement(uri, localName, qName, data); if (qName.equals("passable")) { - ((MisoTileSetImpl)_tset).passable = StringUtil.parseIntArray(data); - } + _passable = StringUtil.parseIntArray(data); + } else if (qName.equals("tileset")) { + _passable = null; + _layer = -1; + } } // documentation inherited - protected TileSetImpl createTileSet () + protected TileSet createTileSet () { - return new MisoTileSetImpl(); + return new MisoTileSet( + _imgmgr, _info.tsid, _info.name, _info.imgFile, _info.tileCount, + _info.rowWidth, _info.rowHeight, _info.numTiles, _info.offsetPos, + _info.gapDist, _info.isObjectSet, _info.objects, + _layer, _passable); } + + protected int _passable[]; + protected int _layer = -1; } diff --git a/src/java/com/threerings/miso/tile/tools/xml/XMLTileSetRepository.java b/src/java/com/threerings/miso/tile/tools/xml/XMLTileSetRepository.java new file mode 100644 index 000000000..d5275cdc9 --- /dev/null +++ b/src/java/com/threerings/miso/tile/tools/xml/XMLTileSetRepository.java @@ -0,0 +1,68 @@ +// +// $Id: XMLTileSetRepository.java,v 1.1 2001/11/01 01:40:42 shaper Exp $ + +package com.threerings.miso.tile; + +import java.io.IOException; +import java.util.*; + +import com.samskivert.util.Config; +import com.samskivert.util.HashIntMap; + +import com.threerings.media.ImageManager; +import com.threerings.media.tile.*; + +import com.threerings.miso.Log; +import com.threerings.miso.util.MisoUtil; + +/** + * Extends general tile set repository functionality to read tile set + * descriptions from an XML file. + */ +public class XMLFileTileSetRepository implements TileSetRepository +{ + // documentation inherited + public void init (Config config, ImageManager imgmgr) + { + // get the tile set description file path + String fname = config.getValue(TILESETS_KEY, DEFAULT_TILESETS); + + // load the tilesets from the XML description file + try { + XMLMisoTileSetParser p = new XMLMisoTileSetParser(imgmgr); + p.loadTileSets(fname, _tilesets); + } catch (IOException ioe) { + Log.warning("Exception loading tile sets [ioe=" + ioe + "]."); + return; + } + } + + // documentation inherited + public TileSet getTileSet (int tsid) + throws NoSuchTileSetException + { + TileSet tset = (TileSet)_tilesets.get(tsid); + if (tset == null) { + throw new NoSuchTileSetException(tsid); + } + + return tset; + } + + // documentation inherited + public Iterator enumerateTileSets () + { + return Collections.unmodifiableMap(_tilesets).values().iterator(); + } + + /** The config key for the tileset description file. */ + protected static final String TILESETS_KEY = + MisoUtil.CONFIG_KEY + ".tilesets"; + + /** The default tileset description file. */ + protected static final String DEFAULT_TILESETS = + "rsrc/config/miso/tilesets.xml"; + + /** The available tilesets keyed by tileset id. */ + protected HashIntMap _tilesets = new HashIntMap(); +} diff --git a/src/java/com/threerings/miso/util/MisoUtil.java b/src/java/com/threerings/miso/util/MisoUtil.java index 20210e364..7e7b00140 100644 --- a/src/java/com/threerings/miso/util/MisoUtil.java +++ b/src/java/com/threerings/miso/util/MisoUtil.java @@ -1,5 +1,5 @@ // -// $Id: MisoUtil.java,v 1.11 2001/10/30 16:16:01 shaper Exp $ +// $Id: MisoUtil.java,v 1.12 2001/11/01 01:40:42 shaper Exp $ package com.threerings.miso.util; @@ -82,16 +82,16 @@ public class MisoUtil * Creates a CharacterManager object. * * @param config the Config object. - * @param tilemgr the tile manager. + * @param imgmgr the ImageManager object. * * @return the new character manager object or null if an error * occurred. */ public static CharacterManager createCharacterManager ( - Config config, TileManager tilemgr) + Config config, ImageManager imgmgr) { XMLFileComponentRepository crepo = - new XMLFileComponentRepository(config, tilemgr); + new XMLFileComponentRepository(config, imgmgr); CharacterManager charmgr = new CharacterManager(crepo); charmgr.setCharacterClass(MisoCharacterSprite.class); return charmgr; @@ -123,19 +123,31 @@ public class MisoUtil } /** - * Creates a TileManager object. + * Creates an ImageManager object. * - * @param config the Config object. * @param frame the root frame to which images will be rendered. * * @return the new tile manager object or null if an error occurred. */ - public static TileManager createTileManager (Config config, Frame frame) + public static ImageManager createImageManager (Frame frame) { ResourceManager rmgr = createResourceManager(); - ImageManager imgmgr = new ImageManager(rmgr, frame); - TileSetManager tilesetmgr = createTileSetManager(config, imgmgr); - TileManager tilemgr = new TileManager(tilesetmgr); + return new ImageManager(rmgr, frame); + } + + /** + * Creates a TileManager object. + * + * @param config the Config object. + * @param imgmgr the ImageManager object. + * + * @return the new tile manager object or null if an error occurred. + */ + public static TileManager createTileManager ( + Config config, ImageManager imgmgr) + { + TileSetRepository tsrepo = createTileSetRepository(config, imgmgr); + TileManager tilemgr = new TileManager(tsrepo); return tilemgr; } @@ -150,43 +162,44 @@ public class MisoUtil } /** - * Creates a TileSetManager object, reading the class - * name to instantiate from the config object. + * Creates a TileSetRepository object, reading the + * class name to instantiate from the config object. * * @param config the Config object. * @param imgmgr the ImageManager object from which * images are obtained. * - * @return the new tileset manager object or null if an error occurred. + * @return the new tile set repository or null if an error + * occurred. */ - protected static TileSetManager createTileSetManager ( + protected static TileSetRepository createTileSetRepository ( Config config, ImageManager imgmgr) { - TileSetManagerImpl tilesetmgr = null; + TileSetRepository tsrepo = null; try { - tilesetmgr = (TileSetManagerImpl) - config.instantiateValue(TILESETMGR_KEY, DEF_TILESETMGR); - tilesetmgr.init(config, imgmgr); + tsrepo = (TileSetRepository)config.instantiateValue( + TILESETREPO_KEY, DEF_TILESETREPO); + tsrepo.init(config, imgmgr); } catch (Exception e) { - Log.warning("Failed to instantiate tileset manager " + + Log.warning("Failed to instantiate tile set repository " + "[e=" + e + "]."); } - - return tilesetmgr; + return tsrepo; } /** The default scene repository class name. */ protected static final String DEF_SCENEREPO = XMLFileSceneRepository.class.getName(); - /** The default tileset manager class name. */ - protected static final String DEF_TILESETMGR = - EditableTileSetManager.class.getName(); + /** The default tile set repository class name. */ + protected static final String DEF_TILESETREPO = + XMLFileTileSetRepository.class.getName(); /** The config key for the scene repository class. */ protected static final String SCENEREPO_KEY = CONFIG_KEY + ".scenerepo"; - /** The config key for the tileset manager class. */ - protected static final String TILESETMGR_KEY = CONFIG_KEY + ".tilesetmgr"; + /** The config key for the tile set repository class. */ + protected static final String TILESETREPO_KEY = + CONFIG_KEY + ".tilesetrepo"; } diff --git a/tests/src/java/com/threerings/cast/builder/TestApp.java b/tests/src/java/com/threerings/cast/builder/TestApp.java index c3670906b..ec2c9c93b 100644 --- a/tests/src/java/com/threerings/cast/builder/TestApp.java +++ b/tests/src/java/com/threerings/cast/builder/TestApp.java @@ -1,5 +1,5 @@ // -// $Id: TestApp.java,v 1.1 2001/10/30 16:16:01 shaper Exp $ +// $Id: TestApp.java,v 1.2 2001/11/01 01:40:42 shaper Exp $ package com.threerings.cast.builder.test; @@ -11,9 +11,9 @@ import com.samskivert.swing.util.SwingUtil; import com.threerings.cast.Log; import com.threerings.cast.CharacterManager; -import com.threerings.media.tile.TileManager; -import com.threerings.miso.util.MisoContext; +import com.threerings.media.ImageManager; + import com.threerings.miso.util.MisoUtil; public class TestApp @@ -26,13 +26,10 @@ public class TestApp // create the handles on our various services _config = MisoUtil.createConfig(); - _tilemgr = MisoUtil.createTileManager(_config, _frame); + _imgmgr = MisoUtil.createImageManager(_frame); CharacterManager charmgr = - MisoUtil.createCharacterManager(_config, _tilemgr); - - // create the context object - _ctx = new TestContextImpl(); + MisoUtil.createCharacterManager(_config, _imgmgr); // initialize the frame ((TestFrame)_frame).init(charmgr); @@ -50,28 +47,12 @@ public class TestApp app.run(); } - protected class TestContextImpl implements MisoContext - { - public Config getConfig () - { - return _config; - } - - public TileManager getTileManager () - { - return _tilemgr; - } - } - /** The test frame. */ protected JFrame _frame; - /** The test context. */ - protected MisoContext _ctx; - /** The config object. */ protected Config _config; - /** The tile manager object. */ - protected TileManager _tilemgr; + /** The image manager object. */ + protected ImageManager _imgmgr; } diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java index 25da6e54b..25703e8a2 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java @@ -1,5 +1,5 @@ // -// $Id: ViewerApp.java,v 1.10 2001/10/30 16:16:01 shaper Exp $ +// $Id: ViewerApp.java,v 1.11 2001/11/01 01:40:43 shaper Exp $ package com.threerings.miso.viewer; @@ -8,6 +8,8 @@ import java.io.IOException; import com.samskivert.swing.util.SwingUtil; import com.samskivert.util.Config; + +import com.threerings.media.ImageManager; import com.threerings.media.tile.TileManager; import com.threerings.miso.Log; @@ -35,7 +37,8 @@ public class ViewerApp _config = MisoUtil.createConfig( ViewerModel.CONFIG_KEY, "rsrc/config/miso/viewer"); _model = createModel(_config, args); - _tilemgr = MisoUtil.createTileManager(_config, _frame); + ImageManager imgmgr = MisoUtil.createImageManager(_frame); + _tilemgr = MisoUtil.createTileManager(_config, imgmgr); _screpo = MisoUtil.createSceneRepository(_config, _tilemgr); // create the context object diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java index b9daf4743..f06a3673a 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java @@ -1,13 +1,15 @@ // -// $Id: ViewerFrame.java,v 1.25 2001/10/25 16:33:20 shaper Exp $ +// $Id: ViewerFrame.java,v 1.26 2001/11/01 01:40:43 shaper Exp $ package com.threerings.miso.viewer; import javax.swing.JFrame; +import com.threerings.media.ImageManager; import com.threerings.media.sprite.SpriteManager; import com.threerings.miso.Log; +import com.threerings.miso.util.MisoUtil; import com.threerings.miso.viewer.util.ViewerContext; /** @@ -28,10 +30,11 @@ public class ViewerFrame extends JFrame */ public void init (ViewerContext ctx) { - // create the sprite manager + // create the various managers + ImageManager imgmgr = MisoUtil.createImageManager(this); SpriteManager spritemgr = new SpriteManager(); // add the main panel to the frame - getContentPane().add(new ViewerSceneViewPanel(ctx, spritemgr)); + getContentPane().add(new ViewerSceneViewPanel(ctx, imgmgr, spritemgr)); } } diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java index a53f0d977..e38ee1fcf 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java @@ -1,5 +1,5 @@ // -// $Id: ViewerSceneViewPanel.java,v 1.25 2001/10/30 16:16:01 shaper Exp $ +// $Id: ViewerSceneViewPanel.java,v 1.26 2001/11/01 01:40:43 shaper Exp $ package com.threerings.miso.viewer; @@ -15,6 +15,7 @@ import com.samskivert.util.Config; import com.threerings.cast.*; +import com.threerings.media.ImageManager; import com.threerings.media.sprite.*; import com.threerings.media.tile.TileManager; import com.threerings.media.util.RandomUtil; @@ -34,7 +35,8 @@ public class ViewerSceneViewPanel extends SceneViewPanel /** * Construct the panel and initialize it with a context. */ - public ViewerSceneViewPanel (ViewerContext ctx, SpriteManager spritemgr) + public ViewerSceneViewPanel (ViewerContext ctx, ImageManager imgmgr, + SpriteManager spritemgr) { super(ctx.getConfig(), spritemgr); @@ -47,8 +49,8 @@ public class ViewerSceneViewPanel extends SceneViewPanel prepareStartingScene(); // construct the character manager from which we obtain sprites - CharacterManager charmgr = MisoUtil.createCharacterManager( - ctx.getConfig(), ctx.getTileManager()); + CharacterManager charmgr = + MisoUtil.createCharacterManager(ctx.getConfig(), imgmgr); // create the character descriptors _descUser = createCharacterDescriptor(charmgr); @@ -193,11 +195,6 @@ public class ViewerSceneViewPanel extends SceneViewPanel protected CharacterDescriptor createCharacterDescriptor (CharacterManager charmgr) { - // get the base component type (always the first type for now). - // TODO: change this to retrieve component type by name - Iterator iter = charmgr.enumerateComponentTypes(); - ComponentType ctype = (ComponentType)iter.next(); - // get all available classes ArrayList classes = new ArrayList(); CollectionUtil.addAll(classes, charmgr.enumerateComponentClasses()); @@ -210,7 +207,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel // get the components available for this class ArrayList choices = new ArrayList(); - iter = charmgr.enumerateComponentsByClass(ctype.ctid, cclass.clid); + Iterator iter = charmgr.enumerateComponentsByClass(cclass.clid); CollectionUtil.addAll(choices, iter); // choose a random component @@ -218,7 +215,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel components[cclass.clid] = ((Integer)choices.get(idx)).intValue(); } - return new CharacterDescriptor(ctype, components); + return new CharacterDescriptor(components); } // documentation inherited