diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 2b847e55e..21f9b1aed 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.57 2002/05/03 04:12:48 mdb Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.58 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene; @@ -117,7 +117,7 @@ public class DisplayMisoSceneImpl 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]; + int tsid = _model.getBaseTile(column, row); if (tsid > 0) { int tid = (tsid & 0xFFFF); tsid >>= 16; @@ -130,15 +130,6 @@ public class DisplayMisoSceneImpl BaseTile mtile = (BaseTile)_tmgr.getTile(tsid, tid); _base.setTile(column, row, mtile); } - - // 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); - } } } diff --git a/src/java/com/threerings/miso/client/IsoSceneViewModel.java b/src/java/com/threerings/miso/client/IsoSceneViewModel.java index 01cb2571b..bea310573 100644 --- a/src/java/com/threerings/miso/client/IsoSceneViewModel.java +++ b/src/java/com/threerings/miso/client/IsoSceneViewModel.java @@ -1,5 +1,5 @@ // -// $Id: IsoSceneViewModel.java,v 1.23 2002/03/28 22:32:32 mdb Exp $ +// $Id: IsoSceneViewModel.java,v 1.24 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene; @@ -34,6 +34,9 @@ public class IsoSceneViewModel /** Scene dimensions in tile count. */ public int scenewid, scenehei; + /** Size of the view in tile count. */ + public int scenevwid, scenevhei; + /** The bounds of the view in screen pixel coordinates. */ public Rectangle bounds; @@ -87,6 +90,12 @@ public class IsoSceneViewModel scenehei = MisoConfig.config.getValue( SCENE_HEIGHT_KEY, DEF_SCENE_HEIGHT); + // and the view dimensions + scenevwid = MisoConfig.config.getValue( + SCENE_VWIDTH_KEY, DEF_SCENE_VWIDTH); + scenevhei = MisoConfig.config.getValue( + SCENE_VHEIGHT_KEY, DEF_SCENE_VHEIGHT); + // get the tile dimensions tilewid = MisoConfig.config.getValue(TILE_WIDTH_KEY, DEF_TILE_WIDTH); tilehei = MisoConfig.config.getValue(TILE_HEIGHT_KEY, DEF_TILE_HEIGHT); @@ -102,12 +111,8 @@ public class IsoSceneViewModel SHOW_FOOTPRINTS_KEY, DEF_SHOW_FOOTPRINTS); // precalculate various things - int svwid = MisoConfig.config.getValue( - SCENE_VWIDTH_KEY, DEF_SCENE_VWIDTH); - int svhei = MisoConfig.config.getValue( - SCENE_VHEIGHT_KEY, DEF_SCENE_VHEIGHT); int offy = MisoConfig.config.getValue(SCENE_OFFSET_Y_KEY, DEF_OFFSET_Y); - precalculate(svwid, svhei, offy); + precalculate(offy); } /** @@ -135,11 +140,13 @@ public class IsoSceneViewModel this.tilewid = tilewid; this.tilehei = tilehei; this.finegran = finegran; + this.scenevwid = svwid; + this.scenevhei = svhei; // let our flags default to false // precalculate various things - precalculate(svwid, svhei, offy); + precalculate(offy); } /** @@ -203,10 +210,10 @@ public class IsoSceneViewModel * Pre-calculate various member data that are commonly used in working * with an isometric view. */ - protected void precalculate (int svwid, int svhei, int offy) + protected void precalculate (int offy) { // set the desired scene view bounds - bounds = new Rectangle(0, 0, svwid * tilewid, svhei * tilehei); + bounds = new Rectangle(0, 0, scenevwid * tilewid, scenevhei * tilehei); // set the scene display origin origin = new Point((bounds.width / 2), (offy * tilehei)); diff --git a/src/java/com/threerings/miso/data/MisoSceneModel.java b/src/java/com/threerings/miso/data/MisoSceneModel.java index 3aed83b93..ced8ad4c7 100644 --- a/src/java/com/threerings/miso/data/MisoSceneModel.java +++ b/src/java/com/threerings/miso/data/MisoSceneModel.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneModel.java,v 1.7 2002/05/16 03:54:18 mdb Exp $ +// $Id: MisoSceneModel.java,v 1.8 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene; @@ -12,6 +12,8 @@ import java.nio.IntBuffer; import com.samskivert.util.StringUtil; +import com.threerings.miso.Log; + /** * 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 @@ -26,13 +28,16 @@ public class MisoSceneModel /** 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 viewport width in tiles. */ + public int vwidth; - /** 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 viewport height in tiles. */ + public int vheight; + + /** The combined tile ids (tile set id and tile id) + * in compressed format. + * Don't go poking around in here, use the accessor methods. */ + public int[] baseTileIds; /** The combined tile ids (tile set id and tile id) of the files in * the object layer in (x, y, tile id) format. */ @@ -44,25 +49,102 @@ public class MisoSceneModel * empty string during serialization. */ public String[] objectActions; + /** + * Get the fully-qualified tile id of the base tile at the specified + * row and column. + */ + public int getBaseTile (int col, int row) + { + int index = getIndex(col, row); + return (index == -1) ? 0 : baseTileIds[index]; + } + + /** + * Set the fully-qualified tile id of a base tile. + * + * @return false if the specified tile coordinates are outside + * of the viewport and the tile was not saved. + */ + public boolean setBaseTile (int col, int row, int fqBaseTileId) + { + int index = getIndex(col, row); + if (index == -1) { + return false; + } + baseTileIds[index] = fqBaseTileId; + return true; + } + + /** + * Get the index into the baseTileIds[] for the specified + * x and y coordinates, or return -1 if the specified coordinates + * are outside of the viewable area. + * + * Assumption: The viewable area is centered and aligned as far + * to the top of the isometric scene as possible, such that + * the upper-left corner is at the point where the tiles + * (0, vwid) and (0, vwid-1) touch. The upper-right corner + * is at the point where the tiles (vwid-1, 0) and (vwid, 0) + * touch. + * + * The viewable area is made up of "fat" rows and "thin" rows. The + * fat rows display one more tile than the thin rows because their + * first and last tiles are halfway off the viewable area. The thin + * rows are fully contained within the viewable area except for the + * first and last thin rows, which display only their bottom and top + * halves, respectively. Note that #fatrows == #thinrows - 1; + */ + protected int getIndex (int x, int y) + { + // check to see if the index lies in one of the "fat" rows + if (((x + y) & 1) == (vwidth & 1)) { + + int col = (vwidth + x - y) >> 1; + int row = x - col; + if ((col < 0) || (col > vwidth) || + (row < 0) || (row >= vheight)) { + return -1; // out of view + } + + return (vwidth + 1) * row + col; + + } else { + // the index must be in a "thin" row + int col = (vwidth + x - y - 1) >> 1; + int row = x - col; + if ((col < 0) || (col >= vwidth) || + (row < 0) || (row > vheight)) { + return -1; // out of view + } + + // we store the all the fat rows first, then all the thin + // rows, the '(vwidth + 1) * vheight' is the size of all + // the fat rows. + return row * vwidth + col + (vwidth + 1) * vheight; + } + } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { - int tcount = width*height; int otc = objectTileIds.length; + int btc = baseTileIds.length; // write everything into a ByteBuffer, viewed as an IntBuffer and // then write the bytes from those operations out to the output // stream - ByteBuffer bbuf = ByteBuffer.allocate(4*tcount + 4*otc + 4*3); + ByteBuffer bbuf = ByteBuffer.allocate(4*(btc + otc + 5)); IntBuffer ibuf = bbuf.asIntBuffer(); // insert the dimensions ibuf.put(width); ibuf.put(height); + ibuf.put(vwidth); + ibuf.put(vheight); ibuf.put(otc); - // insert the layer data (except fringe) + // insert the layer data ibuf.put(baseTileIds); ibuf.put(objectTileIds); @@ -85,18 +167,16 @@ public class MisoSceneModel // what the data input stream expects width = in.readInt(); height = in.readInt(); + vwidth = in.readInt(); + vheight = in.readInt(); int otc = in.readInt(); // read in the base layer - int tcount = width*height; - baseTileIds = new int[tcount]; - for (int i = 0; i < tcount; i++) { + allocateBaseTileArray(); + for (int i = 0; i < baseTileIds.length; i++) { baseTileIds[i] = in.readInt(); } - // allocate, but don't read, the fringe layer - fringeTileIds = new int[tcount]; - // read in the object layer objectTileIds = new int[otc]; for (int i = 0; i < otc; i++) { @@ -110,14 +190,50 @@ public class MisoSceneModel } } + /** + * Convert an old school model to the new-style, baby. + * TODO: Remove this method someday after we've converted all + * our old scenes. + */ + public void convertOldSchool (int vwidth, int vheight) + { + // sanity check + if (baseTileIds.length != (width * height)) { + Log.warning("This isn't an old-school scene model!"); + return; + } + + this.vwidth = vwidth; + this.vheight = vheight; + + // make a copy of the oldschool base tile ids + int[] oldschool = baseTileIds; + allocateBaseTileArray(); + + int idx = 0; + for (int yy=0; yy < height; yy++) { + for (int xx=0; xx < width; xx++) { + setBaseTile(xx, yy, oldschool[idx++]); + } + } + } + + /** + * Allocate the base tile array. + */ + protected void allocateBaseTileArray () + { + baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)]; + } + /** * Generates a string representation of this scene model. */ public String toString () { return "[width=" + width + ", height=" + height + + ", vwidth=" + vwidth + ", vheight=" + vheight + ", baseTileIds=" + StringUtil.toString(baseTileIds) + - ", fringeTileIds=" + StringUtil.toString(fringeTileIds) + ", objectTileIds=" + StringUtil.toString(objectTileIds) + ", objectActions=" + StringUtil.toString(objectActions) + "]"; } @@ -130,7 +246,6 @@ public class MisoSceneModel { MisoSceneModel model = (MisoSceneModel)super.clone(); model.baseTileIds = (int[])baseTileIds.clone(); - model.fringeTileIds = (int[])fringeTileIds.clone(); model.objectTileIds = (int[])objectTileIds.clone(); model.objectActions = (String[])objectActions.clone(); return model; @@ -143,7 +258,7 @@ public class MisoSceneModel public static MisoSceneModel blankMisoSceneModel () { MisoSceneModel model = new MisoSceneModel(); - populateBlankMisoSceneModel(model, 0, 0); + populateBlankMisoSceneModel(model, 0, 0, 0, 0); return model; } @@ -151,10 +266,11 @@ public class MisoSceneModel * Creates and returns a blank scene model with the specified width * and height. */ - public static MisoSceneModel blankMisoSceneModel (int width, int height) + public static MisoSceneModel blankMisoSceneModel ( + int width, int height, int vwidth, int vheight) { MisoSceneModel model = new MisoSceneModel(); - populateBlankMisoSceneModel(model, width, height); + populateBlankMisoSceneModel(model, width, height, vwidth, vheight); return model; } @@ -162,12 +278,13 @@ public class MisoSceneModel * Populates a blank scene model with blank values. */ protected static void populateBlankMisoSceneModel ( - MisoSceneModel model, int width, int height) + MisoSceneModel model, int width, int height, int vwidth, int vheight) { model.width = width; model.height = height; - model.baseTileIds = new int[width*height]; - model.fringeTileIds = new int[width*height]; + model.vwidth = vwidth; + model.vheight = vheight; + model.allocateBaseTileArray(); model.objectTileIds = new int[0]; model.objectActions = new String[0]; } diff --git a/src/java/com/threerings/miso/tools/EditableMisoScene.java b/src/java/com/threerings/miso/tools/EditableMisoScene.java index e1939930b..fc2383cb5 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoScene.java +++ b/src/java/com/threerings/miso/tools/EditableMisoScene.java @@ -1,5 +1,5 @@ // -// $Id: EditableMisoScene.java,v 1.15 2002/04/27 18:41:14 mdb Exp $ +// $Id: EditableMisoScene.java,v 1.16 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene.tools; @@ -58,17 +58,6 @@ public interface EditableMisoScene */ public void setBaseTiles (Rectangle r, BaseTileSet set, int setId); - /** - * Updates the tile at the specified location in the fringe layer. - * - * @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 - * TileUtil#getFQTileId}) of the new default base tile. - */ - public void setFringeTile (int x, int y, Tile tile, int fqTileId); - /** * Addds an object tile to this scene. * @@ -90,11 +79,6 @@ public interface EditableMisoScene */ 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 specified tile from the object list. */ diff --git a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java index daafa071d..37110049f 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java +++ b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: EditableMisoSceneImpl.java,v 1.19 2002/05/03 04:12:48 mdb Exp $ +// $Id: EditableMisoSceneImpl.java,v 1.20 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene.tools; @@ -91,8 +91,8 @@ public class EditableMisoSceneImpl try { int index = _rando.nextInt(setcount); _base.setTile(x, y, (BaseTile) set.getTile(index)); - _model.baseTileIds[_model.width*y + x] = - TileUtil.getFQTileId(setId, index); + _model.setBaseTile( + x, y, TileUtil.getFQTileId(setId, index)); } catch (NoSuchTileException nste) { // not going to happen @@ -109,18 +109,10 @@ public class EditableMisoSceneImpl public void setBaseTile (int x, int y, BaseTile tile, int fqTileId) { _base.setTile(x, y, tile); - _model.baseTileIds[_model.width*y + x] = fqTileId; + _model.setBaseTile(x, y, fqTileId); _fringer.fringe(_model, _fringe, new Rectangle(x, y, 1, 1), _rando); } - // 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 addObjectTile (ObjectTile tile, int x, int y, int fqTileId) { @@ -148,14 +140,6 @@ public class EditableMisoSceneImpl _defaultBaseTileSet, _defaultBaseTileSetId); } - // 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 removeObjectTile (ObjectTile tile) { diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java index 0f1b38364..df13f023e 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneRuleSet.java,v 1.8 2002/05/16 02:25:19 ray Exp $ +// $Id: MisoSceneRuleSet.java,v 1.9 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene.tools.xml; @@ -9,6 +9,7 @@ import org.apache.commons.digester.RuleSetBase; import com.samskivert.xml.CallMethodSpecialRule; import com.samskivert.xml.SetFieldRule; +import com.threerings.miso.Log; import com.threerings.miso.scene.MisoSceneModel; /** @@ -51,6 +52,10 @@ public class MisoSceneRuleSet extends RuleSetBase new SetFieldRule(digester, "width")); digester.addRule(_prefix + "/height", new SetFieldRule(digester, "height")); + digester.addRule(_prefix + "/viewwidth", + new SetFieldRule(digester, "vwidth")); + digester.addRule(_prefix + "/viewheight", + new SetFieldRule(digester, "vheight")); digester.addRule(_prefix + "/base", new SetFieldRule(digester, "baseTileIds")); digester.addRule(_prefix + "/object", @@ -72,8 +77,13 @@ public class MisoSceneRuleSet extends RuleSetBase model.objectActions = new String[1]; } - // and allocate the fringe tile layer - model.fringeTileIds = new int[model.baseTileIds.length]; + // check to see if we've read in an old-style model. + // TODO: remove this someday after all our scenes are + // converted. + if (model.vwidth == 0) { + model.convertOldSchool(10, 12); + Log.info("Converted old-school MisoSceneModel."); + } } }); } diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java index 3225d6d3f..9427b45f4 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneWriter.java,v 1.6 2002/05/16 02:25:19 ray Exp $ +// $Id: MisoSceneWriter.java,v 1.7 2002/05/17 19:06:23 ray Exp $ package com.threerings.miso.scene.tools.xml; @@ -38,9 +38,10 @@ public class MisoSceneWriter { writer.dataElement("width", Integer.toString(model.width)); writer.dataElement("height", Integer.toString(model.height)); + writer.dataElement("viewwidth", Integer.toString(model.vwidth)); + writer.dataElement("viewheight", Integer.toString(model.vheight)); writer.dataElement("base", StringUtil.toString(model.baseTileIds, "", "")); - // note that we don't write the fringe layer. writer.dataElement("object", StringUtil.toString(model.objectTileIds, "", "")); writer.dataElement("actions",