From 9bec86fe87065afdd6ea4f8796a9794c4c494e60 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Wed, 25 Jul 2001 01:38:08 +0000 Subject: [PATCH] Completed parsing of multi-layer scene XML files. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@123 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../miso/client/DisplayMisoSceneImpl.java | 4 +- .../miso/tools/xml/XMLSceneParser.java | 158 ++++++++++++++---- 2 files changed, 123 insertions(+), 39 deletions(-) diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 98ac45a3f..73fc9c11f 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.13 2001/07/24 22:52:02 shaper Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.14 2001/07/25 01:38:08 shaper Exp $ package com.threerings.miso.scene; @@ -174,7 +174,7 @@ public class Scene /** The unique scene id. */ protected short _sid; - /** Hot-spot zone points */ + /** Hot-spot zone points. */ protected Point _hotspots[]; /** Exit points to different scenes. */ diff --git a/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java b/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java index d7bbbcab2..8b9d013cd 100644 --- a/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java +++ b/src/java/com/threerings/miso/tools/xml/XMLSceneParser.java @@ -1,5 +1,5 @@ // -// $Id: XMLSceneParser.java,v 1.2 2001/07/24 22:52:02 shaper Exp $ +// $Id: XMLSceneParser.java,v 1.3 2001/07/25 01:38:08 shaper Exp $ package com.threerings.miso.scene.xml; @@ -35,35 +35,29 @@ public class XMLSceneParser extends DefaultHandler String qName, Attributes attributes) { _tag = qName; + if (_tag.equals("layer")) { + _scLnum = getInt(attributes.getValue("lnum")); + + } else if (_tag.equals("row")) { + _scRownum = getInt(attributes.getValue("rownum")); + + // get the column start value if present + String strcs = attributes.getValue("colstart"); + if (strcs != null) _scColstart = getInt(strcs); + } } 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 + "]."); - } + // we know we've received the entirety of the character data + // for the elements we're tracking at this point, so proceed + // with saving off element values for use when we construct + // the scene object. + if (qName.equals("name")) { + _scName = _chars.toString().trim(); - // 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); + } else if (qName.equals("version")) { + int version = getInt(_chars.toString()); if (version < 0 || version > Scene.VERSION) { Log.warning( "Unrecognized scene file format version, will attempt " + @@ -72,19 +66,102 @@ public class XMLSceneParser extends DefaultHandler ", known_version=" + Scene.VERSION + "]."); } - } else if (_tag.equals("hotspots")) { - _scHotspots = toPointArray(StringUtil.parseIntArray(str)); + } else if (qName.equals("hotspots")) { + int vals[] = StringUtil.parseIntArray(_chars.toString()); + _scHotspots = toPointArray(vals); - } else if (_tag.equals("exits")) { - _scExits = toExitPointArray(StringUtil.parseStringArray(str)); + } else if (qName.equals("exits")) { + String vals[] = StringUtil.parseStringArray(_chars.toString()); + _scExits = toExitPointArray(vals); + + } else if (qName.equals("row")) { + if (_scLnum == Scene.LAYER_BASE) { + readRowData(_chars.toString()); + } else { + readSparseRowData(_chars.toString()); + } + + } else if (qName.equals("scene")) { + // construct the scene object on tag close + _scene = new Scene(_tilemgr, Scene.SID_INVALID, _scName, + _scHotspots, _scExits, _scTiles); + Log.info("Constructed parsed scene [scene=" + _scene + "]."); } - // TODO: - // tiles - // layer lnum="0" - // row - // layer lnum="1" - // row + // note that we're not within a tag to avoid considering any + // characters during this quiescent time + _tag = null; + + // and clear out the character data we're gathering + _chars = new StringBuffer(); + } + + public void characters (char ch[], int start, int length) + { + // bail if we're not within a meaningful tag + if (_tag == null) return; + + _chars.append(ch, start, length); + } + + /** + * Given a string of comma-delimited tuples as (tileset id, tile + * id), populate the _scTiles tile array with tiles + * to suit. + * + * @param data the tile data. + */ + protected void readRowData (String data) + { + int[] vals = StringUtil.parseIntArray(data); + + // make sure we have a suitable number of tiles + int validLen = Scene.TILE_WIDTH * 2; + if (vals.length != validLen) { + Log.warning( + "Invalid number of tiles in full row data set, skipping set " + + "[rownum=" + _scRownum + ", len=" + vals.length + + ", valid_len=" + validLen + ", data=" + data + "]."); + return; + } + + // create the tile objects in the tile array + for (int xx = 0; xx < vals.length; xx += 2) { + Tile tile = _tilemgr.getTile(vals[xx], vals[xx + 1]); + _scTiles[xx / 2][_scRownum][_scLnum] = tile; + } + } + + /** + * Given a string of comma-delimited tuples as (tileset id, tile + * id) and having previously set up the _scRownum and + * _scColstart member data by retrieving the + * attribute values when the row element tag was + * noted, this method then proceeds to populate the + * _scTiles tile array with tiles to suit. + * + * @param data the tile data. + */ + protected void readSparseRowData (String data) + { + int[] vals = StringUtil.parseIntArray(data); + + // make sure we have a suitable number of tiles + if ((vals.length % 2) == 1) { + Log.warning( + "Odd number of tiles in sparse row data set, skipping set " + + "[rownum=" + _scRownum + ", colstart=" + _scColstart + + ", len=" + vals.length + "]."); + return; + } + + // create the tile objects in the tile array + Log.info("Sparse row data [colstart=" + _scColstart + + ", rownum=" + _scRownum + ", lnum=" + _scLnum + "]."); + for (int xx = 0; xx < vals.length; xx += 2) { + Tile tile = _tilemgr.getTile(vals[xx], vals[xx + 1]); + _scTiles[_scColstart + (xx / 2)][_scRownum][_scLnum] = tile; + } } /** @@ -178,8 +255,13 @@ public class XMLSceneParser extends DefaultHandler FileInputStream fis = new FileInputStream(fname); BufferedInputStream bis = new BufferedInputStream(fis); - // read the XML input stream and construct the scene object + // prepare temporary data storage for parsing + _chars = new StringBuffer(); _scene = null; + int width = Scene.TILE_WIDTH, height = Scene.TILE_HEIGHT; + _scTiles = new Tile[width][height][Scene.NUM_LAYERS]; + + // read the XML input stream and construct the scene object XMLUtil.parse(this, bis); // return the final scene object @@ -205,9 +287,11 @@ public class XMLSceneParser extends DefaultHandler /** The tile manager object for use in constructing scenes. */ protected TileManager _tilemgr; - // temporary storage of scene object values + // temporary storage of scene object values and data + protected StringBuffer _chars; protected String _scName; protected Point[] _scHotspots; protected ExitPoint[] _scExits; protected Tile[][][] _scTiles; + protected int _scLnum, _scRownum, _scColstart; }