From 4c4ffc1b84ada5dc47f9d36e9154564b68ff7fed Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 11 Jul 2023 23:11:21 +0100 Subject: Add gol/silver keys and door logic --- src/effect.c | 20 +++++++++++++++++++ src/effect.h | 1 + src/map.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/map.h | 4 ++++ src/pickup.c | 51 ++++++++++++++++++++++++++++++++++++++++++------ src/pickup.h | 2 ++ 6 files changed, 132 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/effect.c b/src/effect.c index a2e58c2..e9ee55e 100644 --- a/src/effect.c +++ b/src/effect.c @@ -1,4 +1,6 @@ #include +#include +#include #include "vga.h" #include "entities.h" @@ -21,6 +23,24 @@ static const Rect frames[2 * 4] = { 0, 0, 144, 144 } }; +void effect_out_new(uint16_t x, uint16_t y) +{ + Entity *e = entities_new(); +#ifdef DEBUG + if (!e) + { + set_mode(3); + fprintf(stderr, "ERROR: run out of entities\n"); + exit(1); + } +#endif + + e->x = x; + e->y = y; + + effect_out_init(e); +} + void effect_out_init(Entity *e) { e->frames = (const Rect *)frames; diff --git a/src/effect.h b/src/effect.h index 9c9d654..10427fb 100644 --- a/src/effect.h +++ b/src/effect.h @@ -1,6 +1,7 @@ #ifndef _EFFECT_H #define _EFFECT_H +void effect_out_new(uint16_t x, uint16_t y); void effect_out_init(Entity *e); void effect_out_update(Entity *e); diff --git a/src/map.c b/src/map.c index 5599ae9..4aafdca 100644 --- a/src/map.c +++ b/src/map.c @@ -7,6 +7,7 @@ #include "data.h" #include "entities.h" +#include "effect.h" #include "player.h" #include "snake.h" #include "bat.h" @@ -17,7 +18,7 @@ #include "map.h" /* current map; set via map_init */ -static const uint8_t *cmap; +static uint8_t cmap[MAP_W * MAP_H]; static uint8_t gold[MAP_W * MAP_H]; static uint8_t total_gold; @@ -30,14 +31,17 @@ static void (* const init[])(Entity *) = pickup_time_init, pickup_bonus_init, pickup_pickaxe_init, + pickup_goldkey_init, + pickup_silverkey_init, }; void map_init(const uint8_t map[]) { - cmap = map; + /* make a copy of the map data in RAM */ + memcpy(cmap, map, MAP_W * MAP_H); /* make a copy of the gold data in RAM */ - memcpy(gold, cmap + MAP_W * MAP_H, MAP_W * MAP_H); + memcpy(gold, map + MAP_W * MAP_H, MAP_W * MAP_H); /* count how many pieces of gold on this map */ total_gold = 0; @@ -154,6 +158,59 @@ uint8_t map_update_gold(uint16_t x, uint16_t y) return 0; } +static void map_open_key(uint8_t top, uint8_t bottom) +{ + Rect src = { 0, 0, 160, 48 }; + Rect dst = { 0, 0, 16, 8 }; + + blit_target(TARGET_BUFFER); + + for (uint8_t y = 0; y < MAP_H; y++) + for (uint8_t x = 0; x < MAP_W; x++) + { + uint8_t t = cmap[x + y * MAP_W]; + + if (t == top || t == bottom) + { + /* not solid */ + cmap[x + y * MAP_W] = 0; + cmap[x + 1 + y * MAP_W] = 0; + + dst.x = x * MAP_TILE_W; + dst.y = y * MAP_TILE_H + MAP_OFFS_Y; + + /* top */ + if (t == top) + { + src.x = 64; + src.y = 0; + + effect_out_new(x * MAP_TILE_W, y * MAP_TILE_H); + } + else + { + /* bottom */ + src.x = 32; + src.y = 8; + } + blitrc(binary_tiles_start, &src, &dst); + continue; + } + } + + blit_target(TARGET_SCREEN); +} + +void map_open_goldkey() +{ + map_open_key(45, 65); +} + +void map_open_silverkey() +{ + map_open_key(47, 67); +} + uint8_t map_is_complete() { return total_gold == 0; diff --git a/src/map.h b/src/map.h index 42f8da7..138abcd 100644 --- a/src/map.h +++ b/src/map.h @@ -21,6 +21,10 @@ uint8_t map_is_blocked(uint16_t x, uint16_t y); uint8_t map_is_deadly(uint16_t x, uint16_t y); uint8_t map_update_gold(uint16_t x, uint16_t y); + +void map_open_goldkey(); +void map_open_silverkey(); + uint8_t map_is_complete(); #endif /* _MAP_H */ diff --git a/src/pickup.c b/src/pickup.c index afc5ef2..fe7d15e 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -4,6 +4,7 @@ #include "vga.h" #include "sound.h" #include "entities.h" +#include "map.h" #include "game.h" #include "player.h" @@ -21,8 +22,8 @@ typedef enum PICKUP_TIME = 0, PICKUP_BONUS, PICKUP_PICKAXE, - PICKUP_GOLD_KEY, - PICKUP_SILVER_KEY, + PICKUP_GOLDKEY, + PICKUP_SILVERKEY, } PickupType; static const Rect frames_in[2 * 4] = @@ -48,10 +49,10 @@ static const Rect frames[2 * 4] = { 64, 16, 144, 144 }, /* gold key */ - { 0, 0, 144, 144 }, + { 32, 16, 144, 144 }, /* siver key */ - { 0, 0, 144, 144 }, + { 48, 16, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, @@ -134,6 +135,24 @@ void pickup_pickaxe_init(Entity *e) e->update = pickup_wait_update; } +void pickup_goldkey_init(Entity *e) +{ + e->used = USED_BG; + e->frames = (const Rect *)frames_in; + e->flags = PICKUP_GOLDKEY; + e->counter = 2 + (rand() % MAX_TTL); + e->update = pickup_wait_update; +} + +void pickup_silverkey_init(Entity *e) +{ + e->used = USED_BG; + e->frames = (const Rect *)frames_in; + e->flags = PICKUP_SILVERKEY; + e->counter = 2 + (rand() % MAX_TTL); + e->update = pickup_wait_update; +} + void pickup_wait_update(Entity *e) { if (e->counter-- == 0) @@ -165,6 +184,14 @@ void pickup_in_update(Entity *e) e->frames = (const Rect *)frames; e->frame = 1; break; + case PICKUP_GOLDKEY: + e->frames = (const Rect *)frames; + e->frame = 2; + break; + case PICKUP_SILVERKEY: + e->frames = (const Rect *)frames; + e->frame = 3; + break; } e->counter = 0; e->update = pickup_update; @@ -174,7 +201,9 @@ void pickup_in_update(Entity *e) void pickup_update(Entity *e) { - if (e->counter++ == MAX_TTL) + /* the keys NEVER disappear */ + if (e->flags != PICKUP_GOLDKEY && e->flags != PICKUP_SILVERKEY + && e->counter++ == MAX_TTL) { effect_out_init(e); sound_play_efx(EFX_WARP); @@ -202,15 +231,25 @@ void pickup_update(Entity *e) { case PICKUP_TIME: reset_time(); + sound_play_efx(EFX_PICKUP); break; case PICKUP_BONUS: add_score(250); + sound_play_efx(EFX_PICKUP); break; case PICKUP_PICKAXE: add_pickaxe(); + sound_play_efx(EFX_PICKUP); + break; + case PICKUP_GOLDKEY: + map_open_goldkey(); + sound_play_efx(EFX_WARP); + break; + case PICKUP_SILVERKEY: + map_open_silverkey(); + sound_play_efx(EFX_WARP); break; } e->used = USED_FREE; - sound_play_efx(EFX_PICKUP); } } diff --git a/src/pickup.h b/src/pickup.h index ecb5350..4b5a82c 100644 --- a/src/pickup.h +++ b/src/pickup.h @@ -4,6 +4,8 @@ void pickup_time_init(Entity *e); void pickup_bonus_init(Entity *e); void pickup_pickaxe_init(Entity *e); +void pickup_goldkey_init(Entity *e); +void pickup_silverkey_init(Entity *e); void pickup_wait_update(Entity *e); void pickup_in_update(Entity *e); -- cgit v1.2.3