Syncing This Movie
This game has major sync problems. Sync for this TAS is dependent on video hardware, and so far it looks like
only Intel UHD integrated graphics will sync the movie at native 320x240 resolution, on BizHawk 2.4. Both UHD 620 and UHD 630 have been tested and verified to sync. If you want to try to sync the movie, let me know the results so that they can be added here for posterity.
Configurations Tested
Intel Core i7-8550U Intel UHD 620 **Full Sync**
Intel Core i7-4600K Nvidia GTX 980 Ti Desync on lap 2 of DR
Intel Core i5-3470 Radeon HD 7000 Desync on lap 1 of GVG
Intel Core i7-10750H Intel UHD 630 **Full Sync**
Intel Core i7-6700HQ Nvidia GTX 1060 Desync at 73k
Intel Core i7-9700K Intel UHD 630 **Full Sync**
Intel Core i5-7300U Intel HD 620 Desync on 3099
AMD Ryzen 5 1600X Radeon RX 5700 XT Desync on 3099
Intel Core i7-7700 Radeon RX 470 Desync on lap 1 of GVG
Encoding
Unfortunately, this game represents a
pathologically bad case for the mupen64+ core for both sync and encoding. To create a good SD encode of this run, the following must be done:
- Dump the movie using clock sync. Discard the audio from this dump as it will be useless.
- Dump the movie using alt. sync. Discard the video from this dump as it will be useless.
- Encode the audio dump via the Avisynth script below to get an audio track that syncs up with the video
- If using the tasvideos.org publishing scripts or just avisynth in general, swaudio.avs can just be loaded via wavsource("swaudio.avs") and then dubbed with audiodub onto the video source.
- Otherwise, just encode the swaudio.avs script directly using something like FFmpeg.
- Encode the video
- Mux
For high resolution encodes, the movie will almost certainly not sync at higher resolutions than native. To get around this, these scripts and techniques will need to be used:
/Zinfidel/SyncScripts.html. Overall the encoding process is the same as above, except that video from the first step must be produced via the syncing scripts technique.
Language: avisynth
# SET ME TO THE AUDIO DUMP
audio = "swaudio2.wav"
global feeps = 60000/1001
function ba(float duration) {
return BlankClip(fps=feeps, length=int(feeps*duration), audio_rate=44100, channels=2).KillVideo()
}
function buffer(clip c, float ts) {
return c + ba(ts - c.AudioDuration)
}
function fbuffer(clip c, int frames) {
return c + ba(frames/59.94) # 59.94 is inaccurate and was a mistake but must remain for timing to work.
}
# Offset audio to actual start point
global aud = ba(4.79) + WavSource(audio)
global sliceTS = 0.0
function nextSlice(float duration) {
newSliceTS = sliceTS + duration
ret = aud.AudioTrim(sliceTS, newSliceTS)
global sliceTS = newSliceTS
return ret
}
cut = nextSlice(36.003)
cut = cut.buffer(36.889)
cut = cut + nextSlice(331.48).ConvertAudioToFloat().TimeStretch(rate=99.919)
cut = cut.buffer(368.81)
cut = cut + nextSlice(21.11)
cut = cut.buffer(390.19)
cut = cut + nextSlice(141.15).ConvertAudioToFloat().TimeStretch(rate=99.90)
cut = cut + nextSlice(31.2)
cut = cut.fbuffer(67)
cut = cut + nextSlice(292.1).ConvertAudioToFloat().TimeStretch(rate=99.88)
cut = cut + nextSlice(7.0)
cut = cut.fbuffer(41)
cut = cut + nextSlice(240.2).ConvertAudioToFloat().TimeStretch(rate=99.90)
cut = cut + nextSlice(12.58)
cut = cut.fbuffer(34)
cut = cut + nextSlice(135.08).ConvertAudioToFloat().TimeStretch(rate=99.92)
cut = cut + nextSlice(7.1)
cut = cut.fbuffer(60)
cut = cut + nextSlice(331).ConvertAudioToFloat().TimeStretch(rate=99.89)
cut = cut + nextSlice(7)
cut = cut.fbuffer(26)
cut = cut + nextSlice(292.2).ConvertAudioToFloat().TimeStretch(rate=99.88)
cut = cut + nextSlice(45.15)
cut = cut.fbuffer(8)
cut = cut + nextSlice(37.21)
cut = cut.fbuffer(25)
cut = cut + nextSlice(56)
cut = cut.fbuffer(28)
cut = cut + nextSlice(75)
cut = cut.fbuffer(43)
cut = cut + nextSlice(135)
cut = cut.fbuffer(48)
cut = cut + nextSlice(70)
cut