supercasiobros/src/world.c

209 lines
5.0 KiB
C
Raw Normal View History

2020-02-17 18:43:16 +01:00
#include <world.h>
#include <base.h>
#include <tile.h>
#include <level.h>
#include <keyboard.h>
#include <camera.h>
#include <mario.h>
#include <ennemi.h>
#include <bonus.h>
#include <ennemi.h>
#include <plateforme.h>
2020-01-24 12:08:40 +01:00
#include <tuyau.h>
2020-01-29 14:34:47 +01:00
#include <bullets.h>
2020-02-17 18:43:16 +01:00
#include <liblog.h>
#include <gint/display.h>
2020-02-02 16:24:40 +01:00
#include <gint/std/string.h>
#include <gint/std/stdlib.h>
2020-01-06 20:56:10 +01:00
map_t * map_current=0;
int worldGetWidth()
{
return map_current->w*8;
}
2019-11-16 11:44:09 +01:00
cell_t death={0,0};
2019-12-04 19:27:27 +01:00
cell_t* worldGetCell(int x, int y)
2019-11-16 11:44:09 +01:00
{
2019-12-04 19:27:27 +01:00
x/=8;
y/=8;
if (0<=x && x<map_current->w && 0<=y && y<map_current->h)
return &map_current->data[x*map_current->h+y];
2019-12-04 19:27:27 +01:00
else
{
return &death;
}
2019-11-16 11:44:09 +01:00
}
void cellDraw(int cx, int cy, int sx, int sy, int plan)
2019-11-16 11:44:09 +01:00
{
const cell_t * cell=worldGetCell(cx,cy);
2019-12-07 19:26:55 +01:00
if (cell==0)
return;
2020-02-17 18:43:16 +01:00
if (plan==1) switch (cell->type)
2019-12-04 19:27:27 +01:00
{
2020-02-17 18:43:16 +01:00
case TUYAU:
tileDraw(sx, sy, &tuyau, ((tuyau_t*)cell)->x, ((tuyau_t*)cell)->y);
break;
2019-12-04 19:27:27 +01:00
2020-02-17 18:43:16 +01:00
case ARBRE:
tileDraw(sx, sy, &arbre, ((arbre_t*)cell)->x, ((arbre_t*)cell)->y);
break;
2020-02-17 18:43:16 +01:00
case EARTH:
tileDraw(sx, sy, &earth, ((earth_t*)cell)->x, ((earth_t*)cell)->y);
break;
2020-02-17 18:43:16 +01:00
case BLOC:
tileDraw(sx, sy, &bloc, 0, 0);
break;
case BRICK:
if (((brick_t*)cell)->time_hit_id) // calculate collision animation
2019-12-04 19:27:27 +01:00
{
2020-02-17 18:43:16 +01:00
((brick_t*)cell)->time_hit_id++; // Next frame for the animation
sy+=2+(((brick_t*)cell)->time_hit_id-4)/4; // For the brick coordinate
if (((brick_t*)cell)->time_hit_id==8) ((brick_t*)cell)->time_hit_id=0; // End of animation
if (((brick_t*)cell)->state==1 && ((brick_t*)cell)->time_hit_id==0) ((brick_t*)cell)->type=0; // Delete brick
2019-12-04 19:27:27 +01:00
}
2020-02-17 18:43:16 +01:00
if (!((brick_t*)cell)->hidden)
2019-12-08 16:34:32 +01:00
{
if (((brick_t*)cell)->time_hit_id || !((brick_t*)cell)->content || ((brick_t*)cell)->number) tileDraw(sx, sy, &brick, 0, ((brick_t*)cell)->state);
2020-02-17 18:43:16 +01:00
else tileDraw(sx, sy, &gift, 1, 0);
if (((brick_t*)cell)->content==1 && ((brick_t*)cell)->time_hit_id && ((brick_t*)cell)->time_hit_id<=4) tileDraw(sx, sy+8, &coin, 0, 0); // Draw a coin
2019-12-08 16:34:32 +01:00
}
2020-02-17 18:43:16 +01:00
break;
2019-12-04 19:27:27 +01:00
2020-02-17 18:43:16 +01:00
case GIFT:
if (((gift_t*)cell)->time_hit_id)
2019-12-04 19:27:27 +01:00
{
2020-02-17 18:43:16 +01:00
((gift_t*)cell)->time_hit_id++;
sy+=2+(((gift_t*)cell)->time_hit_id-4)/4;
if (((gift_t*)cell)->time_hit_id==8) ((gift_t*)cell)->time_hit_id=0;
2019-12-04 19:27:27 +01:00
}
2020-02-17 18:43:16 +01:00
if (((gift_t*)cell)->hidden==0)
{
2020-02-17 18:43:16 +01:00
if (((gift_t*)cell)->time_hit_id || ((gift_t*)cell)->number) tileDraw(sx, sy, &gift, 0, 0);
else tileDraw(sx, sy, &gift, 1, 0);
if (((gift_t*)cell)->content==1 && ((gift_t*)cell)->time_hit_id && ((gift_t*)cell)->time_hit_id<=4) tileDraw(sx, sy+8, &coin, 0, 0);
}
2020-02-17 18:43:16 +01:00
break;
}
2020-02-17 18:43:16 +01:00
else switch (cell->type)
2019-12-04 19:27:27 +01:00
{
2020-02-17 18:43:16 +01:00
case COIN:
tileDraw(sx, sy, &coin, ((coin_t*)cell)->taken, 0);
break;
2020-02-17 18:43:16 +01:00
case BUISSON:
tileDraw(sx, sy, &buisson, ((deco_t*)cell)->x, ((deco_t*)cell)->y);
break;
case NUAGE:
tileDraw(sx, sy, &nuage, ((deco_t*)cell)->x, ((deco_t*)cell)->y);
break;
case COLLINE:
tileDraw(sx, sy, &colline, ((deco_t*)cell)->x, ((deco_t*)cell)->y);
break;
case CASTLE:
tileDraw(sx, sy, &castle, ((deco_t*)cell)->x, ((deco_t*)cell)->y);
break;
case END_LEVEL:
tileDraw(sx, sy, &end_level, ((deco_t*)cell)->x, ((deco_t*)cell)->y);
break;
2019-12-04 19:27:27 +01:00
}
2019-11-16 11:44:09 +01:00
}
int worldGetCellCategory(int x, int y)
2019-11-16 12:02:30 +01:00
{
2020-02-17 18:43:16 +01:00
cell_t *c=worldGetCell(x,y); // get cell props
if (c==0) return CTG_DEATH; // out of the map
if (platformsCollisionTest(x,y)) return CTG_SOIL; // tested point is a platform
if (c->type==ARBRE && (((arbre_t*)c)->x==1&&((arbre_t*)c)->y==1)) return CTG_EMPTY; // tree trunk
2019-12-07 19:26:55 +01:00
switch (c->type)
2019-12-04 19:27:27 +01:00
{
2020-02-17 18:43:16 +01:00
case TUYAU: case GIFT: case BRICK: case EARTH: case BLOC: case ARBRE:
2019-12-04 19:27:27 +01:00
return CTG_SOIL;
2020-02-17 18:43:16 +01:00
2019-12-04 19:27:27 +01:00
default:
return CTG_EMPTY;
}
2019-11-20 15:33:34 +01:00
}
void worldDraw()
2019-11-20 15:33:34 +01:00
{
2020-02-17 18:43:16 +01:00
cameraMove();
const int mx0=cameraX(), my0=cameraY();
const int sx0=mx0%8, sy0=my0%8;
//background tiles
for (int i=0, mx=mx0; i<=17; i++, mx+=8) for (int j=0, my=my0; j<=9; j++, my+=8) cellDraw(mx, my, 8*i-sx0, 8*j-sy0,0);
2019-12-07 14:32:38 +01:00
2020-02-17 18:43:16 +01:00
// animated items
bonusDraw();
ennemiesDisplay();
bulletsDraw();
platformsDraw();
marioDraw();
//foreground tiles
for (int i=0, mx=mx0; i<=17; i++, mx+=8) for (int j=0, my=my0; j<=9; j++, my+=8) cellDraw(mx, my, 8*i-sx0, 8*j-sy0,1);
2020-02-17 18:43:16 +01:00
// draw immunity remaining time [It's a progress bar on the left side of the screen]
if (mario_immunity) drect(0,64-MARIO_IMMUNITY_TIME+mario_immunity,2,64, C_BLACK);
2019-12-08 16:34:32 +01:00
}
void worldMove()
2019-12-08 16:34:32 +01:00
{
MKB_update();
2020-02-17 18:43:16 +01:00
for (int i=0; i<ennemis_global_size; i++) ennemiMove(&ennemis_global[i]);
bonusMove();
bulletsMove();
platformsMove();
marioMove();
teleportersActive();
}
2020-02-01 14:39:08 +01:00
2020-02-18 13:03:57 +01:00
void worldSet(int w, int h, int x, int y, cell_t * a)
2020-02-01 14:39:08 +01:00
{
// Resets mario's vx
2020-02-17 18:43:16 +01:00
mario.p.vx=mario.p.vy=0;
2020-02-01 14:39:08 +01:00
// Free the previous map
if (map_current)
2020-02-03 11:12:54 +01:00
{
2020-02-18 13:03:57 +01:00
if (map_current->data) freeProf(map_current->data);
freeProf(map_current);
2020-02-03 11:12:54 +01:00
map_current=0;
}
2020-02-01 14:39:08 +01:00
// If the new map size is null => invalid map, return
2020-02-18 13:03:57 +01:00
if (0==w*h) return;
2020-02-16 18:47:20 +01:00
// Copy map into ram
2020-02-18 13:03:57 +01:00
map_current=(map_t*)mallocProf(sizeof(map_t)); if (!map_current) mallocError();
2020-02-01 14:39:08 +01:00
// Copy the map to ram
map_current->w = w;
map_current->h = h;
mario.p.x = map_current->start_x = x;
mario.p.y = map_current->start_y = y;
2020-02-18 13:03:57 +01:00
map_current->data=a;
//memcpy(map_current->data, a, sizeof(cell_t)*w*h);
}