Beta Zelda ... Kind Of


sebt3 said:
But for now, I just want to track down that nasty bug that drive the game to segfault if the sound card isn't available (let's say I want to listen Metallica while playing :p ). But I'm not surprised as the code don't handle this :p
I was damn wrong here : code looks clean :(

sebt3 said:
And I want to have good control not there yet (thanks God Ginrai for the reference).
Are they better now ? [Download]

Shin-NiL said:
@sebt3 Sure, we can share our work :)
Thanks a lot :)


EDIT: I just tried freepats and it still freeze. so no music tht way :(
BTW : While the game is frozen, the pandora isn't at all : 90% cpu free and 75M memory free. not sure the leaks are the cause of the freeze. (still sane to close them :p)
 
Last edited by a moderator:
I'm also still poking around the source and trying different library versions to find the cause of the lockups. Here are some notes:

  • On PC using Ubuntu 10.04, it hangs after the opening screen when using the default timidy patches from Ubuntu (deadlock in SDL_LockAudio). It works though when you use the custom timidity.cfg and smallpats patches.
  • The main problem that I am experiencing on the Wiz is not so much crashing, but rather freezes with only short "bursts" of response from the program.
  • This behaviour usually starts after playing for a while (>30 minutes)
  • This behaviour usually starts just after walking into a new zone (which one does not seem to matter)
  • This behaviour seems to be more frequent in OLB than in ROTH
  • On PC I could not reproduce this so far.
  • On the Wiz I'm having a hard time debugging this, because the back traces are broken (corrupt stack).

Btw, the problem with cleaning up the code in order to fix the controls, memory leaks etc. is that there would be a LOT to clean up :)
 
hmn said:
Btw, the problem with cleaning up the code in order to fix the controls, memory leaks etc. is that there would be a LOT to clean up :)
I know :( that's why I though about sharing the work.
 
Last edited by a moderator:
hmn said:
  • The main problem that I am experiencing on the Wiz is not so much crashing, but rather freezes with only short "bursts" of response from the program.
  • This behaviour usually starts just after walking into a new zone (which one does not seem to matter)
  • This behaviour seems to be more frequent in OLB than in ROTH
  • On PC I could not reproduce this so far.
In these respects my problems are identical to yours. The only difference is that I'm just working on zelda ROTH.

hmn said:
  • This behaviour usually starts after playing for a while (>30 minutes)
After I removed the sound, I played for exactly 30 minutes before the freezing, with the sound turned on takes around 3-7.


Here's my top at the freezing time (playing with music):


Note that the status of process 170 is "D" (uninterruptible sleep), maybe it's waiting an I/O operation :blink:
 
Last edited by a moderator:
Shin-NiL said:
Note that the status of process 170 is "D" (uninterruptible sleep), maybe it's waiting an I/O operation :blink:

Yes, I think this my be blocking on a mutex (deadlock)...
 
Last edited by a moderator:
Here is top while Zelda is frozen on pandora :
Code:
top - 11:10:51 up 15:23,  3 users,  load average: 0.45, 0.76, 0.57
Tasks:  95 total,   1 running,  94 sleeping,   0 stopped,   0 zombie
Cpu(s): 12.0%us,  8.8%sy,  0.0%ni, 78.2%id,  0.0%wa,  1.0%hi,  0.0%si,  0.0%st
Mem:    248908k total,   191000k used,    57908k free,    10352k buffers
Swap:        0k total,        0k used,        0k free,    87820k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                  
 4034 seb       20   0 35124  21m 3756 S 11.7  8.7   0:17.15 Zelda3T_US

and here is the end of the strace output :
Code:
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
write(4, "\212\3\n\0\20\0\340\2\21\0\340\2\200\2\340\1\0\0\0\0\200"..., 44) = 44
read(4, "\1\1`\2\0\0\0\0\2\0\340\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32) = 32
gettimeofday({1281179384, 383972}, NULL) = 0
gettimeofday({1281179384, 384246}, NULL) = 0
gettimeofday({1281179384, 384521}, NULL) = 0
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
write(4, "\212\3\n\0\20\0\340\2\21\0\340\2\200\2\340\1\0\0\0\0\200"..., 44) = 44
read(4, "\1\1b\2\0\0\0\0\2\0\340\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32) = 32
gettimeofday({1281179384, 404052}, NULL) = 0
gettimeofday({1281179384, 409820}, NULL) = 0
nanosleep({4294967, 291000000}, 0xbefee720) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCONT (Continued) @ 0 (0) ---
restart_syscall(<... resuming interrupted call ...> <unfinished ...>
+++ killed by SIGKILL +++
Process 4034 detached
Edit : Might worth reading : http://sourceware.org/bugzilla/show_bug.cgi?id=10267
 
@sebt3: Can you get a backtrace of that? I have a hard time debugging this on the Wiz, as I see no symbols for any system libs... maybe Pandora has proper dbg support packages?
 
hmn said:
@sebt3: Can you get a backtrace of that? I have a hard time debugging this on the Wiz, as I see no symbols for any system libs... maybe Pandora has proper dbg support packages?
First gdb experience ever :)
For now :
Code:
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
^C
Program received signal SIGINT, Interrupt.
0x401494a4 in nanosleep () from /lib/libpthread.so.0
(gdb) bt
#0  0x401494a4 in nanosleep () from /lib/libpthread.so.0
#1  0x40148270 in ?? () from /lib/libpthread.so.0
Cannot access memory at address 0x0
#2  0x40148270 in ?? () from /lib/libpthread.so.0
Cannot access memory at address 0x0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)


There is no debug symbol available for angstrom, so I'm stuck here :(
 
Last edited by a moderator:
You already have more symbols than I see on the Wiz :) unfortunately, the trace is also broken...

BTW: try "thread apply all bt" to see the other threads as well.
 
Code:
(gdb) run
Starting program: /mnt/utmp/Zelda3T_US/Zelda3T_US 
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
...
(gdb) thread apply all bt

Thread 1 (LWP 4598):
#0  0x401494a4 in nanosleep () from /lib/libpthread.so.0
#1  0x40148270 in ?? () from /lib/libpthread.so.0
Cannot access memory at address 0x0
#2  0x40148270 in ?? () from /lib/libpthread.so.0
Cannot access memory at address 0x0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Nothing more :(
 
I think i have found a lockup (in main.cpp):
Code:
if (SDL_GetTicks() < lastAnimTime + 20) SDL_Delay(lastAnimTime+20-SDL_GetTicks());

This can produce an integer overflow:
  • Assume that lastAnimTime = 0
  • Assume that the first call to SDL_GetTicks returns 11, which triggers the SDL_Delay part (11 < 0 + 20)
  • Thread gets preempted for 10ms
  • SDL_GetTicks gets called again, now returns 21
  • SDL_Delay gets called with ( 0 + 20 - 21 ) = -1
  • This is cast to an Uint32: 4294967295
  • SDL_Delay waits for ~50 days :) (BTW: this is the nanosleep you see in the backtrace...)

So the code should be replaced with something like this:
Code:
Uint32 currentTime = SDL_GetTicks();                                                           |
if (currentTime < lastAnimTime + 20) SDL_Delay(lastAnimTime+20-currentTime);
 
Ok boys,

I didn't find why this lockup this way, but I think I have found a work around : quit using midi :p
Music are now in a tracker format.
The good news is that it now sound worderfully great.
The bad news is that the PND is now 25M
The ugly news is the impact on performance : I would recommand playing at 700Mz (it too slow below that).

Because it sounded that good, I changed to scaler to better fit : h2q :)

The control should be good now too.


PND : http://sebastien.huss.free.fr/pnd/Zelda3T_US.pnd
Patch : http://sebastien.huss.free.fr/pnd/Zelda3T_US-pandora.patch.gz
 
hmn said:
I think i have found a lockup (in main.cpp):
Code:
if (SDL_GetTicks() < lastAnimTime + 20) SDL_Delay(lastAnimTime+20-SDL_GetTicks());

This can produce an integer overflow:
  • Assume that lastAnimTime = 0
  • Assume that the first call to SDL_GetTicks returns 11, which triggers the SDL_Delay part (11 < 0 + 20)
  • Thread gets preempted for 10ms
  • SDL_GetTicks gets called again, now returns 21
  • SDL_Delay gets called with ( 0 + 20 - 21 ) = -1
  • This is cast to an Uint32: 4294967295
  • SDL_Delay waits for ~50 days :) (BTW: this is the nanosleep you see in the backtrace...)

So the code should be replaced with something like this:
Code:
Uint32 currentTime = SDL_GetTicks();                                                           |
if (currentTime < lastAnimTime + 20) SDL_Delay(lastAnimTime+20-currentTime);

Thank you very much hmn! I think you've found the solution to the problem of freezing, this explains why the music still playing. I made the changes you suggested and for the first time I could play more than 30 minutes without freezing.

But now I could see another problem, after I loaded the game for more than three times the entire system crashed, a clear sign of memory leak. I looked at the code and just finding its cause in file jeu.cpp, following is a possible fix.

Code:
void Jeu::init(int save) {

    zone=21;

    // clean all previous references - added by Shin-NiL
    if (gpProjectile) delete gpProjectile;
    if (gpObjet) delete gpObjet;
    if (gpSnipe) delete gpSnipe;
    if (gpCaisse) delete gpCaisse;
    if (gpEnnemi) delete gpEnnemi;
    if (gpPiege) delete gpPiege;
    if (gpPnj) delete gpPnj;
    if (gpJoueur) delete gpJoueur;
    if (gpMonde) delete gpMonde;
    if (gpMenu) delete gpMenu;
    if (gpStatut) delete gpStatut;
    //END

    gpProjectile = new Projectile(this, 0, N, 0, 0, 0);
    gpObjet = new Objet(this, 0, 0, 0, 0);
    gpSnipe = new Snipe(this, 0, 0, 0, 0, 0);
    gpCaisse = new Caisse(this, 0, 0, 0);
    gpEnnemi = new Ennemi(this, 0, 0, 0, true);
    gpPiege = new Ennemi(this, 0, 0, 0, true);
    gpPnj = new Pnj(this, 0, 0, 0, 0);
    gpJoueur = new Joueur(this, save);
    gpMonde = new Monde(this);
    gpMenu = new Menu(this);
    //gpTexte = new Texte(this);
    gpStatut = new Statut(this);
    gpAudio->playMusic(zone);
    if (isDonjon()) ecrit(206+zone-12);

}

After those two changes I had no more problems with freezing or crashing, at least until now.

Thank you again guys!
 
Last edited by a moderator:
@Shin-NiL: I made the same change in Jeu::init, but forgot to mention it over the other, more important bugfix :) There even is a method for this called "videListes()":

Code:
    //gpProjectile = new Projectile(this, 0, N, 0, 0, 0);                       
    //gpObjet = new Objet(this, 0, 0, 0, 0);                                    
    //gpSnipe = new Snipe(this, 0, 0, 0, 0, 0);                                 
    //gpCaisse = new Caisse(this, 0, 0, 0);                                     
    //gpEnnemi = new Ennemi(this, 0, 0, 0, true);                               
    //gpPiege = new Ennemi(this, 0, 0, 0, true);                                
    //gpPnj = new Pnj(this, 0, 0, 0, 0);                                        
    videListes();

There still are some more leaks left though (at least in OLB)...
 
So I guess fixing it up and going back to midi music makes more sense here (it runs faster :))
 
EvilDragon said:
So I guess fixing it up and going back to midi music makes more sense here (it runs faster :) )
No :(
I did try every fix hmn & Shin-NiL proposed. And with midi the games was still freezing.
I guess we have several issue with this code and a problem with timidity :

Hooka said:
This is just a small shot in the dark, but could timidity be to blame, I've noticed pickles is having some weird crashes associated with some of his ports that use it also... maybe if somebody has the old timidity-less version to give a test with, might prove useful ;)

But I'm sure of nothing
 
Last edited by a moderator:
Well, instead of tracker, you could also use OGG. Should need less CPU speed.
Shall I convert them properly?
 
EvilDragon said:
Well, instead of tracker, you could also use OGG. Should need less CPU speed.
Shall I convert them properly?
If you want, modifing the source code will be easy.

But if the tracker version are phat, the ogg will probably be even bigger.
Well if that make the game enjoyable, why not :)
 
Last edited by a moderator:
EvilDragon said:
Well, instead of tracker, you could also use OGG. Should need less CPU speed.
Shall I convert them properly?

Why do that? It's a minimal overclock, and IT isn't bad.

-God Ginrai
 
Last edited by a moderator:
One thing to consider regarding overclock is that some was already necessary. In most places it was fine, but in the forest of Time to Triumph for instance, the fog really slowed things down without overclocking.
 
Back
Top