Re: [AD] offscreen sub bitmaps revisited |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
- To: "Coordination of admins/developers of the game programming library Allegro" <alleg-developers@xxxxxxxxxx>
- Subject: Re: [AD] offscreen sub bitmaps revisited
- From: Matthew Leverton <meffer@xxxxxxxxxx>
- Date: Sat, 26 Jun 2010 02:00:24 -0500
On Fri, Jun 25, 2010 at 8:13 PM, Matthew Leverton <meffer@xxxxxxxxxx> wrote:
> So would _al_draw_bitmap_region_memory need to be updated to clip sub-bitmaps?
>
Attached is a half-implemented patch for memory bitmaps. Maybe there
is an easier way to implement this at a lower level...
The patch adds support for copying from an out-of-bounds sub-bitmap
into an in-bounds sub-bitmap. Test with ex_subbitmap.
Scaling works, but transformations do not. After taking a look at the
transformation code, I didn't even bother to try.
It also doesn't work with bitmap flipping, but that's already screwed
up (IMO) with sub-bitmaps as is.
--
Matthew Leverton
Index: src/bitmap.c
===================================================================
--- src/bitmap.c (revision 13401)
+++ src/bitmap.c (working copy)
@@ -616,24 +616,6 @@
{
ALLEGRO_BITMAP *bitmap;
- /* Clip */
- if (x < 0) {
- w += x;
- if (w < 0) w = 0;
- x = 0;
- }
- if (y < 0) {
- h += y;
- if (h < 0) h = 0;
- y = 0;
- }
- if (x+w > parent->w) {
- w = parent->w - x;
- }
- if (y+h > parent->h) {
- h = parent->h - y;
- }
-
if (parent->parent) {
x += parent->xofs;
y += parent->yofs;
Index: src/memblit.c
===================================================================
--- src/memblit.c (revision 13401)
+++ src/memblit.c (working copy)
@@ -166,8 +166,73 @@
#define SRC_NOT_MODIFIED \
src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && \
tint.r == 1.0f && tint.g == 1.0f && tint.b == 1.0f && tint.a == 1.0f
+
+#define HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, wr, hr) \
+ /* TODO: handle dest bitmaps that are out of bounds */ \
+ if (dest->parent) { \
+ dx += dest->xofs; \
+ dy += dest->yofs; \
+ dest = dest->parent; \
+ } \
+ \
+ if (bitmap->parent) { \
+ if (bitmap->xofs < 0) { \
+ /* sub-bitmap origin is left of parent: \
+ * shrink source width \
+ * move source to left edge, and dest x to the right \
+ */ \
+ sw += bitmap->xofs; \
+ sx = 0; \
+ dx -= bitmap->xofs / wr; \
+ dw += bitmap->xofs / wr; \
+ } \
+ else { \
+ sx += bitmap->xofs; \
+ if (sx >= bitmap->parent->w) { \
+ /* sub-bitmap origin begins to the right of parent: \
+ * nothing to do. \
+ */ \
+ return; \
+ } \
+ } \
+ \
+ if (bitmap->yofs < 0) { \
+ /* sub-bitmap origin is above parent: \
+ * shrink source height \
+ * move source to top edge, and dest y down \
+ */ \
+ sh += bitmap->yofs; \
+ sy = 0; \
+ dy -= bitmap->yofs / hr; \
+ dh += bitmap->yofs / hr; \
+ } \
+ else { \
+ sy += bitmap->yofs; \
+ if (sy >= bitmap->parent->h) { \
+ /* sub-bitmap origin begins to the right of parent: \
+ * nothing to do. \
+ */ \
+ return; \
+ } \
+ } \
+ \
+ bitmap = bitmap->parent; \
+ \
+ if (sx + sw > bitmap->w) { \
+ dw -= (sx + sw - bitmap->w) / wr; \
+ sw = bitmap->w - sx; \
+ } \
+ \
+ if (sy + sh > bitmap->h) { \
+ dh -= (sy + sh - bitmap->h) / hr; \
+ sh = bitmap->h - sy; \
+ } \
+ \
+ if (sw <= 0 || sh <= 0) { \
+ return; \
+ } \
+ } \
-
void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap,
ALLEGRO_COLOR tint,
int sx, int sy, int sw, int sh,
@@ -182,6 +247,7 @@
int xinc, yinc;
int yd;
int sxd;
+ int dw, dh;
if(!is_identity(al_get_current_transform()))
{
@@ -228,19 +294,12 @@
return;
}
- /* Handle sub bitmaps */
- if (dest->parent) {
- dx += dest->xofs;
- dy += dest->yofs;
- dest = dest->parent;
- }
+ dw = sw;
+ dh = dh;
+
+ HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1.0f, 1.0f)
+
- if (bitmap->parent) {
- sx += bitmap->xofs;
- sy += bitmap->yofs;
- bitmap = bitmap->parent;
- }
-
#ifdef ALLEGRO_GP2XWIZ
if (src_mode == ALLEGRO_ALPHA &&
dst_mode == ALLEGRO_INVERSE_ALPHA &&
@@ -431,19 +490,8 @@
if (dw == 0 || dh == 0)
return;
- /* Handle sub bitmaps */
- if (dest->parent) {
- dx += dest->xofs;
- dy += dest->yofs;
- dest = dest->parent;
- }
+ HANDLE_SUB_BITMAPS(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc)
- if (src->parent) {
- sx += src->xofs;
- sy += src->yofs;
- src = src->parent;
- }
-
if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY))) {
return;
}
@@ -1256,6 +1304,7 @@
ALLEGRO_BITMAP *dest = al_get_target_bitmap();
int x;
int y;
+ int dw, dh;
ASSERT(_al_pixel_format_is_real(bitmap->format));
ASSERT(_al_pixel_format_is_real(dest->format));
@@ -1283,19 +1332,11 @@
sh -= inc;
}
- /* Handle sub bitmaps */
- if (dest->parent) {
- dx += dest->xofs;
- dy += dest->yofs;
- dest = dest->parent;
- }
+ dw = sw;
+ dh = sh;
+
+ HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1.0f, 1.0f)
- if (bitmap->parent) {
- sx += bitmap->xofs;
- sy += bitmap->yofs;
- bitmap = bitmap->parent;
- }
-
/* Fast paths for no flipping */
if (!(flags & ALLEGRO_FLIP_HORIZONTAL) &&
!(flags & ALLEGRO_FLIP_VERTICAL)) {
@@ -1419,19 +1460,8 @@
if (dw == 0 || dh == 0)
return;
- /* Handle sub bitmaps */
- if (dest->parent) {
- dx += dest->xofs;
- dy += dest->yofs;
- dest = dest->parent;
- }
+ HANDLE_SUB_BITMAPS(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc)
- if (src->parent) {
- sx += src->xofs;
- sy += src->yofs;
- src = src->parent;
- }
-
if (src->format == dest->format) {
if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY,
ALLEGRO_LOCK_READONLY))) {