Shine wrote:Panajev2001a wrote:For others who might have trouble using Jason's code, I thought it might be useful to see as many working implementations of it as possible.
I think one working implementation, which works with all pixel formats and all vram start adresses, is better:
main.c
Makefile
I finally got around to implementing your improved screenshot code (the version you put links to subversion of), and of course, being the n00b I am, I have a few errors giving me trouble.
I've isolated the problem to your showimage function, when I comment it out, the screenshot functions works great, but when I leave your showimage function in there, it outputs this to the shell;
Code: Select all
Owner@Pavilion1200 /usr/local/pspdev/psp/sdk/My_Homebrew/test
$ make
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -c -o main.o mai
n.c
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -L. -L/usr/local/
pspdev/psp/sdk/lib main.o -lpng -lz -lpspdebug -lpspdisplay -lpspge -lpspctrl
-lpspsdk -lc -lpspuser -lpspkernel -o test.elf
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libpng.a(pngrtran.o): In
function `png_build_gamma_table':
pngrtran.c:(.text+0x1264): undefined reference to `pow'
pngrtran.c:(.text+0x147c): undefined reference to `pow'
pngrtran.c:(.text+0x1524): undefined reference to `pow'
pngrtran.c:(.text+0x163c): undefined reference to `pow'
pngrtran.c:(.text+0x1718): undefined reference to `pow'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libpng.a(pngrtran.o):png
rtran.c:(.text+0x1804): more undefined references to `pow' follow
collect2: ld returned 1 exit status
make: *** [test.elf] Error 1
Owner@Pavilion1200 /usr/local/pspdev/psp/sdk/My_Homebrew/test
$
And here is my screenshot.h file;
Code: Select all
//////////////////////////////////////////////////////////////////////////////////////////
// Screenshot.h Version 1.0
// By Jason J. Owens
// September 10, 2005 6:27 AM
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __SCREENSHOT__
#define __SCREENSHOT__
//////////////////////////////////////////////////////////////////////////////////////////
// #includes
#include <png.h>
//////////////////////////////////////////////////////////////////////////////////////////
// Function Prototypes
void Screenshot(const char* filename);
void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg);
void ShowImage(const char* filename);
//////////////////////////////////////////////////////////////////////////////////////////
// Function Definitions
// Saves the current contents of the screen to the filepath passed to 'filename'
void Screenshot(const char* filename)
{
u32* vram32;
u16* vram16;
int bufferwidth;
int pixelformat;
int unknown;
int i, x, y;
png_structp png_ptr;
png_infop info_ptr;
FILE* fp;
u8* line;
fp = fopen(filename, "wb");
if (!fp) return;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) return;
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
fclose(fp);
return;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, SCR_WIDTH, SCR_HEIGHT,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
line = (u8*) malloc(SCR_WIDTH * 3);
sceDisplayWaitVblankStart(); // if framebuf was set with PSP_DISPLAY_SETBUF_NEXTFRAME, wait until it is changed
sceDisplayGetFrameBuf((void*)&vram32, &bufferwidth, &pixelformat, &unknown);
vram16 = (u16*) vram32;
for (y = 0; y < SCR_HEIGHT; y++) {
for (i = 0, x = 0; x < SCR_WIDTH; x++) {
u32 color = 0;
u8 r = 0, g = 0, b = 0;
switch (pixelformat) {
case PSP_DISPLAY_PIXEL_FORMAT_565:
color = vram16[x + y * bufferwidth];
r = (color & 0x1f) << 3;
g = ((color >> 5) & 0x3f) << 2 ;
b = ((color >> 11) & 0x1f) << 3 ;
break;
case PSP_DISPLAY_PIXEL_FORMAT_5551:
color = vram16[x + y * bufferwidth];
r = (color & 0x1f) << 3;
g = ((color >> 5) & 0x1f) << 3 ;
b = ((color >> 10) & 0x1f) << 3 ;
break;
case PSP_DISPLAY_PIXEL_FORMAT_4444:
color = vram16[x + y * bufferwidth];
r = (color & 0xf) << 4;
g = ((color >> 4) & 0xf) << 4 ;
b = ((color >> 8) & 0xf) << 4 ;
break;
case PSP_DISPLAY_PIXEL_FORMAT_8888:
color = vram32[x + y * bufferwidth];
r = color & 0xff;
g = (color >> 8) & 0xff;
b = (color >> 16) & 0xff;
break;
}
line[i++] = r;
line[i++] = g;
line[i++] = b;
}
png_write_row(png_ptr, line);
}
free(line);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Function to pass warnings to, and it ignores them.
void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
{
// ignore PNG warnings
}
//////////////////////////////////////////////////////////////////////////////////////////
// Display screenshot saved at the filepath passed to 'filename'.
void ShowImage(const char* filename)
{
u32* vram32;
u16* vram16;
int bufferwidth;
int pixelformat;
int unknown;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, x, y;
u32* line;
FILE *fp;
if ((fp = fopen(filename, "rb")) == NULL) return;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(fp);
return;
}
png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
png_set_strip_16(png_ptr);
png_set_packing(png_ptr);
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
line = (u32*) malloc(width * 4);
if (!line) {
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return;
}
sceDisplayWaitVblankStart(); // if framebuf was set with PSP_DISPLAY_SETBUF_NEXTFRAME, wait until it is changed
sceDisplayGetFrameBuf((void*)&vram32, &bufferwidth, &pixelformat, &unknown);
vram16 = (u16*) vram32;
for (y = 0; y < height; y++) {
png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
for (x = 0; x < width; x++) {
u32 color32 = line[x];
u16 color16;
int r = color32 & 0xff;
int g = (color32 >> 8) & 0xff;
int b = (color32 >> 16) & 0xff;
switch (pixelformat) {
case PSP_DISPLAY_PIXEL_FORMAT_565:
color16 = (r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11);
vram16[x + y * bufferwidth] = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_5551:
color16 = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10);
vram16[x + y * bufferwidth] = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_4444:
color16 = (r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8);
vram16[x + y * bufferwidth] = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_8888:
color32 = r | (g << 8) | (b << 16);
vram32[x + y * bufferwidth] = color32;
break;
}
}
}
free(line);
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////////////////////
#endif
//////////////////////////////////////////////////////////////////////////////////////////
Any ideas?
Ask not for whom the bell tolls, it tolls for thee, besides, I'm playing my PSP, tee hee!
------------------------------------------------------
Visit my website for my PSP Homebrew!