Oh the vast sweeping changes, and they're not even close to complete, but

things compile and most things run so this is a good time to checkpoint.
Let me recall:

- Refactored the whole scene deal.
- Revamped the XML parser stuff (now uses Digester).
- Rethought the tile management.
- Started tile bundle stuff.
- Wrote some tests.
- Did a bit of Mike-ification.

Onward and moreward.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@621 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-11-18 04:09:23 +00:00
parent 45251dba8c
commit ae1052a371
77 changed files with 2188 additions and 3512 deletions
@@ -1,88 +0,0 @@
//
// $Id: Cluster.java,v 1.3 2001/09/28 01:24:54 mdb Exp $
package com.threerings.miso.scene;
import java.util.List;
import java.util.ArrayList;
import com.samskivert.util.StringUtil;
/**
* A <code>Cluster</code> is a gathering of <code>Location</code> objects
* that represent a logical grouping for the purposes of display and
* interaction in a scene.
*
* <p> This class is currently just a wrapper around an
* <code>ArrayList</code>, but the theory is that we may soon want
* more useful functionality encapsulated herein, and the
* <code>Cluster</code> nomenclature is useful in any case.
*/
public class Cluster
{
/**
* Construct a <code>Cluster</code> object.
*/
public Cluster ()
{
_locations = new ArrayList();
}
/**
* Add a location to the cluster.
*
* @param loc the location.
*/
public void add (Location loc)
{
_locations.add(loc);
}
/**
* Return whether the cluster contains the given location.
*
* @param loc the location.
*/
public boolean contains (Location loc)
{
return _locations.contains(loc);
}
/**
* Removes the location from the cluster if present, and returns true
* if the location was present, false if not.
*
* @param loc the location.
*/
public boolean remove (Location loc)
{
return _locations.remove(loc);
}
/**
* Return the number of locations in the cluster.
*/
public int size ()
{
return _locations.size();
}
/**
* Return the list of locations that the cluster is made up of.
*/
public List getLocations ()
{
return _locations;
}
/**
* Return a string representation of this object.
*/
public String toString ()
{
return StringUtil.toString(_locations);
}
/** The list of locations in this cluster. */
protected ArrayList _locations;
}
@@ -1,5 +1,5 @@
//
// $Id: DirtyItemList.java,v 1.5 2001/10/30 16:16:01 shaper Exp $
// $Id: DirtyItemList.java,v 1.6 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
@@ -93,8 +93,8 @@ public class DirtyItemList extends ArrayList
ly = ry = oy;
if (obj instanceof ObjectTile) {
ObjectTile tile = (ObjectTile)obj;
lx -= (tile.baseWidth - 1);
ry -= (tile.baseHeight - 1);
lx -= (tile.getBaseWidth() - 1);
ry -= (tile.getBaseHeight() - 1);
}
}
@@ -0,0 +1,35 @@
//
// $Id: DisplayMisoScene.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
import com.threerings.media.tile.ObjectTileLayer;
import com.threerings.media.tile.TileLayer;
import com.threerings.miso.tile.MisoTileLayer;
/**
* Makes available the information from the {@link MisoSceneModel} in a
* form that is amenable to actually displaying the scene in a user
* interface. As with all display scene implementations, the information
* provided is read-only and should never be modified by the caller.
*/
public interface DisplayMisoScene
{
/**
* Returns the tiles that comprise the base layer of this scene. This
* layer is read-only and not to be modified.
*/
public MisoTileLayer getBaseLayer ();
/**
* Returns the tiles that comprise the fringe layer of this scene.
* This layer is read-only and not to be modified.
*/
public TileLayer getFringeLayer ();
/**
* Returns the tiles that comprise the object layer of this scene.
* This layer is read-only and not to be modified.
*/
public ObjectTileLayer getObjectLayer ();
}
@@ -1,283 +1,121 @@
//
// $Id: DisplayMisoSceneImpl.java,v 1.43 2001/11/12 20:56:55 mdb Exp $
// $Id: DisplayMisoSceneImpl.java,v 1.44 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
import java.awt.Point;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import com.samskivert.util.StringUtil;
import com.threerings.media.tile.*;
import com.threerings.media.tile.NoSuchTileException;
import com.threerings.media.tile.NoSuchTileSetException;
import com.threerings.media.tile.ObjectTile;
import com.threerings.media.tile.ObjectTileLayer;
import com.threerings.media.tile.Tile;
import com.threerings.media.tile.TileLayer;
import com.threerings.media.tile.TileManager;
import com.threerings.miso.Log;
import com.threerings.miso.scene.util.ClusterUtil;
import com.threerings.miso.tile.MisoTile;
import com.threerings.miso.tile.MisoTileLayer;
import com.threerings.miso.tile.ShadowTile;
/**
* 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.
* The default implementation of the {@link DisplayMisoScene} interface.
*/
public class MisoSceneImpl implements EditableMisoScene
public class DisplayMisoSceneImpl
implements DisplayMisoScene
{
/** The scene name. */
public String name = DEF_SCENE_NAME;
/** The locations within the scene. */
public ArrayList locations = new ArrayList();
/** The clusters within the scene. */
public ArrayList clusters = new ArrayList();
/** The portals to different scenes. */
public ArrayList portals = new ArrayList();
/** The default entrance portal. */
public Portal entrance;
/** The base tiles in the scene. */
public MisoTile[][] baseTiles;
/** The fringe tiles in the scene. */
public Tile[][] fringeTiles;
/** The object tiles in the scene. */
public ObjectTile[][] objectTiles;
/** All tiles in the scene. */
public Tile[][][] tiles;
/**
* Construct a new miso scene object. The base layer tiles are
* initialized to contain tiles of the specified default tileset and
* tile id.
* Constructs an instance that will be used to display the supplied
* miso scene data. The tiles identified by the scene model will be
* loaded via the supplied tile manager.
*
* <em>Note:</em> Be sure to call {@link
* #generateAllObjectShadows} before the scene is first used so
* that the base layer will be properly populated with shadow
* tiles in the footprint of all object tiles.
* @param model the scene data that we'll be displaying.
* @param tmgr the tile manager from which to load our tiles.
*
* @param model the iso scene view model.
* @param deftile the default tile.
* @exception NoSuchTileException thrown if the model references a
* tile which is not available via the supplied tile manager.
*/
public MisoSceneImpl (IsoSceneViewModel model, MisoTile deftile)
public DisplayMisoSceneImpl (MisoSceneModel model, TileManager tmgr)
throws NoSuchTileException, NoSuchTileSetException
{
_model = model;
_deftile = deftile;
int swid = model.width;
int shei = model.height;
// create the individual tile layer arrays
baseTiles = new MisoTile[_model.scenewid][_model.scenehei];
fringeTiles = new Tile[_model.scenewid][_model.scenehei];
objectTiles = new ObjectTile[_model.scenewid][_model.scenehei];
// create the individual tile layer objects
_base = new MisoTileLayer(new MisoTile[swid*shei], swid, shei);
_fringe = new TileLayer(new Tile[swid*shei], swid, shei);
_object = new ObjectTileLayer(new ObjectTile[swid*shei], swid, shei);
// create the conjoined array for purely utilitarian purposes
tiles = new Tile[][][] { baseTiles, fringeTiles, objectTiles };
// populate the base and fringe layers
for (int column = 0; column < shei; column++) {
for (int row = 0; row < swid; row++) {
// first do the base layer
int tsid = model.baseTileIds[swid*row+column];
if (tsid > 0) {
int tid = (tsid & 0xFFFF);
tsid >>= 16;
// this is a bit magical, but the tile manager will
// fetch tiles from the tileset repository and the
// tile set id from which we request this tile must
// map to a miso tile as provided by the repository,
// so we just cast it to a miso tile and know that all
// is well
MisoTile mtile = (MisoTile)tmgr.getTile(tsid, tid);
_base.setTile(column, row, mtile);
}
// initialize the always-fully-populated base layer
initBaseTiles();
}
// documentation inherited
public String getName ()
{
return name;
}
// documentation inherited
public void setDefaultTile (MisoTile tile)
{
_deftile = tile;
}
// documentation inherited
public void setTile (int lnum, int x, int y, Tile tile)
{
// if the tile being replaced is an object tile, clear out its
// shadow tiles
Tile otile = tiles[lnum][x][y];
if (otile instanceof ObjectTile) {
removeObjectShadow(x, y);
// then the fringe layer
tsid = model.fringeTileIds[swid*row+column];
if (tsid > 0) {
int tid = (tsid & 0xFFFF);
tsid >>= 16;
Tile tile = tmgr.getTile(tsid, tid);
_fringe.setTile(column, row, tile);
}
}
}
// place the new tile
tiles[lnum][x][y] = tile;
// sanity check the object layer info
int ocount = model.objectTileIds.length;
if (ocount % 3 != 0) {
throw new IllegalArgumentException(
"model.objectTileIds.length % 3 != 0");
}
// if the tile being placed is an object tile, create the
// shadow tiles that lie in its footprint
if (tile instanceof ObjectTile) {
generateObjectShadow(x, y);
// now populate the object layer
for (int i = 0; i < ocount; i+= 3) {
int row = model.objectTileIds[i];
int col = model.objectTileIds[i+1];
int tsid = model.objectTileIds[i+2];
int tid = (tsid & 0xFFFF);
tsid >>= 16;
// create the object tile and stick it into the appropriate
// spot in the object layer
ObjectTile otile = (ObjectTile)tmgr.getTile(tsid, tid);
_object.setTile(col, row, otile);
// we have to generate a shadow for this object tile in the
// base layer so that we can prevent sprites from walking on
// the object
generateObjectShadow(row, col);
}
}
// documentation inherited
public int getId ()
public MisoTileLayer getBaseLayer ()
{
return _sid;
return _base;
}
// documentation inherited
public int getVersion ()
public TileLayer getFringeLayer ()
{
return _version;
return _fringe;
}
// documentation inherited
public int[] getNeighborIds ()
public ObjectTileLayer getObjectLayer ()
{
return null;
}
// documentation inherited
public Tile[][][] getTiles ()
{
return tiles;
}
// documentation inherited
public Tile[][] getTiles (int lnum)
{
return tiles[lnum];
}
// documentation inherited
public MisoTile[][] getBaseLayer ()
{
return baseTiles;
}
// documentation inherited
public Tile[][] getFringeLayer ()
{
return fringeTiles;
}
// documentation inherited
public ObjectTile[][] getObjectLayer ()
{
return objectTiles;
}
// documentation inherited
public MisoTile getDefaultTile ()
{
return _deftile;
}
// documentation inherited
public List getLocations ()
{
return locations;
}
// documentation inherited
public List getClusters ()
{
return clusters;
}
// documentation inherited
public List getPortals ()
{
return portals;
}
// documentation inherited
public Portal getEntrance ()
{
return entrance;
}
// documentation inherited
public void setId (int sceneId)
{
_sid = sceneId;
}
// documentation inherited
public void setVersion (int version)
{
_version = version;
}
// documentation inherited
public void setName (String name)
{
this.name = name;
}
// documentation inherited
public void setEntrance (Portal entrance)
{
this.entrance = entrance;
}
/**
* Update the specified location in the scene. If the cluster
* index number is -1, the location will be removed from any
* cluster it may reside in.
*
* @param loc the location.
* @param clusteridx the cluster index number.
*/
public void updateLocation (Location loc, int clusteridx)
{
// add the location if it's not already present
if (!locations.contains(loc)) {
locations.add(loc);
}
// update the cluster contents
ClusterUtil.regroup(clusters, loc, clusteridx);
}
/**
* Add the specified portal to the scene. Adds the portal to the
* location list as well if it's not already present and removes
* it from any cluster it may reside in.
*
* @param portal the portal.
*/
public void addPortal (Portal portal)
{
// make sure it's in the location list and absent from any cluster
updateLocation(portal, -1);
// don't allow adding a portal more than once
if (portals.contains(portal)) {
Log.warning("Attempt to add already-existing portal " +
"[portal=" + portal + "].");
return;
}
// add it to the list
portals.add(portal);
}
/**
* Remove the given location object from the location list, and from
* any containing cluster. If the location is a portal, it is removed
* from the portal list as well.
*
* @param loc the location object.
*/
public void removeLocation (Location loc)
{
// remove from the location list
if (!locations.remove(loc)) {
// we didn't know about it, so it can't be in a cluster or
// the portal list
return;
}
// remove from any possible cluster
ClusterUtil.remove(clusters, loc);
// remove from any possible existence on the portal list
portals.remove(loc);
return _object;
}
/**
@@ -286,47 +124,15 @@ public class MisoSceneImpl implements EditableMisoScene
public String toString ()
{
StringBuffer buf = new StringBuffer();
buf.append("[name=").append(name);
buf.append(", sid=").append(_sid);
buf.append(", locations=").append(StringUtil.toString(locations));
buf.append(", clusters=").append(StringUtil.toString(clusters));
buf.append(", portals=").append(StringUtil.toString(portals));
buf.append("[width=").append(_base.getWidth());
buf.append(", height=").append(_base.getHeight());
return buf.append("]").toString();
}
/**
* Initialize the base tile layer with the default tile.
*/
protected void initBaseTiles ()
{
for (int xx = 0; xx < _model.scenewid; xx++) {
for (int yy = 0; yy < _model.scenehei; yy++) {
baseTiles[xx][yy] = _deftile;
}
}
}
/**
* Place shadow tiles in the footprint of all object tiles in the
* scene. This method should be called once the scene tiles are
* fully populated, but before the scene is used in any other
* meaningful capacity.
*/
public void generateAllObjectShadows ()
{
for (int xx = 0; xx < _model.scenewid; xx++) {
for (int yy = 0; yy < _model.scenehei; yy++) {
if (objectTiles[xx][yy] != null) {
generateObjectShadow(xx, yy);
}
}
}
}
/**
* Place shadow tiles in the footprint of the object tile at the
* given coordinates in the scene. This method should be called
* when an object tile is added to the scene.
* Place shadow tiles in the footprint of the object tile at the given
* coordinates in the scene. This method should be called when an
* object tile is added to the scene.
*
* @param x the tile x-coordinate.
* @param y the tile y-coordinate.
@@ -336,19 +142,6 @@ public class MisoSceneImpl implements EditableMisoScene
setObjectTileFootprint(x, y, new ShadowTile(x, y));
}
/**
* Remove shadow tiles from the footprint of the object tile at
* the given coordinates in the scene. This method should be
* called when an object tile is removed from the scene.
*
* @param x the tile x-coordinate.
* @param y the tile y-coordinate.
*/
protected void removeObjectShadow (int x, int y)
{
setObjectTileFootprint(x, y, _deftile);
}
/**
* Place the given tile in the footprint of the object tile at the
* given coordinates in the scene.
@@ -359,30 +152,23 @@ public class MisoSceneImpl implements EditableMisoScene
*/
protected void setObjectTileFootprint (int x, int y, MisoTile stamp)
{
ObjectTile tile = objectTiles[x][y];
int endx = Math.max(0, (x - tile.baseWidth + 1));
int endy = Math.max(0, (y - tile.baseHeight + 1));
ObjectTile tile = _object.getTile(y, x);
int endx = Math.max(0, (x - tile.getBaseWidth() + 1));
int endy = Math.max(0, (y - tile.getBaseHeight() + 1));
for (int xx = x; xx >= endx; xx--) {
for (int yy = y; yy >= endy; yy--) {
baseTiles[xx][yy] = stamp;
_base.setTile(yy, xx, stamp);
}
}
}
/** The default scene name. */
protected static final String DEF_SCENE_NAME = "Untitled Scene";
/** The base layer of tiles. */
protected MisoTileLayer _base;
/** The unique scene id. */
protected int _sid = SID_INVALID;
/** The fringe layer of tiles. */
protected TileLayer _fringe;
/** The scene version. */
protected int _version;
/** The default tile for the base layer in the scene. */
protected MisoTile _deftile;
/** The iso scene view data model. */
protected IsoSceneViewModel _model;
/** The object layer of tiles. */
protected ObjectTileLayer _object;
}
@@ -1,24 +1,40 @@
//
// $Id: IsoSceneView.java,v 1.71 2001/10/27 01:37:37 shaper Exp $
// $Id: IsoSceneView.java,v 1.72 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Rectangle;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.Font;
import java.awt.BasicStroke;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import com.samskivert.util.HashIntMap;
import com.threerings.media.sprite.*;
import com.threerings.media.tile.Tile;
import com.threerings.media.sprite.DirtyRectList;
import com.threerings.media.sprite.Path;
import com.threerings.media.sprite.SpriteManager;
import com.threerings.media.tile.ObjectTile;
import com.threerings.media.tile.ObjectTileLayer;
import com.threerings.media.tile.Tile;
import com.threerings.media.tile.TileLayer;
import com.threerings.miso.Log;
import com.threerings.miso.scene.DirtyItemList.DirtyItem;
import com.threerings.miso.scene.util.*;
import com.threerings.miso.scene.util.AStarPathUtil;
import com.threerings.miso.scene.util.IsoUtil;
import com.threerings.miso.tile.MisoTileLayer;
/**
* The iso scene view provides an isometric view of a particular
@@ -54,7 +70,7 @@ public class IsoSceneView implements SceneView
}
// documentation inherited
public void setScene (MisoScene scene)
public void setScene (DisplayMisoScene scene)
{
_scene = scene;
@@ -106,11 +122,6 @@ public class IsoSceneView implements SceneView
_spritemgr.renderSpritePaths(gfx);
}
// draw marks at each location
if (_model.showLocs) {
paintLocations(gfx);
}
// paint any extra goodies
paintExtras(gfx);
@@ -145,8 +156,7 @@ public class IsoSceneView implements SceneView
{
_dirtyRects.clear();
_dirtyItems.clear();
_numDirty = 0;
_numDirty = 0;
for (int xx = 0; xx < _model.scenewid; xx++) {
for (int yy = 0; yy < _model.scenehei; yy++) {
_dirty[xx][yy] = false;
@@ -207,25 +217,23 @@ public class IsoSceneView implements SceneView
*/
protected void renderTiles (Graphics2D gfx)
{
Tile[][][] tiles = _scene.getTiles();
MisoTileLayer base = _scene.getBaseLayer();
TileLayer fringe = _scene.getFringeLayer();
// render the base and fringe layers
for (int yy = 0; yy < _model.scenehei; yy++) {
for (int xx = 0; xx < _model.scenewid; xx++) {
if (_dirty[xx][yy]) {
// draw both layers at this tile position
for (int kk = MisoScene.LAYER_BASE;
kk <= MisoScene.LAYER_FRINGE; kk++) {
// get the tile at these coordinates and layer
Tile tile = tiles[kk][xx][yy];
if (tile != null) {
// draw the tile image
tile.paint(gfx, _polys[xx][yy]);
}
}
for (int yy = 0; yy < base.getHeight(); yy++) {
for (int xx = 0; xx < base.getWidth(); xx++) {
if (!_dirty[xx][yy]) {
continue;
}
// draw the base and fringe tile images
Tile tile;
if ((tile = base.getTile(yy, xx)) != null) {
tile.paint(gfx, _polys[xx][yy]);
}
if ((tile = fringe.getTile(yy, xx)) != null) {
tile.paint(gfx, _polys[xx][yy]);
}
}
}
@@ -251,8 +259,8 @@ public class IsoSceneView implements SceneView
}
/**
* Generates and stores bounding polygons for all object tiles in
* the scene for later use while rendering.
* Generates and stores bounding polygons for all object tiles in the
* scene for later use while rendering.
*/
protected void initAllObjectBounds ()
{
@@ -260,10 +268,10 @@ public class IsoSceneView implements SceneView
_objpolys.clear();
// generate bounding polygons for all objects
ObjectTile[][] tiles = _scene.getObjectLayer();
for (int xx = 0; xx < _model.scenewid; xx++) {
for (int yy = 0; yy < _model.scenehei; yy++) {
ObjectTile tile = tiles[xx][yy];
ObjectTileLayer tiles = _scene.getObjectLayer();
for (int yy = 0; yy < tiles.getHeight(); yy++) {
for (int xx = 0; xx < tiles.getWidth(); xx++) {
ObjectTile tile = tiles.getTile(yy, xx);
if (tile != null) {
generateObjectBounds(tile, xx, yy);
}
@@ -343,47 +351,47 @@ public class IsoSceneView implements SceneView
}
}
/**
* Paint demarcations at all locations in the scene, with each
* location's cluster index, if any, along the right side of its
* rectangle.
*
* @param gfx the graphics context.
*/
protected void paintLocations (Graphics2D gfx)
{
List locations = _scene.getLocations();
int size = locations.size();
// /**
// * Paint demarcations at all locations in the scene, with each
// * location's cluster index, if any, along the right side of its
// * rectangle.
// *
// * @param gfx the graphics context.
// */
// protected void paintLocations (Graphics2D gfx)
// {
// List locations = _scene.getLocations();
// int size = locations.size();
for (int ii = 0; ii < size; ii++) {
// retrieve the location
Location loc = (Location)locations.get(ii);
// for (int ii = 0; ii < size; ii++) {
// // retrieve the location
// Location loc = (Location)locations.get(ii);
// get the cluster index this location is in, if any
int clusteridx = MisoSceneUtil.getClusterIndex(_scene, loc);
// // get the cluster index this location is in, if any
// int clusteridx = MisoSceneUtil.getClusterIndex(_scene, loc);
// get the location's center coordinate
Point spos = new Point();
IsoUtil.fullToScreen(_model, loc.x, loc.y, spos);
int cx = spos.x, cy = spos.y;
// // get the location's center coordinate
// Point spos = new Point();
// IsoUtil.fullToScreen(_model, loc.x, loc.y, spos);
// int cx = spos.x, cy = spos.y;
// paint the location
loc.paint(gfx, cx, cy);
// // paint the location
// loc.paint(gfx, cx, cy);
if (clusteridx != -1) {
// draw the cluster index number on the right side
gfx.setFont(_font);
gfx.setColor(Color.white);
gfx.drawString(String.valueOf(clusteridx), cx + 5, cy + 3);
}
// if (clusteridx != -1) {
// // draw the cluster index number on the right side
// gfx.setFont(_font);
// gfx.setColor(Color.white);
// gfx.drawString(String.valueOf(clusteridx), cx + 5, cy + 3);
// }
// highlight the location if it's the default entrance
if (_scene.getEntrance() == loc) {
gfx.setColor(Color.cyan);
gfx.drawRect(spos.x - 5, spos.y - 5, 10, 10);
}
}
}
// // highlight the location if it's the default entrance
// if (_scene.getEntrance() == loc) {
// gfx.setColor(Color.cyan);
// gfx.drawRect(spos.x - 5, spos.y - 5, 10, 10);
// }
// }
// }
// documentation inherited
public void invalidateRects (DirtyRectList rects)
@@ -555,7 +563,7 @@ public class IsoSceneView implements SceneView
}
// add any objects impacted by the dirty rectangle
ObjectTile tiles[][] = _scene.getObjectLayer();
ObjectTileLayer tiles = _scene.getObjectLayer();
Iterator iter = _objpolys.keys();
while (iter.hasNext()) {
// get the object's coordinates and bounding polygon
@@ -563,13 +571,11 @@ public class IsoSceneView implements SceneView
Polygon poly = (Polygon)_objpolys.get(coord);
if (poly.intersects(r)) {
// get the dirty portion of the object
Rectangle drect = poly.getBounds().intersection(r);
int tx = coord >> 16, ty = coord & 0x0000FFFF;
_dirtyItems.appendDirtyObject(
tiles[tx][ty], poly, tx, ty, drect);
tiles.getTile(ty, tx), poly, tx, ty, drect);
// Log.info("Dirtied item: Object(" + tx + ", " +
// ty + ")");
}
@@ -628,8 +634,8 @@ public class IsoSceneView implements SceneView
/** The scene view model data. */
protected IsoSceneViewModel _model;
/** The scene object to be displayed. */
protected MisoScene _scene;
/** The scene to be displayed. */
protected DisplayMisoScene _scene;
/** The sprite manager. */
protected SpriteManager _spritemgr;
@@ -1,10 +1,10 @@
//
// $Id: IsoSceneViewModel.java,v 1.17 2001/10/22 23:55:14 mdb Exp $
// $Id: IsoSceneViewModel.java,v 1.18 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import com.samskivert.util.Config;
@@ -14,9 +14,8 @@ import com.threerings.miso.scene.util.IsoUtil;
import com.threerings.miso.util.MisoUtil;
/**
* The iso scene view model provides a holding place for the myriad
* parameters and bits of data that describe the details of an isometric
* view of a scene.
* Provides a holding place for the myriad parameters and bits of data
* that describe the details of an isometric view of a scene.
*
* <p> The member data are public to facilitate speedy referencing by the
* {@link IsoSceneView} class. The model should only be modified through
@@ -56,7 +55,7 @@ public class IsoSceneViewModel
public float slopeX, slopeY;
/** The x-axis line. */
public Point lineX[];
public Point[] lineX;
/** The length between fine coordinates in pixels. */
public float finelen;
@@ -70,9 +69,6 @@ public class IsoSceneViewModel
/** Whether tile coordinates should be drawn. */
public boolean showCoords;
/** Whether locations in the scene should be drawn. */
public boolean showLocs;
/** Whether sprite paths should be drawn. */
public boolean showPaths;
@@ -106,7 +102,6 @@ public class IsoSceneViewModel
// set our various flags
showCoords = config.getValue(SHOW_COORDS_KEY, DEF_SHOW_COORDS);
showLocs = config.getValue(SHOW_COORDS_KEY, DEF_SHOW_COORDS);
showPaths = config.getValue(SHOW_PATHS_KEY, DEF_SHOW_PATHS);
}
@@ -158,15 +153,6 @@ public class IsoSceneViewModel
fy >= 0 && fy < finegran);
}
/**
* Toggle whether locations in the scene should be drawn.
*/
public void toggleShowLocations ()
{
showLocs = !showLocs;
notifyListeners(IsoSceneViewModelListener.SHOW_LOCATIONS_CHANGED);
}
/**
* Toggle whether coordinates should be drawn for each tile.
*/
@@ -275,10 +261,6 @@ public class IsoSceneViewModel
protected static final String SHOW_COORDS_KEY =
MisoUtil.CONFIG_KEY + ".show_coords";
/** The config key for whether to show locations. */
protected static final String SHOW_LOCS_KEY =
MisoUtil.CONFIG_KEY + ".show_locs";
/** The config key for whether to show sprite paths. */
protected static final String SHOW_PATHS_KEY =
MisoUtil.CONFIG_KEY + ".show_paths";
@@ -293,7 +275,6 @@ public class IsoSceneViewModel
protected static final int DEF_SCENE_HEIGHT = 22;
protected static final int DEF_OFFSET_Y = -5;
protected static final boolean DEF_SHOW_COORDS = false;
protected static final boolean DEF_SHOW_LOCS = false;
protected static final boolean DEF_SHOW_PATHS = false;
/** The model listeners. */
@@ -1,5 +1,5 @@
//
// $Id: IsoSceneViewModelListener.java,v 1.2 2001/10/26 01:40:22 mdb Exp $
// $Id: IsoSceneViewModelListener.java,v 1.3 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
@@ -12,13 +12,13 @@ package com.threerings.miso.scene;
*/
public interface IsoSceneViewModelListener
{
/** Notification event constant indicating that the "show coordinates"
* configuration has changed.. */
public static final int SHOW_COORDINATES_CHANGED = 0;
/**
* Called by the {@link com.threerings.miso.scene.IsoSceneView} when
* the model is changed.
*/
public void viewChanged (int event);
/** Notification event constants. */
public static final int SHOW_LOCATIONS_CHANGED = 0;
public static final int SHOW_COORDINATES_CHANGED = 1;
}
@@ -1,133 +0,0 @@
//
// $Id: Location.java,v 1.8 2001/10/25 16:36:42 shaper Exp $
package com.threerings.miso.scene;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import com.threerings.media.sprite.Sprite;
/**
* A location object represents a unique well-defined location within
* the scene at the lowest level of granularity available within the
* scene coordinate system. Locations reside at a full coordinate
* (comprised of tile coordinates and fine coordinates within the
* tile), and only one location may reside at each full coordinate in
* the scene.
*/
public class Location
{
/** The unique identifier for this location. */
public int id = -1;
/** The location position in full coordinates. */
public int x, y;
/** The location orientation. */
public int orient;
/**
* Constructs a location object.
*
* @param x the x-position full coordinate.
* @param y the y-position full coordinate.
* @param orient the location orientation.
*/
public Location (int x, int y, int orient)
{
this.x = x;
this.y = y;
this.orient = orient;
}
/**
* Constructs a location object with a default orientation.
*
* @param x the x-position full coordinate.
* @param y the y-position full coordinate.
*/
public Location (int x, int y)
{
this.x = x;
this.y = y;
this.orient = Sprite.DIR_SOUTHWEST;
}
/**
* Renders the location centered at the given coordinates to the
* given graphics context.
*
* @param gfx the graphics context.
* @param cx the center x-coordinate.
* @param cy the center y-coordinate.
*/
public void paint (Graphics2D gfx, int cx, int cy)
{
// translate the origin to center on the location
gfx.translate(cx, cy);
// rotate to reflect the location orientation
double rot = (Math.PI / 4.0f) * orient;
gfx.rotate(rot);
// draw the triangle
gfx.setColor(getColor());
gfx.fill(_tri);
// outline the triangle in black
gfx.setColor(Color.black);
gfx.draw(_tri);
// draw the rectangle
gfx.setColor(Color.red);
gfx.fillRect(-1, 2, 3, 3);
// restore the original transform
gfx.rotate(-rot);
gfx.translate(-cx, -cy);
}
/**
* Returns a string representation of the location.
*/
public String toString ()
{
StringBuffer buf = new StringBuffer();
buf.append("[");
toString(buf);
return buf.append("]").toString();
}
/**
* This should be overridden by derived classes (which should be sure
* to call <code>super.toString()</code>) to append the derived class
* specific event information to the string buffer.
*/
protected void toString (StringBuffer buf)
{
buf.append("id=").append(id);
buf.append(", x=").append(x);
buf.append(", y=").append(y);
buf.append(", orient=").append(orient);
}
/**
* Returns the color to paint the inside of the location.
*/
protected Color getColor ()
{
return Color.yellow;
}
/** The triangle used to render a location on-screen. */
protected static Polygon _tri;
static {
_tri = new Polygon();
_tri.addPoint(-3, -3);
_tri.addPoint(3, -3);
_tri.addPoint(0, 3);
};
}
@@ -1,5 +1,5 @@
//
// $Id: MisoCharacterSprite.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
// $Id: MisoCharacterSprite.java,v 1.2 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
@@ -24,7 +24,7 @@ public class MisoCharacterSprite
public boolean canTraverse (MisoTile tile)
{
// by default, passability is solely the province of the tile
return tile.passable;
return tile.isPassable();
}
/**
@@ -1,109 +0,0 @@
//
// $Id: MisoScene.java,v 1.6 2001/10/17 22:21:22 shaper Exp $
package com.threerings.miso.scene;
import java.util.List;
import com.threerings.media.tile.Tile;
import com.threerings.media.tile.ObjectTile;
import com.threerings.miso.tile.MisoTile;
/**
* 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 interface MisoScene
{
/** Scene id to denote an unset or otherwise invalid scene id. */
public static final int SID_INVALID = -1;
/** The total number of layers. */
public static final int NUM_LAYERS = 3;
/** The base layer id. */
public static final int LAYER_BASE = 0;
/** The fringe layer id. */
public static final int LAYER_FRINGE = 1;
/** The object layer id. */
public static final int LAYER_OBJECT = 2;
/**
* Returns the scene's unique identifier.
*/
public int getId ();
/**
* Returns the scene's name. Every scene has a descriptive name.
*/
public String getName ();
/**
* Returns an array of the tile layers that comprise the scene.
* The array returned by this method should <em>not</em> be
* modified.
*/
public Tile[][][] getTiles ();
/**
* Returns the tile layer for the specified layer index. The
* array returned by this method should <em>not</em> be modified.
*/
public Tile[][] getTiles (int lnum);
/**
* Returns the tiles that comprise the base layer of this scene.
* The array returned by this method should <em>not</em> be
* modified.
*/
public MisoTile[][] getBaseLayer ();
/**
* Returns the tiles that comprise the fringe layer of this scene.
* The array returned by this method should <em>not</em> be
* modified.
*/
public Tile[][] getFringeLayer ();
/**
* Returns the tiles that comprise the object layer of this scene.
* The array returned by this method should <em>not</em> be
* modified.
*/
public ObjectTile[][] getObjectLayer ();
/**
* Returns the default tile for the base layer of the scene.
*/
public MisoTile getDefaultTile ();
/**
* Returns the locations in this scene. The locations list should
* contain all locations and portals in the scene. The list
* returned by this method should <em>not</em> be modified.
*/
public List getLocations ();
/**
* Returns the clusters in this scene. The clusters will reference
* all of the locations that are clustered. The list returned by
* this method should <em>not</em> be modified.
*/
public List getClusters ();
/**
* Returns the portals associated with this scene. Portals should
* never be part of a cluster. The list returned by this method
* should <em>not</em> be modified.
*/
public List getPortals ();
/**
* Returns the portal that is the default entrance to this scene.
*/
public Portal getEntrance ();
}
@@ -1,72 +0,0 @@
//
// $Id: Portal.java,v 1.4 2001/10/25 16:36:43 shaper Exp $
package com.threerings.miso.scene;
import java.awt.Color;
/**
* The portal class represents a {@link Location} in a scene that both
* leads to a different scene and serves as a potential entrance into
* its containing scene.
*/
public class Portal extends Location
{
/** The portal name used for binding the portal to another scene. */
public String name;
/** The destination scene id. */
public int sid;
/** The destination portal within the destination scene. */
public Portal dest;
/**
* Construct a portal object.
*
* @param loc the location associated with the portal.
* @param name the portal name.
*/
public Portal (Location loc, String name)
{
super(loc.x, loc.y, loc.orient);
this.name = name;
sid = MisoScene.SID_INVALID;
}
/**
* Set the destination information for this portal.
*
* @param sid the scene id.
* @param dest the destination portal.
*/
public void setDestination (int sid, Portal dest)
{
this.sid = sid;
this.dest = dest;
}
/**
* Return whether this portal has a valid destination scene and
* portal.
*/
public boolean hasDestination ()
{
return (sid != MisoScene.SID_INVALID && dest != null);
}
// documentation inherited
protected void toString (StringBuffer buf)
{
super.toString(buf);
buf.append(", name=").append(name);
buf.append(", sid=").append(sid);
buf.append(", dest=").append(dest);
}
// documentation inherited
protected Color getColor ()
{
return Color.green;
}
}
@@ -1,5 +1,5 @@
//
// $Id: SceneView.java,v 1.18 2001/10/26 01:17:21 shaper Exp $
// $Id: SceneView.java,v 1.19 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
@@ -36,7 +36,7 @@ public interface SceneView
*
* @param scene the scene to render in the view.
*/
public void setScene (MisoScene scene);
public void setScene (DisplayMisoScene scene);
/**
* Returns a {@link Path} object detailing a valid path for the
@@ -1,5 +1,5 @@
//
// $Id: SceneViewPanel.java,v 1.19 2001/10/22 18:21:41 shaper Exp $
// $Id: SceneViewPanel.java,v 1.20 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
@@ -56,7 +56,7 @@ public class SceneViewPanel extends AnimatedPanel
/**
* Sets the scene managed by the panel.
*/
public void setScene (MisoScene scene)
public void setScene (DisplayMisoScene scene)
{
_view.setScene(scene);
}
@@ -1,5 +1,5 @@
//
// $Id: AStarPathUtil.java,v 1.7 2001/10/22 21:32:13 shaper Exp $
// $Id: AStarPathUtil.java,v 1.8 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene.util;
@@ -11,6 +11,7 @@ import com.threerings.media.util.MathUtil;
import com.threerings.miso.Log;
import com.threerings.miso.scene.Traverser;
import com.threerings.miso.tile.MisoTile;
import com.threerings.miso.tile.MisoTileLayer;
/**
* The <code>AStarPathUtil</code> class provides a facility for
@@ -43,7 +44,7 @@ public class AStarPathUtil
* @return the list of points in the path.
*/
public static List getPath (
MisoTile tiles[][], int tilewid, int tilehei, Traverser trav,
MisoTileLayer tiles, int tilewid, int tilehei, Traverser trav,
int ax, int ay, int bx, int by)
{
AStarInfo info = new AStarInfo(tiles, tilewid, tilehei, trav, bx, by);
@@ -202,7 +203,7 @@ public class AStarPathUtil
protected static boolean isTraversable (AStarInfo info, int x, int y)
{
return (isCoordinateValid(info, x, y) &&
info.trav.canTraverse(info.tiles[x][y]));
info.trav.canTraverse(info.tiles.getTile(y, x)));
}
/**
@@ -252,8 +253,8 @@ public class AStarPathUtil
*/
class AStarInfo
{
/** The array of tiles being traversed. */
public MisoTile tiles[][];
/** The tile layer being traversed. */
public MisoTileLayer tiles;
/** The tile array dimensions. */
public int tilewid, tilehei;
@@ -274,7 +275,7 @@ class AStarInfo
public int destx, desty;
public AStarInfo (
MisoTile tiles[][], int tilewid, int tilehei, Traverser trav,
MisoTileLayer tiles, int tilewid, int tilehei, Traverser trav,
int destx, int desty)
{
// save off references
@@ -1,125 +0,0 @@
//
// $Id: ClusterUtil.java,v 1.3 2001/09/28 01:31:32 mdb Exp $
package com.threerings.miso.scene.util;
import java.util.List;
import com.threerings.miso.Log;
import com.threerings.miso.scene.*;
/**
* The <code>ClusterUtil</code> class provides utility routines for
* working with a list of <code>Cluster</code> objects associated with
* a scene.
*/
public class ClusterUtil
{
/**
* Return the cluster index number the given location is in, or -1
* if the location is not in any cluster.
*
* @param clusters the cluster list.
* @param loc the location.
*/
public static int getClusterIndex (List clusters, Location loc)
{
int size = clusters.size();
for (int ii = 0; ii < size; ii++) {
Cluster cluster = (Cluster)clusters.get(ii);
if (cluster.contains(loc)) {
return ii;
}
}
return -1;
}
/**
* Remove the given location from its cluster, if any.
*
* @param clusters the cluster array.
* @param loc the location.
*/
public static void remove (List clusters, Location loc)
{
int size = clusters.size();
for (int ii = 0; ii < size; ii++) {
Cluster cluster = (Cluster)clusters.get(ii);
if (cluster.contains(loc)) {
cluster.remove(loc);
// remove the cluster itself if it contains no more locations
if (cluster.size() == 0) {
clusters.remove(cluster);
}
// we know the location can only reside in at most one cluster
break;
}
}
}
/**
* Re-group the given location to be placed within the given cluster
* index.
*
* <p> If the cluster index is -1, the location is simply removed
* from any cluster it may reside in. Otherwise, the location is
* removed from any location it may already be in, and placed in
* the cluster corresponding to the requested cluster index.
*
* <p> The cluster index may be equal to the current number of clusters
* in the group, in which case a new cluster object will be created
* that initially contains only the given location.
*
* @param clusters the cluster list.
* @param loc the location.
* @param clusteridx the cluster index, or -1 to remove the location
* from any cluster.
*/
public static void regroup (List clusters, Location loc, int clusteridx)
{
// just remove the location if clusteridx is -1
if (clusteridx == -1) {
remove(clusters, loc);
return;
}
// make sure we're okay with the requested cluster index
int size = clusters.size();
if (clusteridx > size) {
Log.warning("Attempt to regroup location to a non-contiguous " +
"cluster index [loc=" + loc + ", clusteridx=" +
clusteridx + "].");
return;
}
// get the cluster object the location's to be placed in
Cluster cluster = null;
if (clusteridx == size) {
// the location's being added to a new cluster, so create it
clusters.add(cluster = new Cluster());
} else {
// retrieve the cluster we're planning to place the location in
cluster = (Cluster)clusters.get(clusteridx);
// this should never happen, but sanity-check anyway
if (cluster == null) {
Log.warning("Failed to retrieve cluster [clusteridx=" +
clusteridx + "].");
return;
}
// bail if the cluster already contains the location
if (cluster.contains(loc)) return;
}
// remove the location from any other cluster it may already be in
remove(clusters, loc);
// add the location to the cluster
cluster.add(loc);
}
}
@@ -1,5 +1,5 @@
//
// $Id: IsoUtil.java,v 1.14 2001/10/26 01:17:21 shaper Exp $
// $Id: IsoUtil.java,v 1.15 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene.util;
@@ -54,15 +54,15 @@ public class IsoUtil
IsoSceneViewModel model, Polygon root, ObjectTile tile)
{
Rectangle bounds = root.getBounds();
int sx = bounds.x - ((tile.baseWidth - 1) * model.tilehwid);
int sy = bounds.y - tile.height + model.tilehei;
int sx = bounds.x - ((tile.getBaseWidth() - 1) * model.tilehwid);
int sy = bounds.y - tile.getHeight() + model.tilehei;
Polygon boundsPoly = new Polygon();
int rx = sx, ry = sy;
// right point
rx = sx + tile.width;
ry = bounds.y - ((tile.baseHeight - 2) * model.tilehhei);
rx = sx + tile.getWidth();
ry = bounds.y - ((tile.getBaseHeight() - 2) * model.tilehhei);
boundsPoly.addPoint(rx, ry);
// bottom-middle point
@@ -72,17 +72,17 @@ public class IsoUtil
// left point
rx = sx;
ry = bounds.y - ((tile.baseWidth - 2) * model.tilehhei);
ry = bounds.y - ((tile.getBaseWidth() - 2) * model.tilehhei);
boundsPoly.addPoint(rx, ry);
// top-middle point
rx += (tile.baseHeight * model.tilehwid);
ry -= (tile.baseHeight * model.tilehhei);
rx += (tile.getBaseHeight() * model.tilehwid);
ry -= (tile.getBaseHeight() * model.tilehhei);
boundsPoly.addPoint(rx, ry);
// right point
rx = sx + tile.width;
ry = bounds.y - ((tile.baseHeight - 2) * model.tilehhei);
rx = sx + tile.getWidth();
ry = bounds.y - ((tile.getBaseHeight() - 2) * model.tilehhei);
boundsPoly.addPoint(rx, ry);
return boundsPoly;
@@ -104,8 +104,8 @@ public class IsoUtil
IsoSceneViewModel model, Polygon root, ObjectTile tile)
{
Rectangle bounds = root.getBounds();
int sx = bounds.x - ((tile.baseWidth - 1) * model.tilehwid);
int sy = bounds.y - tile.height + model.tilehei;
int sx = bounds.x - ((tile.getBaseWidth() - 1) * model.tilehwid);
int sy = bounds.y - tile.getHeight() + model.tilehei;
Polygon boundsPoly = new Polygon();
int rx = sx, ry = sy;
@@ -114,11 +114,11 @@ public class IsoUtil
boundsPoly.addPoint(rx, ry);
// top-right point
rx = sx + tile.width;
rx = sx + tile.getWidth();
boundsPoly.addPoint(rx, ry);
// bottom-right point
ry = bounds.y - ((tile.baseHeight - 2) * model.tilehhei);
ry = bounds.y - ((tile.getBaseHeight() - 2) * model.tilehhei);
boundsPoly.addPoint(rx, ry);
// bottom-middle point
@@ -128,7 +128,7 @@ public class IsoUtil
// bottom-left point
rx = sx;
ry = bounds.y - ((tile.baseWidth - 2) * model.tilehhei);
ry = bounds.y - ((tile.getBaseWidth() - 2) * model.tilehhei);
boundsPoly.addPoint(rx, ry);
// top-left point
@@ -1,105 +0,0 @@
//
// $Id: MisoSceneUtil.java,v 1.4 2001/10/15 23:53:43 shaper Exp $
package com.threerings.miso.scene.util;
import java.util.List;
import com.threerings.miso.scene.*;
/**
* Miso scene related utility functions and information.
*/
public class MisoSceneUtil
{
/** String translations of each tile layer name. */
public static final String[] XLATE_LAYERS = { "Base", "Fringe", "Object" };
/**
* Returns the layer index number for the named layer. Layer
* names are looked up via <code>XLATE_LAYERS</code> and are
* case-insensitive.
*
* @param name the layer name.
*/
public static int getLayerIndex (String name)
{
if (name == null) {
return DEF_LAYER;
}
name = name.toLowerCase();
for (int ii = 0; ii < MisoScene.NUM_LAYERS; ii++) {
String b = MisoSceneUtil.XLATE_LAYERS[ii].toLowerCase();
if (name.equals(b)) {
return ii;
}
}
return DEF_LAYER;
}
/**
* Return the location object at the given full coordinates, or null
* if no location is currently present at that location.
*
* @param scene the scene whose locations should be searched.
* @param x the full x-position coordinate.
* @param y the full y-position coordinate.
*
* @return the location object.
*/
public static Location getLocation (MisoScene scene, int x, int y)
{
List locs = scene.getLocations();
int size = locs.size();
for (int ii = 0; ii < size; ii++) {
Location loc = (Location)locs.get(ii);
if (loc.x == x && loc.y == y) {
return loc;
}
}
return null;
}
/**
* Return the portal with the given name, or null if the portal isn't
* found in the portal list.
*
* @param scene the scene whose portals should be searched.
* @param name the portal name.
*
* @return the portal object.
*/
public static Portal getPortal (MisoScene scene, String name)
{
List portals = scene.getPortals();
int size = portals.size();
for (int ii = 0; ii < size; ii++) {
Portal portal = (Portal)portals.get(ii);
if (portal.name.equals(name)) {
return portal;
}
}
return null;
}
/**
* Return the cluster index number the given location is in, or -1
* if the location is not in any cluster.
*
* @param scene the containing scene.
* @param loc the location.
*
* @return the cluster index or -1 if the location is not in any
* cluster.
*/
public static int getClusterIndex (MisoScene scene, Location loc)
{
return ClusterUtil.getClusterIndex(scene.getClusters(), loc);
}
/** The default layer index for an unknown named layer. */
protected static final int DEF_LAYER = -1;
}
@@ -0,0 +1,30 @@
//
// $Id: MisoSceneModel.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene;
/**
* The scene model is the bare bones representation of the data for a
* scene in the Miso system. From the scene model, one would create an
* instance of {@link DisplayMisoScene}.
*/
public class MisoSceneModel
{
/** The width of the scene in tile units. */
public int width;
/** The height of the scene in tile units. */
public int height;
/** The combined tile ids (tile set id and tile id) of the tiles in
* the base layer, in row-major order. */
public int[] baseTileIds;
/** The combined tile ids (tile set id and tile id) of the tiles in
* the fringe layer, in row-major order. */
public int[] fringeTileIds;
/** The combined tile ids (tile set id and tile id) of the files in
* the object layer in (x, y, tile id) format. */
public int[] objectTileIds;
}
@@ -1,23 +1,54 @@
//
// $Id: BaseTile.java,v 1.1 2001/10/08 21:04:25 shaper Exp $
// $Id: BaseTile.java,v 1.2 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.tile;
import java.awt.Image;
import com.threerings.media.tile.Tile;
/**
* The miso tile class extends the base tile class to add support for
* tile passability.
* Extends the base tile class to add support for tile passability.
*
* @see MisoTileSet
*/
public class MisoTile extends Tile
{
/** Whether the tile is passable. */
public boolean passable;
public MisoTile (int tsid, int tid)
/**
* Constructs a new miso tile with the specified image. Passability
* will be assumed to be true.
*/
public MisoTile (Image image)
{
super(tsid, tid);
super(image);
}
/**
* Constructs a new miso tile with the specified passability.
*/
public MisoTile (Image image, boolean passable)
{
super(image);
_passable = passable;
}
/**
* Returns whether or not this tile can be walked upon by character
* sprites.
*/
public boolean isPassable ()
{
return _passable;
}
/**
* Sets whether or not this tile can be walked upon by character
* sprites.
*/
public void setPassable (boolean passable)
{
_passable = passable;
}
/** Whether the tile is passable. */
protected boolean _passable = true;
}
@@ -0,0 +1,84 @@
//
// $Id: BaseTileLayer.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.tile;
/**
* The miso tile layer class is a convenience class provided to simplify
* the management of a two-dimensional array of miso tiles. It takes care
* of dereferencing the tile array efficiently with methods that the Java
* compiler should inline, and prevents the caller from having to do the
* indexing multiplication by hand every time.
*
* <p> This is equivalent to {@link TileLayer} except that it contains
* {@link MisoTile} instances. For efficiency's sake, we don't extend
* that class but instead provide a direct implementation.
*/
public final class MisoTileLayer
{
/**
* Constructs a miso tile layer instance with the supplied tiles,
* width and height. The tiles should exist in row-major format (the
* first row of tiles followed by the second and so on).
*
* @exception IllegalArgumentException thrown if the size of the tiles
* array does not match the specified width and height.
*/
public MisoTileLayer (MisoTile[] tiles, int width, int height)
{
// sanity check
if (tiles.length != width*height) {
String errmsg = "tiles.length != width*height";
throw new IllegalArgumentException(errmsg);
}
_tiles = tiles;
_width = width;
_height = height;
}
/**
* Returns the width of the layer in tiles.
*/
public int getWidth ()
{
return _width;
}
/**
* Returns the height of the layer in tiles.
*/
public int getHeight ()
{
return _height;
}
/**
* Fetches the tile at the specified row and column. Bounds checking
* is not done. Note that the parameters are column first, followed by
* row (x, y order rather than row, column order).
*/
public MisoTile getTile (int column, int row)
{
return _tiles[row*_width+column];
}
/**
* Sets the tile at the specified row and column. Bounds checking is
* not done. Note that the parameters are column first, followed by
* row (x, y order rather than row, column order).
*/
public void setTile (int column, int row, MisoTile tile)
{
_tiles[row*_width+column] = tile;
}
/** Our tiles array. */
private MisoTile[] _tiles;
/** The number of tiles in a row. */
private int _width;
/** The number of rows. */
private int _height;
}
@@ -1,81 +1,36 @@
//
// $Id: BaseTileSet.java,v 1.5 2001/11/08 03:04:45 mdb Exp $
// $Id: BaseTileSet.java,v 1.6 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.tile;
import java.awt.Point;
import java.awt.Image;
import com.samskivert.util.HashIntMap;
import com.threerings.media.ImageManager;
import com.threerings.media.tile.*;
import com.threerings.miso.scene.MisoScene;
import com.threerings.media.tile.Tile;
import com.threerings.media.tile.SwissArmyTileSet;
/**
* The miso tile set extends the swiss army 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 MisoScene}.
* tile in a scene.
*/
public class MisoTileSet extends SwissArmyTileSet
{
/**
* Constructs a Miso tileset with the swiss army tile set
* configuration information and additional information about tile
* passability.
*
* @param layer the layer to which this tileset is assigned.
* @param passable info on each tile indicating whether or not the
* tile is passable (can be walked on by sprites).
*
* @see SwissArmyTileSet#SwissArmyTileSet
* Sets the passability information for the tiles in this tileset.
* Each entry in the array corresponds to the tile at that tile index.
*/
public MisoTileSet (
ImageManager imgmgr, String imgFile, String name, int tsid,
int[] tileCount, int[] rowWidth, int[] rowHeight,
Point offsetPos, Point gapDist, int layer, int[] passable)
public void setPassability (boolean[] passable)
{
super(imgmgr, imgFile, name, tsid, tileCount,
rowWidth, rowHeight, offsetPos, gapDist);
_layer = layer;
_passable = passable;
}
// documentation inherited
public Tile createTile (int tid)
public Tile createTile (Image image, int tileIndex)
{
// only create miso tiles for the base layer
if (_layer != MisoScene.LAYER_BASE) {
return super.createTile(tid);
}
return new MisoTile(_tsid, tid);
return new MisoTile(image, _passable[tileIndex]);
}
// 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[];
protected boolean[] _passable;
}
@@ -1,5 +1,5 @@
//
// $Id: ShadowTile.java,v 1.2 2001/10/17 22:22:03 shaper Exp $
// $Id: ShadowTile.java,v 1.3 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.tile;
@@ -7,10 +7,9 @@ import java.awt.Graphics2D;
import java.awt.Shape;
/**
* The shadow tile extends miso tile to provide an always-impassable
* tile that has no display image. Shadow tiles are intended for
* placement in the footprint of {@link
* com.threerings.media.tile.ObjectTile} objects.
* The shadow tile extends miso tile to provide an always-impassable tile
* that has no display image. Shadow tiles are intended for placement in
* the footprint of {@link com.threerings.media.tile.ObjectTile} objects.
*/
public class ShadowTile extends MisoTile
{
@@ -22,14 +21,14 @@ public class ShadowTile extends MisoTile
*/
public ShadowTile (int x, int y)
{
super(SHADOW_TSID, SHADOW_TID);
super(null);
// save the coordinates of our parent object tile
ox = x;
oy = y;
// shadow tiles are always impassable
passable = false;
_passable = false;
}
// documentation inherited
@@ -37,10 +36,4 @@ public class ShadowTile extends MisoTile
{
// paint nothing as we're naught but a measly shadow of a tile
}
/** The shadow tile set id. */
protected static final int SHADOW_TSID = -1;
/** The shadow tile id. */
protected static final int SHADOW_TID = -1;
}
@@ -0,0 +1,57 @@
//
// $Id: BaseTileSetRuleSet.java,v 1.1 2001/11/18 04:09:23 mdb Exp $
package com.threerings.media.tile.xml;
import org.xml.sax.Attributes;
import org.apache.commons.digester.Digester;
import com.threerings.media.tile.TileSet;
import com.threerings.media.tile.xml.SwissArmyTileSetRuleSet;
import com.threerings.miso.tile.MisoTileSet;
/**
* Parses {@link MisoTileSet} instances from a tileset description. A
* uniform tileset description looks like so:
*
* <pre>
* &lt;tileset name="Sample Miso Tileset"&gt;
* &lt;imgpath&gt;path/to/image.png&lt;/imgpath&gt;
* &lt;!-- the width of each tile in pixels --&gt;
* &lt;width&gt;64&lt;/width&gt;
* &lt;!-- the height of each tile in pixels --&gt;
* &lt;height&gt;48&lt;/height&gt;
* &lt;!-- the total number of tiles in the set --&gt;
* &lt;tileCount&gt;16&lt;/tileCount&gt;
* &lt;/tileset&gt;
* </pre>
*/
public class MisoTileSetRuleSet extends SwissArmyTileSetRuleSet
{
/**
* Constructs a uniform tileset rule set that will match tilesets with
* the specified prefix. See the documentation for {@link
* TileSetRuleSet#TileSetruleSet} for more info on matching.
*/
public MisoTileSetRuleSet (String prefix)
{
super(prefix);
}
// documentation inherited
public void addRuleInstances (Digester digester)
{
super.addRuleInstances(digester);
digester.addCallMethod(
_prefix + "/tileset/width", "setWidth", 0,
new Class[] { java.lang.Integer.TYPE });
}
// documentation inherited
protected TileSet createTileSet (Attributes attributes)
{
// we use uniform tilesets
return new MisoTileSet();
}
}
@@ -1,78 +0,0 @@
//
// $Id: XMLMisoTileSetParser.java,v 1.6 2001/11/08 03:04:45 mdb 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;
/**
* Extends the base XML tile set parser to construct {@link
* MisoTileSet} tilesets that provide additional functionality
* specific to the miso layer.
*/
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)
{
super.startElement(uri, localName, qName, attributes);
if (qName.equals("tileset")) {
String val = attributes.getValue("layer");
_layer = MisoSceneUtil.getLayerIndex(val);
}
}
// documentation inherited
protected void finishElement (
String uri, String localName, String qName, String data)
{
super.finishElement(uri, localName, qName, data);
if (qName.equals("passable")) {
_passable = StringUtil.parseIntArray(data);
} else if (qName.equals("tileset")) {
_passable = null;
_layer = -1;
}
}
// documentation inherited
protected TileSet createTileSet ()
{
if (_info.isObjectSet) {
return new ObjectTileSet(
_imgmgr, _info.imgFile, _info.name, _info.tsid,
_info.tileCount, _info.rowWidth, _info.rowHeight,
_info.offsetPos, _info.gapDist, _info.objects);
} else {
return new MisoTileSet(
_imgmgr, _info.imgFile, _info.name, _info.tsid,
_info.tileCount, _info.rowWidth, _info.rowHeight,
_info.offsetPos, _info.gapDist, _layer, _passable);
}
}
/** Info on whether or not the tiles are passable (can be walked on by
* sprites). */
protected int[] _passable;
/** The layer to which the tiles are assigned. */
protected int _layer = -1;
}
@@ -1,68 +0,0 @@
//
// $Id: XMLTileSetRepository.java,v 1.2 2001/11/02 02:52:16 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 XMLTileSetRepository 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();
}
@@ -1,74 +1,100 @@
//
// $Id: EditableMisoScene.java,v 1.4 2001/10/17 22:21:22 shaper Exp $
// $Id: EditableMisoScene.java,v 1.5 2001/11/18 04:09:23 mdb Exp $
package com.threerings.miso.scene;
package com.threerings.miso.tools;
import com.threerings.media.tile.ObjectTile;
import com.threerings.media.tile.Tile;
import com.threerings.miso.tile.MisoTile;
import com.threerings.miso.scene.DisplayMisoScene;
import com.threerings.miso.scene.MisoSceneModel;
/**
* The editable Miso scene interface provides the means for modifying a
* Miso scene which is needed by things like the scene editor. This is
* separated from the read-only interface to avoid implying to users of
* the Miso scene interface that editing scenes is a safe thing to do. In
* fact it should only be done under special circumstances.
* The editable Miso scene interface is used in the offline scene building
* tools as well as by the tools that load those prototype scenes into the
* runtime database. Accordingly, it provides a means for modifying scene
* values and for obtaining access to the underlying scene models that
* represent the underlying scene information.
*
* @see DisplayMisoScene
*/
public interface EditableMisoScene
extends MisoScene
extends DisplayMisoScene
{
/**
* Updates the scene's unique identifier.
* Returns the default base tile.
*/
public void setId (int sceneId);
public MisoTile getDefaultBaseTile ();
/**
* Updates the scene's name.
*/
public void setName (String name);
/**
* Updates the scene's default tile.
*/
public void setDefaultTile (MisoTile tile);
/**
* Updates the specified tile in the scene.
*/
public void setTile (int lnum, int x, int y, Tile tile);
/**
* Set the default entrance portal for this scene.
* Sets the default base tile.
*
* @param entrance the entrance portal.
* @param defaultBaseTile the new default base tile.
* @param fqTileId the fully-qualified tile id (@see
* com.threerings.media.tile.TileUtil#getFQTileId}) of the new default
* base tile.
*/
public void setEntrance (Portal entrance);
public void setDefaultBaseTile (MisoTile defaultBaseTile, int fqTileId);
/**
* Update the specified location in the scene. If the cluster
* index number is -1, the location will be removed from any
* cluster it may reside in.
* Updates the tile at the specified location in the base layer.
*
* @param loc the location.
* @param clusteridx the cluster index number.
* @param x the x-coordinate of the tile to set.
* @param y the y-coordinate of the tile to set.
* @param tile the tile to set.
* @param fqTileId the fully-qualified tile id (@see
* com.threerings.media.tile.TileUtil#getFQTileId}) of the new default
* base tile.
*/
public void updateLocation (Location loc, int clusteridx);
public void setBaseTile (int x, int y, MisoTile tile, int fqTileId);
/**
* Add the specified portal to the scene. Adds the portal to the
* location list as well if it's not already present and removes
* it from any cluster it may reside in.
* Updates the tile at the specified location in the fringe layer.
*
* @param portal the portal.
* @param x the x-coordinate of the tile to set.
* @param y the y-coordinate of the tile to set.
* @param tile the tile to set.
* @param fqTileId the fully-qualified tile id (@see
* com.threerings.media.tile.TileUtil#getFQTileId}) of the new default
* base tile.
*/
public void addPortal (Portal portal);
public void setFringeTile (int x, int y, Tile tile, int fqTileId);
/**
* Remove the given location object from the location list, and
* from any containing cluster. If the location is a portal, it
* is removed from the portal list as well.
* Updates the tile at the specified location in the object layer. Any
* previous object tile at that location should be cleared out by the
* implementation of this method before the new tile is set to ensure
* that footprint tiles associated with the old object are properly
* disposed of.
*
* @param loc the location object.
* @param x the x-coordinate of the tile to set.
* @param y the y-coordinate of the tile to set.
* @param tile the tile to set.
* @param fqTileId the fully-qualified tile id (@see
* com.threerings.media.tile.TileUtil#getFQTileId}) of the new default
* base tile.
*/
public void removeLocation (Location loc);
public void setObjectTile (int x, int y, ObjectTile tile, int fqTileId);
/**
* Clears out the tile at the specified location in the base layer.
*/
public void clearBaseTile (int x, int y);
/**
* Clears out the tile at the specified location in the fringe layer.
*/
public void clearFringeTile (int x, int y);
/**
* Clears out the tile at the specified location in the object layer.
*/
public void clearObjectTile (int x, int y);
/**
* Returns a reference to the miso scene model that reflects the
* changes that have been made to this editable miso scene.
*/
public MisoSceneModel getModel ();
}
@@ -0,0 +1,139 @@
//
// $Id: EditableMisoSceneImpl.java,v 1.1 2001/11/18 04:09:23 mdb Exp $
package com.threerings.miso.tools;
import com.threerings.media.tile.NoSuchTileException;
import com.threerings.media.tile.NoSuchTileSetException;
import com.threerings.media.tile.ObjectTile;
import com.threerings.media.tile.Tile;
import com.threerings.media.tile.TileManager;
import com.threerings.miso.tile.MisoTile;
import com.threerings.miso.scene.DisplayMisoSceneImpl;
import com.threerings.miso.scene.MisoSceneModel;
/**
* The default implementation of the {@link EditableMisoScene} interface.
*/
public class EditableMisoSceneImpl
extends DisplayMisoSceneImpl implements EditableMisoScene
{
/**
* Constructs an instance that will be used to display and edit the
* supplied miso scene data. The tiles identified by the scene model
* will be loaded via the supplied tile manager.
*
* @param model the scene data that we'll be displaying.
* @param tmgr the tile manager from which to load our tiles.
*
* @exception NoSuchTileException thrown if the model references a
* tile which is not available via the supplied tile manager.
*/
public EditableMisoSceneImpl (MisoSceneModel model, TileManager tmgr)
throws NoSuchTileException, NoSuchTileSetException
{
super(model, tmgr);
// we'll need to be keeping this
_model = model;
// we need this to track object layer mods
_objectTileIds = new int[_model.baseTileIds.length];
}
// documentation inherited
public MisoTile getDefaultBaseTile ()
{
return _defaultBaseTile;
}
// documentation inherited
public void setDefaultBaseTile (MisoTile defaultBaseTile, int fqTileId)
{
_defaultBaseTile = defaultBaseTile;
_defaultBaseTileId = fqTileId;
}
// documentation inherited
public void setBaseTile (int x, int y, MisoTile tile, int fqTileId)
{
_base.setTile(x, y, tile);
// update the model as well
_model.baseTileIds[_model.width*y + x] = fqTileId;
}
// documentation inherited
public void setFringeTile (int x, int y, Tile tile, int fqTileId)
{
_fringe.setTile(x, y, tile);
// update the model as well
_model.fringeTileIds[_model.width*y + x] = fqTileId;
}
// documentation inherited
public void setObjectTile (int x, int y, ObjectTile tile, int fqTileId)
{
ObjectTile prev = _object.getTile(x, y);
// clear out any previous tile so that shadow tiles are properly
// removed
if (prev != null) {
clearObjectTile(x, y);
}
_object.setTile(x, y, tile);
// stick this value into our non-sparse object layer
_objectTileIds[_model.width*y + x] = fqTileId;
}
// documentation inherited
public void clearBaseTile (int x, int y)
{
_base.setTile(x, y, _defaultBaseTile);
// clear it out in the model
_model.baseTileIds[_model.width*y + x] = _defaultBaseTileId;
}
// documentation inherited
public void clearFringeTile (int x, int y)
{
_fringe.setTile(x, y, null);
// clear it out in the model
_model.fringeTileIds[_model.width*y + x] = 0;
}
// documentation inherited
public void clearObjectTile (int x, int y)
{
setObjectTileFootprint(x, y, _defaultBaseTile);
// clear it out in our non-sparse array
_objectTileIds[_model.width*y + x] = 0;
// we don't have to worry about setting the footprint in the model
// because footprints are always inferred from the contents of the
// object layer and the base layer in the model can simply contain
// the default tiles
}
// documentation inherited
public MisoSceneModel getModel ()
{
// we need to flush the object layer to the model prior to
// returning it
return _model;
}
/** Our scene model, which we always keep in sync with our display
* model data. */
protected MisoSceneModel _model;
/** A non-sparse array where we can keep track of the object tile
* ids. */
protected int[] _objectTileIds;
/** The default tile with which to fill the base layer. */
protected MisoTile _defaultBaseTile;
/** The fully qualified tile id of the default base tile. */
protected int _defaultBaseTileId;
}
@@ -0,0 +1,63 @@
//
// $Id: MisoSceneRuleSet.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
package com.threerings.media.tile.xml;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSetBase;
import com.samskivert.xml.SetFieldRule;
import com.threerings.miso.scene.MisoSceneModel;
/**
* Used to parse a {@link MisoSceneModel} from XML.
*/
public abstract class MisoSceneRuleSet extends RuleSetBase
{
/**
* Constructs a miso scene rule set which will match scenes with the
* supplied prefix. For example, passing <code>scene.miso</code> will
* match the scene in the following XML file:
*
* <pre>
* &lt;scene&gt;
* &lt;miso&gt;
* &lt;width&gt;50&lt;/width&gt;
* &lt;height&gt;50&lt;/height&gt;
* &lt;!-- ... --&gt;
* &lt;/miso&gt;
* &lt;/scene&gt;
* </pre>
*/
public MisoSceneRuleSet (String prefix)
{
_prefix = prefix;
}
/**
* Adds the necessary rules to the digester to parse our miso scene
* data.
*/
public void addRuleInstances (Digester digester)
{
// this creates the appropriate instance when we encounter our
// prefix tag
digester.addObjectCreate(_prefix, MisoSceneModel.class.getName());
// set up rules to parse and set our fields
digester.addRule(_prefix + "/width",
new SetFieldRule(digester, "width"));
digester.addRule(_prefix + "/height",
new SetFieldRule(digester, "height"));
digester.addRule(_prefix + "/base",
new SetFieldRule(digester, "baseTileIds"));
digester.addRule(_prefix + "/fringe",
new SetFieldRule(digester, "fringeTileIds"));
digester.addRule(_prefix + "/object",
new SetFieldRule(digester, "objectTileIds"));
}
/** The prefix at which me match our scenes. */
protected String _prefix;
}
@@ -0,0 +1,34 @@
//
// $Id: MisoSceneWriter.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
package com.threerings.miso.scene.xml;
import org.xml.sax.SAXException;
import com.megginson.sax.DataWriter;
import com.samskivert.util.StringUtil;
import com.threerings.miso.scene.MisoSceneModel;
/**
* Generates an XML representation of a {@link MisoSceneModel}.
*/
public class MisoSceneWriter
{
/**
* Writes the data for the supplied {@link MisoSceneModel} to the XML
* writer supplied. The writer will already be configured with the
* appropriate indentation level so that this writer can simply output
* its elements and allow the calling code to determine where in the
* greater scene description file the miso data should live.
*/
public void writeScene (MisoSceneModel model, DataWriter writer)
throws SAXException
{
writer.startElement("miso");
writer.dataElement("width", Integer.toString(model.width));
writer.dataElement("height", Integer.toString(model.height));
writer.dataElement("base", StringUtil.toString(model.baseTileIds));
writer.dataElement("fringe", StringUtil.toString(model.fringeTileIds));
writer.dataElement("object", StringUtil.toString(model.objectTileIds));
writer.endElement("miso");
}
}
@@ -1,315 +0,0 @@
//
// $Id: XMLSceneGroupParser.java,v 1.8 2001/11/12 20:56:55 mdb Exp $
package com.threerings.miso.scene.xml;
import java.io.*;
import java.util.*;
import org.xml.sax.*;
import com.samskivert.util.*;
import com.samskivert.xml.SimpleParser;
import com.threerings.miso.Log;
import com.threerings.miso.scene.*;
import com.threerings.miso.scene.util.MisoSceneUtil;
/**
* Parses an XML scene group description file, loads the referenced
* scenes into the runtime scene repository, and creates bindings
* between the portals in the scenes. Does not currently perform
* validation on the input XML stream, though the parsing code assumes
* the XML document is well-formed.
*/
public class XMLSceneGroupParser extends SimpleParser
{
// documentation inherited
public void startElement (
String uri, String localName, String qName, Attributes attributes)
{
if (qName.equals("scene")) {
// construct a new scene info object
_info.curscene = new SceneInfo(attributes.getValue("src"));
// add it to the list of scene info objects
_info.sceneinfo.add(_info.curscene);
} else if (qName.equals("portal")) {
// pull out the portal data
String src = attributes.getValue("src");
String destScene = attributes.getValue("destscene");
String dest = attributes.getValue("dest");
// construct a new portal info object
PortalInfo pinfo = new PortalInfo(src, destScene, dest);
// add it to the current scene's list of portal info objects
_info.curscene.portals.add(pinfo);
}
}
// documentation inherited
public void finishElement (
String uri, String localName, String qName, String data)
{
if (qName.equals("name")) {
_info.curscene.name = data;
} else if (qName.equals("entrance")) {
_info.curscene.entrance = data;
} else if (qName.equals("scene")) {
// TODO: load scene from scene repository and set
// _info.curscene.scene to the resulting scene object
} else if (qName.equals("scenegroup")) {
// now that we've obtained all scene info and fully loaded
// the associated scene objects, resolve bindings between
// all scenes in the group.
_info.resolveBindings();
// warn about any remaining un-bound portals
_info.checkUnboundPortals();
}
}
/**
* Parse the specified XML file and return a list of miso scene
* objects that have been fully bound and loaded into the scene
* repository.
*
* @param fname the file name.
*
* @return the list of scene objects, or null if an error occurred.
*/
public List loadSceneGroup (String fname) throws IOException
{
_info = new SceneGroupInfo();
parseFile(fname);
return _info.getScenes();
}
/** The scene group info gathered while parsing. */
protected SceneGroupInfo _info;
/**
* A class to hold information on the overall scene group while
* parsing, as well as the resulting list of scene objects
* produced when finished.
*/
class SceneGroupInfo
{
/** The scene info for all scenes described in the group. */
public ArrayList sceneinfo;
/** The current scene info. */
public SceneInfo curscene;
public SceneGroupInfo ()
{
sceneinfo = new ArrayList();
}
/**
* Return a list of the scene objects contained within all
* scene info objects. Intended to be called once all parsing
* and resolving of portal bindings has been completed.
*/
public List getScenes ()
{
ArrayList scenes = new ArrayList();
int size = sceneinfo.size();
for (int ii = 0; ii < size; ii++) {
scenes.add(((SceneInfo)sceneinfo.get(ii)).scene);
}
return scenes;
}
/**
* Return the scene object associated with the named scene
* info object.
*
* @param name the scene info name.
*
* @return the scene object or null if the scene info object
* isn't found or has no scene object.
*/
public MisoScene getScene (String name)
{
int size = sceneinfo.size();
for (int ii = 0; ii < size; ii++) {
SceneInfo sinfo = (SceneInfo)sceneinfo.get(ii);
if (sinfo.name.equals(name)) return sinfo.scene;
}
return null;
}
/**
* Resolve the portal bindings and entrance portal for all scenes.
*/
public void resolveBindings ()
{
int size = sceneinfo.size();
for (int ii = 0; ii < size; ii++) {
// retrieve the next scene info object
SceneInfo sinfo = (SceneInfo)sceneinfo.get(ii);
int psize = sinfo.portals.size();
for (int jj = 0; jj < psize; jj++) {
// retrieve the next portal info object
PortalInfo pinfo = (PortalInfo)sinfo.portals.get(jj);
// resolve the portal binding
resolvePortal(sinfo, pinfo);
// resolve the entrance portal
resolveEntrance(sinfo);
}
}
}
/**
* Resolve the binding for the portal in the given scene.
*
* @param sinfo the scene info.
* @param pinfo the portal info.
*/
protected void resolvePortal (SceneInfo sinfo, PortalInfo pinfo)
{
// get the source portal object
Portal src = MisoSceneUtil.getPortal(sinfo.scene, pinfo.src);
if (src == null) {
Log.warning("Missing source portal [scene=" + sinfo.name +
", pinfo=" + pinfo + "].");
return;
}
// get the destination scene
MisoScene destScene = getScene(pinfo.destScene);
if (destScene == null) {
Log.warning("Missing destination scene [scene=" + sinfo.name +
", pinfo=" + pinfo + "].");
return;
}
// get the destination portal object
Portal dest = MisoSceneUtil.getPortal(destScene, pinfo.dest);
if (dest == null) {
Log.warning("Missing destination portal [scene=" + sinfo.name +
", pinfo=" + pinfo + "].");
return;
}
// update source portal with full destination information
src.setDestination(destScene.getId(), dest);
}
/**
* Resolve the binding for the entrance portal in the given scene.
*
* @param sinfo the scene info.
*/
protected void resolveEntrance (SceneInfo sinfo)
{
Portal entrance = MisoSceneUtil.getPortal(
sinfo.scene, sinfo.entrance);
if (entrance == null) {
Log.warning( "Missing entrance portal [scene=" + sinfo.name +
", entrance=" + sinfo.entrance + "].");
return;
}
sinfo.scene.setEntrance(entrance);
}
/**
* Scan through all scenes and output a warning message if any
* portals are found that aren't bound to a destination
* portal. Intended for calling after {@link
* #resolveBindings} is called to make sure the scene group
* description wasn't lacking a binding for some portal; or,
* that the scenes don't contain any unintended or unnecessary
* portals.
*/
public void checkUnboundPortals ()
{
int size = sceneinfo.size();
for (int ii = 0; ii < size; ii++) {
// retrieve the next scene info object
SceneInfo sinfo = (SceneInfo)sceneinfo.get(ii);
// get the portals in the scene
List portals = sinfo.scene.getPortals();
// check each portal to make sure it has a valid destination
int psize = portals.size();
for (int jj = 0; jj < size; jj++) {
Portal portal = (Portal)portals.get(jj);
if (!portal.hasDestination()) {
Log.warning("Unbound portal [scene=" + sinfo.name +
", portal=" + portal + "].");
}
}
}
}
}
/**
* A class to hold information on a single scene's bindings.
*/
class SceneInfo
{
/** The logical scene name. */
public String name;
/** The scene description file path. */
public String src;
/** The default scene entrance. */
public String entrance;
/** The list of portal info objects describing portal bindings. */
public ArrayList portals;
/** The scene object obtained from the scene repository. */
public MisoSceneImpl scene;
public SceneInfo (String src)
{
this.src = src;
portals = new ArrayList();
}
}
/**
* A class to hold information on a single portal's bindings.
*/
class PortalInfo
{
/** The source portal name. */
public String src;
/** The destination portal name within the destination scene. */
public String dest;
/** The logical destination scene name. */
public String destScene;
public PortalInfo (String src, String destScene, String dest)
{
this.src = src;
this.destScene = destScene;
this.dest = dest;
}
public String toString ()
{
StringBuffer buf = new StringBuffer();
buf.append("[src=").append(src);
buf.append(", dest=").append(dest);
buf.append(", destScene=").append(destScene);
return buf.append("]").toString();
}
}
}
@@ -1,330 +0,0 @@
//
// $Id: XMLSceneParser.java,v 1.24 2001/11/08 03:04:44 mdb Exp $
package com.threerings.miso.scene.xml;
import java.io.*;
import java.util.ArrayList;
import org.xml.sax.*;
import com.samskivert.util.*;
import com.samskivert.xml.SimpleParser;
import com.threerings.media.tile.*;
import com.threerings.miso.Log;
import com.threerings.miso.scene.*;
import com.threerings.miso.tile.MisoTile;
/**
* 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 SimpleParser
{
public XMLSceneParser (IsoSceneViewModel model, TileManager tilemgr)
{
_model = model;
_tilemgr = tilemgr;
}
// documentation inherited
public void startElement (
String uri, String localName, String qName, Attributes attributes)
{
if (qName.equals("layer")) {
_info.lnum = parseInt(attributes.getValue("lnum"));
} else if (qName.equals("row")) {
_info.rownum = parseInt(attributes.getValue("rownum"));
_info.colstart = parseInt(attributes.getValue("colstart"));
}
}
// documentation inherited
public void finishElement (
String uri, String localName, String qName, String data)
{
if (qName.equals("name")) {
_info.scene.name = data;
} else if (qName.equals("version")) {
int version = parseInt(data);
if (version < 0 || version > XMLSceneVersion.VERSION) {
Log.warning(
"Unrecognized scene file format version, will attempt " +
"to continue parsing file but your mileage may vary " +
"[version=" + version +
", known_version=" + XMLSceneVersion.VERSION + "].");
}
} else if (qName.equals("locations")) {
int vals[] = StringUtil.parseIntArray(data);
addLocations(_info.scene.locations, vals);
} else if (qName.equals("cluster")) {
int vals[] = StringUtil.parseIntArray(data);
_info.scene.clusters.add(toCluster(_info.scene.locations, vals));
} else if (qName.equals("portals")) {
String vals[] = StringUtil.parseStringArray(data);
addPortals(_info.scene.portals, _info.scene.locations, vals);
} else if (qName.equals("entrance")) {
_info.scene.entrance = getEntrancePortal(data);
} else if (qName.equals("row")) {
addTileRow(_info, data);
} else if (qName.equals("scene")) {
// nothing for now
}
}
/**
* Add the tiles described by the given data to the scene.
*/
protected void addTileRow (SceneInfo info, String data)
{
try {
if (info.lnum == MisoScene.LAYER_BASE) {
readRowData(info, data);
} else {
readSparseRowData(info, data);
}
} catch (TileException te) {
Log.warning("Exception reading scene tile data " +
"[te=" + te + "].");
}
}
/**
* Given a string of comma-delimited tuples as (tileset id, tile
* id), populate the scene info tile array with tiles to suit.
*
* @param info the scene info.
* @param data the tile data.
*/
protected void readRowData (SceneInfo info, String data)
throws TileException
{
int[] vals = StringUtil.parseIntArray(data);
// make sure we have a suitable number of tiles
int validLen = _model.scenewid * 2;
if (vals.length != validLen) {
Log.warning(
"Invalid number of tiles in full row data set, skipping set " +
"[rownum=" + info.rownum + ", len=" + vals.length +
", valid_len=" + validLen + ", data=" + data + "].");
return;
}
// create the tile objects in the tile array
Tile[][] tiles = info.scene.getTiles(info.lnum);
for (int xx = 0; xx < vals.length; xx += 2) {
Tile tile = _tilemgr.getTile(vals[xx], vals[xx + 1]);
tiles[xx / 2][info.rownum] = tile;
}
}
/**
* Given a string of comma-delimited tuples as (tileset id, tile
* id) and having previously set up the scene info object's
* <code>rownum</code> and <code>colstart</code> member data by
* retrieving the attribute values when the <code>row</code>
* element tag was noted, this method then proceeds to populate
* the info object's tile array with tiles to suit.
*
* @param info the scene info.
* @param data the tile data.
*/
protected void readSparseRowData (SceneInfo info, String data)
throws TileException
{
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=" + info.rownum + ", colstart=" + info.colstart +
", len=" + vals.length + "].");
return;
}
// create the tile objects in the tile array
Tile[][] tiles = info.scene.getTiles(info.lnum);
for (int xx = 0; xx < vals.length; xx += 2) {
Tile tile = _tilemgr.getTile(vals[xx], vals[xx + 1]);
int xidx = info.colstart + (xx / 2);
tiles[xidx][info.rownum] = tile;
}
}
/**
* Given an array of integer values, return a <code>Cluster</code>
* object containing the location objects identified by location
* index number in the integer array.
*
* @param locs the locations list.
* @param vals the integer values.
*
* @return the cluster object.
*/
protected Cluster toCluster (ArrayList locs, int[] vals)
{
Cluster cluster = new Cluster();
for (int ii = 0; ii < vals.length; ii++) {
cluster.add((Location)locs.get(vals[ii]));
}
return cluster;
}
/**
* Given an array of integer values, add the <code>Location</code>
* objects represented therein to the given list, constructed from
* each successive triplet of values as (x, y, orientation) in the
* integer array.
*
* @param vals the integer values.
*/
protected void addLocations (ArrayList list, int[] vals)
{
// make sure we have a seemingly-appropriate number of points
if ((vals.length % 3) != 0) {
return;
}
// read in all of the locations and add to the list
for (int ii = 0; ii < vals.length; ii += 3) {
Location loc = new Location(
vals[ii], vals[ii+1], vals[ii+2]);
list.add(loc);
}
}
/**
* Given an array of string values, add the <code>Portal</code>
* objects constructed from each successive triplet of values as
* (locidx, portal name) in the array to the given portal list.
* The list of <code>Location</code> objects must have already
* been fully read previously.
*
* <p> 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
* <code>StringUtil.toString()</code> method to take care of
* tokenizing things for us, so, there you have it.
*
* @param portals the portal list.
* @param locs the location list.
* @param vals the String values.
*/
protected void addPortals (
ArrayList portals, ArrayList locs, String[] vals)
{
// make sure we have an appropriate number of values
if ((vals.length % 2) != 0) {
return;
}
// read in all of the portals
for (int ii = 0; ii < vals.length; ii += 2) {
int locidx = parseInt(vals[ii]);
// create the portal and add to the list
Portal portal = new Portal((Location)locs.get(locidx), vals[ii+1]);
portals.add(portal);
// upgrade the corresponding location in the location list
locs.set(locidx, portal);
}
}
/**
* Returns the default entrance portal for the scene, or
* <code>null</code> if an error occurs.
*/
protected Portal getEntrancePortal (String data)
{
ArrayList locs = _info.scene.locations;
int size = locs.size();
int pidx = parseInt(data);
if (size == 0 || pidx < 0 || pidx > size - 1) {
return null;
}
return (Portal)locs.get(pidx);
}
/**
* Parse the specified XML file and return a miso scene object with
* the data contained therein.
*
* @param path the full path to the scene description file.
*
* @return the scene object, or null if an error occurred.
*/
public EditableMisoScene loadScene (String path) throws IOException
{
return loadScene(getInputStream(path));
}
/**
* Parse the specified XML file and return a miso scene object with
* the data contained therein.
*
* @param stream the input stream from which the XML scene description
* can be read.
*
* @return the scene object, or null if an error occurred.
*/
public EditableMisoScene loadScene (InputStream stream) throws IOException
{
_info = new SceneInfo();
parseStream(stream);
// place shadow tiles for any objects in the scene
_info.scene.generateAllObjectShadows();
// return the final scene object
return _info.scene;
}
/** The iso scene view data model. */
protected IsoSceneViewModel _model;
/** The tile manager object for use in constructing scenes. */
protected TileManager _tilemgr;
/** Temporary storage of scene info while parsing. */
protected SceneInfo _info;
/**
* A class to hold the information gathered while parsing.
*/
class SceneInfo
{
/** The scene populated with data while parsing. */
public MisoSceneImpl scene;
/** The current layer number being processed. */
public int lnum;
/** The current row number being processed. */
public int rownum;
/** The column at which the current row data begins. */
public int colstart;
public SceneInfo ()
{
scene = new MisoSceneImpl(_model, null);
}
}
}
@@ -1,116 +0,0 @@
//
// $Id: XMLSceneRepository.java,v 1.15 2001/11/08 18:36:56 mdb Exp $
package com.threerings.miso.scene.xml;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import com.samskivert.util.Config;
import com.threerings.media.tile.TileManager;
import com.threerings.miso.Log;
import com.threerings.miso.scene.IsoSceneViewModel;
import com.threerings.miso.scene.MisoScene;
import com.threerings.miso.scene.EditableMisoScene;
import com.threerings.miso.util.MisoUtil;
/**
* The xml scene repository provides a mechanism for reading scenes
* from and writing scenes to XML files. These files are template
* scene files from which actual runtime game scenes will be
* constructed.
*/
public class XMLSceneRepository
{
/**
* Initializes the xml scene repository.
*
* @param config the config object.
* @param tilemgr the tile manager object.
*/
public void init (Config config, TileManager tilemgr)
{
// keep these for later
_config = config;
_tilemgr = tilemgr;
// get path-related information
_sceneRoot = _config.getValue(SCENEROOT_KEY, DEF_SCENEROOT);
// create an iso scene view model detailing scene dimensions
_model = new IsoSceneViewModel(config);
// construct the scene parser and writer objects for later use
_parser = new XMLSceneParser(_model, _tilemgr);
_writer = new XMLSceneWriter(_model);
}
/**
* Loads and returns a miso scene object for the scene described in
* the specified XML file.
*
* @param path the full pathname to the file.
*
* @return the scene object.
*/
public EditableMisoScene loadScene (String path) throws IOException
{
Log.info("Loading scene [path=" + path + "].");
return _parser.loadScene(path);
}
/**
* Loads and returns a miso scene object for the scene described in
* the XML file available via the supplied input stream.
*
* @param path the full pathname to the file.
*
* @return the scene object.
*/
public EditableMisoScene loadScene (InputStream stream)
throws IOException
{
return _parser.loadScene(stream);
}
/**
* Writes a scene to the specified file in the scene root
* directory in XML format. The filename should be relative to
* the scene root directory.
*
* @param scene the scene to save.
* @param path the full path of the file to write the scene to.
*/
public void saveScene (MisoScene scene, String path) throws IOException
{
Log.info("Saving scene [path=" + path + "].");
_writer.saveScene(scene, path);
}
/** The config object. */
protected Config _config;
/** The tile manager from which the scenes obtain their tiles. */
protected TileManager _tilemgr;
/** The root scene directory path. */
protected String _sceneRoot;
/** The iso scene view data model. */
protected IsoSceneViewModel _model;
/** The parser object for reading scenes from files. */
protected XMLSceneParser _parser;
/** The writer object for writing scenes to files. */
protected XMLSceneWriter _writer;
/** The config key for the root scene directory. */
protected static final String SCENEROOT_KEY =
MisoUtil.CONFIG_KEY + ".sceneroot";
/** The default root scene directory path. */
protected static final String DEF_SCENEROOT = "rsrc/scenes";
}
@@ -1,15 +0,0 @@
//
// $Id: XMLSceneVersion.java,v 1.1 2001/09/21 02:30:35 mdb Exp $
package com.threerings.miso.scene.xml;
/**
* This class tracks the version number of the XML scene file format. When
* modifications are made to the file format, the version number in this
* class should be increased.
*/
public class XMLSceneVersion
{
/** The latest scene file format version. */
public static int VERSION = 1;
}
@@ -1,368 +0,0 @@
//
// $Id: XMLSceneWriter.java,v 1.18 2001/10/25 16:36:43 shaper Exp $
package com.threerings.miso.scene.xml;
import java.io.*;
import java.util.List;
import com.samskivert.util.ListUtil;
import org.xml.sax.*;
import org.xml.sax.helpers.AttributesImpl;
import com.megginson.sax.DataWriter;
import com.threerings.media.tile.Tile;
import com.threerings.miso.Log;
import com.threerings.miso.scene.*;
import com.threerings.miso.tile.ShadowTile;
/**
* The <code>XMLSceneWriter</code> writes a {@link
* com.threerings.miso.scene.MisoScene} object to an XML file.
*
* <p> The scene id is omitted as the scene id is assigned when the
* scene template is actually loaded into a server. Similarly,
* portals are named and bound to their target scene ids later.
*/
public class XMLSceneWriter extends DataWriter
{
/**
* Construct an XMLSceneWriter object.
*/
public XMLSceneWriter (IsoSceneViewModel model)
{
_model = model;
setIndentStep(2);
}
/**
* Write the scenes to the specified output file in XML format.
*
* @param fname the file to write to.
*/
public void saveScene (MisoScene scene, String fname) throws IOException
{
FileOutputStream fos = new FileOutputStream(fname);
setOutput(new OutputStreamWriter(fos));
try {
startDocument();
startElement("scene");
dataElement("name", scene.getName());
dataElement("version", "" + XMLSceneVersion.VERSION);
dataElement("locations", getLocationData(scene));
startElement("clusters");
writeClusters(scene);
endElement("clusters");
dataElement("portals", getPortalData(scene));
dataElement("entrance", getEntranceData(scene));
startElement("tiles");
for (int lnum = 0; lnum < MisoScene.NUM_LAYERS; lnum++) {
writeLayer(scene, lnum);
}
endElement("tiles");
endElement("scene");
endDocument();
} catch (SAXException saxe) {
Log.warning("Exception writing scene to file " +
"[scene=" + scene + ", fname=" + fname +
", saxe=" + saxe + "].");
}
}
/**
* Output XML detailing the cluster objects. Clusters are
* described by a list of location object indexes that are
* contained within the cluster.
*
* @param scene the scene object.
*/
protected void writeClusters (MisoScene scene) throws SAXException
{
List clusters = scene.getClusters();
List locs = scene.getLocations();
int size = clusters.size();
for (int ii = 0; ii < size; ii++) {
Cluster cluster = (Cluster)clusters.get(ii);
List clusterlocs = cluster.getLocations();
StringBuffer buf = new StringBuffer();
int clustersize = clusterlocs.size();
for (int jj = 0; jj < clustersize; jj++) {
Location cloc = (Location)clusterlocs.get(jj);
buf.append(locs.indexOf(cloc));
if (jj < clustersize - 1) {
buf.append(",");
}
}
dataElement("cluster", buf.toString());
}
}
/**
* Output XML detailing the tiles at the specified layer in the
* given scene. The first layer is outputted in its entirety,
* whereas subsequent layers are outputted in a sparse notation
* that details each contiguous horizontal chunk of tiles in each
* row separately.
*
* @param scene the scene object.
* @param lnum the layer number.
*/
protected void writeLayer (MisoScene scene, int lnum) throws SAXException
{
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "lnum", "", "CDATA", "" + lnum);
startElement("", "layer", "", attrs);
for (int yy = 0; yy < _model.scenehei; yy++) {
if (lnum == MisoScene.LAYER_BASE) {
writeTileRowData(scene, yy, lnum);
} else {
writeSparseTileRowData(scene, yy, lnum);
}
}
endElement("layer");
}
/**
* Return a string representation of the portals in the scene. Each
* portal is specified by a comma-delimited tuple of (location
* index, portal name) values.
*
* @param scene the scene object.
*
* @return the portals in String format.
*/
protected String getPortalData (MisoScene scene)
{
List locs = scene.getLocations();
List portals = scene.getPortals();
StringBuffer buf = new StringBuffer();
int size = portals.size();
for (int ii = 0; ii < size; ii++) {
Portal portal = (Portal)portals.get(ii);
buf.append(locs.indexOf(portal)).append(",");
buf.append(portal.name);
if (ii < size - 1) {
buf.append(",");
}
}
return buf.toString();
}
/**
* Return a string representation of the locations in the scene.
* Each location is specified by a comma-delimited triplet of
* (x, y, orientation) values.
*
* @return the locations in String format.
*/
protected String getLocationData (MisoScene scene)
{
List locs = scene.getLocations();
StringBuffer buf = new StringBuffer();
int size = locs.size();
for (int ii = 0; ii < size; ii++) {
Location loc = (Location)locs.get(ii);
buf.append(loc.x).append(",");
buf.append(loc.y).append(",");
buf.append(loc.orient);
if (ii < size - 1) {
buf.append(",");
}
}
return buf.toString();
}
/**
* Returns a string detailing the location index of the default
* entrance portal for the scene, or <code>"-1"</code> if no
* default portal is specified or an error occurs.
*/
protected String getEntranceData (MisoScene scene)
{
List locs = scene.getLocations();
Portal entrance = scene.getEntrance();
if (locs.size() == 0 || entrance == null) {
return "-1";
}
return String.valueOf(locs.indexOf(entrance));
}
/**
* Return a string representation of the tiles at the specified
* row and layer in the given scene. Only <code>len</code> tiles
* starting at column <code>colstart</code> are included in the
* string.
*
* @param scene the scene object.
* @param rownum the row number.
* @param lnum the layer number.
* @param colstart the first column of data.
* @param len the number of columns of data.
*
* @return the tile data in String format.
*/
protected String getTileData (MisoScene scene, int rownum, int lnum,
int colstart, int len)
{
StringBuffer buf = new StringBuffer();
Tile[][][] tiles = scene.getTiles();
int numtiles = colstart + len;
for (int ii = colstart; ii < numtiles; ii++) {
Tile tile = tiles[lnum][ii][rownum];
if (tile == null) {
Log.warning("Null tile [x=" + ii + ", rownum=" + rownum +
", lnum=" + lnum + "].");
continue;
}
// replace shadow tiles with the default tile for the
// scene since they'll be re-created when the object's
// footprint is stamped into the scene upon its
// un-serialization
if (tile instanceof ShadowTile) {
tile = scene.getDefaultTile();
}
buf.append(tile.tsid).append(",");
buf.append(tile.tid);
if (ii != numtiles - 1) {
buf.append(",");
}
}
return buf.toString();
}
/**
* Write the row data for a specified row in the scene tile array.
*
* <p> The row is written as a <code>row</code> element. Each
* tile is specified by a comma-delimited tuple of (tile set id,
* tile id) numbers, with the associated row number detailed in
* the <code>rownum</code> attribute of the <code>row</code>
* element.
*
* @param scene the scene object.
* @param rownum the row in the scene tile array.
* @param lnum the layer number in the scene tile array.
*/
protected void writeTileRowData (MisoScene scene, int rownum, int lnum)
throws SAXException
{
// set up the attributes for this row
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "rownum", "", "CDATA", "" + rownum);
// output the full row data element
String data = getTileData(scene, rownum, lnum, 0, _model.scenewid);
dataElement("", "row", "", attrs, data);
}
/**
* Utility routine used by <code>writeSparseTileRowData</code> to
* obtain the sets of contiguous tile sets in each row.
*
* <p> The search for contiguous tiles starts at the column
* specified in <code>info[0]</code.
*
* <p> Results are returned in the <code>info</code> array as
* <code>{ colstart, len }</code>. colstart is -1 if no
* tiles were found in the rest of the row.
*
* @param scene the scene object.
* @param rownum the row number.
* @param lnum the layer number.
* @param info the info array.
*
* @return true if any tiles were found, false if not.
*/
protected boolean getSparseColumn (
MisoScene scene, int rownum, int lnum, int info[])
{
Tile[][][] tiles = scene.getTiles();
int start = -1, len = 0;
for (int xx = info[0]; xx < _model.scenewid; xx++) {
Tile tile = tiles[lnum][xx][rownum];
if (tile == null) {
if (start == -1) {
continue;
} else {
break;
}
}
if (start == -1) {
start = xx;
}
len++;
}
info[0] = start;
info[1] = len;
return (start != -1);
}
/**
* Write the row data for a specified row in the scene tile array
* in sparse row format.
*
* <p> Sparse row format is identical to the format detailed in
* <code>writeTileRowData()</code> except that a separate
* <code>row</code> element is outputted for each contiguous set
* of tiles, with the starting column detailed in the
* <code>colstart</code> attribute of the <code>row</code>
* element.
*
* @param scene the scene object.
* @param rownum the row in the scene tile array.
* @param lnum the layer number in the scene tile array.
*/
protected void
writeSparseTileRowData (MisoScene scene, int rownum, int lnum)
throws SAXException
{
// set up the attributes for this row
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "rownum", "", "CDATA", "" + rownum);
attrs.addAttribute("", "colstart", "", "CDATA", "0");
int info[] = new int[] { 0, 0 };
while (getSparseColumn(scene, rownum, lnum, info)) {
// update the colstart attribute
attrs.setAttribute(1, "", "colstart", "", "CDATA", "" + info[0]);
// output the partial row data element
String data = getTileData(scene, rownum, lnum, info[0], info[1]);
dataElement("", "row", "", attrs, data);
// update the colstart value
info[0] = info[0] + info[1];
}
}
/** The iso scene view data model. */
protected IsoSceneViewModel _model;
}
@@ -1,5 +1,5 @@
//
// $Id: MisoContext.java,v 1.6 2001/11/02 03:09:10 shaper Exp $
// $Id: MisoContext.java,v 1.7 2001/11/18 04:09:23 mdb Exp $
package com.threerings.miso.util;
@@ -10,12 +10,6 @@ import com.threerings.media.tile.TileManager;
public interface MisoContext extends Context
{
/**
* Returns a reference to the image manager. This reference is
* valid for the lifetime of the application.
*/
public ImageManager getImageManager ();
/**
* Returns a reference to the tile manager. This reference is
* valid for the lifetime of the application.
+3 -120
View File
@@ -1,25 +1,11 @@
//
// $Id: MisoUtil.java,v 1.14 2001/11/08 03:04:45 mdb Exp $
// $Id: MisoUtil.java,v 1.15 2001/11/18 04:09:23 mdb Exp $
package com.threerings.miso.util;
import java.awt.Frame;
import java.io.*;
import java.net.URL;
import java.net.MalformedURLException;
import com.samskivert.util.*;
import com.threerings.cast.CharacterManager;
import com.threerings.media.ImageManager;
import com.threerings.media.tile.*;
import java.io.IOException;
import com.samskivert.util.Config;
import com.threerings.miso.Log;
import com.threerings.miso.scene.*;
import com.threerings.miso.scene.xml.XMLComponentRepository;
import com.threerings.miso.scene.xml.XMLSceneRepository;
import com.threerings.miso.tile.*;
/**
* The miso util class provides miscellaneous routines for
@@ -75,107 +61,4 @@ public class MisoUtil
return config;
}
/**
* Creates a <code>CharacterManager</code> object.
*
* @param config the <code>Config</code> object.
* @param imgmgr the <code>ImageManager</code> object.
*
* @return the new character manager object or null if an error
* occurred.
*/
public static CharacterManager createCharacterManager (
Config config, ImageManager imgmgr)
{
XMLComponentRepository crepo =
new XMLComponentRepository(config, imgmgr);
CharacterManager charmgr = new CharacterManager(crepo);
charmgr.setCharacterClass(MisoCharacterSprite.class);
return charmgr;
}
/**
* Creates an <code>XMLSceneRepository</code> object, reading
* the name of the class to instantiate from the config object.
*
* @param config the <code>Config</code> object.
*
* @return the new scene repository object or null if an error
* occurred.
*/
public static XMLSceneRepository createSceneRepository (
Config config, TileManager tilemgr)
{
try {
XMLSceneRepository scenerepo = (XMLSceneRepository)
config.instantiateValue(SCENEREPO_KEY, DEF_SCENEREPO);
scenerepo.init(config, tilemgr);
return scenerepo;
} catch (Exception e) {
Log.warning("Failed to instantiate scene repository " +
"[e=" + e + "].");
return null;
}
}
/**
* Creates a <code>TileManager</code> object.
*
* @param config the <code>Config</code> object.
* @param imgmgr the <code>ImageManager</code> 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(imgmgr);
tilemgr.setTileSetRepository(tsrepo);
return tilemgr;
}
/**
* Creates a <code>TileSetRepository</code> object, reading the
* class name to instantiate from the config object.
*
* @param config the <code>Config</code> object.
* @param imgmgr the <code>ImageManager</code> object from which
* images are obtained.
*
* @return the new tile set repository or null if an error
* occurred.
*/
protected static TileSetRepository createTileSetRepository (
Config config, ImageManager imgmgr)
{
TileSetRepository tsrepo = null;
try {
tsrepo = (TileSetRepository)config.instantiateValue(
TILESETREPO_KEY, DEF_TILESETREPO);
tsrepo.init(config, imgmgr);
} catch (Exception e) {
Log.warning("Failed to instantiate tile set repository " +
"[e=" + e + "].");
}
return tsrepo;
}
/** The default scene repository class name. */
protected static final String DEF_SCENEREPO =
XMLSceneRepository.class.getName();
/** The default tile set repository class name. */
protected static final String DEF_TILESETREPO =
XMLTileSetRepository.class.getName();
/** The config key for the scene repository class. */
protected static final String SCENEREPO_KEY = CONFIG_KEY + ".scenerepo";
/** The config key for the tile set repository class. */
protected static final String TILESETREPO_KEY =
CONFIG_KEY + ".tilesetrepo";
}