so, I am basically making a game based loosely around break-out, and im having some weird problems...
when you hit the block that releases an extra ball, sometimes (like when maybe 4 or more are on the screen, but its not a set number) the game will completely lag to death. that is to say, it will go from refreshing every 1/30th of a sec to not refreshing for about 6 seconds. I have no idea why this is happening, and to my knowledge is not in any way a glitch in my code (espiecially due to the variance of its occurence).
Also, possibly related, this is my crappy method of screen refreshing (since I dont know how to use things like vblankwait and sceflipbuffers (or whatever it is)):
i looked at a simple program which all it did was swap the x and o button functionality, and its source, to see how the simple text graphics were done.
This program showed me that writing to a specific memory address will put pixels on the screen.
To get a double buffer effect, what i did was declare a portion of memory equal to an extra screen, and I write to this. When I call my Update function, this memory is copied over byte for byte to the screen memory.
Now obviously this is inefficient, but except for that problem above, I can still hold 30 fps. And with that glitch, its isnt like 4 balls will start to lag, 5 will be a bit worse, and 6 will practically stop the game... its like 3 will run at 30 fps, 4 will slow it to about 1 frame per 6 secs.
Any opinions? possibly memory management problems (I know the space is limited for memory), or maybe because balls use almost all floating-point calcs, whereas everything else in the game is ints?
I have no idea really, and if I can't fix it, I'll just fudge my way around it by never having too many balls onscreen at once...
Thanks anyone who has an idea!
Strange game glitch, need opinions
Strange game glitch, need opinions
http://omegagames.netfirms.com -- Support struggling programmers by suffering through their crappy games! (Ok, you don't have to...)
-
- Posts: 197
- Joined: Fri Jul 01, 2005 2:50 am
The vblankwait function you describe may be the problem. Basically, this is a pause which waits until the screen is refreshed, up to 1/60th of a second. Call this once per loop, and you get a max of 60fps, call it twice, you get a max of 30fps. Look in your ball rendering code and see if you're calling this function, remove as many of these function calls as possible.
The same rule applies to controls, with respect to ReadBufferPositive is blocking, and PeekBufferPositive is non-blocking.
Failing that, post some of the relevant source, sounds like the problem will either be in the ball management code, or the code called when a ball is created/released.
The same rule applies to controls, with respect to ReadBufferPositive is blocking, and PeekBufferPositive is non-blocking.
Failing that, post some of the relevant source, sounds like the problem will either be in the ball management code, or the code called when a ball is created/released.
Well, I actually never use the vblankwait function at all... I only said that I didn't know how to do that. As for the readbuffer, thats only once per loop, but here's the main loop code... sorry if most of it is unreadable:
Code: Select all
int StartBreakInRound(RoundData * rdat,float idel,int MC(RoundData*),RoundResults * res)
{
SceCtrlData pad;
Blockrow * rows = rdat->rows;
int totalblocks = 0;
int i;
for(i=0;i<rdat->row_cnt;i++)
totalblocks += rows[i].rowsz << 2;
res->total_blocks = totalblocks;
u64 time_st, time_end;
float inp_time = 0;
u64 total_time_tks = 0;
RoundData rdata;
if(rdat)
rdata = *rdat;
else
return -3;
rdata.timepassed = 0;
int ss = 0; //set to 1 to take a screenshot
static int screens = 0;
char buf[60];
int brdrot = 0;
while(1)
{
sceRtcGetCurrentTick(&time_st);
brdrot = 0;
if(inp_time >= idel)
{
sceCtrlReadBufferPositive(&pad, 1);
if(pad.Buttons & PSP_CTRL_LEFT)
{
brdrot = 1;
for(i=0;i<rdata.row_cnt;i++)
RotateCW(&rows[i]);
}
else if(pad.Buttons & PSP_CTRL_RIGHT)
{
brdrot = 2;
for(i=0;i<rdata.row_cnt;i++)
RotateCCW(&rows[i]);
}
else if(pad.Buttons & PSP_CTRL_START)
{
int pause_result = PauseScreen();
if(pause_result == 1)
{
return -1;
}
else if(pause_result == 2)
{
ss = 1;
}
}
inp_time = 0.0f;
}
ClearScreen(0);
//TrackMemory();
for(i=0;i<rdata.row_cnt;i++)
RenderBlockrow(rows+i);
inp_time += 1.0f / MY_FPS;
int MCRes = 0;
if((MCRes = MC(&rdata)) > 0)
{
res->cleared_blocks = totalblocks - RemainingBlocksAll(rdata.rows,rdata.row_cnt);
res->time = total_time_tks;
res->score = 0;
res->success = 1;
return 0;
}
else if(MCRes < 0)
{
res->cleared_blocks = totalblocks - RemainingBlocksAll(rdata.rows,rdata.row_cnt);
res->time = total_time_tks;
res->score = 0;
res->success = 0;
return 0;
}
Ball * ballptr = rdata.balls;
Ball * btmp;
int bc = rdata.ball_cnt;
for(i=0;i<bc;i++)
{
if(!ballptr) break;
if(brdrot)
MikesFunction(&rdata,ballptr,brdrot-1);
FillBall((int)ballptr->loc.x-HALFBS,(int)ballptr->loc.y-HALFBS,&White);
ballptr->speed += ballptr->speedinc / (float)MY_FPS;
ballptr->spinrad = ballptr->spinrad + (ballptr->spinrad * ballptr->spinrecov) / MY_FPS; //MAKE ME EXPONENTIAL!
if(ballptr->spinrad > 10000.0f)
{
ballptr->spinrad = 10000.0f;
ballptr->spindir = 0;
}
btmp = (Ball*)(ballptr->next);
if(!MoveBallCC(&rdata,ballptr))
{
FreeBall(&(rdata.balls),i);
rdata.ball_cnt--;
bc--;
i--;
if(rdata.ball_cnt < 1)
{
res->cleared_blocks = totalblocks - RemainingBlocksAll(rdata.rows,rdata.row_cnt);
res->time = total_time_tks;
res->score = 0;
res->success = 0;
return 0;
}
}
ballptr = btmp;
}
DrawStats(&rdata);
CopyBuf();
if(ss)
{
sprintf(buf,"screen%d.raw",screens++);
TakeScreenshot(buf);
ss = 0;
}
do{
sceRtcGetCurrentTick(&time_end);
}while(time_end - time_st < (sceRtcGetTickResolution()/MY_FPS));
total_time_tks += time_end - time_st;
rdata.timepassed = total_time_tks;
}
}
http://omegagames.netfirms.com -- Support struggling programmers by suffering through their crappy games! (Ok, you don't have to...)
i think i may have found it...
Actually, I was calling ReadBufferPositive at a very random time, and it just happened to be in a point where it could have been called up to 100 times each loop... NOT GOOD. Switched to PeekBufferPositive, and... its a tiny bit faster... but a good start. Thankz!
Actually, I was calling ReadBufferPositive at a very random time, and it just happened to be in a point where it could have been called up to 100 times each loop... NOT GOOD. Switched to PeekBufferPositive, and... its a tiny bit faster... but a good start. Thankz!
http://omegagames.netfirms.com -- Support struggling programmers by suffering through their crappy games! (Ok, you don't have to...)