Fixing BinaryParser Loader
This commit is contained in:
		@ -31,11 +31,20 @@ level data at the top of the file.
 | 
			
		||||
      - 4 first bits : width
 | 
			
		||||
      - 4 last bits: height
 | 
			
		||||
    - next bytes -> Width * Height (+1 if Width * Height % 8 is not 0)
 | 
			
		||||
    - Position ( only for saved file )
 | 
			
		||||
      - 'F' and 'L' on 2 bytes for floating positions when the piece is not placed
 | 
			
		||||
      - x and y on 2 bytes for position if the piece is placed
 | 
			
		||||
 | 
			
		||||
### Saved file
 | 
			
		||||
 | 
			
		||||
For saved file, the extension will be .slevel
 | 
			
		||||
The only difference is that at the end of the map data (after the pieces and before the
 | 
			
		||||
Footer. there will be the position of each pieces from their top-left corner in the map.
 | 
			
		||||
following this pattern for each pieces
 | 
			
		||||
 | 
			
		||||
  - 'F' and 'L' on 2 bytes for floating positions when the piece is not placed
 | 
			
		||||
  - x and y on 2 bytes for position if the piece is placed
 | 
			
		||||
 | 
			
		||||
## Known Limitation
 | 
			
		||||
 | 
			
		||||
1) by putting the piece size on one byte. We limit the maximum piece size to 15 x 15 (1111 | 1111)
 | 
			
		||||
I don't think we will ever need a piece larger than 5x5 so this is clearly a feature, not a bug! :-)
 | 
			
		||||
We might use the same methods for the pieces positions but there could be a posibility to have
 | 
			
		||||
larger map if I use 2 bytes for the positions.
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ package school_project.Parsers;
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import school_project.Piece;
 | 
			
		||||
import school_project.Utils.Bitwise;
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
@ -115,14 +116,23 @@ public class BinaryParser implements FileParser {
 | 
			
		||||
        byte piece_count = levelData[3 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0)];
 | 
			
		||||
        Piece[] ret = new Piece[piece_count];
 | 
			
		||||
        byte[] pieces_data = Arrays.copyOfRange(levelData, 4 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0), levelData.length - 1);
 | 
			
		||||
        byte[] pieces_positions = saved_data ? Arrays.copyOfRange(levelData, levelData.length - 1 - piece_count,levelData.length - 1): null;
 | 
			
		||||
        int piece_offset = 0;
 | 
			
		||||
        for (int piece_index = 0; piece_index < piece_count; piece_index++) {
 | 
			
		||||
            // TODO: 3/24/23 BUG! this should not check every byte linearly like this... data are not next to each other...
 | 
			
		||||
            byte[] _piece_size = Bitwise.ByteToNible(pieces_data[piece_index]);
 | 
			
		||||
            byte _piece_width = _piece_size[0], _piece_height = _piece_size[1];
 | 
			
		||||
            byte[] _piece_data = Arrays.copyOfRange(pieces_data, piece_index + 1, 1 + _piece_width * _piece_height / 8 + (_piece_height * _piece_width % 8 != 0 ? 1 : 0));
 | 
			
		||||
            byte[] _piece_save_data = Arrays.copyOfRange(pieces_data, )
 | 
			
		||||
            boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_width, _piece_height, _piece_data);
 | 
			
		||||
            Vec2 _piece_size = Bitwise.ByteToNible(pieces_data[piece_index + piece_offset]);
 | 
			
		||||
 | 
			
		||||
            byte[] _piece_data = Arrays.copyOfRange(pieces_data, piece_index + piece_offset + 1, piece_index + piece_offset + 1 + _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
            boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_size.x, _piece_size.y, _piece_data);
 | 
			
		||||
 | 
			
		||||
            ret[piece_index] = new Piece(_piece_matrix);
 | 
			
		||||
 | 
			
		||||
            if(saved_data){
 | 
			
		||||
                Vec2 _piece_pos = new Vec2(pieces_positions[piece_index*2], pieces_positions[piece_index*2 + 1]);
 | 
			
		||||
                ret[piece_index].setPosition(_piece_pos);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            piece_offset += _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0);
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
@ -212,7 +222,7 @@ public class BinaryParser implements FileParser {
 | 
			
		||||
            ret += p.getHeight() * p.getWidth() / 8;
 | 
			
		||||
            ret += p.getHeight() * p.getWidth() % 8 == 0 ? 0 : 1; // add 1 if the size of the piece is not mult of 8
 | 
			
		||||
            if(data){
 | 
			
		||||
                ret += p.getPosition() != null ? 2: 1; // if the piece is not placed, only one byte else 2
 | 
			
		||||
                ret += 2; // if the piece is not placed, only one byte else 2
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ public interface FileParser {
 | 
			
		||||
     * Could be used for generating level file. might not be used in game.
 | 
			
		||||
     * @param file the file where to save
 | 
			
		||||
     * @param levelData the map to save
 | 
			
		||||
     * @param save_data should save the map data (need to be false only in development I think)
 | 
			
		||||
     */
 | 
			
		||||
    void saveLevel(File file, Map levelData, boolean save_data) throws IOException;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
public class Bitwise {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -16,15 +18,16 @@ public class Bitwise {
 | 
			
		||||
    /**
 | 
			
		||||
     * Transform a byte (8 bit) to two Nible (4 bit) with a split in the middle
 | 
			
		||||
     * Exemple:
 | 
			
		||||
     *  in = 01000101 (=69)
 | 
			
		||||
     *  out = { 00000100, 00000101 } (={4, 5})
 | 
			
		||||
     * in = 01000101 (=69)
 | 
			
		||||
     * out = { 00000100, 00000101 } (={4, 5})
 | 
			
		||||
     *
 | 
			
		||||
     * @param in the byte to split
 | 
			
		||||
     * @return an arrya of 2 byte ret[0] = left part; ret[1] = right part
 | 
			
		||||
     */
 | 
			
		||||
    public static byte[] ByteToNible(byte in){
 | 
			
		||||
        byte[] ret = new byte[2];
 | 
			
		||||
        ret[0] = (byte) (in >> 4);
 | 
			
		||||
        ret[1] = (byte) (in & 15); // apply the mask '00001111'
 | 
			
		||||
    public static Vec2 ByteToNible(byte in){
 | 
			
		||||
        Vec2 ret = new Vec2();
 | 
			
		||||
        ret.x = (byte) (in >> 4);
 | 
			
		||||
        ret.y = (byte) (in & 15); // apply the mask '00001111'
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user