;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 水波效果公用子程序; by 罗云彬,https://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值。;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ifndefWAVEOBJ_INCWAVEOBJ_INCequ1;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>F_WO_ACTIVEequ0001hF_WO_NEED_UPDATEequ0002hF_WO_EFFECTequ0004hF_WO_ELLIPSEequ0008hWAVE_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;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 随机数产生子程序; 输入:要产生的随机数的最大值,输出:随机数; 根据:; 1. 数学公式 Rnd=(Rnd*I+J) mod K 循环回带生成 K 次以内不重复的; 伪随机数,但K,I,J必须为素数; 2. 2^(2n-1)-1 必定为素数(即2的奇数次方减1);>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveRandom16proc_lpWaveObjectmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECTpushedxpushecxmoveax,[ebx].dwRandommovecx,32768-1;2^15-1mulecxaddeax,2048-1;2^11-1adcedx,0movecx,2147483647;2^31-1divecxmoveax,[ebx].dwRandommov[ebx].dwRandom,edxandeax,0000ffffhpopecxpopedxret_WaveRandom16endp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveRandomprocuses ebx ecx edx _lpWaveObject,_dwMaxinvoke_WaveRandom16,_lpWaveObjectmovedx,eaxinvoke_WaveRandom16,_lpWaveObjectshleax,16orax,dxmovecx,_dwMaxorecx,ecxjz@Fxoredx,edxdivecxmoveax,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_lpWaveObjectpushadmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECT;********************************************************************test[ebx].dwFlag,F_WO_ACTIVEjz_Retmovesi,[ebx].lpWave1movedi,[ebx].lpWave2movecx,[ebx].dwBmpWidthmoveax,[ebx].dwBmpHeightdeceaxmulecx;********************************************************************; ebx = width; ecx = i,eax = max;********************************************************************.whileecx < eaxpusheax.if[ebx].dwFlag & F_WO_ELLIPSEmovedx,[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].dwWaveByteWidthmoveax,[eax]shleax,3addedx,eaxleaeax,[esi+ecx*4]addeax,[ebx].dwWaveByteWidthmoveax,[eax]shleax,3addedx,eaxsaredx,4subedx,[edi+ecx*4]moveax,edxsareax,5subedx,eaxmov[edi+ecx*4],edx.elsemovedx,[esi+ecx*4-1*4]addedx,[esi+ecx*4+1*4]leaeax,[esi+ecx*4]subeax,[ebx].dwWaveByteWidthaddedx,[eax]leaeax,[esi+ecx*4]addeax,[ebx].dwWaveByteWidthaddedx,[eax]saredx,1subedx,[edi+ecx*4]moveax,edxsareax,5subedx,eaxmov[edi+ecx*4],edx.endifpopeaxincecx.endwmov[ebx].lpWave1,edimov[ebx].lpWave2,esi_Ret:;********************************************************************assumeebx:nothingpopadret_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,2movzxedx,byte ptr [esi+3]leaedx,[edx+2*edx]addeax,edxmovzxedx,byte ptr [esi-3]leaedx,[edx+2*edx]addeax,edxmovzxedx,byte ptr [esi+ecx]leaedx,[edx+2*edx]addeax,edxmovedx,esisubedx,ecxmovzxedx,byte ptr [edx]leaedx,[edx+2*edx]addeax,edxshreax,4mov[edi],alincesiincediret;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 渲染子程序,将新的帧数据渲染到 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);>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveRenderproc_lpWaveObjectlocal@dwPosX,@dwPosY,@dwPtrSource,@dwFlagpushadxoreax,eaxmov@dwFlag,eaxmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECTtest[ebx].dwFlag,F_WO_ACTIVEjz_Retor[ebx].dwFlag,F_WO_NEED_UPDATEmovesi,[ebx].lpWave1movedi,[ebx].dwWaveByteWidth; edi = 像素指针xorecx,ecxincecx; ecx=i -- i=1; i<height; i++_Loop1:xoredx,edx; edx=j -- j=0; j<width; j++_Loop2:pushedx;********************************************************************; PosY=i+像素上1能量-像素下1能量; PosX=j+像素左1能量-像素右1能量;********************************************************************moveax,edisubeax,[ebx].dwWaveByteWidthmoveax,[esi+eax]mov@dwPosY,eaxmoveax,[ebx].dwWaveByteWidthleaeax,[edi+eax]moveax,[esi+eax]sub@dwPosY,eaxadd@dwPosY,ecxmoveax,[esi+edi-4]subeax,[esi+edi+4]addeax,edx;@dwPosX = eaxmov@dwPosX,eaxcmpeax,0jl_Continuecmpeax,[ebx].dwBmpWidthjge_Continuemoveax,@dwPosYcmpeax,0jl_Continuecmpeax,[ebx].dwBmpHeightjge_Continue;********************************************************************; ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3; ptrDest = i * dwDIByteWidth + j * 3;********************************************************************moveax,@dwPosXleaeax,[eax+eax*2]mov@dwPosX,eaxpushedxmoveax,@dwPosYmul[ebx].dwDIByteWidthaddeax,@dwPosXmov@dwPtrSource,eaxmoveax,ecxmul[ebx].dwDIByteWidthpopedxleaedx,[edx+edx*2]addeax,edx;@dwPtrDest = eax;********************************************************************; 渲染像素 [ptrDest] = 原始像素 [ptrSource];********************************************************************pushadmovecx,@dwPtrSourcemovesi,[ebx].lpDIBitsSourcemovedi,[ebx].lpDIBitsRenderleaesi,[esi+ecx]leaedi,[edi+eax].ifecx !=eaxor@dwFlag,1;如果存在源像素和目标像素不同,则表示还在活动状态movecx,[ebx].dwDIByteWidthcall_WaveGetPixelcall_WaveGetPixelcall_WaveGetPixel.elsecldmovswmovsb.endifpopad;********************************************************************; 继续循环;********************************************************************_Continue:popedxincedxaddedi,4; 像素++cmpedx,[ebx].dwBmpWidthjb_Loop2incecxmoveax,[ebx].dwBmpHeightdeceaxcmpecx,eaxjb_Loop1;********************************************************************; 将渲染的像素数据拷贝到 hDc 中;********************************************************************invokeSetDIBits,[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:;********************************************************************assumeebx:nothingpopadret_WaveRenderendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveUpdateFrameproc_lpWaveObject,_hDc,_bIfForcepushadmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECTcmp_bIfForce,0jnz@F.if[ebx].dwFlag & F_WO_NEED_UPDATE@@:invokeBitBlt,_hDc,0,0,[ebx].dwBmpWidth,[ebx].dwBmpHeight,/[ebx].hDcRender,0,0,SRCCOPYand[ebx].dwFlag,not F_WO_NEED_UPDATE.endifassumeebx:nothingpopadret_WaveUpdateFrameendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 扔一块石头;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveDropStoneproc_lpWaveObject,_dwX,_dwY,_dwSize,_dwWeightlocal@dwMaxX,@dwMaxYpushadmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECT;********************************************************************; 计算范围;********************************************************************movedx,_dwSizeshredx,1moveax,_dwXmovesi,_dwYmovecx,eaxmovedi,esiaddeax,edx; x + sizesubecx,edx; x - sizepushedx.if[ebx].dwFlag & F_WO_ELLIPSEshredx,1.endifaddesi,edx; y + sizesubedi,edx; y - sizepopedxshledx,1.if! edxincedx.endifmov_dwSize,edx;********************************************************************; 判断范围的合法性;********************************************************************inceaxcmpeax,[ebx].dwBmpWidthjge_Retcmpecx,1jl_Retincesicmpesi,[ebx].dwBmpHeightjge_Retcmpedi,1jl_Retdeceaxdecesi;********************************************************************; 将范围内的点的能量置为 _dwWeight;********************************************************************mov@dwMaxX,eaxmov@dwMaxY,esi.whileecx <=@dwMaxXpushedi.whileedi <=@dwMaxYmoveax,ecxsubeax,_dwXimuleaxpusheaxmoveax,edisubeax,_dwYimuleaxpopedxaddeax,edxpusheaxmoveax,_dwSizeimuleaxpopedx.ifedx <=eaxmoveax,edimul[ebx].dwBmpWidthaddeax,ecxshleax,2addeax,[ebx].lpWave1push_dwWeightpop[eax].endifincedi.endwpopediincecx.endwor[ebx].dwFlag,F_WO_ACTIVE;********************************************************************_Ret:assumeebx:nothingpopadret_WaveDropStoneendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 计算扩散数据、渲染位图、更新窗口、处理特效的定时器过程;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveTimerProcproc_hWnd,_uMsg,_idEvent,_dwTimepushadmovebx,_idEventassumeebx:ptr WAVE_OBJECTinvoke_WaveSpread,ebxinvoke_WaveRender,ebx.if[ebx].dwFlag & F_WO_NEED_UPDATEinvokeGetDC,[ebx].hWndinvoke_WaveUpdateFrame,ebx,eax,FALSEinvokeReleaseDC,[ebx].hWnd,eax.endif;********************************************************************; 特效处理;********************************************************************test[ebx].dwFlag,F_WO_EFFECTjz_Retmoveax,[ebx].dwEffectType;********************************************************************; Type = 1 雨点,Param1=速度(0最快,越大越慢),Param2=雨点大小,Param3=能量;********************************************************************.ifeax ==1moveax,[ebx].dwEffectParam1oreax,eaxjz@Finvoke_WaveRandom,ebx,eax.if! eax@@:moveax,[ebx].dwBmpWidthdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmovecx,eaxmoveax,[ebx].dwBmpHeightdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmovedx,eaxinvoke_WaveRandom,ebx,[ebx].dwEffectParam2inceaxmovesi,eaxinvoke_WaveRandom,ebx,[ebx].dwEffectParam3addeax,50invoke_WaveDropStone,ebx,ecx,edx,esi,eax.endif;********************************************************************; Type = 2 行船,Param1=速度(0最快,越大越快),Param2=大小,Param3=能量;********************************************************************.elseifeax ==2inc[ebx].dwEff2Fliptest[ebx].dwEff2Flip,1jnz_Retmovecx,[ebx].dwEff2Xmovedx,[ebx].dwEff2Yaddecx,[ebx].dwEff2XAddaddedx,[ebx].dwEff2YAddcmpecx,1jge@Fsubecx,1negecxneg[ebx].dwEff2XAdd@@:cmpedx,1jge@Fsubedx,1negedxneg[ebx].dwEff2YAdd@@:moveax,[ebx].dwBmpWidthdeceaxcmpecx,eaxjl@Fsubecx,eaxxchgeax,ecxsubecx,eaxneg[ebx].dwEff2XAdd@@:moveax,[ebx].dwBmpHeightdeceaxcmpedx,eaxjl@Fsubedx,eaxxchgeax,edxsubedx,eaxneg[ebx].dwEff2YAdd@@:mov[ebx].dwEff2X,ecxmov[ebx].dwEff2Y,edxinvoke_WaveDropStone,ebx,ecx,edx,[ebx].dwEffectParam2,[ebx].dwEffectParam3;********************************************************************; Type = 3 波浪,Param1=密度,Param2=大小,Param3=能量;********************************************************************.elseifeax ==3xoredi,edi.whileedi <=[ebx].dwEffectParam1moveax,[ebx].dwBmpWidthdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmovecx,eaxmoveax,[ebx].dwBmpHeightdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmovedx,eaxinvoke_WaveRandom,ebx,[ebx].dwEffectParam2inceaxmovesi,eaxinvoke_WaveRandom,ebx,[ebx].dwEffectParam3invoke_WaveDropStone,ebx,ecx,edx,esi,eaxincedi.endw.endif_Ret:assumeebx:nothingpopadret_WaveTimerProcendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 释放对象;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveFreeproc_lpWaveObjectpushadmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECT;********************************************************************.if[ebx].hDcRenderinvokeDeleteDC,[ebx].hDcRender.endif.if[ebx].hBmpRenderinvokeDeleteObject,[ebx].hBmpRender.endif.if[ebx].lpDIBitsSourceinvokeGlobalFree,[ebx].lpDIBitsSource.endif.if[ebx].lpDIBitsRenderinvokeGlobalFree,[ebx].lpDIBitsRender.endif.if[ebx].lpWave1invokeGlobalFree,[ebx].lpWave1.endif.if[ebx].lpWave2invokeGlobalFree,[ebx].lpWave2.endifinvokeKillTimer,[ebx].hWnd,ebxinvokeRtlZeroMemory,ebx,sizeof WAVE_OBJECT;********************************************************************assumeebx:nothingpopadret_WaveFreeendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 初始化对象; 参数:_lpWaveObject = 指向 WAVE_OBJECT的指针; 返回:eax = 0 成功、= 1 失败;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveInitproc_lpWaveObject,_hWnd,_hBmp,_dwSpeed,_dwTypelocal@stBmp:BITMAP,@dwReturnpushadxoreax,eaxmov@dwReturn,eaxmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECTinvokeRtlZeroMemory,ebx,sizeof WAVE_OBJECT.if_dwTypeor[ebx].dwFlag,F_WO_ELLIPSE.endif;********************************************************************; 获取位图尺寸;********************************************************************push_hWndpop[ebx].hWndinvokeGetTickCountmov[ebx].dwRandom,eaxinvokeGetObject,_hBmp,sizeof BITMAP,addr @stBmp.if! eax@@:inc@dwReturnjmp_Ret.endifmoveax,@stBmp.bmHeightmov[ebx].dwBmpHeight,eaxcmpeax,3jle@Bmoveax,@stBmp.bmWidthmov[ebx].dwBmpWidth,eaxcmpeax,3jle@Bpusheaxshleax,2mov[ebx].dwWaveByteWidth,eaxpopeaxleaeax,[eax+eax*2]addeax,3andeax,not 0011bmov[ebx].dwDIByteWidth,eax;********************************************************************; 创建用于渲染的位图;********************************************************************invokeGetDC,_hWndmovesi,eaxinvokeCreateCompatibleDC,esimov[ebx].hDcRender,eaxinvokeCreateCompatibleBitmap,esi,[ebx].dwBmpWidth,[ebx].dwBmpHeightmov[ebx].hBmpRender,eaxinvokeSelectObject,[ebx].hDcRender,eax;********************************************************************; 分配波能缓冲区;********************************************************************moveax,[ebx].dwWaveByteWidthmul[ebx].dwBmpHeightmovedi,eaxinvokeGlobalAlloc,GPTR,edimov[ebx].lpWave1,eaxinvokeGlobalAlloc,GPTR,edimov[ebx].lpWave2,eax;********************************************************************; 分配像素缓冲区;********************************************************************moveax,[ebx].dwDIByteWidthmul[ebx].dwBmpHeightmovedi,eaxinvokeGlobalAlloc,GPTR,edimov[ebx].lpDIBitsSource,eaxinvokeGlobalAlloc,GPTR,edimov[ebx].lpDIBitsRender,eax;********************************************************************; 获取原始像素数据;********************************************************************mov[ebx].stBmpInfo.bmiHeader.biSize,sizeof BITMAPINFOHEADERpush[ebx].dwBmpWidthpop[ebx].stBmpInfo.bmiHeader.biWidthmoveax,[ebx].dwBmpHeightnegeaxmov[ebx].stBmpInfo.bmiHeader.biHeight,eaxinc[ebx].stBmpInfo.bmiHeader.biPlanesmov[ebx].stBmpInfo.bmiHeader.biBitCount,24mov[ebx].stBmpInfo.bmiHeader.biCompression,BI_RGBmov[ebx].stBmpInfo.bmiHeader.biSizeImage,0invokeCreateCompatibleDC,esipusheaxinvokeSelectObject,eax,_hBmpinvokeReleaseDC,_hWnd,esipopeaxmovesi,eaxinvokeGetDIBits,esi,_hBmp,0,[ebx].dwBmpHeight,[ebx].lpDIBitsSource,/addr [ebx].stBmpInfo,DIB_RGB_COLORSinvokeGetDIBits,esi,_hBmp,0,[ebx].dwBmpHeight,[ebx].lpDIBitsRender,/addr [ebx].stBmpInfo,DIB_RGB_COLORSinvokeDeleteDC,esi.if![ebx].lpWave1 || ![ebx].lpWave2 || ![ebx].lpDIBitsSource ||/![ebx].lpDIBitsRender || ![ebx].hDcRenderinvoke_WaveFree,ebxinc@dwReturn.endifinvokeSetTimer,_hWnd,ebx,_dwSpeed,addr _WaveTimerProcor[ebx].dwFlag,F_WO_ACTIVE or F_WO_NEED_UPDATEinvoke_WaveRender,ebxinvokeGetDC,[ebx].hWndinvoke_WaveUpdateFrame,ebx,eax,TRUEinvokeReleaseDC,[ebx].hWnd,eax;********************************************************************_Ret:assumeebx:nothingpopadmoveax,@dwReturnret_WaveInitendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 一些特效; 输入:_dwType = 0关闭特效;_dwType <> 0开启特效,参数具体见上面;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WaveEffectprocuses ebx eax _lpWaveObject,/_dwType,_dwParam1,_dwParam2,_dwParam3local@dwMaxX,@dwMaxYmovebx,_lpWaveObjectassumeebx:ptr WAVE_OBJECT;********************************************************************moveax,_dwType.ifeax ==0;********************************************************************; 关闭特效;********************************************************************and[ebx].dwFlag,not F_WO_EFFECTmov[ebx].dwEffectType,eax.elseifeax ==2;********************************************************************; 行船特效;********************************************************************moveax,_dwParam1mov[ebx].dwEff2XAdd,eaxmov[ebx].dwEff2YAdd,eaxmoveax,[ebx].dwBmpWidthdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmov[ebx].dwEff2X,eaxmoveax,[ebx].dwBmpHeightdeceaxdeceaxinvoke_WaveRandom,ebx,eaxinceaxmov[ebx].dwEff2Y,eaxjmp@F.else;********************************************************************; 默认;********************************************************************@@:push_dwTypepop[ebx].dwEffectTypepush_dwParam1pop[ebx].dwEffectParam1push_dwParam2pop[ebx].dwEffectParam2push_dwParam3pop[ebx].dwEffectParam3or[ebx].dwFlag,F_WO_EFFECT.endif;********************************************************************assumeebx:nothingret_WaveEffectendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>endif;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 你的当前访问异常,请进行认证后继续阅读剩余内容。 提交