supercasiobros/src/level.c

344 lines
7.1 KiB
C

#include "level.h"
#include "world.h"
#include "mario.h"
#include "score.h"
#include "ennemi.h"
#include "keyboard.h"
#include <plateforme.h>
#include <tuyau.h>
#include <gint/display.h>
#include <gint/std/stdlib.h>
#include <gint/keyboard.h>
#include <gint/timer.h>
#include <gint/std/string.h>
#include <gint/std/stdio.h>
#include <liblog.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
#define PACKED_FLAG 10
#define PACKED_GOOMBA 11
#define PACKED_KOOPA_VERT 12
#define PACKED_KOOPA_ROUGE 13
void malloc_error()
{
extern image_t img_ram;
timer_stop(0);
dimage(0,0,&img_ram);
dupdate();
while (1)
mkb_getkey();
}
static uint8_t pack_access(packed_level_t const * const p, unsigned int x, unsigned int y)
{
if (x<p->width && y<p->height)
{
ll_sendp(LEVEL_INFO, "\n[i]pack access at %d,%d",x,y);
return p->data[x*p->height+y];
}
else
{
ll_sendp(LEVEL_WARNING, "\n[w]pack access out of range at %d,%d",x,y);
return PACKED_EMPTY;
}
}
static void cell_set(cell_t *const array, unsigned int w, unsigned int h, unsigned int x, unsigned int y, cell_t const cell)
{
if (x<w && y<h)
array[x*h+y] = cell;
}
static void unpack_level(packed_level_t * p)
{
unsigned int w = p->width;
unsigned int h = p->height;
ll_sendp(LEVEL_INFO, "\nUnpacking level %dx%d", w,h);
cell_t * c = (cell_t *) malloc(sizeof(cell_t) * w * h);
ll_sendp(LEVEL_INFO, "\n[i]malloc %d", sizeof(cell_t) * w * h);
if (c==0)
{ // overriding parameters
w = 232;//p->width;
h = 13;//p->height;
ll_sendp(LEVEL_CRITICAL, "\n[e]malloc failed !\n[i]Trying defaults:\n %dx%d", w,h);
ll_sendp(LEVEL_WARNING, "\n[w]writing into pack new coordinates:\n %dx%d", w,h);
p->width=w;
p->height=h;
cell_t * c = (cell_t *) malloc(sizeof(cell_t) * w * h);
if (c==0)
malloc_error();
}
ll_set_level(LEVEL_WARNING);
int sx=0, sy=p->height; // Mario start coords
ll_sendp(LEVEL_INFO, "\n[i]Converting...", w,h);
ennemi_t ennemis[20]={0};
int nombre_ennemis=0;
for (unsigned int x=0; x<w; x++)
{
for (unsigned int y=0; y<h; y++)
{
unsigned 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 px=0, py=0;
int props=0;
{ // haut du tuyau horizontal
if (pack_access(p,x-1,y)==PACKED_TUYAU_BOUT)
{
px=1;
if (pack_access(p,x,y-1)==PACKED_TUYAU_MIDDLE)
py=2;
if (pack_access(p,x,y+1)==PACKED_TUYAU_MIDDLE)
py=4;
}
if (pack_access(p,x+1,y)==PACKED_TUYAU_BOUT)
{
px=0;
if (pack_access(p,x,y-1)==PACKED_TUYAU_MIDDLE)
py=2;
if (pack_access(p,x,y+1)==PACKED_TUYAU_MIDDLE)
py=4;
}
}
{ // bout de tuyau vertical
if (pack_access(p,x,y-1)==PACKED_TUYAU_BOUT)
{
py=0;
if (pack_access(p,x+1,y)==PACKED_TUYAU_MIDDLE)
px=0;
if (pack_access(p,x-1,y)==PACKED_TUYAU_MIDDLE)
px=2;
}
if (pack_access(p,x,y+1)==PACKED_TUYAU_BOUT)
{
py=1;
if (pack_access(p,x+1,y)==PACKED_TUYAU_MIDDLE)
px=0;
if (pack_access(p,x-1,y)==PACKED_TUYAU_MIDDLE)
px=2;
}
}
props=16*px+py;
cell_t t={TUYAU,props};
cell = t;
}
else if (contents==PACKED_TUYAU_MIDDLE)
{
int px=0, py=0;
int props=0;
if (/*pack_access(p,x-1,y)==PACKED_TUYAU_MIDDLE && */pack_access(p,x+1,y)!=PACKED_TUYAU_MIDDLE)
{
if (pack_access(p,x+1,y)==PACKED_TUYAU_BOUT)
{
px=1;
if (pack_access(p,x,y+1)!=PACKED_TUYAU_MIDDLE)
py=0;
else
py=1;
}
else
{
px=1;
py=3;
}
}
if (/*pack_access(p,x+1,y)==PACKED_TUYAU_MIDDLE && */pack_access(p,x-1,y)!=PACKED_TUYAU_MIDDLE)
{
if (pack_access(p,x-1,y)==PACKED_TUYAU_BOUT)
{
px=1;
if (pack_access(p,x,y+1)!=PACKED_TUYAU_MIDDLE)
py=0;
else
py=1;
}
else
{
px=0;
py=3;
}
}
props=16*px+py;
cell_t t={TUYAU,props};
cell = t;
}
else if (contents==PACKED_FLAG)
{
int props=0;
if (pack_access(p,x,y+1)!=PACKED_FLAG)
props=0x1400;
else if (pack_access(p,x,y+2)!=PACKED_FLAG)
props=0x1401;
else if (pack_access(p,x,y+3)!=PACKED_FLAG)
props=0x1302;
else if (pack_access(p,x,y+4)!=PACKED_FLAG)
props=0x1302;
else if (pack_access(p,x,y+5)!=PACKED_FLAG)
props=0x1202;
else if (pack_access(p,x,y+6)!=PACKED_FLAG)
props=0x1202;
else
props=0x1102;
cell_t t={END_LEVEL,props};
cell = t;
}
ll_sendp(LEVEL_INFO, "\n[i]Converted cell %d,%d\n {%d,%p}\n[i]Writing cell...", x,y, cell.type, cell.data);
cell_set(c,w,h,x,y,cell);
ll_sendp(LEVEL_INFO, "\n[i]Wrote cell", x,y, cell.type, cell.data);
if (contents==PACKED_GOOMBA)
{
ennemi_t e=GOOMBA(8*x,8*y,-1);
ennemis[nombre_ennemis]=e;
nombre_ennemis++;
}
else if (contents==PACKED_KOOPA_VERT)
{
ennemi_t e=KOOPA_V(8*x,8*y,-1);
ennemis[nombre_ennemis]=e;
nombre_ennemis++;
}
else if (contents==PACKED_KOOPA_ROUGE)
{
ennemi_t e=KOOPA_R(8*x,8*y,-1);
ennemis[nombre_ennemis]=e;
nombre_ennemis++;
}
}
}
ll_sendp(LEVEL_INFO, "\n[i]Converted!\n[i]Sending to level zone...", w,h);
world_set(w, h, sx, sy, c);
ll_sendp(LEVEL_INFO, "\n[i]Achieved unpacking", w,h);
free(c);
init_ennemi(ennemis, nombre_ennemis);
}
void set_level(int w, int l)
{
new_level();
set_teleporteurs(0,0);
if (map_current)
{
free(map_current);
map_current=0;
}
ennemis_global_size=0;
plateforme_table_size=0;
if (w+1==1 && l+1==2) // 1-2
{
extern packed_level_t bin_lvl_1_2;
unpack_level(&bin_lvl_1_2);
teleport_t t[]=
{
{6,4, 21,12, MK_DOWN},
{106,5, 188,12, MK_DOWN},
{197,2, 118,4, MK_RIGHT},
{180,5, 206,2, MK_RIGHT},
};
set_teleporteurs(t, sizeof(t)/sizeof(teleport_t));
plateforme_t plateforme0[]=
{
PLATEFORME_MOVING_H(8*144,6*8+5,32,1,8*142,8*150)
};
init_plateformes(plateforme0,sizeof(plateforme0)/sizeof(plateforme_t));
}
}
void get_lvl_id(int w, int l, char * str)
{
str[3]='\0';
sprintf(str, "%d-%d", w+1, l+1);
}