mirror of https://git.sr.ht/~kikoodx/crystal-tower
136 lines
2.5 KiB
C
136 lines
2.5 KiB
C
#include "level.h"
|
|
#include "camera.h"
|
|
#include "conf.h"
|
|
#include "particles.h"
|
|
#include "player.h"
|
|
#include "tile.h"
|
|
#include "vec.h"
|
|
#include <gint/display.h>
|
|
#include <stdlib.h>
|
|
|
|
static struct Level self;
|
|
extern struct LevelBin lvl_0, lvl_1, lvl_2, lvl_3, lvl_4, lvl_5, lvl_6, lvl_7,
|
|
lvl_8, lvl_9, lvl_end;
|
|
static const struct LevelBin *levels[] = {&lvl_0, &lvl_1, &lvl_2, &lvl_3,
|
|
&lvl_4, &lvl_5, &lvl_6, &lvl_7,
|
|
&lvl_8, &lvl_9, &lvl_end, NULL};
|
|
|
|
void
|
|
level_load(int id)
|
|
{
|
|
extern int end;
|
|
const struct LevelBin *s = levels[id];
|
|
int i = s->width * s->height;
|
|
self.width = s->width;
|
|
self.height = s->height;
|
|
self.size = i;
|
|
self.data = malloc(i);
|
|
self.id = id;
|
|
while (i-- > 0)
|
|
self.data[i] = s->data[i];
|
|
player_init(level_find(TILE_PLAYER));
|
|
particles_init();
|
|
if (levels[self.id + 1] == NULL)
|
|
end = 1;
|
|
}
|
|
|
|
void
|
|
level_reload(void)
|
|
{
|
|
level_load(self.id);
|
|
}
|
|
|
|
void
|
|
level_next(void)
|
|
{
|
|
if (levels[self.id + 1] != NULL)
|
|
level_load(self.id + 1);
|
|
else
|
|
level_reload();
|
|
}
|
|
|
|
void
|
|
level_free(void)
|
|
{
|
|
free(self.data);
|
|
}
|
|
|
|
void
|
|
level_draw(void)
|
|
{
|
|
extern bopti_image_t bimg_tileset;
|
|
const int tileset_width = bimg_tileset.width / TILE_SIZE;
|
|
const struct Vec off = camera_offset();
|
|
int i;
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
for (i = 0; i < self.size; i++) {
|
|
const int tile = self.data[i];
|
|
if (tile && tile != TILE_THUNDER) {
|
|
const int sx = x * TILE_SIZE + off.x;
|
|
const int sy = y * TILE_SIZE + off.y;
|
|
const int rx = tile % tileset_width * TILE_SIZE;
|
|
const int ry = tile / tileset_width * TILE_SIZE;
|
|
|
|
dsubimage(sx, sy, &bimg_tileset, rx, ry, TILE_SIZE,
|
|
TILE_SIZE, DIMAGE_NONE);
|
|
}
|
|
|
|
if (++x >= self.width) {
|
|
x = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Vec
|
|
level_find(enum Tile seek)
|
|
{
|
|
int i;
|
|
for (i = 0; i < self.size; i++) {
|
|
const enum Tile tile = self.data[i];
|
|
if (tile == seek) {
|
|
return VEC(i % self.width * TILE_SIZE,
|
|
i / self.width * TILE_SIZE);
|
|
}
|
|
}
|
|
return VEC(0, 0);
|
|
}
|
|
|
|
enum Tile
|
|
level_get(int x, int y)
|
|
{
|
|
if (y < 0)
|
|
return TILE_NEXT;
|
|
if (x < 0 || x >= self.width || y >= self.height)
|
|
return TILE_OOB;
|
|
return self.data[x + y * self.width];
|
|
}
|
|
|
|
enum Tile
|
|
level_get_px(int x, int y)
|
|
{
|
|
return level_get(x / TILE_SIZE, y / TILE_SIZE);
|
|
}
|
|
|
|
void
|
|
level_set(int x, int y, enum Tile v)
|
|
{
|
|
if (x < 0 || y < 0 || x >= self.width || y >= self.height)
|
|
return;
|
|
self.data[x + y * self.width] = v;
|
|
}
|
|
|
|
void
|
|
level_set_px(int x, int y, enum Tile v)
|
|
{
|
|
level_set(x / TILE_SIZE, y / TILE_SIZE, v);
|
|
}
|
|
|
|
int
|
|
level_oob(int x, int y)
|
|
{
|
|
return level_get_px(x, y) == TILE_OOB;
|
|
}
|