somewhat improved memory management. hopefully GameCube memory issues are gone now :)

This commit is contained in:
dborth 2010-06-29 07:48:17 +00:00
parent 7b9772cec9
commit f3aa820d4d
12 changed files with 201 additions and 98 deletions

View File

@ -37,7 +37,7 @@
#define THREAD_SLEEP 100 #define THREAD_SLEEP 100
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN(32); unsigned char *savebuffer = NULL;
static mutex_t bufferLock = LWP_MUTEX_NULL; static mutex_t bufferLock = LWP_MUTEX_NULL;
FILE * file; // file pointer - the only one we should ever use! FILE * file; // file pointer - the only one we should ever use!
bool unmountRequired[7] = { false, false, false, false, false, false, false }; bool unmountRequired[7] = { false, false, false, false, false, false, false };

View File

@ -43,7 +43,7 @@ size_t LoadSzFile(char * filepath, unsigned char * rbuffer);
size_t SaveFile(char * buffer, char *filepath, size_t datasize, bool silent); size_t SaveFile(char * buffer, char *filepath, size_t datasize, bool silent);
size_t SaveFile(char * filepath, size_t datasize, bool silent); size_t SaveFile(char * filepath, size_t datasize, bool silent);
extern unsigned char savebuffer[SAVEBUFFERSIZE]; extern unsigned char *savebuffer;
extern FILE * file; extern FILE * file;
extern bool unmountRequired[]; extern bool unmountRequired[];
extern bool isMounted[]; extern bool isMounted[];

View File

@ -20,7 +20,7 @@ GuiImageData::GuiImageData(const u8 * i, int maxw, int maxh)
height = 0; height = 0;
if(i) if(i)
data = DecodePNG(i, &width, &height, maxw, maxh); data = DecodePNG(i, &width, &height, data, maxw, maxh);
} }
/** /**

43
source/mem2.cpp Normal file
View File

@ -0,0 +1,43 @@
/****************************************************************************
* Snes9x Nintendo Wii/Gamecube Port
*
* Tantric 2010
*
* mem2.cpp
*
* MEM2 memory allocator
***************************************************************************/
#ifdef HW_RVL
#include <ogc/machine/asm.h>
#include <ogc/lwp_heap.h>
#include <ogc/system.h>
#include <ogc/machine/processor.h>
static heap_cntrl mem2_heap;
u32 InitMem2Manager ()
{
int size = (12*1024*1024);
u32 level;
_CPU_ISR_Disable(level);
size &= ~0x1f; // round down, because otherwise we may exceed the area
void *mem2_heap_ptr = (void *)((u32)SYS_GetArena2Hi()-size);
SYS_SetArena2Hi(mem2_heap_ptr);
_CPU_ISR_Restore(level);
size = __lwp_heap_init(&mem2_heap, mem2_heap_ptr, size, 32);
return size;
}
void* mem2_malloc(u32 size)
{
return __lwp_heap_allocate(&mem2_heap, size);
}
bool mem2_free(void *ptr)
{
return __lwp_heap_free(&mem2_heap, ptr);
}
#endif

22
source/mem2.h Normal file
View File

@ -0,0 +1,22 @@
/****************************************************************************
* Snes9x Nintendo Wii/Gamecube Port
*
* Tantric 2010
*
* mem2.h
*
* MEM2 memory allocator
***************************************************************************/
#ifdef HW_RVL
#ifndef _MEM2MANAGER_H_
#define _MEM2MANAGER_H_
u32 InitMem2Manager ();
void* mem2_malloc(u32 size);
bool mem2_free(void *ptr);
#endif
#endif

View File

@ -53,8 +53,8 @@ static GuiTrigger * trigA = NULL;
static GuiTrigger * trig2 = NULL; static GuiTrigger * trig2 = NULL;
static GuiButton * btnLogo = NULL; static GuiButton * btnLogo = NULL;
static GuiImageData * gameScreen = NULL;
static GuiImage * gameScreenImg = NULL; static GuiImage * gameScreenImg = NULL;
static GuiImage * bgImg = NULL;
static GuiImage * bgTopImg = NULL; static GuiImage * bgTopImg = NULL;
static GuiImage * bgBottomImg = NULL; static GuiImage * bgBottomImg = NULL;
static GuiSound * bgMusic = NULL; static GuiSound * bgMusic = NULL;
@ -851,11 +851,7 @@ static void WindowCredits(void * ptr)
{ {
UpdatePads(); UpdatePads();
if(gameScreenImg) gameScreenImg->Draw();
gameScreenImg->Draw();
else
bgImg->Draw();
bgBottomImg->Draw(); bgBottomImg->Draw();
bgTopImg->Draw(); bgTopImg->Draw();
creditsWindow.Draw(); creditsWindow.Draw();
@ -1434,14 +1430,17 @@ static int MenuGame()
{ {
if (WindowPrompt("Quit Game", "Quit this game? Any unsaved progress will be lost.", "OK", "Cancel")) if (WindowPrompt("Quit Game", "Quit this game? Any unsaved progress will be lost.", "OK", "Cancel"))
{ {
if(gameScreenImg) HaltGui();
{ mainWindow->Remove(gameScreenImg);
mainWindow->Remove(gameScreenImg); delete gameScreenImg;
delete gameScreenImg; delete gameScreen;
gameScreenImg = NULL; gameScreen = NULL;
} free(gameScreenPng);
gameScreenPng = NULL;
bgImg->SetVisible(true); gameScreenImg = new GuiImage(screenwidth, screenheight, (GXColor){175, 200, 215, 255});
gameScreenImg->ColorStripe(10);
mainWindow->Insert(gameScreenImg, 0);
ResumeGui();
#ifndef NO_SOUND #ifndef NO_SOUND
bgMusic->Play(); // startup music bgMusic->Play(); // startup music
#endif #endif
@ -3784,29 +3783,22 @@ MainMenu (int menu)
mainWindow = new GuiWindow(screenwidth, screenheight); mainWindow = new GuiWindow(screenwidth, screenheight);
bgImg = new GuiImage(screenwidth, screenheight, (GXColor){175, 200, 215, 255});
bgImg->ColorStripe(10);
mainWindow->Append(bgImg);
if(menu == MENU_GAME) if(menu == MENU_GAME)
{ {
IMGCTX pngContext = PNGU_SelectImageFromBuffer(gameScreenPng); gameScreen = new GuiImageData(gameScreenPng);
gameScreenImg = new GuiImage(gameScreen);
if (pngContext != NULL)
{
gameScreenPngSize = PNGU_EncodeFromGXTexture(pngContext, vmode->fbWidth, vmode->efbHeight, gameScreenTex, 0);
PNGU_ReleaseImageContext(pngContext);
DCFlushRange(gameScreenPng, gameScreenPngSize);
}
gameScreenImg = new GuiImage(gameScreenTex, vmode->fbWidth, vmode->efbHeight);
gameScreenImg->SetAlpha(192); gameScreenImg->SetAlpha(192);
gameScreenImg->ColorStripe(30); gameScreenImg->ColorStripe(30);
gameScreenImg->SetScaleX(screenwidth/(float)vmode->fbWidth); gameScreenImg->SetScaleX(screenwidth/(float)vmode->fbWidth);
gameScreenImg->SetScaleY(screenheight/(float)vmode->efbHeight); gameScreenImg->SetScaleY(screenheight/(float)vmode->efbHeight);
mainWindow->Append(gameScreenImg);
bgImg->SetVisible(false);
} }
else
{
gameScreenImg = new GuiImage(screenwidth, screenheight, (GXColor){175, 200, 215, 255});
gameScreenImg->ColorStripe(10);
}
mainWindow->Append(gameScreenImg);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM);
GuiSound btnSoundClick(button_click_pcm, button_click_pcm_size, SOUND_PCM); GuiSound btnSoundClick(button_click_pcm, button_click_pcm_size, SOUND_PCM);
@ -3929,17 +3921,20 @@ MainMenu (int menu)
#endif #endif
delete btnLogo; delete btnLogo;
delete bgImg; delete gameScreenImg;
delete bgTopImg; delete bgTopImg;
delete bgBottomImg; delete bgBottomImg;
delete mainWindow; delete mainWindow;
mainWindow = NULL; mainWindow = NULL;
if(gameScreenImg) if(gameScreen)
delete gameScreen;
if(gameScreenPng)
{ {
delete gameScreenImg; free(gameScreenPng);
gameScreenImg = NULL; gameScreenPng = NULL;
} }
// wait for keys to be depressed // wait for keys to be depressed

View File

@ -455,7 +455,7 @@ DefaultSettings ()
Settings.Stereo = true; Settings.Stereo = true;
Settings.ReverseStereo = true; Settings.ReverseStereo = true;
Settings.SoundPlaybackRate = 32000; Settings.SoundPlaybackRate = 32000;
Settings.SoundInputRate = 32000; Settings.SoundInputRate = 31955;
// Graphics // Graphics
Settings.Transparency = true; Settings.Transparency = true;

View File

@ -39,6 +39,7 @@
#include "fileop.h" #include "fileop.h"
#include "filebrowser.h" #include "filebrowser.h"
#include "input.h" #include "input.h"
#include "mem2.h"
#include "utils/usb2storage.h" #include "utils/usb2storage.h"
#include "utils/mload.h" #include "utils/mload.h"
#include "utils/FreeTypeGX.h" #include "utils/FreeTypeGX.h"
@ -339,6 +340,9 @@ main(int argc, char *argv[])
ResetVideo_Menu (); // change to menu video mode ResetVideo_Menu (); // change to menu video mode
SetupPads(); SetupPads();
MountAllFAT(); // Initialize libFAT for SD and USB MountAllFAT(); // Initialize libFAT for SD and USB
#ifdef HW_RVL
InitMem2Manager();
#endif
// Initialize DVD subsystem (GameCube only) // Initialize DVD subsystem (GameCube only)
#ifdef HW_DOL #ifdef HW_DOL
@ -378,8 +382,13 @@ main(int argc, char *argv[])
S9xInitSync(); // initialize frame sync S9xInitSync(); // initialize frame sync
InitFreeType((u8*)font_ttf, font_ttf_size); // Initialize font system InitFreeType((u8*)font_ttf, font_ttf_size); // Initialize font system
gameScreenPng = (u8 *)malloc(512*1024); #ifdef HW_RVL
savebuffer = (unsigned char *)mem2_malloc(SAVEBUFFERSIZE);
browserList = (BROWSERENTRY *)mem2_malloc(sizeof(BROWSERENTRY)*MAX_BROWSER_SIZE);
#else
savebuffer = (unsigned char *)malloc(SAVEBUFFERSIZE);
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY)*MAX_BROWSER_SIZE); browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY)*MAX_BROWSER_SIZE);
#endif
AllocGfxMem(); AllocGfxMem();
InitGUIThreads(); InitGUIThreads();

View File

@ -1,15 +1,14 @@
/******************************************************************************************** /****************************************************************************
* *
* PNGU * PNGU
* *
* Original author: frontier (http://frontier-dev.net) * Original author: frontier (http://frontier-dev.net)
* Modified by Tantric, 2009-2010 * Modified by Tantric, 2009-2010
* *
********************************************************************************************/ ***************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <malloc.h> #include <malloc.h>
#include <gccore.h>
#include "pngu.h" #include "pngu.h"
#include <png.h> #include <png.h>
@ -43,12 +42,12 @@ struct _IMGCTX
int source; int source;
void *buffer; void *buffer;
char *filename; char *filename;
PNGU_u32 cursor; u32 cursor;
PNGU_u32 propRead; u32 propRead;
PNGUPROP prop; PNGUPROP prop;
PNGU_u32 infoRead; u32 infoRead;
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
FILE *fd; FILE *fd;
@ -294,7 +293,7 @@ static int pngu_info (IMGCTX ctx)
return PNGU_OK; return PNGU_OK;
} }
static int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha) static int pngu_decode (IMGCTX ctx, u32 width, u32 height, u32 stripAlpha)
{ {
png_uint_32 rowbytes; png_uint_32 rowbytes;
png_uint_32 i, propImgHeight; png_uint_32 i, propImgHeight;
@ -369,14 +368,14 @@ static int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 st
return PNGU_OK; return PNGU_OK;
} }
static inline PNGU_u32 coordsRGBA8(PNGU_u32 x, PNGU_u32 y, PNGU_u32 w) static inline u32 coordsRGBA8(u32 x, u32 y, u32 w)
{ {
return ((((y >> 2) * (w >> 2) + (x >> 2)) << 5) + ((y & 3) << 2) + (x & 3)) << 1; return ((((y >> 2) * (w >> 2) + (x >> 2)) << 5) + ((y & 3) << 2) + (x & 3)) << 1;
} }
static u8 * PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, int * dstWidth, int * dstHeight, int maxWidth, int maxHeight) static u8 * PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, u32 width, u32 height, int * dstWidth, int * dstHeight, u8 *dstPtr, int maxWidth, int maxHeight)
{ {
PNGU_u8 default_alpha = 255; u8 default_alpha = 255;
u8 *dst; u8 *dst;
int x, y, x2, y2, offset; int x, y, x2, y2, offset;
int xRatio = 0, yRatio = 0; int xRatio = 0, yRatio = 0;
@ -412,7 +411,10 @@ static u8 * PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height,
int len = (padWidth * padHeight) << 2; int len = (padWidth * padHeight) << 2;
if(len%32) len += (32-len%32); if(len%32) len += (32-len%32);
dst = memalign (32, len); if(dstPtr)
dst = dstPtr; // use existing allocation
else
dst = memalign (32, len);
if(!dst) if(!dst)
return NULL; return NULL;
@ -557,7 +559,7 @@ int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop)
return PNGU_OK; return PNGU_OK;
} }
PNGU_u8 * DecodePNG(const PNGU_u8 *src, int * width, int * height, int maxwidth, int maxheight) u8 * DecodePNG(const u8 *src, int * width, int * height, u8 *dstPtr, int maxwidth, int maxheight)
{ {
PNGUPROP imgProp; PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(src); IMGCTX ctx = PNGU_SelectImageFromBuffer(src);
@ -567,16 +569,16 @@ PNGU_u8 * DecodePNG(const PNGU_u8 *src, int * width, int * height, int maxwidth,
return NULL; return NULL;
if(PNGU_GetImageProperties(ctx, &imgProp) == PNGU_OK) if(PNGU_GetImageProperties(ctx, &imgProp) == PNGU_OK)
dst = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, width, height, maxwidth, maxheight); dst = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, width, height, dstPtr, maxwidth, maxheight);
PNGU_ReleaseImageContext (ctx); PNGU_ReleaseImageContext (ctx);
return dst; return dst;
} }
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_EncodeFromRGB (IMGCTX ctx, u32 width, u32 height, void *buffer, u32 stride)
{ {
png_uint_32 rowbytes; png_uint_32 rowbytes;
PNGU_u32 y; u32 y;
// Erase from the context any readed info // Erase from the context any readed info
pngu_free_info (ctx); pngu_free_info (ctx);
@ -633,10 +635,9 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
rowbytes = width * 3; rowbytes = width * 3;
if (rowbytes % 4) if (rowbytes % 4)
rowbytes = ((rowbytes >>2) + 1) <<2; // Add extra padding so each row starts in a 4 byte boundary rowbytes = ((rowbytes >>2) + 1) <<2; // Add extra padding so each row starts in a 4 byte boundary
ctx->img_data = malloc(rowbytes * height); ctx->img_data = malloc(rowbytes * height);
memset(ctx->img_data, 0, rowbytes * height);
if (!ctx->img_data) if (!ctx->img_data)
{ {
png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL); png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL);
@ -645,9 +646,9 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
return PNGU_LIB_ERROR; return PNGU_LIB_ERROR;
} }
memset(ctx->img_data, 0, rowbytes * height);
ctx->row_pointers = malloc (sizeof (png_bytep) * height); ctx->row_pointers = malloc (sizeof (png_bytep) * height);
memset(ctx->row_pointers, 0, sizeof (png_bytep) * height);
if (!ctx->row_pointers) if (!ctx->row_pointers)
{ {
png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL); png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL);
@ -656,6 +657,8 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
return PNGU_LIB_ERROR; return PNGU_LIB_ERROR;
} }
memset(ctx->row_pointers, 0, sizeof (png_bytep) * height);
for (y = 0; y < height; ++y) for (y = 0; y < height; ++y)
{ {
ctx->row_pointers[y] = buffer + (y * rowbytes); ctx->row_pointers[y] = buffer + (y * rowbytes);
@ -681,13 +684,17 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
return ctx->cursor; return ctx->cursor;
} }
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_EncodeFromGXTexture (IMGCTX ctx, u32 width, u32 height, void *buffer, u32 stride)
{ {
int res; int res;
PNGU_u32 x,y, tmpy1, tmpy2, tmpyWid, tmpxy; u32 x, y, tmpy1, tmpy2, tmpyWid, tmpxy;
unsigned char * ptr = (unsigned char*)buffer; unsigned char * ptr = (unsigned char*)buffer;
unsigned char * tmpbuffer = (unsigned char *)malloc(width*height*3); unsigned char * tmpbuffer = malloc(width*height*3);
if(!tmpbuffer)
return PNGU_LIB_ERROR;
memset(tmpbuffer, 0, width*height*3); memset(tmpbuffer, 0, width*height*3);
png_uint_32 offset; png_uint_32 offset;
@ -712,3 +719,33 @@ int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void
free(tmpbuffer); free(tmpbuffer);
return res; return res;
} }
int PNGU_EncodeFromEFB (IMGCTX ctx, u32 width, u32 height)
{
int res;
u32 x, y, tmpy1, tmpxy;
GXColor color;
unsigned char * tmpbuffer = malloc(width*height*3);
if(!tmpbuffer)
return PNGU_LIB_ERROR;
for(y=0; y < height; y++)
{
tmpy1 = y * width * 3;
for(x=0; x < width; x++)
{
tmpxy = x * 3 + tmpy1;
GX_PeekARGB(x, y, &color);
tmpbuffer[tmpxy ] = color.r; // R
tmpbuffer[tmpxy+1] = color.g; // G
tmpbuffer[tmpxy+2] = color.b; // B
}
}
res = PNGU_EncodeFromRGB (ctx, width, height, tmpbuffer, 0);
free(tmpbuffer);
return res;
}

View File

@ -10,32 +10,28 @@
#ifndef __PNGU__ #ifndef __PNGU__
#define __PNGU__ #define __PNGU__
#include <gccore.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
// Types
typedef unsigned char PNGU_u8;
typedef unsigned short PNGU_u16;
typedef unsigned int PNGU_u32;
typedef unsigned long long PNGU_u64;
typedef struct typedef struct
{ {
PNGU_u8 r; u8 r;
PNGU_u8 g; u8 g;
PNGU_u8 b; u8 b;
} PNGUCOLOR; } PNGUCOLOR;
typedef struct typedef struct
{ {
PNGU_u32 imgWidth; // In pixels u32 imgWidth; // In pixels
PNGU_u32 imgHeight; // In pixels u32 imgHeight; // In pixels
PNGU_u32 imgBitDepth; // In bitx u32 imgBitDepth; // In bitx
PNGU_u32 imgColorType; // PNGU_COLOR_TYPE_* u32 imgColorType; // PNGU_COLOR_TYPE_*
PNGU_u32 validBckgrnd; // Non zero if there is a background color u32 validBckgrnd; // Non zero if there is a background color
PNGUCOLOR bckgrnd; // Backgroun color PNGUCOLOR bckgrnd; // Background color
PNGU_u32 numTrans; // Number of transparent colors u32 numTrans; // Number of transparent colors
PNGUCOLOR *trans; // Transparent colors PNGUCOLOR *trans; // Transparent colors
} PNGUPROP; } PNGUPROP;
@ -47,10 +43,10 @@ typedef struct _IMGCTX *IMGCTX;
* Image context handling * * Image context handling *
****************************************************************************/ ****************************************************************************/
// Selects a PNG file, previosly loaded into a buffer, and creates an image context for subsequent procesing. // Selects a PNG file, previously loaded into a buffer, and creates an image context for subsequent processing.
IMGCTX PNGU_SelectImageFromBuffer (const void *buffer); IMGCTX PNGU_SelectImageFromBuffer (const void *buffer);
// Selects a PNG file, from any devoptab device, and creates an image context for subsequent procesing. // Selects a PNG file, from any devoptab device, and creates an image context for subsequent processing.
IMGCTX PNGU_SelectImageFromDevice (const char *filename); IMGCTX PNGU_SelectImageFromDevice (const char *filename);
// Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX. // Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX.
@ -67,9 +63,10 @@ int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties);
* Image conversion * * Image conversion *
****************************************************************************/ ****************************************************************************/
PNGU_u8 * DecodePNG(const PNGU_u8 *src, int *width, int *height, int maxwidth, int maxheight); u8 * DecodePNG(const u8 *src, int *width, int *height, u8 *dst, int maxwidth, int maxheight);
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride); int PNGU_EncodeFromRGB (IMGCTX ctx, u32 width, u32 height, void *buffer, u32 stride);
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride); int PNGU_EncodeFromGXTexture (IMGCTX ctx, u32 width, u32 height, void *buffer, u32 stride);
int PNGU_EncodeFromEFB (IMGCTX ctx, u32 width, u32 height);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -60,7 +60,6 @@ static Mtx view;
static Mtx GXmodelView2D; static Mtx GXmodelView2D;
static int vwidth, vheight, oldvwidth, oldvheight; static int vwidth, vheight, oldvwidth, oldvheight;
u8 * gameScreenTex = NULL; // a GX texture screen capture of the game
u8 * gameScreenPng = NULL; u8 * gameScreenPng = NULL;
int gameScreenPngSize = 0; int gameScreenPngSize = 0;
@ -571,8 +570,6 @@ InitGCVideo ()
xfb[0] = (u32 *) MEM_K0_TO_K1 (memalign(32, 640*574*2)); xfb[0] = (u32 *) MEM_K0_TO_K1 (memalign(32, 640*574*2));
xfb[1] = (u32 *) MEM_K0_TO_K1 (memalign(32, 640*574*2)); xfb[1] = (u32 *) MEM_K0_TO_K1 (memalign(32, 640*574*2));
gameScreenTex = (u8 *)memalign(32, 640*574*4);
GXRModeObj *rmode = FindVideoMode(); GXRModeObj *rmode = FindVideoMode();
SetupVideoMode(rmode); SetupVideoMode(rmode);
#ifdef HW_RVL #ifdef HW_RVL
@ -878,11 +875,15 @@ setGFX ()
***************************************************************************/ ***************************************************************************/
void TakeScreenshot() void TakeScreenshot()
{ {
GX_SetTexCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight); IMGCTX pngContext = PNGU_SelectImageFromBuffer(savebuffer);
GX_SetTexCopyDst(vmode->fbWidth, vmode->efbHeight, GX_TF_RGBA8, GX_FALSE);
GX_CopyTex(gameScreenTex, GX_FALSE); if (pngContext != NULL)
GX_PixModeSync(); {
DCFlushRange(gameScreenTex, vmode->fbWidth * vmode->efbHeight * 4); gameScreenPngSize = PNGU_EncodeFromEFB(pngContext, vmode->fbWidth, vmode->efbHeight);
PNGU_ReleaseImageContext(pngContext);
gameScreenPng = (u8 *)malloc(gameScreenPngSize);
memcpy(gameScreenPng, savebuffer, gameScreenPngSize);
}
} }
/**************************************************************************** /****************************************************************************

View File

@ -33,7 +33,6 @@ extern GXRModeObj *vmode;
extern int screenheight; extern int screenheight;
extern int screenwidth; extern int screenwidth;
extern bool progressive; extern bool progressive;
extern u8 * gameScreenTex;
extern u8 * gameScreenPng; extern u8 * gameScreenPng;
extern int gameScreenPngSize; extern int gameScreenPngSize;
extern u32 FrameTimer; extern u32 FrameTimer;