 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
AllSystemGo
Joined: 02 Jun 2007 Posts: 26
|
Posted: Mon Aug 27, 2007 11:51 pm Post subject: Memory leak |
|
|
Hi everyone,
I curently have a problem with memory leak I think. I created a new class that draws all the icons on screen, and for some reason as soon as I create a second icon the PSP goes into a loop the shutdown. If I only create one it paints on the screen perfectly. I'll post what I think is the relevant code.
Main.cpp
| Code: |
SDL_Surface *ecran = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
Button butCalendar(125, 80, 67, 80, "data/gfx/calendar.png", "Calendar", 15);
Button butSettings(218, 80, 67, 80, "data/gfx/tools.png", "Settings", 15);
while(isrunning)
{
butCalendar.Render(ecran);
butSettings.Render(ecran);
SDL_Flip(ecran);
}
|
Button.cpp
| Code: |
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psprtc.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include "Button.h"
using namespace std;
Button::Button(SDL_Rect bounds, const char *imagePath, const char *text, int fontSize) : Bounds(bounds), ImagePath(imagePath), Text(text), FontSize(fontSize)
{
}
Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
SDL_FreeSurface(TextSurface);
SDL_FreeSurface(ImageSurface);
if(FontObject == NULL)
FontObject = CreateFont();
if(TextSurface == NULL)
TextSurface = CreateText();
if(ImageSurface == NULL)
ImageSurface = CreateImage();
SDL_Rect temp = {x, y, width, height};
Bounds = temp;
}
Button::~Button()
{
if(FontObject != NULL)
TTF_CloseFont(FontObject);
if(TextSurface != NULL)
SDL_FreeSurface(TextSurface);
if(ImageSurface != NULL)
SDL_FreeSurface(ImageSurface);
}
void Button::Render(SDL_Surface* screen)
{
Render(screen, Bounds);
}
void Button::Render(SDL_Surface* screen, SDL_Rect bounds)
{
SDL_Rect imageRect;
imageRect.y = bounds.y;
imageRect.x = bounds.x + (bounds.w / 2 - ImageSurface->w / 2);
SDL_Rect textRect;
int textWidth;
int textHeight;
TTF_SizeText(FontObject, Text, &textWidth, &textHeight);
textRect.y = (bounds.y + bounds.h) - textHeight;
textRect.x = bounds.x + (bounds.w / 2 - textWidth / 2);
SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
SDL_BlitSurface(TextSurface, NULL, screen, &textRect);
}
bool Button::Contains(SDL_Rect point)
{
return point.x >= Bounds.x && point.x <= (Bounds.x + Bounds.w) &&
point.y >= Bounds.y && point.y <= (Bounds.y + Bounds.h);
}
TTF_Font* Button::CreateFont()
{
return TTF_OpenFont("data/font/Rippen.ttf", FontSize);
}
SDL_Surface* Button::CreateText()
{
SDL_Color white = {255, 255, 255};
return TTF_RenderText_Blended(FontObject, Text, white);
}
SDL_Surface* Button::CreateImage()
{
return SDL_DisplayFormatAlpha(IMG_Load(ImagePath));
}
|
Thank you for your help. If you need more code let me know!!!
Cheers! |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Tue Aug 28, 2007 4:12 am Post subject: |
|
|
| If you check some of the older threads, you'll find someone else had almost the same problem. You simple can't sit in a loop calling SDL_Flip() or the PSP goes out to lunch. You need something to delay things - a call to sceKernelDelayThread(), a check of the rtc time, a wait on the vbl... |
|
| Back to top |
|
 |
AllSystemGo
Joined: 02 Jun 2007 Posts: 26
|
Posted: Tue Aug 28, 2007 5:41 am Post subject: |
|
|
I do understand what you are saying J.F. but the thing is if I remove the Button butSettings(xxxxx); and the butSettings.Render(ecran);
Everything loads perfectly. That is my concern, why when I declare a second button the PSP stays black for 15 seconds then shutdown...
Thxs |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Tue Aug 28, 2007 6:51 am Post subject: |
|
|
| Okay. I don't see a TTF_Init() in there, and you might try checking if the CreateFont() (and other similar calls in Button) fail. Your code just assumes that all calls are working without error. Maybe the second Button created has one of them failing. |
|
| Back to top |
|
 |
danzel
Joined: 04 Nov 2005 Posts: 182
|
Posted: Tue Aug 28, 2007 11:41 am Post subject: |
|
|
| Code: |
Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
SDL_FreeSurface(TextSurface);
SDL_FreeSurface(ImageSurface);
if(FontObject == NULL)
FontObject = CreateFont();
if(TextSurface == NULL)
TextSurface = CreateText();
if(ImageSurface == NULL)
ImageSurface = CreateImage(); |
Why do you free these surfaces in the constructor, and then optionally recreate them?
They could be uninitialised variables (Hard to tell if they are from the code pasted), and SDL_FreeSurface()'ing them would be bad, possibly crashable. |
|
| Back to top |
|
 |
AllSystemGo
Joined: 02 Jun 2007 Posts: 26
|
Posted: Tue Aug 28, 2007 1:19 pm Post subject: |
|
|
Thank you for the replies. I will check into the TTF_Init missing, and for Danzel the FreeSurface wasn't there before and it still crashed, I'll remove that and try with the TTF_Init
Thank you again. |
|
| Back to top |
|
 |
AllSystemGo
Joined: 02 Jun 2007 Posts: 26
|
Posted: Wed Aug 29, 2007 1:58 am Post subject: |
|
|
Still the same problem. I'll repost my main.cpp and the class
main.cpp
| Code: |
/*
iPDA
June 18 2007
*/
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psppower.h>
#include <psprtc.h>
#include <png.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <list>
#include <iostream>
#include <fstream>
#include "alarm.h"
#include "alarmmanager.h"
#include "button.h"
using namespace std;
PSP_MODULE_INFO("iPDA", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
static bool isrunning = true;
static int curWindow = 1;
// Exit callback
int exit_callback(int arg1, int arg2, void *common) {
isrunning = false;
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;
}
int main() {
//Initialize the controler
SceCtrlData pad;
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
u64 CurTick;
u64 CmpTick;
char timeText[8];
sceRtcGetCurrentTick(&CmpTick);
//Initialize the PSP Time
pspTime time;
//Initialize the SDL Library (audio and video)
if(SDL_Init(SDL_INIT_VIDEO) < 0)
cout << stderr << "Couldn't initialize SDL: " << SDL_GetError() << endl;
//Initialize the SDL True Type Font Library
if(TTF_Init() < 0)
cout << stderr << "Couldn't initialize TTF: " << SDL_GetError() << endl;
//Initialize the font color.
SDL_Color white = {255, 255, 255};
SDL_Color black = {0, 0, 0};
//Initializing the images and text.
Button butCalendar(125, 80, 67, 80, "data/gfx/calendar.png", "Calendar", 15);
Button butSettings(218, 80, 67, 80, "data/gfx/tools.png", "Settings", 15);
//Initialize the mouse.
SDL_Rect mouse = {239, 134};
//Initialize the Joystick.
SDL_Rect posJoy;
posJoy.x = pad.Lx-128;
posJoy.y = pad.Ly-128;
SDL_Surface *ecran = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_Surface *textTime = NULL;
//Initialize the callbacks
pspDebugScreenInit();
SetupCallbacks();
//Start the loop
while(isrunning)
{
sceCtrlReadBufferPositive(&pad, 1); //Read the joystick
sceRtcGetCurrentClockLocalTime(&time); //Get the current time
//Move the mouse on screen
if((pad.Lx < 35) && (mouse.x > 0))
{
mouse.x = mouse.x-3;
}
else if((pad.Lx > 200) && (mouse.x < 480))
{
mouse.x = mouse.x+3;
}
if((pad.Ly < 35) && (mouse.y > 0))
{
mouse.y = mouse.y-3;
}
else if((pad.Ly > 200) && (mouse.y < 480))
{
mouse.y = mouse.y+3;
}
// Don't let the mouse go off screen
if(mouse.x >= 470)(mouse.x = 470);
if(mouse.y >= 265)(mouse.y = 265);
sceRtcGetCurrentTick(&CurTick);
//Verify that a second passed before blitting the new clock. This was done to correct the problem were the clock disapear for blitting to many times.
if (sceRtcCompareTick(&CurTick, &CmpTick) >= 0)
{
SDL_FreeSurface(textTime);
snprintf(timeText, 8, "%02i : %02i", time.hour, time.minutes);
textTime = TTF_RenderText_Shaded(timeFont, timeText, white, black);
sceRtcGetTick(&time, &CmpTick);
sceRtcTickAddMinutes(&CmpTick, &CmpTick, 1);
SDL_BlitSurface(textTime, NULL, ecran, &txttime_position);
}
if (curWindow == 1)
{
if (pad.Buttons & PSP_CTRL_CROSS)
{
if ((mouse.x > calculator_position.x) && (mouse.x < (calculator_position.x + 64)) &&
(mouse.y > calculator_position.y) && (mouse.y < (calculator_position.y + 64)))
{
curWindow = 2;
}
}
butCalendar.Render(ecran);
butSettings.Render(ecran);
}
SDL_BlitSurface(mousePointer, NULL, ecran, &mouse);
SDL_Flip(ecran);
}
//Free the memory.
SDL_FreeSurface(mousePointer);
TTF_Quit();
SDL_Quit();
sceKernelSleepThread();
return 0;
}
|
button.cpp
| Code: |
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psprtc.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <iostream>
#include <fstream>
#include "button.h"
using namespace std;
Button::Button(SDL_Rect bounds, const char *imagePath, const char *text, int fontSize) : Bounds(bounds), ImagePath(imagePath), Text(text), FontSize(fontSize)
{
}
Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
FontObject = CreateFont();
TextSurface = CreateText();
ImageSurface = CreateImage();
SDL_Rect temp = {x, y, width, height};
Bounds = temp;
}
Button::~Button()
{
if(FontObject != NULL)
TTF_CloseFont(FontObject);
if(TextSurface != NULL)
SDL_FreeSurface(TextSurface);
if(ImageSurface != NULL)
SDL_FreeSurface(ImageSurface);
}
void Button::Render(SDL_Surface* screen)
{
Render(screen, Bounds);
}
void Button::Render(SDL_Surface* screen, SDL_Rect bounds)
{
SDL_Rect imageRect;
imageRect.y = bounds.y;
imageRect.x = bounds.x + (bounds.w / 2 - ImageSurface->w / 2);
SDL_Rect textRect;
int textWidth;
int textHeight;
TTF_SizeText(FontObject, Text, &textWidth, &textHeight);
textRect.y = (bounds.y + bounds.h) - textHeight;
textRect.x = bounds.x + (bounds.w / 2 - textWidth / 2);
SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
SDL_BlitSurface(TextSurface, NULL, screen, &textRect);
}
bool Button::Contains(SDL_Rect point)
{
return point.x >= Bounds.x && point.x <= (Bounds.x + Bounds.w) &&
point.y >= Bounds.y && point.y <= (Bounds.y + Bounds.h);
}
TTF_Font* Button::CreateFont()
{
return TTF_OpenFont("data/font/Rippen.ttf", FontSize);
}
SDL_Surface* Button::CreateText()
{
SDL_Color white = {255, 255, 255};
if(FontObject == NULL)
CreateFont();
return TTF_RenderText_Blended(FontObject, Text, white);
}
SDL_Surface* Button::CreateImage()
{
return SDL_DisplayFormatAlpha(IMG_Load(ImagePath));
}
|
I still get the same problem. If I remove the Button butSettings everything loads up perfectly but as soon as I add the second button then the PSP stay black for about 10 seconds then shutdown.
Thanks for your help.
Cheers. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Wed Aug 29, 2007 6:04 am Post subject: |
|
|
You're still not checking if your surfaces are created. Try adding a check in the Render function.
| Code: | if (ImageSurface != NULL)
SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
if (TextSurface != NULL)
SDL_BlitSurface(TextSurface, NULL, screen, &textRect);
|
If that works, then you know that one of the surfaces fails to be created the second time a button is created. Your program has very little error checking - it's something you need to worry about, at least until you get the bugs worked out. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|