Add transparency option on Flat and Surface map, fix file locks

This commit is contained in:
Mike Primm 2011-05-31 23:44:17 -05:00
parent c48d06eec1
commit c4646dc299
5 changed files with 102 additions and 15 deletions

View File

@ -38,6 +38,7 @@ public class FlatMap extends MapType {
private int ambientlight = 15;; private int ambientlight = 15;;
private int shadowscale[] = null; private int shadowscale[] = null;
private boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */ private boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
protected boolean transparency;
public FlatMap(ConfigurationNode configuration) { public FlatMap(ConfigurationNode configuration) {
this.configuration = configuration; this.configuration = configuration;
@ -69,6 +70,7 @@ public class FlatMap extends MapType {
ambientlight = Integer.parseInt(String.valueOf(o)); ambientlight = Integer.parseInt(String.valueOf(o));
} }
night_and_day = configuration.getBoolean("night-and-day", false); night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", false); /* Default off */
} }
@Override @Override
@ -115,8 +117,8 @@ public class FlatMap extends MapType {
boolean rendered = false; boolean rendered = false;
Color rslt = new Color(); Color rslt = new Color();
int[] pixel = new int[3]; int[] pixel = new int[4];
int[] pixel_day = new int[3]; int[] pixel_day = null;
KzedBufferedImage im = KzedMap.allocateBufferedImage(t.size, t.size); KzedBufferedImage im = KzedMap.allocateBufferedImage(t.size, t.size);
int[] argb_buf = im.argb_buf; int[] argb_buf = im.argb_buf;
KzedBufferedImage im_day = null; KzedBufferedImage im_day = null;
@ -124,6 +126,7 @@ public class FlatMap extends MapType {
if(night_and_day) { if(night_and_day) {
im_day = KzedMap.allocateBufferedImage(t.size, t.size); im_day = KzedMap.allocateBufferedImage(t.size, t.size);
argb_buf_day = im_day.argb_buf; argb_buf_day = im_day.argb_buf;
pixel_day = new int[4];
} }
MapChunkCache.MapIterator mapiter = cache.getIterator(t.x * t.size, 127, t.y * t.size); MapChunkCache.MapIterator mapiter = cache.getIterator(t.x * t.size, 127, t.y * t.size);
for (int x = 0; x < t.size; x++) { for (int x = 0; x < t.size; x++) {
@ -178,20 +181,27 @@ public class FlatMap extends MapType {
pixel[0] = c.getRed(); pixel[0] = c.getRed();
pixel[1] = c.getGreen(); pixel[1] = c.getGreen();
pixel[2] = c.getBlue(); pixel[2] = c.getBlue();
pixel[3] = c.getAlpha();
/* If transparency needed, process it */
if(transparency && (pixel[3] < 255)) {
process_transparent(pixel, pixel_day, mapiter);
}
/* If ambient light less than 15, do scaling */ /* If ambient light less than 15, do scaling */
if((shadowscale != null) && (ambientlight < 15)) { else if((shadowscale != null) && (ambientlight < 15)) {
if(mapiter.y < 127) if(mapiter.y < 127)
mapiter.incrementY(); mapiter.incrementY();
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */ if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
pixel_day[0] = pixel[0]; pixel_day[0] = pixel[0];
pixel_day[1] = pixel[1]; pixel_day[1] = pixel[1];
pixel_day[2] = pixel[2]; pixel_day[2] = pixel[2];
pixel_day[3] = 255;
} }
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight()); int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
pixel[0] = (pixel[0] * shadowscale[light]) >> 8; pixel[0] = (pixel[0] * shadowscale[light]) >> 8;
pixel[1] = (pixel[1] * shadowscale[light]) >> 8; pixel[1] = (pixel[1] * shadowscale[light]) >> 8;
pixel[2] = (pixel[2] * shadowscale[light]) >> 8; pixel[2] = (pixel[2] * shadowscale[light]) >> 8;
pixel[3] = 255;
} }
else { /* Only do height keying if we're not messing with ambient light */ else { /* Only do height keying if we're not messing with ambient light */
boolean below = mapiter.y < 64; boolean below = mapiter.y < 64;
@ -215,22 +225,25 @@ public class FlatMap extends MapType {
pixel[0] -= pixel[0] * scale; pixel[0] -= pixel[0] * scale;
pixel[1] -= pixel[1] * scale; pixel[1] -= pixel[1] * scale;
pixel[2] -= pixel[2] * scale; pixel[2] -= pixel[2] * scale;
pixel[3] = 255;
} else { } else {
pixel[0] += (255-pixel[0]) * scale; pixel[0] += (255-pixel[0]) * scale;
pixel[1] += (255-pixel[1]) * scale; pixel[1] += (255-pixel[1]) * scale;
pixel[2] += (255-pixel[2]) * scale; pixel[2] += (255-pixel[2]) * scale;
pixel[3] = 255;
} }
if(night_and_day) { if(night_and_day) {
pixel_day[0] = pixel[0]; pixel_day[0] = pixel[0];
pixel_day[1] = pixel[1]; pixel_day[1] = pixel[1];
pixel_day[2] = pixel[2]; pixel_day[2] = pixel[2];
pixel_day[3] = 255;
} }
} }
rslt.setRGBA(pixel[0], pixel[1], pixel[2], 255); rslt.setRGBA(pixel[0], pixel[1], pixel[2], pixel[3]);
argb_buf[(t.size-y-1) + (x*t.size)] = rslt.getARGB(); argb_buf[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
if(night_and_day) { if(night_and_day) {
rslt.setRGBA(pixel_day[0], pixel_day[1], pixel_day[2], 255); rslt.setRGBA(pixel_day[0], pixel_day[1], pixel_day[2], pixel[3]);
argb_buf_day[(t.size-y-1) + (x*t.size)] = rslt.getARGB(); argb_buf_day[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
} }
rendered = true; rendered = true;
@ -291,6 +304,75 @@ public class FlatMap extends MapType {
return rendered; return rendered;
} }
private void process_transparent(int[] pixel, int[] pixel_day, MapChunkCache.MapIterator mapiter) {
int r = pixel[0], g = pixel[1], b = pixel[2], a = pixel[3];
int r_day = 0, g_day = 0, b_day = 0, a_day = 0;
if(pixel_day != null) {
r_day = pixel[0]; g_day = pixel[1]; b_day = pixel[2]; a_day = pixel[3];
}
/* Handle lighting on cube */
if((shadowscale != null) && (ambientlight < 15)) {
boolean did_inc = false;
if(mapiter.y < 127) {
mapiter.incrementY();
did_inc = true;
}
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
r_day = r; g_day = g; b_day = b; a_day = a;
}
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
r = (r * shadowscale[light]) >> 8;
g = (g * shadowscale[light]) >> 8;
b = (b * shadowscale[light]) >> 8;
if(did_inc)
mapiter.decrementY();
}
if(a < 255) { /* If not opaque */
pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
if(pixel_day != null)
pixel_day[0] = pixel_day[1] = pixel_day[2] = pixel_day[3] = 0;
mapiter.decrementY();
if(mapiter.y >= 0) {
int blockType = mapiter.getBlockTypeID();
int data = 0;
Color[] colors = colorScheme.colors[blockType];
if(colorScheme.datacolors[blockType] != null) {
data = mapiter.getBlockData();
colors = colorScheme.datacolors[blockType][data];
}
if (colors != null) {
Color c = colors[0];
if (c != null) {
pixel[0] = c.getRed();
pixel[1] = c.getGreen();
pixel[2] = c.getBlue();
pixel[3] = c.getAlpha();
/* Recurse to resolve color here */
process_transparent(pixel, pixel_day, mapiter);
}
}
}
}
/* Blend colors from behind block and block, based on alpha */
r *= a;
g *= a;
b *= a;
int na = 255 - a;
pixel[0] = (pixel[0] * na + r) >> 8;
pixel[1] = (pixel[1] * na + g) >> 8;
pixel[2] = (pixel[2] * na + b) >> 8;
pixel[3] = 255;
if(pixel_day != null) {
r_day *= a_day;
g_day *= a_day;
b_day *= a_day;
na = 255 - a_day;
pixel_day[0] = (pixel_day[0] * na + r_day) >> 8;
pixel_day[1] = (pixel_day[1] * na + g_day) >> 8;
pixel_day[2] = (pixel_day[2] * na + b_day) >> 8;
pixel_day[3] = 255;
}
}
public String getName() { public String getName() {
return prefix; return prefix;

View File

@ -36,6 +36,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */ protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */ protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */
protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */ protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
protected boolean transparency; /* Is transparency support active? */
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -78,6 +79,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme")); colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
night_and_day = configuration.getBoolean("night-and-day", false); night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", true); /* Default on */
} }
public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) { public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) {
@ -438,10 +440,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
if (colors != null) { if (colors != null) {
Color c = colors[seq]; Color c = colors[seq];
if (c.getAlpha() > 0) { if (c.getAlpha() > 0) {
/* we found something that isn't transparent! */ /* we found something that isn't transparent, or not doing transparency */
if (c.getAlpha() == 255) { if ((!transparency) || (c.getAlpha() == 255)) {
/* it's opaque - the ray ends here */ /* it's opaque - the ray ends here */
result.setColor(c); result.setARGB(c.getARGB() | 0xFF000000);
if(lightlevel < 15) { /* Not full light? */ if(lightlevel < 15) { /* Not full light? */
shadowColor(result, lightlevel); shadowColor(result, lightlevel);
} }

View File

@ -113,15 +113,17 @@ public abstract class FileHandler implements HttpHandler {
out.write(readBuffer, 0, readBytes); out.write(readBuffer, 0, readBytes);
} }
} catch (IOException e) { } catch (IOException e) {
fileInput.close();
throw e; throw e;
} finally { } finally {
freeReadBuffer(readBuffer); freeReadBuffer(readBuffer);
} if(fileInput != null) {
closeFileInput(path, fileInput); closeFileInput(path, fileInput);
fileInput = null;
}
}
} catch (Exception e) { } catch (Exception e) {
if (fileInput != null) { if (fileInput != null) {
try { fileInput.close(); } catch (IOException ex) { } try { closeFileInput(path, fileInput); fileInput = null; } catch (IOException ex) { }
} }
throw e; throw e;
} }

View File

@ -28,6 +28,7 @@ public class FilesystemHandler extends FileHandler {
try { try {
result = new FileInputStream(file); result = new FileInputStream(file);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
FileLockManager.releaseReadLock(file);
return null; return null;
} }
response.fields.put(HttpField.ContentLength, Long.toString(file.length())); response.fields.put(HttpField.ContentLength, Long.toString(file.length()));