Page 5 of 9

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 1:05 am
by Artcfox
uze6666 wrote:Do you have array manipulation or pointer code that could overflow? Array out of bound could be a possibility for the garbage you saw. Since we are pretty much in the dark with this method of investigation, I implemented a controller capture mode in uzem. This allow to debug on uzem with GDB. Are you on Windows? If so:
To capture input:

Code: Select all

uzem -c YOURGAME.HEX
This will write to a file named yourgame.cap. Try replicate the sustained note issue and send me both your .hex and .cap files.

To replay a capture file:

Code: Select all

uzem -l YOURGAME.HEX
. The capture file with the same name (yourgame.cap) must be in the same folder.

Attached is uzem 1.31. an me playing ghosty ghost.

Code: Select all

uzem -l GGHOST.HEX
That is awesome, though I'm not on Windows, but if the code is on Github I will do a git pull and recompile uzem to get the newest changes and then I'll record a bunch of input captures.

Further investigation shows that even with no calls to TriggerFx, or InitMusicPlayer, the patchCurrDeltaTime variables are still incremented. Does that mean that the code that plays sounds is running regardless of using it or not? I tried getting rid of all my sound code to see if the glitches still happen, but it doesn't appear that I can stop the sound code from running. Sometimes I get weird graphical glitches, like the player 1 and 2 sprite drawing all over the place, but the stack looks good, and the actual x and y variables for player 1 and player 2 are correct. It's almost as if it's drawing sprites that aren't defined. If I make it so only a single player is defined, then I can't seem to reproduce the graphical glitches. The exact same code is running for both players, the only difference is I'm more likely to go over on cycles when I'm doing physics and collision detection on two players versus one.

I've looked and looked for any place where I could be writing out of bounds, but most of my loops have constant terminations, and I'm not doing anything too clever.

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 2:58 am
by uze6666
That is awesome, though I'm not on Windows, but if the code is on Github I will do a git pull and recompile uzem to get the newest changes and then I'll record a bunch of input captures.
Just pushed it on Github. :)

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 3:48 am
by Artcfox
uze6666 wrote:
That is awesome, though I'm not on Windows, but if the code is on Github I will do a git pull and recompile uzem to get the newest changes and then I'll record a bunch of input captures.
Just pushed it on Github. :)
I recompiled everything, and grabbed a capture where the note stuck, but when I played it back, it does not match what I pressed. I do miss vsync sometimes, especially in the beginning while loading the level, and it looks like it's getting out of sync in the very beginning.

The first thing I do is run left, then jump, but when I play it back the first thing it does is jump to the left and fall down the hole I jumped over.

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 5:14 am
by uze6666
I recompiled everything, and grabbed a capture where the note stuck, but when I played it back, it does not match what I pressed. I do miss vsync sometimes, especially in the beginning while loading the level, and it looks like it's getting out of sync in the very beginning.

The first thing I do is run left, then jump, but when I play it back the first thing it does is jump to the left and fall down the hole I jumped over.
The feature is in beta state so there's no doubt a few bugs. Though I find this puzzling since I output the button state to file exactly once each frame during vsync. And it's read back at the same spot. Can you PM me you latest HEX I will see what is going on.

edit: There's bugs. I had only tested with ghosty ghost and it clearly doesn't work well with other roms like my CastleVania demo.

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 6:07 am
by uze6666
It's fixed and I tested it with a build you gave me. A really stupid bug :oops: . Commited in git as uzem 1.3.2.

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 5:47 pm
by Artcfox
So I decided to take a different approach. No pad bytes, went back to the non-inline mixer, but disabled all sound effects except the jump sound, which ensures that only a single sound can ever play at once. I got rid of the pad bytes, and enabled both players, and I've yet to get a note to stick, or have any funny behavior at all. Let me know if you want me to use this build to make a capture and send it to you as well.

Edit: As usual, I can play test it for 30 mins, everything will be fine, and then as soon as I make a statement, it proves me wrong. If I keep reloading the level, eventually I'll see the number of free bytes decrease, and that's when I'll get graphical glitches.

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 6:28 pm
by Artcfox
Could it be the LDFLAGS?

I just changed mine from:

Code: Select all

LDFLAGS += -Wl,--section-start,.noinit=0x800100 -Wl,--section-start,.data=0x800300
to:

Code: Select all

LDFLAGS += -Wl,--section-start,.noinit=0x800100
since I'm not using scrolling, and it freed up a huge amount of RAM, enough that I am able to use 32 RAM tiles, and I still have 509 bytes of stack left unused! As long as there are no adverse effects, this is like a dream come true, because now I should be able to use even more sprites!

Re: TriggerFx sometimes gets stuck on a note

Posted: Sun Aug 02, 2015 9:06 pm
by uze6666
Wait a sec...those are flags using when using scrolling only! And they must be set very carefully depending on the ram used by ramtiles or you risk memory corruption.

If your Makefile does not contain -DSCROLLING=1 you must remove those althogether:

Code: Select all

LDFLAGS += -Wl,--section-start,.noinit=0x800100 -Wl,--section-start,.data=0x800300
So your linker flags should only be:

Code: Select all

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=$(GAME).map 
LDFLAGS += -Wl,-gc-sections 
With that removed, do you still have sound issues? If so, can you PM me your whole project, that will be simpler for me to debug.

Re: TriggerFx sometimes gets stuck on a note

Posted: Mon Aug 03, 2015 1:46 am
by Artcfox
uze6666 wrote:Wait a sec...those are flags using when using scrolling only! And they must be set very carefully depending on the ram used by ramtiles or you risk memory corruption.

If your Makefile does not contain -DSCROLLING=1 you must remove those althogether:

Code: Select all

LDFLAGS += -Wl,--section-start,.noinit=0x800100 -Wl,--section-start,.data=0x800300
So your linker flags should only be:

Code: Select all

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=$(GAME).map 
LDFLAGS += -Wl,-gc-sections 
With that removed, do you still have sound issues? If so, can you PM me your whole project, that will be simpler for me to debug.
Yes, unfortunately the sound issue remains, however the random memory corruption is gone, and I have way more RAM available, and my program takes up way less space! :D

I modeled my Makefile after the tutorials on the wiki, and I guess I didn't see that those settings were meant for scrolling only. :oops:

The weird thing is if I uncomment out the calls to DisplayNumber() calls for tracks[1].patchCommandStreamPos, tracks[1].patchCurrDeltaTime, tracks[2].patchCommandStreamPos, tracks[2].patchCurrDeltaTime, then I can't reproduce the sound issue at all, which suggests that it is definitely something timing related, perhaps only when I'm in a certain part of the code and miss vsync?

PM sent.

Edit: The same .cap file can be played back with the aforementioned DisplayNumber() calls uncommented or commented, which is rather nice.

Edit 2: I tried getting rid of all the debugging statements, and the black bar at the top, and now I'm getting some memory issues after the sound glitches. Sigh...

Re: TriggerFx sometimes gets stuck on a note

Posted: Mon Aug 03, 2015 7:44 pm
by Artcfox
I'm just going to leave this here…

Code: Select all

diff --git a/kernel/uzeboxSoundEngine.c b/kernel/uzeboxSoundEngine.c
index 380c723..9431b84 100644
--- a/kernel/uzeboxSoundEngine.c
+++ b/kernel/uzeboxSoundEngine.c
@@ -778,7 +778,7 @@ void ProcessMusic(void){
                                track->patchCurrDeltaTime>=track->patchNextDeltaTime){
 
                                //process all simultaneous events
-                               while(track->patchCurrDeltaTime==track->patchNextDeltaTime){
+                               while(track->patchCurrDeltaTime>=track->patchNextDeltaTime){

                                        c1=pgm_read_byte(track->patchCommandStreamPos++);
                                        if(c1==0xff){
In my limited test of making one capture that triggers a sustained note, playing it back to verify that the note is indeed sustained in the replay, and then making the above modification to the sound engine, re-compiling, and then playing back the capture file, it seems like TriggerFx() works properly—the note was no longer sustained! :D

I do think that this "defensive programming" fix may be masking another bug though. When it is left as a strict equality check, something seems to be causing that check to be skipped.

Also, in the following block of code:

Code: Select all

		//process patch command stream
		if((track->flags & TRACK_FLAGS_HOLD_ENV)==0){	//patchEnvelopeHold==false

			if(track->patchCommandStreamPos!=NULL && 
				track->patchCurrDeltaTime>=track->patchNextDeltaTime){			

				//process all simultaneous events
				while(track->patchCurrDeltaTime>=track->patchNextDeltaTime){	
					
					c1=pgm_read_byte(track->patchCommandStreamPos++);
					if(c1==0xff){					
						//end of stream!
						track->flags&=(~TRACK_FLAGS_PRIORITY);// priority=0;
						track->patchCommandStreamPos=NULL;
						break;

					}else{
						c2=pgm_read_byte(track->patchCommandStreamPos++);
						//invoke patch command function
						( (PatchCommand)pgm_read_word(&patchCommands[c1]) )(track,trackNo,c2);				
					}			
			
					//read next delta time
					track->patchNextDeltaTime=pgm_read_byte(track->patchCommandStreamPos++);						
					
					track->patchCurrDeltaTime=0;	

				}		
			}				
			
			track->patchCurrDeltaTime++;
		}
the

Code: Select all

 && track->patchCurrDeltaTime>=track->patchNextDeltaTime)
part of the if condition can be removed, since now the while loop automatically checks that part of the condition.