Hi all, For the last hour I have tried to make since of the disassembly of MS's msimg32.dll (ships with Win 98+). I desperatly need a smooth shading function (linear gradient) that will work with Win95/NT4.0/98/ME/etc. I found the starting point of the code I need: "BFDD6008 GradientFill:"... but I don't know how to determine where it ends nor how to transplant it into my app. Any help would be greatly appreciated. PS. Will this DLL work on Win 95? Xtreme
Posted on 2001-02-21 20:37:00 by Xtreme
Ripping code from microsoft, or shipping a (as far as I know) non-redistributable DLL with your application is not a good idea. How hard can it be to code a gradient fill yourself? Really? It seems everybody are becoming so lazy these days.:(
Posted on 2001-02-22 02:32:00 by f0dder
I'm not being lazy. See my post titled "I have source for "Icon" Menus". I created this code for my normal, everyday menus. I just don't know the methodology involved in creating a linear gradient. I've never heard anyone state in plain english how they can go from dark blue to light blue (COLORREF) mathematically... Honestly, I'd rather write my own function so I can have it do specifically what I need and optimize it accordingly. Xtreme This message was edited by Xtreme, on 2/22/2001 3:22:26 AM
Posted on 2001-02-22 02:40:00 by Xtreme
I have some C source for a gradient fill, if you want I can post it here. umbongo
Posted on 2001-02-22 05:46:00 by umbongo
you have your first colour COLORREF ie 0000ffh, and want to get to the second colout 000011h, say. subtract the lower number from the higher number, then divide by the number of steps you will be taking ( the number of line), call it ebx draw aline subtract ebx from colour, and set new colour repeat until you have drawn all your lines.... fairly simple
Posted on 2001-02-22 07:16:00 by mega
COLOR1: cc6600 (13395456) COLOR2: ffdebb (16768699) DIFFERENCE: ffdebb - cc6600 = 3378BB ebx: 3378BB / FF (255) = 33ac BEGIN: cc6600 - 33ac = CC3254 CC3254 - 33ac = CBFEA8 CBFEA8 - 33ac = CBCAFC The first color CC3254 seems to be correct but the second and third are red and green! What did I do wrong? Xtreme This message was edited by Xtreme, on 2/22/2001 2:40:10 PM
Posted on 2001-02-22 14:38:00 by Xtreme
Subract the R, G, B individually and then add with saturation (i.e. stop at 00 or FF). Some color components will increase in value others will decrease. Half the demos ever coded have a fade routine - this is the same thing as a good fade routine. bitRAKE This message was edited by bitRAKE, on 2/22/2001 2:51:39 PM
Posted on 2001-02-22 14:48:00 by bitRAKE
(see my last message) BEGIN: cc - 33ac = FFFFCD20 66 - 33ac = FFFFCCBA 00 - 33ac = FFFFCC54 :confused: Help :confused: Xtreme
Posted on 2001-02-22 15:48:00 by Xtreme
COLOR1: cc6600 (13395456)
COLOR2: ffdebb (16768699)

x1 = ff - cc
x2 = de - 66
x3 = bb - 00

dx1 = x1/(increments)
dx2 = x2/(increments)
dx3 = x3/(increments)

c1 = cc
c2 = 66
c3 = 00

loop:

  (color) = c1 * 256 * 256 + c2 * 256 + c3

  {do something with the color}

  c1=c1+dx1
  c2=c2+dx2
  c3=c3+dx3

  (increments)=(increments)-1
loop until (increments)=0
There you go. Convert to ASM :P bitRAKE This message was edited by bitRAKE, on 2/22/2001 4:02:22 PM
Posted on 2001-02-22 15:59:00 by bitRAKE
OOOOOOOh.... subtract the begin and end colors individually. Kewl... Thanks!
Posted on 2001-02-22 16:04:00 by Xtreme
Of course, you can optimize it a little :P I'm sure that there is a MMX version around on the web for a crossfade effect. You do the same thing, but for every pixel on the screen - going from one image to another. I'll put it on my ToDo list :) bitRAKE p.s. Always glad to help!
Posted on 2001-02-22 16:36:00 by bitRAKE
Note to everyone else: BitRAKE's equation should be evaluated from left to right; not according to operator precedence. (color) = cc * 256 * 256 + 66 * 256 + 00 = CC6600 PS. I've worked out this alogorithm using Calc and Paint Shop Pro. It certainly works and I'll post my proc soon... Thanks! This message was edited by Xtreme, on 2/22/2001 5:09:14 PM
Posted on 2001-02-22 16:57:00 by Xtreme
I don't know about anybody else, but I've always done multiplication before addition. And in all the languages I know it is preformed first. So, I really don't understand what you were trying to say :confused: I'm glad it help you :cool: bitRAKE p.s. I would put ASM instead of making up my own language, but I was at work and couldn't take much time :) This message was edited by bitRAKE, on 2/22/2001 11:44:07 PM
Posted on 2001-02-22 23:31:00 by bitRAKE
I haven't tested this, but it looks okay. Just coded it :P Maybe, I'll have time to test it in the morning. bitRAKE
;Please, note that the color is scaled by 256 to provide smoother
;color ranges.

ColorRange PROC USES ebx esi edi ebp,
	StartColor:DWORD, EndColor:DWORD, RangeCount:DWORD

	LOCAL	dx1:DWORD
	LOCAL	dx2:DWORD
	LOCAL	dx3:DWORD

	mov	edi, EndColor
	mov	ebx, StartColor
	mov	ebp, RangeCount	;1+
	sal	edi, 8
	sal	ebx, 8

	mov	eax, edi
	mov	edx, ebx
	and	eax, 0FF000000h
	and	edx, 0FF000000h
	sub	eax, edx
	xor	edx, edx
	div	ebp
	mov	dx1, eax

	mov	eax, edi
	mov	edx, ebx
	and	eax, 0FF0000h
	and	edx, 0FF0000h
	sub	eax, edx
	xor	edx, edx
	div	ebp
	mov	dx2, eax

	mov	eax, edi
	mov	edx, ebx
	and	eax, 0FF00h
	and	edx, 0FF00h
	sub	eax, edx
	xor	edx, edx
	div	ebp
	mov	dx3, eax


	mov	esi, ebx
	mov	edi, esi
	mov	eax, edi
	and	ebx, 0FF000000h
	and	esi, 0FF0000h
	and	edi, 0FF00h
lp:
	shr	eax, 8

;--------------------------------------------
;Color is in eax do something with it here...
;Need to preserve: ebx, esi, edi, ebp
;--------------------------------------------

	add	ebx, dx1
	mov	eax, ebx
	and	eax, 0FF000000h

	add	esi, dx2
	mov   edx, esi
	and	edx, 0FF0000h
	or	eax, edx

	add	edi, dx3
	mov	edx, edi
	and	edx, 0FF00h ;could just OR word
	or	eax, edx

	dec	ebp
	jne	lp

	ret

ColorRange ENDP
This message was edited by bitRAKE, on 2/23/2001 5:39:49 AM
Posted on 2001-02-23 00:45:00 by bitRAKE
BitRAKE, The source above crashes with or without my drawing code. I'm looking for the problem. I've narrowed it down to the third section in the proc. I called this proc like so:
invoke ColorRange, 00CC6600h, 00FFDEBBh, 10
...

mov eax, edi
mov edx, ebx
and eax, 0FF000000h
and edx, 0FF000000h
sub eax, edx
xor edx, edx
div ebp
mov dx1, eax
... Thanks for your help!! Xtreme
Posted on 2001-02-23 13:48:00 by Xtreme
It doesn't work because I used EBP. Just make a local for the count, or trash the passed count, and it should work. bitRAKE. p.s. The algorithm is good - the register useage is bad :P It's been a log night on the town, and hopefully I'll work up an example using it tommorrow :)
Posted on 2001-02-24 03:39:00 by bitRAKE
BitRAKE, I too have had quite a night on the town... However, even though my brain's getting ready to explode, I replaced all references to ebp with RangeCount and then did some PatBlt'ing... SUCCESS! Although I believe I'm messing something up with this code because the gradient turns completely white after a few window resizes. The higher RangeCount is, the sooner the gradient turns white... ...

;--------------------------------------------
;Color is in eax do something with it here...
;Need to preserve: ebx, esi, edi
;--------------------------------------------
invoke CreateSolidBrush, eax
invoke SelectObject, hDC, eax
invoke PatBlt, hDC, 0, 0, RangeCount, 400, PATCOPY
invoke SelectObject, hDC, BLACK_BRUSH
invoke DeleteObject, eax
... Xtreme This message was edited by Xtreme, on 2/24/2001 3:14:11 PM
Posted on 2001-02-24 13:01:00 by Xtreme
...so your using the deincrementing RangeCount for the width - that means your blitting rectangles and then over-writing most of them. Try using it as the x-coordinate, and setting the width to one. Let me know if you get the same problem. bitRAKE
Posted on 2001-02-24 21:56:00 by bitRAKE
Those need to be signed division, sorry :P So, edx needs to be the signed extension of eax.

    cdq
    idiv   RangeCount
...should do the trick. And delete the xor edx,edx. It works just like it should now. I ran it through several color ranges. :cool: bitRAKE This message was edited by bitRAKE, on 2/24/2001 11:04:04 PM This message was edited by bitRAKE, on 2/24/2001 11:10:26 PM
Posted on 2001-02-24 22:51:00 by bitRAKE
I have to be doing something wrong. The gradient still goes white after a couple resizes. I call the proc from WM_PAINT like so: ...

.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR Ps
invoke Gradient, Ps.hdc, 0CC6600h, 0FFDEBBh, 255
invoke EndPaint,hWin,ADDR Ps
return 0
... Here's my version of the proc itself:

Gradient PROC USES ebx esi edi, hDC:DWORD, StartColor:DWORD, EndColor:DWORD, RangeCount:DWORD

    LOCAL dx1:DWORD
    LOCAL dx2:DWORD
    LOCAL dx3:DWORD

    mov edi, EndColor                                       ; Move Endcolor into edi
    mov ebx, StartColor                                     ; Move Startcolor into ebx
    sal edi, 8                                              ; Shift edi left by 8
    sal ebx, 8                                              ; Shift ebx left by 8


    mov eax, edi                                            ; Move EndColor into eax
    mov edx, ebx                                            ; Move StartColor into edx
    and eax, 0FF000000h                                     ; Get the EndColor's Blue Component
    and edx, 0FF000000h                                     ; Get the StartColor's Blue Component
    sub eax, edx                                            ; Subtract "StartColor Blue Component" from "EndColor Blue Component"
    cdq                                                     ; Convert Double to Quad in eax
    idiv RangeCount                                         ; Divide eax by RangeCount
    mov dx1, eax                                            ; Move result into dx1


    mov eax, edi                                            ; Move EndColor into eax
    mov edx, ebx                                            ; Move StartColor into edx
    and eax, 0FF0000h                                       ; Get the EndColor's Green Component
    and edx, 0FF0000h                                       ; Get the StartColor's Green Component
    sub eax, edx                                            ; Subtract "StartColor Green Component" from "EndColor Green Component"
    cdq                                                     ; Convert Double to Quad in eax
    idiv RangeCount                                         ; divide eax by RangeCount
    mov dx2, eax                                            ; Move result into dx2


    mov eax, edi                                            ; Move EndColor into eax
    mov edx, ebx                                            ; Move StartColor into edx
    and eax, 0FF00h                                         ; Get the EndColor's Red Component
    and edx, 0FF00h                                         ; Get the StartColor's Red Component
    sub eax, edx                                            ; Subtract "StartColor Red Component" from "EndColor Red Component"
    cdq                                                     ; Convert Double to Quad in eax
    idiv RangeCount                                         ; divide eax by RangeCount
    mov dx3, eax                                            ; Move result into dx3


    mov esi, ebx                                            ; Move StartColor into esi
    mov edi, esi                                            ; Move StartColor into edi
    mov eax, edi                                            ; Move StartColor into eax
    and ebx, 0FF000000h                                     ; Get the StartColor's Blue Component
    and esi, 0FF0000h                                       ; Get the StartColor's Green Component
    and edi, 0FF00h                                         ; Get the StartColor's Red Component


lp:
    shr eax, 8                                              ;

    invoke CreateSolidBrush, eax                            ;
    invoke SelectObject, hDC, eax                           ;
    invoke PatBlt, hDC, RangeCount, 0, 1, 400, PATCOPY      ;
    invoke SelectObject, hDC, BLACK_BRUSH                   ;
    invoke DeleteObject, eax
Posted on 2001-02-25 05:05:00 by xtreme