Advertisement
Guest User

Untitled

a guest
Feb 18th, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.22 KB | None | 0 0
  1. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2. ; Water ripple effect common subroutine
  3. ; by Luo Yunbin, http://asm.yeah.net, luoyunbin@sina.com
  4. ; V 1.0.041019 --- Initial version
  5. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  6. ; In the source code, only need to include WaveObject.asm
  7. ; Then call as follows:
  8. ;********************************************************************
  9. ; 1. Create a water ripple object:
  10. ; To draw on a window, first create a water ripple object (this function allocates some buffers)
  11. ; invoke _WaveInit, lpWaveObject, hWnd, hBmp, dwTime, dwType
  12. ; lpWaveObject --> Points to an empty WAVE_OBJECT structure
  13. ; hWnd --> The window on which the water ripple effect will be drawn, the rendered image will be drawn to the client area of the window
  14. ; hBmp --> Background image, the drawing range is the same as the size of the background image
  15. ; dwTime --> Refresh interval (milliseconds), recommended value: 10~30
  16. ; dwType --> =0 indicates circular water ripples, =1 indicates elliptical water ripples (used for perspective effects)
  17. ; Return value: eax = 0 (success, object initialized), eax = 1 (failure)
  18. ;********************************************************************
  19. ; 2. If the _WaveInit function returns successfully, the object is initialized, pass the object to various functions below
  20. ; Various effects can be achieved, the lpWaveObject parameter in the following functions points to the WAVE_OBJECT structure initialized in the _WaveInit function
  21. ;
  22. ; ◎ "Throw a stone" at a specified position, causing ripples
  23. ; invoke _WaveDropStone, lpWaveObject, dwPosX, dwPosY, dwStoneSize, dwStoneWeight
  24. ; dwPosX, dwPosY --> Position where the stone is thrown
  25. ; dwStoneSize --> Stone size, i.e., initial point size, recommended value: 0~5
  26. ; dwStoneWeight --> Stone weight, determines the range of the ripple, recommended value: 10~1000
  27. ;
  28. ; ◎ Automatically display special effects
  29. ; invoke _WaveEffect, lpWaveObject, dwEffectType, dwParam1, dwParam2, dwParam3
  30. ; dwParam1, dwParam2, dwParam3 --> Effect parameters, meaning varies for different effect types
  31. ; dwEffectType --> Effect type
  32. ; 0 --> Turn off the effect
  33. ; 1 --> Rain, Param1=Intensity speed (0 is the densest, larger values are sparser), recommended value: 0~30
  34. ; Param2=Maximum raindrop diameter, recommended value: 0~5
  35. ; Param3=Maximum raindrop weight, recommended value: 50~250
  36. ; 2 --> Motorboat, Param1=Speed (0 is the slowest, larger values are faster), recommended value: 0~8
  37. ; Param2=Boat size, recommended value: 0~4
  38. ; Param3=Range of water ripple diffusion, recommended value: 100~500
  39. ; 3 --> Wind waves, Param1=Density (larger is denser), recommended value: 50~300
  40. ; Param2=Size, recommended value: 2~5
  41. ; Param3=Energy, recommended value: 5~10
  42. ;
  43. ; ◎ Force update of the window client area (used to force update the client area in the window's WM_PAINT message)
  44. ; .if uMsg == WM_PAINT
  45. ; invoke BeginPaint, hWnd, addr @stPs
  46. ; mov @hDc, eax
  47. ; invoke _WaveUpdateFrame, lpWaveObject, eax, TRUE
  48. ; invoke EndPaint, hWnd, addr @stPs
  49. ; xor eax, eax
  50. ; ret
  51. ;********************************************************************
  52. ; 3. Release the water ripple object:
  53. ; After use, the water ripple object must be released (this function releases allocated buffer memory and other resources)
  54. ; invoke _WaveFree, lpWaveObject
  55. ; lpWaveObject --> Points to the WAVE_OBJECT structure
  56. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  57. ; Implementation details:
  58. ;
  59. ; 1. Characteristics of water ripples:
  60. ; ◎ Diffusion: The wave at each point will spread to its surrounding positions
  61. ; ◎ Attenuation: Each diffusion loses a small amount of energy (otherwise the water ripple will oscillate indefinitely)
  62. ;
  63. ; 2. To save the energy distribution maps at two moments, the object defines 2 buffers Wave1 and Wave2
  64. ; (saved in the buffers pointed to by lpWave1 and lpWave2), Wave1 is the current data, and Wave2 is
  65. ; the data of the last frame. Each time during rendering, based on the above two characteristics, the new
  66. ; energy distribution maps are calculated from the data of Wave1, saved to Wave2, and then Wave1 and Wave2 are swapped,
  67. ; at this point, Wave1 is still the newest data.
  68. ; The calculation method is that the energy at a certain point = the average value of the last energy of the surrounding points * attenuation coefficient
  69. ; Taking the average value of the surrounding points reflects the spreading characteristics, and multiplying by the attenuation coefficient reflects the attenuation characteristics.
  70. ; This part of the code is implemented in the _WaveSpread subroutine.
  71. ;
  72. ; 3. The object saves the data of the original bitmap in lpDIBitsSource, each time during rendering, a new bitmap is generated from the energy distribution data saved in Wave1.
  73. ; Visually, if the energy at a certain point is larger (the water ripple is larger), the scene refracted by the light will be farther away.
  74. ; The algorithm is: for point (x, y), find this point in Wave1, calculate the wave energy difference of adjacent points
  75. ; (two data Dx and Dy), then the new bitmap pixel (x, y) = original bitmap pixel (x+Dx, y+Dy), this algorithm reflects that the size of the energy affects the offset of pixel refraction.
  76. ; This part of the code is implemented in the _WaveRender subroutine.
  77. ;
  78. ; 4. The algorithm for throwing stones is easy to understand, that is, set the energy value of a certain point in Wave1 to a non-zero value, the larger the value,
  79. ; the greater the energy of the stone thrown. If the stone is large, set all the points around that point to a non-zero value.
  80. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  81. ;
  82. ;
  83. ;
  84. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  85. ifndef WAVEOBJ_INC
  86. WAVEOBJ_INC equ 1
  87. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  88. F_WO_ACTIVE equ 0001h
  89. F_WO_NEED_UPDATE equ 0002h
  90. F_WO_EFFECT equ 0004h
  91. F_WO_ELLIPSE equ 0008h
  92.  
  93. WAVE_OBJECT struct
  94. hWnd dd ?
  95. dwFlag dd ? ; Refer to the F_WO_xxx combination
  96. ;********************************************************************
  97. hDcRender dd ?
  98. hBmpRender dd ?
  99. lpDIBitsSource dd ? ; Original pixel data
  100. lpDIBitsRender dd ? ; Pixel data used for displaying on the screen
  101. lpWave1 dd ? ; Water ripple energy data buffer 1
  102. lpWave2 dd ? ; Water ripple energy data buffer 2
  103. ;********************************************************************
  104. dwBmpWidth dd ?
  105. dwBmpHeight dd ?
  106. dwDIByteWidth dd ? ; = (dwBmpWidth * 3 + 3) and ~3
  107. dwWaveByteWidth dd ? ; = dwBmpWidth * 4
  108. dwRandom dd ?
  109. ;********************************************************************
  110. ; Special Effect Parameters
  111. ;********************************************************************
  112. dwEffectType dd ?
  113. dwEffectParam1 dd ?
  114. dwEffectParam2 dd ?
  115. dwEffectParam3 dd ?
  116. ;********************************************************************
  117. ; Used for boat effect
  118. ;********************************************************************
  119. dwEff2X dd ?
  120. dwEff2Y dd ?
  121. dwEff2XAdd dd ?
  122. dwEff2YAdd dd ?
  123. dwEff2Flip dd ?
  124. ;********************************************************************
  125. stBmpInfo BITMAPINFO <>
  126. WAVE_OBJECT ends
  127. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  128.  
  129.  
  130. .code
  131.  
  132. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  133. ; Random Number Generation Subroutine
  134. ; Input: Maximum value of the desired random number, Output: Random number
  135. ; Based on:
  136. ; 1. Mathematical formula Rnd = (Rnd * I + J) mod K cyclically generates pseudo-random numbers within K times without repetition,
  137. ; but K, I, J must be prime numbers.
  138. ; 2. 2^(2n-1)-1 is guaranteed to be a prime number (i.e., 2 raised to the power of an odd number minus 1).
  139. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  140. _WaveRandom16 proc _lpWaveObject
  141.  
  142. mov ebx,_lpWaveObject
  143. assume ebx:ptr WAVE_OBJECT
  144. push edx
  145. push ecx
  146. mov eax,[ebx].dwRandom
  147. mov ecx,32768-1 ;2^15-1
  148. mul ecx
  149. add eax,2048-1 ;2^11-1
  150. adc edx,0
  151. mov ecx,2147483647 ;2^31-1
  152. div ecx
  153. mov eax,[ebx].dwRandom
  154. mov [ebx].dwRandom,edx
  155. and eax,0000ffffh
  156. pop ecx
  157. pop edx
  158. ret
  159.  
  160. _WaveRandom16 endp
  161. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  162. _WaveRandom proc uses ebx ecx edx _lpWaveObject,_dwMax
  163.  
  164. invoke _WaveRandom16,_lpWaveObject
  165. mov edx,eax
  166. invoke _WaveRandom16,_lpWaveObject
  167. shl eax,16
  168. or ax,dx
  169. mov ecx,_dwMax
  170. or ecx,ecx
  171. jz @F
  172. xor edx,edx
  173. div ecx
  174. mov eax,edx
  175. @@:
  176. ret
  177.  
  178. _WaveRandom endp
  179. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  180. ; Wave Energy Diffusion
  181. ; Algorithm:
  182. ; Wave2(x, y) = (Wave1(x+1, y) + Wave1(x-1, y) + Wave1(x, y+1) + Wave1(x, y-1))/2 - Wave2(x, y)
  183. ; Wave2(x, y) = Wave2(x, y) - (Wave2(x, y) >> 5)
  184. ; xchg Wave1, Wave2
  185. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  186. _WaveSpread proc _lpWaveObject
  187.  
  188. pushad
  189. mov ebx,_lpWaveObject
  190. assume ebx:ptr WAVE_OBJECT
  191. ;********************************************************************
  192. test [ebx].dwFlag,F_WO_ACTIVE
  193. jz _Ret
  194.  
  195. mov esi,[ebx].lpWave1
  196. mov edi,[ebx].lpWave2
  197. mov ecx,[ebx].dwBmpWidth
  198.  
  199. mov eax,[ebx].dwBmpHeight
  200. dec eax
  201. mul ecx
  202. ;********************************************************************
  203. ; ebx = width
  204. ; ecx = i,eax = max
  205. ;********************************************************************
  206. .while ecx < eax
  207. push eax
  208. .if [ebx].dwFlag & F_WO_ELLIPSE
  209. mov edx,[esi+ecx*4-1*4]
  210. add edx,[esi+ecx*4+1*4]
  211. add edx,[esi+ecx*4-2*4]
  212. add edx,[esi+ecx*4+2*4]
  213. lea edx,[edx+edx*2]
  214. add edx,[esi+ecx*4-3*4]
  215. add edx,[esi+ecx*4-3*4]
  216. add edx,[esi+ecx*4+3*4]
  217. add edx,[esi+ecx*4+3*4]
  218.  
  219. lea eax,[esi+ecx*4]
  220. sub eax,[ebx].dwWaveByteWidth
  221. mov eax,[eax]
  222. shl eax,3
  223. add edx,eax
  224.  
  225. lea eax,[esi+ecx*4]
  226. add eax,[ebx].dwWaveByteWidth
  227. mov eax,[eax]
  228. shl eax,3
  229. add edx,eax
  230.  
  231. sar edx,4
  232. sub edx,[edi+ecx*4]
  233.  
  234. mov eax,edx
  235. sar eax,5
  236. sub edx,eax
  237.  
  238. mov [edi+ecx*4],edx
  239. .else
  240. mov edx,[esi+ecx*4-1*4]
  241. add edx,[esi+ecx*4+1*4]
  242.  
  243. lea eax,[esi+ecx*4]
  244. sub eax,[ebx].dwWaveByteWidth
  245. add edx,[eax]
  246.  
  247. lea eax,[esi+ecx*4]
  248. add eax,[ebx].dwWaveByteWidth
  249. add edx,[eax]
  250.  
  251. sar edx,1
  252. sub edx,[edi+ecx*4]
  253.  
  254. mov eax,edx
  255. sar eax,5
  256. sub edx,eax
  257.  
  258. mov [edi+ecx*4],edx
  259. .endif
  260. pop eax
  261. inc ecx
  262. .endw
  263.  
  264. mov [ebx].lpWave1,edi
  265. mov [ebx].lpWave2,esi
  266. _Ret:
  267. ;********************************************************************
  268. assume ebx:nothing
  269. popad
  270. ret
  271.  
  272. _WaveSpread endp
  273. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  274. ; esi -> edi, ecx = line width
  275. ; 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
  276. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  277. _WaveGetPixel:
  278. movzx eax,byte ptr [esi] ; esi = Src
  279. shl eax,2
  280. movzx edx,byte ptr [esi+3]
  281. lea edx,[edx+2*edx]
  282. add eax,edx
  283. movzx edx,byte ptr [esi-3]
  284. lea edx,[edx+2*edx]
  285. add eax,edx
  286. movzx edx,byte ptr [esi+ecx] ; ecx = dwDIByteWidth
  287. lea edx,[edx+2*edx]
  288. add eax,edx
  289. mov edx,esi
  290. sub edx,ecx
  291. movzx edx,byte ptr [edx]
  292. lea edx,[edx+2*edx]
  293. add eax,edx
  294. shr eax,4
  295. mov [edi],al ; edi = Rdr
  296. inc esi
  297. inc edi
  298. ret
  299. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  300. ; Rendering subroutine, renders the new frame data into lpDIBitsRender
  301. ; Algorithm:
  302. ; posx = Wave1(x-1, y) - Wave1(x+1, y) + x
  303. ; posy = Wave1(x, y-1) - Wave1(x, y+1) + y
  304. ; SourceBmp(x, y) = DestBmp(posx, posy)
  305. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  306. _WaveRender proc _lpWaveObject
  307. local @dwPosX,@dwPosY,@dwPtrSource,@dwFlag
  308.  
  309. pushad
  310. xor eax,eax
  311. mov @dwFlag,eax
  312. mov ebx,_lpWaveObject
  313. assume ebx:ptr WAVE_OBJECT
  314.  
  315. test [ebx].dwFlag,F_WO_ACTIVE
  316. jz _Ret
  317.  
  318. or [ebx].dwFlag,F_WO_NEED_UPDATE
  319. mov esi,[ebx].lpWave1
  320. mov edi,[ebx].dwWaveByteWidth ; edi = pixel pointer
  321.  
  322. xor ecx,ecx
  323. inc ecx ; ecx=i -- i=1; i<height; i++
  324. _Loop1:
  325. xor edx,edx ; edx=j -- j=0; j<width; j++
  326. _Loop2:
  327. push edx
  328. ;********************************************************************
  329. ; PosY = i + energy above pixel - energy below pixel
  330. ; PosX = j + energy left of pixel - energy right of pixel
  331. ;********************************************************************
  332. mov eax,edi
  333. sub eax,[ebx].dwWaveByteWidth
  334. mov eax,[esi+eax]
  335. mov @dwPosY,eax
  336.  
  337. mov eax,[ebx].dwWaveByteWidth
  338. lea eax,[edi+eax]
  339. mov eax,[esi+eax]
  340. sub @dwPosY,eax
  341. add @dwPosY,ecx
  342.  
  343. mov eax,[esi+edi-4];;;;;
  344. sub eax,[esi+edi+4]
  345. add eax,edx ;@dwPosX = eax
  346. mov @dwPosX,eax
  347.  
  348. cmp eax,0
  349. jl _Continue
  350. cmp eax,[ebx].dwBmpWidth ; = 395
  351. jge _Continue
  352. mov eax,@dwPosY
  353. cmp eax,0
  354. jl _Continue
  355. cmp eax,[ebx].dwBmpHeight ; = 123
  356. jge _Continue
  357. ;********************************************************************
  358. ; ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3
  359. ; ptrDest = i * dwDIByteWidth + j * 3
  360. ;********************************************************************
  361. mov eax,@dwPosX
  362. lea eax,[eax+eax*2]
  363. mov @dwPosX,eax
  364. push edx
  365. mov eax,@dwPosY
  366. mul [ebx].dwDIByteWidth ; = 1188
  367. add eax,@dwPosX
  368. mov @dwPtrSource,eax
  369.  
  370. mov eax,ecx
  371. mul [ebx].dwDIByteWidth
  372. pop edx
  373. lea edx,[edx+edx*2]
  374. add eax,edx ;@dwPtrDest = eax
  375. ;********************************************************************
  376. ; Render pixel [ptrDest] = Original pixel [ptrSource]
  377. ;********************************************************************
  378. pushad
  379. mov ecx,@dwPtrSource
  380. mov esi,[ebx].lpDIBitsSource
  381. mov edi,[ebx].lpDIBitsRender
  382. lea esi,[esi+ecx]
  383. lea edi,[edi+eax]
  384. .if ecx != eax
  385. or @dwFlag,1 ; If the source pixel and destination pixel are different, it indicates that the activity is still ongoing
  386. mov ecx,[ebx].dwDIByteWidth
  387. call _WaveGetPixel
  388. call _WaveGetPixel
  389. call _WaveGetPixel
  390. .else
  391. cld
  392. movsw ; ESI + 3
  393. movsb ; EDI + 3
  394. .endif
  395. popad
  396. ;********************************************************************
  397. ; Continue looping
  398. ;********************************************************************
  399. _Continue:
  400. pop edx
  401. inc edx
  402. add edi,4 ; Increment pixel
  403. cmp edx,[ebx].dwBmpWidth
  404. jb _Loop2
  405.  
  406. inc ecx
  407. mov eax,[ebx].dwBmpHeight
  408. dec eax
  409. cmp ecx,eax
  410. jb _Loop1
  411. ;********************************************************************
  412. ; Copy the rendered pixel data to hDc (Device Context)
  413. ;********************************************************************
  414. invoke SetDIBits,[ebx].hDcRender,[ebx].hBmpRender,0,[ebx].dwBmpHeight,\
  415. [ebx].lpDIBitsRender,addr [ebx].stBmpInfo,DIB_RGB_COLORS
  416. .if ! @dwFlag
  417. and [ebx].dwFlag,not F_WO_ACTIVE
  418. .endif
  419. _Ret:
  420. ;********************************************************************
  421. assume ebx:nothing
  422. popad
  423. ret
  424.  
  425. _WaveRender endp
  426. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  427. _WaveUpdateFrame proc _lpWaveObject,_hDc,_bIfForce
  428.  
  429. pushad
  430. mov ebx,_lpWaveObject
  431. assume ebx:ptr WAVE_OBJECT
  432.  
  433. cmp _bIfForce,0
  434. jnz @F
  435. .if [ebx].dwFlag & F_WO_NEED_UPDATE
  436. @@:
  437. invoke BitBlt,_hDc,0,0,[ebx].dwBmpWidth,[ebx].dwBmpHeight,\
  438. [ebx].hDcRender,0,0,SRCCOPY
  439. and [ebx].dwFlag,not F_WO_NEED_UPDATE
  440. .endif
  441.  
  442. assume ebx:nothing
  443. popad
  444. ret
  445.  
  446. _WaveUpdateFrame endp
  447. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  448. ; Throw a stone
  449. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  450. _WaveDropStone proc _lpWaveObject,_dwX,_dwY,_dwSize,_dwWeight
  451. local @dwMaxX,@dwMaxY
  452.  
  453. pushad
  454. mov ebx,_lpWaveObject
  455. assume ebx:ptr WAVE_OBJECT
  456. ;********************************************************************
  457. ; Calculate Range
  458. ;********************************************************************
  459. mov edx,_dwSize
  460. shr edx,1
  461.  
  462. mov eax,_dwX
  463. mov esi,_dwY
  464.  
  465. mov ecx,eax ; ecx = _dwX
  466. mov edi,esi ; edi = _dwY
  467. add eax,edx ; x + size
  468. sub ecx,edx ; x - size
  469.  
  470. push edx ; dwSize >> 1
  471. .if [ebx].dwFlag & F_WO_ELLIPSE
  472. shr edx,1
  473. .endif
  474. add esi,edx ; y + size
  475. sub edi,edx ; y - size
  476. pop edx
  477.  
  478. shl edx,1
  479. .if ! edx
  480. inc edx
  481. .endif
  482. mov _dwSize,edx
  483. ;********************************************************************
  484. ; Check the Validity of the Range
  485. ;********************************************************************
  486. inc eax
  487. cmp eax,[ebx].dwBmpWidth
  488. jge _Ret
  489. cmp ecx,1
  490. jl _Ret
  491. inc esi
  492. cmp esi,[ebx].dwBmpHeight
  493. jge _Ret
  494. cmp edi,1
  495. jl _Ret
  496.  
  497. dec eax
  498. dec esi
  499. ;********************************************************************
  500. ; Set the energy of points within the range to _dwWeight
  501. ;********************************************************************
  502. mov @dwMaxX,eax
  503. mov @dwMaxY,esi
  504. .while ecx <= @dwMaxX
  505. push edi
  506. .while edi <= @dwMaxY
  507. mov eax,ecx
  508. sub eax,_dwX
  509. imul eax
  510. push eax
  511. mov eax,edi
  512. sub eax,_dwY
  513. imul eax
  514. pop edx
  515. add eax,edx
  516. push eax
  517. mov eax,_dwSize
  518. imul eax
  519. pop edx
  520. .if edx <= eax
  521. mov eax,edi
  522. mul [ebx].dwBmpWidth
  523. add eax,ecx
  524. shl eax,2
  525. add eax,[ebx].lpWave1
  526. push _dwWeight
  527. pop [eax]; ipwave1 = 00506F98 ; ipwave1[...] = 00512ec4
  528. .endif
  529. inc edi
  530. .endw
  531. pop edi
  532. inc ecx
  533. .endw
  534. or [ebx].dwFlag,F_WO_ACTIVE
  535. ;********************************************************************
  536. _Ret:
  537. assume ebx:nothing
  538. popad
  539. ret
  540.  
  541. _WaveDropStone endp
  542. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  543. ; Timer procedure for calculating diffusion data, rendering bitmaps, updating the window, and handling special effects
  544. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  545. _WaveTimerProc proc _hWnd,_uMsg,_idEvent,_dwTime
  546.  
  547. pushad
  548. mov ebx,_idEvent
  549. assume ebx:ptr WAVE_OBJECT
  550.  
  551. invoke _WaveSpread,ebx
  552. invoke _WaveRender,ebx
  553. .if [ebx].dwFlag & F_WO_NEED_UPDATE
  554. invoke GetDC,[ebx].hWnd
  555. invoke _WaveUpdateFrame,ebx,eax,FALSE
  556. invoke ReleaseDC,[ebx].hWnd,eax
  557. .endif
  558. ;********************************************************************
  559. ; Special Effect Processing
  560. ;********************************************************************
  561. test [ebx].dwFlag, F_WO_EFFECT
  562. jz _Ret
  563. mov eax, [ebx].dwEffectType
  564. ;********************************************************************
  565. ; Type = 1 Raindrops, Param1 = Speed (0 is the fastest, larger values are slower), Param2 = Raindrop Size, Param3 = Energy
  566. ;********************************************************************
  567. .if eax == 1
  568. mov eax,[ebx].dwEffectParam1
  569. or eax,eax
  570. jz @F
  571. invoke _WaveRandom,ebx,eax
  572. .if ! eax
  573. @@:
  574. mov eax,[ebx].dwBmpWidth
  575. dec eax
  576. dec eax
  577. invoke _WaveRandom,ebx,eax
  578. inc eax
  579. mov ecx,eax
  580.  
  581. mov eax,[ebx].dwBmpHeight
  582. dec eax
  583. dec eax
  584. invoke _WaveRandom,ebx,eax
  585. inc eax
  586. mov edx,eax
  587.  
  588. invoke _WaveRandom,ebx,[ebx].dwEffectParam2
  589. inc eax
  590. mov esi,eax
  591. invoke _WaveRandom,ebx,[ebx].dwEffectParam3
  592. add eax,50
  593. invoke _WaveDropStone,ebx,ecx,edx,esi,eax
  594. .endif
  595. ;********************************************************************
  596. ; Type = 2 Boat, Param1 = Speed (0 is the fastest, larger values are faster), Param2 = Size, Param3 = Energy
  597. ;********************************************************************
  598. .elseif eax == 2
  599. inc [ebx].dwEff2Flip
  600. test [ebx].dwEff2Flip,1
  601. jnz _Ret
  602.  
  603. mov ecx,[ebx].dwEff2X
  604. mov edx,[ebx].dwEff2Y
  605. add ecx,[ebx].dwEff2XAdd
  606. add edx,[ebx].dwEff2YAdd
  607.  
  608. cmp ecx,1
  609. jge @F
  610. sub ecx,1
  611. neg ecx
  612. neg [ebx].dwEff2XAdd
  613. @@:
  614. cmp edx,1
  615. jge @F
  616. sub edx,1
  617. neg edx
  618. neg [ebx].dwEff2YAdd
  619. @@:
  620. mov eax,[ebx].dwBmpWidth
  621. dec eax
  622. cmp ecx,eax
  623. jl @F
  624. sub ecx,eax
  625. xchg eax,ecx
  626. sub ecx,eax
  627. neg [ebx].dwEff2XAdd
  628. @@:
  629. mov eax,[ebx].dwBmpHeight
  630. dec eax
  631. cmp edx,eax
  632. jl @F
  633. sub edx,eax
  634. xchg eax,edx
  635. sub edx,eax
  636. neg [ebx].dwEff2YAdd
  637. @@:
  638. mov [ebx].dwEff2X,ecx
  639. mov [ebx].dwEff2Y,edx
  640. invoke _WaveDropStone,ebx,ecx,edx,[ebx].dwEffectParam2,[ebx].dwEffectParam3
  641. ;********************************************************************
  642. ; Type = 3 Waves, Param1 = Density, Param2 = Size, Param3 = Energy
  643. ;********************************************************************
  644. .elseif eax == 3
  645. xor edi,edi
  646. .while edi <= [ebx].dwEffectParam1
  647. mov eax,[ebx].dwBmpWidth
  648. dec eax
  649. dec eax
  650. invoke _WaveRandom,ebx,eax
  651. inc eax
  652. mov ecx,eax
  653.  
  654. mov eax,[ebx].dwBmpHeight
  655. dec eax
  656. dec eax
  657. invoke _WaveRandom,ebx,eax
  658. inc eax
  659. mov edx,eax
  660.  
  661. invoke _WaveRandom,ebx,[ebx].dwEffectParam2
  662. inc eax
  663. mov esi,eax
  664. invoke _WaveRandom,ebx,[ebx].dwEffectParam3
  665. invoke _WaveDropStone,ebx,ecx,edx,esi,eax
  666. inc edi
  667. .endw
  668. .endif
  669. _Ret:
  670. assume ebx:nothing
  671. popad
  672. ret
  673.  
  674. _WaveTimerProc endp
  675. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  676. ; Release the object
  677. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  678. _WaveFree proc _lpWaveObject
  679.  
  680. pushad
  681. mov ebx,_lpWaveObject
  682. assume ebx:ptr WAVE_OBJECT
  683. ;********************************************************************
  684. .if [ebx].hDcRender
  685. invoke DeleteDC,[ebx].hDcRender
  686. .endif
  687. .if [ebx].hBmpRender
  688. invoke DeleteObject,[ebx].hBmpRender
  689. .endif
  690. .if [ebx].lpDIBitsSource
  691. invoke GlobalFree,[ebx].lpDIBitsSource
  692. .endif
  693. .if [ebx].lpDIBitsRender
  694. invoke GlobalFree,[ebx].lpDIBitsRender
  695. .endif
  696. .if [ebx].lpWave1
  697. invoke GlobalFree,[ebx].lpWave1
  698. .endif
  699. .if [ebx].lpWave2
  700. invoke GlobalFree,[ebx].lpWave2
  701. .endif
  702. invoke KillTimer,[ebx].hWnd,ebx
  703. invoke RtlZeroMemory,ebx,sizeof WAVE_OBJECT
  704. ;********************************************************************
  705. assume ebx:nothing
  706. popad
  707. ret
  708.  
  709. _WaveFree endp
  710. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  711. ; Initialize the object
  712. ; Parameters: _lpWaveObject = Pointer to WAVE_OBJECT
  713. ; Returns: eax = 0 Success, = 1 Failure
  714. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  715. _WaveInit proc _lpWaveObject,_hWnd,_hBmp,_dwSpeed,_dwType
  716. local @stBmp:BITMAP,@dwReturn
  717.  
  718. pushad
  719. xor eax,eax
  720. mov @dwReturn,eax
  721. mov ebx,_lpWaveObject
  722. assume ebx:ptr WAVE_OBJECT
  723. invoke RtlZeroMemory,ebx,sizeof WAVE_OBJECT
  724.  
  725. .if _dwType
  726. or [ebx].dwFlag,F_WO_ELLIPSE
  727. .endif
  728. ;********************************************************************
  729. ; Get Bitmap Dimensions
  730. ;********************************************************************
  731. push _hWnd
  732. pop [ebx].hWnd
  733. invoke GetTickCount
  734. mov [ebx].dwRandom,eax
  735.  
  736. invoke GetObject,_hBmp,sizeof BITMAP,addr @stBmp
  737. .if ! eax
  738. @@:
  739. inc @dwReturn
  740. jmp _Ret
  741. .endif
  742. mov eax,@stBmp.bmHeight
  743. mov [ebx].dwBmpHeight,eax
  744. cmp eax,3
  745. jle @B
  746. mov eax,@stBmp.bmWidth
  747. mov [ebx].dwBmpWidth,eax
  748. cmp eax,3
  749. jle @B
  750.  
  751. push eax
  752. shl eax,2
  753. mov [ebx].dwWaveByteWidth,eax
  754. pop eax
  755. lea eax,[eax+eax*2] ;;;;
  756. add eax,3
  757. and eax,not 0011b
  758. mov [ebx].dwDIByteWidth,eax
  759. ;********************************************************************
  760. ; Create a bitmap for rendering
  761. ;********************************************************************
  762. invoke GetDC,_hWnd
  763. mov esi,eax
  764. invoke CreateCompatibleDC,esi
  765. mov [ebx].hDcRender,eax
  766. invoke CreateCompatibleBitmap,esi,[ebx].dwBmpWidth,[ebx].dwBmpHeight
  767. mov [ebx].hBmpRender,eax
  768. invoke SelectObject,[ebx].hDcRender,eax
  769. ;********************************************************************
  770. ; Allocate wave energy buffer
  771. ;********************************************************************
  772. mov eax,[ebx].dwWaveByteWidth
  773. mul [ebx].dwBmpHeight
  774. mov edi,eax
  775. invoke GlobalAlloc,GPTR,edi
  776. mov [ebx].lpWave1,eax
  777. invoke GlobalAlloc,GPTR,edi
  778. mov [ebx].lpWave2,eax
  779. ;********************************************************************
  780. ; Allocate pixel buffer
  781. ;********************************************************************
  782. mov eax,[ebx].dwDIByteWidth
  783. mul [ebx].dwBmpHeight
  784. mov edi,eax
  785. invoke GlobalAlloc,GPTR,edi
  786. mov [ebx].lpDIBitsSource,eax
  787. invoke GlobalAlloc,GPTR,edi
  788. mov [ebx].lpDIBitsRender,eax
  789. ;********************************************************************
  790. ; Get original pixel data
  791. ;********************************************************************
  792. mov [ebx].stBmpInfo.bmiHeader.biSize,sizeof BITMAPINFOHEADER
  793. push [ebx].dwBmpWidth
  794. pop [ebx].stBmpInfo.bmiHeader.biWidth
  795. mov eax,[ebx].dwBmpHeight
  796. neg eax
  797. mov [ebx].stBmpInfo.bmiHeader.biHeight,eax
  798. inc [ebx].stBmpInfo.bmiHeader.biPlanes
  799. mov [ebx].stBmpInfo.bmiHeader.biBitCount,24
  800. mov [ebx].stBmpInfo.bmiHeader.biCompression,BI_RGB
  801. mov [ebx].stBmpInfo.bmiHeader.biSizeImage,0
  802.  
  803. invoke CreateCompatibleDC,esi
  804. push eax
  805. invoke SelectObject,eax,_hBmp
  806. invoke ReleaseDC,_hWnd,esi
  807. pop eax
  808. mov esi,eax
  809.  
  810. invoke GetDIBits,esi,_hBmp,0,[ebx].dwBmpHeight,[ebx].lpDIBitsSource,\
  811. addr [ebx].stBmpInfo,DIB_RGB_COLORS
  812. invoke GetDIBits,esi,_hBmp,0,[ebx].dwBmpHeight,[ebx].lpDIBitsRender,\
  813. addr [ebx].stBmpInfo,DIB_RGB_COLORS
  814. invoke DeleteDC,esi
  815.  
  816. .if ![ebx].lpWave1 || ![ebx].lpWave2 || ![ebx].lpDIBitsSource ||\
  817. ![ebx].lpDIBitsRender || ![ebx].hDcRender
  818. invoke _WaveFree,ebx
  819. inc @dwReturn
  820. .endif
  821.  
  822. invoke SetTimer,_hWnd,ebx,_dwSpeed,addr _WaveTimerProc
  823.  
  824. or [ebx].dwFlag,F_WO_ACTIVE or F_WO_NEED_UPDATE
  825. invoke _WaveRender,ebx
  826. invoke GetDC,[ebx].hWnd
  827. invoke _WaveUpdateFrame,ebx,eax,TRUE
  828. invoke ReleaseDC,[ebx].hWnd,eax
  829. ;********************************************************************
  830. _Ret:
  831. assume ebx:nothing
  832. popad
  833. mov eax,@dwReturn
  834. ret
  835.  
  836. _WaveInit endp
  837. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  838. ; Some special effects
  839. ; Input: _dwType = 0 Close the special effect
  840. ; _dwType <> 0 Enable the special effect, specific parameters as described above
  841. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  842. _WaveEffect proc uses ebx eax _lpWaveObject,\
  843. _dwType,_dwParam1,_dwParam2,_dwParam3
  844. local @dwMaxX,@dwMaxY
  845.  
  846. mov ebx,_lpWaveObject
  847. assume ebx:ptr WAVE_OBJECT
  848. ;********************************************************************
  849. mov eax,_dwType
  850. .if eax == 0
  851. ;********************************************************************
  852. ; Turn off the special effect
  853. ;********************************************************************
  854. and [ebx].dwFlag,not F_WO_EFFECT
  855. mov [ebx].dwEffectType,eax
  856. .elseif eax == 2
  857. ;********************************************************************
  858. ; Boat special effect
  859. ;********************************************************************
  860. mov eax,_dwParam1
  861. mov [ebx].dwEff2XAdd,eax
  862. mov [ebx].dwEff2YAdd,eax
  863.  
  864. mov eax,[ebx].dwBmpWidth
  865. dec eax
  866. dec eax
  867. invoke _WaveRandom,ebx,eax
  868. inc eax ;;;;
  869. mov [ebx].dwEff2X,eax
  870.  
  871. mov eax,[ebx].dwBmpHeight
  872. dec eax
  873. dec eax
  874. invoke _WaveRandom,ebx,eax
  875. inc eax
  876. mov [ebx].dwEff2Y,eax
  877.  
  878. jmp @F
  879. .else
  880. ;********************************************************************
  881. ; Default
  882. ;********************************************************************
  883. @@:
  884. push _dwType
  885. pop [ebx].dwEffectType
  886. push _dwParam1
  887. pop [ebx].dwEffectParam1
  888. push _dwParam2
  889. pop [ebx].dwEffectParam2
  890. push _dwParam3
  891. pop [ebx].dwEffectParam3
  892. or [ebx].dwFlag,F_WO_EFFECT
  893. .endif
  894. ;********************************************************************
  895. assume ebx:nothing
  896. ret
  897.  
  898. _WaveEffect endp
  899. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  900. ;
  901. ;
  902. ;
  903. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  904. endif
  905. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  906.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement