Archived

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

BeanDog

My shadow code - needs optimized

Recommended Posts

This chunk of code really slows down the game when there are tons of units there... DDSURFACEDESC2 SprDDSD; DDSURFACEDESC2 BackDDSD; BYTE* lpSprite; BYTE* lpBack; WORD SprPitch; WORD BackPitch; BYTE byte1, byte2; //used later, keep watching... ZeroMemory(&SprDDSD, sizeof(SprDDSD)); SprDDSD.dwSize = sizeof(SprDDSD); ZeroMemory(&BackDDSD, sizeof(BackDDSD)); BackDDSD.dwSize = sizeof(BackDDSD); //this CreaturePics surface is my regular sprite picture surface, not only for shadows CreaturePics[picnum]->Lock(NULL, &SprDDSD, DDLOCK_READONLY, NULL); lpSprite = (BYTE*)SprDDSD.lpSurface; SprPitch = (WORD)SprDDSD.lPitch; Back->Lock(NULL, &BackDDSD, DDLOCK_WRITEONLY, NULL); lpBack = (BYTE*)BackDDSD.lpSurface; BackPitch = (WORD)BackDDSD.lPitch; if (flies) { //starts where the sprite''s shadow will be put lpBack += 2*drawrect.left; lpBack += BackPitch*(drawrect.top+ysize/2); //you''ll have to trust me here, this sets it up to where the sprite starts on the surface lpSprite += ((dir-1)*ysize)*SprPitch; lpSprite += (((int)frame-1)*xsize + attacking*xsize*8)*2; //now loop through every other pixel in it... for (int sy = 0; sy < ysize; sy++) { for (int sx = 0; sx < xsize; sx+=2) { byte1 = lpSprite[0]; //does this save speed or waste it? byte2 = lpSprite[1]; //i heard using subscripts over and over is slow? if (byte1 != 0 // byte2 != 0) //not a black (background) pixel { lpBack[1] = 0;//sets the pixel on the destination to black lpBack[1] = 0; } lpSprite += 4;//move the pointers ahead two pixels lpBack += 4; } lpBack += BackPitch - (xsize+((sy%2)*2-1))*2; //next line on dest surface - makes checkerboard pattern lpSprite += SprPitch - xsize*2; //next line on sprite surface } } You get the idea. If someone could tell me how I could significangly increase the speed here, I''d really be happy.

Share this post


Link to post
Share on other sites
Hi!

I'm no 2D Wizard, but using 16-bit aligned data is going to kill any loop. Actually, you should try to read 32-bits at a time and also write 32-bits at a time. This would allow you to work on two pixels at a time. The lpSprite and lpBack pointers should point to 32-bit values. So, using lpSprite++ will move the pointer 4 bytes at a time. This would also save you from using array indices. Sorta like this:


unsigned long data;
unsigned long pixel1, pixel2;

for (int sy = 0; sy < ysize; sy++) //This might need changing, too
{
for (int sx = 0; sx < xsize; sx+=4) //So does this,
{
data = *lpSprite;
pixel1 = data && 0xffff0000;
pixel2 = data && 0x0000ffff;

//work on the first pixel
if (pixel1)
{
//Second pixel
if(pixel2)
{
//both black
*lpBack = 0;
}else
{
//only pixel1 black
*lpBack = pixel2;
}
}else
{
//Second pixel
if(pixel2)
{
//pixel2 black
*lpBack = pixel1;
}else
{
//both fully colored
*lpBack = data;
}
}
}
lpSprite++;//move the pointers ahead two pixels
lpBack++;
}


Mmmh, again, I'm no 2D expert (and doing this outa my head), but this should be a bit faster. Obviously, you have to adjust your initialization code and where you update lpSprite and lpBack. There's probably some MMX instruction which automatically does, what the if-construct does. BTW, with all these ifs, this might look slower, but I'd bet my life that this inner loop is just as fast as your code, but it works on two-pixels at a time, whereas your code only deals with one pixel !

Also, some more helpfull coding tips (for speed):

instead of doing:

i = 2*j;

do:

i = j << 1;

instead of doing:

i = j%2;

do:

i = j&1;

This might give you a bit more speed, but combined with the loop above, you should really be on the right track. MMX will help even more, but I don't know enough about it. Using 16-bit graphics can REALLY slow you down. Sometimes, it's better to work with 32-bit graphics internally and then just convert this down to 16-bit when copying to the backbuffer.

Hope this helps a bit,

MK42


Edited by - MK42 on June 15, 2000 6:57:19 AM

Edited by - MK42 on June 15, 2000 6:57:50 AM

Edited by - MK42 on June 15, 2000 6:58:09 AM

Share this post


Link to post
Share on other sites