Merge pull request #103 from LoveEevee/importsongs-add-song-genre
ImportSongs: Add song genre
This commit is contained in:
commit
51e270d3b0
@ -1167,7 +1167,7 @@
|
|||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
this.layeredText({
|
this.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "クリア",
|
text: strings.clear,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontFamily: config.font,
|
fontFamily: config.font,
|
||||||
x: gaugeClear + 3,
|
x: gaugeClear + 3,
|
||||||
|
294
public/src/js/importsongs.js
Normal file
294
public/src/js/importsongs.js
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
class ImportSongs{
|
||||||
|
constructor(songSelect, event){
|
||||||
|
this.songSelect = songSelect
|
||||||
|
this.songSelect.redrawRunning = false
|
||||||
|
this.songSelect.pointer(false)
|
||||||
|
|
||||||
|
this.loaderDiv = document.createElement("div")
|
||||||
|
this.loaderDiv.innerHTML = assets.pages["loadsong"]
|
||||||
|
loader.screen.appendChild(this.loaderDiv)
|
||||||
|
var loadingText = document.getElementById("loading-text")
|
||||||
|
loadingText.appendChild(document.createTextNode(strings.loading))
|
||||||
|
loadingText.setAttribute("alt", strings.loading)
|
||||||
|
|
||||||
|
var files = []
|
||||||
|
for(var i = 0; i < event.target.files.length; i++){
|
||||||
|
files.push(event.target.files[i])
|
||||||
|
}
|
||||||
|
var extensionRegex = /\.[^\/]+$/
|
||||||
|
files.sort((a, b) => {
|
||||||
|
var path1 = a.webkitRelativePath.replace(extensionRegex, "")
|
||||||
|
var path2 = b.webkitRelativePath.replace(extensionRegex, "")
|
||||||
|
return path1 > path2 ? 1 : -1
|
||||||
|
})
|
||||||
|
|
||||||
|
this.tjaFiles = []
|
||||||
|
this.osuFiles = []
|
||||||
|
var metaFiles = []
|
||||||
|
this.otherFiles = {}
|
||||||
|
this.songs = []
|
||||||
|
this.courseTypes = {
|
||||||
|
"easy": 0,
|
||||||
|
"normal": 1,
|
||||||
|
"hard": 2,
|
||||||
|
"oni": 3,
|
||||||
|
"ura": 4
|
||||||
|
}
|
||||||
|
this.categories = {
|
||||||
|
"j-pop": "J-POP",
|
||||||
|
"pop": "J-POP",
|
||||||
|
"アニメ": "アニメ",
|
||||||
|
"anime": "アニメ",
|
||||||
|
"アニメ": "アニメ",
|
||||||
|
"ボーカロイド™曲": "ボーカロイド™曲",
|
||||||
|
"ボーカロイド曲": "ボーカロイド™曲",
|
||||||
|
"ボーカロイド": "ボーカロイド™曲",
|
||||||
|
"vocaloid™ music": "ボーカロイド™曲",
|
||||||
|
"vocaloid music": "ボーカロイド™曲",
|
||||||
|
"vocaloid": "ボーカロイド™曲",
|
||||||
|
"バラエティ": "バラエティ",
|
||||||
|
"バラエティー": "バラエティ",
|
||||||
|
"どうよう": "バラエティ",
|
||||||
|
"童謡・民謡": "バラエティ",
|
||||||
|
"variety": "バラエティ",
|
||||||
|
"children": "バラエティ",
|
||||||
|
"children/folk": "バラエティ",
|
||||||
|
"children-folk": "バラエティ",
|
||||||
|
"クラシック": "クラシック",
|
||||||
|
"クラッシック": "クラシック",
|
||||||
|
"classical": "クラシック",
|
||||||
|
"classic": "クラシック",
|
||||||
|
"ゲームミュージック": "ゲームミュージック",
|
||||||
|
"game music": "ゲームミュージック",
|
||||||
|
"ナムコオリジナル": "ナムコオリジナル",
|
||||||
|
"namco original": "ナムコオリジナル"
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < files.length; i++){
|
||||||
|
var file = files[i]
|
||||||
|
var name = file.name.toLowerCase()
|
||||||
|
var path = file.webkitRelativePath.toLowerCase()
|
||||||
|
if(name.endsWith(".tja")){
|
||||||
|
this.tjaFiles.push({
|
||||||
|
file: file,
|
||||||
|
index: i
|
||||||
|
})
|
||||||
|
}else if(name.endsWith(".osu")){
|
||||||
|
this.osuFiles.push({
|
||||||
|
file: file,
|
||||||
|
index: i
|
||||||
|
})
|
||||||
|
}else if(name === "genre.ini" || name === "box.def"){
|
||||||
|
var level = (file.webkitRelativePath.match(/\//g) || []).length
|
||||||
|
metaFiles.push({
|
||||||
|
file: file,
|
||||||
|
level: (level * 2) + (name === "genre.ini" ? 1 : 0)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
this.otherFiles[file.webkitRelativePath.toLowerCase()] = file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var metaPromises = []
|
||||||
|
|
||||||
|
metaFiles.forEach(fileObj => {
|
||||||
|
metaPromises.push(this.addMeta(fileObj))
|
||||||
|
})
|
||||||
|
|
||||||
|
Promise.all(metaPromises).then(() => {
|
||||||
|
var songPromises = []
|
||||||
|
|
||||||
|
this.tjaFiles.forEach(fileObj => {
|
||||||
|
songPromises.push(this.addTja(fileObj))
|
||||||
|
})
|
||||||
|
this.osuFiles.forEach(fileObj => {
|
||||||
|
songPromises.push(this.addOsu(fileObj))
|
||||||
|
})
|
||||||
|
Promise.all(songPromises).then(this.loaded.bind(this))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addMeta(fileObj){
|
||||||
|
var file = fileObj.file
|
||||||
|
var level = fileObj.level
|
||||||
|
var name = file.name.toLowerCase()
|
||||||
|
var reader = new FileReader()
|
||||||
|
var promise = pageEvents.load(reader).then(event => {
|
||||||
|
var data = event.target.result.replace(/\0/g, "").split("\n")
|
||||||
|
var category
|
||||||
|
if(name === "genre.ini"){
|
||||||
|
var key
|
||||||
|
for(var i = 0; i < data.length; i++){
|
||||||
|
var line = data[i].trim().toLowerCase()
|
||||||
|
if(line.startsWith("[") && line.endsWith("]")){
|
||||||
|
key = line.slice(1, -1)
|
||||||
|
}else if(key === "genre"){
|
||||||
|
var equalsPos = line.indexOf("=")
|
||||||
|
if(equalsPos !== -1 && line.slice(0, equalsPos).trim() === "genrename"){
|
||||||
|
var value = line.slice(equalsPos + 1).trim()
|
||||||
|
category = this.categories[value] || data[i].trim().slice(equalsPos + 1).trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(name === "box.def"){
|
||||||
|
for(var i = 0; i < data.length; i++){
|
||||||
|
var line = data[i].trim().toLowerCase()
|
||||||
|
if(line.startsWith("#title:")){
|
||||||
|
var value = line.slice(7).trim()
|
||||||
|
if(value in this.categories){
|
||||||
|
category = this.categories[value]
|
||||||
|
}
|
||||||
|
}else if(line.startsWith("#genre:")){
|
||||||
|
var value = line.slice(7).trim()
|
||||||
|
category = this.categories[value] || data[i].trim().slice(7).trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(category){
|
||||||
|
var metaPath = file.webkitRelativePath.toLowerCase().slice(0, file.name.length * -1)
|
||||||
|
var filesLoop = fileObj => {
|
||||||
|
var tjaPath = fileObj.file.webkitRelativePath.toLowerCase().slice(0, fileObj.file.name.length * -1)
|
||||||
|
if(tjaPath.startsWith(metaPath) && (!("categoryLevel" in fileObj) || fileObj.categoryLevel < level)){
|
||||||
|
fileObj.category = category
|
||||||
|
fileObj.categoryLevel = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tjaFiles.forEach(filesLoop)
|
||||||
|
this.osuFiles.forEach(filesLoop)
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
reader.readAsText(file, "sjis")
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
addTja(fileObj){
|
||||||
|
var file = fileObj.file
|
||||||
|
var index = fileObj.index
|
||||||
|
var category = fileObj.category
|
||||||
|
var reader = new FileReader()
|
||||||
|
var promise = pageEvents.load(reader).then(event => {
|
||||||
|
var data = event.target.result.replace(/\0/g, "").split("\n")
|
||||||
|
var tja = new ParseTja(data, "oni", 0, true)
|
||||||
|
var songObj = {
|
||||||
|
id: index + 1,
|
||||||
|
type: "tja",
|
||||||
|
chart: data,
|
||||||
|
stars: []
|
||||||
|
}
|
||||||
|
var dir = file.webkitRelativePath.toLowerCase()
|
||||||
|
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
||||||
|
var hasCategory = false
|
||||||
|
for(var diff in tja.metadata){
|
||||||
|
var meta = tja.metadata[diff]
|
||||||
|
songObj.title = songObj.title_en = meta.title || file.name.slice(0, file.name.lastIndexOf("."))
|
||||||
|
var subtitle = meta.subtitle || ""
|
||||||
|
if(subtitle.startsWith("--")){
|
||||||
|
subtitle = subtitle.slice(2)
|
||||||
|
}
|
||||||
|
songObj.subtitle = songObj.subtitle_en = subtitle
|
||||||
|
songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0
|
||||||
|
if(meta.level){
|
||||||
|
songObj.stars[this.courseTypes[diff]] = meta.level
|
||||||
|
}
|
||||||
|
if(meta.wave){
|
||||||
|
songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()]
|
||||||
|
}
|
||||||
|
if(meta.genre){
|
||||||
|
songObj.category = this.categories[meta.genre.toLowerCase()] || meta.genre
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!songObj.category){
|
||||||
|
songObj.category = category || this.getCategory(file)
|
||||||
|
}
|
||||||
|
if(songObj.music && songObj.stars.filter(star => star).length !== 0){
|
||||||
|
this.songs[index] = songObj
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
reader.readAsText(file, "sjis")
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
addOsu(fileObj){
|
||||||
|
var file = fileObj.file
|
||||||
|
var index = fileObj.index
|
||||||
|
var category = fileObj.category
|
||||||
|
var reader = new FileReader()
|
||||||
|
var promise = pageEvents.load(reader).then(event => {
|
||||||
|
var data = event.target.result.replace(/\0/g, "").split("\n")
|
||||||
|
var osu = new ParseOsu(data, 0, true)
|
||||||
|
var dir = file.webkitRelativePath.toLowerCase()
|
||||||
|
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
||||||
|
var songObj = {
|
||||||
|
id: index + 1,
|
||||||
|
type: "osu",
|
||||||
|
chart: data,
|
||||||
|
subtitle: osu.metadata.ArtistUnicode || osu.metadata.Artist,
|
||||||
|
subtitle_en: osu.metadata.Artist || osu.metadata.ArtistUnicode,
|
||||||
|
preview: osu.generalInfo.PreviewTime,
|
||||||
|
stars: [null, null, null, parseInt(osu.difficulty.overallDifficulty) || 1],
|
||||||
|
music: this.otherFiles[dir + osu.generalInfo.AudioFilename.toLowerCase()]
|
||||||
|
}
|
||||||
|
var filename = file.name.slice(0, file.name.lastIndexOf("."))
|
||||||
|
var title = osu.metadata.TitleUnicode || osu.metadata.Title
|
||||||
|
if(title){
|
||||||
|
var suffix = ""
|
||||||
|
var matches = filename.match(/\[.+?\]$/)
|
||||||
|
if(matches){
|
||||||
|
suffix = " " + matches[0]
|
||||||
|
}
|
||||||
|
songObj.title = title + suffix
|
||||||
|
songObj.title_en = (osu.metadata.Title || osu.metadata.TitleUnicode) + suffix
|
||||||
|
}else{
|
||||||
|
songObj.title = filename
|
||||||
|
}
|
||||||
|
if(songObj.music){
|
||||||
|
this.songs[index] = songObj
|
||||||
|
}
|
||||||
|
songObj.category = category || this.getCategory(file)
|
||||||
|
}).catch(() => {})
|
||||||
|
reader.readAsText(file)
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategory(file){
|
||||||
|
var path = file.webkitRelativePath.toLowerCase().split("/")
|
||||||
|
for(var i = path.length - 2; i >= 0; i--){
|
||||||
|
for(var cat in this.categories){
|
||||||
|
if(path[i].indexOf(cat) !== -1){
|
||||||
|
return this.categories[cat]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded(){
|
||||||
|
this.songs = this.songs.filter(song => typeof song !== "undefined")
|
||||||
|
if(this.songs.length){
|
||||||
|
assets.songs = this.songs
|
||||||
|
assets.customSongs = true
|
||||||
|
assets.customSelected = 0
|
||||||
|
assets.sounds["don"].play()
|
||||||
|
this.songSelect.clean()
|
||||||
|
setTimeout(() => {
|
||||||
|
loader.screen.removeChild(this.loaderDiv)
|
||||||
|
this.clean()
|
||||||
|
new SongSelect("browse", false, this.songSelect.touchEnabled)
|
||||||
|
}, 500)
|
||||||
|
}else{
|
||||||
|
loader.screen.removeChild(this.loaderDiv)
|
||||||
|
this.songSelect.browse.parentNode.reset()
|
||||||
|
this.songSelect.redrawRunning = true
|
||||||
|
this.clean()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean(){
|
||||||
|
delete this.loaderDiv
|
||||||
|
delete this.songs
|
||||||
|
delete this.tjaFiles
|
||||||
|
delete this.osuFiles
|
||||||
|
delete this.otherFiles
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,14 @@ class LoadSong{
|
|||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
|
|
||||||
loader.changePage("loadsong")
|
loader.changePage("loadsong")
|
||||||
|
var loadingText = document.getElementById("loading-text")
|
||||||
|
loadingText.appendChild(document.createTextNode(strings.loading))
|
||||||
|
loadingText.setAttribute("alt", strings.loading)
|
||||||
|
if(multiplayer){
|
||||||
|
var cancel = document.getElementById("p2-cancel-button")
|
||||||
|
cancel.appendChild(document.createTextNode(strings.cancel))
|
||||||
|
cancel.setAttribute("alt", strings.cancel)
|
||||||
|
}
|
||||||
this.run()
|
this.run()
|
||||||
}
|
}
|
||||||
run(){
|
run(){
|
||||||
|
@ -278,7 +278,7 @@ class ParseOsu{
|
|||||||
id: circleID,
|
id: circleID,
|
||||||
start: start + this.offset,
|
start: start + this.offset,
|
||||||
type: "balloon",
|
type: "balloon",
|
||||||
txt: "ふうせん",
|
txt: strings.note.balloon,
|
||||||
speed: speed,
|
speed: speed,
|
||||||
endTime: endTime + this.offset,
|
endTime: endTime + this.offset,
|
||||||
requiredHits: requiredHits,
|
requiredHits: requiredHits,
|
||||||
@ -296,10 +296,10 @@ class ParseOsu{
|
|||||||
|
|
||||||
if(hitSound & this.osu.FINISH){
|
if(hitSound & this.osu.FINISH){
|
||||||
type = "daiDrumroll"
|
type = "daiDrumroll"
|
||||||
txt = "連打(大)ーっ!!"
|
txt = strings.note.daiDrumroll
|
||||||
}else{
|
}else{
|
||||||
type = "drumroll"
|
type = "drumroll"
|
||||||
txt = "連打ーっ!!"
|
txt = strings.note.drumroll
|
||||||
}
|
}
|
||||||
circles.push(new Circle({
|
circles.push(new Circle({
|
||||||
id: circleID,
|
id: circleID,
|
||||||
@ -328,10 +328,10 @@ class ParseOsu{
|
|||||||
}
|
}
|
||||||
}else if(hitSound & this.osu.WHISTLE || hitSound & this.osu.CLAP){
|
}else if(hitSound & this.osu.WHISTLE || hitSound & this.osu.CLAP){
|
||||||
type = "ka"
|
type = "ka"
|
||||||
txt = "カッ"
|
txt = strings.note.ka
|
||||||
}else if(hitSound & this.osu.NORMAL || hitSound === 0){
|
}else if(hitSound & this.osu.NORMAL || hitSound === 0){
|
||||||
type = "don"
|
type = "don"
|
||||||
txt = "ドン"
|
txt = strings.note.don
|
||||||
}else{
|
}else{
|
||||||
emptyValue = true
|
emptyValue = true
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,15 @@
|
|||||||
this.soundOffset = 0
|
this.soundOffset = 0
|
||||||
this.noteTypes = [
|
this.noteTypes = [
|
||||||
{name: false, txt: false},
|
{name: false, txt: false},
|
||||||
{name: "don", txt: "ドン"},
|
{name: "don", txt: strings.note.don},
|
||||||
{name: "ka", txt: "カッ"},
|
{name: "ka", txt: strings.note.ka},
|
||||||
{name: "daiDon", txt: "ドン(大)"},
|
{name: "daiDon", txt: strings.note.daiDon},
|
||||||
{name: "daiKa", txt: "カッ(大)"},
|
{name: "daiKa", txt: strings.note.daiKa},
|
||||||
{name: "drumroll", txt: "連打ーっ!!"},
|
{name: "drumroll", txt: strings.note.drumroll},
|
||||||
{name: "daiDrumroll", txt: "連打(大)ーっ!!"},
|
{name: "daiDrumroll", txt: strings.note.daiDrumroll},
|
||||||
{name: "balloon", txt: "ふうせん"},
|
{name: "balloon", txt: strings.note.balloon},
|
||||||
{name: false, txt: false},
|
{name: false, txt: false},
|
||||||
{name: "balloon", txt: "ふうせん"}
|
{name: "balloon", txt: strings.note.balloon}
|
||||||
]
|
]
|
||||||
this.courseTypes = {
|
this.courseTypes = {
|
||||||
"0": "easy",
|
"0": "easy",
|
||||||
@ -41,6 +41,7 @@
|
|||||||
parseMetadata(){
|
parseMetadata(){
|
||||||
var metaNumbers = ["bpm", "offset", "demostart", "level"]
|
var metaNumbers = ["bpm", "offset", "demostart", "level"]
|
||||||
var inSong = false
|
var inSong = false
|
||||||
|
var hasSong = false
|
||||||
var courses = {}
|
var courses = {}
|
||||||
var currentCourse = {}
|
var currentCourse = {}
|
||||||
var courseName = this.difficulty
|
var courseName = this.difficulty
|
||||||
@ -53,6 +54,7 @@
|
|||||||
if(name === "start" && !inSong){
|
if(name === "start" && !inSong){
|
||||||
|
|
||||||
inSong = true
|
inSong = true
|
||||||
|
if(!hasSong){
|
||||||
for(var name in currentCourse){
|
for(var name in currentCourse){
|
||||||
if(!(courseName in courses)){
|
if(!(courseName in courses)){
|
||||||
courses[courseName] = {}
|
courses[courseName] = {}
|
||||||
@ -61,11 +63,14 @@
|
|||||||
}
|
}
|
||||||
courses[courseName].start = lineNum + 1
|
courses[courseName].start = lineNum + 1
|
||||||
courses[courseName].end = this.data.length
|
courses[courseName].end = this.data.length
|
||||||
|
}
|
||||||
}else if(name === "end" && inSong){
|
}else if(name === "end" && inSong){
|
||||||
inSong = false
|
inSong = false
|
||||||
|
if(!hasSong){
|
||||||
|
hasSong = true
|
||||||
courses[courseName].end = lineNum
|
courses[courseName].end = lineNum
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}else if(!inSong){
|
}else if(!inSong){
|
||||||
|
|
||||||
@ -82,6 +87,7 @@
|
|||||||
}else{
|
}else{
|
||||||
courseName = value
|
courseName = value
|
||||||
}
|
}
|
||||||
|
hasSong = false
|
||||||
}else if(name === "balloon"){
|
}else if(name === "balloon"){
|
||||||
value = value ? value.split(",").map(digit => parseInt(digit)) : []
|
value = value ? value.split(",").map(digit => parseInt(digit)) : []
|
||||||
}else if(this.inArray(name, metaNumbers)){
|
}else if(this.inArray(name, metaNumbers)){
|
||||||
|
@ -363,7 +363,7 @@ class Scoresheet{
|
|||||||
}, ctx => {
|
}, ctx => {
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "成績発表",
|
text: strings.results,
|
||||||
fontSize: 48,
|
fontSize: 48,
|
||||||
fontFamily: this.font,
|
fontFamily: this.font,
|
||||||
x: 23,
|
x: 23,
|
||||||
@ -459,8 +459,8 @@ class Scoresheet{
|
|||||||
ctx.fillStyle = "#fff"
|
ctx.fillStyle = "#fff"
|
||||||
ctx.strokeStyle = "#000"
|
ctx.strokeStyle = "#000"
|
||||||
ctx.lineWidth = 0.5
|
ctx.lineWidth = 0.5
|
||||||
ctx.fillText("点", 788, 284)
|
ctx.fillText(strings.points, 788, 284)
|
||||||
ctx.strokeText("点", 788, 284)
|
ctx.strokeText(strings.points, 788, 284)
|
||||||
|
|
||||||
this.draw.score({
|
this.draw.score({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
@ -487,7 +487,7 @@ class Scoresheet{
|
|||||||
grd.addColorStop(0.9, "#f7fb00")
|
grd.addColorStop(0.9, "#f7fb00")
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "最大コンボ数",
|
text: strings.maxCombo,
|
||||||
x: 1149,
|
x: 1149,
|
||||||
y: 193,
|
y: 193,
|
||||||
fontSize: 29,
|
fontSize: 29,
|
||||||
@ -501,7 +501,7 @@ class Scoresheet{
|
|||||||
])
|
])
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "連打数",
|
text: strings.drumroll,
|
||||||
x: 1150,
|
x: 1150,
|
||||||
y: 233,
|
y: 233,
|
||||||
fontSize: 29,
|
fontSize: 29,
|
||||||
|
@ -118,15 +118,15 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: "もどる",
|
title: strings.back,
|
||||||
skin: this.songSkin.back,
|
skin: this.songSkin.back,
|
||||||
action: "back"
|
action: "back"
|
||||||
})
|
})
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: "ランダムに曲をえらぶ",
|
title: strings.randomSong,
|
||||||
skin: this.songSkin.random,
|
skin: this.songSkin.random,
|
||||||
action: "random",
|
action: "random",
|
||||||
category: "ランダム"
|
category: strings.random
|
||||||
})
|
})
|
||||||
if(touchEnabled){
|
if(touchEnabled){
|
||||||
if(fromTutorial === "tutorial"){
|
if(fromTutorial === "tutorial"){
|
||||||
@ -134,31 +134,31 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: "あそびかた説明",
|
title: strings.tutorial,
|
||||||
skin: this.songSkin.tutorial,
|
skin: this.songSkin.tutorial,
|
||||||
action: "tutorial",
|
action: "tutorial",
|
||||||
category: "ランダム"
|
category: strings.random
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: "このシミュレータについて",
|
title: strings.aboutSimulator,
|
||||||
skin: this.songSkin.about,
|
skin: this.songSkin.about,
|
||||||
action: "about",
|
action: "about",
|
||||||
category: "ランダム"
|
category: strings.random
|
||||||
})
|
})
|
||||||
if("webkitdirectory" in HTMLInputElement.prototype && !(/Android|iPhone|iPad/.test(navigator.userAgent))){
|
if("webkitdirectory" in HTMLInputElement.prototype && !(/Android|iPhone|iPad/.test(navigator.userAgent))){
|
||||||
this.browse = document.getElementById("browse")
|
this.browse = document.getElementById("browse")
|
||||||
pageEvents.add(this.browse, "change", this.browseChange.bind(this))
|
pageEvents.add(this.browse, "change", this.browseChange.bind(this))
|
||||||
|
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: assets.customSongs ? "デフォルト曲リスト" : "参照する…",
|
title: assets.customSongs ? strings.defaultSongList : strings.browse,
|
||||||
skin: this.songSkin.browse,
|
skin: this.songSkin.browse,
|
||||||
action: "browse",
|
action: "browse",
|
||||||
category: "ランダム"
|
category: strings.random
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: "もどる",
|
title: strings.back,
|
||||||
skin: this.songSkin.back,
|
skin: this.songSkin.back,
|
||||||
action: "back"
|
action: "back"
|
||||||
})
|
})
|
||||||
@ -177,19 +177,19 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.diffOptions = [{
|
this.diffOptions = [{
|
||||||
text: "もどる",
|
text: strings.back,
|
||||||
fill: "#efb058",
|
fill: "#efb058",
|
||||||
iconName: "back",
|
iconName: "back",
|
||||||
iconFill: "#f7d39c",
|
iconFill: "#f7d39c",
|
||||||
letterSpacing: 4
|
letterSpacing: 4
|
||||||
}, {
|
}, {
|
||||||
text: "演奏オプション",
|
text: strings.songOptions,
|
||||||
fill: "#b2e442",
|
fill: "#b2e442",
|
||||||
iconName: "options",
|
iconName: "options",
|
||||||
iconFill: "#d9f19f",
|
iconFill: "#d9f19f",
|
||||||
letterSpacing: 0
|
letterSpacing: 0
|
||||||
}]
|
}]
|
||||||
this.optionsList = ["なし", "オート", "ネットプレイ"]
|
this.optionsList = [strings.none, strings.auto, strings.netplay]
|
||||||
|
|
||||||
this.draw = new CanvasDraw()
|
this.draw = new CanvasDraw()
|
||||||
this.songTitleCache = new CanvasCache()
|
this.songTitleCache = new CanvasCache()
|
||||||
@ -199,12 +199,12 @@ class SongSelect{
|
|||||||
this.sessionCache = new CanvasCache()
|
this.sessionCache = new CanvasCache()
|
||||||
this.currentSongCache = new CanvasCache()
|
this.currentSongCache = new CanvasCache()
|
||||||
|
|
||||||
this.difficulty = ["かんたん", "ふつう", "むずかしい", "おに"]
|
this.difficulty = [strings.easy, strings.normal, strings.hard, strings.oni]
|
||||||
this.difficultyId = ["easy", "normal", "hard", "oni", "ura"]
|
this.difficultyId = ["easy", "normal", "hard", "oni", "ura"]
|
||||||
|
|
||||||
this.sessionText = {
|
this.sessionText = {
|
||||||
"sessionstart": "オンラインセッションを開始する!",
|
"sessionstart": strings.sessionStart,
|
||||||
"sessionend": "オンラインセッションを終了する"
|
"sessionend": strings.sessionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectedSong = 0
|
this.selectedSong = 0
|
||||||
@ -557,124 +557,7 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
browseChange(event){
|
browseChange(event){
|
||||||
this.redrawRunning = false
|
new ImportSongs(this, event)
|
||||||
this.pointer(false)
|
|
||||||
|
|
||||||
var loaderDiv = document.createElement("div")
|
|
||||||
loaderDiv.innerHTML = assets.pages["loadsong"]
|
|
||||||
loader.screen.appendChild(loaderDiv)
|
|
||||||
var files = event.target.files
|
|
||||||
var promises = []
|
|
||||||
var tjaFiles = []
|
|
||||||
var osuFiles = []
|
|
||||||
var otherFiles = {}
|
|
||||||
|
|
||||||
for(var i = 0; i < files.length; i++){
|
|
||||||
var file = files[i]
|
|
||||||
var name = file.name.toLowerCase()
|
|
||||||
if(name.endsWith(".tja")){
|
|
||||||
tjaFiles.push([file, i])
|
|
||||||
}else if(name.endsWith(".osu")){
|
|
||||||
osuFiles.push([file, i])
|
|
||||||
}else{
|
|
||||||
otherFiles[file.webkitRelativePath.toLowerCase()] = file
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var songs = []
|
|
||||||
var courseTypes = {"easy": 0, "normal": 1, "hard": 2, "oni": 3, "ura": 4}
|
|
||||||
for(var i = 0; i < tjaFiles.length; i++){
|
|
||||||
let file = tjaFiles[i][0]
|
|
||||||
let index = tjaFiles[i][1]
|
|
||||||
var reader = new FileReader()
|
|
||||||
promises.push(pageEvents.load(reader).then(event => {
|
|
||||||
var data = event.target.result.replace(/\0/g, "").split("\n")
|
|
||||||
var tja = new ParseTja(data, "oni", 0, true)
|
|
||||||
var songObj = {
|
|
||||||
id: index + 1,
|
|
||||||
type: "tja",
|
|
||||||
chart: data,
|
|
||||||
stars: []
|
|
||||||
}
|
|
||||||
var dir = file.webkitRelativePath.toLowerCase()
|
|
||||||
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
|
||||||
for(var diff in tja.metadata){
|
|
||||||
var meta = tja.metadata[diff]
|
|
||||||
songObj.title = songObj.title_en = meta.title || file.name.slice(0, file.name.lastIndexOf("."))
|
|
||||||
var subtitle = meta.subtitle || ""
|
|
||||||
if(subtitle.startsWith("--")){
|
|
||||||
subtitle = subtitle.slice(2)
|
|
||||||
}
|
|
||||||
songObj.subtitle = songObj.subtitle_en = subtitle
|
|
||||||
songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0
|
|
||||||
if(meta.level){
|
|
||||||
songObj.stars[courseTypes[diff]] = meta.level
|
|
||||||
}
|
|
||||||
if(meta.wave){
|
|
||||||
songObj.music = otherFiles[dir + meta.wave.toLowerCase()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(songObj.music && songObj.stars.filter(star => star).length !== 0){
|
|
||||||
songs[index] = songObj
|
|
||||||
}
|
|
||||||
}).catch(() => {}))
|
|
||||||
reader.readAsText(file, "sjis")
|
|
||||||
}
|
|
||||||
for(var i = 0; i < osuFiles.length; i++){
|
|
||||||
let file = osuFiles[i][0]
|
|
||||||
let index = osuFiles[i][1]
|
|
||||||
var reader = new FileReader()
|
|
||||||
promises.push(pageEvents.load(reader).then(event => {
|
|
||||||
var data = event.target.result.replace(/\0/g, "").split("\n")
|
|
||||||
var osu = new ParseOsu(data, 0, true)
|
|
||||||
var dir = file.webkitRelativePath.toLowerCase()
|
|
||||||
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
|
||||||
var songObj = {
|
|
||||||
id: index + 1,
|
|
||||||
type: "osu",
|
|
||||||
chart: data,
|
|
||||||
subtitle: osu.metadata.ArtistUnicode || osu.metadata.Artist,
|
|
||||||
subtitle_en: osu.metadata.Artist || osu.metadata.ArtistUnicode,
|
|
||||||
preview: osu.generalInfo.PreviewTime,
|
|
||||||
stars: [null, null, null, parseInt(osu.difficulty.overallDifficulty) || 1],
|
|
||||||
music: otherFiles[dir + osu.generalInfo.AudioFilename.toLowerCase()]
|
|
||||||
}
|
|
||||||
var filename = file.name.slice(0, file.name.lastIndexOf("."))
|
|
||||||
var title = osu.metadata.TitleUnicode || osu.metadata.Title
|
|
||||||
if(title){
|
|
||||||
var suffix = ""
|
|
||||||
var matches = filename.match(/\[.+?\]$/)
|
|
||||||
if(matches){
|
|
||||||
suffix = " " + matches[0]
|
|
||||||
}
|
|
||||||
songObj.title = title + suffix
|
|
||||||
songObj.title_en = (osu.metadata.Title || osu.metadata.TitleUnicode) + suffix
|
|
||||||
}else{
|
|
||||||
songObj.title = filename
|
|
||||||
}
|
|
||||||
if(songObj.music){
|
|
||||||
songs[index] = songObj
|
|
||||||
}
|
|
||||||
}).catch(() => {}))
|
|
||||||
reader.readAsText(file)
|
|
||||||
}
|
|
||||||
Promise.all(promises).then(() => {
|
|
||||||
songs = songs.filter(song => typeof song !== "undefined")
|
|
||||||
if(songs.length){
|
|
||||||
assets.songs = songs
|
|
||||||
assets.customSongs = true
|
|
||||||
assets.customSelected = 0
|
|
||||||
assets.sounds["don"].play()
|
|
||||||
this.clean()
|
|
||||||
setTimeout(() => {
|
|
||||||
loader.screen.removeChild(loaderDiv)
|
|
||||||
new SongSelect("browse", false, this.touchEnabled)
|
|
||||||
}, 500)
|
|
||||||
}else{
|
|
||||||
loader.screen.removeChild(loaderDiv)
|
|
||||||
this.browse.parentNode.reset()
|
|
||||||
this.redrawRunning = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toSelectDifficulty(fromP2){
|
toSelectDifficulty(fromP2){
|
||||||
@ -996,7 +879,7 @@ class SongSelect{
|
|||||||
}, ctx => {
|
}, ctx => {
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "曲をえらぶ",
|
text: strings.selectSong,
|
||||||
fontSize: 48,
|
fontSize: 48,
|
||||||
fontFamily: this.font,
|
fontFamily: this.font,
|
||||||
x: 53,
|
x: 53,
|
||||||
@ -1025,9 +908,14 @@ class SongSelect{
|
|||||||
h: this.songAsset.marginTop,
|
h: this.songAsset.marginTop,
|
||||||
id: category + selectedSong.skin.outline
|
id: category + selectedSong.skin.outline
|
||||||
}, ctx => {
|
}, ctx => {
|
||||||
|
if(category in strings.categories){
|
||||||
|
var categoryName = strings.categories[category]
|
||||||
|
}else{
|
||||||
|
var categoryName = category
|
||||||
|
}
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: category,
|
text: categoryName,
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontFamily: this.font,
|
fontFamily: this.font,
|
||||||
x: 280 / 2,
|
x: 280 / 2,
|
||||||
@ -1236,7 +1124,7 @@ class SongSelect{
|
|||||||
}, ctx => {
|
}, ctx => {
|
||||||
this.draw.layeredText({
|
this.draw.layeredText({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "むずかしさをえらぶ",
|
text: strings.selectDifficulty,
|
||||||
fontSize: 46,
|
fontSize: 46,
|
||||||
fontFamily: this.font,
|
fontFamily: this.font,
|
||||||
x: 53,
|
x: 53,
|
||||||
|
55
public/src/js/strings.js
Normal file
55
public/src/js/strings.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
class StringsJa{
|
||||||
|
constructor(){
|
||||||
|
this.titleProceed = "Click or Press Enter!"
|
||||||
|
this.categories = {
|
||||||
|
"J-POP": "J-POP",
|
||||||
|
"アニメ": "アニメ",
|
||||||
|
"ボーカロイド™曲": "ボーカロイド™曲",
|
||||||
|
"バラエティ": "バラエティ",
|
||||||
|
"クラシック": "クラシック",
|
||||||
|
"ゲームミュージック": "ゲームミュージック",
|
||||||
|
"ナムコオリジナル": "ナムコオリジナル"
|
||||||
|
}
|
||||||
|
this.selectSong = "曲をえらぶ"
|
||||||
|
this.selectDifficulty = "むずかしさをえらぶ"
|
||||||
|
this.back = "もどる"
|
||||||
|
this.random = "ランダム"
|
||||||
|
this.randomSong = "ランダムに曲をえらぶ"
|
||||||
|
this.tutorial = "あそびかた説明"
|
||||||
|
this.aboutSimulator = "このシミュレータについて"
|
||||||
|
this.browse = "参照する…"
|
||||||
|
this.defaultSongList = "デフォルト曲リスト"
|
||||||
|
this.songOptions = "演奏オプション"
|
||||||
|
this.none = "なし"
|
||||||
|
this.auto = "オート"
|
||||||
|
this.netplay = "ネットプレイ"
|
||||||
|
this.easy = "かんたん"
|
||||||
|
this.normal = "ふつう"
|
||||||
|
this.hard = "むずかしい"
|
||||||
|
this.oni = "おに"
|
||||||
|
this.sessionStart = "オンラインセッションを開始する!"
|
||||||
|
this.sessionEnd = "オンラインセッションを終了する"
|
||||||
|
this.loading = "Loading..."
|
||||||
|
this.cancel = "Cancel"
|
||||||
|
this.note = {
|
||||||
|
don: "ドン",
|
||||||
|
ka: "カッ",
|
||||||
|
daiDon: "ドン(大)",
|
||||||
|
daiKa: "カッ(大)",
|
||||||
|
drumroll: "連打ーっ!!",
|
||||||
|
daiDrumroll: "連打(大)ーっ!!",
|
||||||
|
balloon: "ふうせん"
|
||||||
|
}
|
||||||
|
this.clear = "クリア"
|
||||||
|
this.pauseOptions = [
|
||||||
|
"演奏をつづける",
|
||||||
|
"はじめからやりなおす",
|
||||||
|
"「曲をえらぶ」にもどる"
|
||||||
|
]
|
||||||
|
this.results = "成績発表"
|
||||||
|
this.points = "点"
|
||||||
|
this.maxCombo = "最大コンボ数"
|
||||||
|
this.drumroll = "連打数"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var strings = new StringsJa()
|
@ -2,6 +2,10 @@ class Titlescreen{
|
|||||||
constructor(){
|
constructor(){
|
||||||
loader.changePage("titlescreen")
|
loader.changePage("titlescreen")
|
||||||
this.titleScreen = document.getElementById("title-screen")
|
this.titleScreen = document.getElementById("title-screen")
|
||||||
|
var proceed = document.getElementById("title-proceed")
|
||||||
|
proceed.appendChild(document.createTextNode(strings.titleProceed))
|
||||||
|
proceed.setAttribute("alt", strings.titleProceed)
|
||||||
|
|
||||||
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
|
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
|
||||||
pageEvents.add(this.titleScreen, ["mousedown", "touchstart"], this.onPressed.bind(this))
|
pageEvents.add(this.titleScreen, ["mousedown", "touchstart"], this.onPressed.bind(this))
|
||||||
assets.sounds["title"].play()
|
assets.sounds["title"].play()
|
||||||
|
@ -14,11 +14,7 @@
|
|||||||
this.touchp2Class = false
|
this.touchp2Class = false
|
||||||
this.darkDonBg = false
|
this.darkDonBg = false
|
||||||
|
|
||||||
this.pauseOptions = [
|
this.pauseOptions = strings.pauseOptions
|
||||||
"演奏をつづける",
|
|
||||||
"はじめからやりなおす",
|
|
||||||
"「曲をえらぶ」にもどる"
|
|
||||||
]
|
|
||||||
this.categories = {
|
this.categories = {
|
||||||
"J-POP": {
|
"J-POP": {
|
||||||
sort: 0,
|
sort: 0,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div id="load-song">
|
<div id="load-song">
|
||||||
<div id="loading-song">
|
<div id="loading-song">
|
||||||
<div id="loading-don"></div>
|
<div id="loading-don"></div>
|
||||||
<div class="loading-text stroke-sub" alt="Loading...">Loading...</div>
|
<div class="loading-text stroke-sub" id="loading-text"></div>
|
||||||
<div id="p2-cancel-button" class="taibtn stroke-sub" alt="Cancel">Cancel</div>
|
<div id="p2-cancel-button" class="taibtn stroke-sub"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div id="title-screen">
|
<div id="title-screen">
|
||||||
<div class="logo-big">太鼓の達人ウェブ</div>
|
<div class="logo-big">太鼓の達人ウェブ</div>
|
||||||
<div class="click-to-continue stroke-sub" alt="Click or Press Enter!">Click or Press Enter!</div>
|
<div class="click-to-continue stroke-sub" id="title-proceed"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
<!----------------------------------------------------------------------->
|
|
||||||
<!-- -->
|
|
||||||
<!-- TAIKO WEB TATSUJIN -->
|
|
||||||
<!-- 2015-2018 -->
|
|
||||||
<!-- Created by Clemaister, maintained by Bui -->
|
|
||||||
<!-- https://github.com/bui/taiko-web -->
|
|
||||||
<!-- -->
|
|
||||||
<!----------------------------------------------------------------------->
|
|
||||||
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@ -57,6 +47,8 @@
|
|||||||
<script src="/src/js/about.js?{{version.commit_short}}"></script>
|
<script src="/src/js/about.js?{{version.commit_short}}"></script>
|
||||||
<script src="/src/js/debug.js?{{version.commit_short}}"></script>
|
<script src="/src/js/debug.js?{{version.commit_short}}"></script>
|
||||||
<script src="/src/js/session.js?{{version.commit_short}}"></script>
|
<script src="/src/js/session.js?{{version.commit_short}}"></script>
|
||||||
|
<script src="/src/js/strings.js?{{version.commit_short}}"></script>
|
||||||
|
<script src="/src/js/importsongs.js?{{version.commit_short}}"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
Loading…
Reference in New Issue
Block a user