📄 bitmaphi.cpp
字号:
/*
* 移植自WatcomC++,于1999年4月14日
*
*/
#include <malloc.h>
#include <string.h>
#include "bitmap.hpp"
#include "gl.h"
BitmapHi::BitmapHi( )
{
}
BitmapHi::~BitmapHi( )
{
if( dat )
delete dat;
if( line )
delete *line ;
}
DWORD BitmapHi::GetPixel( int x, int y )
{
if( x < 0 || x >= width || y < 0 || y >= height )
return -1;
return ( (( WORD* )line[y])[x] );
}
// drawMode will do its work
// solid xor blend
void BitmapHi::PutPixel( int x, int y )
{
if( clip ){
if( x < cl || x >= cr || y < ct || y >= cb )
return;
}
else{
if( x < 0 || x >= width || y < 0 || y >= height )
return;
}
short pixel = color;
if( drawMode & XorMode )
pixel ^= *(short*)( line[y] + x*2 );
else if( drawMode & AlphaMode )
pixel = pixel;//(short)blender->blender[ alpha ]( pixel, *(short*)( line[y] + x*2 ) );
*(WORD*)( line[y] + x*2 ) = pixel;
}
void BitmapHi::Blit( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
BLITCLIP()
if( dest == this ){
if( y > sy )
BlitInside( x, y, sx, sy, w, h );
else if( y == sy && sx < x )
BlitInside( x, y, sx, sy, w, h );
else
BlitOutside( (Bitmap16*)dest, x, y, sx, sy, w, h );
}
else{
BlitOutside( (Bitmap16*)dest, x, y, sx, sy, w, h );
}
}
// the source bitmap and the destination bitmap are the same bitmap
// reverse must be considered
void BitmapHi::BlitInside( int x, int y, int sx, int sy, int w, int h )
{
char** line = BitmapHi::line;
__asm{
push es;
mov ax, ds;
mov es, ax;
/* copy from the bottom to the top */;
mov eax, sy;
mov ebx, h;
dec ebx;
add eax, ebx;
mov sy, eax;
add y, ebx;
inc ebx;
mov ecx, w;
mov edx, sx;
dec ecx;
add edx, ecx;
mov sx, edx;
add x, ecx;
std;
inc ecx;
shl sx, 1;
shl x, 1;
mov edx, y;
shl eax, 2;
shl edx, 2;
cmp ecx, 1;
jg blitinside16_dw;
blitinside16_w: /* the width is one word */
mov esi, line;
mov edi, esi;
mov esi, dword ptr [esi+eax];
add esi, sx;
mov edi, dword ptr [edi+edx];
add edi, x;
mov ecx, w;
repnz movsw;
sub eax, 4;
sub edx, 4;
dec ebx;
jnz blitinside16_w;
jmp blitinside16_end;
blitinside16_dw: /* the width is larger than 1 */
mov ecx, w;
mov esi, line;
mov edi, esi;
mov esi, dword ptr [esi+eax];
add esi, sx;
mov edi, dword ptr [edi+edx];
add edi, x;
shr ecx, 1;
jnc blitinside16_dwdw;
movsw;
blitinside16_dwdw:
sub esi, 2;
sub edi, 2;
repnz movsd;
sub eax, 4;
sub edx, 4;
dec ebx;
jnz blitinside16_dw;
blitinside16_end:
pop es;
}
}
// blit from a bitmap to another bitmap
// no reverse at all
void BitmapHi::BlitOutside( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
char** dline = dest->line;
char** sline = line;
int dpitch = dest->pitch, spitch = pitch;
__asm{
push es;
mov ax, ds;
mov es, ax;
mov ebx, h;
cld;
mov ecx, w;
mov eax, y;
mov edx, sy;
shl eax, 2;
shl edx, 2;
shl sx, 1;
shl x, 1;
mov esi, sline;
mov esi, [esi+edx];
add esi, sx;
mov edi, dline;
mov edi, [edi+eax];
add edi, x;
shl ecx, 1;
mov edx, spitch;
mov eax, dpitch;
sub edx, ecx;
sub eax, ecx;
shr ecx, 1;
cmp ecx, 1;
jg blitoutside16_dwloop;
blitoutside16_w: /* width is one word */;
movsw;
add esi, edx;
add edi, eax;
dec ebx;
jnz blitoutside16_w;
jmp blitoutside16_end;
mov ecx, w;
blitoutside16_dwloop: /* width larger than one word */;
shr ecx, 1;
jnc blitoutside16_dwl;
movsw;
blitoutside16_dwl:
repnz movsd;
add esi, edx;
add edi, eax;
mov spitch, esi;
mov ecx, w;
dec ebx;
jnz blitoutside16_dwloop;
blitoutside16_end:
pop es;
}
}
// blit to another bitmap with SOURCE color key
void BitmapHi::BlitMask( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
BLITCLIP()
if( dest == this )
return; /*failed */
else{
BlitMasked( (Bitmap*)dest, x, y, sx, sy, w, h );
}
}
void BitmapHi::BlitMasked( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
char** dline = dest->line;
char** sline = line;
int colorkey = colorKey;
_asm{
push es;
mov ax, ds;
mov es, ax;
mov eax, colorkey;
mov ebx, h;
shl y, 2;
shl sy, 2;
shl sx, 1;
shl x, 1;
blitmasked16_w:
mov esi, sline;
add esi, sy;
mov esi, [esi];
add esi, sx;
mov edi, dline;
add edi, y;
mov edi, [edi];
add edi, x;
mov ecx, w;
blitmasked16_loop:
mov dx, ds:[esi] /* source pixel */;
add esi, 2;
cmp dx, ax /* is transparent ? */;
je blitmasked16_skip;
mov es:[edi], dx;
blitmasked16_skip:
add edi, 2;
loop blitmasked16_loop;
add y, 4;
add sy, 4;
dec ebx;
jnz blitmasked16_w;
pop es;
}
}
// clear a rectangle area with the color
// clip will do its work
void BitmapHi::Clear( int l, int t, int w, int h, int color )
{
char **line = BitmapHi::line;
color = MakeColor( color );
if( clip ){
if( l < cl ){
w -= cl - l;
l = cl;
}
if( t < ct ){
h -= ct - t;
t = ct;
}
if( l + w > cr )
w = cr - l;
if( t + h > cb )
h = cb - t;
}
else{
if( l < 0 ){
w += l;
l = 0;
}
if( t < 0 ){
h += t;
t = 0;
}
if( l + w > width )
w = width - l;
if( t + h > height )
h = height - t;
}
__asm{
push es;
mov ax, ds;
mov es, ax;
mov eax, color;
mov ebx, eax;
shl eax, 16;
mov edx, t;
mov ax, bx;
mov ebx, h;
shl edx, 2;
cld;
mov esi, l;
shl esi, 1;
mov ecx, w;
shr ecx, 1;
jnc clear16_dw;
jz clear16_onew;
shr w, 1;
clear16_dww: /* n long + one word */
mov edi, line;
mov edi, [edi+edx];
add edi, esi;
mov ecx, w;
stosw;
repnz stosd;
add edx, 4;
dec ebx;
jnz clear16_dww;
jmp clear16_end;
;
clear16_onew: /* only one word */
mov edi, line;
mov edi, [edi+edx];
add edi, esi;
stosw;
add edx, 4;
dec ebx;
jnz clear16_onew;
jmp clear16_end;
clear16_dw: /* n long */
shr w, 1;
clear16_dwloop:
mov edi, line;
mov edi, [edi+edx];
add edi, esi;
mov ecx, w;
repnz stosd;
add edx, 4;
dec ebx;
jnz clear16_dwloop;
clear16_end:
pop es;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -