#### Archived

This topic is now archived and is closed to further replies.

# Fade to Black in 16 bit color mode

This topic is 6182 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I can do this in 8 bit mode, but since my new game requires 16 bit graphics, I need to find a new way to fade a screen. Any suggestions?

##### Share on other sites
Alpha blending will do the trick. Just take a black bitmap (or use 0 to blend into in your Fade() function) and start put over top your image. Then make the black bitmap (or whatever) more opaque until the screen has faded.

##### Share on other sites
So I''m assuming that I need a new DDraw surface right? Can you explain this a bit more?

##### Share on other sites
Alpha-Blending is probably your only choice. But it is very slow. There are tutorials on how to do this on this site in the reference section. I think you could also use gamma controls to fade the screen (it''s a lot faster than software alpha-blending) but there is no support for this in the HEL.

##### Share on other sites
OK, so I should just stick to my 8 bit games =^). Another thing: Is 256 colors sufficient for a SNES style RPG? Thanks for the help, though.

##### Share on other sites
I thought the SNES only used something like 256 onscreen at once anyway? So I don''t see why it would be a problem.

By the way, alpha-blending will be far less slow if you keep your video buffers in system memory, although not as fast as running the graphics in video memory and avoiding alpha blending

Use a Gamma Ramp

##### Share on other sites
Yeah, I used gamma stuff. No offense (if any) but it's ugly... It makes the colors look weird and stuff. I wanted to try assembler as seen on one of the sites tutorials here is the code:

  _asm { xor eax, eax // Initialize the variables. This is VC++ 6 xor ebx, ebx // inline Assembler. Mostly this is designed mov ecx, xheight // for a DirectDraw locked surface. xor edx, edx mov esi, ddsdSource.lpddsprimary // This variable should be the pointer to the source surface. mov edi, ddsdDest.lpddsprimary // This variable should be the pointer to the dest surface. heightLoop16bit565: push ecx mov ecx, xwidth widthLoop16bit565: mov ax, [esi] // Reads the 16-bit pixel (this is designed for 565 RGB). test ax, ax // Tests it with an AND to itself. Sets flags, basically. jz exLoop16bit565 // Skips if pure black (transparent in my game). Use cmp ax, value // if black isn't transparent for you. Take out this line and the previous // if you don't need a transparent additive effect. mov dx, [edi] and edx, 63454 // Take out the last bits of red, green, and blue. and eax, 63454 // This ensures the last bits aren't used by the colors. add eax, edx // This is necessary later on. Total source and dest up into a 32-bit register. mov ebx, eax // EBX is going to be used as our temporary register here. and ebx, 65536 // AND it by 65536, which strips out all but the last bit if it overflowed past the max. jz noRedLoop16bitAAB565 // Skips the next line if an overflow did not occur. or eax, 63488 // This OR turns on all the red bits. noRedLoop16bitAAB565: mov ebx, eax // We do the same thing to green. and ebx, 2048 // Oh and don't worry about bit 17 being turned on in red, jz noGreenLoop16bitAAB565 // that will be solved later. or eax, 2016 noGreenLoop16bitAAB565: mov ebx, eax // Finally we process blue. and ebx, 32 // Almost done here! jz noBlueLoop16bitAAB565 or eax, 31 noBlueLoop16bitAAB565: mov [edi], ax // Move the latter 16-bits of the pixel into the destination. exLoop16bit565: add esi, 2 // Add 2 bytes to the source pointer, to go to the next pixel. add edi, 2 // Ditto with the destination pointer. dec ecx // Decrease ECX. As you may have noticed, height was PUSHed in ECX, // and we did that to make room for width. x86 needs more registers. jnz widthLoop16bit565 // If we aren't out of pixels on that row, go back for another pixel. pop ecx // Pulls the height from the stack. Height is now in ECX for a sec. add esi, ipitchsrc // ipitchsrc should be the pitch DirectDraw gave you in Lock() add edi, ipitchdest // minus twice the source width. ipitchdest should be the same thing for dec ecx // the destination surface. We're almost done, now we are decreasing jnz heightLoop16bit565 // the height and looping back for the next row. }

only problem is, it gives errors saying that (these lines:
  mov esi, ddsdSource.lpddsprimary // This variable should be the pointer to the source surface. mov edi, ddsdDest.lpddsprimary // This variable should be the pointer to the dest surface.

"lpddsprimary" must be a valid union/struct/type. So I can't use that for now, can anyone tell me what I'm supposed to do?

Currently, this is the ugly gamma result that I'm using:

  //initialize the gamma control so that we can use it. LPDIRECTDRAWGAMMACONTROL lpDDGammaControl = NULL; //this structure will be the ramp value that we modify DDGAMMARAMP DDGammaRamp; //this structure will hold the old gamma values so that we can reset our video card after our fade is complete. DDGAMMARAMP DDGammaOld; lpddsprimary->QueryInterface(IID_IDirectDrawGammaControl,(void **)&lpDDGammaControl); lpDDGammaControl->GetGammaRamp(0, &DDGammaOld); lpDDGammaControl->GetGammaRamp(0, &DDGammaRamp); for(int blackloop=0;blackloop<256;blackloop++) { //we wouldn't want to decrement a value unless it's greater than 0 if(DDGammaRamp.red[blackloop] > 0) { //set the current value of DDGammaRamp.Red to 0. DDGammaRamp.red[blackloop]=0; //now let's update our primary surface with the new gamma setting lpDDGammaControl->SetGammaRamp(0, &DDGammaRamp); } //end if //the routine was a little too fast so this slows it down a bit…. //we wouldn't want to decrement a value unless it's greater than 0 if(DDGammaRamp.green[blackloop] > 0) { //set the current value of DDGammaRamp.yellow to 0. DDGammaRamp.green[blackloop]=0; lpDDGammaControl->SetGammaRamp(DDSGR_CALIBRATE, &DDGammaRamp); } //end if //the routine was a little too fast so this slows it down a bit…. //we wouldn't want to decrement a value unless it's greater than 0 if(DDGammaRamp.blue[blackloop] > 0) { //set the current value of DDGammaRamp.Blue to 0. DDGammaRamp. blue [blackloop]=0; lpDDGammaControl->SetGammaRamp(DDSGR_CALIBRATE, &DDGammaRamp); } //end if //the routine was a little too fast so this slows it down a bit…. } //end for lpDDGammaControl->SetGammaRamp(0, &DDGammaOld);

Edited by - Dismantler on August 14, 2001 10:37:08 AM

##### Share on other sites
Why don''t you pass ddsdSource.lpddsprimary and the other one as pointer parameters? Then use these parameters in the asm code.

If that doesn''t work, why don''t you convert the asm into c?

If that doesn''t work either, I''ve got a question about the gamma:
You check if red/green/blue is above 0. If it is, you set it to 0. If you want it to fade, shouldn''t you decrease the intensities? Otherwise, won''t the screen will go completely black? Tell me if I''m wrong, I''m not working with DirectX, sitting in linux...

##### Share on other sites
About the gamma, what I want is for the screen to be completely black, it _is_ called a fade to black... =^] I don''t know what''s wrong with the asm becuase I just copied it off one of the articles here. BTW, I know nothing about assembly +_+.

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
18
5. 5

• 14
• 22
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631766
• Total Posts
3002218
×