It is currently Wed May 22, 2019 1:35 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Fri May 17, 2019 3:39 pm 
Offline
User avatar

Joined: Sun May 27, 2012 8:43 pm
Posts: 1348
Street Fighter II reads inputs at the start of the game's polling loop. This is troublesome for emulator authors who don't update the virtual inputs frequently. If the game has a "turbo" setting on, it means that the number of game ticks that run per visual frame can vary, and with that, the frequency of input polls.

Dwedit - why would reading the gamepad during the NMI produce controller data changes mid-frame?


Top
 Profile  
 
PostPosted: Fri May 17, 2019 4:18 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4172
Just assuming you store your byte after you did the 8 joypad reads.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Fri May 17, 2019 5:10 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7461
Location: Canada
Race conditions with a vblank interrupt aren't necessarily a big deal. It depends how often you refer to your input, and what you do with it. If you handle your player control early on in a frame and never later on it'd be pretty unlikely to get clobbered even in a lag situation. There are lots of "convenient" reasons one might end up checking again later on in a frame though...

The main disadvantage is just that you've introduced another situation that can go wrong if you're not aware of the threading / timing. Probably most of the time it wouldn't matter at all, but the kind of errors you get when you forget can be pretty insidious.

That's basically why I'd advocate not doing it by default on the NES, but if you've got a reason you need it then sure go for it.

tepples wrote:
Would it be likewise "apples to oranges" between the NES and Super NES?

Ask me when you've got a concrete example for SNES, I don't want to get hypothetical. We're comparing a C games library API on Genesis to what's appropriate for NES, or at least, I was.

Polling in a vblank interrupt is a valid technique on NES, SNES, or Genesis. Polling on demand is also valid on all three of these platforms.

Should one way or the other be "standard" for any of these platforms? I don't care. I think I already stated what purposes it can be used for. If you've got a good use case for it, use it. If you don't, I'd probably recommend not doing it for simplicity's sake. If you're using a library like SGDK, just roll with however it expects you to do things.


Top
 Profile  
 
PostPosted: Fri May 17, 2019 11:57 pm 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 938
tepples wrote:
And which get linked into the executable, occupying ROM and RAM, even if unused.

No, they do not. These are modern tools, with LTO and other such conveniences the ancient platforms can only dream of.

LTO will notice you never call function X. That cascades. If you don't use any SGDK joy functions, they will be optimized out such that only the var update in the vblank func will remain.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 12:17 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7711
Location: Chexbres, VD, Switzerland
tokumaru wrote:
One reason not to read controllers in the NMI handler is the consistency of controller state within the same logic frame. If a lag frame happens, and an NMI fires in the middle of that logic frame, it's possible that different controller states will be readable in that same logic frame.

I was going to say the exact same thing. This is really the only significant problem with reading the controller in NMI. I can't think of anything else. If the main code is designed robustly, either by making it's local copies during decision-taking routines, or by making sure the potentially slow code is always executed after the code using the controller-read value and taking decisions, it's fine. But the danger of having main codes behaving weirdly, or, in worst cases, even crashing, if the controller changes states during a lag frame, is there. This could also be a thing to exploit for speedruners.

For similar reasons, it would be bad practice to poll the controller multiple times during the same frame (*) - unless the logic is solid, and for example once only the directional pad are used and the other time only the buttons are used.
(*) I'm not including cases where reading the controller multiple times is part of the read routine

Also I disagree with tepples that games usually don't read controller during NMI. This practice might be not recommended, but commercial games still do it, often. Just check the NMI routine of your favourite games.

The only real advantage of reading the controller in NMI I can think of, is that you don't need to call the controller reading routine at many different places across the game's code. This saves a tiny bit of ROM. Other than that I can't think of any advantages.

tokumaru wrote:
I don't know about the Mega Drive, but on the NES, where vblank time is at a premium, wasting part of it on a task that could literally be performed at any other time, would be completely nonsensical.

Doing it before the VRAM updates would be completely nonsensical, but doign it in NMI after all VRAM updates, I really don't see the problem. Just like playing the music engine, by the way. And reading controllers in constant-cycle-timed routine is not hard to do, so it even doesn't clash with potential further-raster-effects-that-don't rely-on-sprite-zero-hit.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 2:58 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 1162
Location: Hokkaido, Japan
Yeah I'm also not sure what Tepples is talking about. It is commonly done in games. I once even thought it was preferable to have input reading in NMI, but Tokumaru taught me about the possible inconsistency it introduces, and I stopped doing it.

Also doesn't the SNES controller auto-reading function read the controllers in vblank or something?

Bregalad wrote:
The only real advantage of reading the controller in NMI I can think of, is that you don't need to call the controller reading routine at many different places across the game's code. This saves a tiny bit of ROM. Other than that I can't think of any advantages.
That could be done in the main loop as well. If you have a jump table for the various modes your game has in the main thread, you can just read the controllers before the jump table and jumping to the active mode's logic. As long as all modes are fine with the same controller reading routine it's enough with just one call.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 3:18 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 103
calima wrote:
tepples wrote:
And which get linked into the executable, occupying ROM and RAM, even if unused.

No, they do not. These are modern tools, with LTO and other such conveniences the ancient platforms can only dream of.

LTO will notice you never call function X. That cascades. If you don't use any SGDK joy functions, they will be optimized out such that only the var update in the vblank func will remain.


LTO is only good if there is a means of indicating when a function call needs to be regarded as "opaque", and all functions where that is necessary are thus marked. When C was invented, there was no need for such a directive because all or nearly all extant compilers would extend the language by treating cross-module function calls as opaque(in fact such treatment was so universal it wasn't generally thought of as an "extension", but simply part of how the language worked), and thus very little code that relies upon such treatment that is marked to indicate such reliance.

Without such marking, something like:
Code:
   volatile unsigned char data_ready_flag;
   void wait_for_frame(void)
   {
      while(data_ready_flag)
        ;
   }
   ...
   databuff[0] = 123;
   wait_for_frame();
   databuff[0] = 45;
   wait_for_frame();

may get "optimized" to remove one of the stores to databuff[0].


Top
 Profile  
 
PostPosted: Sat May 18, 2019 3:25 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 103
Bregalad wrote:
(*) I'm not including cases where reading the controller multiple times is part of the read routine


If one performs an OAM DMA within the NMI routine, and keeps track of whether an even or odd number of cycles have elapsed between then and the code that will read the controller, one can avoid the possibility of DMC clobbering the controller read. Likewise if one reads the controller at a suitable time within a DMC IRQ. While one needs to be mindful of how controller inputs will behave in the presence of lag, and ensure that such behaviors will always be sensible, I think reading then at a consistent point each frame is for many purposes better than just reading them "whenever".


Top
 Profile  
 
PostPosted: Sat May 18, 2019 3:30 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7711
Location: Chexbres, VD, Switzerland
supercat wrote:
If one performs an OAM DMA within the NMI routine, and keeps track of whether an even or odd number of cycles have elapsed between then and the code that will read the controller, one can avoid the possibility of DMC clobbering the controller read. Likewise if one reads the controller at a suitable time within a DMC IRQ. While one needs to be mindful of how controller inputs will behave in the presence of lag, and ensure that such behaviors will always be sensible, I think reading then at a consistent point each frame is for many purposes better than just reading them "whenever".

I've edited this note in quickly because when I claimed that reading controller twice per frame could be potentially harmful, I was sure someone came up with an annoying remark noticing how this is useful for DMC. Apparently even though I've edited this in, I still didn't avoid people quibble over that.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 3:46 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 103
Bregalad wrote:
supercat wrote:
If one performs an OAM DMA within the NMI routine, and keeps track of whether an even or odd number of cycles have elapsed between then and the code that will read the controller, one can avoid the possibility of DMC clobbering the controller read. Likewise if one reads the controller at a suitable time within a DMC IRQ. While one needs to be mindful of how controller inputs will behave in the presence of lag, and ensure that such behaviors will always be sensible, I think reading then at a consistent point each frame is for many purposes better than just reading them "whenever".

I've edited this note in quickly because when I claimed that reading controller twice per frame could be potentially harmful, I was sure someone came up with an annoying remark noticing how this is useful for DMC. Apparently even though I've edited this in, I still didn't avoid people quibble over that.


My point was that if one is using DMC for video frame timing and reads controllers from the main loop, one will have to read them multiple times to make them reliable, but the necessity of reading them twice suggests that the controllers should be read differently.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 10:55 pm 
Offline
User avatar

Joined: Wed Aug 03, 2005 3:15 pm
Posts: 399
I'm not sure I understand what is bein' posited? I think every NES game I've made strobes the controller in NMI, but not necessarily in vblank. Are we talkin' about readin' the actual inputs that the user... inputs? Like testin' if they pushed the 'A' button and all that jazz?


Top
 Profile  
 
PostPosted: Sat May 18, 2019 11:16 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11345
Location: Rio de Janeiro - Brazil
Yeah, we're talking about reading the state of the controller's buttons. The main argument against doing this in the NMI handler is that the state of the controller will change in the middle of lag frames, which could cause problems depending on how the game uses the input data, while the main argument for reading the controllers in the NMI handler appears to be the possibility of using the OAM DMA to avoid controller data corruption caused by DPCM sample fetches.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 11:28 pm 
Offline
User avatar

Joined: Wed Aug 03, 2005 3:15 pm
Posts: 399
haha What a weird debate. Obviously it will depend on the engine bein' used, because if you KNOW there will be no input lag due to lagging frames, then implement it. Alternatively, if you can implement a DMC bug squash with it, then do it.

The way I tend to program though, I would shy away from anything not PPU related during vblank. But that's because everyone has a different way to implement things hehe No one is right or wrong, if I'm reading this correctly. Just all about implementation?


Top
 Profile  
 
PostPosted: Sun May 19, 2019 4:26 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 1162
Location: Hokkaido, Japan
It's not about being right or wrong. It's about different possibilities and pros and cons, but yeah it heavily depends on what you are trying to do.

Also it is not about input lag, but rather the opposite (logic lags but not the controller). It's about a possible bug if you have slowdown in your game and have the controller reading in NMI instead of the main thread.
If the main thread lags and an NMI interrupts it, having the controller reading in the NMI will update the controller state again before the main thread has finished the logic. So the first part of the logic is processing one controller state and the second part (after PC has returned from NMI) is processing an updated controller state, which would potentially be the cause of a bug, although possibly rarely.

If you can guarantee you have no lag frames there is no problem in having the controller reading in NMI though, since there will be an equal number of main thread logic frames as NMI frames.

Either way NMI isn't strictly for vblank related things. Your sound driver is best updated in the NMI or the music will not have a consistent beat if you have lag frames (some commercial games messes this up too).


The DMC fix is very advanced, and I'm not sure it's fully PAL compatible either.


Top
 Profile  
 
PostPosted: Sun May 19, 2019 5:12 am 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2018
Location: Gothenburg, Sweden
Quote:
The DMC fix is very advanced, and I'm not sure it's fully PAL compatible either.

The theory behind is in-depth but the implementation is plug and play, provided there's nothing in your game that makes controller reads right after OAMDMA directly unsuitable.

the PAL version doesn't have the dmc bug (it was fixed), so it should work either way you do it, rahsennors' cycle alignment fix or not. There might be problems with several emulators, though - the even/odd observation was only highlighted a few years ago and emulators might not have the bug correctly implemented. Then again, you need games that use the dmc fix to create incentive to fix emulation inaccuracies.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 11 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group