diff --git a/.gitignore b/.gitignore index ceb37e6..c4b39bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /XDUData / web.config +/Js/Typed diff --git a/Css/main.css b/Css/main.css index fd90aaa..a618643 100644 --- a/Css/main.css +++ b/Css/main.css @@ -41,11 +41,15 @@ .centered { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; } -#app-container { position: relative; width: 1334px; height: 750px; } +.hidden { opacity: 0; } + +.shown { opacity: 0; } + +#app-container { position: relative; width: 1334px; height: 750px; display: flex; justify-content: center; align-items: center; } #parent-container { display: flex; flex-direction: column; align-items: center; } -#text-container { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; height: 750px; width: 1334px; font-family: 'FOT-RodinNTLGPro'; } +#text-container { position: absolute; margin: auto; height: 750px; width: 1334px; font-family: 'FOT-RodinNTLGPro'; } #text-container #title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; font-size: 20px; transition: opacity 0.3s; } @@ -59,10 +63,32 @@ #dialog-box #character { position: absolute; top: -5px; left: 70px; font-size: 30px; } -#dialog-box #dialog { overflow: hidden; position: absolute; padding: 0 30px 0 70px; margin-top: 60px; box-sizing: border-box; height: 120px; width: 100%; font-size: 30px; line-height: 60px; } +#dialog-box #dialog { overflow: hidden; position: absolute; padding: 0 30px 0 70px; margin-top: 60px; box-sizing: border-box; height: 120px; width: 100%; font-size: 28px; font-weight: normal; line-height: 68px; } + +#dialog #dialog-inner { max-width: 1125px; } + +#dialog b { font-weight: bold; } #dialog-box #ui-buttons { right: 20px; top: -50px; position: absolute; } #dialog-box .ui-button { position: relative; height: 85px; } -#other-controls-container { display: flex; width: 100; justify-content: center; } \ No newline at end of file +#dialog #dialog-controls { position: fixed; right: 0; display: flex; height: 135px; align-items: center; } + +#dialog-controls #dialog-next { margin-right: 37px; } + +#dialog-next img { height: 80px; } + +#dialog-controls #dialog-scroll { display: flex; flex-direction: column; height: 80px; margin-right: 30px; justify-content: space-between; } + +#dialog-scroll #dialog-scroll-up { transform: scale(1, -1); } + +#dialog-scroll img { height: 35px; } + +#other-controls-container { display: flex; width: 100; justify-content: center; } + +#select-mission { max-width: 300px; } + +#volume-control { display: flex; margin-right: 10px; } + +#volume-control #mute-button { cursor: pointer; } \ No newline at end of file diff --git a/Images/next_icon.png b/Images/next_icon.png new file mode 100644 index 0000000..10b3e4e Binary files /dev/null and b/Images/next_icon.png differ diff --git a/Js/Audio.js b/Js/Audio.js index 43ee13b..78e18f2 100644 --- a/Js/Audio.js +++ b/Js/Audio.js @@ -61,15 +61,68 @@ class bufferLoader { } }); } + + resetAll() { + this.bufferList = {}; + } } class audioController { - constructor() { + constructor(utage) { + this.utage = utage; this.volume = 1.0; this.muted = false; this.audioCtx = new (window.AudioContext || window.webkitAudioContext)(); this.gainNode = this.audioCtx.createGain(); + this.gainNode.connect(this.audioCtx.destination); this.loader = undefined; + this.sources = {}; + } + + playSound(sound, type) { + if(!this.loader.bufferList[sound]) { + return; + } + let source = this.audioCtx.createBufferSource() + this.sources[sound] = source; + source.buffer = this.loader.bufferList[sound]; + source.loop = false; + if(type === "bgm") { + if(this.utage.bgmLoopData[this.utage.soundInfo[sound].origFileName]) { + let loop = this.utage.bgmLoopData[this.utage.soundInfo[sound].origFileName]; + source.loopStart = loop["loop_start"]["seconds"]; + source.loopEnd = loop["loop_end"]["seconds"]; + source.loop = true; + } + } + source.connect(this.gainNode); + source.onended = () => { + if(!this.sources[sound]) { return; } + this.sources[sound].disconnect(this.gainNode); + this.sources[sound] = undefined; + } + source.start(0); + } + + stopSound(sound) { + if(sound === 'bgm') { + for(let sKey of Object.keys(this.sources)) { + try { + if(!sKey.startsWith('bgm')) { continue; } + let s = this.sources[sKey]; + s.stop(); + s.disconnect(this.gainNode); + s = undefined; + } catch (error) { } + } + } else { + if(!this.sources[sound]) { + return; + } + this.sources[sound].stop(); + this.sources[sound].disconnect(this.gainNode); + this.sources[sound] = undefined; + } } changeVolume(vol) { @@ -79,10 +132,14 @@ class audioController { } } - mute() { - this.muted = !this.muted; + mute(mute) { + if(mute != undefined) { + this.muted = mute; + } else { + this.muted = !this.muted; + } if(this.muted) { - this.gainNode.gain.setValueAtTime(0, athis.udioCtx.currentTime); + this.gainNode.gain.setValueAtTime(0, this.audioCtx.currentTime); } else { this.gainNode.gain.setValueAtTime(this.volume, this.audioCtx.currentTime); } @@ -96,4 +153,20 @@ class audioController { }); this.loader.load(); } + + resetAll() { + if(this.loader) { + this.loader.resetAll(); + this.loader = undefined; + } + for(let sKey of Object.keys(this.sources)) { + let s = this.sources[sKey]; + try { + s.stop(); + s.disconnect(this.gainNode); + s = undefined; + } catch(error) { } + } + this.sources = {}; + } } \ No newline at end of file diff --git a/Js/Common.js b/Js/Common.js index 725f2e5..2f62a75 100644 --- a/Js/Common.js +++ b/Js/Common.js @@ -85,6 +85,13 @@ class commonFunctions { case "sqrt": t = Math.sqrt(t); break; + //Some of the stuff here is just kinda arbitrary + case "dampsin": + t = (1 * (Math.pow(0.3, t)) * Math.sin((2*Math.PI*t/0.5) + 0)) / 1.25; + if(t < -0.45) { + t = -0.45; + } + break; } return (1 - t) * start + t * end; //-(2*x-1)^4 +1 @@ -165,7 +172,7 @@ class commonFunctions { return {x, y}; } - static getPropertiesFromTweenCommand(props) { + static getPropertiesFromTweenCommand(props, reverseY = true) { var retval = {}; let indexX = props.indexOf("x="); if(indexX !== -1) { @@ -183,7 +190,7 @@ class commonFunctions { if(props[i] == " ") { break; } retval.y += props[i]; } - retval.y = -Number(retval.y); + retval.y = reverseY ? -Number(retval.y) : Number(retval.y); } let indexT = props.indexOf("time="); if(indexT !== -1) { @@ -212,6 +219,15 @@ class commonFunctions { } retval.alpha = Number(retval.alpha); } + let indexS = props.indexOf("speed="); + if(indexS !== -1) { + retval.speed = ""; + for(let i = indexS + 6; i < props.length; ++i) { + if(props[i] == " ") { break; } + retval.speed += props[i]; + } + retval.speed = Number(retval.speed); + } return retval; } } \ No newline at end of file diff --git a/Js/Main.js b/Js/Main.js index 3b9d2fe..6d45bfc 100644 --- a/Js/Main.js +++ b/Js/Main.js @@ -7,7 +7,7 @@ const pixiApp = { const utage = new UtageInfo(); const textFunc = new TextFunctions(); -const audio = new audioController(); +const audio = new audioController(utage); const player = new Player(pixiApp, utage, textFunc, audio); const context = new (window.AudioContext || window.webkitAudioContext)(); const languages = ["eng", "jpn"]; @@ -17,6 +17,8 @@ let selectedLang = "eng"; let screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); let screenSizeTimeout = undefined; +let isMuted = false; +let volume = 0.5; function onBodyLoaded() { bodyLoaded = true; @@ -38,6 +40,19 @@ function onBodyLoaded() { (function checkIsLoaded() { if(bodyLoaded) { document.getElementById('loading-font').style.cssText = "display: none;"; + volume = localStorage.getItem('volume') || 0.5; + volume = Number(volume); + audio.changeVolume(volume); + document.getElementById('volume-range').value = volume * 100; + isMuted = localStorage.getItem('ismuted') || false; + if(isMuted === "false") { isMuted = false; } + else if(isMuted === "true") { isMuted = true; } + audio.mute(isMuted); + if(isMuted) { + document.getElementById('mute-button').innerText = "🔇"; + } else { + document.getElementById('mute-button').innerText = "🔊"; + } } if(utageLoaded) { document.getElementById('loading-utage').style.cssText = "display: none;"; @@ -115,6 +130,35 @@ function hideUiClicked(event) { player.hideUiClicked(event); } +function dialogScrollUp(event) { + event.preventDefault(); + event.stopPropagation(); + textFunc.scrollTextUp(); +} + +function dialogScrollDown(event) { + event.preventDefault(); + event.stopPropagation(); + textFunc.scrollTextDown(); +} + +function toggleMute(event) { + isMuted = !isMuted; + audio.mute(isMuted); + localStorage.setItem('ismuted', isMuted); + if(isMuted) { + document.getElementById('mute-button').innerText = "🔇"; + } else { + document.getElementById('mute-button').innerText = "🔊"; + } +} + +function onVolumeChange(event) { + let vol = event.currentTarget.value / 100; + audio.changeVolume(vol); + localStorage.setItem('volume', vol); +} + function onWindowResize(event) { if(screenSizeTimeout) { clearTimeout(screenSizeTimeout); diff --git a/Js/Player.js b/Js/Player.js index 96c29b8..55e5b0c 100644 --- a/Js/Player.js +++ b/Js/Player.js @@ -32,6 +32,7 @@ class Player { this.center = {x: ((baseDimensions.width / 2) * this.resolutionScale), y: ((baseDimensions.height / 2) * this.resolutionScale) }; this.assetLoadPercent = 0; this.audioLoadPercent = 0; + this.playingVoice = undefined; } playFile() { @@ -162,8 +163,6 @@ class Player { //center the position of the container then offset it by the value in the layer info let x = (((baseDimensions.width / 2) + Number(l.X)) * this.resolutionScale); let y = (((baseDimensions.height / 2) - Number(l.Y)) * this.resolutionScale); - //let x = (Number(l.X) * this.resolutionScale); - //let y = (Number(l.Y) * this.resolutionScale); cont.position.set(x, y); cont.visible = false; } @@ -249,8 +248,7 @@ class Player { //Loop through the lerp targets, modify the needed objects. If a object is at its 1 time state remove it from the list. let toRemove = []; for(let i = 0; i < this.lerpTargets.length; ++i) { - try - { + try { let l = this.lerpTargets[i]; l.curTime += deltaTime; if(l.curTime < 0) { continue; } @@ -264,17 +262,41 @@ class Player { continue; } } - let newValue = commonFunctions.lerp(l.initV, l.finalV, pos, inter); - let split = l.type.split("."); - switch(split.length) { - case 1: - l.object[split[0]] = newValue; + switch(l.type) { + case "shake": { + if(pos === 1) { + if(l.object instanceof HTMLElement) { + l.object.style = ""; + } else { + l.object.position.set(l.initV.x, l.initV.y); + } + } else { + let x = Math.floor(Math.random() * (l.finalV.x * (1-pos))); + let y = Math.floor(Math.random() * (l.finalV.y * (1-pos))); + if(l.object instanceof HTMLElement) { + l.object.style = `transform: translate(${x}px, ${y}px);`; + } else { + l.object.position.set(x, y); + } + } break; - case 2: - l.object[split[0]][split[1]] = newValue; + } + default: { + let newValue = commonFunctions.lerp(l.initV, l.finalV, pos, inter); + let split = l.type.split("."); + if(split[0] == 'scale') { debugger; } + switch(split.length) { + case 1: + l.object[split[0]] = newValue; + break; + case 2: + l.object[split[0]][split[1]] = newValue; + break; + default: + continue; + } break; - default: - continue; + } } } catch(error) { //If we got an exception during this it probably means the object doesnt exist anymore so just remove it. @@ -418,14 +440,26 @@ class Player { this.processTween(delta, cur); break; case "bgm": + if(!this.utage.soundInfo[cur.Arg1]) { + break; + } + this.audio.playSound(cur.Arg1, 'bgm'); break; case "stopbgm": + this.audio.stopSound('bgm'); break; case "se": + if(!this.utage.soundInfo[cur.Arg1]) { + break; + } + this.audio.playSound(cur.Arg1, 'se'); break; - case "shake": + case "shake": { + this.processShake(delta, cur); break; + } case "henshin01_bgmoff": + this.audio.stopSound('bgm'); this.checkPutCharacterScreen(cur, true); break; default: @@ -500,8 +534,11 @@ class Player { lay.container.visible = true; } } - + checkPutText(cur) { + if(this.playingVoice) { + this.audio.stopSound(this.playingVoice); + } if(!cur.Command && cur.Arg1 && cur.Text) { //If its chracter off screen text var text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text; @@ -541,6 +578,10 @@ class Player { this.text.dialogText(true, commonFunctions.convertUtageTextTags(text)); this.manualNext = true; } + if(cur.Voice) { + this.playingVoice = cur.Voice; + this.audio.playSound(cur.Voice); + } } processTween(delta, cur) { @@ -587,24 +628,43 @@ class Player { } case "punchposition": { let props = commonFunctions.getPropertiesFromTweenCommand(cur.Arg3); - if(!props.time) { props.time = 0.5; } + if(!props.time) { props.time = 500; } if(!cur.Arg6 || cur.Arg6 !== "NoWait") { this.waitTime = props.time + (props.delay || 0); } if(props.x) { this.lerpTargets.push({type: 'position.x', object: curChar.sprite, curTime: 0 - (props.delay || 0), time: props.time, - finalV: curChar.sprite.position.x + props.x, initV: curChar.sprite.position.x, inter: 'fullwait' }); + finalV: curChar.sprite.position.x + props.x, initV: curChar.sprite.position.x, inter: 'dampsin' }); } if(props.y) { this.lerpTargets.push({type: 'position.y', object: curChar.sprite, curTime: 0 - (props.delay || 0), time: props.time, - finalV: curChar.sprite.position.y + props.y, initV: curChar.sprite.position.y, inter: 'fullwait' }); + finalV: curChar.sprite.position.y + props.y, initV: curChar.sprite.position.y, inter: 'dampsin' }); } break; } + case "scaleto": { + let props = commonFunctions.getPropertiesFromTweenCommand(cur.Arg3, false); + if(!props.time) { props.time = 500; } + //cuz I don't care about their values that make no sense when everything else uses time. + if(props.speed) { props.time = props.speed * 1000; } + if(!cur.Arg6 || cur.Arg6 !== "NoWait") { + this.waitTime = props.time + (props.delay || 0); + } + if(props.x) { + this.lerpTargets.push({type: 'scale.x', object: curChar.sprite, curTime: 0 - (props.delay || 0), time: props.time, + finalV: curChar.sprite.scale.x * props.x, initV: curChar.sprite.scale.x }); + } + if(props.y) { + this.lerpTargets.push({type: 'scale.y', object: curChar.sprite, curTime: 0 - (props.delay || 0), time: props.time, + finalV: curChar.sprite.scale.y * props.y, initV: curChar.sprite.scale.y }); + } + } case "colorto": { let props = commonFunctions.getPropertiesFromTweenCommand(cur.Arg3); if(props.alpha) { if(props.time) { + this.lerpTargets.push({type: 'alpha', object: curChar.sprite, curTime: 0 - (props.delay || 0), time: props.time, + finalV: props.alpha, initV: curChar.sprite.alpha }); } else { curChar.sprite.alpha = 0; } @@ -612,6 +672,37 @@ class Player { } } } + + processShake(delta, cur) { + let obj = cur.Arg1; + switch(obj.toLowerCase()) { + case "camera": { + let props = commonFunctions.getPropertiesFromTweenCommand(cur.Arg3); + if(!props.time) { props.time = 1000; } + if(!cur.Arg6 || cur.Arg6 !== "NoWait") { + this.waitTime = props.time + (props.delay || 0); + } + if(!props.x) { props.x = 30; } + if(!props.y) { props.y = 30; } + let stage = this.pixi.app.stage.position; + this.lerpTargets.push({type: 'shake', object: this.pixi.app.stage, curTime: 0 - (props.delay || 0), time: props.time, + finalV: {x: props.x + stage.x, y: props.y + stage.y}, initV: {x: stage.x, y: stage.y} }); + break; + } + case "messagewindow": { + let props = commonFunctions.getPropertiesFromTweenCommand(cur.Arg3); + if(!props.time) { props.time = 1000; } + if(!cur.Arg6 || cur.Arg6 !== "NoWait") { + this.waitTime = props.time + (props.delay || 0); + } + if(!props.x) { props.x = 30; } + if(!props.y) { props.y = 30; } + this.lerpTargets.push({type: 'shake', object: document.getElementById('dialog-box'), curTime: 0 - (props.delay || 0), time: props.time, + finalV: {x: props.x, y: props.y}, initV: {x: 0, y: 0} }); + break; + } + } + } processEndCommand(delta) { let cur = this.currentCommand; @@ -680,9 +771,6 @@ class Player { } updateResolution(res) { - //this.resolutionScale = res.height / baseDimensions.height; - //this.center = {x: ((baseDimensions.width / 2) * this.resolutionScale), y: ((baseDimensions.height / 2) * this.resolutionScale) }; - //this.pixi.app.renderer.resolution = res.height / baseDimensions.height; let newScale = res.height / baseDimensions.height; this.pixi.app.stage.scale.set(newScale, newScale); this.pixi.app.renderer.resize(res.width, res.height); @@ -714,7 +802,9 @@ class Player { this.hasMoreText = false; this.audioLoadPercent = 0; this.assetLoadPercent = 0; + this.playingVoice = undefined; this.text.resetAll(); + this.audio.resetAll(); resolve(); } catch (error) { reject(error); diff --git a/Js/TextFunctions.js b/Js/TextFunctions.js index 60cfa5a..36f5a87 100644 --- a/Js/TextFunctions.js +++ b/Js/TextFunctions.js @@ -8,6 +8,8 @@ class TextFunctions { this.dialogBox = undefined; this.character = undefined; this.dialog = undefined; + this.scrollControls = undefined; + this.nextIndicator = undefined; this.dialogToDisplay = {timeout: undefined, fullText: "", text: "", curPos: 0}; this.textScrollSpeedMs = 40; this.scrollingText = false; @@ -22,34 +24,38 @@ class TextFunctions { this.character = document.getElementById('character'); this.dialog = document.getElementById('dialog'); this.dialogInner = document.getElementById('dialog-inner'); + this.scrollControls = document.getElementById('dialog-scroll'); + this.nextIndicator = document.getElementById('dialog-next'); } titleText(show, text) { if(text != undefined) { this.title.innerHTML = text; } - this.title.style = show ? "opacity: 1;" : "opacity: 0;"; + this.title.classList.toggle('hidden', !show); } divaText(show, text) { if(text != undefined) { this.diva.innerHTML = text; } - this.diva.style = show ? "opacity: 1;" : "opacity: 0;"; + this.diva.classList.toggle('hidden', !show); } characterName(show, text) { if(text != undefined) { this.character.innerHTML = text; } - this.mainUi.style = show ? "opacity: 1;" : "opacity: 0;"; - this.character.style = show ? "opacity: 1;" : "opacity: 0;"; + this.mainUi.classList.toggle('hidden', !show); + this.character.classList.toggle('hidden', !show); } dialogText(show, text) { if(this.lineHeight == -1) { this.lineHeight = Number(window.getComputedStyle(this.dialog, null).getPropertyValue("line-height").replace('px', '')); } + this.showNextIndicator(false); + this.showScrollControls(false); if(text != undefined) { if(this.dialogToDisplay.timeout) { clearTimeout(this.dialogToDisplay.timeout); @@ -69,8 +75,8 @@ class TextFunctions { this.dialogToDisplay.timeout = setTimeout(putText.bind(this), this.textScrollSpeedMs); } } - this.mainUi.style = show ? "opacity: 1;" : "opacity: 0;"; - this.dialogBox.style = show ? "opacity: 1;" : "opacity: 0;"; + this.mainUi.classList.toggle('hidden', !show); + this.dialogBox.classList.toggle('hidden', !show); //This is based off https://github.com/mattboldt/typed.js/ function putText() { @@ -78,6 +84,7 @@ class TextFunctions { this.dialogToDisplay.curPos = this.typeHtmlChars(this.dialogToDisplay.text, this.dialogToDisplay.curPos); let substr = this.dialogToDisplay.text.substr(this.dialogToDisplay.curPos); if (this.dialogToDisplay.curPos === this.dialogToDisplay.text.length) { + this.showNextIndicator(true); this.scrollingText = false; return; } else { @@ -85,8 +92,10 @@ class TextFunctions { const nextString = this.dialogToDisplay.text.substr(0, this.dialogToDisplay.curPos); this.dialogInner.innerHTML = nextString; let lHeight = this.lineHeight * 2 - if(this.dialogInner.offsetHeight > lHeight) { + //the +5 is just to give a bit of tolerance + if(this.dialogInner.offsetHeight > lHeight + 5) { this.dialog.scrollTop = this.dialogInner.offsetHeight - lHeight; + this.showScrollControls(true); } } @@ -100,13 +109,15 @@ class TextFunctions { this.dialogToDisplay.timeout = undefined; } this.dialogInner.innerHTML = this.dialogToDisplay.fullText; - let lHeight = this.lineHeight * 2 - if(this.dialogInner.offsetHeight > lHeight) { + let lHeight = this.lineHeight * 2; + if(this.dialogInner.offsetHeight > lHeight + 5) { this.dialog.scrollTop = this.dialogInner.offsetHeight - lHeight; + this.showScrollControls(true); } + this.showNextIndicator(true); this.scrollingText = false; } - + typeHtmlChars(curString, curStrPos) { const curChar = curString.substr(curStrPos).charAt(0); if (curChar === '<' || curChar === '&') { @@ -125,10 +136,36 @@ class TextFunctions { return curStrPos; } + showScrollControls(show) { + this.scrollControls.classList.toggle('hidden', !show); + } + + scrollTextUp() { + let lHeight = this.lineHeight * 2; + let val = this.dialog.scrollTop - lHeight; + if(val < 0) { + val = 0; + } + this.dialog.scrollTop = val; + } + + scrollTextDown() { + let lHeight = this.lineHeight * 2; + let val = this.dialog.scrollTop + lHeight; + if(val > this.dialogInner.offsetHeight - lHeight) { + val = this.dialogInner.offsetHeight - lHeight; + } + this.dialog.scrollTop = val; + } + + showNextIndicator(show) { + this.nextIndicator.classList.toggle('hidden', !show); + } + hideUi(show) { - this.mainUi.style = show ? "opacity: 1;" : "opacity: 0;"; - this.dialogBox.style = show ? "opacity: 1;" : "opacity: 0;"; - this.character.style = show ? "opacity: 1;" : "opacity: 0;"; + this.mainUi.classList.toggle('hidden', !show); + this.dialogBox.classList.toggle('hidden', !show); + this.character.classList.toggle('hidden', !show); } resetAll() { @@ -136,10 +173,12 @@ class TextFunctions { this.diva.innerHTML = ''; this.character.innerHTML = ''; this.dialogInner.innerHTML = ''; - this.title.style = "opacity: 0;"; - this.diva.style = "opacity: 0;"; - this.mainUi.style = "opacity: 0;"; - this.character.style = "opacity: 0;"; - this.dialogBox.style = "opacity: 0;"; + this.title.classList.add('hidden'); + this.diva.classList.add('hidden'); + this.mainUi.classList.add('hidden'); + this.character.classList.add('hidden'); + this.dialogBox.classList.add('hidden'); + this.scrollControls.classList.add('hidden'); + this.nextIndicator.classList.add('hidden'); } } \ No newline at end of file diff --git a/Js/UtageParse.js b/Js/UtageParse.js index 96d2a51..9261bee 100644 --- a/Js/UtageParse.js +++ b/Js/UtageParse.js @@ -14,6 +14,7 @@ class UtageInfo { this.soundInfo = {}; this.textureInfo = {}; this.currentTranslation = {}; + this.bgmLoopData = {}; } loadUtageSettings(resolve, reject) { @@ -26,7 +27,8 @@ class UtageInfo { commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Param.tsv`), //commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Scenario.tsv`), commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Sound.tsv`), - commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`) + commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`), + commonFunctions.getFileJson(`${this.rootDirectory}Js/bgmLoop.json`), ]; Promise.all(promises) .then((success) => { @@ -41,6 +43,7 @@ class UtageInfo { this.parseParamInfo(success[4]); this.parseSoundInfo(success[5]); this.parseTextureInfo(success[6]); + this.bgmLoopData = success[7]; resolve(); }, (failure) => { reject(failure); @@ -186,6 +189,7 @@ class UtageInfo { let read = commonFunctions.readLine(line, headers); if(read && read.Label) { if(read.FileName && read.Type) { + read.origFileName = read.FileName; if(!read.FileName.includes('.')) { read.FileName = `${read.FileName}.opus`; } diff --git a/Player.html b/Player.html index f7e7212..e36c672 100644 --- a/Player.html +++ b/Player.html @@ -7,6 +7,7 @@ + @@ -20,23 +21,35 @@