[AD] possible bug in draw_sprite_h_flip C version while clipping |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
The sprite does not clip right,
I think sxbeg and w are not calculated right, I have included my unoptimized
fix. The code below shows what I mean.
with regards,
Deepak T(coolbool@xxxxxxxxxx)
#include <allegro.h>
// #define novideo
// Driver can be GFX_VGA, GFX_GDI, GFX_SAFE, GFX_AUTODETECT
// #define driver GFX_GDI
// #define driver GFX_VGA
#define driver GFX_AUTODETECT
#define resw 640
#define resh 480
#define colordepth 16
#if colordepth==16
#include "d:\allegro\src\c\cdefs16.h"
#elif colordepth==15
#include "d:\allegro\src\c\cdefs15.h"
#elif colordepth==24
#include "d:\allegro\src\c\cdefs24.h"
#elif colordepth==32
#include "d:\allegro\src\c\cdefs32.h"
#endif
// #define nomouse
// #define nokeyboard
/* _linear_draw_sprite_h_flip:
* Draws a sprite to a linear bitmap, flipping horizontally.
*/
void draw_sprite_h_flipc(BITMAP *dst, BITMAP *src, int dx, int dy)
{
int x, y, w, h;
int dxbeg, dybeg;
int sxbeg, sybeg;
if (dst->clip) {
int tmp;
// possible bug here
tmp = dst->cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
/*
// fix
sxbeg = 0;
// crop from left
if (dx <= 0) {
dxbeg = 0;
w = src->w + dx;
}
// inside the dst
else {
dxbeg = dx;
w = src->w;
}
// crop from right
tmp = dxbeg + w;
if (tmp > dst->cr) {
sxbeg = tmp - dst->cr;
w = w - (tmp -dst->cr);
}
*/
if (w <= 0)
return;
dxbeg += w - 1;
tmp = dst->ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
}
else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx + w - 1;
dybeg = dy;
}
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
bmp_select(dst);
for (y = 0; y < h; y++) {
PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
unsigned long c = GET_MEMORY_PIXEL(s);
if (!IS_SPRITE_MASK(src, c)) {
PUT_PIXEL(d, c);
}
}
}
bmp_unwrite_line(dst);
}
else {
for (y = 0; y < h; y++) {
PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
unsigned long c = GET_MEMORY_PIXEL(s);
if (!IS_SPRITE_MASK(src, c)) {
PUT_MEMORY_PIXEL(d, c);
}
}
}
}
}
int main()
{
BITMAP *bmp, *buffer;
allegro_init();
#ifndef nokeyboard
// set up the keyboard handler
install_keyboard();
#endif
#ifndef nomouse
// set up the mouse
install_mouse();
#endif
#if driver==GFX_VGA
#define resw 320
#define resh 200
#define colordepth 8
#endif
set_color_depth(colordepth);
#ifndef novideo
// set a graphics mode
if (set_gfx_mode(driver, resw, resh, 0, 0) != 0) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message("Unable to set %dx%dx%d graphic mode\n%s\n",
resw, resh, colordepth, allegro_error);
return 1;
}
#endif
// set the color palette
#if colordepth<9
set_palette(desktop_palette);
#endif
#ifndef novideo
// clear the screen to white
clear_to_color(screen, makecol(255, 255, 255));
#endif
// CODE
bmp = load_bitmap("test.bmp", NULL);
buffer = create_bitmap(resw, resh);
if ((!bmp) || (!buffer)) return 1;
clear(buffer);
draw_sprite(buffer, bmp, 0, 0);
draw_sprite_h_flipc(buffer, bmp, bmp->w/-2, bmp->h+10);
blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
readkey();
destroy_bitmap(bmp);
destroy_bitmap(buffer);
return 0;
}
END_OF_MAIN();