Finishing Parser, Have to finish Tests
Signed-off-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
This commit is contained in:
		@ -1,16 +1,28 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import school_project.Utils.Bitwise;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
public class MapParser {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse the file and create a Map with its shape and pieces setup
 | 
			
		||||
     * @param file file to parse
 | 
			
		||||
     * @return Map Object parsed with file data
 | 
			
		||||
     * @see "TODO: Add Specification when done"
 | 
			
		||||
     */
 | 
			
		||||
    public static Map ParseMapFile(File file) throws IllegalArgumentException, IllegalAccessException, IOException {
 | 
			
		||||
        System.out.println(file.getAbsolutePath());
 | 
			
		||||
        Map ret;
 | 
			
		||||
 | 
			
		||||
        // Get the file and check that this file exists and can be read
 | 
			
		||||
        FileInputStream fileStream = new FileInputStream(file);
 | 
			
		||||
        if(!file.isFile()) throw new IllegalArgumentException("The argument should be a file");
 | 
			
		||||
        if(!file.canRead()) throw new IllegalAccessException("This file can't be read");
 | 
			
		||||
 | 
			
		||||
        // Read the file an array of byte, then look for the HEADER (SMS) and then the FOOTER (SME)
 | 
			
		||||
        // Then Put everything that is in between in level_data[]
 | 
			
		||||
        byte[] bytes = fileStream.readAllBytes();
 | 
			
		||||
        int start_position = 0, end_position = 0;
 | 
			
		||||
        for (int i = 0; i < bytes.length; i++) {
 | 
			
		||||
@ -26,32 +38,64 @@ public class MapParser {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        byte[] level_data = Arrays.copyOfRange(bytes, start_position, end_position);
 | 
			
		||||
        int width_map = level_data[0], height_map = level_data[1];
 | 
			
		||||
        byte[] map_data = Arrays.copyOfRange(level_data, 2, 2 + width_map * height_map / 8 + (height_map * width_map % 8 != 0 ? 1 : 0));
 | 
			
		||||
        byte piece_count = level_data[3 + width_map * height_map / 8 + (height_map * width_map % 8 != 0 ? 1 : 0)];
 | 
			
		||||
        byte[] pieces_datas = Arrays.copyOfRange(level_data, 4 + width_map * height_map / 8 + (height_map * width_map % 8 != 0 ? 1 : 0), level_data.length-1);
 | 
			
		||||
 | 
			
		||||
        // Get the 2 first byte as the map width and height
 | 
			
		||||
        // Then get the map data. This map data is every bit of the byte that represent either a true if it is a 1 or false if it is a 0
 | 
			
		||||
        int map_width = level_data[0], map_height = level_data[1];
 | 
			
		||||
        byte[] map_data = Arrays.copyOfRange(level_data, 2, 2 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0));
 | 
			
		||||
        boolean[][] map_matrix = BuildMatrixFromBytes(map_width, map_height, map_data);
 | 
			
		||||
        ret = new Map(map_matrix);
 | 
			
		||||
 | 
			
		||||
        // Get the amount of pieces
 | 
			
		||||
        // For each of these pieces, get the size of the piece on 1 octet, 4 byte are for width then 4 byte are for height
 | 
			
		||||
        // the same method as the map is used to get the piece shape.
 | 
			
		||||
        byte piece_count = level_data[3 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0)];
 | 
			
		||||
        byte[] pieces_data = Arrays.copyOfRange(level_data, 4 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0), level_data.length-1);
 | 
			
		||||
        for (int piece_index = 0; piece_index < piece_count; piece_index++) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            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));
 | 
			
		||||
            boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_width, _piece_height, _piece_data);
 | 
			
		||||
            Piece _piece = new Piece(_piece_matrix);
 | 
			
		||||
            ret.AddShape(_piece);
 | 
			
		||||
            piece_index = piece_index + _piece_width * _piece_height / 8 + (_piece_height * _piece_width % 8 != 0 ? 1 : 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Close the file and return the generated map
 | 
			
		||||
        fileStream.close();
 | 
			
		||||
        return new Map(); //TODO: Send the parsed map
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    public static void SaveMapFile(File file){
 | 
			
		||||
//    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Build a boolean Matrix From a byte array
 | 
			
		||||
     * Each Byte is composed of 8 bit, each bit is 1 or 0
 | 
			
		||||
     *  if the bit is 0 then it's a false for this cell
 | 
			
		||||
     *  else it's true for this cell
 | 
			
		||||
     * @param matrix_width width of the matrix
 | 
			
		||||
     * @param matrix_height height of the matrix
 | 
			
		||||
     * @param matrix_data byte array of the data to export
 | 
			
		||||
     * @return boolean Matrix of the data decompiled
 | 
			
		||||
     */
 | 
			
		||||
    private static boolean[][] BuildMatrixFromBytes(int matrix_width, int matrix_height, byte[] matrix_data){
 | 
			
		||||
        boolean[][] ret = new boolean[matrix_height][matrix_width];
 | 
			
		||||
 | 
			
		||||
        // Transforming the bit from matrix_data's byte into boolean array for better manipulation
 | 
			
		||||
        boolean[] b_array = new boolean[matrix_height * matrix_width];
 | 
			
		||||
        int index = 0;
 | 
			
		||||
        for(byte b: matrix_data){
 | 
			
		||||
            for (int i = 0; i < 8; i++) { // because 8 bit in a byte
 | 
			
		||||
                b_array[index] = Bitwise.IsBitSetAt(b, i);
 | 
			
		||||
                index++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private static boolean[][] BuildMatrixFromBytes(int map_width, int map_height, byte[] map_data){
 | 
			
		||||
        boolean[][] ret = new boolean[map_height][map_width];
 | 
			
		||||
        //TODO tonitch: cursor 2
 | 
			
		||||
 | 
			
		||||
        // Transforming b_array to a 2D matrix
 | 
			
		||||
        for (int x = 0; x < matrix_height; x++) {
 | 
			
		||||
            for (int y = 0; y < matrix_width; y++) {
 | 
			
		||||
                ret[x][y] = b_array[y + x * 8];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    public static void main(String[] args) throws IOException, IllegalAccessException {
 | 
			
		||||
        ParseMapFile(new File("test.smap"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								app/src/main/java/school_project/Utils/Bitwise.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/src/main/java/school_project/Utils/Bitwise.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
public class Bitwise {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the bit at pos is 1 or 0
 | 
			
		||||
     * @param b byte to test
 | 
			
		||||
     * @param pos position in b to check
 | 
			
		||||
     * @return true if the bit at pos is 1 or false if it is 0
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean IsBitSetAt(byte b, int pos){
 | 
			
		||||
        pos = 7 - pos;
 | 
			
		||||
        return (b & (1 << pos))!= 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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})
 | 
			
		||||
     * @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'
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user