TriggerFx sometimes gets stuck on a note

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by Artcfox »

So I DEFINITELY was running into a cycle issue. :oops:

When I took out all of the non-essential collision checking (treasures) everything sped up by 2x. As long as I only enable 1 player, the only glitch so far is the same TriggerFx thing. When I enable the second player, then I sometimes get a screen full of garbage that changes until the emulator either locks up, or until it restarts the game. Changing the algorithm for collision checking seems to have fixed my cycle issue, though maybe not under all code paths.

The full screen graphic glitches seem to be a memory issue, so I figured the easiest way to free up more RAM is to decrease the number of RAM tiles I'm using, but that doesn't seem to help. From the tutorials, I gather that if I enable 8 sprites, I'm not required to have 32 RAM tiles configured. If I don't have enough RAM tiles configured, is it correct that some sprites just won't draw, and that's why people use sprite rotation to multiplex more sprites onto a limited number of RAM tiles?

As an experiment, I tried drawing my sprites first to last and last to first every other frame, to see if I can implement flickering, but the same sprite (the last one) always seems to flicker. I'm not clear on whether I need to actually reassign all of the sprite ids to different objects in order to implement flickering.

I made a test level that forces each sprite to use 4 RAM tiles, and things seem to get super glitchy, rather than just having some of the sprites not draw themselves.
User avatar
D3thAdd3r
Posts: 3175
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: TriggerFx sometimes gets stuck on a note

Post by D3thAdd3r »

I can't figure what is causing that sound issue right now, I'd just move on with development and come back to it later.

You got it on the sprites/ram tiles. ProcessSprites()(in videoMode3.c) starts with sprite 0 and ram tile 0, and increments by one through the sprites and also increments through ram tile as they are required for each one. When they are all used, it is still possible to blit more sprites under the right conditions. If a sprite overlaps vram indices that are a ram tile(because some previous sprite required one there), then the sprite pixels will get drawn over the top of that previous blit(but any pixel overlapping normal tiles, wont be drawn in this situation). So "mega-sprites" of something like 2x2 tiles(max 9 ram tiles) can cover the screen with more sprite pixels overall than a whole bunch of single 8x8 pixel sprites in random locations taking up to 4 each.

Haven't touched sprite flickering stuff for a while now(so if you can verify stuff below that would be great), but I remember it was during MegaBomber development(which barely needed flickering until later on) mostly on hardware and I also remember I didn't write much about important issues with the emulator I ran into later. If you are doing 1 frame on 1 frame off type thing I recall the emulator only draws 30 unique frames a second. This test should explain it better than anything, it helps to think that a real television might be expecting 480interlaced when really Uzebox(or nes/snes/etc) is sending what is more like a 240progressive signal.

Code: Select all

void main(){
//frame 0
	InitMusicPlayer(patches);
	SetTileTable(TilesData);
	SetSpritesTileTable(SpriteData);
	SetMasterVolume(224);

	while(1){
		SetTile(0,0,10);
		WaitVsync(1);
//frame 1
		SetTile(0,0,0);
		WaitVsync(1);
	}
}
You'd probably expect to see whatever tile 10 is flickering on and off with tile 0. In the emulator you will only ever see tile 10 solid however, if you swap those two SetTile() calls around you should then not see 10 drawn at all. On actual hardware, if memory serves me, you will indeed see them flickering back and forth. I will look into this to make sure this info is all correct but the above shows Uzem is drawing frame 1 for 1/30 second, in which case frame 2,4,6,etc are never actually drawn. I also noticed this had an effect on animation(made it look less smooth particularly in Lolo's 7 frame walking anim where each one lasts 1 tick) depending on how those frames lined up. I know I have reluctantly adjusted animation timing to work around this in games, and it does really change the look. I believe I ended up flickering things on for 2 frames and off for 2 frames so it works correctly with the 30hz emulator drawing. Of course the flicker is much more noticeable and I do wonder how much speed Uzem really gains from this since it has to calculate all those cycles anyway? If you animate anything where it's a new frame each tick, you will simply only see half the frames of animation with the current Uzem :|

So basically if you draw from game object 0...16 for 2 frames, starting on frame 1, then starting on frame 3 draw from 16...0 it should work. If you are pushing way more sprites than there are ram tiles, then the sprites in the middle will get drawn most often if you think about it. That was the basis of the priority system idea to tailor things to a game if required, for instance always draw the player first since it's annoying if he flickers.

Edit- if you were going to do that with a game that sometimes takes more than 1/60 second for a game tick, you would need a way to have a frame counter that happens 60hz no matter what. This would do that:

Code: Select all

//main()..
	SetUserPostVsyncCallback(&VsyncCallBack);
//..
}

void VsyncCallBack(){
	global_frame++;
}

//game logic..
	if(global_frame & 1){//odd number frame the emulator will show
		//..
	}
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by Artcfox »

Since I've decreased my cycle usage, and freed up a bunch of RAM, I'm not noticing the TriggerFx() issue as much, so I agree; I'll revisit the issue later once I get some more stuff implemented.

Thank you for describing the sprite rotation stuff, and especially the nuances of uzem regarding its frame rendering. I don't believe those things are currently explained on the wiki. I'm too much of a purist, so I think I would just make a compile time option that changes how many frames the flicker lasts, so when testing on the emulator it can flicker more, but when running on real hardware it would flicker less. Even better if you could detect whether you're running in the emulator or not, and have it automatically select the correct flicker rate on the fly.

At some point I'll probably end up writing a tutorial, or a walkthrough on my development process and add it to the wiki, though I prefer LaTeX for typesetting tutorials. I just realized that this is probably the first actual game that I've written, despite being a software developer for many years. I'm a huge fan of the AVR microcontrollers, and I might end up doing some performance testing/tweaking using a logic analyzer on one of the GPIO pins. That's how I optimized the libraries that I've written for AVRs in the past: When I enter a function/ISR, have it set a pin high, and when i leave the function/ISR set the pin back low.

When I get more time tonight (time is precious and hard to come by) I'll verify the current behavior of the emulator. I haven't looked at the code for the emulator yet, but I wonder how hard it would be to fix that. I did notice that the behavior of the emulator is slightly different than the actual hardware, specifically in my physics calculations. Everything should be deterministic, since I'm using int16_t with fixed point math, but on the actual hardware I noticed that one of my flying entities took a pixel or two longer for friction to decelerate him when changing directions. I only noticed this because I had tweaked that entity's max velocity based on feedback using the emulator so he would fly up and down between two tiles (but skid past them when switching directions) and in the emulator it slides up through the bottom of the floor above it a few pixels, but not enough to cause its hitbox to overlap you if you're standing on the floor above it; whereas on the actual hardware it slides up through the bottom of the floor above it just enough to cause its hitbox to overlap you if you're standing on the floor above it.

I'm viewing the emulator as a tool to help speed up development, but periodically I'm testing it on the real hardware, just so I can discover, and work around these differences before they become hard to work around. If anything, I'll treat the actual hardware as the truth.

That's a great trick! I will use the VsyncCallBack() trick if I need to implement flickering. So far I've been able to avoid flickering completely, because all of my sprites are only 8x8 pixels. But now I'm confused about the actual FPS. I thought NTSC frame rate is 29.97 fps, so I've been using an FPS of 30 for my physics calculations (which I might end up changing to 32, just so I can do bit shifts rather than divides for the integration of acceleration and velocity), because I thought that NTSC is meant to be interlaced, but on the UZEBOX it just sends the same frame twice, so it acts more like progressive, so the perceived FPS is ~30. If I change the order of my sprites 60 times a second, how could that work? Wouldn't that just end up flipping them for only the "odd" scan lines, giving you a mis-mash of stripes from different sprites every other frame? Or is it because the UZEBOX is actually drawing each frame twice (for the even and odd scanlines), then you get exactly what is intended (full sprites that switch @ 30fps)?
User avatar
kivan117
Posts: 73
Joined: Sat Mar 14, 2015 5:43 am

Re: TriggerFx sometimes gets stuck on a note

Post by kivan117 »

Feel like I'm late to the party but wanted to chime in and mention that I ran into this exact same music/effect getting stuck issue when playing around with Ghosty Ghost and parallax initially. It was, as you seem to have solved, an issue of just not having enough cycles for the way I was doing it.

Interestingly, I also noticed the emulator updating the screen at 30hz on both my first and second hand. With the racing game it caused the player sprite, which was swapped between 2 frames of 1tick each, to appear correct on hardware but frozen on one frame in the emulator. For Ghosty Ghost the biggest problem is how fluid the scrolling looks. On hardware it's nice and smooth (on a CRT it's REALLY smooth) but on the emulator the stuttering is just enough that I think hardware players are at an advantage.

I don't know much about the inner workings of the emulator but it would obviously be ideal to have it match hardware if at all possible regarding the frequency of the screen output. Otherwise it's just confusing and inaccurate. Maybe it needs to be 30hz for performance reasons but if not, it would be awesome to get this changed.
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by Artcfox »

kivan117 wrote:Feel like I'm late to the party but wanted to chime in and mention that I ran into this exact same music/effect getting stuck issue when playing around with Ghosty Ghost and parallax initially. It was, as you seem to have solved, an issue of just not having enough cycles for the way I was doing it.
Thanks for chiming in. I'm relieved to know that I'm not the only one that has experienced this!

I'm curious how you finally solved it though. Did you have to decrease the number of cycles you used per frame so all of your game logic got completed before the next call to WaitVsync(1), or were you able to get the sound working properly even if your game logic spilled you over into the next frame?

Before I did some optimization work, I was spilling over into the next frame (and possibly even into the frame(s) after that), and it didn't seem to affect the gameplay that much at all (other than the sustained note issue) so I'd like to keep the option of spilling over into the next frame if possible.

If the only way to solve the sustained note issue is to lower the cycle count, then I guess I can decrease the number of vertical tiles, and steal back some RAM and cycles, but I was hoping for as large of a screen as possible.
User avatar
uze6666
Site Admin
Posts: 4778
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by uze6666 »

Hi Matt, welcome to the Uzebox community! Been offline for a couple day and just saw your thread. I also think the lack of cycles is what's causing the issue. Normally the game should gracefully slow down the main program without much other effects. Though, in this case it seems to also affect the kernel that is running at a fixed 60hz speed. I'll try to think why it could happens. If you can record an example with camstudio ans PM it to me it could help understanding the issue (though no garantees it's fixable).
And wow this frees up a lot of RAM! I can use even more RAM tiles now! :D This is great! I'm not exactly sure what:
-DSOUND_CHANNEL_4_ENABLE=0
The channel disabling switches are for the vsync mixer to lower the cpu cycles and does nothing for the inline mixer so you can safely remove it.
I'm a huge fan of the AVR microcontrollers, and I might end up doing some performance testing/tweaking using a logic analyzer on one of the GPIO pins. That's how I optimized the libraries that I've written for AVRs in the past: When I enter a function/ISR, have it set a pin high, and when i leave the function/ISR set the pin back low.
Have you tried using Atmel's simulator in AvrStudio and AtmelStudio? It has a cycle counter and I use it heavily when doing assembler stuff, specially video modes. Just put breakpoints in you code and calculate the elapsed cycles.
When I get more time tonight (time is precious and hard to come by) I'll verify the current behavior of the emulator. I haven't looked at the code for the emulator yet, but I wonder how hard it would be to fix that. I did notice that the behavior of the emulator is slightly different than the actual hardware, specifically in my physics calculations. Everything should be deterministic, since I'm using int16_t with fixed point math, but on the actual hardware I noticed that one of my flying entities took a pixel or two longer for friction to decelerate him when changing directions. I only noticed this because I had tweaked that entity's max velocity based on feedback using the emulator so he would fly up and down between two tiles (but skid past them when switching directions) and in the emulator it slides up through the bottom of the floor above it a few pixels, but not enough to cause its hitbox to overlap you if you're standing on the floor above it; whereas on the actual hardware it slides up through the bottom of the floor above it just enough to cause its hitbox to overlap you if you're standing on the floor above it.

I'm viewing the emulator as a tool to help speed up development, but periodically I'm testing it on the real hardware, just so I can discover, and work around these differences before they become hard to work around. If anything, I'll treat the actual hardware as the truth.
As you mentionne the emulator is really so speed up development and is far from perfect emulation. Perhaps less than 50% of peripherals are emulated and we patch it as requirements comes in (like timer1 overflow interrupt for Tornado2000). Also, the whole video is hacked on using the sound output to synchronize frames! So there's definitely things that could differ timing wise. But the AVR CPU core with memory and registers,peripherals are ok, but again I never tested it against running in AVR Simulator.
But now I'm confused about the actual FPS. I thought NTSC frame rate is 29.97 fps, so I've been using an FPS of 30 for my physics calculations (which I might end up changing to 32, just so I can do bit shifts rather than divides for the integration of acceleration and velocity), because I thought that NTSC is meant to be interlaced, but on the UZEBOX it just sends the same frame twice, so it acts more like progressive, so the perceived FPS is ~30. If I change the order of my sprites 60 times a second, how could that work? Wouldn't that just end up flipping them for only the "odd" scan lines, giving you a mis-mash of stripes from different sprites every other frame? Or is it because the UZEBOX is actually drawing each frame twice (for the even and odd scanlines), then you get exactly what is intended (full sprites that switch @ 30fps)?
NTSC is 29.97 frames per second, with each frames made of two interlaced fields. At the end of each fields there a vsync retrace and that's what the Uzebox internal interrupts is based on, the field rate that is about 60hz. So when you WaitVsync(1), you are really waiting until the next field retrace (up to 1/60 of a second). In reality the kernel will render (at least actually) each field independently at 60hz with whatever the vram,sprites, etc are setup at that time. So not a full sprites that switch @ 30fps.
For Ghosty Ghost the biggest problem is how fluid the scrolling looks. On hardware it's nice and smooth (on a CRT it's REALLY smooth) but on the emulator the stuttering is just enough that I think hardware players are at an advantage.I don't know much about the inner workings of the emulator but it would obviously be ideal to have it match hardware if at all possible regarding the frequency of the screen output. Otherwise it's just confusing and inaccurate. Maybe it needs to be 30hz for performance reasons but if not, it would be awesome to get this changed.
You can run uzem.exe -i yourgame.hex to enable interlacing. By default it just draws the even fields twice. Things are smoother, but there's obvious shearing artifacts between scanlines for moving objects. That's the reason why it's optional.
If the only way to solve the sustained note issue is to lower the cycle count, then I guess I can decrease the number of vertical tiles, and steal back some RAM and cycles, but I was hoping for as large of a screen as possible.
This is indeed a great way to at least test to see if it's a cycle thing. You can use the SetRenderingParameters() function to lower the number of vertical lines to be rendered.

On a related note regarding uzem, MAME will soon ship (if not already) with partial Uzebox emulation. Since they go for perfect emulation at the expense of speed I don't know if it will run full speed on current machines. Could be another way to tests things when uzem seems to act weird.

Looking forward to see your game! :P
User avatar
D3thAdd3r
Posts: 3175
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: TriggerFx sometimes gets stuck on a note

Post by D3thAdd3r »

It is interesting that too many cycles is at fault here, never saw such a subtle problem from it. There really is no other explanation for it.

Very interesting also that MAME(as opposed to MESS) will include Uzebox support..I suppose Uzebox JAMMA is the reason? If we are lucky they will throw a bunch of man hours at it and if we are really lucky, maybe, we could end up with a faster version for free!

I don't remember the original reason for IsRunningInEmulator (), but I do think it's existence is quite valid since no one is going to make games that only run on Uzem. It's similar to the true random number generator which we really can't use yet, even with IsRunningInEmulator(), since its compile time and automatically seeds at kernel start. No one will want to make a hardware only game for sure. In the same vein we really cannot implement any smooth animation in a game because few people would know your game needed it and actually use "-i". It just appears broken to nearly everyone, and having different emulator and hardware roms is not ideal either.

The -i works, but it seems to me it's useless besides development, unless a game that needs it can force it without users specifying it on the command line. I'm not in love with those kind of implementations, but still seems "less gross" then essentially forcing games to 30hz animations for the reasons above. The tearing does not seem like an easy thing to eliminate in a windowed mode, since monitor refresh rates arent all 60hz to just lock to vsync. I guess fullscreen might be a solution, but NES emulators like FCEUX surely deal with the same issues.
User avatar
uze6666
Site Admin
Posts: 4778
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by uze6666 »

It is interesting that too many cycles is at fault here, never saw such a subtle problem from it. There really is no other explanation for it.
Well, it's just gut feeling, but it could be something else. I can't be sure of it because I never experienced such behavior either. I'd have to run the code locally.
Very interesting also that MAME(as opposed to MESS) will include Uzebox support..I suppose Uzebox JAMMA is the reason? If we are lucky they will throw a bunch of man hours at it and if we are really lucky, maybe, we could end up with a faster version for free!
Not sure but there was some news that MAME and MESS fused. It's probably at the source level only. http://mamedev.org/?p=406 Still 2 targets I think, so it's MESS I meant then. :? I was chatting a while ago with the guy who ported the uzebox to MESS to see the effort on completing the thing. From what I heard he implemented sound afterwards and SD card would remain. But for sure, so far, emulation is slower than even uzem. MAME and MESS go for the perfect emulation at the expense of speed.

Using the -i option doesn't change the game logic or timing per se, it's just that it will appear more fluid since you can see new movements at 60hz instead or 30hz. On a CRT the brain seems to merge the two fields pretty well. No so much on a monitor as you said.
User avatar
D3thAdd3r
Posts: 3175
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: TriggerFx sometimes gets stuck on a note

Post by D3thAdd3r »

Cool I didn't know about the MAME/MESS merger but I like it!

It really does look and feel smoother but right now -i artifacts are so bad it's not worth it.
blurry_i.png
blurry_i.png (7.84 KiB) Viewed 6578 times
It looks like it's blending 2 frames together and outputting it as one with the fields shifted up/down 1 pixel. I don't think it's actually tearing that looks so bad, I think Uzem is trying to emulate interlacing...over 2 frames? I run NES emulators in frame by frame all the time for stealing game play timings, and they make no attempt to do that and just output 60 progressive frames(and it looks great, probably faster). I am not sure what the implications are for the pixel scaling(to emulate non-square television pixels on square PC pixels). For emulators on other consoles I always found non-integral scaling twisted things pretty badly. I guess on Uzebox there is not set hardware resolution so that complicates things a bit, probably the only real way to do it would be 1 pixel per cycle or a resolution of around 1440 horizontal.

I hesitate to speculate on something that I have not looked into the code for years now, but a screen capture should always show a non-blurred image if Uzem wasn't actually doing what I think it is:
closeup_i.png
closeup_i.png (714 Bytes) Viewed 6575 times
Only reason it gets under my skin is that I think it does have real gameplay and design effects(Lolo has to appear walking 1/2 NES speed or it looks totally weird) for some games since you only have 1/2 the precision of display<->input response. Ghosty Ghost is likely the most intense timing game and I do think there is a very real difference playing on hardware and emulator....so then make a fix right?...well...too lazy to act on half my "utmost importance" ideas and talk is easy :roll:
User avatar
uze6666
Site Admin
Posts: 4778
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: TriggerFx sometimes gets stuck on a note

Post by uze6666 »

It looks like it's blending 2 frames together and outputting it as one with the fields shifted up/down 1 pixel. I don't think it's actually tearing that looks so bad, I think Uzem is trying to emulate interlacing...over 2 frames? I run NES emulators in frame by frame all the time for stealing game play timings, and they make no attempt to do that and just output 60 progressive frames(and it looks great, probably faster).
To not hijack this thread, I have opened a new topic for this here:http://uzebox.org/forums/viewtopic.php?p=15429#p15429
Post Reply