package com.eb.rpg.builtin; import java.io.IOException; import com.jinoh.ruby.marshal.CustomMarshallable; import com.jinoh.ruby.marshal.Marshaler; import com.jinoh.ruby.marshal.Unmarshaler; public class Table implements CustomMarshallable { private short[][][] mArray; public Table () { } public Table (int xSize, int ySize, int zSize) { mArray = new short[zSize][ySize][xSize]; } public short[][][] getInnerArray () { return mArray; } public void resize (int x, int y, int z) { short[][][] old = mArray; mArray = new short[x][y][z]; if (x == 0 || y == 0 || z == 0 || old.length == 0 || old[0].length == 0 || old[0][0].length == 0) return; for (int i = 0; i < old.length; ++i) for (int j = 0; j < old[0].length; ++i) System.arraycopy(old[i][j], 0, mArray[i][j], 0, old[i][j].length); } public int getXSize () { return mArray.length > 0 && mArray[0].length > 0 ? mArray[0][0].length : 0; } public int getYSize () { return mArray.length > 0 ? mArray[0].length : 0; } public int getZSize () { return mArray.length; } public int getValueAt (int x, int y, int z) { return mArray[z][y][x] & 0xFFFF; } public void setValueAt (int x, int y, int z, int val) { mArray[z][y][x] = (short) val; } protected int unpackL(byte[] arr, int start) { return (arr[start] & 0xFF) | ((arr[start+1] & 0xFF) << 8) | ((arr[start+2] & 0xFF) << 16) | ((arr[start+3] & 0xFF) << 24); } protected void packL(byte[] arr, int start, int val) { arr[0] = (byte) val; arr[1] = (byte) (val >>> 8); arr[2] = (byte) (val >>> 16); arr[3] = (byte) (val >>> 24); } protected short unpackS(byte[] arr, int start) { return (short) ((arr[start] & 0xFF) | ((arr[start+1] & 0xFF) << 8)); } protected void packS(byte[] arr, int start, short val) { arr[0] = (byte) val; arr[1] = (byte) (val >>> 8); } @Override public void load(Unmarshaler inst, byte[] data) throws IOException { unpackL(data, 0); // FIXME: This is 4byte integer (size), but what is the purpose of this? int sizeX = unpackL(data, 4), sizeY = unpackL(data, 8), sizeZ = unpackL(data, 12), p = 20; if (sizeX < 0 || sizeY < 0 || sizeZ < 0) throw new IOException ("Invalid size"); mArray = new short[sizeZ][sizeY][sizeX]; for (int i = 0; i < sizeZ; ++i) { for (int j = 0; j < sizeY; ++j) { for (int k = 0; k < sizeX; ++k) { mArray[i][j][k] = unpackS(data, p); p += 2; } } } } @Override public byte[] dump(Marshaler inst) throws IOException { int sizeZ = mArray.length, sizeY = mArray[0].length, sizeX = mArray[0][0].length, p = 20; byte[] data = new byte[p + (sizeZ * sizeY * sizeX * 2)]; packL(data, 3, 0); packL(data, sizeX, 4); packL(data, sizeY, 8); packL(data, sizeZ, 12); packL(data, sizeX * sizeY * sizeZ, 16); for (int i = 0; i < sizeZ; ++i) { for (int j = 0; j < sizeY; ++j) { for (int k = 0; k < sizeX; ++k) { packS(data, p, mArray[i][j][k]); p += 2; } } } return data; } }