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!