First implementation of new map

There are still a lot of issues, such as the lack of all the old layers,
left over code, and a few missing features (move to for example) But
this is a start.

Note that caching methods should not be bothered with for the moment, as
a cache directory and expiration date have not been coded.
master
Skiphs 2013-04-11 06:33:23 -07:00
parent 0a16501f8d
commit dafa8abd79
21 changed files with 1076 additions and 236 deletions

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src/test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/-4.10.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -100,7 +100,7 @@ public class ChunkManager extends Thread
this.players = null;
this.netherholdFinder = null;
}
private int[] ba(int a, int b, int c, int d) {
public int[] ba(int a, int b, int c, int d) {
try {
clearCache.invoke(iCache);
@ -111,6 +111,7 @@ public class ChunkManager extends Thread
return null;
}
public byte[] getBiomeForArea(int x, int y, int range) {
byte[] barr = new byte[range*range];
int[] temp = ba(x*Project.FRAGMENT_SIZE, y*Project.FRAGMENT_SIZE, range, range);

View File

@ -79,7 +79,7 @@ public class MapInfoPanel extends JPanel {
}
public void bPaint(Graphics2D g2d) {
public void bPaint(Graphics2D g2d) {/*
PixelInfo p = map.getCursorInformation();
int yOffset = getHeight() - 100;
@ -101,7 +101,7 @@ public class MapInfoPanel extends JPanel {
g2d.drawString("Z: " + p.getBlockY(), 16, yOffset + 90);
} else {
}
}*/
}
public void dispose() {

View File

@ -2,8 +2,10 @@ package MoF;
import amidst.Options;
import amidst.map.Map;
import amidst.map.MapObject;
import amidst.map.MapObjectPlayer;
import amidst.map.layers.BiomeLayer;
import java.awt.Color;
import java.awt.Font;
@ -46,6 +48,17 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
private double scale = 1;
private boolean dataChange, sizeChange, firstRun;
public int strongholdCount, villageCount;
private Map testMap;
private float lastMouseX, lastMouseY;
private float panSpeedX, panSpeedY;
private boolean mouseDown;
private int zoomLevel = 0, zoomTicksRemaining = 0;
private float targetZoom = 1.0f, curZoom = 1.0f;
private float zoomMouseX, zoomMouseY;
private static int offset[] = new int[] {
-1,-1,
-1, 0,
@ -78,68 +91,22 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
dataChange = true;
sizeChange = true;
firstRun = true;
chart = new PieChart(Biome.colors.length,0);
this.addMouseListener(this);
resized = true;
this.addComponentListener(this);
this.addMouseWheelListener(this);
menu = new JPopupMenu();
if (proj.saveLoaded) {
List<MapObjectPlayer> pl = proj.save.getPlayers();
for (MapObjectPlayer player : pl) {
JMenuItem tj = new JMenuItem("Move " + player.getName() + " here.");
tj.addActionListener(new MapListener(this, player.getName()));
menu.add(tj);
}
}
this.proj = proj;
testMap = new Map(proj.manager);
testMap.addLayer(new BiomeLayer());
testMap.load();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
updateFragments();
if (firstRun) {
centerAt(0,0);
firstRun = false;
}
for (int ey = 0; ey < fragYMax; ey++) {
for (int ex = 0; ex < fragXMax; ex++) {
Fragment tempFrag = frags.get(ey).get(ex);
tempFrag.tempX = (int)(((tempFrag.x - fragX - 1)*Project.FRAGMENT_SIZE)*scale + (int)mX);
tempFrag.tempY = (int)(((tempFrag.y - fragY - 1)*Project.FRAGMENT_SIZE)*scale + (int)mY);
tempFrag.paint(g2d,
tempFrag.tempX,
tempFrag.tempY,
(int)(Project.FRAGMENT_SIZE*scale),
(int)(Project.FRAGMENT_SIZE*scale));
if (tempFrag.marked) {
g2d.setColor(Color.pink);
g2d.drawRect(
tempFrag.tempX,
tempFrag.tempY,
(int)(Project.FRAGMENT_SIZE*scale),
(int)(Project.FRAGMENT_SIZE*scale));
}
}
}
for (int ey = 0; ey < fragYMax; ey++) {
for (int ex = 0; ex < fragXMax; ex++) {
Fragment tempFrag = frags.get(ey).get(ex);
for (MapObject m : tempFrag.objects) {
g2d.drawImage(m.getImage(),
(int) (tempFrag.tempX + m.rx * scale - (m.getWidth() >> 1)),
(int) (tempFrag.tempY + m.ry * scale - (m.getHeight() >> 1)),
m.getWidth(),
m.getHeight(),
null);
}
}
}
g2d.setColor(new Color(25, 25, 25));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(new Font("arial", Font.BOLD, 15));
@ -153,138 +120,44 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
tY = p.y;
}
}
if (resized) {
resized = false;
cleanUpdate();
if (zoomTicksRemaining-- > 0) {
float lastZoom = curZoom;
curZoom = (targetZoom + curZoom) * 0.5f;
double targetZoomX = testMap.getScaledX(lastZoom, curZoom, zoomMouseX);
double targetZoomY = testMap.getScaledY(lastZoom, curZoom, zoomMouseY);
testMap.moveBy(targetZoomX, targetZoomY);
testMap.setZoom(curZoom);
}
updateChart();
if (mouseDown) {
Point curMouse = this.getMousePosition();
if (curMouse != null) {
float difX = curMouse.x - lastMouseX;
float difY = curMouse.y - lastMouseY;
// TODO : Scale with time
panSpeedX = difX * 0.2f;
panSpeedY = difY * 0.2f;
lastMouseX += panSpeedX;
lastMouseY += panSpeedY;
}
}
panSpeedX *= 0.95f;
panSpeedY *= 0.95f;
testMap.moveBy(panSpeedX, panSpeedY);
testMap.draw(g2d);
}
public Project getProject() {
return proj;
}
private void updateChart() {
if (sizeChange) {
chart.setSources(fragXMax*fragYMax);
}
if (dataChange) {
chart.clearData();
villageCount = 0;
strongholdCount = 0;
for (int y = 0; y < fragYMax; y++) {
for (int x = 0; x < fragXMax; x++) {
chart.addData(frags.get(y).get(x).stat);
strongholdCount += frags.get(y).get(x).strongholdCount;
villageCount += frags.get(y).get(x).villageCount;
}
}
}
}
private void shiftFragmentX(int pos) {
dataChange = true;
int offset = (pos + 1) >> 1;
int marker = getWriteX(fragX + offset + fragXMax - 1);
fragX += pos;
for (int i = 0; i < fragYMax; i++) {
frags.get(getWriteY(fragY + i)).get(marker).disable();
frags.get(getWriteY(fragY + i)).set(marker, proj.getFragment(fragX + (fragXMax - 1) * offset, fragY + i));
}
}
private void shiftFragmentY(int pos) {
dataChange = true;
int offset = (pos + 1) >> 1;
int marker = getWriteY(fragY + offset + fragYMax - 1);
fragY += pos;
ArrayList<Fragment> tempList = new ArrayList<Fragment>(fragXMax);
for (int i = 0; i < fragXMax; i++)
tempList.add(null);
for (int i = 0; i < fragXMax; i++) {
frags.get(marker).get(getWriteX(fragX + i)).disable();
tempList.set(getWriteX(fragX + i), proj.getFragment(fragX + i, fragY + (fragYMax - 1) * offset));
}
frags.set(marker, tempList);
}
public void cleanUpdate() {
System.gc();
dataChange = true;
sizeChange = true;
for (int i = 0; i < fragYMax; i++) {
for (int c = 0; c < fragXMax; c++) {
frags.get(i).get(c).disable();
}
}
//Resize arrays
fragXMax = (int) (Math.round((double)this.getWidth()/((double)Project.FRAGMENT_SIZE*scale)) + 2);
fragYMax = (int) (Math.round((double)this.getHeight()/((double)Project.FRAGMENT_SIZE*scale)) + 2);
frags = new ArrayList<ArrayList<Fragment>>(fragYMax);
for (int i = 0; i < fragYMax; i++) {
frags.add(new ArrayList<Fragment>(fragXMax));
for (int c = 0; c < fragXMax; c++) {
frags.get(i).add(null);
}
}
for (int i = fragY; i < fragY + fragYMax; i++) {
for (int c = fragX; c < fragX + fragXMax; c++) {
frags.get(getWriteY(i)).set(getWriteX(c), proj.getFragment(c, i));
}
}
}
public PixelInfo getCursorInformation(Point c) {
PixelInfo p = null;
if (c!=null) {
if (fragXMax + fragYMax > 0) {
double fx = (((c.x - mX)/(scale*Project.FRAGMENT_SIZE)) + 1 + fragX);
double fy = (((c.y - mY)/(scale*Project.FRAGMENT_SIZE)) + 1 + fragY);
int ix = (int)fx;
int iy = (int)fy;
if (fx < 0)
ix--;
if (fy < 0)
iy--;
Fragment curFrag = frags.get(getWriteY(iy)).get(getWriteX(ix));
int ox = (int) ((fx - ix)*Project.FRAGMENT_SIZE);
int oy = (int) ((fy - iy)*Project.FRAGMENT_SIZE);
p = new PixelInfo(ix*Project.FRAGMENT_SIZE + ox, iy*Project.FRAGMENT_SIZE + oy, curFrag);
}
}
return p;
}
public PixelInfo getCursorInformation() {
Point c = this.getMousePosition();
return getCursorInformation(c);
}
private void updateFragments() {
double fragSize = scale*Project.FRAGMENT_SIZE;
if (mX > fragSize) {
mX -= fragSize; //Trigger Left Moving
shiftFragmentX(-1);
} else if (mX < 0) {
mX += fragSize; //Trigger Right Moving
shiftFragmentX(1);
}
if (mY > fragSize) {
mY -= fragSize; //Trigger Up Moving
shiftFragmentY(-1);
} else if (mY < 0) {
mY += fragSize; //Trigger Down Moving
shiftFragmentY(1);
}
}
public void centerAt(double x, double y) {
double adjX, adjY, zx, zy;
zx = x;
@ -301,14 +174,12 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
public void centerAndReset(double x, double y) {
centerAt(x,y);
cleanUpdate();
}
public void setScale(double scale) {
if ((scale <= 8)&&(scale >= 0.25)) {
this.scale = scale;
sizeChange = true;
cleanUpdate();
}
}
public void scaleBy(double scale) {
@ -336,7 +207,25 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
}
public void mouseWheelMoved(MouseWheelEvent e) {
Point curMouse = getMousePosition();
zoomMouseX = curMouse.x;
zoomMouseY = curMouse.y;
int notches = e.getWheelRotation();
if (notches > 0) {
if (zoomLevel < 10) {
targetZoom /= 1.1;
zoomLevel++;
zoomTicksRemaining = 100;
}
} else {
if (zoomLevel > -10) {
targetZoom *= 1.1;
zoomLevel--;
zoomTicksRemaining = 100;
}
}
double z = 2;
if (notches == 1)
z = 0.5;
@ -344,40 +233,6 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
}
@Override
public void mouseClicked(MouseEvent me) {
if (!me.isPopupTrigger()) {
PixelInfo p = getCursorInformation();
MapObject m = p.getFrag().getObjectAt(p.getX(), p.getY());
int rx = p.getX() - (p.getFrag().x * Project.FRAGMENT_SIZE);
int ry = p.getY() - (p.getFrag().y * Project.FRAGMENT_SIZE);
double dist = 3600;
if (m!=null)
dist = m.tempDist;
for (int i = 0; i < offset.length; i+=2) {
int ix = rx + offset[i ]*40;
int iy = ry + offset[i+1]*40;
if ( ((Math.abs(ix - (Project.FRAGMENT_SIZE >> 1))>(Project.FRAGMENT_SIZE >> 1))||(offset[i]==0))&
((Math.abs(iy - (Project.FRAGMENT_SIZE >> 1))>(Project.FRAGMENT_SIZE >> 1))||(offset[i+1]==0)) ) {
MapObject m2 = frags.get(getWriteY(p.getFrag().y + offset[i+1])).get(getWriteX(p.getFrag().x + offset[i])).getObjectAt(p.getX(), p.getY());
if ((m2!=null)&&(m2.isSelectable())&&(m2.tempDist < dist)) {
m = m2;
}
}
}
if (m!=null) {
if (proj.curTarget!=null) {
proj.curTarget.localScale = 1.0;
}
m.localScale = 2.0;
proj.curTarget = m;
} else {
if (proj.curTarget!=null)
proj.curTarget.localScale = 1.0;
proj.curTarget = null;
}
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
@ -390,9 +245,13 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
if (!arg0.isMetaDown()) {
mTracking = true;
Point p = this.getMousePosition();
tX = p.x;
tY = p.y;
Point curMouse = this.getMousePosition();
tX = curMouse.x;
tY = curMouse.y;
lastMouseX = curMouse.x;
lastMouseY = curMouse.y;
mouseDown = true;
}
}
private int tempX, tempY;
@ -405,6 +264,7 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
menu.show(e.getComponent(), e.getX(), e.getY());
}
} else {
mouseDown = false;
mTracking = false;
}
}
@ -437,9 +297,9 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi
}
public void movePlayer(String name, ActionEvent e) {
PixelInfo p = getCursorInformation(new Point(tempX, tempY));
//PixelInfo p = getCursorInformation(new Point(tempX, tempY));
proj.movePlayer(name, p);
//proj.movePlayer(name, p);
}
public void saveToFile(File f) {

View File

@ -69,6 +69,7 @@ public class Project extends JPanel {
//Create MapViewer
map = new MapViewer(this);
add(map, BorderLayout.CENTER);
minfo = new MapInfoPanel(map);
add(minfo, BorderLayout.EAST);
@ -114,11 +115,11 @@ public class Project extends JPanel {
}
return ret;
}
public void movePlayer(String name, PixelInfo p) {
for (int i = 0; i < save.getPlayers().size(); i++) {
if (name.toLowerCase().equals(save.getPlayers().get(i).getName().toLowerCase())) {
save.getPlayers().get(i).setPosition(p.getBlockX(), p.getBlockY());
map.cleanUpdate();
}
}
}
@ -132,12 +133,6 @@ public class Project extends JPanel {
this.seed = seed;
}
public Fragment getFragment(int x, int y) {
Fragment frag = new Fragment(x, y, FRAGMENT_SIZE);
manager.requestChunk(frag);
return frag;
}
public void moveMapTo(int x, int y) {
map.centerAndReset(x, y);

View File

@ -8,16 +8,25 @@ import java.io.IOException;
public class Amidst {
public final static int version_major = 3;
public final static int version_minor = 0;
private static FinderWindow mainWindow;
public static void main(String args[]) throws IOException {
Util.setLookAndFeel();
Google.startTracking();
Google.track("Run");
//TODO: load options
new FinderWindow();
mainWindow = new FinderWindow();
}
public static String version() {
return version_major + "." + version_minor;
}
public static FinderWindow getActiveWindow() {
return mainWindow;
}
public static String getPath() {
return ClassLoader.getSystemClassLoader().getResource(".").getPath();
}
}

38
src/amidst/Log.java Normal file
View File

@ -0,0 +1,38 @@
package amidst;
public class Log {
private static LogListener listener;
private static boolean isUsingListener;
public static void i(Object s) {
System.out.println("[info] " + s);
if (isUsingListener)
listener.info(s);
}
public static void debug(Object s) {
System.out.println("[debug] " + s);
if (isUsingListener)
listener.debug(s);
}
public static void w(Object s) {
System.err.println("[warning] " + s);
if (isUsingListener)
listener.warning(s);
}
public static void e(Object s) {
System.err.println("[error] " + s);
if (isUsingListener)
listener.error(s);
}
public static void kill(Object s) {
System.err.println("[kill] " + s);
if (isUsingListener)
listener.kill(s);
System.exit(0);
}
public static void writeTo(LogListener l) {
listener = l;
isUsingListener = (l != null);
}
}

View File

@ -0,0 +1,9 @@
package amidst;
public interface LogListener {
public void debug(Object o);
public void info(Object o);
public void warning(Object o);
public void error(Object o);
public void kill(Object o);
}

View File

@ -46,6 +46,21 @@ public class Util {
minecraftDirectory = (mcDir != null) ? mcDir : new File(homeDirectory, ".minecraft");
}
// Added for scripting support. (javascript has issues retaining the array types)
public static int[] arrayToColors(int[] src, int[] dst, int[] colors, int length) {
for (int i = 0; i < length; i++) {
dst[i] = colors[src[i]];
}
return dst;
}
public static int makeColor(int r, int g, int b) {
int color = 0xFF000000;
color |= 0xFF0000 & (r << 16);
color |= 0xFF00 & (g << 8);
color |= 0xFF & b;
return color;
}
// public static void main(String[] args) {
// try {
// int infinity = 1 / 0;

View File

@ -89,9 +89,9 @@ public class AmidstMenu extends JMenuBar {
@Override
public void actionPerformed(ActionEvent arg0) {
//Create the JOptionPane.
String s = JOptionPane.showInputDialog(null, "Enter seed", "New Project", JOptionPane.QUESTION_MESSAGE);
String s = JOptionPane.showInputDialog(null, "Enter seed", "New Project", JOptionPane.QUESTION_MESSAGE);
if (s != null) {
SaveLoader.Type worldType = choose("New Project", "Enter world type\n", SaveLoader.Type.values());
SaveLoader.Type worldType = choose("New Project", "Enter world type\n", SaveLoader.Type.values());
//If a string was returned, say so.
if (worldType != null)
@ -292,7 +292,7 @@ public class AmidstMenu extends JMenuBar {
* @param name name displayed in the choice
*/
private <T extends Point> void goToChosenPoint(T[] points, String name) {
T p = choose("Go to", "Select " + name + ":", points);
T p = choose("Go to", "Select " + name + ":", points);
if (p != null)
window.curProject.moveMapTo(p.x >> 2, p.y >> 2);
}

View File

@ -0,0 +1,93 @@
package amidst.map;
import java.util.Vector;
import amidst.Log;
public class ByteArrayCache extends CacheManager {
public static final int CACHE_SIZE = 32, CACHE_SHIFT = 5;
public static final int HEADER_SIZE = (CACHE_SIZE*CACHE_SIZE) >> 3;
public static final int CACHE_MAX_SIZE = CACHE_SIZE*CACHE_SIZE; // TODO : Change name to CACHE_LENGTH ?
private int maxUnits;
private byte unitSize;
private Vector<ByteArrayHub> cacheMap;
private byte[] byteCache;
public ByteArrayCache(byte unitSize, int maxUnits) {
cacheMap = new Vector<ByteArrayHub>();
this.unitSize = unitSize;
this.maxUnits = maxUnits;
byteCache = new byte[unitSize*maxUnits];
}
@Override
public void save(Fragment frag) {
}
@Override
public void load(Fragment frag, int layerID) {
long keyX = frag.getFragmentX() >> CACHE_SHIFT;
long keyY = frag.getFragmentY() >> CACHE_SHIFT;
long key = (keyX << 32) | (keyY & 0xFFFFFFFFL);
ByteArrayHub hub = getHub(key);
if (hub == null) {
hub = new ByteArrayHub(key, unitSize, maxUnits, cachePath);
Log.i("Loading [X:" + keyX + " Y:" + keyY + " KEY:" + key + "]"); // TODO : Remove
cacheMap.add(hub);
}
int subKeyX = Math.abs(frag.getFragmentX()) % CACHE_SIZE;
int subKeyY = Math.abs(frag.getFragmentY()) % CACHE_SIZE;
int subKey = (subKeyX << CACHE_SHIFT) + subKeyY;
//Log.i("FragX:" + frag.getFragmentX() + " FragY:" + frag.getFragmentY() + " |keyX:" + keyX + " keyY:" + keyY + " key:" + key + "| X:" + subKeyX + " Y:" + subKeyY + " Key:" + subKey + " TKey:" + hub.getKey());
byte[] tempData = null;
if (hub.exists(subKey)) {
tempData = hub.get(subKey);
} else {
//tempData = (byte[]) ((NativeJavaArray)PluginManager.call(funcSave, frag)).unwrap();
hub.put(subKey, tempData);
}
//PluginManager.call(funcLoad, frag, tempData, layerID);
hub.activeFragments++;
}
public void unload(Fragment frag) {
long keyX = frag.getFragmentX() >> CACHE_SHIFT;
long keyY = frag.getFragmentY() >> CACHE_SHIFT;
long key = (keyX << 32) | (keyY & 0xFFFFFFFFL);
ByteArrayHub hub = getHub(key);
hub.activeFragments--;
//Log.i(masterCount);
if (hub.activeFragments == 0) {
Log.i("Unloading [X:" + keyX + " Y:" + keyY + " KEY:" + key + "]"); // TODO : Remove
hub.unload();
cacheMap.remove(hub);
}
}
private ByteArrayHub getHub(long key) {
for (ByteArrayHub hub : cacheMap) {
if (hub.getKey() == key)
return hub;
}
return null;
}
// JS Shortcut
// TODO : Add more?
public byte[] intToCachedBytes(int[] data) {
for (int i = 0; i < byteCache.length; i++) {
byteCache[i] = (byte) data[i];
}
return byteCache;
}
}

View File

@ -0,0 +1,95 @@
package amidst.map;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import amidst.Log;
public class ByteArrayHub {
private File path;
private long key;
private byte unitSize;
private int maxUnits;
private int dataHop;
public int activeFragments = 0;
private byte[] data;
private byte[] returnCache;
private int unitOffset;
public ByteArrayHub(long key, byte unitSize, int maxUnits, String strPath) {
this.unitSize = unitSize;
this.maxUnits = maxUnits;
this.key = key;
unitOffset = maxUnits*unitSize;
path = new File(strPath + Long.toHexString(key).toUpperCase() + ".acache");
data = new byte[unitOffset*ByteArrayCache.CACHE_MAX_SIZE + ByteArrayCache.HEADER_SIZE];
returnCache = new byte[unitSize*maxUnits];
if (path.exists()) {
GZIPInputStream inStream;
try {
inStream = new GZIPInputStream(new FileInputStream(path));
byte[] readBuffer = new byte[1024];
int len;
int offset = 0;
while ((len = inStream.read(readBuffer)) != -1) {
System.arraycopy(readBuffer, 0, data, offset, len);
offset += len;
}
//Log.i("@@@@@ " + inStream.read(data));
inStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public boolean exists(int id) {
return (((data[id >> 3] >> (id % 8)) & 0x1) == 0x1);
}
public byte[] get(int id) {
System.arraycopy(data, ByteArrayCache.HEADER_SIZE + unitOffset*id, returnCache, 0, unitOffset);
return returnCache;
}
public void put(int id, byte[] indata) {
System.arraycopy(indata, 0, data, ByteArrayCache.HEADER_SIZE + unitOffset*id, unitOffset);
data[id >> 3] |= 0x1 << (id % 8);
}
public void unload() {
try {
BufferedOutputStream outStream = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(path)));
outStream.write(data, 0, data.length);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public long getKey() {
return key;
}
}

View File

@ -0,0 +1,23 @@
package amidst.map;
import java.io.File;
import amidst.Amidst;
public abstract class CacheManager {
protected String cachePath;
public CacheManager() {
}
public void setCachePath(String path) {
cachePath = Amidst.getPath() + "cache/" + path;
(new File(cachePath)).mkdirs();
}
public abstract void save(Fragment frag);
public abstract void load(Fragment frag, int layerID);
public abstract void unload(Fragment frag);
}

View File

@ -0,0 +1,118 @@
package amidst.map;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.Vector;
import amidst.Log;
public class Fragment {
public static final int SIZE = 256, SIZE_SHIFT = 8;
public int blockX, blockY;
private Layer[] layers;
private BufferedImage[] imgBuffers;
public boolean isActive = false;
public boolean isLoaded = false;
public Fragment nextFragment = null, prevFragment = null;
public boolean hasNext = false;
public boolean endOfLine = false;
private static int[] dataCache = new int[SIZE*SIZE];
public Fragment(Layer... layers) {
this.layers = layers;
imgBuffers = new BufferedImage[layers.length];
for (int i = 0; i < layers.length; i++) {
imgBuffers[i] = new BufferedImage(layers[i].size, layers[i].size, BufferedImage.TYPE_INT_ARGB);
}
}
public void load() {
if (isLoaded) {
Log.i("This should never happen!");
}
for (int i = 0; i < layers.length; i++) {
if (!layers[i].isLive())
layers[i].draw(this, i);
}
isLoaded = true;
}
public void recycle() {
isActive = false;
if (isLoaded) {
for (int i = 0; i < layers.length; i++) {
layers[i].unload(this);
}
}
isLoaded = false;
}
public void clear() {
//isLoaded = false;
hasNext = false;
endOfLine = false;
isActive = true;
for (int i = 0; i < imgBuffers.length; i++) {
imgBuffers[i].setRGB(0, 0, layers[i].size, layers[i].size, layers[i].getDefaultData(), 0, layers[i].size);
}
}
public void draw(Graphics2D g, AffineTransform mat) {
for (int i = 0; i < imgBuffers.length; i++) {
if (layers[i].isLive()) {
layers[i].drawLive(this, g, layers[i].getMatrix(mat));
} else {
g.setTransform(layers[i].getScaledMatrix(mat));
g.drawImage(imgBuffers[i], 0, 0, null);
}
}
}
public void setImageData(int layerID, int[] data) {
Layer layer = layers[layerID];
imgBuffers[layerID].setRGB(0, 0, layer.size, layer.size, data, 0, layer.size);
}
public int getChunkX() {
return blockX >> 4;
}
public int getChunkY() {
return blockY >> 4;
}
public int getFragmentX() {
return blockX >> SIZE_SHIFT;
}
public int getFragmentY() {
return blockY >> SIZE_SHIFT;
}
public void setNext(Fragment frag) {
nextFragment = frag;
frag.prevFragment = this;
hasNext = true;
}
public void remove() {
if (hasNext)
prevFragment.setNext(nextFragment);
else
prevFragment.hasNext = false;
}
public Graphics2D getDraw(int layerID) {
Graphics2D g2d = imgBuffers[layerID].createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
return g2d;
}
public static int[] getIntArray() {
return dataCache;
}
public BufferedImage getBufferedImage(int layerID) {
return imgBuffers[layerID];
}
}

View File

@ -0,0 +1,134 @@
package amidst.map;
import java.io.File;
import java.util.Arrays;
import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.ConcurrentLinkedQueue;
import amidst.Log;
public class FragmentManager extends Thread {
private static final int CACHE_SIZE = 512;
// TODO : Implement custom cache paths?
private boolean cacheEnabled = false;
private File cachePath;
private boolean running = true;
private boolean loaded = false;
private Fragment[] fragmentCache;
private ConcurrentLinkedQueue<Fragment> fragmentStack;
private ConcurrentLinkedQueue<Fragment> requestQueue;
private ConcurrentLinkedQueue<Fragment> recycleQueue;
private int sleepTick = 0;
private Stack<Layer> layerList;
public FragmentManager() {
cacheEnabled = false;
fragmentStack = new ConcurrentLinkedQueue<Fragment>();
requestQueue = new ConcurrentLinkedQueue<Fragment>();
recycleQueue = new ConcurrentLinkedQueue<Fragment>();
layerList = new Stack<Layer>();
}
public FragmentManager(File cachePath) {
this();
cacheEnabled = true;
this.cachePath = cachePath;
}
public void load() {
if (loaded) {
reset();
} else {
fragmentCache = new Fragment[CACHE_SIZE];
}
Layer[] layers = new Layer[layerList.size()];
for (int i = 0; i < layers.length; i++)
layers[i] = layerList.pop();
Arrays.sort(layers);
for (int i = 0; i < CACHE_SIZE; i++) {
fragmentCache[i] = new Fragment(layers);
fragmentStack.offer(fragmentCache[i]);
}
loaded = true;
}
public void reset() {
// TODO : Unload all fragments
}
public void addLayer(Layer layer) {
layerList.add(layer);
}
public Fragment requestFragment(int x, int y) {
if (!running)
return null;
Fragment frag = fragmentStack.poll();
frag.clear();
frag.blockX = x;
frag.blockY = y;
frag.isActive = true;
requestQueue.offer(frag);
return frag;
}
public void returnFragment(Fragment frag) {
recycleQueue.offer(frag);
}
public void run() {
this.setPriority(MIN_PRIORITY);
while (running) {
boolean needsSleep = false;
needsSleep = requestQueue.isEmpty();
if (!requestQueue.isEmpty()) {
Fragment frag = requestQueue.poll();
if (frag.isActive&&!frag.isLoaded) {
frag.load();
sleepTick++;
if (sleepTick == 10) {
sleepTick = 0;
try {
Thread.sleep(1L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**/
}
}
needsSleep &= recycleQueue.isEmpty();
while (!recycleQueue.isEmpty()) {
Fragment frag = recycleQueue.poll();
frag.recycle();
fragmentStack.offer(frag);
}
if (needsSleep) {
sleepTick = 0;
try {
Thread.sleep(2L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void close() {
this.running = false;
for (int i = 0; i < fragmentCache.length; i++) {
fragmentCache[i].recycle();
}
}
}

116
src/amidst/map/Layer.java Normal file
View File

@ -0,0 +1,116 @@
package amidst.map;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import MoF.ChunkManager;
import amidst.Log;
public class Layer implements Comparable<Layer> {
public String name;
public int size;
public float depth;
public float minZoom = 0;
public float maxZoom = 1024;
public double scale;
private AffineTransform mat = new AffineTransform();
private int[] defaultData;
public boolean cacheEnabled;
public CacheManager cacheManager;
public String cachePath;
private boolean live;
protected ChunkManager chunkManager;
public Layer(String name) {
this(name, null);
}
public Layer(String name, CacheManager cacheManager) {
this(name, cacheManager, 1f);
}
public Layer(String name, CacheManager cacheManager, float depth) {
this(name, cacheManager, depth, Fragment.SIZE);
}
public Layer(String name, CacheManager cacheManager, float depth, int size) {
this.name = name;
this.cacheManager = cacheManager;
this.cacheEnabled = (cacheManager != null);
this.depth = depth;
this.size = size;
defaultData = new int[size*size];
scale = ((double)Fragment.SIZE)/((double)size);
for (int i = 0; i < defaultData.length; i++)
defaultData[i] = 0x00000000;
}
public void unload(Fragment frag) {
if (cacheEnabled) {
cacheManager.unload(frag);
}
}
public void setLive(boolean live) {
this.live = live;
}
public Layer setMaxZoom(float maxZoom) {
this.maxZoom = maxZoom;
return this;
}
public Layer setMinZoom(float minZoom) {
this.minZoom = minZoom;
return this;
}
public int compareTo(Layer obj) {
Layer lObj = (Layer)obj;
if (depth < lObj.depth) return -1;
return (depth > lObj.depth)?1:0;
}
public int[] getDefaultData() {
return defaultData;
}
public void draw(Fragment frag, int layerID) {
if (cacheEnabled) {
cacheManager.load(frag, layerID);
} else {
drawCached(frag, layerID);
//PluginManager.call(funcDraw, frag, layerID);
}
}
public AffineTransform getMatrix(AffineTransform inMat) {
mat.setTransform(inMat);
return mat;
}
public AffineTransform getScaledMatrix(AffineTransform inMat) {
mat.setTransform(inMat); mat.scale(scale, scale);
return mat;
}
public boolean isLive() {
return live;
}
public void drawCached(Fragment fragment, int layerID) {
}
public void drawLive(Fragment fragment, Graphics2D g, AffineTransform mat) {
}
public void setChunkManager(ChunkManager chunkManager) {
this.chunkManager = chunkManager;
}
}

264
src/amidst/map/Map.java Normal file
View File

@ -0,0 +1,264 @@
package amidst.map;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.Stack;
import MoF.ChunkManager;
import amidst.Amidst;
import amidst.Log;
public class Map {
private static final boolean START = true, END = false;
private static final AffineTransform iMat = new AffineTransform();
private FragmentManager fManager;
private Fragment startNode = new Fragment();
private double drawPadding = Fragment.SIZE;
private double scale = 1.0, startX, startY;
private int sBlockX = 0;
private int eBlockX = 0;
private int tileWidth, tileHeight;
private boolean isLoaded = false;
private Object resizeLock = new Object();
private AffineTransform mat;
private ChunkManager chunkManager;
// TODO : This must be changed with the removal of ChunkManager
public Map(ChunkManager manager) {
chunkManager = manager;
fManager = new FragmentManager();
mat = new AffineTransform();
}
public void draw(Graphics2D g) {
if (!isLoaded) return;
// TODO : Change this to directly reference the window that renders it.
int width = Amidst.getActiveWindow().getWidth();
int height = Amidst.getActiveWindow().getHeight();
double size = ((double)Fragment.SIZE)*scale;
int w = (width) / (int)size + 2;
int h = (height) / (int)size + 2;
while (tileWidth < w) addColumn(END);
while (tileWidth > w) removeColumn(END);
while (tileHeight < h) addRow(END);
while (tileHeight > h) removeRow(END);
while (startX > 0) { startX -= size; addColumn(START); removeColumn(END); }
while (startX < -size) { startX += size; addColumn(END); removeColumn(START); }
while (startY > 0) { startY -= size; addRow(START); removeRow(END); }
while (startY < -size) { startY += size; addRow(END); removeRow(START); }
//g.setColor(Color.pink);
//g.fillRect(5, 5, width - 10, height - 10);
Fragment frag = startNode;
size = (double)Fragment.SIZE;
if (frag.hasNext) {
Fragment corner = frag.nextFragment;
double drawX = startX;
double drawY = startY;
mat.setToIdentity();
mat.translate(drawX, drawY);
mat.scale(scale, scale);
while (frag.hasNext) {
frag = frag.nextFragment;
frag.draw(g, mat);
mat.translate(size, 0);
if (frag.endOfLine) {
mat.translate(-size * w, size);
}
}
}
g.setTransform(iMat);
/*if (frag != null) {
frag.draw(g, 0, 0, Fragment.SIZE);
}*/
}
public void addStart(int x, int y) {
synchronized (resizeLock) {
Fragment start = fManager.requestFragment(x, y);
start.endOfLine = true;
startNode.setNext(start);
tileWidth = 1;
tileHeight = 1;
}
}
public void clear() {
}
public void addColumn(boolean start) {
synchronized (resizeLock) {
int x = 0;
Fragment frag = startNode;
if (start) {
x = frag.nextFragment.blockX - Fragment.SIZE;
Fragment newFrag = fManager.requestFragment(x, frag.nextFragment.blockY);
newFrag.setNext(startNode.nextFragment);
startNode.setNext(newFrag);
}
while (frag.hasNext) {
frag = frag.nextFragment;
if (frag.endOfLine) {
if (start) {
if (frag.hasNext) {
Fragment newFrag = fManager.requestFragment(x, frag.blockY + Fragment.SIZE);
newFrag.setNext(frag.nextFragment);
frag.setNext(newFrag);
frag = newFrag;
}
} else {
Fragment newFrag = fManager.requestFragment(frag.blockX + Fragment.SIZE, frag.blockY);
if (frag.hasNext) {
newFrag.setNext(frag.nextFragment);
}
newFrag.endOfLine = true;
frag.endOfLine = false;
frag.setNext(newFrag);
frag = newFrag;
}
}
}
tileWidth++;
}
}
public void removeRow(boolean start) {
synchronized (resizeLock) {
if (start) {
for (int i = 0; i < tileWidth; i++) {
Fragment frag = startNode.nextFragment;
frag.remove();
fManager.returnFragment(frag);
}
} else {
Fragment frag = startNode;
while (frag.hasNext)
frag = frag.nextFragment;
for (int i = 0; i < tileWidth; i++) {
frag.remove();
fManager.returnFragment(frag);
frag = frag.prevFragment;
}
}
tileHeight--;
}
}
public void addRow(boolean start) {
synchronized (resizeLock) {
Fragment frag = startNode;
int y;
if (start) {
frag = startNode.nextFragment;
y = frag.blockY - Fragment.SIZE;
} else {
while (frag.hasNext)
frag = frag.nextFragment;
y = frag.blockY + Fragment.SIZE;
}
tileHeight++;
Fragment newFrag = fManager.requestFragment(startNode.nextFragment.blockX, y);
Fragment chainFrag = newFrag;
for (int i = 1; i < tileWidth; i++) {
Fragment tempFrag = fManager.requestFragment(chainFrag.blockX + Fragment.SIZE, chainFrag.blockY);
chainFrag.setNext(tempFrag);
chainFrag = tempFrag;
if (i == (tileWidth - 1))
chainFrag.endOfLine = true;
}
if (start) {
chainFrag.setNext(frag);
startNode.setNext(newFrag);
} else {
frag.setNext(newFrag);
}
}
}
public void removeColumn(boolean start) {
synchronized (resizeLock) {
Fragment frag = startNode;
if (start) {
fManager.returnFragment(frag.nextFragment);
startNode.nextFragment.remove();
}
while (frag.hasNext) {
frag = frag.nextFragment;
if (frag.endOfLine) {
if (start) {
if (frag.hasNext) {
Fragment tempFrag = frag.nextFragment;
tempFrag.remove();
fManager.returnFragment(tempFrag);
}
} else {
frag.prevFragment.endOfLine = true;
frag.remove();
fManager.returnFragment(frag);
frag = frag.prevFragment;
}
}
}
tileWidth--;
}
}
public void moveBy(double x, double y) {
startX += x;
startY += y;
}
public void centerOn(int x, int y) {
}
public void addLayer(Layer layer) {
layer.setChunkManager(chunkManager);
fManager.addLayer(layer);
}
public void load() {
fManager.load();
fManager.start();
addStart(0, 0);
isLoaded = true;
}
public void setZoom(double scale) {
this.scale = scale;
}
public double getZoom() {
return scale;
}
public double getScaledX(double oldScale, double newScale, double x) {
double baseX = x - startX;
double dif = baseX - (baseX/oldScale) * newScale;
return dif;
}
public double getScaledY(double oldScale, double newScale, double y) {
double baseY = y - startY;
double dif = baseY - (baseY/oldScale) * newScale;
return dif;
}
public void close() {
isLoaded = false;
synchronized (resizeLock) {
fManager.close();
}
}
}

View File

@ -0,0 +1,71 @@
package amidst.map.layers;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import amidst.Util;
import amidst.map.ByteArrayCache;
import amidst.map.CacheManager;
import amidst.map.Fragment;
import amidst.map.Layer;
public class BiomeLayer extends Layer {
private static int[] biomeColors = new int[] {
Util.makeColor(13 ,51 ,219), //Ocean;
Util.makeColor(104,222,104), //Plains;
Util.makeColor(226,242,131), //Desert;
Util.makeColor(171,105,34 ), //Extreme Hills;
Util.makeColor(40 ,181,22 ), //Forest;
Util.makeColor(32 ,110,22 ), //Taiga;
Util.makeColor(108,158,79), //Swampland;
Util.makeColor(14,127,227), //River;
Util.makeColor(143,25 ,10 ), //Hell;
Util.makeColor(209,233,235), //Sky;
Util.makeColor(70 ,104,199), //FrozenOcean;
Util.makeColor(171,216,255), //FrozenRiver;
Util.makeColor(156,214,190), //Ice Plains;
Util.makeColor(151,162,130), //Ice Mountains;
Util.makeColor(219,196,164), //MushroomIsland;
Util.makeColor(242,216,179), //MushroomIslandShore;
Util.makeColor(255,254,189), //Beach
Util.makeColor(230,202, 78), //DesertHills
Util.makeColor(89 ,176, 32), //ForestHills
Util.makeColor(66 ,110, 22), //TaigaHills
Util.makeColor(186,159, 39), //Extreme Hills Edge
Util.makeColor(26 ,87 ,34 ),
Util.makeColor(73 ,105,33 )
};
private static int size = Fragment.SIZE >> 2;
public BiomeLayer() {
super("biome", null, 0.0f, size);
setLive(false);
}
public void drawCached(Fragment fragment, int layerID) {
int[] dataCache = Fragment.getIntArray();
int x = fragment.getChunkX() << 2;
int y = fragment.getChunkY() << 2;
// TODO : Change this when ChunkManager is removed!
int[] biomeData = chunkManager.ba(x, y, size, size);
dataCache = Util.arrayToColors(biomeData, dataCache, biomeColors, size*size);
fragment.setImageData(layerID, dataCache);
}
public void drawLive(Fragment fragment, Graphics2D g, AffineTransform mat) {
g.setColor(Color.black);
g.setTransform(mat);
g.fillRect(2, 2, 20, 20);
}
}

View File

@ -1,7 +1,5 @@
package amidst.nbt;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

View File

@ -6,7 +6,7 @@ import java.io.IOException;
import java.net.URL;
/**
* Allows to retrieve images, URLs,
* Allows to retrieve images, URLs,
*/
public class ResourceLoader {
private ResourceLoader() {}

View File

@ -1,7 +1,9 @@
package amidst.map;
package test.amidst.map;
import java.io.IOException;
import amidst.map.MapMarkers;
/** Tests if MapMarkers finds all files*/
public class MapMarkersTest {
@org.junit.Test