The way I use my routines is weird but efficient and simple. Here is the
code:
.EQU maxh, 240
@ ******** ASMFastTransBlit(unsigned char *src4, unsigned char *dst4, int
nbx, int nby, int height2, int trans) ********
.ALIGN
.GLOBAL ASMFastTransBlit
.TYPE ASMFastTransBlit, function
.CODE 32
@r0 = src4
@r1 = dst4
@r2 = nbx
@r3 = nby
@r4 = height2
@r5 = trans
@r6 = tmp
@r7 = tmpnby
ASMFastTransBlit:
sub sp,sp,#8
stmfd r13!,{r4-r7}
ldr r4,[r13,#24]
ldr r5,[r13,#28]
_bx7:
MOV r7,r3
.REPT maxh
LDRB r6,[r0,+r7]
TEQ r6,r5
STRNEB r6,[r1,+r7]
SUBS r7,r7,#1
BMI _sauty2
.ENDR
_sauty2:
SUB r0,r0,r4
SUB r1,r1,#240
SUBS r2,r2,#1
BPL _bx7
ldmfd r13!,{r4-r7}
add sp,sp,#8
bx lr
.EQU works like #define for c, and defines a constant.
src4 point to the beginning of the picture data to be blitted.
dst4 is the destination bitmap, so this is more flexible than the blitting
functions from the sdk.
The thing that makes this function fast, is that it is unrolled (.REPT maxh
will assemble the loop with 240 times the things between .REPT and .ENDR.
Assemble that using AS, then include your .o file in your makefile, and add
this to your c code:
extern void ASMFastTransBlit(unsigned char *src4, unsigned char *dst4, int
nbx, int nby, int height2, int trans);
So now, we have to clip the bitmap. Here it is:
void FastTransBlit(int numsurface, int dx, int dy, int width, int height,
unsigned char *src, int trans) {
int xmin = 0;
int ymin = 0;
int xmax = width - 1;
int ymax = height - 1;
int height2 = ( (height + 3) >> 2) << 2;
int decaly = screen_height - height - dy;
if(dx < 0) {
xmin = -dx;
} else if( (dx + width) > play_width) xmax = play_width - dx - 1;
if(dy < 0) {
ymax = height + dy - 1;
} else if( (dy + height) > screen_height) ymin = dy + height -
screen_height;
if(xmin > xmax) return;
if(ymin > ymax) return;
unsigned char *dst4 = gpDraw[numsurface].ptbuffer + (dx + xmax) *
screen_height + decaly + ymin;
src += (xmax * height2 + ymin);
ASMFastTransBlit(src, dst4, xmax - xmin, ymax - ymin, height2, trans);
}
Be careful, as I don't control if the picture is too large and goes out of
the screen on both sides (up and down, or left and right). So you should
blit only
20,<240 sized bitmaps. Or you can easily fix that removing the
else statements making the tests independant. Note that this routine clips
the bitmap, but receives a surface number to blit on.
unsigned char *dst4 = gpDraw[numsurface].ptbuffer + (dx + xmax) *
screen_height + decaly + ymin;
Change that line to point to your bitmap in memory if you use Mirko's sdk.
Also here, the picture must be stored rotated 90° anti-clockwise, with its
height rounded to the next word (int height2 = ( (height + 3) >> 2) << 2
.
This is the same as the sdk, and GP32converter will produce correct c code.
But I can also send you a bitmap loading routine (8bit only) if you want to.
Hope that helps.