About DPCM Samples

User avatar
Kasumi
Posts: 148
Joined: Fri Mar 09, 2018 11:13 pm

Re: About DPCM Samples

Post by Kasumi » Tue Jul 03, 2018 4:38 am

CutterCross - From my understanding (because this is where we get to the end of my knowledge) the buffer can only hold a single byte regardless of anything. So yes, it must constantly refill sample data all the time regardless of if it's the same sample because samples you'd want are larger than a byte.

Rather than change your samples to avoid it, you change your joypad read subroutine to avoid it. It's a simple, one time change.
Here's the one from Indivisible (NESASM syntax rather than asm6). This is "the easy way" I described in my post.

Code: Select all

	lda <p1curstate
	sta <p1oldstate

	lda #$01
	sta <p1curstate ;initialize the buffer with a flag
	
	sta $4016;Strobe joypads
	lsr a
	sta $4016
p1and2loop:
	lda $4016
	and #%00000011
	cmp #$01
	rol <p1curstate
	bcc p1and2loop ;loop if the flag wasn't shifted out yet
	
	lda #$01
	sta <reserved0 ;initialize the buffer with a flag
	
	sta $4016;Strobe joypads
	lsr a
	sta $4016
p1testloop:
	lda $4016
	and #%00000011
	cmp #$01
	rol <reserved0
	bcc p1testloop;loop if the flag wasn't shifted out yet
	
	lda <reserved0
	cmp <p1curstate
	beq joypad1matched
	lda <p1oldstate
	sta <p1curstate
joypad1matched:
This is what the Super Mario Bros. 3 method looks like (more or less. Mario 3 would use the second read's result to compare to the third's and the third's to compare to the fourth's rather than starting again with two new reads). (The "equally easy way" I described in my post.)

Code: Select all

	lda <p1curstate
	sta <p1oldstate
joypad1didnotmatch:
	lda #$01
	sta <p1curstate ;initialize the buffer with a flag
	
	sta $4016;Strobe joypads
	lsr a
	sta $4016
p1and2loop:
	lda $4016
	and #%00000011
	cmp #$01
	rol <p1curstate
	bcc p1and2loop ;loop if the flag wasn't shifted out yet
	
	lda #$01
	sta <reserved0 ;initialize the buffer with a flag
	
	sta $4016;Strobe joypads
	lsr a
	sta $4016
p1testloop:
	lda $4016
	and #%00000011
	cmp #$01
	rol <reserved0
	bcc p1testloop;loop if the flag wasn't shifted out yet
	
	lda <reserved0
	cmp <p1curstate
	bne joypad1didnotmatch
Remove the last 13 instructions and you have a "regular" controller read routine.

Code: Select all

	lda <p1curstate
	sta <p1oldstate

	lda #$01
	sta <p1curstate ;initialize the buffer with a flag
	
	sta $4016;Strobe joypads
	lsr a
	sta $4016
p1and2loop:
	lda $4016
	and #%00000011
	cmp #$01
	rol <p1curstate
	bcc p1and2loop ;loop if the flag wasn't shifted out yet	
Though from what I can remember NES Maker stores the buttons reversed of what's here. ("A" is the rightmost bit rather than the leftmost.)
User avatar
CutterCross
Posts: 246
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Tue Jul 03, 2018 4:59 am

Kasumi, you've been a great help! The assembly routines don't actually look too difficult (for someone like me who's never written assembly code in his life).
Mihoshi20 wrote:
Tue Jul 03, 2018 3:26 am
There and interesting forum thread I stumbled across on NESDEV titled "DPCM generates extra $4016 read pulse" that talks about DPCM and it's relation to the controller inputs you might find interesting. http://forums.nesdev.com/viewtopic.php?t=4116

There's also this little nugget of info on the NESDEV wiki. "DPCM Safety using Repeated Reads: If your code is intended to be used with APU DMC playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, Super Mario Bros. 3 reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over. Because repeated rereads can take a long time, another way is to just use the previous frame's button press data if the results differ: "

I think the disabling DPCM capabilities for the engine and letting advanced users deal with it was the overall right choice given the tool's market and scope as nice as it would be to have the feature and once the tool is release to the public, a clever user may work the functionality back in that doesn't cause issues with controller input and release release the code for others to use.
I also think it was a good idea to disable DPCM for newbies just as long as it's simple for craftier users to enable it back again. After all, you shouldn't exclude others from innovating if they know the means to do so, whether it involves DPCM samples or anything else the NES is capable of. If nobody was innovating, we probably wouldn't see anything notable coming from NESmaker. It would kinda be like Unity, a very capable game engine but is really only known for cheap shovelware-type games, despite being capable of so much more than that.

Thankfully, there's a lot of dedicated people here, so were bound to see some awesome releases coming from NESmaker!
The Tower of Turmoil: viewtopic.php?f=13&t=227
User avatar
Kasumi
Posts: 148
Joined: Fri Mar 09, 2018 11:13 pm

Re: About DPCM Samples

Post by Kasumi » Tue Jul 03, 2018 6:49 am

I've attached a specifically NES Maker joypad routine that allows for what Super Mario Bros. 3 does. But don't use it! Heh. I've left it only for reference.
I made the original text small, since there's no strike through or similar on this forum.
It's tied to the same define that GGSound uses to enable the DPCM features. If DPCM is enabled in GGSound, you get a routine that attempts to avoid controller corruption. If DPCM is not enabled in GGSound, you get a regular controller read routine.

No need to swap out files, just the define. (Which you'd do anyway to enable/disable the feature within GGSound.) It goes in GameEngineData\Routines\System (Replace what's there.)

Edit: Oh. Since NES Maker seems to read the controller in the NMI anyway, it could actually do a much simpler method of avoiding this. https://forums.nesdev.com/viewtopic.php ... 15#p172188 The sprite DMA puts you on a specific side of the 50/50 coin, that code makes sure all the reads are on the side that doesn't get hit by corruption.

Provided that works (and I haven't tested it), there doesn't even need to be a different controller read routine to avoid the issue. (One does have to keep on top of it to make sure to avoid page boundary crossing.)

Regardless! There seem to be about 2,000 bytes you can use for samples. (But as the NES Maker Engine grows, that space gets smaller and smaller. Be smart. Be careful. Be prepared for the engine to grow.)

To add your DPCM data, you'd open GameEngineData\MainASM.asm, and directly below the line with .include "Routines\System\AssignBanks.asm"
You'd .include your DPCM data file that GGSound exports.

The define for DPCM in GGSound seems to already be enabled in NES Maker. But in case that changes (and none of the rest of this does) for some reason, in sound/ggsound.inc you'd add
FEATURE_DPCM = 1
right above
FEATURE_ARPEGGIOS = 1

At least... in theory! If it doesn't work, yell at me and I'll try to help.

Edit again!: Since NES Maker does read the controller in the NMI (and before other kinds of updates are done) I've realized the attached thing is actually pretty unsafe to just drop in. You'd have to change the NMI update order and while that's a thing I know how to swing, it's also something that would have to be done for every release.
Attachments
GamePadCheck.zip
(740 Bytes) Downloaded 33 times
Last edited by Kasumi on Tue Jul 03, 2018 7:48 am, edited 6 times in total.
User avatar
CutterCross
Posts: 246
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Tue Jul 03, 2018 7:00 am

Kasumi wrote:
Tue Jul 03, 2018 6:49 am
I've attached a specifically NES Maker joypad routine that allows for what Super Mario Bros. 3 does.

It's tied to the same define that GGSound uses to enable the DPCM features. If DPCM is enabled in GGSound, you get a routine that attempts to avoid controller corruption. If DPCM is not enabled in GGSound, you get a regular controller read routine.

No need to swap out files, just the define. (Which you'd do anyway to enable/disable the feature within GGSound.)
Kasumi, you are AWESOME! I think you just saved all of us several hours of work. (Granted, I won't be able to test it out until August when NESmaker releases, but it's incredible nonetheless!)
The Tower of Turmoil: viewtopic.php?f=13&t=227
User avatar
Kasumi
Posts: 148
Joined: Fri Mar 09, 2018 11:13 pm

Re: About DPCM Samples

Post by Kasumi » Tue Jul 03, 2018 7:55 am

Well, I'm not that awesome. I realized the code would have done bad things to NES Maker. There's a limited time to do certain kinds of graphical updates. NES Maker reads the controller before all such updates are done. The SMB3 method of reading controllers in this context could take enough time to make certain graphical updates happen outside the time when they're allowed.

The non Super Mario Bros 3. method (read both, but take the previous frame if they don't match) would be a little better. (Since the time used would be fixed.)

I know how to fix it (you'd move jsr GamePadCheck to right above skipNMUstuff:) but the file the fix needs to go in is not as isolated. (MainASM.asm is much more likely to change in updates such that just replacing the file would break it.)

Edit: If you wanna get your hands really dirty, you could also just try this: https://forums.nesdev.com/viewtopic.php ... 15#p172188 Since NES Maker reads the controller very near to a sprite DMA currently anyway, that's a method that could be tried. (But I haven't tested it.) You'd have to modify it to read the buttons as NES Maker does.
User avatar
Mihoshi20
Posts: 431
Joined: Tue Mar 06, 2018 11:47 pm

Re: About DPCM Samples

Post by Mihoshi20 » Wed Jul 04, 2018 12:42 am

Kasumi wrote:
Tue Jul 03, 2018 7:55 am
Well, I'm not that awesome. I realized the code would have done bad things to NES Maker. There's a limited time to do certain kinds of graphical updates. NES Maker reads the controller before all such updates are done. The SMB3 method of reading controllers in this context could take enough time to make certain graphical updates happen outside the time when they're allowed.

The non Super Mario Bros 3. method (read both, but take the previous frame if they don't match) would be a little better. (Since the time used would be fixed.)

I know how to fix it (you'd move jsr GamePadCheck to right above skipNMUstuff:) but the file the fix needs to go in is not as isolated. (MainASM.asm is much more likely to change in updates such that just replacing the file would break it.)

Edit: If you wanna get your hands really dirty, you could also just try this: https://forums.nesdev.com/viewtopic.php ... 15#p172188 Since NES Maker reads the controller very near to a sprite DMA currently anyway, that's a method that could be tried. (But I haven't tested it.) You'd have to modify it to read the buttons as NES Maker does.
This is mostly why I'm not focusing on major projects until after August when I'm more confident that the code will at least be a bit more stable or in a more finalize state as far as MainASM and primary areas of the code not designed to be edited by the general user. In 'feature lock' if you will. Currently I'm opting more to work on smaller projects to get used to the tool and it's functions and changes during the beta period so if a major part of the tool changes and I have to start over, it's not as big of a deal.
User avatar
CutterCross
Posts: 246
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Wed Jul 04, 2018 5:43 am

Mihoshi20 wrote:
Wed Jul 04, 2018 12:42 am
Kasumi wrote:
Tue Jul 03, 2018 7:55 am
Well, I'm not that awesome. I realized the code would have done bad things to NES Maker. There's a limited time to do certain kinds of graphical updates. NES Maker reads the controller before all such updates are done. The SMB3 method of reading controllers in this context could take enough time to make certain graphical updates happen outside the time when they're allowed.

The non Super Mario Bros 3. method (read both, but take the previous frame if they don't match) would be a little better. (Since the time used would be fixed.)

I know how to fix it (you'd move jsr GamePadCheck to right above skipNMUstuff:) but the file the fix needs to go in is not as isolated. (MainASM.asm is much more likely to change in updates such that just replacing the file would break it.)

Edit: If you wanna get your hands really dirty, you could also just try this: https://forums.nesdev.com/viewtopic.php ... 15#p172188 Since NES Maker reads the controller very near to a sprite DMA currently anyway, that's a method that could be tried. (But I haven't tested it.) You'd have to modify it to read the buttons as NES Maker does.
This is mostly why I'm not focusing on major projects until after August when I'm more confident that the code will at least be a bit more stable or in a more finalize state as far as MainASM and primary areas of the code not designed to be edited by the general user. In 'feature lock' if you will. Currently I'm opting more to work on smaller projects to get used to the tool and it's functions and changes during the beta period so if a major part of the tool changes and I have to start over, it's not as big of a deal.
Yeah, I understand that. You never know what sort of things will change in the future, but it doesn't hurts to start planning things out early. I know that I probably won't use DPCM samples in most of my games anyway, but it's good to experiment to see what you can get away with.

If anyone wants to see the music I've experimented samples with, you can check it out here:


Version with DPCM samples:

YouTube: https://www.youtube.com/watch?v=ryEhzFigTAc
SoundCloud: https://soundcloud.com/paul-haas-752206 ... acker-2a03

Version without DPCM samples:

YouTube: https://www.youtube.com/watch?v=hRWg7aD0Mig
SoundCloud: https://soundcloud.com/paul-haas-752206 ... acker-2a03


I know that it's more impractical to use samples in an actual NES game, so that's why I also a version without samples, just in case it doesn't work out in the end.
The Tower of Turmoil: viewtopic.php?f=13&t=227
kimmysawi
Posts: 1
Joined: Fri Jul 06, 2018 9:57 am

Re: About DPCM Samples

Post by kimmysawi » Mon Jul 16, 2018 12:34 pm

CutterCross wrote:
Tue Jul 03, 2018 2:45 am
Kasumi wrote:
Tue Jul 03, 2018 2:19 am
CutterCross - If a sample is playing at all, input corruption is always possible. But it's not specifically playing the sample that causes the corruption. Playback only relies on the thing that causes the corruption.

If you're familiar with streaming services like youtube: A portion of the video loads. When you've watched most of the portion that loaded, more of the video is sent to you. And when you've watched most of that, more of the video is sent to you.

Sample playback works similarly. A portion of the sample data is loaded into a buffer by the hardware to play back later. When that portion is done playing, the next portion of the sample data is loaded.

If the read the hardware does that loads more sample data into the buffer happens at exactly the same time as the software reads the "controller register", the value given to the software will be incorrect. (But "at exactly the same time" is very specific. It's basically a 50/50 shot whether the read will be wrong even if it's as close to the sample read as is possible for the CPU to be at that point in time.)

High quality samples mean the buffer needs to be filled more often which increases the likelihood of the two things happening at the same time. It's like how a 1080p 60FPS stereo video would request data more often than a 240p mono video on youtube. visit phenq review here

So input data can be read correctly while a sample is playing, but not when the buffer is getting filled (well, even that has a 50/50 shot of no effect). Since the buffer is not getting filled all the time, input data won't always be corrupted when playing back samples.

Anyway, this is just information. I could probably just provide joypad code that's DPCM safe and you wouldn't have to worry about the specifics. It's a one time change.

I see the harder bit as where the sample data needs to be and the implications of that. The engine growing could get in the way of someone's samples that used to fit. A user's samples growing could crash into the engine. So it's an "over time" change rather than a "one time" change.
Okay, that explains a lot! Thanks!

So, what if I had a very small sample that constantly loops to make the sound last longer? Does the buffer need to constantly refill the same sample data over and over again, or is it a one-time thing at the start of sample playback?

I guess another question I'm asking is, how much sample data can the buffer hold at one time?
It can beat the items and can effect easily those blast
User avatar
SuperMar10Brothe
Posts: 65
Joined: Sat Aug 11, 2018 4:43 pm

Re: About DPCM Samples

Post by SuperMar10Brothe » Sun Aug 12, 2018 8:16 pm

This is very disappointing to hear, it would have been a lot better if you left it enabled but made a warning pop up or something about the potential problems it may cause.

Are there any plans on DPCM support in the future ? maybe developing some smart way of handling it to work around those problems?
darkhog
Posts: 256
Joined: Sun May 13, 2018 10:02 am

Re: About DPCM Samples

Post by darkhog » Sun Aug 12, 2018 8:23 pm

Yeah, sad that it doesn't have support for DPCM samples, it would be a great enhancement to music and perhaps sfx. I understand why you did it as I know NES limitations pretty well, but still I'm disappointed. If you find a way to do it, either with GGSound or by employing different sound engine (or writing your own!), please do so.
Post Reply