adding compressed level format (incomplete)

This commit is contained in:
Milang 2020-02-01 16:39:34 +01:00
parent 04743ed5b5
commit e6f3e6cdaa
5 changed files with 202 additions and 108 deletions

View File

@ -1,8 +1,26 @@
#ifndef LEVEL_H
#define LEVEL_H
void set_level(int w, int l);
void get_lvl_id(int w, int l, char * str);
// Utilitaire de décompression de level
#include <stdint.h>
typedef struct
{
uint16_t width;
uint16_t height;
uint8_t data[]; // rough data
} packed_level_t;
void unpack_level(packed_level_t const * const packed_level_t);
void set_level(int w, int l); // Configures the level
void get_lvl_id(int w, int l, char * str); // Retruns level ID into a char [4]
void malloc_error();
#endif

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,7 @@
import os
import tempfile
import subprocess
from PIL import Image
# Palette de couleurs
@ -23,14 +27,21 @@ def color_compare(color1, color2):
else:
return 0
def write_char(val):
return '%c' % int(val%256)
# Load image
filename = input("File name ?\n> ")
img = Image.open(filename)
print("Converting", filename, "to", "\"" + filename + ".c\",", "size =", img.size)
code = "// !b Here the generated section begins (see the end at \"!e\")\nmap_current->w = " + str(img.size[0]) + ";\nmap_current->h = " + str(img.size[1]) + ";\ncell_t lvl[]=\n{"
#rough binary
code = write_char(img.size[0] - img.size[0]%256)
code += write_char(img.size[0]%256)
code += write_char((img.size[1] - img.size[1]%256)/256)
code += write_char(img.size[1]%256)
nombre_ennemis=0
ennemis = "\nennemi_t ennemies0[]={"
@ -39,102 +50,35 @@ ennemis = "\nennemi_t ennemies0[]={"
# Balayage des pixels : passe pour dessiner les murs
pixels = img.load()
for x in range(0,img.size[0]):
code += "\n "
for i in range(0, img.size[1]):
y=img.size[1]-i-1
if color_compare(pixels[x,y], pierre):
hexa="0x"
if color_compare(pixels[x,y],empty):
code += write_char(0)
left=1
right=1
if x != 0:
left = (color_compare(pixels[x-1,y], pierre))
if x != img.size[0]-1:
right = (color_compare(pixels[x+1,y], pierre))
sx=0
if left and right:
sx=1
elif left and right==0:
sx=2
elif left==0 and right:
sx=0
hexa+= str(sx)
up=0 # vide par defaut
down=1
if y != 0:
up = (color_compare(pixels[x,y-1], pierre))
if y != img.size[1]-1:
down = (color_compare(pixels[x,y+1], pierre))
sy = int(bool(up))
hexa += str(sy)
code += "{EARTH," + hexa + "}, "
elif color_compare(pixels[x,y], pierre):
code += write_char(1)
elif color_compare(pixels[x,y], piece):
code += "{COIN,0}, "
code += write_char(2)
elif color_compare(pixels[x,y], brique):
code += "{BRICK,0}, "
code += write_char(3)
elif color_compare(pixels[x,y],brique_piece):
code += "{BRICK,0x15}, "
code += write_char(4)
elif color_compare(pixels[x,y],boite_piece):
code += "{GIFT,0x11}, "
code += write_char(5)
elif color_compare(pixels[x,y],boite_champi):
code += "{GIFT,0x21}, "
elif color_compare(pixels[x,y],empty):
code += "{0,0}, "
code += write_char(6)
elif color_compare(pixels[x,y],beton):
code += "{BLOC,0}, "
code += write_char(7)
elif color_compare(pixels[x,y],tuyau_bout):
left=0
right=0
up=0 # vide par defaut
down=0
tx=0
ty=0
if x:
left = (color_compare(pixels[x-1,y], tuyau_bout)) or (color_compare(pixels[x-1,y], tuyau_milieu))
if x != img.size[0]-1:
right = (color_compare(pixels[x+1,y], tuyau_bout)) or (color_compare(pixels[x+1,y], tuyau_milieu))
if y:
up = (color_compare(pixels[x,y-1], tuyau_bout)) or (color_compare(pixels[x,y-1], tuyau_milieu))
if y != img.size[1]-1:
down = (color_compare(pixels[x,y+1], tuyau_bout)) or (color_compare(pixels[x,y+1], tuyau_milieu))
if right and down:
tx=0
if (color_compare(pixels[x,y+1], tuyau_milieu)):
ty=2
elif left and down:
if (color_compare(pixels[x,y+1], tuyau_milieu)):
tx=1
ty=2
else:
tx=2
ty=0
elif up and right:
tx=0
if (color_compare(pixels[x,y-1], tuyau_milieu)):
ty=4
else:
ty=1
elif up and left:
if (color_compare(pixels[x,y-1], tuyau_milieu)):
tx=1
ty=4
else:
tx=2
ty=1
hexa="0x"+str(tx)+str(ty)
code += "{TUYAU,"+hexa+"}, "
code += write_char(8)
elif color_compare(pixels[x,y], tuyau_milieu):
left=0
right=0
@ -182,7 +126,7 @@ for x in range(0,img.size[0]):
else:
code+= "{END_LEVEL,0x1102},"
else:
code += "{0,'?'}, "
code += write_char(0)
#code += str(pixels[x,y])
if color_compare(pixels[x,y], goomba):
@ -192,11 +136,12 @@ for x in range(0,img.size[0]):
ennemis += "\n KOOPA_V(" + str(8*x) + ", " + str(8*i) + ", -1),"
elif color_compare(pixels[x,y], koopa_rouge):
ennemis += "\n KOOPA_R(" + str(8*x) + ", " + str(8*i) + ", -1),"
code += "\n};\ninit_level(lvl);\n"
ennemis += "\n};\nennemis_global_size=" + str(nombre_ennemis) + ";\ninit_ennemies(ennemies0);\n"
f = open(filename+".c", 'w')
f.write(code + ennemis + "\n// !e End of generated section")
f.close()
#f = open(filename+".packlvl", 'w')
#f.write(code)
#f.close()
build(bytes(code, 'utf-8'), filename+".o", "_lvl_"+filename.replace(".png",""))
print("Converted succesfully !")

View File

@ -14,6 +14,18 @@
#include <gint/std/string.h>
#include <gint/std/stdio.h>
#define PACKED_EMPTY 0
#define PACKED_STONE 1
#define PACKED_COIN 2
#define PACKED_BRICK 3
#define PACKED_BRICK_COIN 4
#define PACKED_BOX_COIN 5
#define PACKED_BOX_CHAMPI 6
#define PACKED_BETON 7
#define PACKED_TUYAU_BOUT 8
#define PACKED_TUYAU_MIDDLE 9
void malloc_error()
{
extern image_t img_ram;
@ -24,22 +36,141 @@ void malloc_error()
mkb_getkey();
}
void unpack_level(packed_level_t const * const packed_level_t p)
static uint8_t pack_access(packed_level_t const * const p, int x, int y)
{
unsigned int const size = p->width*p->height;
map_t * m = (map_t *) malloc( 4*sizeof(int) + size*sizeof(cell_t) );
if (m==0)
malloc_error();
if (map_current)
{
free(map_current);
map_current=0;
}
map_current=m;
map_current->w = p->width;
map_current->h = p->height;
if (0<=x && x<w && 0<=y && y<h)
return p->data[x*p->height+y];
else
return PACKED_EMPTY;
}
static void cell_set(cell_t *const array, int w, int h, int x, int y, cell_t const cell)
{
if (0<=x && x<w && 0<=y && y<h)
array[x*w+y] = cell;
}
void unpack_level(packed_level_t const * const p)
{
const unsigned int w = p->width;
const unsigned int h = p->height;
cell_t * c = (cell_t *) malloc(sizeof(cell_t) * w * h);
if (c==0)
malloc_error();
int sx=0, sy=p->height; // Mario start coords
for (int x=0; x<w; x++)
{
for (int y=0; y<h; y++)
{
int contents = pack_access(p,x,y);
cell_t cell = {0,0};
if (contents==PACKED_EMPTY)
{
cell_t t={0,0};
cell = t;
}
else if (contents==PACKED_STONE)
{
int props=0;
{ // determiner x
int px=1;
if (pack_access(p,x-1,y)!=PACKED_STONE)
px=0;
if (pack_access(p,x+1,y)!=PACKED_STONE)
px=2;
props+=16*px;
}
{ // determiner y
int py=1;
if (pack_access(p,x,y+1)!=PACKED_STONE)
py=0;
props+=py;
}
cell_t t={EARTH,props};
cell = t;
}
else if (contents==PACKED_COIN)
{
cell_t t={COIN,0};
cell = t;
}
else if (contents==PACKED_BRICK)
{
cell_t t={BRICK,0};
cell = t;
}
else if (contents==PACKED_BRICK_COIN)
{
cell_t t={BRICK,0x15};
cell = t;
}
else if (contents==PACKED_BOX_COIN)
{
cell_t t={GIFT,0x11};
cell = t;
}
else if (contents==PACKED_BOX_CHAMPI)
{
cell_t t={GIFT,0x21};
cell = t;
}
else if (contents==PACKED_BETON)
{
cell_t t={BLOC,0};
cell = t;
}
else if (contents==PACKED_TUYAU_BOUT)
{
int x=0, y=0;
int props=0;
{ // haut du tuyau horizontal
if (pack_access(p,x-1,y)==PACKED_TUYAU_BOUT)
{
x=1;
if (pack_access(p,x,y-1)==PACKED_TUYAU_MIDDLE)
y=2;
if (pack_access(p,x,y+1)==PACKED_TUYAU_MIDDLE)
y=4;
}
if (pack_access(p,x+1,y)==PACKED_TUYAU_BOUT)
{
x=0;
if (pack_access(p,x,y-1)==PACKED_TUYAU_MIDDLE)
y=2;
if (pack_access(p,x,y+1)==PACKED_TUYAU_MIDDLE)
y=4;
}
}
{ // bout de tuyau vertical
if (pack_access(p,x,y-1)==PACKED_TUYAU_BOUT)
{
y=0;
if (pack_access(p,x+1,y)==PACKED_TUYAU_MIDDLE)
x=0;
if (pack_access(p,x-1,y)==PACKED_TUYAU_MIDDLE)
x=2;
}
if (pack_access(p,x,y+1)==PACKED_TUYAU_BOUT)
{
y=1;
if (pack_access(p,x+1,y)==PACKED_TUYAU_MIDDLE)
x=0;
if (pack_access(p,x-1,y)==PACKED_TUYAU_MIDDLE)
x=2;
}
}
props=16*x+y;
cell_t t={TUYAU,props};
cell = t;
}
cell_set(c,w,h,x,y,cell);
}
}
}