Discussion in 'Engineering & Reverse Engineering' started by Clownacy, Mar 31, 2014.
My mistake then Do you mind if I ask oyu a couple of quesitons on PM?
I can't PM a Pending member. If the questions are related to the driver, I'd prefer they be in this thread, anyway, so anyone with similar questions will already have an answer waiting for them.
I see this great piece of work and your notable activity (along wiht flamewing) on the GitHubs. Do you have any plan yourself to branch S1 AS or S2 Master with the driver pre-included?
No... I expect the user to do at least some work. The only reason the ProjectSonic1TwoEight branch is a thing is because a guide for it would have been insane.
I see, I was more interested into the rpeorting issues, and commit possibilities. The guide is clear, no problem.
My toruble is the new "s2p2bin.exe". The fresh GitMaster S2 works as-is, if I use it again I got the expected error of the osund driver being too big. When I use the s2p2bin.exe provided into the package, it asks for "libwinpthread-1.dll". After installing MinGW, it tells me that the applicaiton could not start. I'm using a x64 dev environnment, do you happened to use winX86?
EDIT: forget it, I found the trouble: this file was missing: http://opendll.com/index.php?file-download=libwinpthread-1.dll&arch=32bit&version=184.108.40.206&dsc=POSIX-WinThreads-for-Windows#
Right. I remember removing that from the S2 Git disasm because nothing was using it. How ironic. Anyway, updated the archive with the missing DLL. Thanks.
A bugfix and a new feature.
Added (proper, unlike S2!) fix for music interrupting SFX, causing distortion
Made .silencefm6 more like it was in S2's driver
Removed some instances where DAC is enabled with WriteFMI. Mega PCM can do that on its own
Allowed FM6 to enable itself, letting a song use both FM6 and DAC tracks (the channel itself alternates, so they can't run at the same time)
Removed some instances where DAC is disabled with WriteFMI. The above change means FM6 can do that on its own
Made PlaySega (68k mode) manually enable DAC
Previously, if you went to DEZ, started the fight with Silver Sonic, and revved the spin dash once before the boss music started, the rev sound would be muted. In even earlier versions, the sound would appear muted, but odd noises would be heard afterwards. S2, and recent versions of this driver, hid those noises by halting all SFX when music starts playing. With this version, the actual cause of the problem has been fixed, so, with the spin dash in DEZ, the SFX will continue playing as the boss music starts.
I've attempted to streamline DAC enabling/disabling, so now simply playing a note on FM6, or making Mega PCM play a sample, will enable/disable whatever needed. Theoretically, you can give a song both an FM6 and DAC track, and just have them play notes at different times, and it should all work.
Files changed from v2.4:
MegaPCM - 68k.asm
Sonic 2 Clone Driver v2 - Constants.asm
Sonic 2 Clone Driver v2.asm
Some cleanup and bugfixes
Removed redundant instructions under .silencefm6
Removed WriteFMIorIIMain, and merged its function into the one thing that used it, like S2's driver
Fixed PSG noise channel not shutting up when a new song starts
Rewrote PauseMusic to be more like it was in S2's driver
Fixed Mega PCM DAC samples not pausing properly (holy shit this has been here since v2.0)
Turns out Mega PCM has always had the ability to pause and resume samples. Oops. The fix for sound distortion in v2.4.1 lead to another bug, where, if a song is playing noise, and another song interrupts it, the noise will continue while it plays, and even after it ends. I wound up just forcing PSGNoteOff to silence noise along with PSG3. You can hear the bug by clearing an act in CNZ, where the End of Level music will play noise.
Files changed from v2.4.1:
Sonic 2 Clone Driver v2.asm
Don't know the best place to put this info, so I'll keep it here. It's relevant to the thread, anyway. Those who've ported S3K's DEZ1 to this driver, or any variant of SMPS 68k (S1's driver or S2's), may have noticed this static-y noise right before the song loops. This comes from how SMPS Z80 allows TL values to be marked as 'slots' regardless of the voice's algorithm. In SMPS 68k, they're directly tied to each other.
This is the voice in question in DEZ1:
; Voice $03
; $46, $04, $01, $60, $11, $52, $55, $D5, $0A, $06, $08, $08
; $08, $00, $09, $00, $89, $F8, $F9, $F8, $82, $88, $88, $88
The lower 3 bytes of $3D gives you the algorithm, which is 5. This means only operators 2, 3, and 4 are 'slots', however, the way the TL values are marked says otherwise.
$82, $88, $88, $88
These are the TL values. The sign bit means it's a 'slot'. Here, operators 1, 2, 3, and 4 are 'slots'. SMPS Z80 treats operator 1 as a 'slot', as the sign bit demands, but SMPS 68k won't, in accordance to the algorithm. This is why the voice plays wrong in SMPS 68k.
So, what if you just port the SMPS Z80 behaviour to SMPS 68k? Problem solved, right? Indeed, that would fix DEZ1... but it would break some S2 music.
Oddly enough, S2 has some TL values' sign bit set, even though it's never read, and doesn't match the algorithm. This is such a problem that S2 music will sound incorrect when ported to S3K's driver.
SMPS2ASM could probably be modified to make this a nonissue, but, just to be safe, I'll list all the instances I noticed in S2's music/SFX (S1 doesn't contain any of these):
Sound55 - "Sliding spike"
Sound5C - "Fire"
Ending, Voice 3
OOZ, Voice 0
Title screen, Voice 3
To fix these, simply remove the sign bit from all values in smpsVcTotalLevel. If SMPS2ASM determines that a sign bit is linked to the algorithm, it automatically removes them from smpsVcTotalLevel, leaving only these strange broken ones.
I need to do way more bugtesting.
Fixed hanging notes on music that doesn't define all tracks
Optimised some track RAM write looping
Added missing S3/S3D PSG envelopes
Overhauled SMPS2ASM PSG defining
Slightly lowered pitch on all DAC samples
Renamed DAC_Entry arguments to not conflict with comments
Removed support for other drivers from _smps2asm_inc.asm (a pain to maintain)
Updated sound driver disassembly (track RAM is better-defined)
Made some 'move' instructions safer
Made disabled coordination flags safer
Removed old unused SMPS 68k Type 1a track pointers
Made SFX_SFXChannelRAM and SFX_BGMChannelRAM word-sized
Ported SMPS Z80's TL handling, fixing S3K DEZ1 (bit 7 lets it be changed by volume)
Added support for transposition division overflow, fixing S3D intro (S3D uses these)
Shrinked FM_Notes, to allow for negative transpositions
Removed ReverseFreqs. It was fun while it lasted, but I'm not about to waste time figuring out how to make a negative shrunken FM_Notes
Corrected smpsVcTotalLevel errors in OOZ, Ending, and Title Screen
Corrected smpsVcTotalLevel errors in SFX 55 and 5C (D5 and DC)
Corrected FM5 channel transposition in SFX BC (Spin Dash release)
Added 'readme.txt' files to 'music' and 'SFX' folders, detailing bugfixes made and where to find SMPS2ASM
Added URLs to Mega PCM's thread at start of Mega PCM files
Split PSG volume envelopes to 'Sonic 2 Clone Driver v2 - PSG Volume Envelopes.asm'
Split FM Universal Voice Bank to 'Sonic 2 Clone Driver v2 - FM Universal Voice Bank.asm'
Slightly reordered data at end of driver
Added option to not include FM Universal Voice Bank
Added option to not include certain games' PSG volume envelopes
Fixed cfSetPSGTone when it's run on FM track (forgot to advance the track pointer)
Enhanced SMPS2ASM to ignore S3-specific smpsFade
Reverted bugged optimisations to PSG volume envelopes (fixes VVZ2)
Added support for negative track pointers, fixing SFX CC (holy cow, another one I haven't noticed since v2.0)
What did the original Clone Driver have over this one? A working SFX $EC ($CC in the S2 demo ROM).
Because this new version distinguishes between S3, S&K, and S3D-unique PSGs, certain SMPS files may need to be updated to use their correct names. sTone_04 is either sTone_04a (S3+S&K) or sTone_04b (S3D), and sTone_26 is either sTone_26a (S3) or sTone_26b (S&K+S3D). sTone_28 is an S3D-only envelope, as well.
Also, the '_smps2asm_inc.asm' include has been moved from the start of 'Sonic 2 Clone Driver v2.asm' to the start of your ROM, like this:
; Sonic 2 Clone Driver v2 flags and stuff
TargetDisasm = 1
; | 1 for Sonic 2 Git
; | 2 for Sonic 2 Xenowhirl
; | 3 for Sonic 1 Git
SegaPCM_68k = 0
; | If 0, the Z80 and Mega PCM handle the SEGA sample playback. If 1, the 68k handles it. I recommend Z80, as with the 68k version, if overclocked, the sound plays wrongly.
EnableContSFX = 0
; | If 1, include S3K's continuous SFX system.
First_ContSFX = $BC
; | Set this to the sound ID of your first continous SFX. This ID must be a higher number than any of your normal SFXes.
; | (Default value is S&K's)
include "sound/Sonic 2 Clone Driver v2 - Compatibility.asm"
include "sound/Sonic 2 Clone Driver v2 - Constants.asm"
Files changed from v2.4.2:
Sonic 2 Clone Driver v2 - Compatibility.asm
Sonic 2 Clone Driver v2 - Constants.asm
Sonic 2 Clone Driver v2.asm
PSG (just replace the entire folder)
music/84 - OOZ.asm
music/95 - SWEET SWEET SWEET.asm
music/99 - Title Screen.asm
SFX/BC - Spin Dash Release.asm
Sonic 2 Clone Driver v2 - FM Universal Voice Bank.asm
Sonic 2 Clone Driver v2 - PSG Volume Envelopes.asm
Also, I will never understand why you people download the demo ROMs more than the actual driver.
Sonic 2 Clone Driver v2 is now on GitHub!
While still a work-in-progress, there have been some pretty major changes since the last update. One noteworthy change is that music/SFX data like addresses, flags, priorities, and speed shoes tempos, all are grouped together in so-called 'metadata tables', to make adding or changing music/SFX easier. There's also been an attempt to abstract away parts of the driver, to make installation and use easier. For example, PlayMusic, SoundDriverLoad, and other subroutines, have been moved to a separate 'Functions' file in the sound folder, where I can change whatever I want, without the user needing to copy/paste the new version of PlaySoundStereo or whatever into their s2.asm/sonic.asm. Many parts of the driver have also been made 'disassembly-independent', making theoretical ports to S3K and the like easier.
Oh, and there's backwards-compatibility with the official SMPS2ASM, and MegaPCM's DPCM decoder has been sped up a bit. Just in case you were interested in hearing about actual features. Also, speaking of DAC, there's a branch that uses the original Mega PCM, instead of the custom one, in case you want the older version's higher playback speed, even at the cost of a few features.
It sure has been a while since the last update.
New DPCM tables were ported from SMPS-Treasure, speeding up DPCM loop (unlike SMPS-Treasure, these tables are generated by the DAC driver during initialisation, so they don't waste ROM like the volume table)
Made Spin Dash toggleable, so its code isn't assembled if you're not using it
Fixed bug during song initialisation that caused the last two sound queues to be accidentally cleared
Ported S2's version of Sound_Play (zCycleQueue)
Music/SFX/SpecSFX data has been merged into 'metadata tables', simplifying their addition or modification (for example, the music metadata table contains the music's pointer, speed-shoes tempo, and playback flags)
Restored compatibility with official (flamewing's) SMPS2ASM
All tracks use zTrack.VoicePtr now (saves some RAM)
Overall RAM cleanup
Some Z80 access was made 'safe' (interrupt can't interrupt Z80 bus request, and accidentally deassert it)
Fixed OOZ oil slide SFX (was updating FM volume on a PSG channel)
Added check to prevent above bug from having any negative effects, just like S2's driver
A branch is available that uses the stock v1.1 MegaPCM
There's also been a huge overhaul to the driver's file structure, and an attempt has been made to abstract away driver interaction, allowing me to make whatever under-the-hood changes I need, without the user needing to update segments of their s2.asm/sonic.asm themselves. Things such as speeding up the music, queueing a sound, or updating the driver, have all either been split into separate ASM files, or turned into macros. The installation guides have been overhauled for this new setup.
Since the driver's now on GitHub, I don't know if I'll be announcing 'versions' like this anymore. All changes will be pushed to GitHub when they're made, so you can fetch the latest version whenever you feel. For this update, like the others before it, I've done a fair amount of bugtesting, so perhaps it's a choice between stable and unstable releases.
I'm gonna cut right to the chase.
Support for the 32X
Support for four PWM tracks
Fixed bug where Special SFX incorrectly mute PSG3 while it's being used by SFX (thanks, Markey)
Added proper volume cap check to DoFadeIn (thanks again, Markey)
Fixed bug where PSG 1&2 are not muted during SFX initialisation (Markey, stop, please)
Added a bugfix from S2's driver that stops cfStopTrack from altering the stack too much on DAC channels
Tried to reduce name collision with MegaPCM by adding a prefix to most labels
UpdateDAC has been restructured, so its stack usage is identical to FM and PSG (kind of undoing that last bugfix /> )
Made MegaPCM check that YM2612 isn't busy before enabling DAC (fixes muted drums at start of some songs)
SFX now properly update on the frame that a new song is played
So... yeah, PWM playback. I've gotten most of the ranting out of my system in the description of those YouTube videos, but I'll still list some details here (keep in mind, my terminology might be incorrect):
The SH2-based PWM driver itself is ripped straight out of Knuckles' Chaotix. It software-mixes four PWM channels, with stereo panning support, and a maximum sample rate of 11025Hz (which is interpolated to 22050Hz). This puts it at a bit of a disadvantage over the stock DAC driver from the likes of S1, whose Snare sample has a rate of roughly 22kHz, and the driver fully supports it. In that top video, I actually had to downsample the Snare to get it to play at full speed, and there's a noticeable quality drop. I might be able to modify the driver to remove that limitation at some point, and maybe even add support for more than 4 channels, but for now the PWM driver is entirely vanilla.
The PWM code can easily be 'plugged in' to an existing 32X project: on the SH2 side, the driver just needs to be called on every PWM interrupt, and the driver itself needs loading into the Cache on boot. To demonstrate this, I've included a 'stub SH2' program, based on Gardeguey's SH2 code (available as part of his Sonic 1 32X port), which only runs the PWM driver.
As you can see in the top video, also included is rudimentary support for PWM SFX: simply call the SMPS_PlayPWMSample function, and you can play any sample you want, at any volume/pan you want, on any channel you want. Right now, there's no priority system, so make sure to not play an SFX on a channel the music is using.
Also, yes, as the second video shows, Chaotix music can now be ported to the driver. But don't just use my driver because it's easy to port music to; it's 68k-based for crying out loud. Anyway, to dump Chaotix songs, I have a rough edit of SMPS2ASM here. A pre-converted set of Chaotix music is included with the driver.
On a related note, I've had to expand SMPS2ASM's format to support PWM tracks, while maintaining backwards compatibility with non-32X songs:
Standard SMPS2ASM header
smpsHeaderChan $06, $03
smpsHeaderTempo $02, $06
smpsHeaderFM Mus82_LZ_FM1, $F4, $0C
smpsHeaderFM Mus82_LZ_FM2, $E8, $0D
smpsHeaderFM Mus82_LZ_FM3, $F4, $18
smpsHeaderFM Mus82_LZ_FM4, $F4, $18
smpsHeaderFM Mus82_LZ_FM5, $00, $12
smpsHeaderPSG Mus82_LZ_PSG1, $D0, $02, $00, fTone_09
smpsHeaderPSG Mus82_LZ_PSG2, $D0, $02, $00, fTone_09
smpsHeaderPSG Mus82_LZ_PSG3, $00, $02, $00, fTone_04
Expanded SMPS2ASM 32X header
smpsHeaderChan $07, $03, $04
smpsHeaderTempo $01, $25
smpsHeaderFM DoorIntoSummer_FM1, $00, $09
smpsHeaderFM DoorIntoSummer_FM2, $0C, $10
smpsHeaderFM DoorIntoSummer_FM3, $0C, $10
smpsHeaderFM DoorIntoSummer_FM4, $00, $10
smpsHeaderFM DoorIntoSummer_FM5, $00, $10
smpsHeaderFM DoorIntoSummer_FM6, $00, $10
smpsHeaderPSG DoorIntoSummer_PSG1, $F4, $00, $00, KCVolEnv_0C
smpsHeaderPSG DoorIntoSummer_PSG2, $F4, $03, $00, KCVolEnv_0C
smpsHeaderPSG DoorIntoSummer_PSG3, $23, $01, $00, KCVolEnv_02
smpsHeaderPWM DoorIntoSummer_PWM1, $00, $99
smpsHeaderPWM DoorIntoSummer_PWM2, $00, $AA
smpsHeaderPWM DoorIntoSummer_PWM3, $00, $99
smpsHeaderPWM DoorIntoSummer_PWM4, $00, $99
First, there is the new smpsHeaderPWM (which just redirects to smpsHeaderFM, since they have the same variables), which is straight from Chaotix. And a new new feature, that isn't from Chaotix, is the added third value for smpsHeaderChan: the PWM channel count. Chaotix was hardcoded to expect every song to have four channels, which would be a pain to work around. Instead, a song has however many tracks you say it has. It's completely safe to leave the PWM count blank, instead of setting it to $00, like in a normal header. Support for removing the DAC track, however, has not been ported (in fact, the modified SMPS2ASM just inserts dummy DAC data into Chaotix dumps, for compatibility).
Do note, I haven't tested this thoroughly on hardware, since I don't own a 32X myself. But if someone would like to test it for me, I'd appreciate it (don't mind that all levels but GHZ crash, I just stripped out a lot of other zones' data while porting). The PWM's too quiet on Gens Rerecording (emulator bug?), and a separate possible emulator bug in Gens/GS causes the left speaker to be muted until the first PWM sample is played. I did get MarkeyJester to hardware-test for this specific bug (betcha didn't know what that ROM was for, at the time ;P), and it didn't seem to occur there, which is why I think these all are emulator things. PWM works fine in Kega, though.
The Compatibility flags SMPS_IsOn32X and SMPS_EnablePWM have been added, to enable all this. SMPS_IsOn32X is separate because it fixes Mega PCM to work on the 32X, while SMPS_EnablePWM, well, enables PWM. Just in case you wanted to go the DOOM route, and be on the 32X, and not use the PWM for... some reason.
For anyone who does use the 32X, you'll have to include more than one file this time: include "sound/Sonic 2 Clone Driver v2.asm" should still be done, and contains all the 68k and Z80 stuff. However, you will need to do 'include "sound/Sonic 2 Clone Driver v2 - PWM Driver.asm" and (if you're using the stub 32X program) include "sound/Sonic 2 Clone Driver v2 - Stub SH2.asm", also. This is so the SH2 stuff and 68k/Z80 stuff can be moved around separately, to fit your bank layout.
As for the Stub 32X program itself, its ROM address is defined as 'SH2_Start', its length is 'SH2_Length', and the entry points and VBRs are as follows:
dc.l SH2_Entry ; Master SH2 initial PC
dc.l s_EntryPoint ; Slave SH2 initial PC
dc.l SH2_Master ; Master SH2 initial VBR address
dc.l SH2_Slave ; Slave SH2 intitial VBR address
Aaaand... yeah. I think that's all.
Why no love and support for the current version of Project Sonic 1 Two-Eight? It has no AS version, which sort of blocks me to switching to this.
And that's my problem how? AS has been a requirement since literally day 1. I can't just conjure an asm68k version out of thin air. If you knew how to use Git, you'd know it's easy to combine the AS and Two-Eight branches, anyway.
I Love what you've done with the Driver!
Unfortunately, I've kinda abandoned the thought of a 68k Driver, since I'm now heavily concerned about performance over audio quality, but if 32x support was more widespread, I'd love to incorperate something like this.
So, Knockles Chaotix uses a 68k sound driver then, or is that on the SH processors?
Neither? Chaotix uses the same type of driver as S3K. Made by the same person too, I think. Z80 handles FM and PSG playback, while the SH-2 does PWM. All the 68k does is act as a relay between the two.
I wouldn't worry too much about performance in relation to the sound driver.
There was a big hoo-har a year or two back where the argument for using a z80 driver over a 68k driver was, CPU speed/performance. After heavy tests, the average total game time the sound driver took, was in fact 3.6% of the CPU. If you have so much going on that the game will start lagging with the 68k driver, then there's a huge chance that the game will still lag with the driver removed, since it's a really small window of performance improvement.
This is not to deter you from moving towards a z80 driver however, I do recommend it, but not for performance reasons, you also free up about 3% of RAM in the process (which is roughly 600-700 bytes), 3% of RAM is more beneficial to you than 3% of CPU speed, lag is an acceptable by-product of games for the Mega Drive, people will understand. It does come at a cost of course, the cost of digital audio quality, no matter how well the z80 driver is written, there will always be gaps in the PCM playback causing distortions, but some do a pretty good job considering. The issue should be whether or not you need the RAM space, if you need better performance, your efforts and time are better spent improving other aspects of the engine, you'll get more CPU time gain from that.
You make a strong argument for the 68k - I know RAM space is very important, but it's not really within the scope of my current project to do anything to necessitate the.. $6A0 bytes, I believe, of RAM. Right now, the $500 empty bytes from vanilla Sonic 2 are unused in my hack as is, unless I use the build option to record demos anyway.
Knowing that, and the fact that the loss of quality of DAC/PCM using a Z80 continually annoys my OCD tendencies, I probably am better off using a 68k Driver, like the Clone Driver here... But I'm still not sure about that.
Going back to what Clownacy said, I'm kind of surprised by that. It seems like given the power of the SH processors, it would've made total sense to use a 68k driver, since they wouldn't have to worry about it being bottlenecked as easily... But it is what it is, and I'm not a professional programmer, so there's probably a reason for it I'm not aware of.
EDIT: I just looked at the main post again.. It only needs $39B bytes now. That works for me!
Uhh, Chaotix only uses the SH2 for PWM, and 32X graphics. The game engine still runs on the 68k.
Separate names with a comma.