Skip to main content
gamedev.net
🔒 Locked

Screen Shots

Started by Militant Feb 7, 2001 at 1:41 PM 3 replies 2.1k views
Original Post
Militant
Militant
I want to be able to write out 16-bit BMP screen shots when a key is hit. I am having trouble writing out BMPs. I need to copy the screen (also). Using DX 6.1. The screen is layered: level image (640x480) and a mask on top of the same size. This is probably easy, so be gentle Militant - "Education is that which allows us to get into more intelligent trouble"
I'm not the brightest something or other in a group or similar.~ me ~
Thorin
Thorin
I''m kinda new w/ Direct X, but here goes:

You could just call lock() on your primary surface & then your D surface descriptor would have a pointer to exacly what is displayed on screen. Copy the bits w/ memcpy , unlock the surface & write the data to a file at your liesure.

DDSURFACEDESC2 ddsd;
BYTE *src,*dest;

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
if (FAILED(surface->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL))) return FALSE;
dest = (BYTE*)ddsd.lpSurface;

then read from dest.


surface->Unlock(NULL);
be sure to unlock when done.

Since I''m not much of a windows programmer either, I''d just use fwrite to save the data. Windows also has structures for the bitmap file header, and the info header that you''ll have to fill out & save in the file, I believe the types are BITMAPFILEHEADER & BITMAPINFOHEADER.
Qoy
Qoy
Yep, that''s what I do. If you want to see it, here''s the screenshot function from my game:

  
void Screenshot()
{
char currFileName[30]; // array to build the filename

unsigned char r = 0, g = 0, b = 0; // RGB values to build the bitmap


BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
unsigned char* bitmapBits = NULL;

// allocate the bits, 3 bytes per pixel (24 bits), the size of the screen

bitmapBits = new unsigned char[SCREEN_WIDTH * SCREEN_HEIGHT * 3];
if(bitmapBits == NULL)
{
DebugOut("-Screenshot: Failed to allocate bitmap bits.\n");
return;
}

// copy the screen data to the bitmap


backBuffer->Lock(NULL,&desc,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | SYSLOCK_FLAG,NULL);

unsigned short* videoBuffer = (unsigned short*)desc.lpSurface;

for(int i = 0, j = 0; i < SCREEN_HEIGHT; i++, videoBuffer += pixelLPitch)
for(int col = 0; col < SCREEN_WIDTH; col++, j += 3)
{
ExtractRGB(videoBuffer[col],&r,&g,&b);

// scale the color components up to 8 bits per color levels

r *= 8;
g *= gScale;
b *= 8;

// save them in reverse order

bitmapBits[j] = b;
bitmapBits[j + 1] = g;
bitmapBits[j + 2] = r;
}

backBuffer->Unlock(NULL);

// build the headers

fileHeader.bfType = ''MB''; // MB instead of BM because of intel byte order

fileHeader.bfSize = (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
(SCREEN_WIDTH * SCREEN_HEIGHT * 3));
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));

infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = SCREEN_WIDTH;
infoHeader.biHeight = SCREEN_HEIGHT;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = (SCREEN_WIDTH * SCREEN_HEIGHT * 3);
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;

// generate a filename for the bitmap file

i = 0;
while(true)
{
wsprintf(currFileName,"Inv2Shot%d.bmp",i);

// check if the current file name is available

// (if _access returns -1, then the file doesn''t exist)

if(_access(currFileName,0) == -1)
break;

i++;
}

// flip the bitmap (they''re stored upside-down)

unsigned char* picture; // new byte pointer to the bitmap buffer

unsigned char* tempBuffer; // a temporary buffer


picture = bitmapBits;
tempBuffer = new unsigned char[SCREEN_WIDTH * SCREEN_HEIGHT * 3];
if(tempBuffer == NULL)
{
DebugOut("-ScreenShot: Failed to allocate temp buffer for flipping.\n");
delete[] bitmapBits;
bitmapBits = NULL;
return;
}

memcpy(tempBuffer,picture,(SCREEN_WIDTH * SCREEN_HEIGHT * 3));

for(i = 0; i < SCREEN_HEIGHT; i++)
memcpy(&picture[((SCREEN_HEIGHT - 1) - i) * (SCREEN_WIDTH * 3)],
&tempBuffer[i * (SCREEN_WIDTH * 3)], SCREEN_WIDTH * 3);

delete[] tempBuffer;

// write it all to a file

FILE* file = fopen(currFileName,"wb");

fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,file);
fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,file);
fwrite(bitmapBits,SCREEN_WIDTH * SCREEN_HEIGHT * 3,1,file);

fclose(file);

// deallocate the bitmap

if(bitmapBits)
delete[] bitmapBits;
}
Militant
Militant
Thanx for the help.. hehe, am I too late?


Militant - "Education is that which allows us to get into more intelligent trouble"
I'm not the brightest something or other in a group or similar.~ me ~

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.