mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-27 13:04:21 +01:00
somewhat improved memory management. hopefully GameCube memory issues are gone now :)
This commit is contained in:
parent
7b9772cec9
commit
f3aa820d4d
@ -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 };
|
||||||
|
@ -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[];
|
||||||
|
@ -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
43
source/mem2.cpp
Normal 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
22
source/mem2.h
Normal 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
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user