ngdevkit icon indicating copy to clipboard operation
ngdevkit copied to clipboard

Deferred VBL routines, audio, and then some more

Open ggnkua opened this issue 9 months ago • 4 comments

Hello,

First of all, great work on making this SDK, I'm sure you saved lots of people's hours and head scratches (mine included!).

Sorry if the title sounds a bit of a mixed bag, but all's connected as you'll see in due time.

Long story short: I made a port of an Atari 800 game (http://aim.atariscene.pl) for the Atari ST (a playable version released in July here: https://www.pouet.net/prod.php?which=94605), and while I was waiting for graphics and music, I started porting the game to other 68k platforms, NeoGeo included.

As you can imagine, I used ngdevkit to bootstrap the NegGeo port and I figured most things out, but sound was always a tricky subject. I was aware that nullsound was included, but it barely did more than boot up and play a couple of samples (not to undermine the effort that went into nullsound of course!). For me that was not enough as I wanted a way to play music (finding a musician would of course be another, bigger task!).

Eventually I remembered Leonard's demo (https://www.pouet.net/prod.php?which=59253) in which he took advantage of the SSG inside the YM2610 and played a music which consisted of a register dumped tune from the Atari ST. This got me thinking how hard it would be to adapt an ST tracker routine which generates the register changes per VBL and send them to nullsound to be forwarded to the YM.

A few weeks ago I bit the bullet and started to implement this. For prototyping I used the ST replay routine for Arkos Tracker 2 that I made some time ago (https://github.com/ggnkua/Arkos-Tracker-2-ST/) and simply replaced the YM writes with a buffer mechanism, which then sent the registers/values to the z80, and at the end of transmission play them on the YM. I had to modify nullsound quite a bit, but eventually I succeeded! https://mastodon.gamedev.place/@ggn/111081639543250982

(As an aside, Arkos Tracker 2 - https://www.julien-nevo.com/arkostracker/ - has native z80 replay routines, so I'm pretty sure that they can be adapted to nullsound quite easily. I would use them if I could, but the musician who agreed to make music for the ST version does not use that tracker, so I'll have to modify that. Perhaps I will soon get in touch with the author, see if he's interested. I think it would be a cool thing if ngdevkit suddenly has audio capabilities!)

If you listen carefully to the music on that video linked above, you might spot some glitches. These happen partially because the tune is 50Hz, so in order to make it play at a normal speed in some frames I have to skip calling the music player (i.e. every 6th frame I skip a player call). The other more serious problem is that due to the complexity of the game, the processing can take multiple VBLs to execute. So if you notice carefully you'll realise that there are many glitches happening while things are moving around. Ideally I would have wanted to execute the music player routine inside ng_wait_vblank(), but this seems to be internal to the runtime, and I can't see a hook for that so I can call my own code. So, to tie this in with the issue's subject, would you consider adding a way to run some user defined code inside ng_wait_vblank()? Something like reading a pointer which, if not null, execute the routine that it points to.

Apologies for the long message, I tried to keep this as to the point as I could! Looking forward to your reply.

(For the record, I could have simply recompiled the runtime and added this functionality, but I thought it might benefit more people. If you want, I can also create a pull request with the proposed changes above)

(Also, if you're interested in adding my really bad music hacks as an example, I can make an effort to clean them up and send them to you. Or try to integrate the z80 Arkos routines into nullsound as a module)

ggnkua avatar Sep 25 '23 16:09 ggnkua