【源码备份】win32 asm水波特效源码(by 罗云彬)

来源:互联网 发布:c语言各种符号含义 编辑:程序博客网 时间:2024/06/05 14:48
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 水波效果公用子程序 ; by 罗云彬,http://asm.yeah.net,luoyunbin@sina.com ; V 1.0.041019 --- 初始版本 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 在源代码中只需要 include WaveObject.asm ; 然后按以下步骤调用即可: ;******************************************************************** ; 1、创建水波对象: ;    要对一个窗口进行绘画,首先要创建一个水波对象(本函数申请一些缓冲区) ;    invoke _WaveInit, lpWaveObject, hWnd, hBmp, dwTime, dwType ;       lpWaveObject --> 指向一个空的 WAVE_OBJECT 结构 ;       hWnd --> 要绘画水波效果的窗口,渲染后的图片将画到窗口的客户区中 ;       hBmp --> 背景图片,绘画的范围大小同背景图片大小 ;       dwTime --> 刷新的时间间隔(毫秒),建议值:10~30 ;dwType --> =0 表示圆形水波,=1表示椭圆型水波(用于透视效果) ;       返回值:eax = 0(成功,对象被初始化),eax = 1(失败) ;******************************************************************** ; 2、如果 _WaveInit 函数返回成功,则对象被初始化,将对象传给下列各种函数 ;    可以实现各种效果,下面函数中的 lpWaveObject 参数指向在 _WaveInit 函数 ;    中初始化的 WAVE_OBJECT 结构 ; ;    ◎ 在指定位置“扔石头”,激起水波 ;       invoke _WaveDropStone, lpWaveObject, dwPosX, dwPosY, dwStoneSize, dwStoneWeight ;          dwPosX, dwPosY --> 扔下石头的位置 ;          dwStoneSize --> 石头的大小,即初始点的大小,建议值:0~5;          dwStoneWeight --> 石头的重量,决定了波最后扩散的范围大小,建议值:10~1000 ; ;    ◎ 自动显示特效 ;       invoke _WaveEffect, lpWaveObject, dwEffectType, dwParam1, dwParam2, dwParam3 ;          dwParam1, dwParam2, dwParam3 --> 效果参数,对不同的特效类型参数含义不同 ;          dwEffectType --> 特效类型 ;             0 --> 关闭特效 ;             1 --> 下雨,Param1=密集速度(0最密,越大越稀疏),建议值:0~30 ;                         Param2=最大雨点直径,建议值:0~5 ;                         Param3=最大雨点重量,建议值:50~250 ;             2 --> 汽艇,Param1=速度(0最慢,越大越快),建议值:0~8 ;                         Param2=船大小,建议值:0~4 ;                         Param3=水波扩散的范围,建议值:100~500 ;             3 --> 风浪,Param1=密度(越大越密),建议值:50~300 ;                         Param2=大小,建议值:2~5 ;                         Param3=能量,建议值:5~10 ; ;    ◎ 窗口客户区强制更新(用于在窗口的WM_PAINT消息中强制更新客户端) ;       .if     uMsg == WM_PAINT ;               invoke  BeginPaint, hWnd, addr @stPs ;               mov     @hDc, eax ;               invoke  _WaveUpdateFrame, lpWaveObject, eax, TRUE ;               invoke  EndPaint, hWnd, addr @stPs ;               xor     eax, eax ;               ret ;******************************************************************** ; 3、释放水波对象: ;    使用完毕后,必须将水波对象释放(本函数将释放申请的缓冲区内存等资源) ;       invoke  _WaveFree, lpWaveObject ;       lpWaveObject --> 指向 WAVE_OBJECT 结构 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 实现上的细节说明: ; ; 1、 水波的特征: ;   ◎ 扩散:每一点的波会扩散到其四周的位置中 ;   ◎ 衰减:每次扩散会损失少量能量(否则水波会永不停止的震荡下去) ; ; 2、 为了保存两个时刻中的能量分步图,对象中定义2个缓冲区Wave1和Wave2 ;  (保存在lpWave1和lpWave2指向的缓冲区内),Wave1为当前数据,Wave2为 ;   上一帧的数据,每次渲染时将根据上面的2个特征,由Wave1的数据计算出新 ;   能量分别图后,保存到Wave2中,然后调换Wave1和Wave2,这时Wave1仍是最 ;   新的数据。 ;      计算的方法为,某个点的能量=点四周的上次能量的平均值 * 衰减系数 ;   取四周的平均值表现了扩展特征,乘以衰减系数表现了衰减特征。 ;      这部分代码在 _WaveSpread 子程序中实现。 ; ; 3、 对象在 lpDIBitsSource 中保存了原始位图的数据,每次渲染时,由原始 ;   位图的数据根据Wave1中保存的能量分步数据产生新的位图。从视觉上看,;   某个点的能量越大(水波越大),则光线折射出越远处的场景。 ;      算法为:对于点(x, y),在Wave1中找出该点,计算出相邻点的波能差 ;  (Dx和Dy两个数据),则新位图像素(x, y)=原始位图像素(x+Dx, y+Dy),;   该算法表现了能量大小影响了像素折射的偏移大小。 ;      这部分代码在 _WaveRender 子程序中实现。 ; ; 4、 扔石头的算法很好理解,即将Wave1中的某个点的能量值置为非0值,数值 ;   越大,表示扔下的石头的能量越大。石头比较大,则将该点四周的点全部 ;   置为非0值。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ; ; ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .386 .model flat,  stdcall option casemap: none includewindows.inc includeuser32.inc includelibuser32.lib includekernel32.inc includelibkernel32.lib includeGdi32.inc includelibGdi32.lib ;头文件卫士ifndefWAVEOBJ_INC WAVEOBJ_INCequ1 ;--------------------------------------------------------------------------------;等值定义F_WO_ACTIVEequ0001h F_WO_NEED_UPDATEequ0002h F_WO_EFFECTequ0004h F_WO_ELLIPSEequ0008h ;--------------------------------------------------------------------------------;水波类;--------------------------------------------------------------------------------WAVE_OBJECTstruct hWnddd? dwFlagdd?; 见 F_WO_xxx 组合 ;--------------------------------------------------------------------------------hDcRenderdd? hBmpRenderdd? lpDIBitsSourcedd?; 原始像素数据 lpDIBitsRenderdd?; 用于显示到屏幕的像素数据 lpWave1dd?; 水波能量数据缓冲1 lpWave2dd?; 水波能量数据缓冲2 ;--------------------------------------------------------------------------------dwBmpWidthdd? dwBmpHeightdd? dwDIByteWidthdd?; = (dwBmpWidth * 3 + 3) and ~3 dwWaveByteWidthdd?; = dwBmpWidth * 4 dwRandomdd? ;--------------------------------------------------------------------------------; 特效参数 ;--------------------------------------------------------------------------------dwEffectTypedd? dwEffectParam1dd? dwEffectParam2dd? dwEffectParam3dd? ;--------------------------------------------------------------------------------; 用于行船特效 ;--------------------------------------------------------------------------------dwEff2Xdd? dwEff2Ydd? dwEff2XAdddd? dwEff2YAdddd? dwEff2Flipdd? ;--------------------------------------------------------------------------------stBmpInfoBITMAPINFO <> WAVE_OBJECTends ;-------------------------------------------------------------------------------- .code ;--------------------------------------------------------------------------------; dll 入口点;--------------------------------------------------------------------------------DllEntryproc_hInstance, _dwReason, _dwReservedmoveax, TRUE;仅仅返回TRUEretDllEntryEndp;--------------------------------------------------------------------------------; 随机数产生子程序 ; 输入:要产生的随机数的最大值,输出:随机数 ; 根据: ; 1. 数学公式 Rnd=(Rnd*I+J) mod K 循环回带生成 K 次以内不重复的 ;    伪随机数,但K, I, J必须为素数 ; 2. 2^(2n-1)-1 必定为素数(即2的奇数次方减1) ;--------------------------------------------------------------------------------_WaveRandom16proc_lpWaveObject  movebx, _lpWaveObject assumeebx:ptr WAVE_OBJECT pushedx pushecx moveax, [ebx].dwRandom movecx, 32768-1;2^15-1 mulecx addeax, 2048-1;2^11-1 adcedx, 0 movecx, 2147483647;2^31-1 divecx moveax, [ebx].dwRandom mov[ebx].dwRandom, edx andeax, 0000ffffh popecx popedx ret  _WaveRandom16endp ;--------------------------------------------------------------------------------_WaveRandomprocuses ebx ecx edx _lpWaveObject, _dwMax  invoke_WaveRandom16, _lpWaveObject movedx, eax invoke_WaveRandom16, _lpWaveObject shleax, 16 orax, dx movecx, _dwMax orecx, ecx jz@F xoredx, edx divecx moveax, edx @@: ret  _WaveRandomendp ;--------------------------------------------------------------------------------; 波能扩散 ; 算法: ; Wave2(x, y) = (Wave1(x+1, y)+Wave1(x-1, y)+Wave1(x, y+1)+Wave1(x, y-1))/2-Wave2(x, y) ; Wave2(x, y) = Wave2(x, y) - Wave2(x, y) >> 5 ; xchg Wave1, Wave2 ;--------------------------------------------------------------------------------_WaveSpreadproc_lpWaveObject  pushad movebx, _lpWaveObject assumeebx:ptr WAVE_OBJECT ;--------------------------------------------------------------------------------test[ebx].dwFlag, F_WO_ACTIVE jz_Ret  movesi, [ebx].lpWave1 movedi, [ebx].lpWave2 movecx, [ebx].dwBmpWidth  moveax, [ebx].dwBmpHeight deceax mulecx ;--------------------------------------------------------------------------------; ebx = width ; ecx = i,eax = max ;--------------------------------------------------------------------------------.whileecx < eax pusheax .if[ebx].dwFlag & F_WO_ELLIPSE movedx, [esi+ecx*4-1*4] addedx, [esi+ecx*4+1*4] addedx, [esi+ecx*4-2*4] addedx, [esi+ecx*4+2*4] leaedx, [edx+edx*2] addedx, [esi+ecx*4-3*4] addedx, [esi+ecx*4-3*4] addedx, [esi+ecx*4+3*4] addedx, [esi+ecx*4+3*4]  leaeax, [esi+ecx*4] subeax, [ebx].dwWaveByteWidth moveax, [eax] shleax, 3 addedx, eax  leaeax, [esi+ecx*4] addeax, [ebx].dwWaveByteWidth moveax, [eax] shleax, 3 addedx, eax  saredx, 4 subedx, [edi+ecx*4]  moveax, edx sareax, 5 subedx, eax  mov[edi+ecx*4], edx .else movedx, [esi+ecx*4-1*4] addedx, [esi+ecx*4+1*4]  leaeax, [esi+ecx*4] subeax, [ebx].dwWaveByteWidth addedx, [eax]  leaeax, [esi+ecx*4] addeax, [ebx].dwWaveByteWidth addedx, [eax]  saredx, 1 subedx, [edi+ecx*4]  moveax, edx sareax, 5 subedx, eax  mov[edi+ecx*4], edx .endif popeax incecx .endw  mov[ebx].lpWave1, edi mov[ebx].lpWave2, esi _Ret: ;--------------------------------------------------------------------------------assumeebx:nothing popad ret  _WaveSpreadendp ;--------------------------------------------------------------------------------; esi -> edi,  ecx = line width ; return = (4*Pixel(x, y)+3*Pixel(x-1, y)+3*Pixel(x+1, y)+3*Pixel(x, y+1)+3*Pixel(x, y-1))/16 ;--------------------------------------------------------------------------------_WaveGetPixel: movzxeax, byte ptr [esi] shleax, 2 movzxedx, byte ptr [esi+3] leaedx, [edx+2*edx] addeax, edx movzxedx, byte ptr [esi-3] leaedx, [edx+2*edx] addeax, edx movzxedx, byte ptr [esi+ecx] leaedx, [edx+2*edx] addeax, edx movedx, esisubedx, ecx movzxedx, byte ptr [edx] leaedx, [edx+2*edx] addeax, edx shreax, 4 mov[edi], al incesi incedi ret ;--------------------------------------------------------------------------------; 渲染子程序,将新的帧数据渲染到 lpDIBitsRender 中 ; 算法: ; posx = Wave1(x-1, y)-Wave1(x+1, y)+x ; posy = Wave1(x, y-1)-Wave1(x, y+1)+y ; SourceBmp(x, y) = DestBmp(posx, posy) ;--------------------------------------------------------------------------------_WaveRender    proc    _lpWaveObjectlocal    @dwPosX, @dwPosY, @dwPtrSource, @dwFlagpushadxor    eax, eaxmov    @dwFlag, eaxmov    ebx, _lpWaveObjectassume    ebx:ptr WAVE_OBJECTtest    [ebx].dwFlag, F_WO_ACTIVEjz    _Retor    [ebx].dwFlag, F_WO_NEED_UPDATEmov    esi, [ebx].lpWave1mov    edi, [ebx].dwWaveByteWidth    ; edi = 像素指针xor    ecx, ecxinc    ecx        ; ecx=i  --  i=1; i<height; i++_Loop1:xor    edx, edx        ; edx=j  --  j=0; j<width; j++_Loop2:push    edx;--------------------------------------------------------------------------------; PosY=i+像素上1能量-像素下1能量; PosX=j+像素左1能量-像素右1能量;--------------------------------------------------------------------------------mov    eax, edisub    eax, [ebx].dwWaveByteWidthmov    eax, [esi+eax]mov    @dwPosY, eaxmov    eax, [ebx].dwWaveByteWidthlea    eax, [edi+eax]mov    eax, [esi+eax]sub    @dwPosY, eaxadd    @dwPosY, ecxmov    eax, [esi+edi-4]sub    eax, [esi+edi+4]add    eax, edx            ;@dwPosX = eaxmov    @dwPosX, eaxcmp    eax, 0jl    _Continuecmp    eax, [ebx].dwBmpWidthjge    _Continuemov    eax, @dwPosYcmp    eax, 0jl    _Continuecmp    eax, [ebx].dwBmpHeightjge    _Continue;--------------------------------------------------------------------------------; ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3; ptrDest = i * dwDIByteWidth + j * 3;--------------------------------------------------------------------------------mov    eax, @dwPosXlea    eax, [eax+eax*2]mov    @dwPosX, eaxpush    edxmov    eax, @dwPosYmul    [ebx].dwDIByteWidthadd    eax, @dwPosXmov    @dwPtrSource, eaxmov    eax, ecxmul    [ebx].dwDIByteWidthpop    edxlea    edx, [edx+edx*2]add    eax, edx            ;@dwPtrDest = eax;--------------------------------------------------------------------------------; 渲染像素 [ptrDest] = 原始像素 [ptrSource];--------------------------------------------------------------------------------pushadmov    ecx, @dwPtrSourcemov    esi, [ebx].lpDIBitsSourcemov    edi, [ebx].lpDIBitsRenderlea    esi, [esi+ecx]lea    edi, [edi+eax].if    ecx !=    eaxor    @dwFlag, 1    ;如果存在源像素和目标像素不同,则表示还在活动状态mov    ecx, [ebx].dwDIByteWidthcall    _WaveGetPixelcall    _WaveGetPixelcall    _WaveGetPixel.elsecldmovswmovsb.endifpopad;--------------------------------------------------------------------------------; 继续循环;--------------------------------------------------------------------------------_Continue:pop    edxinc    edxadd    edi, 4        ; 像素++cmp    edx, [ebx].dwBmpWidthjb    _Loop2inc    ecxmov    eax, [ebx].dwBmpHeightdec    eaxcmp    ecx, eaxjb    _Loop1;--------------------------------------------------------------------------------; 将渲染的像素数据拷贝到 hDc 中;--------------------------------------------------------------------------------invoke    SetDIBits, [ebx].hDcRender, [ebx].hBmpRender, 0, [ebx].dwBmpHeight, \[ebx].lpDIBitsRender, addr [ebx].stBmpInfo, DIB_RGB_COLORS.if    ! @dwFlagand    [ebx].dwFlag, not F_WO_ACTIVE.endif_Ret:;--------------------------------------------------------------------------------assume    ebx:nothingpopadret_WaveRender    endp_WaveUpdateFrameproc_lpWaveObject, _hDc, _bIfForce pushad movebx, _lpWaveObject assumeebx: ptr WAVE_OBJECT  cmp_bIfForce, 0 jnz@F.if[ebx].dwFlag & F_WO_NEED_UPDATE @@: invokeBitBlt, _hDc, 0, 0, [ebx].dwBmpWidth, [ebx].dwBmpHeight, \ [ebx].hDcRender, 0, 0, SRCCOPY and[ebx].dwFlag, not F_WO_NEED_UPDATE .endif  assumeebx:nothingpopadret  _WaveUpdateFrameendp ;--------------------------------------------------------------------------------; 扔一块石头 ;--------------------------------------------------------------------------------_WaveDropStoneproc_lpWaveObject, _dwX, _dwY, _dwSize, _dwWeight local@dwMaxX, @dwMaxY  pushad movebx, _lpWaveObject assumeebx:ptr WAVE_OBJECT ;--------------------------------------------------------------------------------; 计算范围 ;--------------------------------------------------------------------------------movedx, _dwSize shredx, 1  moveax, _dwX movesi, _dwY  movecx, eax movedi, esi addeax, edx; x + size subecx, edx; x - size  pushedx .if[ebx].dwFlag & F_WO_ELLIPSE shredx, 1 .endif addesi, edx; y + size subedi, edx; y - size popedx  shledx, 1 .if! edx incedx .endif mov_dwSize, edx ;--------------------------------------------------------------------------------; 判断范围的合法性 ;--------------------------------------------------------------------------------inceax cmpeax, [ebx].dwBmpWidth jge_Ret cmpecx, 1 jl_Ret incesi cmpesi, [ebx].dwBmpHeight jge_Ret cmpedi, 1 jl_Ret  deceax decesi ;--------------------------------------------------------------------------------; 将范围内的点的能量置为 _dwWeight ;--------------------------------------------------------------------------------mov@dwMaxX, eax mov@dwMaxY, esi .whileecx <=@dwMaxX pushedi .whileedi <=@dwMaxY moveax, ecx subeax, _dwX imuleax pusheax moveax, edi subeax, _dwY imuleax popedx addeax, edx pusheax moveax, _dwSize imuleax popedx .ifedx <=eax moveax, edi mul[ebx].dwBmpWidth addeax, ecx shleax, 2 addeax, [ebx].lpWave1 push_dwWeight pop[eax] .endif incedi .endw popedi incecx .endw or[ebx].dwFlag, F_WO_ACTIVE ;--------------------------------------------------------------------------------_Ret: assumeebx:nothing popad ret  _WaveDropStoneendp ;--------------------------------------------------------------------------------; 计算扩散数据、渲染位图、更新窗口、处理特效的定时器过程 ;--------------------------------------------------------------------------------_WaveTimerProcproc_hWnd, _uMsg, _idEvent, _dwTime  pushad movebx, _idEvent assumeebx:ptr WAVE_OBJECT  invoke_WaveSpread, ebx invoke_WaveRender, ebx .if[ebx].dwFlag & F_WO_NEED_UPDATE invokeGetDC, [ebx].hWnd invoke_WaveUpdateFrame, ebx, eax, FALSE invokeReleaseDC, [ebx].hWnd, eax .endif ;--------------------------------------------------------------------------------; 特效处理 ;--------------------------------------------------------------------------------test[ebx].dwFlag, F_WO_EFFECT jz_Ret moveax, [ebx].dwEffectType ;--------------------------------------------------------------------------------; Type = 1 雨点,Param1=速度(0最快,越大越慢),Param2=雨点大小,Param3=能量 ;--------------------------------------------------------------------------------.ifeax ==1 moveax, [ebx].dwEffectParam1 oreax, eax jz@F invoke_WaveRandom, ebx, eax .if! eax @@: moveax, [ebx].dwBmpWidth deceax deceax invoke_WaveRandom, ebx, eax inceax movecx, eax  moveax, [ebx].dwBmpHeight deceax deceax invoke_WaveRandom, ebx, eax inceax movedx, eax  invoke_WaveRandom, ebx, [ebx].dwEffectParam2 inceax movesi, eax invoke_WaveRandom, ebx, [ebx].dwEffectParam3 addeax, 50 invoke_WaveDropStone, ebx, ecx, edx, esi, eax .endif ;--------------------------------------------------------------------------------; Type = 2 行船,Param1=速度(0最快,越大越快),Param2=大小,Param3=能量 ;--------------------------------------------------------------------------------.elseifeax ==2 inc[ebx].dwEff2Flip test[ebx].dwEff2Flip, 1 jnz_Ret  movecx, [ebx].dwEff2X movedx, [ebx].dwEff2Y addecx, [ebx].dwEff2XAdd addedx, [ebx].dwEff2YAdd  cmpecx, 1 jge@F subecx, 1 negecx neg[ebx].dwEff2XAdd @@: cmpedx, 1 jge@F subedx, 1 negedx neg[ebx].dwEff2YAdd @@: moveax, [ebx].dwBmpWidth deceax cmpecx, eax jl@F subecx, eax xchgeax, ecx subecx, eax neg[ebx].dwEff2XAdd @@: moveax, [ebx].dwBmpHeight deceax cmpedx, eax jl@F subedx, eax xchgeax, edx subedx, eax neg[ebx].dwEff2YAdd @@: mov[ebx].dwEff2X, ecx mov[ebx].dwEff2Y, edx invoke_WaveDropStone, ebx, ecx, edx, [ebx].dwEffectParam2, [ebx].dwEffectParam3 ;--------------------------------------------------------------------------------; Type = 3 波浪,Param1=密度,Param2=大小,Param3=能量 ;--------------------------------------------------------------------------------.elseifeax ==3 xoredi, edi .whileedi <=[ebx].dwEffectParam1 moveax, [ebx].dwBmpWidth deceax deceax invoke_WaveRandom, ebx, eax inceax movecx, eax  moveax, [ebx].dwBmpHeight deceax deceax invoke_WaveRandom, ebx, eax inceax movedx, eax  invoke_WaveRandom, ebx, [ebx].dwEffectParam2 inceax movesi, eax invoke_WaveRandom, ebx, [ebx].dwEffectParam3 invoke_WaveDropStone, ebx, ecx, edx, esi, eax incedi .endw .endif _Ret: assumeebx:nothing popad ret  _WaveTimerProcendp ;--------------------------------------------------------------------------------; 释放对象 ;--------------------------------------------------------------------------------_WaveFreeproc_lpWaveObject  pushad movebx, _lpWaveObject assumeebx:ptr WAVE_OBJECT ;--------------------------------------------------------------------------------.if[ebx].hDcRender invokeDeleteDC, [ebx].hDcRender .endif .if[ebx].hBmpRender invokeDeleteObject, [ebx].hBmpRender .endif .if[ebx].lpDIBitsSource invokeGlobalFree, [ebx].lpDIBitsSource .endif .if[ebx].lpDIBitsRender invokeGlobalFree, [ebx].lpDIBitsRender .endif .if[ebx].lpWave1 invokeGlobalFree, [ebx].lpWave1 .endif .if[ebx].lpWave2 invokeGlobalFree, [ebx].lpWave2 .endif invokeKillTimer, [ebx].hWnd, ebx invokeRtlZeroMemory, ebx, sizeof WAVE_OBJECT ;--------------------------------------------------------------------------------assumeebx:nothing popad ret  _WaveFreeendp ;--------------------------------------------------------------------------------; 初始化对象 ; 参数:_lpWaveObject = 指向 WAVE_OBJECT的指针 ; 返回:eax = 0 成功、= 1 失败 ;--------------------------------------------------------------------------------_WaveInitproc_lpWaveObject, _hWnd, _hBmp, _dwSpeed, _dwType local@stBmp:BITMAP, @dwReturn  pushad xoreax, eax mov@dwReturn, eax movebx, _lpWaveObjectassumeebx:ptr WAVE_OBJECTinvokeRtlZeroMemory, ebx, sizeof WAVE_OBJECT  .if_dwType or[ebx].dwFlag, F_WO_ELLIPSE .endif ;--------------------------------------------------------------------------------; 获取位图尺寸 ;--------------------------------------------------------------------------------push_hWndpop[ebx].hWndinvokeGetTickCount mov[ebx].dwRandom, eax  invokeGetObject, _hBmp, sizeof BITMAP, addr @stBmp.if!eax@@:inc@dwReturnjmp_Ret.endif moveax, @stBmp.bmHeight mov[ebx].dwBmpHeight, eax cmpeax, 3 jle@Bmoveax, @stBmp.bmWidth mov[ebx].dwBmpWidth, eax cmpeax, 3 jle@B pusheax shleax, 2 mov[ebx].dwWaveByteWidth, eax popeax leaeax, [eax+eax*2] addeax, 3 andeax, not 0011b mov[ebx].dwDIByteWidth, eax ;--------------------------------------------------------------------------------; 创建用于渲染的位图 ;--------------------------------------------------------------------------------invokeGetDC, _hWnd movesi, eax invokeCreateCompatibleDC, esi mov[ebx].hDcRender, eax invokeCreateCompatibleBitmap, esi, [ebx].dwBmpWidth, [ebx].dwBmpHeight mov[ebx].hBmpRender, eax invokeSelectObject, [ebx].hDcRender, eax ;--------------------------------------------------------------------------------; 分配波能缓冲区 ;--------------------------------------------------------------------------------moveax, [ebx].dwWaveByteWidth mul[ebx].dwBmpHeight movedi, eax invokeGlobalAlloc, GPTR, edi mov[ebx].lpWave1, eax invokeGlobalAlloc, GPTR, edi mov[ebx].lpWave2, eax ;--------------------------------------------------------------------------------; 分配像素缓冲区 ;--------------------------------------------------------------------------------moveax, [ebx].dwDIByteWidth mul[ebx].dwBmpHeight movedi, eax invokeGlobalAlloc, GPTR, edi mov[ebx].lpDIBitsSource, eax invokeGlobalAlloc, GPTR, edi mov[ebx].lpDIBitsRender, eax ;--------------------------------------------------------------------------------; 获取原始像素数据 ;--------------------------------------------------------------------------------mov[ebx].stBmpInfo.bmiHeader.biSize, sizeof BITMAPINFOHEADER push[ebx].dwBmpWidth pop[ebx].stBmpInfo.bmiHeader.biWidth moveax, [ebx].dwBmpHeight negeax mov[ebx].stBmpInfo.bmiHeader.biHeight, eax inc[ebx].stBmpInfo.bmiHeader.biPlanes mov[ebx].stBmpInfo.bmiHeader.biBitCount, 24 mov[ebx].stBmpInfo.bmiHeader.biCompression, BI_RGB mov[ebx].stBmpInfo.bmiHeader.biSizeImage, 0  invokeCreateCompatibleDC, esi pusheax invokeSelectObject, eax, _hBmp invokeReleaseDC, _hWnd, esi popeax movesi, eax  invokeGetDIBits, esi, _hBmp, 0, [ebx].dwBmpHeight, [ebx].lpDIBitsSource, \ addr [ebx].stBmpInfo, DIB_RGB_COLORS invokeGetDIBits, esi, _hBmp, 0, [ebx].dwBmpHeight, [ebx].lpDIBitsRender, \ addr [ebx].stBmpInfo, DIB_RGB_COLORS invokeDeleteDC, esi  .if![ebx].lpWave1 || ![ebx].lpWave2 || ![ebx].lpDIBitsSource ||\ ![ebx].lpDIBitsRender || ![ebx].hDcRender invoke_WaveFree, ebx inc@dwReturn.endif  invokeSetTimer, _hWnd, ebx, _dwSpeed, addr _WaveTimerProc  or[ebx].dwFlag, F_WO_ACTIVE or F_WO_NEED_UPDATE invoke_WaveRender, ebx invokeGetDC, [ebx].hWnd invoke_WaveUpdateFrame, ebx, eax, TRUEinvokeReleaseDC, [ebx].hWnd, eax ;--------------------------------------------------------------------------------_Ret: assumeebx:nothingpopad moveax, @dwReturn ret  _WaveInitendp ;--------------------------------------------------------------------------------; 一些特效 ; 输入:_dwType = 0关闭特效 ;_dwType != 0开启特效,参数具体见上面 ;--------------------------------------------------------------------------------_WaveEffectprocuses ebx eax _lpWaveObject, \ _dwType, _dwParam1, _dwParam2, _dwParam3 local@dwMaxX, @dwMaxY  movebx, _lpWaveObject assumeebx:ptr WAVE_OBJECT ;--------------------------------------------------------------------------------moveax, _dwType .ifeax ==0 ;--------------------------------------------------------------------------------; 关闭特效 ;--------------------------------------------------------------------------------and[ebx].dwFlag, not F_WO_EFFECT mov[ebx].dwEffectType, eax .elseifeax ==2 ;--------------------------------------------------------------------------------; 行船特效 ;--------------------------------------------------------------------------------moveax, _dwParam1 mov[ebx].dwEff2XAdd, eax mov[ebx].dwEff2YAdd, eax  moveax, [ebx].dwBmpWidth deceax deceax invoke_WaveRandom, ebx, eax inceax mov[ebx].dwEff2X, eax  moveax, [ebx].dwBmpHeight deceax deceax invoke_WaveRandom, ebx, eax inceax mov[ebx].dwEff2Y, eax  jmp@F .else ;--------------------------------------------------------------------------------; 默认 ;--------------------------------------------------------------------------------@@: push_dwType pop[ebx].dwEffectType push_dwParam1 pop[ebx].dwEffectParam1 push_dwParam2 pop[ebx].dwEffectParam2 push_dwParam3 pop[ebx].dwEffectParam3 or[ebx].dwFlag, F_WO_EFFECT .endif ;--------------------------------------------------------------------------------assumeebx:nothing ret  _WaveEffectendp ;--------------------------------------------------------------------------------; ; ; ;--------------------------------------------------------------------------------endif ;--------------------------------------------------------------------------------End DllEntry

原创粉丝点击