diff --git a/src/java/com/threerings/media/tile/XMLTileSetParser.java b/src/java/com/threerings/media/tile/XMLTileSetParser.java index 7c310837b..3305c26d4 100644 --- a/src/java/com/threerings/media/tile/XMLTileSetParser.java +++ b/src/java/com/threerings/media/tile/XMLTileSetParser.java @@ -1,5 +1,5 @@ // -// $Id: XMLTileSetParser.java,v 1.6 2001/07/23 22:31:48 shaper Exp $ +// $Id: XMLTileSetParser.java,v 1.7 2001/07/24 22:52:02 shaper Exp $ package com.threerings.miso.tile; @@ -84,7 +84,6 @@ public class XMLTileSetParser extends DefaultHandler } // read all tileset descriptions from the XML input stream - XMLTileSetParser parser = new XMLTileSetParser(); XMLUtil.parse(this, tis); return _tilesets; diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 8ff48101c..98ac45a3f 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,18 +1,20 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.12 2001/07/24 19:15:51 shaper Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.13 2001/07/24 22:52:02 shaper Exp $ package com.threerings.miso.scene; -import com.threerings.miso.tile.Tile; -import com.threerings.miso.tile.TileManager; - import java.awt.Point; import java.io.*; +import com.samskivert.util.StringUtil; +import com.threerings.miso.tile.Tile; +import com.threerings.miso.tile.TileManager; + /** - * A scene represents the data model corresponding to a single screen - * for game play. For instance, one scene might display a portion of - * a street with several buildings scattered about on the periphery. + * A Scene object represents the data model corresponding to a single + * screen for game play. For instance, one scene might display a + * portion of a street with several buildings scattered about on the + * periphery. */ public class Scene { @@ -37,6 +39,9 @@ public class Scene /** String translations of each tile layer name. */ public static final String[] XLATE_LAYERS = { "Base", "Object" }; + /** Scene id to denote an unset or otherwise invalid scene id. */ + public static final int SID_INVALID = -1; + /** The tiles comprising the scene. */ public Tile tiles[][][]; @@ -49,6 +54,7 @@ public class Scene public Scene (TileManager tilemgr, int sid) { _tilemgr = tilemgr; + _sid = (short)sid; _name = DEF_SCENE_NAME; _hotspots = new Point[0]; _exits = new ExitPoint[0]; @@ -66,6 +72,29 @@ public class Scene } } + /** + * Construct a new Scene object with the given values, specifying + * the tile manager from which the scene obtains tiles. + * + * @param tilemgr the tile manager. + * @param sid the scene id. + * @param name the scene name. + * @param hotspots the hotspot points. + * @param exits the exit points. + * @param tiles the tiles comprising the scene. + */ + public Scene (TileManager tilemgr, int sid, String name, + Point hotspots[], ExitPoint exits[], + Tile tiles[][][]) + { + _tilemgr = tilemgr; + _sid = (short)sid; + _name = name; + _hotspots = hotspots; + _exits = exits; + this.tiles = tiles; + } + /** * Return the scene name. */ @@ -117,6 +146,19 @@ public class Scene return numTiles; } + /** + * Return a string representation of this Scene object. + */ + public String toString () + { + StringBuffer buf = new StringBuffer(); + buf.append("[name=").append(_name); + buf.append(", sid=").append(_sid); + buf.append(", hotspots=").append(StringUtil.toString(_hotspots)); + buf.append(", exits=").append(StringUtil.toString(_exits)); + return buf.append("]").toString(); + } + /** The default scene name. */ protected static final String DEF_SCENE_NAME = "Untitled Scene"; diff --git a/src/java/com/threerings/miso/client/ExitPoint.java b/src/java/com/threerings/miso/client/ExitPoint.java index eebe572ca..fab9bf3c5 100644 --- a/src/java/com/threerings/miso/client/ExitPoint.java +++ b/src/java/com/threerings/miso/client/ExitPoint.java @@ -1,5 +1,5 @@ // -// $Id: ExitPoint.java,v 1.4 2001/07/24 19:15:51 shaper Exp $ +// $Id: ExitPoint.java,v 1.5 2001/07/24 22:52:02 shaper Exp $ package com.threerings.miso.scene; @@ -12,9 +12,22 @@ public class ExitPoint /** Coordinates for this exit point. */ public byte x, y; + /** The scene name this exit transitions to. */ + public String name; + /** The scene id this exit transitions to. */ public short sid; - /** The scene name this exit transitions to. */ - public String name; + /** + * Return a String representation of this ExitPoint object. + */ + public String toString () + { + StringBuffer buf = new StringBuffer(); + buf.append("[x=").append(x); + buf.append(", y=").append(y); + buf.append(", name=").append(name); + buf.append(", sid=").append(sid); + return buf.append("]").toString(); + } } diff --git a/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java b/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java index 4c45bf10a..d7bbbcab2 100644 --- a/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java +++ b/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java @@ -1,18 +1,213 @@ // -// $Id: XMLSceneParser.java,v 1.1 2001/07/24 16:10:19 shaper Exp $ +// $Id: XMLSceneParser.java,v 1.2 2001/07/24 22:52:02 shaper Exp $ package com.threerings.miso.scene.xml; -import java.io.IOException; +import java.awt.Point; +import java.io.*; import java.util.ArrayList; +import javax.xml.parsers.ParserConfigurationException; -import com.threerings.miso.scene.Scene; +import org.xml.sax.*; +import org.xml.sax.helpers.DefaultHandler; -public class XMLSceneParser +import com.samskivert.util.*; +import com.samskivert.xml.XMLUtil; +import com.threerings.miso.Log; +import com.threerings.miso.scene.*; +import com.threerings.miso.tile.*; + +/** + * Parse an XML scene description file and construct a scene object. + * Does not currently perform validation on the input XML stream, + * though the parsing code assumes the XML document is well-formed. + * + * @see XMLSceneWriter + */ +public class XMLSceneParser extends DefaultHandler { + public XMLSceneParser (TileManager tilemgr) + { + _tilemgr = tilemgr; + } + + public void startElement (String uri, String localName, + String qName, Attributes attributes) + { + _tag = qName; + } + + public void endElement (String uri, String localName, String qName) + { + // construct the scene object on tag close + if (qName.equals("scene")) { + _scene = new Scene(_tilemgr, Scene.SID_INVALID); + Log.info("Constructed parsed scene [scene=" + _scene + "]."); + } + + // note that we're not within a tag to avoid considering any + // characters during this quiescent time + _tag = null; + } + + public void characters (char ch[], int start, int length) + { + // bail if we're not within a meaningful tag + if (_tag == null) return; + + String str = String.copyValueOf(ch, start, length); + + // store the value associated with the current tag for use + // when we construct the tileset object. + if (_tag.equals("name")) { + _scName = str; + + } else if (_tag.equals("version")) { + int version = getInt(str); + if (version < 0 || version > Scene.VERSION) { + Log.warning( + "Unrecognized scene file format version, will attempt " + + "to continue parsing file but your mileage may vary " + + "[fname=" + _fname + ", version=" + version + + ", known_version=" + Scene.VERSION + "]."); + } + + } else if (_tag.equals("hotspots")) { + _scHotspots = toPointArray(StringUtil.parseIntArray(str)); + + } else if (_tag.equals("exits")) { + _scExits = toExitPointArray(StringUtil.parseStringArray(str)); + } + + // TODO: + // tiles + // layer lnum="0" + // row + // layer lnum="1" + // row + } + + /** + * Given an array of integer values, return a Point array + * constructed from each successive tuple of values as (x, y) in + * the array. + * + * @param vals the integer values. + * + * @return the point array, or null if an error occurred. + */ + protected Point[] toPointArray (int[] vals) + { + // make sure we have an even number of points + if ((vals.length % 2) == 1) return null; + + // pull the point coordinates out of the int array + Point[] points = new Point[vals.length / 2]; + for (int ii = 0; ii < vals.length; ii += 2) { + int idx = ii / 2; + points[idx] = new Point(vals[ii], vals[ii + 1]); + } + + return points; + } + + /** + * Given an array of String values, return an ExitPoint array + * constructed from each successive triplet of values as (x, y, + * scene name) in the array. + * + *

This is something of a hack since we perhaps ought to parse + * the original String into its constituent components ourselves, + * but I'm unable to restrain myself from using the handy + * StringUtil.toString() method to take care of + * tokenizing things for us, so, there you have it. + * + * @param vals the String values. + * + * @return the ExitPoint array, or null if an error occurred. + */ + protected ExitPoint[] toExitPointArray (String[] vals) + { + // make sure we have an appropriate number of values + if ((vals.length % 3) != 0) return null; + + // pull the point values out of the string array + ExitPoint[] exits = new ExitPoint[vals.length / 3]; + for (int ii = 0; ii < vals.length; ii += 3) { + int idx = ii / 3; + exits[idx] = new ExitPoint(); + exits[idx].x = (byte)getInt(vals[ii]); + exits[idx].y = (byte)getInt(vals[ii + 1]); + exits[idx].name = vals[ii + 2]; + + // scene id is only valid at runtime + exits[idx].sid = Scene.SID_INVALID; + } + + return exits; + } + + /** + * Parse the given string as an integer and return the integer + * value, or -1 if the string is malformed. + */ + protected int getInt (String str) + { + try { + return Integer.parseInt(str); + } catch (NumberFormatException nfe) { + Log.warning("Malformed integer value [str=" + str + "]."); + return -1; + } + } + + /** + * Parse the specified XML file and return a Scene object with the + * data contained therein. + * + * @param fname the file name. + * + * @return the scene object, or null if an error occurred. + */ public Scene loadScene (String fname) throws IOException { - // TBD - return null; + _fname = fname; + + try { + // get the file input stream + FileInputStream fis = new FileInputStream(fname); + BufferedInputStream bis = new BufferedInputStream(fis); + + // read the XML input stream and construct the scene object + _scene = null; + XMLUtil.parse(this, bis); + + // return the final scene object + return _scene; + + } catch (ParserConfigurationException pce) { + throw new IOException(pce.toString()); + + } catch (SAXException saxe) { + throw new IOException(saxe.toString()); + } } + + /** The file currently being processed. */ + protected String _fname; + + /** The XML element tag currently being processed. */ + protected String _tag; + + /** The scene object constructed as each scene file is read. */ + protected Scene _scene; + + /** The tile manager object for use in constructing scenes. */ + protected TileManager _tilemgr; + + // temporary storage of scene object values + protected String _scName; + protected Point[] _scHotspots; + protected ExitPoint[] _scExits; + protected Tile[][][] _scTiles; } diff --git a/src/java/com/threerings/miso/tools/xml/XMLSceneRepository.java b/src/java/com/threerings/miso/tools/xml/XMLSceneRepository.java index 36ec7789c..342b88afd 100644 --- a/src/java/com/threerings/miso/tools/xml/XMLSceneRepository.java +++ b/src/java/com/threerings/miso/tools/xml/XMLSceneRepository.java @@ -1,5 +1,5 @@ // -// $Id: XMLSceneRepository.java,v 1.2 2001/07/24 19:15:51 shaper Exp $ +// $Id: XMLSceneRepository.java,v 1.3 2001/07/24 22:52:02 shaper Exp $ package com.threerings.miso.scene.xml; @@ -31,7 +31,7 @@ public class XMLFileSceneRepository extends SceneRepositoryImpl { super.init(config, tilemgr); _root = _config.getValue(CONFIG_ROOT, DEF_ROOT); - _parser = new XMLSceneParser(); + _parser = new XMLSceneParser(_tilemgr); _writer = new XMLSceneWriter(); }