Problems with screenshot code.
-
- Posts: 14
- Joined: Mon Aug 29, 2005 5:00 pm
- Location: Los Angeles, CA
- Contact:
Okay... i got past that error. I had to move that line of code into my main function... But the image still looks the same... i'll keep looking through the code...otherwise, any ideas?
UPDATE: I tried moving the buffer start into the main function, but that didnt work. now its saying the usual BS errors, "VRAM undeclared", "First Use of this function"
UPDATE: I tried moving the buffer start into the main function, but that didnt work. now its saying the usual BS errors, "VRAM undeclared", "First Use of this function"
-
- Posts: 14
- Joined: Mon Aug 29, 2005 5:00 pm
- Location: Los Angeles, CA
- Contact:
Here you go.
Code: Select all
// Include nescicary headers & other files
#include <pspkernel.h>
#include <pspdebug.h>
#include <string.h>
#include <stdlib.h>
#include <png.h>
#include <pspdisplay.h>
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
// Give the program a name -- This isnt the actual name
PSP_MODULE_INFO("xxxxxxxxxxx", 0, 1, 1);
// Rename things to make typing easier
#define printf pspDebugScreenPrintf // Prints to debug screen
#define debugClear pspDebugScreenClear // Clears debug screen
#define textColor pspDebugScreenSetTextColor // Sets debug text color
#define setCursor pspDebugScreenSetXY // Sets cursor on debug screen
#define bgColor pspDebugScreenSetBackColor // Sets background color on Debug screen
// Color converter
#define RGB(r, g, b) ((b << 16) | (g << 8) | r)
#define STEELBLUE RGB(43, 84, 126)
u16* data = VRAM;
// Essential exit stuff
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
// Main function, executed before anything else
int main(void) {
sceDisplaySetMode(1,SCR_WIDTH,SCR_HEIGHT);
// Start screenshot buffer
u16 *VRAM=(void *)(0X44000000);
pspDebugScreenInit();
SetupCallbacks();
// Set BG color
bgColor(SELECTED);
pspDebugScreenClear();
setCursor(25, 16);
printf("THIS IS A TEST OF THE PRINT SCREEN FEATURE");
screenshot("ms0:/test.png");
sceKernelExitGame();
}
void screenshot(const char* filename)
{
png_structp png_ptr;
png_infop info_ptr;
FILE* fp;
int i, x, y;
int width=SCR_WIDTH;
int height=SCR_HEIGHT;
int linesize=BUF_WIDTH;
int saveAlpha=0;
u8* line;
if ((fp = fopen(filename, "wb")) == NULL) 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);
return;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
saveAlpha ? PNG_COLOR_TYPE_RGBA : 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(width * (saveAlpha ? 4 : 3));
for (y = 0; y < height; y++) {
for (i = 0, x = 0; x < width; x++) {
u16 color = data[x + y * linesize];
int r = (color & 0x1f) << 3;
int g = ((color >> 5) & 0x1f) << 3 ;
int b = ((color >> 10) & 0x1f) << 3 ;
line[i++] = r;
line[i++] = g;
line[i++] = b;
if (saveAlpha) {
int a = color & 0x8000 ? 0xff : 0;
line[i++] = a;
}
}
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);
}
I've looked through your source, messed around and expieriemented with it. I even used some of my stuff and tried the same thing. And I confess, this has me dumbfounded as hell!
No matter what I do, I can't get text to be saved in the screenshot without being distorted. I can save pixel-drawn images just fine, but the text is distorted. I also managed to get the text to distort in the same way, but on the psp screen itself. It seems when you set the video mode, it messes with the debug text stuff, causing it to distort on screen. But it looks the same in the png as well! When I don't change video modes, the text looks fine on screen, but still distorts in the png.
I'm not sure if I explained that clearly enough. I'm sorry to say that I'm of no further help to you. I'm a noob too so, yeah, lol.
Ask shine about this, he seems to know his stuff.
Good luck!
[Edit] P.S. Please let me know if you find out what's wrong, as I'd like to draw graphics and text, and take screenshots, without any of them messing up.
No matter what I do, I can't get text to be saved in the screenshot without being distorted. I can save pixel-drawn images just fine, but the text is distorted. I also managed to get the text to distort in the same way, but on the psp screen itself. It seems when you set the video mode, it messes with the debug text stuff, causing it to distort on screen. But it looks the same in the png as well! When I don't change video modes, the text looks fine on screen, but still distorts in the png.
I'm not sure if I explained that clearly enough. I'm sorry to say that I'm of no further help to you. I'm a noob too so, yeah, lol.
Ask shine about this, he seems to know his stuff.
Good luck!
[Edit] P.S. Please let me know if you find out what's wrong, as I'd like to draw graphics and text, and take screenshots, without any of them messing up.
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!
------------------------------------------------------
Visit my website for my PSP Homebrew!
The debug text functions from PSPSDK uses 32 bit mode, which could cause problems if you are using 16 bit mode, like in the PNG save function.jason867 wrote:No matter what I do, I can't get text to be saved in the screenshot without being distorted. I can save pixel-drawn images just fine, but the text is distorted. I also managed to get the text to distort in the same way, but on the psp screen itself.
-
- Posts: 14
- Joined: Mon Aug 29, 2005 5:00 pm
- Location: Los Angeles, CA
- Contact:
If you are searching for a script, use Lua Player, this works all the time, C is not a script language :-)OmahaStylee wrote:Any ideas shrine? Is there another screenshot script that'll work all the time?
But would be useful to have a C screenshot code, which works all the time, perhaps you can write one? Use sceDisplayGetFrameBuf to determine the pixelformat and the start of the framebuffer and use this information to select the appropriate bit shifting before writing it as PNG.
-
- Posts: 14
- Joined: Mon Aug 29, 2005 5:00 pm
- Location: Los Angeles, CA
- Contact:
I could do that if I understood the bit shifting part. ( I do realize that bit shifting is simply rotating a series of bits in one direction or another, such as 00100 turning into 01000 or 00010, I just don't have any expierience in bit shifting)
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!
------------------------------------------------------
Visit my website for my PSP Homebrew!
Bit shifting in C is not rotating, it is shifting. The term "rotating" is used for example when left shifting and the highest bit is fed into the lowest bit again.jason867 wrote:I could do that if I understood the bit shifting part. ( I do realize that bit shifting is simply rotating a series of bits in one direction or another, such as 00100 turning into 01000 or 00010
Then this is a really good task to gain some experience :-)jason867 wrote:I just don't have any expierience in bit shifting)
-
- Posts: 14
- Joined: Mon Aug 29, 2005 5:00 pm
- Location: Los Angeles, CA
- Contact:
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
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.
This is how I call the screen_shot function in my main file:
This is my custom file with all the important define's I use in my project (I centralized there some things from graphics.h and other files):
This is my .h file in which the screen_shot function is located:
This is the corresponding .cpp file:
As you take from my define's file I am taking a single screen_shot, in the main file, from what it is the current front-buffer (I take it after the SwapBuffers function has been called).
I hope this helps in some way.
This is how I call the screen_shot function in my main file:
Code: Select all
screenshot("ms0:/PSP/PHOTO/screen_shot.png", (u16 *) UNCACHED_VRAM_PTR (FRAME_BUFFER_1));
Code: Select all
#ifndef PSP_DEFINES_H
#define PSP_DEFINES_H
#include <psptypes.h>
#define addr_align( x ) __attribute__((aligned( x )));
#define PI 3.14159265358979323846
#define PSP_LINE_SIZE 512
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
#define IS_ALPHA(COLOUR) ((COLOUR)&0x8000?0:1)
#define FRAMEBUFFER_SIZE (PSP_LINE_SIZE*SCREEN_HEIGHT*2) //16 bpp color depth
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define RGBA_5551 (2)
#define RGBA_5650 (2)
#define RGBA_4444 (2)
#define RGBA_8888 (4)
#define PIXEL_SIZE (RGBA_5551) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH * SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
#define UNCACHED_ADDR 0x40000000
#define UNCACHED_PTR(X) ((X) | (UNCACHED_ADDR))
#define VRAM_PTR(Y) ((Y) | 0x04000000)
#define SPRAM_PTR(Y) ((Y) | 0x00010000
#define MAIN_RAM_PTR(Y) ((Y) | 0x08800000)
#define UNCACHED_VRAM_PTR(Z) ((VRAM_PTR(Z)) | (UNCACHED_ADDR))
#define UNCACHED_SPRAM_PTR(Z) ((SPRAM_PTR(Z)) | (UNCACHED_ADDR))
#define UNCACHED_MAIN_RAM_PTR(Z) ((MAIN_RAM_PTR(Z)) | (UNCACHED_ADDR))
/* PSP Memory Map
Base Address Length Description
0×00010000 0×00004000 (16 KiB) Allegrex Scratchpad
0×04000000 0×00200000 (2 MiB) Ge VRAM
0×08000000 0×00800000 (8 MiB) Allegrex Kernel memory
0×08800000 0×01800000 (24 MiB) Allegrex User memory*/
//The following three Macro's are used to help set-up the screen and
//assume the function you will pass the result to will take them as
//VRAM addresses, taking upon itself to OR them with the VRAM base address 0x04000000
#define FRAME_BUFFER_1 (0x0)
#define FRAME_BUFFER_2 (FRAME_SIZE)
#define Z_BUFFER ((FRAME_BUFFER_2) + (FRAME_SIZE))
typedef union IGGSPspMatrix4 {
ScePspFMatrix4 fm;
ScePspIMatrix4 im;
ScePspFVector4 fv[4];
ScePspIVector4 iv[4];
ScePspVector4 v[4];
float m[4*4];
int m_i[4*4];
} IGGSPspMatrix4 addr_align (16);
typedef u16 Color;
typedef short unsigned int uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
typedef unsigned long long ulong64;
#endif
Code: Select all
#ifndef PSP_UTILS_H
#define PSP_UTILS_H
#include <psptypes.h>
#include "PSPDefines.h"
/**
* Save an image or the screen in PNG format.
*
* @pre filename != NULL
* @param filename - filename of the PNG image
* @param data - start of Color type pixel data (can be getVramDisplayBuffer())
* @param width - logical width of the image or SCREEN_WIDTH
* @param height - height of the image or SCREEN_HEIGHT
* @param lineSize - physical width of the image or PSP_LINE_SIZE
* @param saveAlpha - if 0, image is saved without alpha channel
*/
/*when you call the screenshot, make sure to type a valid file path, such as;
screenshot("ms0:/filepath.png");
With filepath being your filepath. You have to have 'ms0:/' at the
beginning and '.png' at the end. Once called you'll see your memory stick led flash
several times, and then when you hook up your psp to your pc, you'll find your filepath.png
screenshot file at the directory of your memory stick that you set it to write to.*/
extern void screenshot(const char* filename, u16 * VRAM_ADDR);
#endif
This is the corresponding .cpp file:
Code: Select all
#include <stdlib.h>
#include <malloc.h>
#include <pspdisplay.h>
#include <psputils.h>
#include <png.h>
#include <pspgu.h>
#include "PSPDefines.h"
#include "PSP_Utils.h"
//static unsigned int __attribute__((aligned(16))) list[256];
//static int dispBufferNumber;
//static int initialized = 0;
void screenshot(const char* filename, u16 * VRAM_ADDR) {
png_structp png_ptr;
png_infop info_ptr;
FILE* fp;
int i, x, y;
u16* data = VRAM_ADDR;
int width=SCR_WIDTH;
int height=SCR_HEIGHT;
int linesize=BUF_WIDTH;
int saveAlpha=0;
u8* line;
if ((fp = fopen(filename, "wb")) == NULL) 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);
return;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
saveAlpha ? PNG_COLOR_TYPE_RGBA : 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(width * (saveAlpha ? 4 : 3));
for (y = 0; y < height; y++) {
for (i = 0, x = 0; x < width; x++) {
u16 color = data[x + y * linesize];
int r = (color & 0x1f) << 3;
int g = ((color >> 5) & 0x1f) << 3 ;
int b = ((color >> 10) & 0x1f) << 3 ;
line[i++] = r;
line[i++] = g;
line[i++] = b;
if (saveAlpha) {
int a = color & 0x8000 ? 0xff : 0;
line[i++] = a;
}
}
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);
}
//void flipScreen() //here as commented sample code
//{
// if (!initialized) return;
// Color* vram = getVramDrawBuffer();
// sceGuSwapBuffers();
// sceDisplaySetFrameBuf(vram, PSP_LINE_SIZE, 1, 1);
// dispBufferNumber ^= 1;
//}
I hope this helps in some way.
-
- Posts: 82
- Joined: Mon Jun 20, 2005 3:32 am
hey shine, ive been using your graphics.c and graphics.h files..and i was trying to do a 65 frame animation today (65 png files) and well, when displaying the 37th frame, i get an exception..and it points to the blittoscreen function
sceGuCopyImage(GU_PSM_5551, sx, sy, width, height, source->textureWidth, source->data, dx, dy, PSP_LINE_SIZE, vram);
points to that line..
not sure whats wrong? any idea?
sceGuCopyImage(GU_PSM_5551, sx, sy, width, height, source->textureWidth, source->data, dx, dy, PSP_LINE_SIZE, vram);
points to that line..
not sure whats wrong? any idea?
Shine, I just tried your main.c and Makefile that you last posted. Either I'm having serious environment set up problems or it's just not compiling for me. I've compiled other sources before without errors, but I'm getting various errors. First one asks for png.h, so I downloaded it and put it with the source and that lead to a thread of errors that scrolls the screen for awhile.
Not sure what's happening here. Unless someone wants to run me through reinstallation. ;)
Not sure what's happening here. Unless someone wants to run me through reinstallation. ;)
Quoting jason867 from earlier in this thread:Shiki wrote:Shine, I just tried your main.c and Makefile that you last posted. Either I'm having serious environment set up problems or it's just not compiling for me. I've compiled other sources before without errors, but I'm getting various errors. First one asks for png.h, so I downloaded it and put it with the source and that lead to a thread of errors that scrolls the screen for awhile.
jason867 wrote:
in your Cygwin Bash Shell (or whatever you use) enter the folowing lines;
svn co svn://svn.ps2dev.org/psp/trunk/zlib -- press [Enter] and wait for the prompt to show back up.
svn co svn://svn.ps2dev.org/psp/trunk/libpng -- press [Enter] and wait for the prompt to show back up.
[Edit] Those two lines up just above this look like links to websites, but they're not, so don't even bother clicking on them.
then you need to change your directory in the bash shell to your psptoolchain/zlib folder, and then type 'make' and then 'make install'
then change the directory over to your psptoolchain/libpng folder and type 'make' and 'make install' again.
Are you sure, that all pointer are valid (no NULL pointers)? If there is not enough memory, loadImage returns NULL and you have to check this. Maybe there are memory leaks in my functions or you forgot to free the memory, can't say it without your source.JJPeerless wrote:hey shine, ive been using your graphics.c and graphics.h files..and i was trying to do a 65 frame animation today (65 png files) and well, when displaying the 37th frame, i get an exception..and it points to the blittoscreen function
sceGuCopyImage(GU_PSM_5551, sx, sy, width, height, source->textureWidth, source->data, dx, dy, PSP_LINE_SIZE, vram);
points to that line..
not sure whats wrong? any idea?
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
Did I push 99% of your buttons at once ?
Hehe, come on I was trying to help. I am glad you posted that code though, it is clean and can be easy plugged in (I quickly replaced the other function: hey, I can admit when a tool is better than another one, after-all it is just a means to an end, not the goal itself :)... well for me, not for the tool designer maybe :D).
I noticed that the code we were using before has problem if the file you are trying to save as the same name as one on the memory stick (running the same program twice without deleting the svaed screenshot).
It should be an easy fix as I had it already in my screenshot code for PS2Linux.
I have tested this with my latest code and of course there is no problem, because fopen with "wb" overwrites old files, as specified by the definition of fopen.Panajev2001a wrote:I noticed that the code we were using before has problem if the file you are trying to save as the same name as one on the memory stick (running the same program twice without deleting the svaed screenshot).
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
Well, I was mentioning the old code (on which I based the code snippets I posted). It might have been related to something else, but I clearly observed it: took a screenshot, restarted the program... it hangs... restart PSP, restart the program... it hangs... restart the PSP, delete the screen_shot, restart the program... it works.Shine wrote:I have tested this with my latest code and of course there is no problem, because fopen with "wb" overwrites old files, as specified by the definition of fopen.Panajev2001a wrote:I noticed that the code we were using before has problem if the file you are trying to save as the same name as one on the memory stick (running the same program twice without deleting the svaed screenshot).
I still am not happy with "wb", it would be neat to just call the screen_shot function each frame and make small movies compositing the frames (this is what I did on PS2Linux... got the images to a series of .ppm files, converted them to jpeg's IIRC and made a small movie... which is fairly smooth too :)).
Memory Stick writes currently kinda "pause" the program, but if you have some "pre-defined" animation (user-input is kinda difficult to apply in an useful way when the fps count is low as if you took a screen_shot each frame: of course you could composite the movie directly in RAM and only save the final file, but that is a topic for another day) that is updated at each iteration of the infinite game loop, then you should be all set anyways.
Basically "wb" is good, but if the code can be modified to do this:
screenshot ("ms0:/image.png");
with this function generating image0000.png, image0001.png, image0002.png, image0003.png, image0005.png, etc... then it would be quasi-perfect IMHO.
Edit: as with the code snippet I have posted here, we could change a bit your function like so:
Code: Select all
static int m_SS_Number = 0;
sprintf (name, "ms0:/filename%05d.png", m_SS_Number);
// Open the file for writing to
FILE * f = fopen(name, "wb");
Here is the code I was mentioning: I also create a .bat file to ease the conversion of the files into JPEG's. I am not sure if sprintf is supported with PSPSDK's libs. I do not see why it should not though.
Code: Select all
void ScreenShotPPM(int addr)
{
static int m_SS_Number = 0;
static int numFrames = 0;
numFrames++;
char name[256];
char name1[256];
unsigned char * data;
//unsigned char tmp;
unsigned short Width, Height;
int BytesPerPixel = 3;
//_sps2SetEIDIEnabled(1, m_iSPS2Desc);
// Current Screen width and height
Width = (unsigned short)sps2UScreenGetWidth();
Height = (unsigned short)sps2UScreenGetHeight();
//printf("%x %x", Width, Height);
sprintf (name, "video/movie%05d.ppm", m_SS_Number);
sprintf (name1, "IGGS_JPEG_script.bat");
// Open the file for writing to
FILE * f = fopen(name, "wb");
FILE * pfScript = fopen(name1, "ab");
// Create a targa header for a 640x480, 32bit picture
const char header[] = { "P6 640 448 255\n" };
fprintf(pfScript, "cjpeg.exe -outfile \\\\ps2linux\\Panajev\\IGGS_PS2\\video\\IGGS_PS2_%05d.jpg \\\\ps2linux\\Panajev\\IGGS_PS2\\video\\movie%05d.ppm\n", m_SS_Number, m_SS_Number );
m_SS_Number++;
//for(int i =0; i< 18; i++)printf("%x ", header[i]);printf("\n");
// write the header to the file
fwrite(header, strlen (header), 1, f);
// Now Download the Frame buffer, from the bottom up
for(int y = 0; y < Height; y++)
{
DownloadVram(m_ScreenShot_global_dma, m_ScreenShot_global, addr, 10, 0, (y), Width, 1);
// convert RGBA to BGRA
data = (unsigned char *)m_ScreenShot_global;
for(int x = 0; x < Width; x++)
{
//tmp = data[0];
//data[0] = data[2];
//data[2] = tmp;
//
// Write pixel to file
fwrite(data, BytesPerPixel, 1, f);
data += 4;
}
// Write data to file
//fwrite(GetSShotBase(), 4, Width, f);
}
// Close the file
fclose(f);
fclose(pfScript);
}
void DownloadVram (void * const pDmaBase, void * const pMemBase,
int addr, int bufw, int x, int y, int w, int h)
{
// Pointer to sps2 allocated unswapable memory.
uint32 * pDmaMem = (uint32 *)pDmaBase;
uint32 uSrcPtr = addr;
uint32 uQSize = (w*h*4)/16; // assuming 24/32bit framebuffer
// Setup transfer texture back to memory
pDmaMem[0] = 0; //NOP;
pDmaMem[1] = 0x06008000; //MSKPATH3(0x8000);
pDmaMem[2] = 0x13000000; //FLUSHA;
pDmaMem[3] = 0x50000006; //DIRECT(6);
// Add GifTag Data
uint64 * pDmaMem64 = (uint64 *) (pDmaMem + 4);
// QW1: The Giftag for A+D mode
sps2GIFTag_t * pGIFTag = (sps2GIFTag_t *)pDmaMem64;
pGIFTag->i128 = 0;
pGIFTag->s.NLOOP = 5; // We want to set 5 registers
pGIFTag->s.PRE = 0;
pGIFTag->s.EOP = 1; // This is the end of the GS Packet
pGIFTag->s.FLG = GIF_FLG_PACKED;
pGIFTag->s.NREG = 1;
pGIFTag->s.REGS = GIF_REG_A_D;
pDmaMem64[2] = (BITBLTBUF_SET( uSrcPtr, bufw, 0, 0, 0, 0 ));
pDmaMem64[3] = (GIF_A_D_REG_BITBLTBUF);
pDmaMem64[4] = (TRXPOS_SET(x, y, 0, 0, 0)); // SSAX, SSAY, DSAX, DSAY, DIR
pDmaMem64[5] = (GIF_A_D_REG_TRXPOS);
pDmaMem64[6] = (TRXREG_SET(w, h)); // RRW, RRh
pDmaMem64[7] = (GIF_A_D_REG_TRXREG);
pDmaMem64[8] = (0);
pDmaMem64[9] = (GIF_A_D_REG_FINISH);
pDmaMem64[10] = (TRXDIR_SET(1)); // XDIR
pDmaMem64[11] = (GIF_A_D_REG_TRXDIR);
uint32 prev_chcr = *EE_D1_CHCR;
// *_GS_IMR fetches the current setting of interrupt mask register (imr)
// DPUT_GS_IMR() sets the current value of imr
// Mark interrupts from the FINISH Event (GS Page 154)
uint32 prev_imr = *_GS_IMR;
DPUT_GS_IMR( prev_imr | 0x0200 );
// vif1 must be available
if ((*EE_D1_CHCR & 0x0100) != 0)
{
printf("VIF1 is not available for the Screen Shot\n");
exit(-1);
}
// Enable generation of the FINISH Event (GS Page 145)
DPUT_GS_CSR( 2 );
// Disable interrupts so we don't lose our finish event
asm __volatile__ ("di");
// Make sure all cache is writen to main memory
sps2FlushCache(iSPS2Device);
// Setup and start DMA transfer to VIF1
*EE_D1_QWC = 0x7;
*EE_D1_MADR = sps2GetPhysicalAddress(pDmaBase, memScreenShot );
// DIR MOD ASP TTE TIE STR
*EE_D1_CHCR = (1<<0) | (0<<2) | (0<<4) | (0<<6) | (0<<7) | (1<<8);
// Wait till memory load is complete
asm __volatile__( " sync.l " );
// Wait till DMA is complete (STR=0)
while ( *EE_D1_CHCR & 0x0100 );
// Wait for the GS to finish loading the registers (FINISH EVENT)
//while ( ((*GS_CSR_OFF(SPS2_GS_REGISTERS_START)) & 2) == 0 );
while ( (*_GS_CSR & 2) == 0 );
// Re-enable interrupts
asm __volatile__ ("ei");
// START! The actual download to memory
// wait for VIF1-FIFO to empty and become idle
while(*EE_VIF1_STAT & 0x1f000003);
// Change the VIF1 direction to VIF1->Memory
*((volatile uint32 *) EE_VIF1_STAT) = (1<<23);
// Change direction of VIF1 FIF0 Local->Host
DPUT_GS_BUSDIR( ( uint64 ) 0x00000001 );
// Setup and start DMA transfer from VIF1
*EE_D1_QWC = uQSize;
*EE_D1_MADR = sps2GetPhysicalAddress(pMemBase, memScreenShot);
// DIR MOD ASP TTE TIE STR
*EE_D1_CHCR = 0 | (0<<2) | (0<<4) | (0<<6) | (0<<7) | (1<<8);
// Wait till memory load is complete
asm __volatile__( " sync.l " );
// check if DMA is complete (STR=0)
while ( *EE_D1_CHCR & 0x0100 );
// Restore CHCR and wait for it to complete
*EE_D1_CHCR = prev_chcr;
asm __volatile__( " sync.l " );
// wait for VIF1-FIFO to empty and become idle
while ( *EE_VIF1_STAT & 0x1f000003 );
// Change the VIF1 and VIF1 FIFO Direction back to normal
*((volatile uint32 *) EE_VIF1_STAT) = 0;
DPUT_GS_BUSDIR( ( uint64 ) 0 );
// restore the setting of IMR
DPUT_GS_IMR( prev_imr);
// set the FINISH event to default
//dput_gs_csr( GS_EE_CSR_FINISH_M );
DPUT_GS_CSR( 2 );
// Re-enable path3 transfers
static uint32 enable_path3[4] ALIGN_QW = {
0x06000000, //MSKPATH3(0),
0,
0,
0};
DPUT_EE_VIF1_FIFO( *( uint128 * ) enable_path3 );
// Make sure data is written to main memory
sps2FlushCache(iSPS2Device);
}
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
Here:
(I am testing it as we speak, it should work)
Conceptually, now writing proper C++ code is another matter... lol, I am hungry... need to feeeeed :).
The "filename" string needs now to be passed as a char * not as a const char * data.
just one smaller fix and this should be sweet: the use of strcat is not so intelligent done this way as it keeps adding the same string to the filename, getting it longer and longer.
Code: Select all
char name[256];
static int m_SS_Number = 0;
sprintf (name, "_%05d.png", m_SS_Number);
strcat (filename, name);
fp = fopen(filename, "wb");
Conceptually, now writing proper C++ code is another matter... lol, I am hungry... need to feeeeed :).
The "filename" string needs now to be passed as a char * not as a const char * data.
just one smaller fix and this should be sweet: the use of strcat is not so intelligent done this way as it keeps adding the same string to the filename, getting it longer and longer.
Last edited by Panajev2001a on Fri Sep 02, 2005 9:30 pm, edited 1 time in total.
No, this will crash in most cases, because you are writing to "filename", which could be shorter than the required number of bytes. Use sprintf(name, "%s_%05d.png", filename, m_SS_Number) instead and then "name" instead of "filename" for creating the file. To be sure, use malloc for "name" and free at end and calculate the length based on strlen(filename).Panajev2001a wrote:Here:
(I am testing it as we speak, it should work)Code: Select all
char name[256]; static int m_SS_Number = 0; sprintf (name, "_%05d.png", m_SS_Number); strcat (filename, name); fp = fopen(filename, "wb");
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
Edit: yeah, thanks Shine :).Shine wrote:No, this will crash in most cases, because you are writing to "filename", which could be shorter than the required number of bytes. Use sprintf(name, "%s_%05d.png", filename, m_SS_Number) instead and then "name" instead of "filename" for creating the file. To be sure, use malloc for "name" and free at end and calculate the length based on strlen(filename).Panajev2001a wrote:Here:
(I am testing it as we speak, it should work)Code: Select all
char name[256]; static int m_SS_Number = 0; sprintf (name, "_%05d.png", m_SS_Number); strcat (filename, name); fp = fopen(filename, "wb");
How effective is this code in taking frames in a row? I made a variation which boots another file and tried to take screenshots while there was an animation happening and the results left the shots distorted. Is there a way to buffer up the frames and then give it time to slowly save it in memory after a few frames are buffered up?
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
That is very strange, never happened to me on PS2... well I had an HDD and not a Flash memory I was writing to and the RAM -> HDD process was a tad faster too I'd think than the PSP RAM -> Memory Stick transfer.Shiki wrote:How effective is this code in taking frames in a row? I made a variation which boots another file and tried to take screenshots while there was an animation happening and the results left the shots distorted. Is there a way to buffer up the frames and then give it time to slowly save it in memory after a few frames are buffered up?
Panajev2001a, I think I was refering to the main.c that Shine posted.
But you seem to know what I'm talking about too. The program's function saves the screens in lines of pixels at a time, if the screen is animated each line will be different from the previous screens lines. This distorts the picture.
I wanted to take a few shots in a row and try animated it in flash.
But you seem to know what I'm talking about too. The program's function saves the screens in lines of pixels at a time, if the screen is animated each line will be different from the previous screens lines. This distorts the picture.
I wanted to take a few shots in a row and try animated it in flash.
In the libpng folder is a sample, how to save one image at once, which uses 522240 bytes instead of only one line with 1920 bytes. If this is ok for your application, you should try it, but I don't think that it helps much.Shiki wrote:Panajev2001a, I think I was refering to the main.c that Shine posted.
But you seem to know what I'm talking about too. The program's function saves the screens in lines of pixels at a time, if the screen is animated each line will be different from the previous screens lines. This distorts the picture.
I wanted to take a few shots in a row and try animated it in flash.
Perhaps a better idea would be to transfer it with FTP. Really nice would be to write a network driver, which lets you to connect to a Unix NFS drive from PSP and write to it like to memory stick :-)
-
- Posts: 100
- Joined: Sat Aug 20, 2005 3:25 am
Umph, that still should not be a problem.Shiki wrote:Panajev2001a, I think I was refering to the main.c that Shine posted.
But you seem to know what I'm talking about too. The program's function saves the screens in lines of pixels at a time, if the screen is animated each line will be different from the previous screens lines. This distorts the picture.
I wanted to take a few shots in a row and try animated it in flash.
Unless you write to the Display/Front-buffer I fail to see how this affects anything.
Let's go over what happens (how I see it anyway heh).
1.) You render the scene in the Draw/Back-buffer.
2.) Back and Front buffers are swapped (SwapBuffers ())
3.) Read from the Front-buffer while it is being displayed into the file (screenshot (...)).
4.) while the screenshot is being taken, your application is working on the next frame of animation rendering it into the "current" Back-buffer.
5.) go back to 2.)
Unless the screenshot (...) function reads from the buffer for a time longer than Vblank + 1 frame_time... there should not be any problems.
Something could be done if you saved the image in RAM and after that you wrote it to a file... adding a mid-step which would allow your function to take a little longer effectively pipelining things.
Edit: are you maybe taking the screenshot taking data from the back-buffer before the switch ? (it would be strange as his function seems to obtain from PSPSDK's libs the DisplayBuffer)