Hello it's about a source code that i've not understood :
well it's about the water effect demo og tom kenny i think :
i'd like to know where in his code is the code for makink the ripples simulating drops ( well if possible the formula he uses , comments on it , .. )
Well before pasting code thanks for all help !!! :


; The Great "Water Effect" Demo!!!
; By Tom Kenny
;
;
; My first full assembler program, this little demo creates a rain-storm (or more
; accurately a light-drizzle :) on the user's desktop for a while. It demonstrates
; the Windows GDI and Multi-threading. There is no program window.
;
; The droplet effect is done by creating a TILE_SIZE x TILE_SIZE bitmap at a random
; location on the user's desktop. The wave is simulated by using two arrays of bytes
; representing water depth (height maps). The main program loop, creates several of
; these tiles at once thus simulating a rainstorm on the desktop.
;
; The separate tiles are handled using an array of structures (WaterTileStruct) which
; define the X and Y coordinates of each tile as well as maintaining pointers to their
; bitmaps and height maps. Each tile runs on its' own thread of execution for
; NUM_FRAMES then dies on its own (no fuss, no muss).
;
; This program was written on the MASM32 package (Version 6).
;

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib


LPCOLORREF TYPEDEF PTR COLORREF; Create some TypeDefs........
LPBYTE TYPEDEF PTR BYTE;
PBITMAPINFO TYPEDEF PTR BITMAPINFO

; Define the structure which keeps our WaterTiles...
WaterTileStruct STRUCT

IsInUse DWORD 0 ; Is this structure currently in use?
DropDepth DWORD 0 ; How deep is the droplet?
OffSetX DWORD 0 ; Offset from the left of the screen
OffSetY DWORD 0 ; Offset from the top of the screen
CaptureBitmap HBITMAP 0 ; Holds the "background" on which the effect is drawn
WaterBitmap HBITMAP 0 ; The finished frame of animation.
CaptureBitmapBits LPCOLORREF 0 ; Points to the bits of CaptureBitmap
WaterBitmapBits LPCOLORREF 0 ; Points to the bits of WaterBitmap
HeightMapOne LPBYTE 0 ; Points to a frame of water height data
HeightMapTwo LPBYTE 0 ; Points to the last frame of water height data

WaterTileStruct ends

LPWaterTileStruct TYPEDEF PTR WaterTileStruct ; typedef a pointer to a WaterTileStruct

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
;
; Our "main" function most of the parameters aren't used, but I kept them for consistency with
; standards.
;

CreateStorm proto WTStruct:LPWaterTileStruct, StormSize:DWORD, Elements:DWORD
;
; This is where the magic happens! This function defines a loop which is responsible
; for creating our water tiles. First it searches the array of WaterTiles to find a free
; structure that we can use to make a new tile. If it finds one, it generates random
; x and y coordinates, and a random droplet depth. Then it searches the existing tiles
; to make sure that the new tile's coordinates don't interfere with any already running
; tiles. provided there is no interference, the new tile's structure is filled out and
; its own thread of execution is created. A short Sleep after each tile's creation makes
; for a steady stream of droplets. Up to MAX_DROPS_AT_ONCE drops can be created at any time.
;

ThreadProc proto WTStruct:LPWaterTileStruct
;
; This is the callback we use when we call CreateThread to create a thread of execution for
; a tile. All it does is call CreateWaterTile. It takes a pointer to the tile's watertile
; structure.
;

CreateWaterTile proto WTStruct:LPWaterTileStruct
;
; This function acts as a sort of parent for each tile. It captures a TILE_SIZE x
; TILE_SIZE portion of the desktop at OffSetX, OffSetY, and then calls the function
; CreateWaterMaps to allocate memory for the two required "height maps". Then it calls
; the CreateADrop function to place the raindrop in one of the "height maps". Then
; it calls AnimationLoop to handle the animation of the tile. When the animation is
; complete, DestroyObjects is called to de-allocate the memory used by the tile's bitmaps
; and height maps. All of the functions from now on take a pointer to an individual Tile's
; structure (i.e. one of the tiles from the global array of tile structures)..
;

CreateWaterMaps proto WTStruct:LPWaterTileStruct
;
; This just allocates two arrays to handle our "height maps" Since we need one byte for
; each pixel, we need TILE_SIZE x TILE_SIZE bytes for each map.
;

CreateADrop proto WTStruct:LPWaterTileStruct
;
; In order to start the ripples, we need a nice big drop placed square in the middle of the
; tile. Using the .DropDepth member of the Tile structure, we calculate the drop's depth
; and put the information into the first "Height Map".
;

AnimationLoop proto WTStruct:LPWaterTileStruct
;
; Here is where the actual animation of the tile happens. This function consists of a loop
; (run once every SLEEP_TIME milliseconds) that calls ProcessWater to produce a new
; water "height map" for the current Tile, then it calls the MakeFrame function to create
; the display bitmap based on the height map. Finally, PaintWaterTile blits the tile
; to the screen.
;

ProcessWater proto WTStruct:LPWaterTileStruct
;
; This function processes our two "height map" arrays to produce a height map for our
; current animation frame.
;
; The animation of a tile is achieved by maintaining two separate arrays of information
; on the height of the water at each pixel in the tile. The first array holds the
; information for the current frame of animation, the second holds the information from
; the last frame. Between the two frames, we have enough information to create a new
; frame of animation (in the second array). Then we switch the pointers to the arrays
; around and do it again for the next frame ect.....

MakeFrame proto WTStruct:LPWaterTileStruct
;
; This function goes through the new height map and depending on the value of each byte
; the corresponding pixel in the destination bitmap is set. If the value of a given byte
; was zero for instance, then the resulting pixel on the desintation bitmap would be the
; same as the pixel in the source (or background) bitmap. Non-zero bytes correspond to
; another pixel from the source bitmap (i.e. due to the water's refraction).
;

PaintWaterTile proto WTStruct:LPWaterTileStruct
;
; Nothing too exciting here! Just creates a DC, and blits the finished bitmap onto the
; screen.
;

DestroyObjects proto WTStruct:LPWaterTileStruct
;
; Here we de-allocate the memory that was used to store the "height maps" and the source and
; destination bitmaps. Also the IsInUse member is set back to false here so that the tile can
; be reused.
;

FillWTStruct proto WTStruct:LPWaterTileStruct, OffSetX:DWORD, OffSetY:DWORD, DropDepth:DWORD
;
; This helper function fills out a Tile Structure for us. It takes the XOffset, the YOffset
; and the Drop Depth. It also sets the IsInUse member to true to indicate the structure is
; in use.
;

SetupBitmapInfoStruct proto BIH:PBITMAPINFO, PicWidth:DWORD, PicHeight:DWORD
;
; Many bitmaps (dibsections actually) are created in this program. Since they are all the same
; size (TILE_SIZE x TILE_SIZE) we just fill out one BITMAPINFO structure and use it every time we
; need to create a bitmap. It takes a pointer to a BITMAPINFO structure, and the width and height
; of the bitmap.
;
;

TRand proto :DWORD
;
; This is the random number generating function. The code is based on something I took
; from VC++'s C library. This function takes one parameter specifying the upper limit
; of the number to be generated.
;


.DATA ; initialized data
BitmapInfo BITMAPINFO <> ; Our BitmapInfo Structure
WTileStruct WaterTileStruct {},{},{},{},{} ; an array of 5 Tile structures...
seed DWORD 1 ; for our Random numbers...

.DATA? ; Uninitialized data
CommandLine LPSTR ? ; Can't have too many of these


.CONST
TILE_SIZE DWORD 100 ; Our Tile's (length and width)
; Unfortunately, I could not use this constant for lea address
; calculations for some reason. So I still have "100" in some
; program areas.....


TILE_SMIN DWORD 99 ; TILE_SIZE -1 Its usefull in a loop.
TRAND_MAX DWORD 32767 ; The maximum possible random number

RAND_DROPDEPTH DWORD 100 ; These two constants help us determine a good
MIN_DROPDEPTH DWORD 27 ; drop depth

MAX_DROPS_AT_ONCE DWORD 5 ; How many drops can we have at once?
STORMLENGTH DWORD 100 ; How many drops should we display in total?
SLEEP_TIME DWORD 120; ; How much time should we wait between creating Tiles?
NUM_FRAMES DWORD 55 ; How many frames should a tile run for?
SLEEP_TICKS DWORD 10 ; How long should we wait between frames of animation?
INVERSE REAL4 0.166666 ; Helps us to divide by 6 quickly!
NOT_AVAILABLE DWORD -99 ; When all WaterTile structures in the array are in use

.CODE ; Here comes the CODE segment
WaterTiles:

invoke GetCommandLine ; get the command line.May be useful later.
mov CommandLine,eax

invoke WinMain, NULL,NULL,CommandLine, NULL ; call the main function
invoke ExitProcess, eax ; quit our program. The exit code is returned
; in eax from WinMain.

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

; First lets fill out our WaterTileStructure....

invoke CreateStorm, ADDR WTileStruct, STORMLENGTH, MAX_DROPS_AT_ONCE;
invoke InvalidateRect, NULL, NULL, 1;

xor eax,eax; All's well..... return 0
ret

WinMain endp

;##########################################################################################

CreateStorm proc WTStruct:LPWaterTileStruct, StormSize:DWORD, Elements:DWORD

LOCAL ScreenX:DWORD
LOCAL ScreenY:DWORD
LOCAL ScreenDC:HDC
LOCAL x:DWORD
LOCAL y:DWORD
LOCAL i:DWORD
LOCAL j:DWORD
LOCAL FreeElement:DWORD
LOCAL DropDepth:DWORD
LOCAL SleepAfter:DWORD
LOCAL ThreadID:DWORD

; Since all tiles are the same size, we only need to set up one bitmap
; info structure

invoke SetupBitmapInfoStruct, ADDR BitmapInfo, TILE_SIZE, TILE_SIZE

xor eax,eax;
mov i, eax;
mov ThreadID, eax;

StormLoop:
; the first thing we need to do is see if there are any available structures...

mov eax, NOT_AVAILABLE;
mov FreeElement, eax;

xor eax,eax;
mov j, eax;

FreeLoop:

mov eax, j;
imul eax, SIZEOF WaterTileStruct;
mov edx, WTStruct;
add edx, eax;

mov eax, ;
cmp eax, TRUE;
je NotFree
mov eax, j;
mov FreeElement, eax; The index of a free structure

NotFree:
inc j;
mov eax, j;
cmp eax, Elements;

jl FreeLoop;

mov eax, FreeElement;
cmp eax, NOT_AVAILABLE;
je NoneFree;

inc i;

invoke GetDC, NULL;
mov ScreenDC, eax;

invoke GetDeviceCaps, ScreenDC, HORZRES;
sub eax, TILE_SIZE;
mov ScreenX, eax;

invoke GetDeviceCaps, ScreenDC, VERTRES;
sub eax, TILE_SIZE;
mov ScreenY, eax;

invoke ReleaseDC, NULL, ScreenDC;

PickCoords:

invoke TRand, ScreenX;
mov x, eax;

invoke TRand, ScreenY;
mov y, eax;

; Now for the "ugly" part. we need to make sure that the x and y coords weve picked
; dont interfere with any already running animation tiles. Basically we need to know whether
; our x and y values are both within +/-TILE_SIZE of already running Tiles. So we go through all
; the tiles and if they are in use, we look for interferences.
;
; If at any point we see that no interference is possible, we jump past all the other tests.
; If we get past all tests we have an interference, and so we jump back up to pick new coordinates...

;-----------------------------------------------------

xor eax, eax;
mov j, eax;

InterferenceLoop:

mov eax, j;
imul eax, SIZEOF WaterTileStruct;
mov edx, WTStruct;
add edx, eax;
add edx, 8;

mov esi, ; // esi holds the XOffSet for structure j
add edx, 4;
mov edi, ; // edi holds the YOffSet for structure j

sub esi, TILE_SIZE;
sub edi, TILE_SIZE;

cmp x, esi;
jl Passed
add esi, TILE_SIZE;
add esi, TILE_SIZE;
cmp x, esi;
jg Passed

cmp y, edi;
jl Passed;
add edi, TILE_SIZE;
add edi, TILE_SIZE;
cmp y, edi;
jg Passed;

jmp PickCoords ; We have an inteference so go back and pick new coords

Passed: ; No interference. Increment j and do the next one...
inc j;
mov eax, j;
cmp eax, Elements;

jl InterferenceLoop;

;-----------------------------------------------


invoke TRand, RAND_DROPDEPTH ; Now get a drop-depth for our droplet
add eax, MIN_DROPDEPTH;
mov DropDepth, eax;

mov eax, FreeElement;
imul eax, SIZEOF WaterTileStruct;
mov edx, WTStruct;
add edx, eax;

invoke FillWTStruct, edx, x, y ,DropDepth ; Fill out our structure

mov eax, FreeElement;
imul eax, SIZEOF WaterTileStruct;
mov edx, WTStruct;
add edx, eax;


xor ebx, ebx ; Create a new thread

invoke CreateThread, ebx, ebx, OFFSET ThreadProc, edx, ebx, ADDR ThreadID
invoke CloseHandle, eax ; We dont need the Handle anymore so lets close it now...

NoneFree: ; If we jumped here, there are no free structures
invoke Sleep, SLEEP_TIME; ; try sleeping for a while....

mov eax, i;
cmp eax, StormSize;

jl StormLoop;
ret

CreateStorm endp

;################################################################################################

ThreadProc proc WTStruct:LPWaterTileStruct

invoke CreateWaterTile, WTStruct ; Create a tile, and off we go.....
ret

ThreadProc endp

;################################################################################################

CreateWaterTile proc WTStruct:LPWaterTileStruct

LOCAL ScreenDC:HDC
LOCAL BitmapDC:HDC
LOCAL CaptureBitmap:HBITMAP
LOCAL pOldBitmap:HGDIOBJ
LOCAL BitmapBits:LPVOID


invoke CreateCompatibleDC, NULL; Create a Memory DC
mov BitmapDC, eax;

invoke GetDC, NULL; Get a Hardware DC for our screen...
mov ScreenDC, eax;

; create the bitmap

invoke CreateDIBSection, BitmapDC, ADDR BitmapInfo, DIB_RGB_COLORS, ADDR BitmapBits, NULL, NULL
mov edx, WTStruct;
mov , eax;
mov ebx, ;
mov , ebx;

invoke CreateDIBSection, BitmapDC, ADDR BitmapInfo, DIB_RGB_COLORS, ADDR BitmapBits, NULL, NULL
mov edx, WTStruct;
mov , eax;
mov ebx, ;
mov , ebx;


; Select the bitmap into our memory DC

invoke SelectObject, BitmapDC, eax; Select the capture bitmap into the memory DC
mov pOldBitmap, eax;

;Capture some screen area into the memory DC...

mov edx, WTStruct;
mov eax, ;
mov ebx, ;

invoke BitBlt, BitmapDC ,0 ,0 ,TILE_SIZE ,TILE_SIZE ,ScreenDC ,eax ,ebx ,SRCCOPY;

; Now clean up our GDI stuff....

invoke SelectObject, BitmapDC, pOldBitmap; Select the bitmap out of the DC and delete it


invoke DeleteDC, BitmapDC; Delete the DCs....
invoke ReleaseDC, NULL, ScreenDC;

invoke CreateWaterMaps, WTStruct; Create the water masks for this tile..
invoke CreateADrop, WTStruct; Place a "drop" on one of the masks

invoke AnimationLoop, WTStruct; Now Animate!

invoke DestroyObjects, WTStruct; Destroy the watermaps and bitmaps
ret

CreateWaterTile endp

;################################################################################################

CreateWaterMaps proc WTStruct:LPWaterTileStruct

; Here is where we allocate the memory for our water masks.....

mov eax, TILE_SIZE;
imul eax, eax;

invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax;
mov edx, WTStruct;
mov , eax;

mov eax, TILE_SIZE;
imul eax, eax;

invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax;
mov edx, WTStruct;
mov , eax;


ret
CreateWaterMaps endp

;################################################################################################

CreateADrop proc WTStruct:LPWaterTileStruct

LOCAL i:DWORD
LOCAL j:DWORD
LOCAL DripRadius:DWORD
LOCAL Distance:DWORD
LOCAL DropDepth:DWORD
LOCAL FinalDepth:DWORD


mov edx, WTStruct;
mov edx, ;

mov DropDepth, edx;
shr edx, 3;
mov DripRadius, edx;

mov esi, TILE_SIZE;
shr esi, 1;

mov ebx, esi; // ebx is both X and Y in the original calculation.

mov edi, esi;
add edi, edx; // edi contains the upper limit of our loops
sub esi, edx; // esi contains the lower limit of our loops

mov j, esi;
JLoop:

mov ecx, esi;
ILoop:
mov eax, ecx;
sub eax, ebx;
imul eax, eax;
mov Distance, eax;

mov eax, j;
sub eax, ebx;
imul eax, eax;
add Distance, eax;

mov eax, DripRadius;
imul eax, eax;

cmp Distance, eax;
jge short NoDrip

fild DripRadius;
fld st(0);
fild Distance;
fsqrt;
fsubp st(1), st(0);
fxch;
fdivp st(1), st(0);
fild DropDepth;
fmulp st(1), st(0);

fistp FinalDepth;
mov eax, j;
imul eax, TILE_SIZE;
add eax, ecx;

mov edx, WTStruct;
mov edx, ;
add edx, eax;
mov eax, FinalDepth;
mov , al;

NoDrip:
inc ecx;
cmp ecx, edi;

jl short ILoop;

inc j;
cmp j, edi;

jl short JLoop;
invoke Sleep, NULL;

ret
CreateADrop endp

;################################################################################################

AnimationLoop proc WTStruct:LPWaterTileStruct

LOCAL Counter:DWORD

xor eax, eax;
mov Counter, eax;
AniLoop:

inc Counter;
invoke ProcessWater, WTStruct;
invoke MakeFrame, WTStruct;
invoke PaintWaterTile, WTStruct;
invoke Sleep, SLEEP_TICKS;
mov ecx, Counter;
cmp ecx, NUM_FRAMES

jl AniLoop

ret

AnimationLoop endp

;################################################################################################

ProcessWater proc WTStruct:LPWaterTileStruct

LOCAL i:DWORD
LOCAL j:DWORD
LOCAL YCounter:DWORD
LOCAL LoopLim:DWORD
LOCAL StPt:DWORD
LOCAL TempInt:DWORD

mov eax, 2;
mov StPt, eax;

mov eax, TILE_SIZE;
sub eax, 2;
mov LoopLim, eax;

fld INVERSE; // For later when we divide by 6...
mov esi, WTStruct;
mov edi, WTStruct;
mov esi, ; // Now esi and edi point to
mov edi, ;

mov eax, TILE_SIZE;
shl eax, 1;
lea edi, ;

mov ecx, StPt;
mov YCounter, ecx;

YLoop:
mov ecx, 2;
XLoop:

lea edx, ;
movsx eax, byte ptr ; // i,j-2

lea edx, ;
movsx ebx, byte ptr ; // i-1,j-1
add eax, ebx;
movsx ebx, byte ptr ; // i,j-1
add eax, ebx;
movsx ebx, byte ptr ; // i + 1,j-1
add eax, ebx;

lea edx, ;
movsx ebx, byte ptr ; // i-2,j
add eax, ebx;
movsx ebx, byte ptr ; // i-1,j
add eax, ebx;
movsx ebx, byte ptr ; // i+1,j
add eax, ebx;
movsx ebx, byte ptr ; // i+2,j
add eax, ebx;

lea edx, ;
movsx ebx, byte ptr ; // i-1,j+1
add eax, ebx;
movsx ebx, byte ptr ; // i,j + 1
add eax, ebx;
movsx ebx, byte ptr ; // i + 1,j + 1
add eax, ebx;

lea edx, ;
movsx ebx, byte ptr ; // i,j + 2
add eax, ebx;

mov TempInt, eax; We need to integer divide by 6, but its quicker to
fild TempInt; do a floating point multiplication by 1/6....

fmul st(0), st(1);
fistp TempInt;

mov eax, TempInt;

movsx ebx, byte ptr ;
sub eax, ebx;

mov ebx, eax;
shr eax, 4;
sub ebx, eax;

cmp ebx, 2;
jge MakeZero;
xor ebx, ebx;

MakeZero:
mov byte ptr , bl; // Nasty partial-register stall?

inc ecx;
cmp ecx, LoopLim ;
jb XLoop;

add edi, TILE_SIZE;
add esi, TILE_SIZE;

mov ecx, YCounter;
inc ecx;
mov YCounter, ecx;
cmp ecx, LoopLim;

jb YLoop;

fstp TempInt; get our float off the stack
invoke Sleep, NULL; Surrender control to a sibling thread
ret

ProcessWater endp

;################################################################################################

MakeFrame proc WTStruct:LPWaterTileStruct

LOCAL CapBits:DWORD
LOCAL WatBits:DWORD
LOCAL YCounter:DWORD
LOCAL Count:DWORD


xor eax, eax;
mov YCounter, eax;
mov Count, eax;

mov ebx, WTStruct;

mov eax, ;
mov CapBits, eax;
mov eax, ;
mov WatBits, eax;

mov eax, WTStruct;
mov esi, ; Make edi and esi point to
mov edi, ; the two watermasks

mov , edi; Now switch them around to
mov , esi; make the animation happen

mov eax, edi; switch them again to make it
mov edi, esi; consistant with ProcessWater
mov esi, eax;

mov YCounter, 0;
YLoop:

xor ecx, ecx;
XLoop:
mov eax, ecx;
mov edx, Count;
test ecx, ecx;

jz short NoX;
cmp ecx, TILE_SMIN;
jnb short NoX;

movsx edi, byte ptr ;
movsx ebx, byte ptr ;

sub ebx, edi;
add eax, ebx;

NoX:
mov ebx, YCounter;
test ebx, ebx;
jz short NoY;
cmp ebx, TILE_SMIN;
jnb short NoY;
movsx edx, byte ptr ;
movsx edi, byte ptr ;

sub edi, edx;
add ebx, edx;

NoY:

test eax, eax; unless xoff and edi are greater than 0, put 0 in them
jns short NoChangeX;
xor eax, eax;

NoChangeX:

test ebx, ebx;
jns short NoChangeY
xor ebx, ebx;
NoChangeY:

mov edx, TILE_SMIN; if xoff and ebx are > than TILE_SIZE, put TILE_SMIN in them

cmp eax, edx;
jng short NoLimX;
mov eax, edx;
NoLimX:


cmp ebx, edx;
jng short NoLimY;
mov ebx, edx;
NoLimY:

inc edx; get some RGB values, ebx is in ebx, TILE_SIZE in edx....
shl ebx, 2;
imul edx, ebx;
lea eax, ;
mov edx, Count;
add eax, CapBits;

movsx edx, byte ptr ;

movzx ebx, byte ptr ;
add ebx, edx;
cmp ebx, 255;
jnge short NoRLim;
mov ebx, 255;
NoRLim:
mov edi, ebx;

movzx ebx, byte ptr ;
add ebx, edx;
cmp ebx, 255;
jnge short NoGLim;
mov ebx, 255;

NoGLim:
shl ebx, 8;
or edi, ebx;
movzx ebx, byte ptr ;
add ebx, edx;
cmp ebx, 255;
jnge short NoBLim;
mov ebx, 255;

NoBLim:
shl ebx, 16;
or edi, ebx;
mov eax, Count;
mov edx, WatBits;
mov , edi;

inc Count;
inc ecx;
cmp ecx, TILE_SIZE ;

jb XLoop;

mov ecx, YCounter;
inc ecx;
mov YCounter, ecx;
cmp ecx, TILE_SIZE;

jb YLoop;

invoke Sleep, NULL;
ret

MakeFrame endp

;################################################################################################

PaintWaterTile proc WTStruct:LPWaterTileStruct
LOCAL ScreenDC:HDC
LOCAL BitmapDC:HDC
LOCAL pOldBitmap:HGDIOBJ
LOCAL BitmapBits:LPVOID
LOCAL Counter:DWORD


invoke CreateCompatibleDC, NULL; Create a Memory DC
mov BitmapDC, eax;

invoke GetDC, NULL; Get a Hardware DC for our screen...
mov ScreenDC, eax;


; Select the bitmap into our memory DC
mov edx, WTStruct
mov edx, ;

invoke SelectObject, BitmapDC, edx; Select the capture bitmap into the memory DC
mov pOldBitmap, eax;


mov edx, WTStruct
mov eax, ;
mov ebx, ;

;Blit our watered bitmap onto the screenDC...

invoke BitBlt, ScreenDC ,eax ,ebx ,TILE_SIZE ,TILE_SIZE ,BitmapDC ,0 ,0 ,SRCCOPY;

; Now clean up our GDI stuff....

invoke SelectObject, BitmapDC, pOldBitmap; Select the bitmap out of its DC

invoke DeleteDC, BitmapDC; Delete the DCs....
invoke ReleaseDC, NULL, ScreenDC;

invoke Sleep, NULL; Surrender control to a sibling thread
ret

PaintWaterTile endp

;################################################################################################

DestroyObjects proc WTStruct:LPWaterTileStruct

mov edx, WTStruct;
mov edx, ;
invoke DeleteObject, edx;

mov edx, WTStruct;
mov edx, ;
invoke DeleteObject, edx;

mov edx, WTStruct;
mov edx, ;
invoke GlobalFree, edx;

mov edx, WTStruct;
mov edx, ;
invoke GlobalFree, edx;

mov edx, WTStruct; Set the IsInUse member to FALSE
xor eax, eax;
mov , eax;

ret
DestroyObjects endp

;################################################################################################

FillWTStruct proc WTStruct:LPWaterTileStruct, OffSetX:DWORD, OffSetY:DWORD, DropDepth:DWORD

mov edx, WTStruct;
mov eax, 1;
mov , eax; Set the IsInUse member to TRUE

mov eax, DropDepth; Set the Drop Depth
mov , eax;

mov eax, OffSetX; Set the X OffSet
mov , eax;

mov eax, OffSetY; Set the Y Offset
mov , eax;

ret

FillWTStruct endp

;################################################################################################

SetupBitmapInfoStruct proc BIH:PBITMAPINFO, PicWidth:DWORD, PicHeight:DWORD

mov edx, BIH;

mov ebx, SIZEOF BITMAPINFOHEADER;
mov , ebx;

mov ebx, PicWidth;
mov , ebx;
mov ebx, PicHeight;
mov , ebx;

mov bx, 1;
mov , bx;

mov bx, 32;
mov , bx;

ret

SetupBitmapInfoStruct endp

;################################################################################################

TRand proc Range:DWORD ; I got the integer part of this from the C++ libs. This function
; returns an integer between 0 and Range instead of 0 and RAND_MAX
LOCAL TempInt:DWORD
LOCAL RMax:DWORD

mov eax, TRAND_MAX;
mov RMax, eax;

mov eax, seed;
imul eax, eax,343FDh;
add eax, 269EC3h;
mov seed,eax;
sar eax,10h;
and eax,7FFFh;

mov TempInt, eax;

fild TempInt;
fild RMax;
fdivp st(1), st(0);
fild Range;
fmulp st(1), st(0);
fistp TempInt;

mov eax, TempInt;
ret

TRand endp

;################################################################################################

end WaterTiles
Posted on 2002-01-19 03:07:00 by ViaX