115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
"""
|
|
The MIT License (MIT)
|
|
|
|
Copyright © 2021 KikooDX
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the
|
|
“Software”), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included
|
|
in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
"""
|
|
|
|
def info(*args) -> None:
|
|
#print("info:", *args)
|
|
pass
|
|
|
|
def merge_bytes(_bytes: bytes) -> int:
|
|
"""
|
|
Get a bytes slice and merge them into an integer.
|
|
"""
|
|
mul = 256 ** len(_bytes)
|
|
sum = 0
|
|
for byte in _bytes:
|
|
mul //= 256
|
|
sum += byte * mul
|
|
return sum
|
|
|
|
def kble_parse(_bytes: bytes) -> list:
|
|
"""
|
|
Read content of binary file using the KBLE format and output a two
|
|
dimensional int grid.
|
|
"""
|
|
# Read whole file at once.
|
|
# Check version byte.
|
|
assert(_bytes[0] == 0)
|
|
# Get byte length of cells.
|
|
cell_size: int = _bytes[1]
|
|
info("Cell size:", cell_size)
|
|
# Get level dimensions.
|
|
width = merge_bytes(_bytes[2:4])
|
|
height = merge_bytes(_bytes[4:6])
|
|
info("Level width:", width)
|
|
info("Level height:", height)
|
|
# Check than the number of bytes matches the obtained informations.
|
|
assert(len(_bytes) == width * height * cell_size + 6)
|
|
info("Correct format.")
|
|
# Process remaining bytes and add them to a list.
|
|
grid: list = [[0 for _ in range(width)] for _ in range(height)]
|
|
i: int = 6
|
|
x: int = 0
|
|
y: int = 0
|
|
while (i < len(_bytes)):
|
|
SLICE = _bytes[i:i + cell_size]
|
|
grid[y][x] = merge_bytes(SLICE)
|
|
i += cell_size
|
|
x += 1
|
|
if x == width:
|
|
x = 0
|
|
y += 1
|
|
info("Parsing ended successfully.")
|
|
return grid
|
|
|
|
if __name__ == "__main__":
|
|
LEVELS_PATHS = (
|
|
"assets/levels/hello_world.kble",
|
|
"assets/levels/damage_boosting_101.kble",
|
|
"assets/levels/chaos.kble",
|
|
"assets/levels/so_far_but_so_close.kble",
|
|
"assets/levels/key_101.kble",
|
|
"assets/levels/two_for_one.kble",
|
|
"assets/levels/up_and_down.kble",
|
|
"assets/levels/dome.kble",
|
|
"assets/levels/die_and_retry.kble",
|
|
"assets/levels/end.kble")
|
|
with open("src/gen_levels.c", "w") as c_file:
|
|
c_file.write("#include \"level.h\"\n#include \"vec2.h\"\n")
|
|
c_file.write("const Level levels[] = {\n")
|
|
for level_path in LEVELS_PATHS:
|
|
c_file.write("\t{\n\t\t.content = {")
|
|
with open(level_path, "rb") as file:
|
|
BYTES = file.read()
|
|
data = kble_parse(BYTES)
|
|
start_x = 0
|
|
start_y = 0
|
|
keys = 0
|
|
for y, line in enumerate(data):
|
|
for x, tile in enumerate(line):
|
|
c_file.write(str(tile))
|
|
c_file.write(", ")
|
|
if tile == 3: # spawn tile
|
|
start_x, start_y = x, y
|
|
if tile == 5: # key tile
|
|
keys += 1
|
|
c_file.write("},\n")
|
|
c_file.write("\t\t.start_pos = (Vec2){")
|
|
c_file.write(f"{start_x} * TILE_SIZE + 2, {start_y} * TILE_SIZE + 4")
|
|
c_file.write("},\n")
|
|
c_file.write(f"\t\t.keys = {keys}\n")
|
|
c_file.write("\t},\n")
|
|
c_file.write("};")
|
|
|