From d97803995c8512738297dcff27ceec60bd023405 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Tue, 19 Feb 2013 00:04:27 -0500 Subject: Implement and test renderer. --- diff --git a/src/area.c b/src/area.c index 3a03198..ae8b071 100644 --- a/src/area.c +++ b/src/area.c @@ -2,6 +2,101 @@ #include "area.h" #include "layer.h" #include "viewport.h" +#include "resources/map.h" +#include "logging.h" + +static void blit_map_layers(struct map *, struct area *); +static void blit_map_layer(struct map *, enum map_layer_id, + struct area *, enum area_layer_id); + +struct area * +area_new(struct map *map) +{ + struct area *a; + + a = malloc(sizeof(*a)); + if (a == NULL) { + return NULL; + } + + blit_map_layers(map, a); + + return a; +} + +static void +blit_map_layers(struct map *map, struct area *area) +{ + blit_map_layer(map, MAP_LAYER_GROUND, area, AREA_LAYER_GROUND); + blit_map_layer(map, MAP_LAYER_OBJ_LOW, area, AREA_LAYER_OBJ_LOW); + blit_map_layer(map, MAP_LAYER_OBJ_MID, area, AREA_LAYER_OBJ_MID); + blit_map_layer(map, MAP_LAYER_OBJ_HIGH, area, AREA_LAYER_OBJ_HIGH); +} + +static void +blit_map_layer(struct map *map, enum map_layer_id map_layer, + struct area *area, enum area_layer_id area_layer) +{ + int i; + Uint32 gid; + int tile_found; + struct map_tileset *mts; + Uint32 mts_lastgid; + SDL_Rect tilerect, layerrect; + + area->map_layers[area_layer] = SDL_CreateRGBSurface( + SDL_SWSURFACE | SDL_SRCCOLORKEY | SDL_SRCALPHA, + map->width * map->tilewidth, + map->height * map->tileheight, + 32, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0x00000000); + SDL_SetColorKey(area->map_layers[area_layer], SDL_SRCCOLORKEY, 0); + for (i = 0; i < map->width * map->height; ++i) { + gid = map->layers[map_layer].tiles[i]; + if (gid == 0) { + continue; + } + tile_found = 0; + for (mts = map->tilesets_head; mts != NULL; mts = mts->next) { + mts_lastgid = mts->firstgid + + mts->tileset->width * mts->tileset->height; + if (gid >= mts->firstgid && gid < mts_lastgid) { + gid -= mts->firstgid; + tilerect.x = gid % mts->tileset->width; + tilerect.y = gid / mts->tileset->width; + tilerect.w = mts->tileset->tilewidth; + tilerect.h = mts->tileset->tileheight; + tilerect.x *= tilerect.w; + tilerect.y *= tilerect.h; + layerrect.x = i % map->width; + layerrect.y = i / map->width; + layerrect.w = mts->tileset->tilewidth; + layerrect.h = mts->tileset->tileheight; + layerrect.x *= layerrect.w; + layerrect.y *= layerrect.h; +#if 0 + debug("Blitting %dx%d tile at (%d,%d) " + "onto layer at (%d,%d)...", + tilerect.w, tilerect.h, + tilerect.x, tilerect.y, + layerrect.x, layerrect.y); +#endif + SDL_BlitSurface(mts->tileset->image->image, + &tilerect, + area->map_layers[area_layer], + &layerrect); + tile_found = 1; + break; + } + } + if (!tile_found) { + warn("Tile with gid 0x%8.8x not found", gid); + } + } +} void render_area_to_viewport(struct area *area, struct viewport *vp) @@ -25,26 +120,33 @@ void render_area_to_surface(struct area *area, SDL_Rect *arearect, SDL_Surface *dst, SDL_Rect *dstrect) { + debug("Rendering %dx%d area rect at (%d,%d) " + "onto %dx%d surface rect at (%d,%d)...", + arearect->w, arearect->h, arearect->x, arearect->y, + dstrect->w, dstrect->h, dstrect->x, dstrect->y); + /* Fast fill with black to avoid artifacts in off-map pixels. */ - SDL_FillRect(dst, dstrect, 0); + /* NB: This is gray, at least temporarily. */ + SDL_FillRect(dst, dstrect, SDL_MapRGB(dst->format, 63, 63, 63)); /* Blit ground layer. */ - SDL_BlitSurface(area->map_layers[LAYER_GROUND], arearect, + SDL_BlitSurface(area->map_layers[AREA_LAYER_GROUND], arearect, dst, dstrect); /* Blit low objects layer. */ - SDL_BlitSurface(area->map_layers[LAYER_OBJ_LOW], arearect, + SDL_BlitSurface(area->map_layers[AREA_LAYER_OBJ_LOW], arearect, dst, dstrect); +/* return;*/ /* TODO: Blit low sprites. */ /* Blit middle objects layer. */ - SDL_BlitSurface(area->map_layers[LAYER_OBJ_MID], arearect, + SDL_BlitSurface(area->map_layers[AREA_LAYER_OBJ_MID], arearect, dst, dstrect); /* TODO: Blit high sprites. */ /* Blit high objects layer. */ - SDL_BlitSurface(area->map_layers[LAYER_OBJ_HIGH], arearect, + SDL_BlitSurface(area->map_layers[AREA_LAYER_OBJ_HIGH], arearect, dst, dstrect); } diff --git a/src/area.h b/src/area.h index 644ab16..a1b7e92 100644 --- a/src/area.h +++ b/src/area.h @@ -4,11 +4,13 @@ #include #include "layer.h" #include "viewport.h" +#include "resources/map.h" struct area { - SDL_Surface *map_layers[LAYERS_MAX]; + SDL_Surface *map_layers[AREA_LAYERS_MAX]; }; +struct area *area_new(struct map *map); void render_area_to_viewport(struct area *area, struct viewport *vp); void render_area_to_surface(struct area *area, SDL_Rect *arearect, SDL_Surface *dst, SDL_Rect *dstrect); diff --git a/src/layer.h b/src/layer.h index 09ad462..5cb7afc 100644 --- a/src/layer.h +++ b/src/layer.h @@ -1,13 +1,13 @@ #ifndef LAYER_H #define LAYER_H -enum layer_id { - LAYER_GROUND = 0, - LAYER_OBJ_LOW, - LAYER_OBJ_MID, - LAYER_OBJ_HIGH, - LAYER_WEATHER, - LAYERS_MAX +enum area_layer_id { + AREA_LAYER_GROUND = 0, + AREA_LAYER_OBJ_LOW, + AREA_LAYER_OBJ_MID, + AREA_LAYER_OBJ_HIGH, + AREA_LAYER_WEATHER, + AREA_LAYERS_MAX }; #endif diff --git a/src/main.c b/src/main.c index 5410d0e..71e465d 100644 --- a/src/main.c +++ b/src/main.c @@ -4,21 +4,116 @@ #include "resources/image.h" #include "resources/map.h" #include "viewport.h" +#include "area.h" int main(void) { + struct viewport *vp; SDL_Surface *screen; struct map *map; struct image *img; struct map_tileset *ts; struct map_exit *e; SDL_Rect imgrect, surfacerect; + struct area *a; init(); - screen = init_viewport(240, 160, 8)->screen; + vp = init_viewport(240, 160, 32); + screen = vp->screen; + + map = map_get("data/forest1-8bit.tmx"); + a = area_new(map); + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(500); + +#if 0 + vp->x = 208; + vp->y = 544; + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(125); + for (; vp->y >= 464; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(50); + } + for (; vp->x <= 256; vp->x += 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(50); + } + for (; vp->y >= 192; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(50); + } + for (; vp->x >= 160; vp->x -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(50); + } + for (; vp->y <= 288; vp->y += 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(50); + } +#endif + + vp->x = 208; + vp->y = 544; + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(125); + for (; vp->y >= 464; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->x <= 256; vp->x += 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->y >= 192; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->x >= 160; vp->x -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->y <= 320; vp->y += 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->x >= -16; vp->x -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->y >= 192; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->x <= 64; vp->x += 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + for (; vp->y >= 0; vp->y -= 4) { + render_area_to_viewport(a, vp); + SDL_Flip(screen); + SDL_Delay(25); + } + + quit(0); - map = map_get("data/forest1.tmx"); debug("Map dimensions: %dx%d", map->width, map->height); for (ts = map->tilesets_head; ts != NULL; ts = ts->next) { debug("Tileset name: %s", ts->tileset->name); @@ -35,6 +130,14 @@ main(void) } img = img_png_get("../forest-6-layer-test_ground.png"); + debug("screen: bpp: %u, masks: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x", + screen->format->BitsPerPixel, + screen->format->Rmask, screen->format->Gmask, + screen->format->Bmask, screen->format->Amask); + debug("image: bpp: %u, masks: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x", + img->image->format->BitsPerPixel, + img->image->format->Rmask, img->image->format->Gmask, + img->image->format->Bmask, img->image->format->Amask); img_png_free(img); quit(0); return 0; -- cgit v0.9.1