- Prizm Screenshot function
- 11 Aug 2012 03:26:15 pm
- Last edited by souvik1997 on 20 Aug 2012 08:26:54 pm; edited 1 time in total
I'm writing a function to store the contents of VRAM into a 24-bit .bmp, but I have no idea why it's not working. Previously I was using the 16-bit RGB 565 bitmap header, but that produced really strange colors.
Here's the code:
Code:
Edit: Here's the complete, functioning code with Tari's assembly code.
Code:
Here's the code:
Code:
#define CREATEMODE_FILE 1
#define CREATEMODE_FOLDER 5
#define READ 0
#define READ_SHARE 1
#define WRITE 2
#define READWRITE 3
#define READWRITE_SHARE 4
#define RETURN_SUCCESS 0
#define RETURN_ERROR -1
#define LCD_WIDTH 384
#define LCD_HEIGHT 216
#define file_size sizeof(bmpheader)+(LCD_WIDTH*LCD_HEIGHT*3)
unsigned short filebuffer[] = {'\\','\\','f','l','s','0','\\','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
unsigned char bmpheader[] =
{0x42, 0x4D, 0x36, 0xCC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int TakeScreenshot(char* filename) //Copies the contents of VRAM to a 24-bit .bmp file in storage memory
{
int fh = 0;
Bfile_StrToName_ncpy(filebuffer+(7), filename, strlen(filename)); //copy the filename to the filebuffer after "\\fls0\"
Bfile_DeleteEntry(filebuffer, CREATEMODE_FILE, 0);
color_t* VRAM = (color_t*)0xA8000000;
int size = file_size;
if (0 > (fh = Bfile_OpenFile_OS(filebuffer,READWRITE))) {
if (Bfile_CreateEntry_OS(filebuffer, CREATEMODE_FILE, &size) < 0)
return RETURN_ERROR;
}
if (fh >= 0)
Bfile_CloseFile_OS(fh);
if (0 <= (fh = Bfile_OpenFile_OS(filebuffer,READWRITE))) {
Bfile_WriteFile_OS(fh, bmpheader, sizeof(bmpheader));
void* scratchSpace = malloc(LCD_WIDTH*3);
for (int x = LCD_HEIGHT-1; x >= 0; x--) //bmp files are upside down
{
//memcpy(scratchSpace, VRAM+(LCD_WIDTH*x), LCD_WIDTH*2); <-- produces weird colors in 16 bit mode
for (int y = 0; y < LCD_WIDTH; y++) // http://stackoverflow.com/questions/2442576/how-does-one-convert-16-bit-rgb565-to-24-bit-rgb888
{
unsigned short color = (unsigned short*)(VRAM+(LCD_WIDTH*x+y));
unsigned char red = (char)((color & 0xf800) >> 11);
unsigned char green = (char)((color & 0x07e0) >> 5);
unsigned char blue = (char)(color & 0x001f);
*((char*)scratchSpace+3*y) = ( red * 527 + 23 ) >> 6;
*((char*)scratchSpace+3*y+1) = ( green * 259 + 33 ) >> 6;
*((char*)scratchSpace+3*y+2) = ( blue * 527 + 23 ) >> 6;
}
Bfile_WriteFile_OS(fh, scratchSpace, LCD_WIDTH*3); //write chunk to file
}
free(scratchSpace);
Bfile_CloseFile_OS(fh);
}
return RETURN_SUCCESS;
}
Edit: Here's the complete, functioning code with Tari's assembly code.
Code:
#define CREATEMODE_FILE 1
#define CREATEMODE_FOLDER 5
#define READ 0
#define READ_SHARE 1
#define WRITE 2
#define READWRITE 3
#define READWRITE_SHARE 4
#define RETURN_SUCCESS 0
#define RETURN_ERROR -1
#define LCD_WIDTH 384
#define LCD_HEIGHT 216
#define file_size sizeof(bmpheader)+(LCD_WIDTH*LCD_HEIGHT*2)
unsigned short filebuffer[] = {'\\','\\','f','l','s','0','\\','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
unsigned char bmpheader[] =
{0x42, 0x4D, 0x46, 0x88, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int TakeScreenshot(char* filename) //Copies the contents of VRAM to a 16-bit .bmp file in storage memory
{
int fh = 0;
Bfile_StrToName_ncpy(filebuffer+(7), filename, strlen(filename)); //copy the filename to the filebuffer after "\\fls0\"
Bfile_DeleteEntry(filebuffer, CREATEMODE_FILE, 0);
color_t* VRAM = (color_t*)0xA8000000;
int size = file_size;
if (Bfile_CreateEntry_OS(filebuffer, CREATEMODE_FILE, &size) < 0)
return RETURN_ERROR;
if (0 <= (fh = Bfile_OpenFile_OS(filebuffer,READWRITE))) {
Bfile_WriteFile_OS(fh, bmpheader, sizeof(bmpheader));
void* scratchSpace = malloc(LCD_WIDTH*2);
for (int x = LCD_HEIGHT-1; x >= 0; x--) //bmp files are upside down
{
memcpy_littleendian(scratchSpace, VRAM+(LCD_WIDTH*x), LCD_WIDTH*2);// <-- produces weird colors in 16 bit mode
Bfile_WriteFile_OS(fh, scratchSpace, LCD_WIDTH*2); //write chunk to file
}
free(scratchSpace);
Bfile_CloseFile_OS(fh);
}
return RETURN_SUCCESS;
}
void memcpy_littleendian(void* dest, void* source, int length)
{
/*unsigned char* dst = (unsigned char*)dest;
unsigned char* src = (unsigned char*)source;
for (int x = 0; x < length; x+=2)
{
*(dst+x) = *(src+x+1);
*(dst+x+1) = *(src+x);
}*/
unsigned short *s = (unsigned short *)source;
unsigned short *d = (unsigned short *)dest;
while (length--) {
unsigned short c = *s++;
__asm__("swap.b %0,%0" : "=r"(c) : "0"(c));
*d++ = c;
}
}