aboutsummaryrefslogtreecommitdiff
path: root/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'map.c')
-rw-r--r--map.c160
1 files changed, 125 insertions, 35 deletions
diff --git a/map.c b/map.c
index c2d9e0d..9566aa2 100644
--- a/map.c
+++ b/map.c
@@ -1,7 +1,9 @@
#include "asset.h"
+#include "random.h"
#include "map.h"
#include "rect.h"
#include "render.h"
+#include "world.h"
#define null_tile 0xffff
@@ -12,44 +14,132 @@ Rect tile_rects[] = {
#undef x
};
-void generate_floor(Map* m, int seed) {
+void generate_room(Map* m) {
+ const Bitmap* b = get_bitmap(asset_id_rooms_img);
+ const unsigned* p = (const unsigned*)&b[1];
+ const int max_rooms = b->h / map_h;
+ const int r = /*get_r() % max_rooms;*/ 1;
+ int o = r * map_w * map_h;
int e = map_w * map_h, i;
- for (i = 0; i < e; i++) {
- m->tiles[i] = null_tile;
- m->collision[i] = 0;
+ for (i = 0; i < e; i++, o++) {
+ int bit = 1 << (o & 0x1f);
+ if (p[o >> 5] & bit)
+ m->tiles[i] = tile_brick;
+ else
+ m->tiles[i] = null_tile;
}
- e = map_w * (map_h - 1);
- for (i = 0; i < map_w; i++) {
- int idx = i + e;
- m->tiles[idx] = tile_stone;
- m->collision[idx] = 1;
+}
+
+unsigned short get_collider(Map_Tile t) {
+ switch (t) {
+ case tile_stone:
+ case tile_block1:
+ case tile_block2:
+ case tile_window_top:
+ case tile_window_mid:
+ case tile_window_bot:
+ case tile_brick_floor:
+ case tile_brick: return 1;
+ case tile_brick_ramp5:
+ case tile_stone_ramp5: return 2;
+ case tile_brick_ramp6:
+ case tile_stone_ramp6: return 3;
+ case tile_brick_ramp7:
+ case tile_stone_ramp7: return 4;
+ case tile_brick_ramp8:
+ case tile_stone_ramp8: return 5;
+ default:
+ return 0;
}
-#define set(x, y) \
- m->tiles[x + y * map_w] = tile_brick; \
- m->collision[x + y * map_w] = 1;
- set(0, 13);
- set(0, 12);
- set(0, 11);
- set(1, 11);
- set(2, 11);
- set(3, 11);
- set(4, 11);
- set(6, 11);
- set(7, 11);
- set(8, 11);
- set(19, 13);
- set(19, 12);
- set(19, 11);
- set(19, 10);
- set(19, 9);
- set(19, 8);
-#undef set
- m->tiles[18 + 13 * map_w] = tile_stone_ramp9;
- m->collision[18 + 13 * map_w] = 6;
- m->tiles[1 + 12 * map_w] = tile_stone_ramp13;
- m->collision[1 + 12 * map_w] = 10;
- m->tiles[2 + 12 * map_w] = tile_stone_ramp14;
- m->collision[2 + 12 * map_w] = 11;
+}
+
+void generate_collision(Map* m) {
+ int e = map_w * map_h, i;
+ for (i = 0; i < e; i++)
+ m->collision[i] = get_collider(m->tiles[i]);
+}
+
+int imp_check(Map* m, Map_Tile t, int x, int y) {
+ return
+ x >= 0 &&
+ y >= 0 &&
+ x < map_w &&
+ y < map_h &&
+ m->tiles[x + y * map_w] == t;
+}
+
+#define check(ox, oy, t) \
+ imp_check(m, t, x + ox, y + oy)
+#define place(t) \
+ m->tiles[x + y * map_w] = t
+#define place_o(t, ox, oy) \
+ m->tiles[x + ox + (y + oy) * map_w] = t
+
+void generate_ramps(Map* m) {
+ int x, y;
+ for (y = 0; y < map_h; y++)
+ for (x = 0; x < map_w; x++) {
+ if (
+ check( 0, 0, null_tile) &&
+ check( 1, 0, null_tile) &&
+ check(-1, 0, tile_brick) &&
+ !check(-1, -1, tile_brick) &&
+ check( 0, 1, tile_brick) &&
+ check( 1, 1, tile_brick)
+ ) {
+ place(tile_brick_ramp7);
+ place_o(tile_brick_ramp8, 1, 0);
+ }
+ if (
+ check( 0, 0, null_tile) &&
+ check(-1, 0, null_tile) &&
+ check( 1, 0, tile_brick) &&
+ !check( 1, -1, tile_brick) &&
+ check( 0, 1, tile_brick) &&
+ check(-1, 1, tile_brick)
+ ) {
+ place(tile_brick_ramp6);
+ place_o(tile_brick_ramp5, -1, 0);
+ }
+ if (
+ check(0, 0, tile_brick) &&
+ check(0, 1, tile_brick) &&
+ check(0, 2, tile_brick) && ((
+ check(1, 0, null_tile) &&
+ check(1, 1, null_tile) &&
+ check(1, 2, null_tile)) || (
+ check(-1, 0, null_tile) &&
+ check(-1, 1, null_tile) &&
+ check(-1, 2, null_tile)))
+ ) {
+ place(tile_window_top);
+ place_o(tile_window_mid, 0, 1);
+ place_o(tile_window_bot, 0, 2);
+ }
+ }
+}
+
+void generate_floors(Map* m) {
+ int x, y;
+ for (y = 0; y < map_h; y++)
+ for (x = 0; x < map_w; x++) {
+ if (
+ check(0, 0, tile_brick) &&
+ check(0, -1, null_tile)
+ ) place(tile_brick_floor);
+ }
+}
+
+#undef check
+#undef place
+
+void generate_floor(Map* m, World* w) {
+ generate_room(m);
+ generate_ramps(m);
+ generate_floors(m);
+ generate_collision(m);
+ w->player.x = 16 << fbits;
+ w->player.y = 16 << fbits;
}
void render_map(const Map* m, Renderer* r) {