From 91aef268319a77ee8f5a082ca89264bf2671e212 Mon Sep 17 00:00:00 2001 From: quou Date: Sat, 6 May 2023 10:39:19 +1000 Subject: Map rendering and camera movement. --- Makefile | 1 + asset.c | 3 +- asset.h | 3 +- game.c | 12 +++++- game_config.h | 6 +++ intermediate/map.bmp | Bin 0 -> 8330 bytes map.c | 95 ++++++++++++++++++++++++++++++++++++++++ map.h | 19 ++++++++ player.c | 22 +++++++++- render.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ render.h | 17 ++++++++ sprite.c | 10 +++++ sprite.h | 4 +- sprite_system.c | 7 ++- world.h | 4 ++ 15 files changed, 314 insertions(+), 8 deletions(-) create mode 100644 intermediate/map.bmp create mode 100644 map.c create mode 100644 map.h diff --git a/Makefile b/Makefile index f4d21cf..c4c00e2 100644 --- a/Makefile +++ b/Makefile @@ -95,6 +95,7 @@ sources = \ game.c \ main.c \ malware.c \ + map.c \ menu.c \ platform.c \ player.c \ diff --git a/asset.c b/asset.c index 5db8a20..162bcbb 100644 --- a/asset.c +++ b/asset.c @@ -9,7 +9,8 @@ static const char* const asset_vpaths[] = { /* asset_id_usr */ "data/usr.img", /* asset_id_char */ "data/char.img", /* asset_id_bullet */ "data/bullet.img", - /* asset_id_enemy */ "data/enemy.img" + /* asset_id_enemy */ "data/enemy.img", + /* asset_id_map */ "data/map.img" }; static struct { diff --git a/asset.h b/asset.h index 23b0893..2650f61 100644 --- a/asset.h +++ b/asset.h @@ -3,13 +3,14 @@ #include "render.h" -#define bitmap_asset_count 4 +#define bitmap_asset_count 5 typedef enum { asset_id_usr = 0, asset_id_char, asset_id_bullet, asset_id_enemy, + asset_id_map, asset_count } Asset_ID; diff --git a/game.c b/game.c index 73d062b..00e4265 100644 --- a/game.c +++ b/game.c @@ -87,18 +87,22 @@ static void menu_deinit(Game* game) { static void gameplay_init(Game* game) { init_world(&game->world); - + init_map(&game->world.map); init_player(&game->world.player, &game->world); - new_skull(&game->world, 0, 0); } static void gameplay_update(Game* game) { + int cx, cy; + cx = game->world.cam_x; + cy = game->world.cam_y; + update_player(&game->world.player, &game->world); enemy_system(&game->world); bullet_system(&game->world); collision_system(&game->world); animation_system(&game->world); + render_map(&game->world.map, cx, cy); sprite_system(&game->world); } @@ -127,11 +131,15 @@ static void dead_init(Game* game) { static void dead_update(Game* game) { const BM_Font* font; + int cx, cy; font = get_default_font(); update_menu(&game->menu); + cx = game->world.cam_x; + cy = game->world.cam_y; + render_map(&game->world.map, cx, cy); sprite_system(&game->world); rfont_text( diff --git a/game_config.h b/game_config.h index b2d569f..8609814 100644 --- a/game_config.h +++ b/game_config.h @@ -11,4 +11,10 @@ #define skull_shoot_cooldown 15 #define enemy_bullet_speed 10 +#define map_width 32 +#define map_height 32 +#define map_tile_size 16 +#define mbmp_w (map_width * map_tile_size) +#define mbmp_h (map_height * map_tile_size) + #endif diff --git a/intermediate/map.bmp b/intermediate/map.bmp new file mode 100644 index 0000000..e6a66ee Binary files /dev/null and b/intermediate/map.bmp differ diff --git a/map.c b/map.c new file mode 100644 index 0000000..2b10abd --- /dev/null +++ b/map.c @@ -0,0 +1,95 @@ +#include "map.h" +#include "sprite.h" +#include "standard.h" + +void init_map(Map* map) { + const Sprite* floor, * bricks; + const Bitmap* fbmp, * bbmp; + Bitmap bitmap; + int i, x, y; + + bitmap.pixels = map->pixels; + bitmap.w = mbmp_w; + bitmap.h = mbmp_h; + + floor = get_sprite(sprite_floor_tile); + bricks = get_sprite(sprite_bricks); + fbmp = get_bitmap(floor->bitmap); + bbmp = get_bitmap(bricks->bitmap); + + for (i = 0; i < mbmp_w * mbmp_h; i++) { + bitmap.pixels[i] = make_black(); + } + + for (x = 1; x < map_width - 1; x++) { + for (y = 1; y < map_height - 1; y++) { + blit( + &bitmap, + fbmp, + map_tile_size * x, + map_tile_size * y, + &floor->rect + ); + } + } + + for (x = 0; x < map_width; x++) { + blit( + &bitmap, + bbmp, + map_tile_size * x, + 0, + &bricks->rect + ); + blit( + &bitmap, + bbmp, + map_tile_size * x, + (map_height - 1) * map_tile_size, + &bricks->rect + ); + } + + for (y = 0; y < map_height; y++) { + blit( + &bitmap, + bbmp, + 0, + map_tile_size * y, + &bricks->rect + ); + blit( + &bitmap, + bbmp, + (map_width - 1) * map_tile_size, + map_tile_size * y, + &bricks->rect + ); + } + + for (i = 0; i < 20; i++) { + x = rand_range(0, map_width - 1) * map_tile_size; + y = rand_range(0, map_height - 1) * map_tile_size; + blit( + &bitmap, + bbmp, + x, + y, + &bricks->rect + ); + } +} + +void render_map(Map* map, int cx, int cy) { + Bitmap bitmap; + Rectangle rect; + + bitmap.pixels = map->pixels; + bitmap.w = mbmp_w; + bitmap.h = mbmp_h; + rect.x = 0; + rect.y = 0; + rect.w = bitmap.w; + rect.h = bitmap.h; + render_bitmap(&bitmap, -cx >> fbits, -cy >> fbits, &rect); +} diff --git a/map.h b/map.h new file mode 100644 index 0000000..35e97f2 --- /dev/null +++ b/map.h @@ -0,0 +1,19 @@ +#ifndef map_h +#define map_h + +#include "game_config.h" +#include "render.h" + +typedef struct { + Colour pixels[ + map_width * + map_tile_size * + map_height * + map_tile_size + ]; +} Map; + +void init_map(Map* map); +void render_map(Map* map, int cx, int cy); + +#endif diff --git a/player.c b/player.c index 592ef4a..d79beed 100644 --- a/player.c +++ b/player.c @@ -55,7 +55,7 @@ void init_player(Player* player, World* world) { } void update_player(Player* player, World* world) { - int dx, dy; + int dx, dy, cbx, cby; int face, moving = 0; Entity e; CPosition* pos; @@ -132,6 +132,26 @@ void update_player(Player* player, World* world) { game_change_state(&game, game_state_dead); } + world->cam_x = pos->x - ((renderer_w / 2) << fbits); + world->cam_y = pos->y - ((renderer_h / 2) << fbits); + + if (world->cam_x < 0) { + world->cam_x = 0; + } + + if (world->cam_y < 0) { + world->cam_y = 0; + } + + cbx = (mbmp_w - renderer_w) << fbits; + if (world->cam_x > cbx) { + world->cam_x = cbx; + } + cby = (mbmp_h - renderer_h) << fbits; + if (world->cam_y > cby) { + world->cam_y = cby; + } + player->shoot_countdown--; } diff --git a/render.c b/render.c index b2a59e2..c18d74d 100644 --- a/render.c +++ b/render.c @@ -261,3 +261,122 @@ void render_bitmap_col( src += sstride; } } + +void blit( + Bitmap* to, + const Bitmap* from, + int x, + int y, + const Rectangle* rect +) { + int i, j, stride, sstride, n; + Colour* dst; + const Colour* src; + Rectangle sub; + + sub = *rect; + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + if (sub.w > from->w) { return; } + if (sub.h > from->h) { return; } + + if ((n = -x) > 0) { + sub.w -= n; + sub.x += n; + x += n; + } + + if ((n = -y) > 0) { + sub.h -= n; + sub.y += n; + y += n; + } + + if ((n = x + sub.w - to->w) > 0) { + sub.w -= n; + } + + if ((n = y + sub.h - to->h) > 0) { + sub.h -= n; + } + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + + dst = to->pixels + (x + y * to->w); + src = from->pixels + (sub.x + sub.y * from->w); + + stride = to->w - sub.w; + sstride = from->w - sub.w; + + for (i = 0; i < sub.h; i++) { + for (j = 0; j < sub.w; j++) { + *dst = blend(*dst, *src); + dst++; + src++; + } + dst += stride; + src += sstride; + } +} + +void blit_col( + Bitmap* to, + const Bitmap* from, + int x, + int y, + const Rectangle* rect, + Colour colour +) { + int i, j, stride, sstride, n; + Colour* dst; + const Colour* src; + Rectangle sub; + + sub = *rect; + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + if (sub.w > from->w) { return; } + if (sub.h > from->h) { return; } + + if ((n = -x) > 0) { + sub.w -= n; + sub.x += n; + x += n; + } + + if ((n = -y) > 0) { + sub.h -= n; + sub.y += n; + y += n; + } + + if ((n = x + sub.w - to->w) > 0) { + sub.w -= n; + } + + if ((n = y + sub.h - to->h) > 0) { + sub.h -= n; + } + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + + dst = to->pixels + (x + y * to->w); + src = from->pixels + (sub.x + sub.y * from->w); + + stride = to->w - sub.w; + sstride = from->w - sub.w; + + for (i = 0; i < sub.h; i++) { + for (j = 0; j < sub.w; j++) { + *dst = blend_mod(*dst, *src, colour); + dst++; + src++; + } + dst += stride; + src += sstride; + } +} diff --git a/render.h b/render.h index be03f02..fc6fed1 100644 --- a/render.h +++ b/render.h @@ -84,4 +84,21 @@ void render_bitmap_col( Colour colour ); +void blit( + Bitmap* dst, + const Bitmap* src, + int x, + int y, + const Rectangle* rect +); + +void blit_col( + Bitmap* dst, + const Bitmap* src, + int x, + int y, + const Rectangle* rect, + Colour colour +); + #endif diff --git a/sprite.c b/sprite.c index ca72f44..708c5e9 100644 --- a/sprite.c +++ b/sprite.c @@ -70,6 +70,16 @@ static const Sprite sprites[] = { { asset_id_usr, { 0, 80, 171, 10 } + }, + /* sprite_floor_tile */ + { + asset_id_map, + { 0, 0, 16, 16 } + }, + /* sprite_bricks */ + { + asset_id_map, + { 16, 0, 16, 16 } } }; diff --git a/sprite.h b/sprite.h index cdc5e28..9f09747 100644 --- a/sprite.h +++ b/sprite.h @@ -19,7 +19,9 @@ typedef enum { sprite_skull_debris_5, sprite_enemy_bullet, sprite_author, - sprite_free + sprite_free, + sprite_floor_tile, + sprite_bricks } Sprite_ID; typedef struct { diff --git a/sprite_system.c b/sprite_system.c index 526c097..b94886e 100644 --- a/sprite_system.c +++ b/sprite_system.c @@ -5,7 +5,7 @@ #include "world.h" void sprite_system(const World* world) { - int i; + int i, x, y; unsigned bits; const CSprite* sprite; const CPosition* pos; @@ -17,8 +17,11 @@ void sprite_system(const World* world) { pos = &world->positions[i]; sprite = &world->sprites[i]; + x = pos->x - world->cam_x; + y = pos->y - world->cam_y; + b = get_bitmap(sprite->id); - render_bitmap(b, pos->x >> fbits, pos->y >> fbits, &sprite->rect); + render_bitmap(b, x >> fbits, y >> fbits, &sprite->rect); } } } diff --git a/world.h b/world.h index 923dc90..ee2dc1a 100644 --- a/world.h +++ b/world.h @@ -3,6 +3,7 @@ #include "components.h" #include "config.h" +#include "map.h" #include "player.h" typedef int Entity; @@ -23,7 +24,10 @@ struct World { CEnemy enemies [max_entities]; CCollider colliders [max_entities]; + int cam_x, cam_y; + Player player; + Map map; }; void init_world(World* world); -- cgit v1.2.3-54-g00ecf