📄 draw.cpp
字号:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include "graphics.h"
// 设置当前绘图笔坐标
void set_draw_xy(BMP *bmp, int x, int y)
{
put_message(bmp == NULL,
"错误,企图对不存在的位图进行操作。");
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV eax, x; // 剪裁
CMP eax, [ebx]BMP.clipleft;
JL _NULL;
CMP eax, [ebx]BMP.clipright;
JG _NULL;
MOV eax, y;
CMP eax, [ebx]BMP.cliptop;
JL _NULL;
CMP eax, [ebx]BMP.clipbottom;
JG _NULL;
MOV edi, [ebx]BMP.bit;
CMP [ebx]BMP.draw_ptr, 0;
JE _normal;
JMP _offset;
// 普通的设置指针
_normal:
MOV eax, y;
IMUL [ebx]BMP.pitch_byte;
ADD eax, x;
ADD eax, x;
ADD edi, eax;
MOV [ebx]BMP.draw_ptr, edi;
JMP _pixel_end;
_offset:
// x > draw_x
MOV eax, x;
CMP eax, [ebx]BMP.draw_x;
JG _x_draw_x;
MOV ecx, [ebx]BMP.draw_x;
SUB ecx, eax;
SAL ecx, 1;
SUB edi, ecx;
MOV [ebx]BMP.draw_ptr, edi;
JMP _offset_y;
_x_draw_x:
SUB eax, [ebx]BMP.draw_x;
SAL eax, 1;
ADD edi, eax;
MOV [ebx]BMP.draw_ptr, edi;
_offset_y:
// y > draw_y
MOV eax, y;
CMP eax, [ebx]BMP.draw_y;
JG _y_draw_y;
JL _y_draw_y_;
JMP _pixel_end;
_y_draw_y_:
MOV ecx, [ebx]BMP.draw_y;
SUB ecx, eax;
MOV eax, ecx;
IMUL [ebx]BMP.pitch_byte;
SUB edi, eax;
MOV [ebx]BMP.draw_ptr, edi;
JMP _offset_y;
_y_draw_y:
SUB eax, [ebx]BMP.draw_y;
IMUL [ebx]BMP.pitch_byte;
ADD edi, eax;
MOV [ebx]BMP.draw_ptr, edi;
JMP _pixel_end;
_NULL:
MOV [ebx]BMP.draw_ptr, 0;
_pixel_end:
POP edi;
}
}
// 在位图上画点(普通)
void pixel_normal(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, color;
MOV [edi], dx;
POP edi;
}
}
// 在位图上画点(OR)
void pixel_or(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, [edi];
OR dx, color;
MOV [edi], dx;
POP edi;
}
}
// 在位图上画点(XOR)
void pixel_xor(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, [edi];
XOR dx, color;
MOV [edi], edx;
POP edi;
}
}
// 在位图上画点(AND)
void pixel_and(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, [edi];
AND dx, color;
MOV [edi], dx;
POP edi;
}
}
// 在位图上画点(NOT)
void pixel_not(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
NOT color;
MOV dx, color;
MOV [edi], dx;
POP edi;
}
}
// 在位图上画点(Alpha一级)
void pixel_alpha_1(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
MOV bx, ax;
SHR bx, 3;
AND bx, alpha125mask;
SUB ax, bx;
MOV bx, [edi];
SHR bx, 3;
AND bx, alpha125mask;
ADD ax, bx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha二级)
void pixel_alpha_2(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
MOV bx, ax;
SHR bx, 2;
AND bx, alpha25mask;
SUB ax, bx;
MOV bx, [edi];
SHR bx, 2
AND bx, alpha25mask;
ADD ax, bx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha三级)
void pixel_alpha_3(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
MOV bx, [edi];
SHR bx, 2;
SHR ax, 2;
AND bx, alpha25mask;
AND ax, alpha25mask;
ADD bx, ax; // (1/4)(ax+bx)
MOV dx, bx;
SHR bx, 1; // (1/8)(ax+bx)
ADD ax, dx;
AND bx, alpha50mask_2;
ADD ax, bx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha四级)
void pixel_alpha_4(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, [edi];
MOV bx, color;
AND ax, alpha50mask;
AND bx, alpha50mask;
ADD ax, bx;
RCR ax, 1;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha五级)
void pixel_alpha_5(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
MOV bx, [edi];
SHR ax, 2;
SHR bx, 2;
AND ax, alpha25mask;
AND bx, alpha25mask;
ADD ax, bx; // (1/4)(eax+ebx)
MOV dx, ax;
SHR ax, 1; // (1/8)(eax+ebx)
ADD dx, bx;
AND ax, alpha50mask_2;
ADD ax, dx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha六级)
void pixel_alpha_6(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
SHR ax, 2;
MOV bx, [edi];
AND ax, alpha25mask;
ADD ax, bx;
SHR bx, 2;
AND bx, alpha25mask;
SUB ax, bx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Alpha七级)
void pixel_alpha_7(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
// 开始混合
MOV ax, color;
SHR ax, 3;
MOV bx, [edi];
AND ax, alpha125mask;
ADD ax, bx;
SHR bx, 3;
AND bx, alpha125mask;
SUB ax, bx;
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Additive_565)
void pixel_additive_565(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, 0xf7df; // 1111 0111 1101 1111
// 开始混合
MOV ax, [edi];
MOV bx, color;
AND ax, dx; // 0111 0111 1101 1111
AND bx, dx;
ADC ax, bx;
JNC _rnc;
OR ax, 0xf000;
_rnc:
TEST ax, 0x20; // 10 0000
JZ _bnc;
OR ax, 0x1f;
_bnc:
TEST ax, 0x800; // 1000 0000 0000
JZ _gnc;
OR ax, 0x7e0; // 111 1110 0000
_gnc:
MOV [edi], ax;
// 混合结束
POP edi;
}
}
// 在位图上画点(Additive_555)
void pixel_additive_555(BMP *bmp, int x, int y, WORD color)
{
set_draw_xy(bmp, x, y);
if (bmp->draw_ptr == NULL)
return;
_asm
{
PUSH edi;
MOV ebx, bmp;
MOV edi, [ebx]BMP.draw_ptr;
MOV dx, 0x7bdf; // 1111 0111 1101 1111
// 开始混合
MOV ax, [edi];
MOV bx, color;
AND ax, dx; // 0111 0111 1101 1111
AND bx, dx;
ADD ax, bx;
TEST ax, 0x20; // 10 0000
JZ _bnc;
OR ax, 0x1f;
_bnc:
TEST ax, 0x400; // 100 0000 0000
JZ _gnc;
OR ax, 0x3e0;
_gnc:
BTR ax, 15;
JNC _rnc;
OR ax, 0x7c00;
_rnc:
MOV [edi], ax;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -