📄 brighter.cpp
字号:
#include <conio.h>
#include <time.h>
#include "gl.h"
#include "gengine.h"
#include "../common.h"
//////////////////////////////////////////////////////////////////////////////////
// 光影效果
#define MAX_LAMPS 32
int brighterInstalled = false;
// brightness是sight及其它光源(Lamp)合成后得到
// 大小为主画面的1/4,一个点代表主画面上四个点的亮度
Bitmap8 *brightness; // 320x176,合成后的亮度掩图
static Bitmap8 *sight; //320x176主角的视野
extern Cache cache;
void LampDrawMMX( Bitmap8 *src, int x, int y );
void LampDraw( Bitmap8 *src, int x, int y );
struct Lamp{ //光源
Bitmap8* light; //亮度掩图
int x, y; //光源位置
Lamp** reg;
void (*draw)( Bitmap8 *src, int x, int y );
Lamp();
inline void Draw( void ){ // 将lamp合成到birghtness
draw( this->light, x, y );
};
void Register( void ); //注册光源:将cache内光源添加到 lamp 中, 刷新cache时调用
void UnRegister( void );
};
Lamp* lamp[32]; // cache范围内的所有光源
Lamp::Lamp()
{
light = NULL;
x = y =0;
reg = NULL;
if( cpu.mmx )
draw = LampDrawMMX;
else
draw = LampDraw;
}
void Lamp::Register( void )
{
for( int i=0; i<MAX_LAMPS; i++ )
if( lamp[i] == NULL ){
lamp[i] = this;
reg = &( lamp[i] );
return;
}
}
void Lamp::UnRegister( void )
{
if( reg )
( *reg ) = NULL;
}
void LampDrawMMX( Bitmap8 *src, int x, int y )
{
int w = src->width;
int h = src->height;
int sx, sy;
x /= 2;
y /= 2;
if( x >= brightness->width || y >= brightness->height )
return;
if( x < 0 ){
sx = -x; x = 0; w -= sx;
if( w <= 0 ) return;
}
else sx = 0;
if( y < 0 ){
sy = -y; y=0; h -= sy;
if( h <= 0 ) return;
}
else sy = 0;
if( x + w > brightness->width )
w = brightness->width - x;
if( y + h > brightness->height )
h = brightness->height - y;
__asm{
mov eax, brightness;
mov ecx, src;
mov edi, [eax]Bitmap.line;
mov esi, [ecx]Bitmap.line;
mov ebx, y;
mov edx, sy;
shl ebx, 2;
shl edx, 2;
mov edi, [edi+ebx];
mov esi, [esi+edx];
mov ebx, w;
mov edx, ebx;
and ebx, 7;
shr edx, 3;
add edi, x;
add esi, sx;
movd mm4, ebx;
movd mm5, edx;
mov ebx, [ecx]Bitmap.pitch;
mov edx, [eax]Bitmap.pitch;
cld;
mov ecx, w;
sub ebx, ecx;
sub edx, ecx;
draw_loop:
movd ecx, mm4;
jecxz useMMX;
draw_head:
lodsb;
add al, [edi];
jnc not_overflow;
mov al, 0xff;
not_overflow:
stosb;
loop draw_head;
useMMX:
movd ecx, mm5;
jecxz end_of_draw;
MMXloop:
movq mm0, [edi];
paddusb mm0, [esi];
movq [edi], mm0;
add esi, 8;
add edi, 8;
loop MMXloop;
end_of_draw:
add esi, ebx;
add edi, edx;
dec h;
jnz draw_loop;
emms;
}
}
void LampDraw( Bitmap8 *src, int x, int y )
{
}
//-------------------------------------------------------------------------------------
static DWORD const brightdegree[8] = { 0x04210421, 0x04210421,
0x0c630c63, 0x0c630c63,
0x1ce71ce7, 0x1ce71ce7,
0x3def3def, 0x3def3def };
static void CopySightToBrightness( void )
{
if( sight->pitch == brightness->pitch ){
__asm{
mov eax, sight;
mov edx, brightness;
mov ebx, [eax]Bitmap.line;
mov ecx, [edx]Bitmap.line;
mov eax, 16;
mov esi, [ebx];
mov edi, [ecx];
mov ecx, WIN_WIDTH*WIN_HEIGHT/16/4;
ALIGN 4;
copy:
movq mm0, [esi];
movq mm1, [esi+8];
movq [edi], mm0;
add esi, eax;
movq [edi+8], mm1;
add edi, eax;
dec ecx;
jnz copy;
}
}
else{
__asm{
mov eax, sight;
mov ecx, WIN_WIDTH/16/2;
mov edx, brightness;
movd mm7, ecx;
mov ebx, [eax]Bitmap.line;
mov ecx, [edx]Bitmap.line;
mov esi, [ebx];
mov edi, [ecx];
mov ebx, WIN_HEIGHT/2;
mov eax, [eax]Bitmap.pitch;
mov edx, [edx]Bitmap.pitch;
sub eax, WIN_WIDTH/2;
sub edx, WIN_WIDTH/2;
mov ecx, WIN_WIDTH/16/2;
ALIGN 4;
copy_line:
movq mm0, [esi];
movq mm1, [esi+8];
movq [edi], mm0;
movq [edi+8], mm1;
add esi, 16;
add edi, 16;
dec ecx;
jnz copy_line;
//loop copy_line;
add esi, eax;
add edi, edx;
movd ecx, mm7;
dec ebx;
jnz copy_line;
emms;
}
}
}
int InitBrighter( void )
{
int i;
sight = ( Bitmap8* )LoadBmp( "bright.bmp", NULL );
if( sight == NULL || sight->colorDepth != 8
|| sight->width < WIN_WIDTH/2 ){
// delete brightness;
return -1;
}
brightness = ( Bitmap8* )CreateBitmapEx( WIN_WIDTH/2, WIN_HEIGHT/2, 8 );
if( brightness == NULL )
return -1;
sight->Blit( brightness, 0,0, 0,0,WIN_WIDTH/2, WIN_HEIGHT/2 );
for( i=0; i<MAX_LAMPS; i++ )
lamp[i] = NULL;
Lamp *lp = new Lamp;
lp->light = ( Bitmap8* )LoadBmp( "bright2.bmp", NULL );
lp->x = 0;
lp->y = 100;
lp->Register();
lp = new Lamp;
lp->light = lamp[0]->light;
lp->x = 640;
lp->y = -1;
lp->Register();
lp = new Lamp;
lp->light = lamp[0]->light;
lp->x = 0;
lp->y = 200;
lp->Register();
lp = new Lamp;
lp->light = lamp[0]->light;
lp->x = 400;
lp->y = 200;
lp->Register();
if( lp->reg == NULL )
return -1;
brighterInstalled = true;
return 0;
}
void CopyGroundBrightnessMMX( int sx, int sy )
{
char **bline = brightness->line;
char **sline = cache.ground->line;
char **dline = backScreen->line;
int bpitch = brightness->pitch - WIN_WIDTH/2;
int dpitch = backScreen->pitch;
int spitch = cache.ground->pitch;
int lines = WIN_HEIGHT/2;
if( sx < 0 || sy < 0 || sx > WIN_WIDTH || sy > WIN_HEIGHT )
return;
// cache.ground->Blit( backScreen, 0,0, sx,sy, 640,352 );
// return;
CopySightToBrightness();
// return;
/* for( int i=0; i<MAX_LAMPS; i++ )
if( lamp[i] )
lamp[i]->Draw();
*/
__asm{
lea eax, colorMask;
xor ebx, ebx;
movq mm4, [eax]; /* red */
movq mm5, [eax+8]; /* green */
movq mm6, [eax+16]; /* blue */
shl sx, 1;
shl sy, 2;
mov ebx, sline;
mov ecx, dline;
mov eax, bline;
add ebx, sy;
mov edi, [ecx];
mov esi, [ebx];
mov ebx, [eax];
mov ecx, 160;
add esi, sx;
mov edx, dpitch;
mov eax, spitch;
ALIGN 4;
copy_line:
// test ecx, 1;
movq mm1, [esi];
// jnz shift_mm7;
pxor mm7, mm7;
movd mm0, [ebx];
movq mm2, mm1;
punpcklbw mm0, mm7;
inc ebx;
movq mm7, mm0;
// jmp mm0_ready;
//shift_mm7:
// psrlq mm7, 32;
// movq mm2, mm1;
// movq mm0, mm7;
//mm0_ready:
movq mm3, mm1;
punpcklwd mm0, mm7;
pand mm3, mm6;
psrlw mm0, 3;
pand mm2, mm5;
pmullw mm3, mm0;
psrlw mm2, 5;
pand mm1, mm4;
pmullw mm2, mm0;
psrlw mm1, 5;
pand mm2, mm5;
psrlw mm3, 5;
pmullw mm1, mm0;
por mm2, mm3;
pand mm1, mm4;
movq mm3, [esi+eax];
por mm1, mm2;
movq [edi], mm1;
movq mm2, mm3;
movq mm1, mm3;
//add ebx, 2;
inc ebx;
pand mm3, mm6;
pand mm2, mm5;
pmullw mm3, mm0;
psrlw mm2, 5;
pand mm1, mm4;
pmullw mm2, mm0;
psrlw mm1, 5;
pand mm2, mm5;
psrlw mm3, 5;
pmullw mm1, mm0;
por mm2, mm3;
pand mm1, mm4;
add esi, 8;
por mm1, mm2;
movq [edi+edx], mm1;
add edi, 8;
dec ecx;
jnz copy_line;
mov ecx, 160;
add ebx, bpitch;
add esi, eax;
add edi, edx;
add esi, eax;
add edi, edx;
sub esi, 1280;
sub edi, 1280;
dec lines;
jnz copy_line;
emms;
}
}
int testBrighter( void )
{
#ifdef _DEBUG
// OutDebugString( " in testBrighter" );
#endif
int i=0;
CopyGroundBrightnessMMX( i, 0 );
lamp[0]->x += 6;
lamp[1]->x -= 6;
if( lamp[0]->x > 640 )
lamp[0]->x = -160;
if( lamp[1]->x < -160 )
lamp[1]->x = 640;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -