summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/stage.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/stage.c b/src/stage.c
index 35d6835..c52e5b1 100644
--- a/src/stage.c
+++ b/src/stage.c
@@ -369,18 +369,46 @@ void stage_get_position(stage_t *stage, v2f_t *res_position)
*res_position = stage->position;
}
-
-static void aabb_to_rect(const aabb_t *aabb, const v2f_t *pos, const SDL_Rect *stage_rect, SDL_Rect *res_rect)
+/* translate an aabb having origin origin at pos position into a dest rect witin stage_rect */
+static void aabb_to_rect(const v2f_t *stage_pos, const aabb_t *aabb, const v2f_t *aabb_origin, const v2f_t *aabb_pos, const SDL_Rect *stage_rect, SDL_Rect *res_rect)
{
- float half_w = ((float)stage_rect->w) * .5f, half_h = ((float)stage_rect->h) * .5f; /* FIXME silly to recompute this repeatedly... */
+ float aabb_w = (aabb->max.x - aabb->min.x);
+ float aabb_h = (aabb->max.y - aabb->min.y);
+
+ /* res dimensions are simply aabb dimensions scaled by stage dimensions */
+ res_rect->w = floorf(aabb_w * .5f * (float)stage_rect->w);
+ res_rect->h = floorf(aabb_h * .5f * (float)stage_rect->h);
+
+ /* center in stage_rect */
+ res_rect->x = stage_rect->x + floorf((float)stage_rect->w * .5f);
+ res_rect->y = stage_rect->y + floorf((float)stage_rect->h * .5f);
+
+ /* apply stage_pos (scaled relative to stage_rect) */
+ res_rect->x += floorf(stage_pos->x * .5f * (float)stage_rect->w);
+ res_rect->y += -floorf(stage_pos->y * .5f * (float)stage_rect->h);
- res_rect->x = stage_rect->x;
- res_rect->y = stage_rect->y;
- res_rect->x += ((float)aabb->min.x + pos->x) * half_w + half_w;
- res_rect->y += stage_rect->h - (((float)aabb->max.y + pos->y) * half_h + half_h);
+ /* apply aabb_pos (scaled relative to stage_rect) */
+ res_rect->x += floorf(aabb_pos->x * .5f * (float)stage_rect->w);
+ res_rect->y += -floorf(aabb_pos->y * .5f * (float)stage_rect->h);
+
+ /* apply aabb_origin (scaled relative to scaled aabb_w) (this probably needs to be inverted) */
+ res_rect->x += floorf(aabb_origin->x * .5f * (float)res_rect->w);
+ res_rect->y += -floorf(aabb_origin->y * .5f * (float)res_rect->h);
+
+ /* apply aabb (scaled relative to stage_rect) */
+ res_rect->x += floorf(aabb->min.x * .5f * (float)stage_rect->w);
+ res_rect->y += -floorf(aabb->max.y * .5f * (float)stage_rect->h);
+
+ /* Prevent producing 0-dimensioned non-zero rects even if it's technicaly incorrect,
+ * what's likely going on is the window has been resized very small. Rather
+ * than allowing things to become completely invisible in such circumstances,
+ * give them at least a single pixel.
+ */
+ if (res_rect->w == 0 && aabb_w > 0.f)
+ res_rect->w = 1;
- res_rect->w = (aabb->max.x - aabb->min.x) * half_w;
- res_rect->h = (aabb->max.y - aabb->min.y) * half_h;
+ if (res_rect->h == 0 && aabb_h > 0.f)
+ res_rect->h = 1;
}
@@ -395,7 +423,7 @@ static void render_nodes(const stage_t *stage, const list_head_t *head, SDL_Rend
continue;
/* scale the node's aabb stage coordinates to destination renderer coordinates */
- aabb_to_rect(&node->aabb, &node->position, dest_rect, &node_rect);
+ aabb_to_rect(&stage->position, &node->aabb, &node->origin, &node->position, dest_rect, &node_rect);
/* if we have a cached texture, see if the dimensions changed */
if (node->cached.texture &&
@@ -503,7 +531,7 @@ stage_node_t * stage_node_lookup_cartesian(const stage_t *stage, int x, int y)
if (!node->active)
continue;
- aabb_to_rect(&node->aabb, &node->position, &rect, &node_rect);
+ aabb_to_rect(&stage->position, &node->aabb, &node->origin, &node->position, &rect, &node_rect);
if (x >= node_rect.x && x < node_rect.x + node_rect.w &&
y >= node_rect.y && y < node_rect.y + node_rect.h)
return node;
© All Rights Reserved