* Add a fringe tile cache
Fringe tiles are added to a WeakHashMap used across the scene panel as they're created and then held with hard references by the scene blocks they're in. Whenever the last scene block referencing a fringe tile goes out of the influential radius, the fringe can be collected from the cache. In fringe heavy scenes this reduces the memory for fringe by a third. * Remove the mask cache The fringe cache reduced the number of times a mask needs to be generated, so eliminate the mask cache in the hopes of reclaiming a little more memory. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@548 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
package com.threerings.miso.client;
|
package com.threerings.miso.client;
|
||||||
|
|
||||||
|
import static com.threerings.miso.Log.log;
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@@ -40,11 +42,11 @@ import java.awt.event.ActionListener;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.event.MouseMotionListener;
|
import java.awt.event.MouseMotionListener;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
@@ -53,12 +55,13 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import com.samskivert.util.HashIntMap;
|
||||||
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.samskivert.swing.Controller;
|
import com.samskivert.swing.Controller;
|
||||||
import com.samskivert.swing.RadialMenu;
|
import com.samskivert.swing.RadialMenu;
|
||||||
import com.samskivert.swing.RuntimeAdjust;
|
import com.samskivert.swing.RuntimeAdjust;
|
||||||
import com.samskivert.swing.event.CommandEvent;
|
import com.samskivert.swing.event.CommandEvent;
|
||||||
import com.samskivert.util.HashIntMap;
|
|
||||||
import com.samskivert.util.StringUtil;
|
|
||||||
|
|
||||||
import com.threerings.media.VirtualMediaPanel;
|
import com.threerings.media.VirtualMediaPanel;
|
||||||
import com.threerings.media.sprite.Sprite;
|
import com.threerings.media.sprite.Sprite;
|
||||||
@@ -74,12 +77,11 @@ import com.threerings.miso.client.DirtyItemList.DirtyItem;
|
|||||||
import com.threerings.miso.data.MisoSceneModel;
|
import com.threerings.miso.data.MisoSceneModel;
|
||||||
import com.threerings.miso.data.ObjectInfo;
|
import com.threerings.miso.data.ObjectInfo;
|
||||||
import com.threerings.miso.tile.BaseTile;
|
import com.threerings.miso.tile.BaseTile;
|
||||||
|
import com.threerings.miso.tile.AutoFringer.FringeTile;
|
||||||
import com.threerings.miso.util.MisoContext;
|
import com.threerings.miso.util.MisoContext;
|
||||||
import com.threerings.miso.util.MisoSceneMetrics;
|
import com.threerings.miso.util.MisoSceneMetrics;
|
||||||
import com.threerings.miso.util.MisoUtil;
|
import com.threerings.miso.util.MisoUtil;
|
||||||
|
|
||||||
import static com.threerings.miso.Log.log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a Miso scene for all to see.
|
* Renders a Miso scene for all to see.
|
||||||
*/
|
*/
|
||||||
@@ -141,7 +143,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
{
|
{
|
||||||
_blocks.clear();
|
_blocks.clear();
|
||||||
_vizobjs.clear();
|
_vizobjs.clear();
|
||||||
_masks.clear();
|
_fringes.clear();
|
||||||
if (_dpanel != null) {
|
if (_dpanel != null) {
|
||||||
_dpanel.newScene();
|
_dpanel.newScene();
|
||||||
}
|
}
|
||||||
@@ -366,7 +368,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
"[scene=" + StringUtil.shortClassName(this) +
|
"[scene=" + StringUtil.shortClassName(this) +
|
||||||
", base=" + base.size() + "->" + (usage[0] / 1024) + "k" +
|
", base=" + base.size() + "->" + (usage[0] / 1024) + "k" +
|
||||||
", fringe=" + fringe.size() + "->" + (usage[1] / 1024) + "k" +
|
", fringe=" + fringe.size() + "->" + (usage[1] / 1024) + "k" +
|
||||||
", fmasks=" + _masks.size() + ", obj=" + object.size() +
|
", obj=" + object.size() +
|
||||||
"->" + (usage[2] / 1024) + "k" + "].");
|
"->" + (usage[2] / 1024) + "k" + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,7 +860,6 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
protected void computeInfluentialBounds ()
|
protected void computeInfluentialBounds ()
|
||||||
{
|
{
|
||||||
computeInfluentialBounds(_vbounds, _ibounds, _vibounds);
|
computeInfluentialBounds(_vbounds, _ibounds, _vibounds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1405,7 +1406,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
/** Computes the fringe tile for the specified coordinate. */
|
/** Computes the fringe tile for the specified coordinate. */
|
||||||
protected BaseTile computeFringeTile (int tx, int ty)
|
protected BaseTile computeFringeTile (int tx, int ty)
|
||||||
{
|
{
|
||||||
return _ctx.getTileManager().getAutoFringer().getFringeTile(_model, tx, ty, _masks);
|
return _ctx.getTileManager().getAutoFringer().getFringeTile(_model, tx, ty, _fringes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1553,8 +1554,14 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
/** A list of the potentially visible objects in the scene. */
|
/** A list of the potentially visible objects in the scene. */
|
||||||
protected List<SceneObject> _vizobjs = Lists.newArrayList();
|
protected List<SceneObject> _vizobjs = Lists.newArrayList();
|
||||||
|
|
||||||
/** For computing fringe tiles. */
|
/**
|
||||||
protected Map _masks = Maps.newHashMap();
|
* Map of active fringe tiles. Scene blocks have hard references to fringe tiles in this map
|
||||||
|
* for the tiles they're using, so the blocks coming in and out of the influential bounds
|
||||||
|
* determines which tiles remain in the map. The map is from FringeTile to FringeTile so a
|
||||||
|
* fully created FringeTile can be extracted from the map using a tile that contains only
|
||||||
|
* what's needed for hashCode and equals: id and passability.
|
||||||
|
*/
|
||||||
|
protected Map<FringeTile, FringeTile> _fringes = new WeakHashMap<FringeTile, FringeTile>();
|
||||||
|
|
||||||
/** The dirty sprites and objects that need to be re-painted. */
|
/** The dirty sprites and objects that need to be re-painted. */
|
||||||
protected DirtyItemList _dirtyItems = new DirtyItemList();
|
protected DirtyItemList _dirtyItems = new DirtyItemList();
|
||||||
|
|||||||
@@ -427,7 +427,6 @@ public class SceneBlock
|
|||||||
Map<Tile.Key,ObjectTile> objects, long[] usage)
|
Map<Tile.Key,ObjectTile> objects, long[] usage)
|
||||||
{
|
{
|
||||||
// account for our base tiles
|
// account for our base tiles
|
||||||
MisoSceneModel model = _panel.getSceneModel();
|
|
||||||
for (int yy = 0; yy < _bounds.height; yy++) {
|
for (int yy = 0; yy < _bounds.height; yy++) {
|
||||||
for (int xx = 0; xx < _bounds.width; xx++) {
|
for (int xx = 0; xx < _bounds.width; xx++) {
|
||||||
int x = _bounds.x + xx, y = _bounds.y + yy;
|
int x = _bounds.x + xx, y = _bounds.y + yy;
|
||||||
|
|||||||
@@ -21,40 +21,76 @@
|
|||||||
|
|
||||||
package com.threerings.miso.tile;
|
package com.threerings.miso.tile;
|
||||||
|
|
||||||
|
import static com.threerings.miso.Log.log;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Transparency;
|
import java.awt.Transparency;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import com.samskivert.util.CheapIntMap;
|
import com.samskivert.util.CheapIntMap;
|
||||||
import com.samskivert.util.QuickSort;
|
import com.samskivert.util.QuickSort;
|
||||||
|
|
||||||
import com.threerings.media.image.ImageManager;
|
|
||||||
import com.threerings.media.image.BufferedMirage;
|
import com.threerings.media.image.BufferedMirage;
|
||||||
|
import com.threerings.media.image.ImageManager;
|
||||||
import com.threerings.media.image.ImageUtil;
|
import com.threerings.media.image.ImageUtil;
|
||||||
|
|
||||||
import com.threerings.media.tile.NoSuchTileSetException;
|
import com.threerings.media.tile.NoSuchTileSetException;
|
||||||
import com.threerings.media.tile.Tile;
|
import com.threerings.media.tile.Tile;
|
||||||
import com.threerings.media.tile.TileManager;
|
import com.threerings.media.tile.TileManager;
|
||||||
import com.threerings.media.tile.TileSet;
|
import com.threerings.media.tile.TileSet;
|
||||||
import com.threerings.media.tile.TileUtil;
|
import com.threerings.media.tile.TileUtil;
|
||||||
|
|
||||||
import com.threerings.miso.data.MisoSceneModel;
|
import com.threerings.miso.data.MisoSceneModel;
|
||||||
|
|
||||||
import static com.threerings.miso.Log.log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically fringes a scene according to the rules in the supplied fringe configuration.
|
* Automatically fringes a scene according to the rules in the supplied fringe configuration.
|
||||||
*/
|
*/
|
||||||
public class AutoFringer
|
public class AutoFringer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static class FringeTile extends BaseTile
|
||||||
|
{
|
||||||
|
public FringeTile (long[] fringeId, boolean passable)
|
||||||
|
{
|
||||||
|
setPassable(passable);
|
||||||
|
_fringeId = fringeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals (Object obj)
|
||||||
|
{
|
||||||
|
if (!(obj instanceof FringeTile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FringeTile fObj = (FringeTile)obj;
|
||||||
|
return _passable == fObj._passable && Arrays.equals(_fringeId, fObj._fringeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode ()
|
||||||
|
{
|
||||||
|
int result = 33;
|
||||||
|
for (long key : _fringeId) {
|
||||||
|
result = result * 37 + (int)(key ^ (key >>> 32));
|
||||||
|
}
|
||||||
|
if(_passable) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The fringe keys of the tiles that went into this tile in the order they were drawn. */
|
||||||
|
protected long[] _fringeId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance that will fringe according to the rules in
|
* Constructs an instance that will fringe according to the rules in the supplied fringe
|
||||||
* the supplied fringe configuration.
|
* configuration.
|
||||||
*/
|
*/
|
||||||
public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr,
|
public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr, TileManager tmgr)
|
||||||
TileManager tmgr)
|
|
||||||
{
|
{
|
||||||
_fringeconf = fringeconf;
|
_fringeconf = fringeconf;
|
||||||
_imgr = imgr;
|
_imgr = imgr;
|
||||||
@@ -64,15 +100,16 @@ public class AutoFringer
|
|||||||
/**
|
/**
|
||||||
* Returns the fringe configuration used by this fringer.
|
* Returns the fringe configuration used by this fringer.
|
||||||
*/
|
*/
|
||||||
public FringeConfiguration getFringeConf () {
|
public FringeConfiguration getFringeConf ()
|
||||||
|
{
|
||||||
return _fringeconf;
|
return _fringeconf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute and return the fringe tile to be inserted at the specified
|
* Compute and return the fringe tile to be inserted at the specified location.
|
||||||
* location.
|
|
||||||
*/
|
*/
|
||||||
public BaseTile getFringeTile (MisoSceneModel scene, int col, int row, Map masks)
|
public BaseTile getFringeTile (MisoSceneModel scene, int col, int row,
|
||||||
|
Map<FringeTile, FringeTile> fringes)
|
||||||
{
|
{
|
||||||
// get the tileset id of the base tile we are considering
|
// get the tileset id of the base tile we are considering
|
||||||
int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16);
|
int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16);
|
||||||
@@ -114,12 +151,11 @@ public class AutoFringer
|
|||||||
// we allow users to splash in the water.
|
// we allow users to splash in the water.
|
||||||
if (passable && (btid > 0)) {
|
if (passable && (btid > 0)) {
|
||||||
try {
|
try {
|
||||||
BaseTile bt = (BaseTile) _tmgr.getTile(btid);
|
BaseTile bt = (BaseTile)_tmgr.getTile(btid);
|
||||||
passable = bt.isPassable();
|
passable = bt.isPassable();
|
||||||
} catch (NoSuchTileSetException nstse) {
|
} catch (NoSuchTileSetException nstse) {
|
||||||
log.warning("Autofringer couldn't find a base " +
|
log.warning("Autofringer couldn't find a base set while attempting to " +
|
||||||
"set while attempting to figure passability " +
|
"figure passability", nstse);
|
||||||
"[error=" + nstse + "].");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,68 +176,90 @@ public class AutoFringer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseTile frTile = new BaseTile();
|
return composeFringeTile(frecs, fringes, TileUtil.getTileHash(col, row), passable);
|
||||||
frTile.setPassable(passable);
|
|
||||||
composeFringeTile(frTile, frecs, masks, TileUtil.getTileHash(col, row));
|
|
||||||
return frTile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compose a FringeTile out of the various fringe images needed.
|
* Compose a FringeTile out of the various fringe images needed.
|
||||||
*/
|
*/
|
||||||
protected void composeFringeTile (Tile frTile, FringerRec[] fringers, Map masks, int hashValue)
|
protected FringeTile composeFringeTile (FringerRec[] fringers,
|
||||||
|
Map<FringeTile, FringeTile> fringes, int hashValue, boolean passable)
|
||||||
{
|
{
|
||||||
// sort the array so that higher priority fringers get drawn first
|
// sort the array so that higher priority fringers get drawn first
|
||||||
QuickSort.sort(fringers);
|
QuickSort.sort(fringers);
|
||||||
|
|
||||||
BufferedImage ftimg = null;
|
// Generate an identifier for the fringe tile being created as an array of the keys of its
|
||||||
|
// component tiles in the order they'll be drawn in the fringe tile.
|
||||||
|
List<Long> keys = Lists.newArrayList();
|
||||||
for (int ii = 0; ii < fringers.length; ii++) {
|
for (int ii = 0; ii < fringers.length; ii++) {
|
||||||
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
||||||
|
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
||||||
|
fringers[ii].baseset, hashValue);
|
||||||
|
int fringeset = tsr.fringe_tsid;
|
||||||
|
for (int jj = 0; jj < indexes.length; jj++) {
|
||||||
|
// Add a key for this tile as a long containing its base tile, the fringe set it's
|
||||||
|
// working with and the index used in that set.
|
||||||
|
keys.add((((long)fringers[ii].baseset) << 32) + (fringeset << 16) + indexes[jj]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long[] fringeId = new long[keys.size()];
|
||||||
|
for (int ii = 0; ii < fringeId.length; ii++) {
|
||||||
|
fringeId[ii] = keys.get(ii);
|
||||||
|
}
|
||||||
|
FringeTile frTile = new FringeTile(fringeId, passable);
|
||||||
|
|
||||||
|
// If the fringes map contains something with the same fringe identifier, this will pull
|
||||||
|
// it out and we can use it instead.
|
||||||
|
FringeTile result = fringes.get(frTile);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's no fringe with he same identifier, so we need to create the tile.
|
||||||
|
BufferedImage img = null;
|
||||||
|
for (int ii = 0; ii < fringers.length; ii++) {
|
||||||
|
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
||||||
|
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
||||||
|
fringers[ii].baseset, hashValue);
|
||||||
for (int jj = 0; jj < indexes.length; jj++) {
|
for (int jj = 0; jj < indexes.length; jj++) {
|
||||||
try {
|
try {
|
||||||
ftimg = getTileImage(ftimg, fringers[ii].baseset, indexes[jj], masks, hashValue);
|
img = getTileImage(img, tsr, fringers[ii].baseset, indexes[jj], hashValue);
|
||||||
} catch (NoSuchTileSetException nstse) {
|
} catch (NoSuchTileSetException nstse) {
|
||||||
log.warning("Autofringer couldn't find a needed tileset [error=" + nstse + "].");
|
log.warning("Autofringer couldn't find a needed tileset", nstse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
frTile.setImage(new BufferedMirage(img));
|
||||||
frTile.setImage(new BufferedMirage(ftimg));
|
fringes.put(frTile, frTile);
|
||||||
|
return frTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve or compose an image for the specified fringe.
|
* Retrieve or compose an image for the specified fringe.
|
||||||
*/
|
*/
|
||||||
protected BufferedImage getTileImage (BufferedImage ftimg, int baseset, int index,
|
protected BufferedImage getTileImage (BufferedImage img,
|
||||||
Map masks, int hashValue)
|
FringeConfiguration.FringeTileSetRecord tsr, int baseset, int index, int hashValue)
|
||||||
throws NoSuchTileSetException
|
throws NoSuchTileSetException
|
||||||
{
|
{
|
||||||
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(baseset, hashValue);
|
|
||||||
int fringeset = tsr.fringe_tsid;
|
int fringeset = tsr.fringe_tsid;
|
||||||
TileSet fset = _tmgr.getTileSet(fringeset);
|
TileSet fset = _tmgr.getTileSet(fringeset);
|
||||||
|
|
||||||
if (!tsr.mask) {
|
if (!tsr.mask) {
|
||||||
// oh good, this is easy
|
// oh good, this is easy
|
||||||
Tile stamp = fset.getTile(index);
|
Tile stamp = fset.getTile(index);
|
||||||
return stampTileImage(stamp, ftimg, stamp.getWidth(), stamp.getHeight());
|
return stampTileImage(stamp, img, stamp.getWidth(), stamp.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, it's a mask.. look for it in the cache..
|
// otherwise, it's a mask..
|
||||||
Long maskkey = Long.valueOf((((long) baseset) << 32) + (fringeset << 16) + index);
|
BufferedImage fsrc = _tmgr.getTileSet(fringeset).getRawTileImage(index);
|
||||||
BufferedImage img = (BufferedImage)masks.get(maskkey);
|
BufferedImage bsrc = _tmgr.getTileSet(baseset).getRawTileImage(0);
|
||||||
if (img == null) {
|
BufferedImage mask = ImageUtil.composeMaskedImage(_imgr, fsrc, bsrc);
|
||||||
BufferedImage fsrc = fset.getRawTileImage(index);
|
|
||||||
BufferedImage bsrc = _tmgr.getTileSet(baseset).getRawTileImage(0);
|
|
||||||
img = ImageUtil.composeMaskedImage(_imgr, fsrc, bsrc);
|
|
||||||
masks.put(maskkey, img);
|
|
||||||
}
|
|
||||||
ftimg = stampTileImage(img, ftimg, img.getWidth(null), img.getHeight(null));
|
|
||||||
|
|
||||||
return ftimg;
|
return stampTileImage(mask, img, mask.getWidth(null), mask.getHeight(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper function for {@link #getTileImage}. */
|
/** Helper function for {@link #getTileImage}. */
|
||||||
protected BufferedImage stampTileImage (Object stamp, BufferedImage ftimg, int width, int height)
|
protected BufferedImage stampTileImage (Object stamp, BufferedImage ftimg, int width,
|
||||||
|
int height)
|
||||||
{
|
{
|
||||||
// create the target image if necessary
|
// create the target image if necessary
|
||||||
if (ftimg == null) {
|
if (ftimg == null) {
|
||||||
@@ -247,17 +305,16 @@ public class AutoFringer
|
|||||||
return new int[0];
|
return new int[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList indexes = new ArrayList();
|
ArrayList<Integer> indexes = Lists.newArrayList();
|
||||||
int weebits = 0;
|
int weebits = 0;
|
||||||
for (int ii=(start + 1) % NUM_FRINGEBITS; ii != start;
|
for (int ii = (start + 1) % NUM_FRINGEBITS; ii != start; ii = (ii + 1) % NUM_FRINGEBITS) {
|
||||||
ii = (ii + 1) % NUM_FRINGEBITS) {
|
|
||||||
|
|
||||||
if (((1 << ii) & bits) != 0) {
|
if (((1 << ii) & bits) != 0) {
|
||||||
weebits |= (1 << ii);
|
weebits |= (1 << ii);
|
||||||
} else if (weebits != 0) {
|
} else if (weebits != 0) {
|
||||||
index = BITS_TO_INDEX[weebits];
|
index = BITS_TO_INDEX[weebits];
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
indexes.add(Integer.valueOf(index));
|
indexes.add(index);
|
||||||
}
|
}
|
||||||
weebits = 0;
|
weebits = 0;
|
||||||
}
|
}
|
||||||
@@ -265,31 +322,33 @@ public class AutoFringer
|
|||||||
if (weebits != 0) {
|
if (weebits != 0) {
|
||||||
index = BITS_TO_INDEX[weebits];
|
index = BITS_TO_INDEX[weebits];
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
indexes.add(Integer.valueOf(index));
|
indexes.add(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] ret = new int[indexes.size()];
|
int[] ret = new int[indexes.size()];
|
||||||
for (int ii=0; ii < ret.length; ii++) {
|
for (int ii = 0; ii < ret.length; ii++) {
|
||||||
ret[ii] = ((Integer) indexes.get(ii)).intValue();
|
ret[ii] = indexes.get(ii);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow subclasses to apply arbitrary modifications to tileset ids for
|
* Allow subclasses to apply arbitrary modifications to tileset ids for whatever nefarious
|
||||||
* whatever nefarious purposes they may have.
|
* purposes they may have.
|
||||||
*/
|
*/
|
||||||
protected int adjustTileSetId (int tileSetId) {
|
protected int adjustTileSetId (int tileSetId)
|
||||||
|
{
|
||||||
// by default, nothing.
|
// by default, nothing.
|
||||||
return tileSetId;
|
return tileSetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A record for holding information about a particular fringe as we're
|
* A record for holding information about a particular fringe as we're computing what it will
|
||||||
* computing what it will look like.
|
* look like.
|
||||||
*/
|
*/
|
||||||
static protected class FringerRec implements Comparable
|
static protected class FringerRec
|
||||||
|
implements Comparable<FringerRec>
|
||||||
{
|
{
|
||||||
int baseset;
|
int baseset;
|
||||||
int priority;
|
int priority;
|
||||||
@@ -301,15 +360,16 @@ public class AutoFringer
|
|||||||
priority = pri;
|
priority = pri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo (Object o)
|
public int compareTo (FringerRec o)
|
||||||
{
|
{
|
||||||
return priority - ((FringerRec) o).priority;
|
return priority - o.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString ()
|
public String toString ()
|
||||||
{
|
{
|
||||||
return "[base=" + baseset + ", pri=" + priority +
|
return "[base=" + baseset + ", pri=" + priority + ", bits="
|
||||||
", bits=" + Integer.toString(bits, 16) + "]";
|
+ Integer.toString(bits, 16) + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,8 +387,7 @@ public class AutoFringer
|
|||||||
|
|
||||||
protected static final int NUM_FRINGEBITS = 8;
|
protected static final int NUM_FRINGEBITS = 8;
|
||||||
|
|
||||||
// A matrix mapping adjacent tiles to which fringe bits
|
// A matrix mapping adjacent tiles to which fringe bits they affect.
|
||||||
// they affect.
|
|
||||||
// (x and y are offset by +1, since we can't have -1 as an array index)
|
// (x and y are offset by +1, since we can't have -1 as an array index)
|
||||||
// again, see docs/miso/fringebits.png
|
// again, see docs/miso/fringebits.png
|
||||||
//
|
//
|
||||||
@@ -339,9 +398,8 @@ public class AutoFringer
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The fringe tiles we use. These are the 17 possible tiles made
|
* The fringe tiles we use. These are the 17 possible tiles made up of continuous fringebits
|
||||||
* up of continuous fringebits sections.
|
* sections. Huh? see docs/miso/fringebits.png
|
||||||
* Huh? see docs/miso/fringebits.png
|
|
||||||
*/
|
*/
|
||||||
protected static final int[] FRINGETILES = {
|
protected static final int[] FRINGETILES = {
|
||||||
SOUTHEAST,
|
SOUTHEAST,
|
||||||
|
|||||||
Reference in New Issue
Block a user