Add global offset

Adds new settings for controlling the note offset while playing. It can be either an actual offset (it is called "Audio Latency" in the settings) or just the visual offset ("Video Latency").
With higher audio latency it means you have to press the button sooner than what you hear, similarly with higher video latency it is sooner than what you see. By offsetting these events the game would play better, however, the sound effect of you hitting the drum would still play at the wrong time, the code cannot anticipate you to hit the drum in the future so to work around this issue a new option that disables drum sounds is also included.
These settings could be set through trial and error but it would be better to get the correct values through the automated latency calibration, where you can hit the drum as you hear sounds or see a blinking animation. I tried making one by measuring latency from user input, adding all the latency up, and dividing, but that gives unreliable results. I hope someone suggests to me what I should be doing during the calibration to get better results, as I cannot figure what to do on my own.
This commit is contained in:
LoveEevee
2019-11-28 09:04:40 +03:00
parent 7a50dec558
commit ff09cb83bd
20 changed files with 1579 additions and 313 deletions

View File

@@ -5,6 +5,14 @@ class SongSelect{
loader.changePage("songselect", false)
this.canvas = document.getElementById("song-sel-canvas")
this.ctx = this.canvas.getContext("2d")
var resolution = settings.getItem("resolution")
var noSmoothing = resolution === "low" || resolution === "lowest"
if(noSmoothing){
this.ctx.imageSmoothingEnabled = false
}
if(resolution === "lowest"){
this.canvas.style.imageRendering = "pixelated"
}
this.songSkin = {
"selected": {
@@ -207,13 +215,13 @@ class SongSelect{
}]
this.optionsList = [strings.none, strings.auto, strings.netplay]
this.draw = new CanvasDraw()
this.songTitleCache = new CanvasCache()
this.selectTextCache = new CanvasCache()
this.categoryCache = new CanvasCache()
this.difficultyCache = new CanvasCache()
this.sessionCache = new CanvasCache()
this.currentSongCache = new CanvasCache()
this.draw = new CanvasDraw(noSmoothing)
this.songTitleCache = new CanvasCache(noSmoothing)
this.selectTextCache = new CanvasCache(noSmoothing)
this.categoryCache = new CanvasCache(noSmoothing)
this.difficultyCache = new CanvasCache(noSmoothing)
this.sessionCache = new CanvasCache(noSmoothing)
this.currentSongCache = new CanvasCache(noSmoothing)
this.difficulty = [strings.easy, strings.normal, strings.hard, strings.oni]
this.difficultyId = ["easy", "normal", "hard", "oni", "ura"]
@@ -234,6 +242,9 @@ class SongSelect{
fromTutorial = false
}
this.drumSounds = settings.getItem("latency").drumSounds
this.playedSounds = {}
var songIdIndex = -1
if(fromTutorial){
this.selectedSong = this.songs.findIndex(song => song.action === fromTutorial)
@@ -252,7 +263,7 @@ class SongSelect{
}else if((!p2.session || fadeIn) && "selectedSong" in localStorage){
this.selectedSong = Math.min(Math.max(0, localStorage["selectedSong"] |0), this.songs.length - 1)
}
assets.sounds[songIdIndex !== -1 ? "v_diffsel" : "v_songsel"].play()
this.playSound(songIdIndex !== -1 ? "v_diffsel" : "v_songsel")
snd.musicGain.fadeOut()
this.playBgm(false)
}
@@ -436,7 +447,7 @@ class SongSelect{
window.open(this.songs[this.selectedSong].maker.url)
}else if(moveBy === this.diffOptions.length + 4){
this.state.ura = !this.state.ura
assets.sounds["se_ka"].play()
this.playSound("se_ka")
if(this.selectedDiff === this.diffOptions.length + 4 && !this.state.ura){
this.state.move = -1
}
@@ -564,7 +575,7 @@ class SongSelect{
var soundsDelay = Math.abs((scroll + resize) / moveBy)
for(var i = 0; i < Math.abs(moveBy) - 1; i++){
assets.sounds["se_ka"].play((resize + i * soundsDelay) / 1000)
this.playSound("se_ka", (resize + i * soundsDelay) / 1000)
}
this.pointer(false)
}
@@ -574,7 +585,7 @@ class SongSelect{
this.state.move = moveBy
this.state.moveMS = this.getMS() - 500
this.state.locked = 1
assets.sounds["se_ka"].play()
this.playSound("se_ka")
}
}
@@ -605,15 +616,15 @@ class SongSelect{
this.selectedDiff = this.diffOptions.length + 3
}
assets.sounds["se_don"].play()
this.playSound("se_don")
assets.sounds["v_songsel"].stop()
assets.sounds["v_diffsel"].play(0.3)
this.playSound("v_diffsel", 0.3)
pageEvents.send("song-select-difficulty", currentSong)
}else if(currentSong.action === "back"){
this.clean()
this.toTitleScreen()
}else if(currentSong.action === "random"){
assets.sounds["se_don"].play()
this.playSound("se_don")
this.state.locked = true
do{
var i = Math.floor(Math.random() * this.songs.length)
@@ -650,7 +661,7 @@ class SongSelect{
this.state.moveHover = null
assets.sounds["v_diffsel"].stop()
assets.sounds["se_cancel"].play()
this.playSound("se_cancel")
}
this.clearHash()
pageEvents.send("song-select-back")
@@ -659,7 +670,7 @@ class SongSelect{
this.clean()
var selectedSong = this.songs[this.selectedSong]
assets.sounds["v_diffsel"].stop()
assets.sounds["se_don"].play()
this.playSound("se_don")
try{
if(assets.customSongs){
@@ -698,7 +709,7 @@ class SongSelect{
}
toOptions(moveBy){
if(!p2.session){
assets.sounds["se_ka"].play()
this.playSound("se_ka")
this.selectedDiff = 1
do{
this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy)
@@ -707,7 +718,7 @@ class SongSelect{
}
toTitleScreen(){
if(!p2.session){
assets.sounds["se_cancel"].play()
this.playSound("se_cancel")
this.clean()
setTimeout(() => {
new Titlescreen()
@@ -715,21 +726,21 @@ class SongSelect{
}
}
toTutorial(){
assets.sounds["se_don"].play()
this.playSound("se_don")
this.clean()
setTimeout(() => {
new Tutorial(true)
}, 500)
}
toAbout(){
assets.sounds["se_don"].play()
this.playSound("se_don")
this.clean()
setTimeout(() => {
new About(this.touchEnabled)
}, 500)
}
toSettings(){
assets.sounds["se_don"].play()
this.playSound("se_don")
this.clean()
setTimeout(() => {
new SettingsView(this.touchEnabled)
@@ -744,7 +755,7 @@ class SongSelect{
}else{
localStorage["selectedSong"] = this.selectedSong
assets.sounds["se_don"].play()
this.playSound("se_don")
this.clean()
setTimeout(() => {
new Session(this.touchEnabled)
@@ -755,7 +766,7 @@ class SongSelect{
if(assets.customSongs){
assets.customSongs = false
assets.songs = assets.songsDefault
assets.sounds["se_don"].play()
this.playSound("se_don")
this.clean()
setTimeout(() => {
new SongSelect("browse", false, this.touchEnabled)
@@ -984,7 +995,7 @@ class SongSelect{
var scroll = resize2 - resize - scrollDelay * 2
var elapsed = ms - this.state.moveMS
if(this.state.move && ms > this.state.moveMS + resize2 - scrollDelay){
assets.sounds["se_ka"].play()
this.playSound("se_ka")
var previousSelectedSong = this.selectedSong
this.selectedSong = this.mod(this.songs.length, this.selectedSong + this.state.move)
if(previousSelectedSong !== this.selectedSong){
@@ -2041,6 +2052,17 @@ class SongSelect{
}
}
playSound(id, time){
if(!this.drumSounds && (id === "se_don" || id === "se_ka" || id === "se_cancel")){
return
}
var ms = Date.now() + (time || 0) * 1000
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
assets.sounds[id].play(time)
this.playedSounds[id] = ms
}
}
getMS(){
return Date.now()
}