comment $
//-----------------------------------------------------------------------------------//
//  Source code                                                                      //
//                                                                                   //
//  Written      by  Chib, amdtm                     http://www.xxcontrols.com       //
//                                                                                   //
//  FileName   : Color.inc                                                           //
//  Description: libraries of functions for work with menu                           //
//  Version    : 1.00.000, January 1, 2004                                           //
//-----------------------------------------------------------------------------------//
$ 

; #########################################################################
;                                                                         ;
; Процедура изменяет значение состовляющих цвета RGB на более светлые     ;                           ;
; чем больше параметр lScale тем светлее получиться цвет.                 ;
;                                                                         ;
; #########################################################################

CalculateRGB PROTO :DWORD, :COLORREF, :COLORREF, :BYTE
CreateFillBmp PROTO :DWORD, :DWORD, :DWORD, :BYTE, :BYTE, :COLORREF
BlendPalette PROTO :DWORD, :DWORD, :COLORREF, :BYTE, :BYTE

.code

LightenColor proc uses ebx lScale :DWORD, lColor :COLORREF

    LOCAL R :DWORD
    LOCAL G :DWORD
    LOCAL B :DWORD

    GetRValue lColor    
    mov ebx, 255
    sub ebx, eax
    mov R, eax
    invoke MulDiv, ebx, lScale, 255
    add R, eax
    
    GetGValue lColor
    mov ebx, 255
    sub ebx, eax
    mov G, eax
    invoke MulDiv, ebx, lScale, 255
    add G, eax    
  
    GetBValue lColor
    mov ebx, 255
    sub ebx, eax
    mov B, eax
    invoke MulDiv, ebx, lScale, 255
    add B, eax 
    
    RGB byte ptr R, byte ptr G, byte ptr B    
  
    ret
LightenColor endp

; #########################################################################
;                                                                         ;
; Процедура изменяет значение состовляющих цвета RGB на более тёмные      ;                           ;
; чем больше параметр lScale тем темнее получиться цвет.                  ;
;                                                                         ;
; #########################################################################

DarkenColor proc uses ebx lScale :DWORD, lColor :COLORREF

    LOCAL R :DWORD
    LOCAL G :DWORD
    LOCAL B :DWORD

    GetRValue lColor
    mov ebx, 255
    sub ebx, lScale
    invoke MulDiv, eax, ebx, 255
    mov R, eax
    
    GetGValue lColor
    mov ebx, 255
    sub ebx, lScale
    invoke MulDiv, eax, ebx, 255
    mov G, eax
    
    GetBValue lColor
    mov ebx, 255
    sub ebx, lScale
    invoke MulDiv, eax, ebx, 255
    mov B, eax
    
    RGB byte ptr R, byte ptr G, byte ptr B

    ret
DarkenColor endp

; (86a + 14b) / 100

MixedColor proc colorA :COLORREF, colorB :COLORREF

    LOCAL R :DWORD
    LOCAL G :DWORD
    LOCAL B :DWORD

    GetRValue colorA
    invoke MulDiv, 86, eax, 100
    mov R, eax  
    GetRValue colorB
    invoke MulDiv, 14, eax, 100
    add R, eax      

    GetGValue colorA
    invoke MulDiv, 86, eax, 100
    mov G, eax  
    GetGValue colorB
    invoke MulDiv, 14, eax, 100
    add G, eax      

    GetBValue colorA
    invoke MulDiv, 86, eax, 100
    mov B, eax  
    GetBValue colorB
    invoke MulDiv, 14, eax, 100
    add B, eax      

    RGB byte ptr R, byte ptr G, byte ptr B

    ret
MixedColor endp

; (7a + 3b) / 10

MidColor proc colorA :COLORREF, colorB :COLORREF

    LOCAL R :DWORD
    LOCAL G :DWORD
    LOCAL B :DWORD

    GetRValue colorA
    invoke MulDiv, 7, eax, 10
    mov R, eax  
    GetRValue colorB
    invoke MulDiv, 3, eax, 10
    add R, eax      

    GetGValue colorA
    invoke MulDiv, 7, eax, 10
    mov G, eax  
    GetGValue colorB
    invoke MulDiv, 3, eax, 10
    add G, eax      

    GetBValue colorA
    invoke MulDiv, 7, eax, 10
    mov B, eax  
    GetBValue colorB
    invoke MulDiv, 3, eax, 10
    add B, eax      

    RGB byte ptr R, byte ptr G, byte ptr B

    ret
MidColor endp

; #########################################################################
;                                                                         ;
; Процедура возвращает цвет подходящий для темы XP                        ;                           ;
;                                                                         ;
; #########################################################################

GetXpHighlightColor proc uses edx

    call NumColorBits
    .if eax > 8
        invoke GetSysColor, COLOR_WINDOW
        mov edx, eax
        invoke GetSysColor, COLOR_HIGHLIGHT
        invoke MidColor,  edx, eax
    .else
        invoke GetSysColor, COLOR_WINDOW
    .endif

    ret
GetXpHighlightColor endp

; Grayscale = ( Red*30 + Green*59 + Blue*11 + 50 ) / 100
; Grayscale = ( Red*77 + Green*151 + Blue*28 + 50 ) / 256

GrayColor proc lColor :COLORREF

    LOCAL R :DWORD
    LOCAL G :DWORD

    GetRValue lColor
    invoke IntMul, eax, 77
    mov R, eax
    
    GetGValue lColor
    invoke IntMul, eax, 151
    mov G, eax
    
    GetBValue lColor
    invoke IntMul, eax, 28
    
    add eax, G
    add eax, R
    add eax, 50
    
    invoke IntDiv, eax, 256         

    ret
GrayColor endp

; #########################################################################
;                                                                         ;
; Процедура возвращает число цветов, которое способен отображать контекст.;                           ;
;                                                                         ;
; #########################################################################

NumColorBits proc

    LOCAL hDCDsk    :HDC
    LOCAL nBits     :DWORD

    mov hDCDsk, $invoke( GetDC, NULL )  ; DC of the desktop
    invoke GetDeviceCaps, hDCDsk, BITSPIXEL	
    .if eax == -1
        mov nBits, 8
    .else
        mov nBits, eax
    .endif
    invoke ReleaseDC, NULL, hDCDsk 
    
    return nBits
    
NumColorBits endp

;	mov1 macro a, b
;		mov eax, b
;		mov a, eax
;	endm
;
;	xora macro
;		xor eax, eax
;	endm
;
;	xorb macro
;		xor ebx, ebx
;	endm
;
;	xord macro
;		xor edx, edx
;	endm

comment $
//-----------------------------------------------------------------------------------//
//  Source code                                                                      //
//                                                                                   //
//  Written      by  Chib, amdtm                     http://www.xxcontrols.com       //
//                                                                                   //
//  FileName   : Gradient.inc                                                        //
//  Description: libraries of functions for work with menu                           //
//  Version    : 1.00.000, January 1, 2004                                           //
//-----------------------------------------------------------------------------------//
$ 

; #########################################################################
;                                                                         ;
; Процедура рисования тени (градиентов) в меню - стиль XP                 ;                           ;
;  
;hDC:HDC         - контекст устройства где будет рисоваться тень (градиент)
;lpRect:DWORD    - указатель на прямоугольник тени (градиентта)
;AlignWidth:BYTE - устанавливает где будет находиться тёмная сторона
;                тени (градиентта) по горизонтали, может принимать значения
;                DARK_LEFT   - слева - направо (слева темнее)
;                DARK_RIGHT  - справа - налево (справа темнее)
;                DARK_NONE   - нет горизонтальной состовляющей градиента.
;AlignHeight:BYTE - устанавливает где будет находиться тёмная сторона
;                тени (градиентта) по вертекали, может принимать значения
;                DARK_UP     - сверху - вниз (сверху темнее)
;                DARK_DOWN   - снизу - вверх (снизу темнее)
;                DARK_NONE   - нет вертикальной состовляющей градиента.
;nHorizDark:BYTE - степень затемнения по горизонтпли (~ 0 -  (max)). !?!
;nVertDark:BYTE  - степень затемнения по вертекали (~ 0 -  (max)). !?!
;
; #########################################################################

DrawShade proc uses ebx hDC :HDC, lpRect:DWORD, AlignWidth :BYTE, AlignHeight :BYTE, 
                             nHorizDark :BYTE, nVertDark :BYTE

    LOCAL X1, Y1            :DWORD
    LOCAL nWidth, nHeight   :DWORD
    LOCAL cnWidth, cnHeight   :DWORD
    LOCAL tClr              :COLORREF
        
        
        mov ebx, lpRect
        
        m2m nWidth, [ebx].RECT.right
        mov eax, [ebx].RECT.left
        sub nWidth, eax                 ; ширина градиента
        m2m cnWidth, nWidth 
        
        m2m nHeight, [ebx].RECT.bottom
        mov eax, [ebx].RECT.top
        sub nHeight, eax                ; высота градиента
        m2m cnHeight, nHeight
        
  
        .while nHeight
 
            m2m Y1, [ebx].RECT.bottom
            mov eax, nHeight 
            sub Y1, eax
  
            push nWidth
            .while nWidth
            
                m2m X1, [ebx].RECT.right
                mov eax, nWidth
                sub X1, eax
                mov tClr, $invoke ( GetPixel, hDC, X1, Y1 )
                ; направление горизонтальной состовляющей градиента
                .if AlignWidth == DARK_LEFT                         ; слева - направо (слева темнее)
                    mov eax, nWidth
                .elseif AlignWidth == DARK_RIGHT                    ; справа - налево (справа темнее)
                    mov eax, cnWidth
                    sub eax, nWidth                    
                .elseif AlignWidth == DARK_NONE                     ; нет горизонтальной состовляющей градиента
                    jmp @f               
                .endif                
                
                invoke IntMul, eax, DWORD PTR nHorizDark    ; степень затемнения по горизонтпли (~ 0 - 15 (max)).
                invoke DarkenColor, eax, tClr
                mov tClr, eax
                
@@:
                ; направление вертикальной состовляющей градиента
                .if AlignHeight == DARK_UP                          ; сверху - вниз (сверху темнее)
                    mov eax, nHeight                    
                .elseif AlignHeight == DARK_DOWN                    ; снизу - вверх (снизу темнее)
                    mov eax, cnHeight 
                    sub eax, nHeight
                .elseif AlignHeight == DARK_NONE                    ; нет вертикальной состовляющей градиента
                    jmp @f    
                .endif                
                
                invoke IntMul, eax, DWORD PTR nVertDark     ; степень затемнения по вертекали (~ 0 - 15 (max)).
                invoke DarkenColor, eax, tClr            
                mov tClr, eax
@@:
            
                invoke SetPixel, hDC, X1, Y1, tClr
                         
                dec nWidth
            
            .endw
            pop nWidth
  
         dec nHeight        
        .endw  
  
    ret
DrawShade endp

Gradient_Fill proc uses edi ebx hDC:HDC, pRect:DWORD, StartColor:COLORREF, EndColor:COLORREF, dwMode:BOOLEAN

    LOCAL vert[2]	:TRIVERTEX
    LOCAL Index		:GRADIENT_RECT

	mov edi, pRect
	    
    m2m vert.x, [edi].RECT.left
	m2m vert.y, [edi].RECT.top
	GetRValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Red, eax
	GetGValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Green, eax
	GetBValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Blue, eax
	mov vert.Alpha, 0
	
	mov ebx, sizeof TRIVERTEX
	
	m2m vert[ebx].x, [edi].RECT.right
	m2m vert[ebx].y, [edi].RECT.bottom
	GetRValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov DWORD PTR vert[ebx].Red, eax
	GetGValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov DWORD PTR vert[ebx].Green, eax
	GetBValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov vert[ebx].Blue, ax
	mov vert[ebx].Alpha, 0
	
	mov Index.UpperLeft, 0
	mov Index.LowerRight, 1	
	
	.if dwMode
	   mov eax, GRADIENT_FILL_RECT_V
	.else
	   mov eax, GRADIENT_FILL_RECT_H
	.endif
	
	   invoke GradientFill, hDC, ADDR vert, 2, ADDR Index, 1, eax
    
    return 0
Gradient_Fill endp

;DrawGradient proc uses ebx esi edi hDC:HDC, pRect:DWORD, StartColor:COLORREF, EndColor:COLORREF
;	local iHeight	:DWORD
;	local iWidth	:DWORD
;	local iTmp		:DWORD
;	local NewColor:DWORD
;	local bitmap	:DWORD
;	local pvBits	:DWORD
;	local dcMem		:DWORD
;	local rcRow		:RECT
;	local bmi		:BITMAPINFOHEADER
;	LOCAL bmpsize   :DWORD
;	local SizeLine  :DWORD
;
;
;	mov edi, pRect
;	mov1 rcRow.left, [edi].RECT.left
;	mov1 rcRow.right, [edi].RECT.right
;	mov1 rcRow.bottom, [edi].RECT.bottom
;	dec eax ; 1 pixel rect
;	mov rcRow.top, eax
;
;;	invoke CreateCompatibleDC, hDC
;;	mov dcMem, eax
;;	mov ebx, eax
;
;	push edi
;	lea edi, bmi
;	mov ecx, sizeof(BITMAPINFOHEADER)/4
;	xora
;	rep stosd
;	pop edi
;	mov eax, 16
;	mov bmi.biSize, sizeof(BITMAPINFOHEADER)
;	mov eax, [edi].RECT.right
;	sub eax, [edi].RECT.left
;	mov iWidth, eax
;	mov bmi.biWidth, eax
;
;	mov eax, [edi].RECT.bottom
;	sub eax, [edi].RECT.top
;	mov iHeight, eax
;	neg eax
;	mov bmi.biHeight, eax
;	mov bmi.biPlanes, 1
;	mov bmi.biBitCount, 32;32 four 8-bit components
;	mov bmi.biCompression, BI_RGB
;	invoke IntMul, iWidth, iHeight 
;	invoke IntMul, eax, 4
;	mov bmi.biSizeImage, eax
;	; create our DIB section and select the bitmap into the dc
;	;invoke CreateDIBSection, ebx,addr bmi, DIB_RGB_COLORS, addr pvBits, ecx, ecx ; ecx=0
;	invoke GlobalAlloc, GPTR, bmi.biSizeImage       ;возьмём память
;	mov pvBits, eax
;	test eax, eax
;	jz @@end
;	;mov bitmap, eax
;	;invoke SelectObject, ebx, eax
;	;mov bmi.bmiHeader.biSize, eax
;	mov edi, pvBits
;	xorb
;@@next_row:
;	xora
;	mov NewColor, eax ; zero new color
;	fild iWidth
;	mov iTmp, ebx
;	fild iTmp
;	dw 0F1DEh ;fdivrp; st(1), st(0) ; st(1) = i/length
;	; B
;	mov eax, StartColor
;	and eax, 0ffh
;	mov edx, eax
;	mov ecx, EndColor
;	and ecx, 0ffh
;	sub eax, ecx
;	mov iTmp, eax
;	fild iTmp
;	fmul st(0), st(1) ; st(0) = (R1-R2)*st(1)
;	fistp iTmp
;	mov eax, iTmp
;	neg eax
;	add eax, edx
;	and eax, 0ffh
;	mov NewColor, eax
;
;	; G
;	mov eax, StartColor
;	shr eax, 8
;	and eax, 0ffh
;	mov edx, eax
;	mov ecx, EndColor
;	shr ecx, 8
;	and ecx, 0ffh
;	sub eax, ecx
;	mov iTmp, eax
;	fild iTmp
;	fmul st(0), st(1) ; st(0) = (R1-R2)*st(1)
;	fistp iTmp
;	mov eax, iTmp
;	neg eax
;	add eax, edx
;	and eax, 0ffh
;	shl eax, 8
;	or NewColor, eax
;
;	; R
;	mov eax, StartColor
;	shr eax, 16
;	and eax, 0ffh
;	mov edx, eax
;	mov ecx, EndColor
;	shr ecx, 16
;	and ecx, 0ffh
;	sub eax, ecx
;	mov iTmp, eax
;	fild iTmp
;	dw 0C9DEh ;fmulp ; st(0) = (R1-R2)*st(1)
;	fistp iTmp
;	mov eax, iTmp
;	neg eax
;	add eax, edx
;	and eax, 0ffh
;	shl eax, 16
;	or eax, NewColor
;	bswap eax
;	shr eax, 8
;	
;	mov ecx, iWidth
;	rep stosd
;	
;	inc ebx
;	cmp ebx, iWidth
;	jnz @@next_row
;	mov edi, pRect
;	;invoke BitBlt,hDC,[edi],[edi+4],iWidth,iHeight,dcMem,0,0,SRCCOPY
;	invoke StretchDIBits,hDC,[edi],[edi+4],iWidth,iHeight,0,0,iWidth,iHeight,pvBits,ADDR bmi, DIB_RGB_COLORS, SRCCOPY
;	invoke GlobalFree, pvBits       ;освободим память, занимаемую изображением
;	;PrintDec eax
;	;invoke SelectObject,dcMem, bmi.bmiHeader.biSize
;	;invoke DeleteDC, dcMem
;	;invoke DeleteObject, bitmap
;@@end:
;	ret
;DrawGradient endp

DrawGradient proc uses ebx esi edi hDC:HDC, pRect:DWORD, StartColor:COLORREF, EndColor:COLORREF, dwMode:BOOLEAN
	local iHeight	:DWORD
	local iWidth	:DWORD
	local iTmp		:DWORD
	local NewColor  :DWORD
	local bitmap	:DWORD
	local pvBits	:DWORD
	local dcMem		:DWORD
	local rcRow		:RECT
	local bmi		:BITMAPINFO

	mov edi, pRect
	mov1 rcRow.left, [edi].RECT.left
	mov1 rcRow.right, [edi].RECT.right
	mov1 rcRow.bottom, [edi].RECT.bottom
	dec eax ; 1 pixel rect
	mov rcRow.top, eax

	invoke CreateCompatibleDC, hDC
	mov dcMem, eax
	mov ebx, eax

	push edi
	lea edi, bmi
	mov ecx, sizeof(BITMAPINFO)/4
	xora
	rep stosd
	pop edi
	mov eax, 16
	mov bmi.bmiHeader.biSize, sizeof(BITMAPINFOHEADER)
	mov eax, [edi].RECT.right
	sub eax, [edi].RECT.left
	mov iWidth, eax
	mov bmi.bmiHeader.biWidth, eax

	mov eax, [edi].RECT.bottom
	sub eax, [edi].RECT.top
	mov iHeight, eax
	neg eax
	mov bmi.bmiHeader.biHeight, eax
	mov bmi.bmiHeader.biPlanes, 1
	mov bmi.bmiHeader.biBitCount, 32;32 four 8-bit components
	mov bmi.bmiHeader.biCompression, BI_RGB
	; create our DIB section and select the bitmap into the dc
	invoke CreateDIBSection, ebx,addr bmi, DIB_RGB_COLORS, addr pvBits, ecx, ecx ; ecx=0
	test eax, eax
	jz @@end
	mov bitmap, eax
	invoke SelectObject, ebx, eax
	mov bmi.bmiHeader.biSize, eax
	mov edi, pvBits
	xorb
@@next_row:
	xora
	mov NewColor, eax ; zero new color
	.if dwMode
	   fild iHeight
	.else
	   fild iWidth
	.endif
	mov iTmp, ebx
	fild iTmp
	dw 0F1DEh ;fdivrp; st(1), st(0) ; st(1) = i/length
	; B
	mov eax, StartColor
	and eax, 0ffh
	mov edx, eax
	mov ecx, EndColor
	and ecx, 0ffh
	sub eax, ecx
	mov iTmp, eax
	fild iTmp
	fmul st(0), st(1) ; st(0) = (R1-R2)*st(1)
	fistp iTmp
	mov eax, iTmp
	neg eax
	add eax, edx
	and eax, 0ffh
	mov NewColor, eax

	; G
	mov eax, StartColor
	shr eax, 8
	and eax, 0ffh
	mov edx, eax
	mov ecx, EndColor
	shr ecx, 8
	and ecx, 0ffh
	sub eax, ecx
	mov iTmp, eax
	fild iTmp
	fmul st(0), st(1) ; st(0) = (R1-R2)*st(1)
	fistp iTmp
	mov eax, iTmp
	neg eax
	add eax, edx
	and eax, 0ffh
	shl eax, 8
	or NewColor, eax

	; R
	mov eax, StartColor
	shr eax, 16
	and eax, 0ffh
	mov edx, eax
	mov ecx, EndColor
	shr ecx, 16
	and ecx, 0ffh
	sub eax, ecx
	mov iTmp, eax
	fild iTmp
	dw 0C9DEh ;fmulp ; st(0) = (R1-R2)*st(1)
	fistp iTmp
	mov eax, iTmp
	neg eax
	add eax, edx
	and eax, 0ffh
	shl eax, 16
	or eax, NewColor
	bswap eax
	shr eax, 8
	
	.if dwMode
	   mov ecx, iWidth
	   rep stosd
	.else
        push ebx    ; сохраним для 1 го цикла, будем использовать во вложенном цикле
        push edi    
        ; вычислим размер строки развёртки в байтах
        mov ecx, iWidth
        shl ecx, 2
        sub ecx, 4
        xorb
@@:
        
        stosd 
        add edi, ecx 
        
        inc ebx
        cmp ebx, iHeight
        jnz @B
        pop edi    
        pop ebx
        add edi, 4	
	.endif
	
	inc ebx
	.if dwMode
	   cmp ebx, iHeight
	.else
	   cmp ebx, iWidth
	.endif
	jnz @@next_row
	mov edi, pRect
	invoke BitBlt,hDC,[edi],[edi+4],iWidth,iHeight,dcMem,0,0,SRCCOPY
	invoke SelectObject,dcMem, bmi.bmiHeader.biSize
	invoke DeleteDC, dcMem
	invoke DeleteObject, bitmap
@@end:
	ret
DrawGradient endp

; #########################################################################
;                                                                         ;
; Процедура рисования иконки в меню.                                      ;
;                                                                         ;
; #########################################################################

DrawIcn proc uses ebx hDC:HDC, lpRect:DWORD, HIcon:HICON, uFlags:BYTE, fEmboss:BYTE

    LOCAL RctIcon    :RECT
    LOCAL xX :DWORD, yY :DWORD
    LOCAL MonoIcon   :DWORD
    LOCAL iconinfo   :ICONINFO
    LOCAL bmp        :BITMAP
    LOCAL hMemDC     :HDC
    LOCAL hBrushShade:HBRUSH    ; Кисть заливки тени под иконкой итема.
    LOCAL OldBrush   :HBRUSH    ; Кисть по умолчанию
    LOCAL OldBmp     :HBITMAP
    LOCAL i_X        :DWORD
    LOCAL i_Y        :DWORD
    
    LOCAL OldTextClr :DWORD
    LOCAL OldBkClr   :DWORD
    
    LOCAL hMemBmp    :HBITMAP
    
    mov ebx, lpRect

;    RGB 255, 255, 255        ; цвет тени обрасываемом иконками
    invoke GetSysColor, COLOR_GRAYTEXT
    mov hBrushShade, $invoke (CreateSolidBrush, eax)    

;   высота и ширина иконки
    invoke GetIconInfo, HIcon,ADDR iconinfo
    invoke GetObject, iconinfo.hbmColor, sizeof(BITMAP), ADDR bmp
   
;   Координаты верхнего левого угла иконки.
   
    mov eax, WidthBorder    
    sub eax, bmp.bmWidth             ; 16 доделать!!! Это что размер иконки?
    invoke IntDiv, eax, 2    
    mov xX, eax             ;[[WidthHeight-16]/2]
    
    mov eax, HeightBorder    
    sub eax, bmp.bmHeight            ; 16
    invoke IntDiv, eax, 2
    mov yY, eax             ;[[WidthHeight-16]/2]
        
    xor eax, eax                    ; состояние вывода
    mov al, uFlags 
    and al, GRAY or SELECT or UNSELECT
    
    .if al == UNSELECT
        
    .elseif al == SELECT    

    ; ЕСЛИ ОСНАВНАЯ ИКОНКА СДВИНУТА, ОТОБРАЗИМ ТЕНЬ ОТ ИКОНКИ       
        mov eax, [ebx].RECT.left
        add eax, xX
        inc eax
        mov RctIcon.left, eax
        mov eax, [ebx].RECT.top
        add eax, yY
        inc eax
        mov RctIcon.top, eax
        
        dec xX     ; нормальная иконка поднимем вверх
        dec yY

        mov hMemDC, $invoke (CreateCompatibleDC,hDC)
        invoke SetBkColor,hDC,White     
        mov OldBmp, $invoke ( SelectObject,hMemDC,iconinfo.hbmMask )
        mov OldBrush, $invoke ( SelectObject, hDC, hBrushShade )
        invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))
        invoke SelectObject, hDC, OldBrush
        invoke SelectObject, hMemDC, OldBmp
        invoke DeleteDC, hMemDC
        
    .elseif al == GRAY                  

    ; ТЕНЬ ОТ ИКОНКИ        
        mov eax, [ebx].RECT.left
        add eax, xX
        mov RctIcon.left, eax
        mov eax, [ebx].RECT.top
        add eax, yY
        mov RctIcon.top, eax

        mov hMemDC, $invoke (CreateCompatibleDC,hDC)
        mov hMemBmp, $invoke (CreateCompatibleBitmap,hMemDC, bmp.bmWidth, bmp.bmHeight)
        mov OldBmp, $invoke (SelectObject, hMemDC, hMemBmp)
        
        invoke PatBlt, hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, WHITENESS        
        invoke DrawIconEx, hMemDC, 0,0, HIcon, bmp.bmWidth, bmp.bmHeight, NULL, NULL,DI_NORMAL
        
        ; преобразуем растр в hMemDC в монохромный        
        mov OldTextClr, $invoke (SetTextColor,hDC,Black)
        mov OldBkClr, $invoke (SetBkColor,hDC,White)
        
        .if fEmboss         ; для стиля 2000 - TRUE
            invoke GetSysColorBrush, COLOR_BTNHIGHLIGHT
            invoke SelectObject,hDC,eax
            mov OldBrush, eax            
            invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))                                       
            invoke GetSysColorBrush, COLOR_BTNSHADOW
            invoke SelectObject,hDC,eax
            dec RctIcon.left
            dec RctIcon.top
            invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))
            inc RctIcon.left
            inc RctIcon.top 
            jmp @f      
        .endif       
        
        ; Выведем черный контур цветом кисти                    ; для стиля XP
        mov OldBrush, $invoke (SelectObject,hDC,hBrushShade)
        invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))
        
@@:
        invoke SelectObject, hDC, OldBrush
        ; востановим цвет фона и текста в контексте
        invoke SetTextColor,hDC,OldTextClr
        invoke SetBkColor,hDC,OldBkClr    

        ; освободим ресурсы GDI
        invoke SelectObject, hMemDC, OldBmp
        invoke DeleteObject, hMemBmp
        invoke DeleteDC, hMemDC

        jmp @f ; НЕ ПРОРИСОВЫВАТЬ ЦВЕТНУЮ ИКОНКУ
        
    .endif  

        mov eax, [ebx].RECT.left
        add eax, xX
        mov RctIcon.left, eax
        mov eax, [ebx].RECT.top
        add eax, yY 
        mov RctIcon.top, eax

        invoke DrawIconEx, hDC, RctIcon.left, RctIcon.top, HIcon, bmp.bmWidth, bmp.bmHeight, NULL, NULL, DI_NORMAL

@@:
        invoke DeleteObject, iconinfo.hbmMask
        invoke DeleteObject, iconinfo.hbmColor
        invoke DeleteObject, hBrushShade
        
   ret
DrawIcn endp

DrawIcnRect  proc uses ebx hDC:HDC, lpRect:DWORD, HIcon:HICON, uFlags:BYTE, fEmboss:BYTE

    LOCAL RctIcon    :RECT
    LOCAL xX :DWORD, yY :DWORD
    LOCAL MonoIcon   :DWORD
    LOCAL iconinfo   :ICONINFO
    LOCAL bmp        :BITMAP
    LOCAL hMemDC     :HDC
    LOCAL hBrushShade:HBRUSH    ; Кисть заливки тени под иконкой итема.
    LOCAL OldBrush   :HBRUSH    ; Кисть по умолчанию
    LOCAL OldBmp     :HBITMAP
    LOCAL i_X        :DWORD
    LOCAL i_Y        :DWORD
    
    LOCAL OldTextClr :DWORD
    LOCAL OldBkClr   :DWORD
    
    LOCAL hMemBmp    :HBITMAP
    
    mov ebx, lpRect

;    RGB 255, 255, 255        ; цвет тени обрасываемом иконками
    invoke GetSysColor, COLOR_GRAYTEXT
    mov hBrushShade, $invoke (CreateSolidBrush, eax)    

;   высота и ширина иконки
    invoke GetIconInfo, HIcon,ADDR iconinfo
    invoke GetObject, iconinfo.hbmColor, sizeof(BITMAP), ADDR bmp
   
;   Координаты верхнего левого угла иконки.
   
    mov eax, [ebx].RECT.right
    sub eax, [ebx].RECT.left
   
    sub eax, bmp.bmWidth             ; 16 доделать!!! Это что размер иконки?
    invoke IntDiv, eax, 2    
    mov xX, eax             ;[[WidthHeight-16]/2]
   
    mov eax, [ebx].RECT.bottom
    sub eax, [ebx].RECT.top  
    
    sub eax, bmp.bmHeight            ; 16
    invoke IntDiv, eax, 2
    mov yY, eax             ;[[WidthHeight-16]/2]
        
    xor eax, eax                    ; состояние вывода
    mov al, uFlags 
    and al, GRAY
    
    .if al == GRAY                  

    ; ТЕНЬ ОТ ИКОНКИ        
        mov eax, [ebx].RECT.left
        add eax, xX
        mov RctIcon.left, eax
        mov eax, [ebx].RECT.top
        add eax, yY
        mov RctIcon.top, eax

        mov hMemDC, $invoke (CreateCompatibleDC,hDC)
        mov hMemBmp, $invoke (CreateCompatibleBitmap,hMemDC, bmp.bmWidth, bmp.bmHeight)
        mov OldBmp, $invoke (SelectObject, hMemDC, hMemBmp)
        
        invoke PatBlt, hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, WHITENESS        
        invoke DrawIconEx, hMemDC, 0,0, HIcon, bmp.bmWidth, bmp.bmHeight, NULL, NULL,DI_NORMAL
        
        ; преобразуем растр в hMemDC в монохромный        
        mov OldTextClr, $invoke (SetTextColor,hDC,Black)
        mov OldBkClr, $invoke (SetBkColor,hDC,White)
        
        .if fEmboss         ; для стиля 2000 - TRUE
            invoke GetSysColorBrush, COLOR_BTNHIGHLIGHT
            invoke SelectObject,hDC,eax
            mov OldBrush, eax            
            invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))                                       
            invoke GetSysColorBrush, COLOR_BTNSHADOW
            invoke SelectObject,hDC,eax
            dec RctIcon.left
            dec RctIcon.top
            invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))
            inc RctIcon.left
            inc RctIcon.top 
            jmp @f      
        .endif       
        
        ; Выведем черный контур цветом кисти                    ; для стиля XP
        mov OldBrush, $invoke (SelectObject,hDC,hBrushShade)
        invoke BitBlt,hDC,RctIcon.left, RctIcon.top, bmp.bmWidth, bmp.bmHeight,hMemDC,0, 0,0B8074Ah ; D^(S&(P^D)))
        
@@:
        invoke SelectObject, hDC, OldBrush
        ; востановим цвет фона и текста в контексте
        invoke SetTextColor,hDC,OldTextClr
        invoke SetBkColor,hDC,OldBkClr    

        ; освободим ресурсы GDI
        invoke SelectObject, hMemDC, OldBmp
        invoke DeleteObject, hMemBmp
        invoke DeleteDC, hMemDC

        jmp @f ; НЕ ПРОРИСОВЫВАТЬ ЦВЕТНУЮ ИКОНКУ
        
    .endif  

        mov eax, [ebx].RECT.left
        add eax, xX
        mov RctIcon.left, eax
        mov eax, [ebx].RECT.top
        add eax, yY 
        mov RctIcon.top, eax

        invoke DrawIconEx, hDC, RctIcon.left, RctIcon.top, HIcon, bmp.bmWidth, bmp.bmHeight, NULL, NULL, DI_NORMAL

@@:
        invoke DeleteObject, iconinfo.hbmMask
        invoke DeleteObject, iconinfo.hbmColor
        invoke DeleteObject, hBrushShade
        
   ret
DrawIcnRect endp

; #########################################################################
;                                                                         ;
; Отображает DDB растр в заданный контекст                                ;
;                                                                         ;
; #########################################################################

DrawDDB proc hDC:HDC, lpRect:DWORD, hBmpDDB:HBITMAP

    LOCAL hOldBmp   :HBITMAP
    LOCAL nWidth    :DWORD
    LOCAL nHeight   :DWORD
    LOCAL hMemDC    :HDC
    LOCAL RctBtn    :RECT

            invoke CopyRect, ADDR RctBtn, lpRect

            invoke CreateCompatibleDC, hDC
            mov hMemDC, eax
            
            invoke InflateRect, ADDR RctBtn, -2, -2
            
            mov eax, RctBtn.right
            sub eax, RctBtn.left
            mov nWidth, eax
            mov eax, RctBtn.bottom
            sub eax, RctBtn.top
            mov nHeight, eax

            invoke SelectObject, hMemDC, hBmpDDB
            mov hOldBmp, eax
            
            invoke BitBlt, hDC, RctBtn.left, RctBtn.top, nWidth, nHeight, hMemDC, 0, 0,SRCCOPY
            
            invoke SelectObject, hMemDC, hOldBmp
            invoke DeleteDC, hMemDC
            
            invoke InflateRect, ADDR RctBtn, 2, 2

	ret
DrawDDB endp

CreateFillBmp proc uses edi ShadeID:DWORD, pRect:DWORD, granularity:DWORD, highlight:BYTE, coloring:BYTE, color:COLORREF
	LOCAL iHeight	:SDWORD
	LOCAL iWidth	:SDWORD
	LOCAL bmi		:BITMAPINFOHEADER
	LOCAL SizeLine  :DWORD
    LOCAL SizeImage :DWORD
    LOCAL SizeAll   :DWORD
    LOCAL pvBmi     :DWORD
    LOCAL pvPalete  :DWORD
    LOCAL pvBits	:DWORD
    LOCAL pvPalete2 :DWORD
    LOCAL hicr      :COLORREF
    LOCAL midcr     :COLORREF
    LOCAL locr      :COLORREF
    LOCAL i         :DWORD
    LOCAL j         :DWORD
    LOCAL R         :DWORD
    LOCAL G         :DWORD
    LOCAL B         :DWORD
    LOCAL R_2       :DWORD
    LOCAL G_2       :DWORD
    LOCAL B_2       :DWORD
    LOCAL grainx2   :DWORD
    LOCAL tmp       :DWORD
    LOCAL posDst    :DWORD
    LOCAL Rct       :RECT
    LOCAL m_nBPS    :DWORD
    LOCAL hDCDsk    :HDC
    LOCAL hBmp      :HBITMAP
    LOCAL hBmp2     :HBITMAP
    LOCAL idxmax    :SDWORD
    LOCAL idxmin    :SDWORD
    LOCAL a         :SDWORD
    LOCAL d         :SDWORD
    LOCAL k         :SDWORD
    LOCAL h         :SDWORD
    LOCAL y         :SDWORD
    LOCAL x         :SDWORD
    LOCAL xs        :SDWORD
    

    invoke GetDC, NULL
    mov hDCDsk, eax

    invoke CopyRect, ADDR Rct, pRect
    
    lea edi, bmi
	mov ecx, sizeof(BITMAPINFOHEADER)/4
	xora
	rep stosd
    
	mov eax, Rct.right
	sub eax, Rct.left
	mov iWidth, eax
	xor eax, eax
    mov         eax, 8
    imul        eax, iWidth 
    add         eax, 1Fh 
    shr         eax,5 
    shl         eax,2
	mov         m_nBPS, eax
	mov eax, Rct.bottom
	sub eax, Rct.top
	mov iHeight, eax
    imul        eax,m_nBPS
	mov SizeImage, eax
	; create our DIB section and select the bitmap into the dc
    add eax, sizeof(RGBQUAD)*256+sizeof(BITMAPINFOHEADER)
    mov SizeAll, eax
	invoke GlobalAlloc, GPTR, SizeAll       ;возьмём память
    mov pvBmi, eax
    add eax, sizeof(BITMAPINFOHEADER)
    mov pvPalete, eax
    add eax, sizeof(RGBQUAD)*256   
	mov pvBits, eax
	
;	invoke memfill, pvBits, SizeImage, 1
	
	mov bmi.biSize, sizeof(BITMAPINFOHEADER)

	m2m bmi.biWidth, iWidth
;	mov eax, iHeight
;	neg eax
	m2m bmi.biHeight, iHeight
	m2m bmi.biSizeImage, SizeImage
	mov bmi.biPlanes, 1
	mov bmi.biBitCount, 8 ; four 8-bit components
	mov bmi.biCompression, BI_RGB
	mov bmi.biClrImportant, 0
	mov bmi.biClrUsed, 0

    invoke MemCopy, ADDR bmi, pvBmi, sizeof(BITMAPINFOHEADER)    
    	    
    .if highlight
    	invoke GlobalAlloc, GPTR, sizeof(RGBQUAD)*256       ;возьмём память
        mov pvPalete2, eax
    .endif    
    
	; get the button base colors
	invoke GetSysColor, COLOR_BTNHIGHLIGHT
	mov hicr, eax
	invoke GetSysColor, COLOR_BTNFACE	
	mov midcr, eax
	invoke GetSysColor, COLOR_BTNSHADOW
	mov locr, eax
	
    ; build the shaded palette
    ;---------------------------------------
    mov i, 0
;    mov edi, pvPalete
    	
@@:	
    invoke CalculateRGB, i, locr, midcr, 1
	mov R, eax
	invoke CalculateRGB, i, locr, midcr, 2
	mov G, eax
	invoke CalculateRGB, i, locr, midcr, 3
	mov B, eax
	
	.if coloring
    	invoke BlendPalette, R, i, color, coloring, 1
    	mov R, eax
    	invoke BlendPalette, G, i, color, coloring, 2
    	mov G, eax
    	invoke BlendPalette, B, i, color, coloring, 3
    	mov B, eax
    .endif
    
    .if highlight
    	invoke BlendPalette, R, i, hicr, highlight, 1
    	mov R_2, eax
    	invoke BlendPalette, G, i, hicr, highlight, 2
    	mov G_2, eax
    	invoke BlendPalette, B, i, hicr, highlight, 3
    	mov B_2, eax
    	
    	mov edi, pvPalete2
    	mov eax, i
    	sal eax, 2
    	add edi, eax 
        RGBQ byte ptr R_2, byte ptr G_2, byte ptr B_2
        stosd    	
    .endif

 
    mov edi, pvPalete
    mov eax, i
    sal eax, 2
    add edi, eax 
    RGBQ byte ptr R, byte ptr G, byte ptr B
    stosd
	
	inc i
	cmp i, 129
	jb @b
	
;	DumpMem pvPalete, 128
	
	
	;---------------------------------------
    mov i, 1
;    mov edi, pvPalete
;    add edi, sizeof(RGBQUAD)*127
    	
@@:	
    invoke CalculateRGB, i, midcr, hicr, 1
	mov R, eax
	invoke CalculateRGB, i, midcr, hicr, 2
	mov G, eax
	invoke CalculateRGB, i, midcr, hicr, 3
	mov B, eax
	
	.if coloring
    	invoke BlendPalette, R, i, color, coloring, 1
    	mov R, eax
    	invoke BlendPalette, G, i, color, coloring, 2
    	mov G, eax
    	invoke BlendPalette, B, i, color, coloring, 3
    	mov B, eax
    .endif
    
    .if highlight
    	invoke BlendPalette, R, i, hicr, highlight, 1
    	mov R_2, eax
    	invoke BlendPalette, G, i, hicr, highlight, 2
    	mov G_2, eax
    	invoke BlendPalette, B, i, hicr, highlight, 3
    	mov B_2, eax
    	
    	mov edi, pvPalete2
    	add edi, sizeof(RGBQUAD)*127
    	mov eax, i
        sal eax, 2
    	add edi, eax 
        RGBQ byte ptr R_2, byte ptr G_2, byte ptr B_2
        stosd   	
    .endif
	
	mov edi, pvPalete
	add edi, sizeof(RGBQUAD)*127
	mov eax, i
    sal eax, 2
    add edi, eax 
    RGBQ byte ptr R, byte ptr G, byte ptr B
    stosd	
	
	inc i
	cmp i, 129
	jb @b
	
;	DumpMem pvPalete, 256

    ; int grainx2=RAND_MAX/(max(1,2*granularity));
    mov         eax,granularity 
    shl         eax,1
    mov         tmp,eax 
    cmp         eax,1 
    jge         @f
    mov         tmp,1  
@@: mov         eax,7FFFh 
    cdq              
    idiv        tmp
    mov         grainx2,eax
    
	; idxmax=255-granularity;
    mov idxmax, 0FFh
    mov eax, granularity 
    sub idxmax, eax 
	
	; idxmin=granularity;
	m2m idxmin, granularity	
	
    m2m posDst, pvBits
    mov i, 0
    mov j, 0
       
   .if ShadeID == FILL_NOISE 

;	default:	//SHS_NOISE
;		for(i = 0; i < sYSize; i++) {
;			for(j = 0; j < sXSize; j++) {
;				posDst[j]=128+rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
    
next_y:	

       mov j, 0     
next_x:
    
        ;invoke nrandom, RAND_MAX
        call ansi_rand
        cdq              
        idiv        grainx2
        add         eax,80h 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],al
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y

    .elseif ShadeID == FILL_SOFTBUMP
    
;	case 6: //SHS_SOFTBUMP
;		for(i = 0; i < sYSize; i++) {
;			h=(255*i/sYSize)-127;
;			for(j = 0; j < sXSize; j++) {
;				k=(255*(sXSize-j)/sXSize)-127;
;				k=(h*(h*h)/128)/128+(k*(k*k)/128)/128;
;				k=k*(128-granularity)/128+128;
;				if (k<idxmin) k=idxmin;
;				if (k>idxmax) k=idxmax;
;				posDst[j]=(BYTE)k;
;				posDst[j]+=rand()/(grainx2-granularity);
;			}
;			posDst+=bytes;
;		}
;		break;
    
next_y2:	
       
       ; h=(255*i/sYSize)-127;
       mov         eax, i 
       imul        eax,eax,0FFh 
       cdq              
       idiv        iHeight 
       sub         eax, 7Fh 
       mov         h, eax
       
       mov j, 0     
next_x2:

        ; k=(255*(sXSize-j)/sXSize)-127;    
        mov         eax, iWidth
        sub         eax, j 
        imul        eax, eax, 0FFh 
        cdq
        idiv        iWidth
        sub         eax, 7Fh 
        mov         k, eax

        ; k=(h*(h*h)/128)/128+(k*(k*k)/128)/128;    
        mov         eax, h 
        imul        eax, h 
        imul        eax, h 
        cdq              
        and         edx, 7Fh 
        add         eax, edx 
        sar         eax, 7 
        cdq              
        and         edx, 7Fh 
        add         eax, edx 
        mov         ecx, eax 
        sar         ecx, 7 
        mov         edx, k 
        imul        edx, k 
        mov         eax, edx 
        imul        eax, k 
        cdq              
        and         edx, 7Fh 
        add         eax, edx 
        sar         eax, 7 
        cdq              
        and         edx, 7Fh 
        add         eax, edx 
        sar         eax, 7 
        add         ecx, eax 
        mov         k, ecx        
    
        xor edx, edx
        ; k=k*(128-granularity)/128+128;    
        ;movzx       eax, byte ptr [granularity] 
        mov         eax, 80h 
        sub         eax, granularity
        imul        eax, k 
        cdq              
        and         edx, 7Fh 
        add         eax, edx 
        sar         eax, 7 
        add         eax, 80h 
        mov         k, eax
        
        ; if (k<idxmin) k=idxmin;
        .if  eax < idxmin
            m2m k, idxmin        
        .endif        
        
        ; if (k>idxmax) k=idxmax;
        .if eax > idxmax
            m2m k, idxmax      
        .endif
    
	    ; posDst[j]=(BYTE)k;
        mov         edx, posDst 
        add         edx, j 
        xor         eax, eax
        mov         al, byte ptr [k]
        mov         byte ptr [edx],al
    
        ; сглаживание переходов цветов
        ; posDst[j]+=rand()/grainx2-granularity;
        ;invoke nrandom, RAND_MAX
        call        ansi_rand
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl    
    
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x2	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y2
      
    .elseif ShadeID == FILL_VBUMP   
 
;	case 5: // SHS_VBUMP
;		for(j = 0; j < sXSize; j++) {
;			k=(255*(sXSize-j)/sXSize)-127;
;			k=(k*(k*k)/128)/128;
;			k=(k*(128-granularity))/128+128;
;			for(i = 0; i < sYSize; i++) {
;				posDst[j+i*bytes]=(BYTE)k;
;				posDst[j+i*bytes]+=rand()/grainx2-granularity;
;			}
;		}
;		break; 
 
next_x3:	

        ; k=(255*(sXSize-j)/sXSize)-127;
        mov         eax, iWidth
        sub         eax,j 
        imul        eax,eax,0FFh 
        cdq              
        idiv        iWidth
        sub         eax,7Fh 
        mov         k,eax

        ; k=(k*(k*k)/128)/128;
        mov         eax,k 
        imul        eax,k 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        mov         k,eax

        ; k=(k*(128-granularity))/128+128;
        movzx       eax,byte ptr [granularity] 
        mov         ecx,80h 
        sub         ecx,eax 
        mov         eax,ecx 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        add         eax,80h 
        mov         k,eax

        mov i, 0     
next_y3:

        ; posDst[j+i*bytes]=(BYTE)k;
        
        mov         eax,i 
        imul        eax,m_nBPS
        add         eax,j 
        mov         ecx,posDst 
        mov         dl,byte ptr [k] 
        mov         byte ptr [ecx+eax],dl  

        ; posDst[j+i*bytes]+=rand()/grainx2-granularity;
        mov         esi,i 
        imul        esi,m_nBPS
        add         esi,j 
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        movzx       ecx,byte ptr [edx+esi] 
        add         ecx,eax 
        mov         edx,i 
        imul        edx,m_nBPS 
        add         edx,j 
        mov         eax,posDst 
        mov         byte ptr [eax+edx],cl 
         
    	inc i
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y3	
    	
    	inc j
    
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x3      

    .elseif ShadeID == FILL_HBUMP
  
;	case 4: //SHS_HBUMP
;		for(i = 0; i < sYSize; i++) {
;			k=(255*i/sYSize)-127;
;			k=(k*(k*k)/128)/128;
;			k=(k*(128-granularity))/128+128;
;			for(j = 0; j < sXSize; j++) {
;				posDst[j]=(BYTE)k;
;				posDst[j]+=rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
;		break;
    
next_y4:

        ; k=(255*i/sYSize)-127;
        mov         eax,i 
        imul        eax,eax,0FFh 
        cdq              
        idiv        iHeight 
        sub         eax,7Fh 
        mov         k,eax	

        ; k=(k*(k*k)/128)/128;
        mov         eax,k
        imul        eax,k 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        mov         k,eax

; k=(k*(128-granularity))/128+128;
        movzx       eax,byte ptr [granularity] 
        mov         ecx,80h 
        sub         ecx,eax 
        mov         eax,ecx 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        add         eax,80h 
        mov         k,eax

        mov j, 0     
next_x4:
    
        ; posDst[j]=(BYTE)k;
        mov         eax,posDst 
        add         eax,j 
        mov         cl,byte ptr [k] 
        mov         byte ptr [eax],cl     
    
	    ; posDst[j]+=rand()/grainx2-granularity;
         ;invoke nrandom, RAND_MAX
        call ansi_rand
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl    
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x4	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y4
    	
    .elseif ShadeID == FILL_HSHADE    	    
    
;	case 2:	//SHS_HSHADE
;		a=idxmax-idxmin;
;		for(i = 0; i < sYSize; i++) {
;			k=a*i/sYSize+idxmin;
;			for(j = 0; j < sXSize; j++) {
;				posDst[j]=(BYTE)k;
;				posDst[j]+=rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
;		break;    
    
        ; a=idxmax-idxmin;
    	mov eax, idxmax 
        sub eax, idxmin 
        mov a, eax    
    
next_y5:	

        ; k=a*i/sYSize+idxmin;
        mov         eax,a 
        imul        eax,i 
        cdq              
        idiv        iHeight
        add         eax,idxmin 
        mov         k,eax

       mov j, 0     
next_x5:
    
        ; posDst[j]=(BYTE)k;
        mov         eax,posDst 
        add         eax,j 
        mov         cl,byte ptr [k] 
        mov         byte ptr [eax],cl
    
        ; posDst[j]+=rand()/grainx2-granularity;
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl    
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x5	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y5
    	
    .elseif ShadeID == FILL_VSHADE    	    

;	case 3:	//SHS_VSHADE:
;		a=idxmax-idxmin;
;		for(j = 0; j < sXSize; j++) {
;			k=a*(sXSize-j)/sXSize+idxmin;
;			for(i = 0; i < sYSize; i++) {
;				posDst[j+i*bytes]=(BYTE)k;
;				posDst[j+i*bytes]+=rand()/grainx2-granularity;
;			}
;		}
;		break;

        ; a=idxmax-idxmin;
    	mov eax, idxmax 
        sub eax, idxmin 
        mov a, eax
 
next_x6:	

        ; k=a*(sXSize-j)/sXSize+idxmin;
        mov         eax,iWidth
        sub         eax,j 
        imul        eax,a 
        cdq              
        idiv        iWidth
        add         eax,idxmin 
        mov         k,eax

        mov i, 0     
next_y6:

        ; posDst[j+i*bytes]=(BYTE)k;
        mov         eax,i 
        imul        eax,m_nBPS 
        add         eax,j 
        mov         ecx,posDst 
        mov         dl,byte ptr [k] 
        mov         byte ptr [ecx+eax],dl
         
        ; posDst[j+i*bytes]+=rand()/grainx2-granularity;
        mov         esi,i 
        imul        esi,m_nBPS
        add         esi,j 
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        movzx       ecx,byte ptr [edx+esi] 
        add         ecx,eax 
        mov         edx,i 
        imul        edx,m_nBPS 
        add         edx,j 
        mov         eax,posDst 
        mov         byte ptr [eax+edx],cl 
         
    	inc i
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y6	
    	
    	inc j
    
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x6    	

    .elseif ShadeID == FILL_DIAGSHADE

;	case 1:	//SHS_DIAGSHADE
;		a=(idxmax-idxmin)/2;
;		for(i = 0; i < sYSize; i++) {
;			for(j = 0; j < sXSize; j++) {
;				posDst[j]=(BYTE)(idxmin+a*i/sYSize+a*(sXSize-j)/sXSize);
;				posDst[j]+=rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
;		break;
    
       ; a=(idxmax-idxmin)/2;
        mov         eax,idxmax 
        sub         eax,idxmin 
        cdq              
        sub         eax,edx 
        sar         eax,1 
        mov         a,eax    
       
next_y7:	

        mov j, 0     
next_x7:
    
        ; posDst[j]=(BYTE)(idxmin+a*i/sYSize+a*(sXSize-j)/sXSize);
        mov         eax,a 
        imul        eax,i 
        cdq              
        idiv        iHeight
        mov         ecx,eax 
        add         ecx,idxmin 
        mov         edx,iWidth
        sub         edx,j 
        mov         eax,edx 
        imul        eax,a 
        cdq              
        idiv        iWidth
        add         ecx,eax 
        mov         eax,posDst 
        add         eax,j 
        mov         byte ptr [eax],cl 

        ; posDst[j]+=rand()/grainx2-granularity;
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl    
    
    
        ;invoke nrandom, RAND_MAX
;        call ansi_rand
;        cdq              
;        idiv        grainx2
;        add         eax,80h 
;        movzx       ecx,byte ptr [granularity] 
;        sub         eax,ecx 
;        mov         edx,posDst 
;        add         edx,j 
;        mov         byte ptr [edx],al
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x7	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y7       
 
    .elseif ShadeID == FILL_HARDBUMP
 
;	case 7:	// SHS_HARDBUMP
;		//set horizontal bump
;		for(i = 0; i < sYSize; i++) {
;			k=(255*i/sYSize)-127;
;			k=(k*(k*k)/128)/128;
;			k=(k*(128-granularity*2))/128+128;
;			for(j = 0; j < sXSize; j++) {
;				posDst[j]=(BYTE)k;
;				posDst[j]+=rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
;		//set vertical bump
;		d=min(16,sXSize/6);	//max edge=16
;		a=sYSize*sYSize/4;
;		posDst =iDst;
;		for(i = 0; i < sYSize; i++) {
;			y=i-sYSize/2;
;			for(j = 0; j < sXSize; j++) {
;				x=j-sXSize/2;
;				xs=sXSize/2-d+(y*y*d)/a;
;				if (x>xs) posDst[j]=idxmin+(BYTE)(((sXSize-j)*128)/d);
;				if ((x+xs)<0) posDst[j]=idxmax-(BYTE)((j*128)/d);
;				posDst[j]+=rand()/grainx2-granularity;
;			}
;			posDst+=bytes;
;		}
;		break; 

        ; set horizontal bump
next_y8:	

        ; k=(255*i/sYSize)-127;
        mov         eax,i 
        imul        eax,eax,0FFh 
        cdq              
        idiv        iHeight 
        sub         eax,7Fh 
        mov         k,eax
         
        ; k=(k*(k*k)/128)/128;
        mov         eax,k 
        imul        eax,k 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        mov         k,eax 

        ; k=(k*(128-granularity*2))/128+128;
        movzx       eax,byte ptr [granularity] 
        shl         eax,1 
        mov         ecx,80h 
        sub         ecx,eax 
        mov         eax,ecx 
        imul        eax,k 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 
        add         eax,80h 
        mov         k,eax

        mov j, 0     
next_x8:
   
        ; posDst[j]=(BYTE)k;
        mov         eax,posDst 
        add         eax,j 
        mov         cl,byte ptr [k] 
        mov         byte ptr [eax],cl 

        ; posDst[j]+=rand()/grainx2-granularity;
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j
        mov         byte ptr [edx],cl   
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x8	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y8
        	
        ; set vertical bump       	
        
        ; d=min(16,sXSize/6);	//max edge=16	
        mov         eax,iWidth 
        cdq              
        mov         ecx,6 
        idiv        ecx 
        cmp         eax,10h 
        jle         @f
        mov         eax,10h 
@@:     mov         d,eax
        	
        ; a=sYSize*sYSize/4;
        mov         eax,iHeight
        imul        eax,iHeight
        cdq              
        and         edx,3 
        add         eax,edx 
        sar         eax,2 
        mov         a,eax 
		
        ; posDst =iDst;
        m2m posDst, pvBits        	
        
        mov j, 0
        mov i, 0	
next_y9:	

        ; y=i-sYSize/2;
        mov         eax,iHeight
        cdq              
        sub         eax,edx 
        sar         eax,1 
        mov         ecx,i 
        sub         ecx,eax 
        mov         y,ecx        

        mov j, 0     
next_x9:
   
   
        ; x=j-sXSize/2;
        mov         eax,iWidth
        cdq              
        sub         eax,edx 
        sar         eax,1 
        mov         ecx,j 
        sub         ecx,eax 
        mov         x,ecx
 
        ; xs=sXSize/2-d+(y*y*d)/a;
        mov         eax,iWidth
        cdq              
        sub         eax,edx 
        mov         ecx,eax 
        sar         ecx,1 
        sub         ecx,d 
        mov         eax,y 
        imul        eax,y 
        imul        eax,d 
        cdq              
        idiv        a 
        add         ecx,eax 
        mov         xs,ecx   
     
        ; if (x>xs) posDst[j]=idxmin+(BYTE)(((sXSize-j)*128)/d);        
        .if x > ecx
        
            mov         eax,iWidth
            sub         eax,j 
            shl         eax,7 
            cdq              
            idiv        d 
            movzx       eax,al 
            add         eax,idxmin 
            mov         ecx,posDst 
            add         ecx,j 
            mov         byte ptr [ecx],al
       
        .endif
   
        ; if ((x+xs)<0) posDst[j]=idxmax-(BYTE)((j*128)/d);
        mov eax, x
        add eax, xs
        jns @f        
        mov         eax,j 
        shl         eax,7 
        cdq              
        idiv        d 
        movzx       eax,al 
        mov         ecx,idxmax 
        sub         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl
@@:
        ; posDst[j]+=rand()/grainx2-granularity;
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        movzx       ecx,byte ptr [granularity] 
        sub         eax,ecx 
        mov         edx,posDst 
        add         edx,j 
        movzx       ecx,byte ptr [edx] 
        add         ecx,eax 
        mov         edx,posDst 
        add         edx,j 
        mov         byte ptr [edx],cl   
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x9	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y9

    .elseif ShadeID == FILL_METAL
    
;    	case 8:	//SHS_METAL
;		m_dNormal.Clear();
;		// create the strokes
;		k=40;	//stroke granularity
;		for(a=0;a<200;a++){
;			x=rand()/(RAND_MAX/sXSize); //stroke postion
;			y=rand()/(RAND_MAX/sYSize);	//stroke position
;			xs=rand()/(RAND_MAX/min(sXSize,sYSize))/2; //stroke lenght
;			d=rand()/(RAND_MAX/k);	//stroke color
;			for(i=0;i<xs;i++){
;				if (((x-i)>0)&&((y+i)<sYSize))
;					m_dNormal.SetPixelIndex(x-i,y+i,(BYTE)d);
;				if (((x+i)<sXSize)&&((y-i)>0))
;					m_dNormal.SetPixelIndex(sXSize-x+i,y-i,(BYTE)d);
;			}
;		}
;		//blend strokes with SHS_DIAGONAL
;		posDst =iDst;
;		a=(idxmax-idxmin-k)/2;
;		for(i = 0; i < sYSize; i++) {
;			for(j = 0; j < sXSize; j++) {
;				d=posDst[j]+((a*i)/sYSize+(a*(sXSize-j))/sXSize);
;				posDst[j]=(BYTE)d;
;				posDst[j]+=rand()/grainx2;
;			}
;			posDst+=bytes;
;		}
;		break;

        ; create the strokes
        ; k=40;	//stroke granularity
        mov         k,28h
        mov         j,0
        
next_a:        
        
        ; x=rand()/(RAND_MAX/sXSize); //stroke postion
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        mov         ecx,eax 
        mov         eax,7FFFh 
        cdq              
        idiv        iWidth
        mov         esi,eax 
        mov         eax,ecx 
        cdq              
        idiv        esi 
        mov         x,eax
 
        ; y=rand()/(RAND_MAX/sYSize);	//stroke position
        ;invoke nrandom, RAND_MAX
        call ansi_rand
        mov         ecx,eax 
        mov         eax,7FFFh 
        cdq              
        idiv        iHeight
        mov         esi,eax 
        mov         eax,ecx 
        cdq              
        idiv        esi 
        mov         y,eax
 
        mov         eax,iWidth 
        cdq              
        mov         ecx,6 
        idiv        ecx 
        cmp         eax,10h 
        jle         @f
        mov         eax,10h 
@@:     mov         d,eax
 
        ; xs=rand()/(RAND_MAX/min(sXSize,sYSize))/2; //stroke lenght
        mov         eax,iWidth
        cmp         eax,iHeight
        jge         @f
        mov         tmp,eax
@@:     m2m         tmp,iHeight
 
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        mov         ecx,eax 
        mov         eax,7FFFh 
        cdq              
        idiv        tmp
        mov         esi,eax 
        mov         eax,ecx 
        cdq              
        idiv        esi 
        cdq              
        sub         eax,edx 
        sar         eax,1 
        mov         xs,eax
 
        ; d=rand()/(RAND_MAX/k);	//stroke color
        ;invoke nrandom, RAND_MAX
        call ansi_rand  
        mov         ecx,eax 
        mov         eax,7FFFh 
        cdq              
        idiv        k 
        mov         esi,eax 
        mov         eax,ecx 
        cdq              
        idiv        esi 
        mov         d,eax        
        
        mov i, 0
next_i: 
 
        ; if (((x-i)>0)&&((y+i)<sYSize))
        mov         eax,x 
        sub         eax,i 
        test        eax,eax 
        jle         @f
        mov         eax,y 
        add         eax,i 
        cmp         eax,iHeight
        jge         @f
        
        mov edx, x
        sub edx, i
        mov ecx, y
        add ecx, i
        
        ; m_dNormal.SetPixelIndex(x-i,y+i,(BYTE)d);
        ; iDst[(m_bi.biHeight - y - 1)*m_LineWidth + x]=i;
        mov         eax,iHeight
        sub         eax,ecx 
        sub         eax,1 
        imul        eax,m_nBPS
        add         eax,edx 
        mov         ecx,pvBits
        xor edx, edx
        mov         dl,byte ptr [d] 
        mov         byte ptr [eax+ecx],dl 

@@:

        ; if (((x+i)<sXSize)&&((y-i)>0))
        mov         eax,x 
        add         eax,i 
        cmp         eax,iWidth
        jge         @f
        mov         eax,y 
        sub         eax,i 
        test        eax,eax 
        jle         @f
        
        mov edx, iWidth
        sub edx, x
        add edx, i
        mov ecx, y
        sub ecx, i
        
        ; m_dNormal.SetPixelIndex(sXSize-x+i,y-i,(BYTE)d);
        ; iDst[(m_bi.biHeight - y - 1)*m_LineWidth + x]=i;
        mov         eax,iHeight
        sub         eax,ecx 
        sub         eax,1 
        imul        eax,m_nBPS
        add         eax,edx 
        mov         ecx,pvBits
        xor edx, edx
        mov         dl,byte ptr [d] 
        mov         byte ptr [eax+ecx],dl
@@: 
 
    	inc i
    
    	mov eax, xs
    	cmp i, eax
    	jb next_i        
        
    	inc j
    	cmp j, 0C8h
    	jb next_a
    	
        ; blend strokes with SHS_DIAGONAL
        
        ; posDst =iDst;
        m2m posDst,pvBits
        
        ; a=(idxmax-idxmin-k)/2;
        mov         eax,idxmax
        sub         eax,idxmin 
        sub         eax,k 
        cdq              
        sub         eax,edx 
        sar         eax,1 
        mov         a,eax
        
        mov i, 0
next_y10:	

       mov j, 0     
next_x10:
    
    
        ; d=posDst[j]+((a*i)/sYSize+(a*(sXSize-j))/sXSize);
        mov         eax,posDst 
        add         eax,j 
        movzx       ecx,byte ptr [eax] 
        mov         eax,a 
        imul        eax,i 
        cdq              
        idiv        iHeight
        mov         esi,eax 
        mov         edx,iWidth
        sub         edx,j 
        mov         eax,edx 
        imul        eax,a 
        cdq              
        idiv        iWidth
        add         esi,eax 
        add         ecx,esi 
        mov         d,ecx
 
        ; posDst[j]=(BYTE)d;
        mov         eax,posDst 
        add         eax,j 
        mov         cl,byte ptr [d] 
        mov         byte ptr [eax],cl 
        
        ; posDst[j]+=rand()/grainx2;
        ;invoke nrandom, RAND_MAX
        call ansi_rand 
        cdq              
        idiv        grainx2 
        mov         ecx,posDst 
        add         ecx,j 
        movzx       edx,byte ptr [ecx] 
        add         edx,eax 
        mov         eax,posDst 
        add         eax,j 
        mov         byte ptr [eax],dl    
         
    	inc j
    	mov eax, iWidth
    	cmp j, eax
    	jb next_x10	
    	
        mov eax, m_nBPS
    	add posDst, eax
    	
    	inc i
    
    	mov eax, iHeight
    	cmp i, eax
    	jb next_y10               
        
        	
	.endif
	
	invoke CreateDIBitmap, hDCDsk,  pvBmi, CBM_INIT, pvBits, pvBmi, DIB_RGB_COLORS 
	mov hBmp, eax
	
	.if highlight
	   invoke MemCopy, pvPalete2, pvPalete, sizeof(RGBQUAD)*256
	   invoke CreateDIBitmap, hDCDsk,  pvBmi, CBM_INIT, pvBits, pvBmi, DIB_RGB_COLORS 
	   mov hBmp2, eax
	.endif

	invoke ReleaseDC, NULL, hDCDsk
	invoke GlobalFree, pvBmi       ;освободим память, занимаемую изображением
	invoke GlobalFree, pvPalete2       ;освободим память, занимаемую изображением	
	
	.if highlight
	   mov edx, hBmp2
    .else    
       xor edx, edx       
    .endif
    mov eax, hBmp

	ret
CreateFillBmp endp

BlendPalette proc cr:DWORD, i:DWORD, color:COLORREF, perc:BYTE, rgb:BYTE

    LOCAL clr     :DWORD

    .if rgb == 1
        GetRValue color
        mov clr, eax      
    .elseif rgb == 2    
        GetGValue color
        mov clr, eax     
    .elseif rgb == 3
        GetBValue color
        mov clr, eax       
    .endif
    
    movzx       eax,byte ptr [cr] 
    mov         edx,64h 
    sub         edx,dword ptr [perc] 
    imul        eax,edx 
    mov         ecx,clr
    imul        ecx,dword ptr [perc] 
    add         eax,ecx 
    cdq              
    mov         ecx,64h 
    idiv        ecx
    
	ret
BlendPalette endp

;    r=((128-i)*GetRValue(locr)+i*GetRValue(midcr))/128;
;    g=((128-i)*GetGValue(locr)+i*GetGValue(midcr))/128;
;    b=((128-i)*GetBValue(locr)+i*GetBValue(midcr))/128;

CalculateRGB proc i:DWORD, c_l:COLORREF, c_r:COLORREF, rgb:BYTE

    LOCAL clr_l     :DWORD
    LOCAL clr_r     :DWORD

    .if rgb == 1
        GetRValue c_l
        mov clr_l, eax
        GetRValue c_r
        mov clr_r, eax        
    .elseif rgb == 2    
        GetGValue c_l
        mov clr_l, eax
        GetGValue c_r
        mov clr_r, eax        
    .elseif rgb == 3
        GetBValue c_l
        mov clr_l, eax
        GetBValue c_r
        mov clr_r, eax        
    .endif
    
        mov         eax,80h 
        sub         eax,dword ptr [i] 
        imul        eax,clr_l 
        mov         edx,clr_r
        imul        edx,dword ptr [i] 
        add         eax,edx 
        cdq              
        and         edx,7Fh 
        add         eax,edx 
        sar         eax,7 

	ret
CalculateRGB endp

ansi_rand proc

.data
ParkerM dd 80000000h -1
seed dd 12345678

.code

mov eax, 343FDh
imul dword ptr seed
add eax, 269EC3h
mov dword ptr seed, eax
shr eax, 16
and eax, 07FFFh

	ret
ansi_rand endp