From 2fbdf974338bde8576efdae40a819a76b2391033 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Sun, 5 Nov 2023 11:22:55 +0000 Subject: Initial import of the open source release --- src/maps.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 src/maps.c (limited to 'src/maps.c') diff --git a/src/maps.c b/src/maps.c new file mode 100644 index 0000000..87928b2 --- /dev/null +++ b/src/maps.c @@ -0,0 +1,239 @@ +/* + Kitsune's Curse + Copyright (C) 2020-2023 Juan J. Martinez + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ +#include + +#include "aplib.h" +#include "main.h" +#include "splib.h" + +#include "tiles.h" + +#define LOCAL +#include "maps.h" +#include "stage.h" + +#include "entities.h" + +// working map (using 4-bit per tile), 8x8 +static uint8_t ml; +static const unsigned char *map_ents; +static uint8_t blocked; + +void _expand_map() +{ + uint8_t *b = (uint8_t *)BUFF_ADDR; + uint16_t i; + + // uncompress at the end of the working area + aplib_uncompress(b, (uint8_t *)(map[cmap] + 2)); + + // expand from 4-bpt to 8-bpt + for (i = 0; i < TMW * TMH; i += 2) + { + wmap[i] = (*b >> 4) + ts; + wmap[i + 1] = (*b & 0x0f) + ts; + b++; + } +} + +void draw_map() +{ + uint8_t i, j, k, c, m; + + validate_screen(); + + // draw the bottom to top; invalidate is LIFO + for (j = TMH; j; --j) + { + k = j - 1; + for (i = 0; i < TMW; ++i) + { + c = wmap[i + k * TMW]; + + // only if is part of a tileset + if (c < LAST_TILE_TILESET) + { + m = c & 15; + + // special tiles: bricks + if (!m || m == 12) { + if (k & 1) + ++c; + } + } else if (c == BLOCKED_OPEN_DOOR) + c = BLOCKED_OPEN_DOOR_TILE; + + put_tile(bgtiles[c], get_tile_xy(i, k)); + } + } +} + +void init_map(uint8_t m) +{ +#ifdef DEBUG + pad_numbers(wmap, 2, m); + set_text_ink(15, 15, 15); + put_text(wmap, 0, 192); +#endif + + cmap = m; + // map length (not including tileset or flags) + ml = map[cmap][0]; + // tileset + ts = (map[cmap][1] & 0x0f) << 4; + blocked = map[cmap][1] & 0xf0; + // map_ents + map_ents = map[cmap] + 2 + ml; + + _expand_map(); + + exit_up = cmap - WMAPS; + offset_up = 0; + exit_down = cmap + WMAPS; + offset_down = 0; + + init_entities(); + spawn_entities(map_ents); + + draw_map(); +} + +void set_map(uint8_t m) +{ + init_map(m); + + if (!player_h) + { + // IMPORTANT: set new player coords before + // calling to set_map! + + // checkpoint + smap = cmap; + spx = px; + spy = py; + sdir = dir; + } + + draw_entities(); + update_screen(); +} + +void set_map_tile(uint8_t x, uint8_t y, uint8_t tile) +{ + wmap[x + (y * TMW)] = tile; +} + +static struct st_entity *sp_mit; +static uint8_t group, last_blocked; + +uint8_t is_map_blocked(uint8_t x, uint8_t y) +{ + last_blocked = wmap[(x >> 3) + ((y >> 3) * TMW)]; + + if (last_blocked == BLOCKED_OPEN_DOOR) + return BLOCKED_OPEN_DOOR; + + if (last_blocked < LAST_TILE_TILESET) + { + if((last_blocked & 15) > LAST_NON_SOLID) + return 1; + } + else + // from this on, all solids + if (last_blocked > SWITCH_DOOR_TILE - 1) + return 1; + + group = 0; + for (sp_mit = sp_used; sp_mit; sp_mit = sp_mit->n) + { + // this requires ET_DOOR and ET_PLATFORM to go grouped + switch (sp_mit->type) + { + case ET_PLATFORM: + group = 1; + if (check_for_point(sp_mit, x, y, 16, 8)) + return BLOCKED_PLATFORM; + break; + + case ET_DOOR: + group = 1; + if (check_for_point(sp_mit, x, y, 8, 32) && (sp_it || !keys || magic)) + return 1; + break; + + default: + if (group) + return 0; + break; + } + } + + return 0; +} + +uint8_t is_map_deadly(uint8_t x, uint8_t y) +{ + last_deadly = wmap[(x >> 3) + ((y >> 3) * TMW)]; + + // deadly tiles are at the end of the tile table + return (last_deadly < 64 && last_deadly > DEADLY_TILE_BASE - 1); +} + +uint8_t exit_map_left() +{ + if (blocked & BLOCKED_LEFT) + return 0; + + opx = px = (uint8_t)(TW * TMW - 8); + set_map(cmap - 1); + return 1; +} + +uint8_t exit_map_right() +{ + if (blocked & BLOCKED_RIGHT) + return 0; + + opx = px = 0; + set_map(cmap + 1); + return 1; +} + +uint8_t exit_map_up() +{ + if (blocked & BLOCKED_UP) + return 0; + + px += offset_up; + opx = px; + opy = py = (uint8_t)(TH * TMH - 24); + set_map(exit_up); + return 1; +} + +uint8_t exit_map_down() +{ + if (blocked & BLOCKED_DOWN) + return 0; + + px += offset_down; + opx = px; + opy = py = 0; + set_map(exit_down); + return 1; +} -- cgit v1.2.3