📄 mappy.java
字号:
/**
* Loads the BKDT chunk from the InputStream. <br>
* <br>
* BKDT: Block data. Contains BLKSTR structures for however many block
* structures were made. <br>
**/
private void loadBKDT(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
byte bytBKDT[];
byte bytTemp;
int intIndex;
int intImageByteSize;
Block block;
log.info("Found Chunk - BKDT, reading...");
log.info(" loading " + Integer.toString(m_intNoOfBlocks) + " blocks.");
bytBKDT = new byte[m_intBlockByteSize];
m_clsMapBlockStrPt = new Block[m_intNoOfBlocks];
for (intIndex = 0; intIndex < m_intNoOfBlocks; intIndex++) {
readStream(stream, bytBKDT, 0, bytBKDT.length);
// twistin..
if (blnLSB) {
for (int j = 0; j < 24; j += 4) {
bytTemp = bytBKDT[j];
bytBKDT[j] = bytBKDT[j+3];
bytBKDT[j+3] = bytTemp;
bytTemp = bytBKDT[j+1];
bytBKDT[j+1] = bytBKDT[j+2];
bytBKDT[j+2] = bytTemp;
}
bytTemp = bytBKDT[24];
bytBKDT[24] = bytBKDT[25];
bytBKDT[25] = bytTemp;
bytTemp = bytBKDT[26];
bytBKDT[26] = bytBKDT[27];
bytBKDT[27] = bytTemp;
}
// read in block
if (m_intMapType == 0) intImageByteSize = m_intBlockWidth * m_intBlockHeight * ((m_intColourDepth + 1) / 8); // that '+1' will be to cater for a colour depth of 15
else intImageByteSize = 1;
block = new Block();
block.setImageIndex(block.BACKGROUND, convertToInt(bytBKDT, 0, 4) / intImageByteSize);
block.setImageIndex(block.FOREGROUND1, convertToInt(bytBKDT, 4, 4) / intImageByteSize);
block.setImageIndex(block.FOREGROUND2, convertToInt(bytBKDT, 8, 4) / intImageByteSize);
block.setImageIndex(block.FOREGROUND3, convertToInt(bytBKDT, 12, 4) / intImageByteSize);
block.setUserData(1, convertToInt(bytBKDT, 16, 4));
block.setUserData(2, convertToInt(bytBKDT, 20, 4));
block.setUserData(3, convertToInt(bytBKDT, 24, 2));
block.setUserData(4, convertToInt(bytBKDT, 26, 2));
block.setUserData(5, convertToInt(bytBKDT, 28, 1));
block.setUserData(6, convertToInt(bytBKDT, 29, 1));
block.setUserData(7, convertToInt(bytBKDT, 30, 1));
block.setFlag(block.COLLISION_TOP_LEFT, ((bytBKDT[31] & 0x01) != 0 ? true : false));
block.setFlag(block.COLLISION_TOP_RIGHT, ((bytBKDT[31] & 0x02) != 0 ? true : false));
block.setFlag(block.COLLISION_BOTTOM_LEFT, ((bytBKDT[31] & 0x04) != 0 ? true : false));
block.setFlag(block.COLLISION_BOTTOM_RIGHT, ((bytBKDT[31] & 0x08) != 0 ? true : false));
block.setFlag(block.TRIGGER, ((bytBKDT[31] & 0x10) != 0 ? true : false));
block.setFlag(block.UNUSED1, ((bytBKDT[31] & 0x20) != 0 ? true : false));
block.setFlag(block.UNUSED2, ((bytBKDT[31] & 0x40) != 0 ? true : false));
block.setFlag(block.UNUSED3, ((bytBKDT[31] & 0x80) != 0 ? true : false));
m_clsMapBlockStrPt[intIndex] = block;
}
}
/**
* Loads the ANDT chunk from the InputStream. <br>
* <br>
* ANDT: Animation data. Contains ANISTR structures for however many
* animation structures were made, and also animation data. <br>
**/
private void loadANDT(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
byte bytANDT[];
byte bytTemp;
int intIndex;
int intANDTPos;
int intOffset1, intOffset2;
log.info("Found Chunk - ANDT, reading...");
bytANDT = new byte[intChunkLength];
readStream(stream, bytANDT, 0, bytANDT.length);
// count the no of AnimStructures
intIndex = 0;
intANDTPos = intChunkLength - 16;
while (bytANDT[intANDTPos] != -1) {
intIndex++;
intANDTPos -= 16;
}
log.info(" loading " + Integer.toString(intIndex) + " animation blocks." );
m_clsMapAniStrPt = new AnimStructure[intIndex];
// read in all the AnimStructures
intIndex = 0;
intANDTPos = intChunkLength - 16;
while (bytANDT[intANDTPos] != -1) {
m_clsMapAniStrPt[intIndex] = new AnimStructure();
m_clsMapAniStrPt[intIndex].antype = (int) bytANDT[intANDTPos + 0];
m_clsMapAniStrPt[intIndex].andelay = (int) bytANDT[intANDTPos + 1];
m_clsMapAniStrPt[intIndex].ancount = (int) bytANDT[intANDTPos + 2];
m_clsMapAniStrPt[intIndex].anuser = (int) bytANDT[intANDTPos + 3];
if (blnLSB) {
for (int j = 4; j < 16; j += 4) {
bytTemp = bytANDT[intANDTPos+j+0];
bytANDT[intANDTPos+j+0] = bytANDT[intANDTPos+j+3];
bytANDT[intANDTPos+j+3] = bytTemp;
bytTemp = bytANDT[intANDTPos+j+1];
bytANDT[intANDTPos+j+1] = bytANDT[intANDTPos+j+2];
bytANDT[intANDTPos+j+2] = bytTemp;
}
}
intOffset1 = convertToInt(bytANDT, intANDTPos + 8, 4);
intOffset2 = convertToInt(bytANDT, intANDTPos + 12, 4);
if (m_intMapType > 0) {
intOffset1 *= 4;
intOffset1 -= intChunkLength;
intOffset2 *= 4;
intOffset2 -= intChunkLength;
}
m_clsMapAniStrPt[intIndex].annumframes = (intOffset2 - intOffset1) / 4;
m_clsMapAniStrPt[intIndex].ancurframe = 1;
m_clsMapAniStrPt[intIndex].anframelist = new int[((intOffset2 - intOffset1) / 4) + 1];
for (int i = 0; i < (m_clsMapAniStrPt[intIndex].annumframes + 1); i++) {
if (blnLSB) {
bytTemp = bytANDT[intChunkLength + intOffset1 - 4];
bytANDT[intChunkLength + intOffset1 - 4] = bytANDT[intChunkLength + intOffset1 - 1];
bytANDT[intChunkLength + intOffset1 - 1] = bytTemp;
bytTemp = bytANDT[intChunkLength + intOffset1 - 3];
bytANDT[intChunkLength + intOffset1 - 3] = bytANDT[intChunkLength + intOffset1 - 2];
bytANDT[intChunkLength + intOffset1 - 2] = bytTemp;
}
m_clsMapAniStrPt[intIndex].anframelist[i] = convertToInt(bytANDT, intChunkLength + intOffset1 - 4, 4);
if (m_intMapType == 0) m_clsMapAniStrPt[intIndex].anframelist[i] /= m_intBlockByteSize;
intOffset1 += 4;
}
intIndex++;
intANDTPos -= 16;
}
}
/**
* Loads the BGFX chunk from the InputStream. <br>
* <br>
* BGFX: The raw graphics in whatever format the map is in. <br>
**/
private void loadBGFX(InputStream stream, int intChunkLength, Component component) throws IOException {
byte bytBGFX[];
byte bytTemp;
int intIndex;
int intRed, intGreen, intBlue;
int intColIndex;
int intX, intY, intImageY = -1;
int intColour;
int intImageSource[];
int intBlockIndex;
log.info("Found Chunk - BGFX, reading...");
log.info("Transpcol = "+((m_intTransparentColour>>16)&0xFF)+"."+((m_intTransparentColour>>8)&0xFF)+"."+((m_intTransparentColour)&0xFF));
log.info(" loading " + Integer.toString(m_intNoOfImages) + " images.");
bytBGFX = new byte[m_intBlockWidth * m_intBlockHeight * ((m_intColourDepth + 1) / 8)];
m_imgOpaqueBlocks = new Image[m_intNoOfImages];
m_imgTransparentBlocks = new Image[m_intNoOfImages];
for (intIndex = 0; intIndex < m_intNoOfImages; intIndex++) {
intImageSource = new int [m_intBlockWidth * m_intBlockHeight];
m_imgOpaqueBlocks[intIndex] = component.createImage(m_intBlockWidth, m_intBlockHeight);
Graphics gfx = m_imgOpaqueBlocks[intIndex].getGraphics();
// read in Image data
readStream(stream, bytBGFX, 0, bytBGFX.length);
// Note: LSB doesn't apply in graphics
intColIndex = 0;
for (intY = 0 ; intY < m_intBlockHeight; intY++) {
intImageY ++;
for (intX = 0 ; intX < m_intBlockWidth; intX++) {
// grab the colour of the pixel
switch (m_intColourDepth) {
case 8:
intRed = ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 0])) & 0xFF;
intGreen = ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 1])) & 0xFF;
intBlue = ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 2])) & 0xFF;
break;
case 15:
intRed = (((int) bytBGFX[intColIndex * 2 + 0]) & 0x7C) << 1;
intGreen = ((((int) bytBGFX[intColIndex * 2 + 0] & 0x03) << 3) | ((((int) bytBGFX[intColIndex * 2 + 1]) & 0xFF) >> 5)) << 3;
intBlue = (((int) bytBGFX[intColIndex * 2 + 1]) & 0x1F) << 3;
intRed &= 0xFF; intRed |= (intRed >> 5);
intGreen &= 0xFF; intGreen |= (intGreen >> 5);
intBlue &= 0xFF; intBlue |= (intBlue >> 5);
break;
case 16:
intRed = (((int) bytBGFX[intColIndex * 2 + 0]) & 0xF8);
intGreen = ((((int) bytBGFX[intColIndex * 2 + 0] & 0x07) << 3) | ((((int) bytBGFX[intColIndex * 2 + 1]) & 0xFF) >> 5)) << 2;
intBlue = (((int) bytBGFX[intColIndex * 2 + 1]) & 0x1F) << 3;
intRed &= 0xFF; intRed |= (intRed >> 5);
intGreen &= 0xFF; intGreen |= (intGreen >> 6);
intBlue &= 0xFF; intBlue |= (intBlue >> 5);
break;
case 24:
intRed = ((int) bytBGFX[intColIndex * 3 + 0]) & 0xFF;
intGreen = ((int) bytBGFX[intColIndex * 3 + 1]) & 0xFF;
intBlue = ((int) bytBGFX[intColIndex * 3 + 2]) & 0xFF;
break;
case 32:
intRed = ((int) bytBGFX[intColIndex * 4 + 1]) & 0xFF; // need & 0xFF to keep the int's posative
intGreen = ((int) bytBGFX[intColIndex * 4 + 2]) & 0xFF;
intBlue = ((int) bytBGFX[intColIndex * 4 + 3]) & 0xFF;
break;
default:
intRed = 0;
intGreen = 0;
intBlue = 0;
break;
}
gfx.setColor(new Color(intRed, intGreen, intBlue));
gfx.drawLine(intX, intY, intX, intY);
// build up pixel information of the transparent image
if (m_intColourDepth == 8) {
if (((int) bytBGFX[intColIndex]) == m_intTransparentColour) {
intColour = 0;
} else {
intColour = (255 << 24) | (intRed << 16) | (intGreen << 8) | intBlue;
}
} else {
if (((intRed << 16) | (intGreen << 8) | intBlue) == m_intTransparentColour) {
if (intX == 0 && intY == 0) log.info("Transpcol = "+m_intTransparentColour);
intColour = 0;
} else {
intColour = (255 << 24) | (intRed << 16) | (intGreen << 8) | intBlue;
}
}
intImageSource[intColIndex] = intColour;
intColIndex++;
}
}
// generate transparent image
m_imgTransparentBlocks[intIndex] = component.createImage(new MemoryImageSource (m_intBlockWidth, m_intBlockHeight, intImageSource, 0, m_intBlockWidth));
}
}
/**
* Loads the BODY / LYR? chunk from the InputStream. <br>
* <br>
* BODY: An array of short ints containing positive offsets into BKDT, and
* negative offsets into ANDT. <br>
* <br>
* LYR?: Where ? is an ASCII number form 1 to 7. These are the same size
* and format as BODY <br>
**/
private void loadLayer(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
byte bytBODY[];
byte bytTemp;
int intIndex;
int intX, intY;
short shtMapLayer[][];
int intLayer;
if (m_intMaxLayerNo == 0) {
log.info("Found Chunk - BODY, reading...");
} else {
log.info("Found Chunk - LYR" + Integer.toString(m_intMaxLayerNo) + ", reading...");
}
shtMapLayer = new short[m_intMapHeight][m_intMapWidth];
bytBODY = new byte[2];
for (intY = 0; intY < m_intMapHeight; intY++) {
for (intX = 0; intX < m_intMapWidth; intX++) {
readStream(stream,bytBODY, 0, 2);
if (blnLSB) {
bytTemp = bytBODY[0];
bytBODY[0] = bytBODY[1];
bytBODY[1] = bytTemp;
}
if (m_intMapType == 2) { //map is RLE compressed
int rlecount = ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
if (rlecount >= 32768) rlecount -= 65536;
if (rlecount > 0) {
while (rlecount > 0) {
readStream(stream,bytBODY, 0, 2);
if (blnLSB) {
bytTemp = bytBODY[0];
bytBODY[0] = bytBODY[1];
bytBODY[1] = bytTemp;
}
shtMapLayer[intY][intX] = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
intX++; rlecount--;
}
} else {
readStream(stream,bytBODY, 0, 2);
if (blnLSB) {
bytTemp = bytBODY[0];
bytBODY[0] = bytBODY[1];
bytBODY[1] = bytTemp;
}
short rleval = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
while (rlecount < 0) {
shtMapLayer[intY][intX] = rleval;
intX++; rlecount++;
}
}
intX--; //correct for RLE
} else {
shtMapLayer[intY][intX] = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
if (shtMapLayer[intY][intX] >= 0) {
if (m_intMapType == 0) shtMapLayer[intY][intX] /= m_intBlockByteSize;
} else {
if (m_intMapType == 0) shtMapLayer[intY][intX] /= 16;
}
}
}
}
// save layer to The Map
m_shtTheMap[m_intMaxLayerNo] = shtMapLayer;
m_intMaxLayerNo++;
}
/**
* This checks wether the given Map layer is valid or not. Originally used
* by a couple of methods, now only used by one, so I may incorporate this
* in to that one method before long. <br>
* <br>
* @see #setCurrentMapLayer(int)
**/
private boolean validateMapLayer(int intMapLayer, String strMethodName) {
boolean blnValid;
// default return value
blnValid = true;
// validate intLayer
if ((intMapLayer < 0) || (intMapLayer >= m_intMaxLayerNo)) {
log.error(new ArrayIndexOutOfBoundsException(strMethodName + " - 'intMapLayer' is out of bounds, there are only " + Integer.toString(m_intMaxLayerNo) + " layers : " + Integer.toString(intMapLayer)));
blnValid = false;
}
// return validity
return blnValid;
}
//______________________________________________________________________________
//------------------------------------------------------------------------------
// Private Methids : Drawing Routines
//______________________________________________________________________________
//------------------------------------------------------------------------------
/**
* This <code>drawLayer()</code> method is called by both of the public draw
* methods. <br>
* <br>
* @see #drawBackground(Graphics, boolean)
* @see #drawForeground(Graphics, int)
**/
private void drawLayer(Graphics gfx, int intBlockLayer, boolean blnTransparency) {
int intBlockX, intBlockY;
int intSrcPixX, intSrcPixY;
if (!m_blnMapLoaded) {
log.warn("drawLayer() - A map hasn't been successfully loaded yet!");
return;
}
intBlockX = m_intX[m_intCurrentMapLayer] / m_intBlockGapX;
intBlockY = m_intY[m_intCurrentMapLayer] / m_intBlockGapY;
intSrcPixX = m_intX[m_intCurrentMapLayer] % m_intBlockGapX;
intSrcPixY = m_intY[m_intCurrentMapLayer] % m_intBlockGapY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -