Fixing BinaryParser Loader

This commit is contained in:
Debucquoy Anthony 2023-03-25 13:32:48 +01:00
parent eb2c293d2a
commit acf1faba49
4 changed files with 39 additions and 16 deletions

View File

@ -31,7 +31,14 @@ level data at the top of the file.
- 4 first bits : width - 4 first bits : width
- 4 last bits: height - 4 last bits: height
- next bytes -> Width * Height (+1 if Width * Height % 8 is not 0) - next bytes -> Width * Height (+1 if Width * Height % 8 is not 0)
- Position ( only for saved file )
### 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 - '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 - x and y on 2 bytes for position if the piece is placed
@ -39,3 +46,5 @@ level data at the top of the file.
1) by putting the piece size on one byte. We limit the maximum piece size to 15 x 15 (1111 | 1111) 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! :-) 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.

View File

@ -3,6 +3,7 @@ package school_project.Parsers;
import school_project.Map; import school_project.Map;
import school_project.Piece; import school_project.Piece;
import school_project.Utils.Bitwise; import school_project.Utils.Bitwise;
import school_project.Vec2;
import java.io.*; import java.io.*;
import java.nio.file.Files; 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)]; byte piece_count = levelData[3 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0)];
Piece[] ret = new Piece[piece_count]; 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_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++) { 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... Vec2 _piece_size = Bitwise.ByteToNible(pieces_data[piece_index + piece_offset]);
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 + 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));
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_size.x, _piece_size.y, _piece_data);
boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_width, _piece_height, _piece_data);
ret[piece_index] = new Piece(_piece_matrix); 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; return ret;
} }
@ -212,7 +222,7 @@ public class BinaryParser implements FileParser {
ret += p.getHeight() * p.getWidth() / 8; 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 ret += p.getHeight() * p.getWidth() % 8 == 0 ? 0 : 1; // add 1 if the size of the piece is not mult of 8
if(data){ 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; return ret;

View File

@ -22,6 +22,7 @@ public interface FileParser {
* Could be used for generating level file. might not be used in game. * Could be used for generating level file. might not be used in game.
* @param file the file where to save * @param file the file where to save
* @param levelData the map 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; void saveLevel(File file, Map levelData, boolean save_data) throws IOException;
} }

View File

@ -1,5 +1,7 @@
package school_project.Utils; package school_project.Utils;
import school_project.Vec2;
public class Bitwise { public class Bitwise {
/** /**
@ -18,13 +20,14 @@ public class Bitwise {
* Exemple: * Exemple:
* in = 01000101 (=69) * in = 01000101 (=69)
* out = { 00000100, 00000101 } (={4, 5}) * out = { 00000100, 00000101 } (={4, 5})
*
* @param in the byte to split * @param in the byte to split
* @return an arrya of 2 byte ret[0] = left part; ret[1] = right part * @return an arrya of 2 byte ret[0] = left part; ret[1] = right part
*/ */
public static byte[] ByteToNible(byte in){ public static Vec2 ByteToNible(byte in){
byte[] ret = new byte[2]; Vec2 ret = new Vec2();
ret[0] = (byte) (in >> 4); ret.x = (byte) (in >> 4);
ret[1] = (byte) (in & 15); // apply the mask '00001111' ret.y = (byte) (in & 15); // apply the mask '00001111'
return ret; return ret;
} }