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