From bb6b0f56ca86b841071f21616e45ffa442f8a3dc Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Fri, 17 May 2002 19:06:23 +0000 Subject: [PATCH] Changed MisoSceneModel so that it knows about the view width and height. It no longer stores base tiles that are not visable in the view, in fact it stores the base tiles in an array almost half the size as the fully expanded scene array, and this new smaller array is used everywhere: when saving the scene, serializing it to the user, or saving it in the database. We must now use the getBaseTile() and setBaseTile() methods to access the base tiles because they are stored in this compressed format. Also removed the fringe layer completely from the MisoSceneModel. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1369 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../miso/client/DisplayMisoSceneImpl.java | 13 +- .../miso/client/IsoSceneViewModel.java | 25 ++- .../threerings/miso/data/MisoSceneModel.java | 165 +++++++++++++++--- .../miso/tools/EditableMisoScene.java | 18 +- .../miso/tools/EditableMisoSceneImpl.java | 24 +-- .../miso/tools/xml/MisoSceneRuleSet.java | 16 +- .../miso/tools/xml/MisoSceneWriter.java | 5 +- 7 files changed, 180 insertions(+), 86 deletions(-) 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",