ImportSongs: Custom assets

This commit is contained in:
LoveEevee 2019-02-03 15:04:25 +03:00
parent 7b9de52d06
commit da40fd58ff
8 changed files with 219 additions and 30 deletions

1
app.py
View File

@ -6,7 +6,6 @@ import json
import sqlite3
import re
import os
import urlparse
from flask import Flask, g, jsonify, render_template, request, abort, redirect
from ffmpy import FFmpeg

View File

@ -288,6 +288,7 @@
var string = inputText.split("")
var drawn = []
var quoteOpened = false
for(var i = 0; i < string.length; i++){
let symbol = string[i]
@ -314,7 +315,12 @@
}else if(symbol === "…"){
drawn.push({text: symbol, x: bold ? 9 : 0, y: 5, h: 25, rotate: true})
}else if(symbol === '"'){
drawn.push({text: symbol, x: 0, y: 5, h: 20, rotate: true})
if(quoteOpened){
drawn.push({realText: symbol, text: "“", x: -25, y: 10, h: 20})
}else{
drawn.push({realText: symbol, text: "”", x: 12, y: 15, h: 20})
}
quoteOpened = !quoteOpened
}else if(r.comma.test(symbol)){
// Comma, full stop
if(bold){
@ -440,14 +446,17 @@
}
var scaling = 1
var strokeScaling = 1
var height = config.height - (ura ? 52 * mul : 0)
if(height && drawnHeight > height){
scaling = height / drawnHeight
if(config.align === "bottom"){
strokeScaling = Math.max(0.6, height / drawnHeight)
ctx.translate(40 * mul, 0)
ctx.scale(Math.max(0.6, height / drawnHeight), scaling)
ctx.scale(strokeScaling, scaling)
ctx.translate(-40 * mul, 0)
}else{
strokeScaling = scaling
ctx.scale(1, scaling)
}
if(config.selectable){
@ -482,7 +491,7 @@
ctx.strokeStyle = config.outline
ctx.lineWidth = config.outlineSize * mul
if(config.align === "bottom"){
ctx.lineWidth /= scaling
ctx.lineWidth /= strokeScaling
}
ctx.lineJoin = "round"
ctx.miterLimit = 1
@ -632,6 +641,9 @@
}else{
drawn.push({text: symbol, x: -3, y: 13, w: 13, scale: [1.2, 0.7]})
}
}else if(r.tilde.test(symbol)){
// Hyphen, tilde
drawn.push({text: symbol === "~" ? "" : symbol, x: 0, y: 0, w: 39})
}else if(r.en.test(symbol)){
// n-width
drawn.push({text: symbol, x: 0, y: 0, w: 28})

View File

@ -75,7 +75,9 @@ class Controller{
}
var ms = this.game.elapsedTime
this.keyboard.checkMenuKeys()
if(this.game.musicFadeOut < 3){
this.keyboard.checkMenuKeys()
}
if(!this.game.isPaused()){
this.keyboard.checkGameKeys()

View File

@ -20,7 +20,7 @@ class Debug{
this.moving = false
pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this))
pageEvents.add(window, "mousemove", this.onMove.bind(this))
pageEvents.mouseAdd(this, this.onMove.bind(this))
pageEvents.add(this.titleDiv, "mousedown", this.startMove.bind(this))
pageEvents.add(this.minimiseDiv, "click", this.minimise.bind(this))
pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this))
@ -173,7 +173,8 @@ class Debug{
clean(){
this.offsetSlider.clean()
pageEvents.remove(window, ["mousedown", "mouseup", "mousemove", "blur"])
pageEvents.remove(window, ["mousedown", "mouseup", "blur"])
pageEvents.mouseRemove(this)
pageEvents.remove(this.title, "mousedown")
pageEvents.remove(this.minimiseDiv, "click")
pageEvents.remove(this.restartBtn, "click")

View File

@ -24,9 +24,11 @@
this.tjaFiles = []
this.osuFiles = []
this.assetFiles = {}
var metaFiles = []
this.otherFiles = {}
this.songs = []
this.stylesheet = []
this.courseTypes = {
"easy": 0,
"normal": 1,
@ -53,6 +55,18 @@
this.categories[allStrings[i].categories[ja].toLowerCase()] = ja
}
}
this.assetSelectors = {
"bg-pattern-1": ".pattern-bg",
"bg_genre_0": "#song-select",
"title-screen": "#title-screen",
"dancing-don": "#loading-don",
"touch_drum": "#touch-drum-img",
"touch_fullscreen": "#touch-full-btn",
"touch_pause": "#touch-pause-btn",
"bg_stage_1": ".song-stage-1",
"bg_stage_2": ".song-stage-2",
"bg_stage_3": ".song-stage-3"
}
for(var i = 0; i < files.length; i++){
var file = files[i]
@ -74,8 +88,12 @@
file: file,
level: (level * 2) + (name === "genre.ini" ? 1 : 0)
})
}else if(path.indexOf("/taiko-web assets/") !== -1){
if(!(name in this.assetFiles)){
this.assetFiles[name] = file
}
}else{
this.otherFiles[file.webkitRelativePath.toLowerCase()] = file
this.otherFiles[path] = file
}
}
@ -94,6 +112,7 @@
this.osuFiles.forEach(fileObj => {
songPromises.push(this.addOsu(fileObj))
})
songPromises.push(this.addAssets())
Promise.all(songPromises).then(this.loaded.bind(this))
})
}
@ -188,6 +207,9 @@
if(meta.genre){
songObj.category = this.categories[meta.genre.toLowerCase()] || meta.genre
}
if(meta.taikowebskin){
songObj.song_skin = this.getSkin(dir, meta.taikowebskin)
}
}
if(!songObj.category){
songObj.category = category || this.getCategory(file)
@ -242,6 +264,67 @@
return promise
}
addAssets(){
return new Promise((resolve, reject) => {
var promises = []
for(let name in this.assetFiles){
let id = this.getFilename(name)
var file = this.assetFiles[name]
if(name === "vectors.json"){
var reader = new FileReader()
promises.push(pageEvents.load(reader).then(() => response => {
vectors = JSON.parse(response)
}))
reader.readAsText(file)
}
if(assets.img.indexOf(name) !== -1){
let image = document.createElement("img")
promises.push(pageEvents.load(image).then(() => {
if(id in this.assetSelectors){
var selector = this.assetSelectors[id]
this.stylesheet.push(selector + '{background-image:url("' + image.src + '")}')
}
}))
image.id = name
image.src = URL.createObjectURL(file)
loader.assetsDiv.appendChild(image)
assets.image[id].parentNode.removeChild(assets.image[id])
assets.image[id] = image
}
if(assets.audioSfx.indexOf(name) !== -1){
assets.sounds[id].clean()
promises.push(this.loadSound(file, name, snd.sfxGain))
}
if(assets.audioMusic.indexOf(name) !== -1){
assets.sounds[id].clean()
promises.push(this.loadSound(file, name, snd.musicGain))
}
if(assets.audioSfxLR.indexOf(name) !== -1){
assets.sounds[id + "_p1"].clean()
assets.sounds[id + "_p2"].clean()
promises.push(this.loadSound(file, name, snd.sfxGain).then(sound => {
assets.sounds[id + "_p1"] = assets.sounds[id].copy(snd.sfxGainL)
assets.sounds[id + "_p2"] = assets.sounds[id].copy(snd.sfxGainR)
}))
}
if(assets.audioSfxLoud.indexOf(name) !== -1){
assets.sounds[id].clean()
promises.push(this.loadSound(file, name, snd.sfxLoudGain))
}
}
Promise.all(promises).then(resolve, reject)
})
}
loadSound(file, name, gain){
var id = this.getFilename(name)
return gain.load(file, true).then(sound => {
assets.sounds[id] = sound
})
}
getFilename(name){
return name.slice(0, name.lastIndexOf("."))
}
getCategory(file){
var path = file.webkitRelativePath.toLowerCase().split("/")
for(var i = path.length - 2; i >= 0; i--){
@ -253,8 +336,55 @@
}
}
getSkin(dir, config){
var configArray = config.toLowerCase().split(",")
var configObj = {}
for(var i in configArray){
var string = configArray[i].trim()
var space = string.indexOf(" ")
if(space !== -1){
configObj[string.slice(0, space).trim()] = string.slice(space + 1).trim()
}
}
if(!configObj.dir){
configObj.dir = ""
}
configObj.prefix = "custom "
var skinnable = ["song", "stage", "don"]
for(var i in skinnable){
var skinName = skinnable[i]
var skinValue = configObj[skinName]
if(skinValue && skinValue !== "none"){
var fileName = "bg_" + skinName + "_" + configObj.name
var skinPath = this.joinPath(dir, configObj.dir, fileName)
for(var j = 0; j < 2; j++){
if(skinValue !== "static"){
var suffix = (j === 0 ? "_a" : "_b") + ".png"
}else{
var suffix = ".png"
}
var skinFull = this.normPath(skinPath + suffix)
if(skinFull in this.otherFiles){
configObj[fileName + suffix] = this.otherFiles[skinFull]
}else{
configObj[skinName] = null
}
if(skinValue === "static"){
break
}
}
}
}
return configObj
}
loaded(){
this.songs = this.songs.filter(song => typeof song !== "undefined")
if(this.stylesheet.length){
var style = document.createElement("style")
style.appendChild(document.createTextNode(this.stylesheet.join("\n")))
document.head.appendChild(style)
}
if(this.songs.length){
assets.songs = this.songs
assets.customSongs = true
@ -274,6 +404,40 @@
}
}
joinPath(){
var resultPath = arguments[0]
for(var i = 1; i < arguments.length; i++){
var pPath = arguments[i]
if(pPath && (pPath[0] === "/" || pPath[0] === "\\")){
resultPath = pPath
}else{
var lastChar = resultPath.slice(-1)
if(resultPath && (lastChar !== "/" || lastChar !== "\\")){
resultPath = resultPath + "/"
}
resultPath = resultPath + pPath
}
}
return resultPath
}
normPath(path){
path = path.replace(/\\/g, "/").toLowerCase()
while(path[0] === "/"){
path = path.slice(1)
}
var comps = path.split("/")
for(var i = 0; i < comps.length; i++){
if(comps[i] === "." || comps[i] === ""){
comps.splice(i, 1)
i--
}else if(i !== 0 && comps[i] === ".." && comps[i - 1] !== ".."){
comps.splice(i - 1, 2)
i -= 2
}
}
return comps.join("/")
}
clean(){
delete this.loaderDiv
delete this.songs

View File

@ -243,7 +243,6 @@ class Loader{
clean(){
var fontDetectDiv = document.getElementById("fontdetectHelper")
fontDetectDiv.parentNode.removeChild(fontDetectDiv)
delete this.assetsDiv
delete this.loaderPercentage
delete this.loaderProgress
delete this.promises

View File

@ -26,11 +26,13 @@ class LoadSong{
song.songStage = this.randInt(1, 3)
song.donBg = this.randInt(1, 6)
var songObj = assets.songs.find(song => song.id === id)
if(song.songSkin && song.songSkin.name){
var imgLoad = []
for(var type in song.songSkin){
var value = song.songSkin[type]
if(type !== "name" && value && value !== "none"){
if(["song", "stage", "don"].indexOf(type) !== -1 && value && value !== "none"){
var filename = "bg_" + type + "_" + song.songSkin.name
if(value === "static"){
imgLoad.push({
@ -57,28 +59,34 @@ class LoadSong{
}
var skinBase = gameConfig.assets_baseurl + "song_skins/"
for(var i = 0; i < imgLoad.length; i++){
let filename = imgLoad[i].filename
let prefix = song.songSkin.prefix || ""
if((prefix + filename) in assets.image){
continue
}
let img = document.createElement("img")
if(this.touchEnabled && imgLoad[i].type === "song"){
if(!songObj.music && this.touchEnabled && imgLoad[i].type === "song"){
img.crossOrigin = "Anonymous"
}
let filename = imgLoad[i].filename
let promise = pageEvents.load(img)
if(imgLoad[i].type === "song"){
promises.push(promise.then(() => {
return this.scaleImg(img, filename)
return this.scaleImg(img, filename, prefix)
}))
}else{
promises.push(promise.then(() => {
assets.image[filename] = img
assets.image[prefix + filename] = img
}))
}
img.src = skinBase + filename + ".png"
if(songObj.music){
img.src = URL.createObjectURL(song.songSkin[filename + ".png"])
}else{
img.src = skinBase + filename + ".png"
}
}
}
promises.push(this.loadSongBg(id))
var songObj = assets.songs.find(song => song.id === id)
promises.push(new Promise((resolve, reject) => {
if(songObj.sound){
songObj.sound.gain = snd.musicGain
@ -136,7 +144,7 @@ class LoadSong{
img.crossOrigin = "Anonymous"
}
promises.push(pageEvents.load(img).then(() => {
return this.scaleImg(img, filenameAb)
return this.scaleImg(img, filenameAb, "")
}))
}else{
promises.push(pageEvents.load(img).then(() => {
@ -150,7 +158,7 @@ class LoadSong{
Promise.all(promises).then(resolve, reject)
})
}
scaleImg(img, filename){
scaleImg(img, filename, prefix){
return new Promise((resolve, reject) => {
if(this.touchEnabled){
var canvas = document.createElement("canvas")
@ -163,7 +171,7 @@ class LoadSong{
var saveScaled = url => {
let img2 = document.createElement("img")
pageEvents.load(img2).then(() => {
assets.image[filename] = img2
assets.image[prefix + filename] = img2
resolve()
}, reject)
img2.src = url
@ -176,7 +184,7 @@ class LoadSong{
saveScaled(canvas.toDataURL())
}
}else{
assets.image[filename] = img
assets.image[prefix + filename] = img
resolve()
}
})

View File

@ -999,6 +999,7 @@
var songSkinName = selectedSong.songSkin.name
var supportsBlend = "mixBlendMode" in this.songBg.style
var songLayers = [document.getElementById("layer1"), document.getElementById("layer2")]
var prefix = selectedSong.songSkin.prefix || ""
if(selectedSong.category in this.categories){
var catId = this.categories[selectedSong.category].sort
@ -1009,19 +1010,19 @@
if(!selectedSong.songSkin.song){
var id = selectedSong.songBg
this.songBg.classList.add("songbg-" + id)
this.setLayers(songLayers, "bg_song_" + id + (supportsBlend ? "" : "a"), supportsBlend)
this.setLayers(songLayers, prefix + "bg_song_" + id + (supportsBlend ? "" : "a"), supportsBlend)
}else if(selectedSong.songSkin.song !== "none"){
var notStatic = selectedSong.songSkin.song !== "static"
if(notStatic){
this.songBg.classList.add("songbg-" + selectedSong.songSkin.song)
}
this.setLayers(songLayers, "bg_song_" + songSkinName + (notStatic ? "_" : ""), notStatic)
this.setLayers(songLayers, prefix + "bg_song_" + songSkinName + (notStatic ? "_" : ""), notStatic)
}
if(!selectedSong.songSkin.stage){
this.songStage.classList.add("song-stage-" + selectedSong.songStage)
}else if(selectedSong.songSkin.stage !== "none"){
this.setBgImage(this.songStage, assets.image["bg_stage_" + songSkinName].src)
this.setBgImage(this.songStage, assets.image[prefix + "bg_stage_" + songSkinName].src)
}
}
setDonBg(){
@ -1029,6 +1030,7 @@
var songSkinName = selectedSong.songSkin.name
var donLayers = []
var filename = !selectedSong.songSkin.don && this.multiplayer === 2 ? "bg_don2_" : "bg_don_"
var prefix = selectedSong.songSkin.prefix || ""
this.donBg = document.createElement("div")
this.donBg.classList.add("donbg")
@ -1047,7 +1049,7 @@
var asset1, asset2
if(!selectedSong.songSkin.don){
this.donBg.classList.add("donbg-" + selectedSong.donBg)
this.setLayers(donLayers, filename + selectedSong.donBg, true)
this.setLayers(donLayers, prefix + filename + selectedSong.donBg, true)
asset1 = filename + selectedSong.donBg + "a"
asset2 = filename + selectedSong.donBg + "b"
}else if(selectedSong.songSkin.don !== "none"){
@ -1060,15 +1062,17 @@
asset1 = filename + songSkinName
asset2 = filename + songSkinName
}
this.setLayers(donLayers, filename + songSkinName + (notStatic ? "_" : ""), notStatic)
this.setLayers(donLayers, prefix + filename + songSkinName + (notStatic ? "_" : ""), notStatic)
}else{
return
}
var w1 = assets.image[asset1].width
var w2 = assets.image[asset2].width
var w1 = assets.image[prefix + asset1].width
var w2 = assets.image[prefix + asset2].width
this.donBg.style.setProperty("--sw", w1 > w2 ? w1 : w2)
this.donBg.style.setProperty("--sw1", w1)
this.donBg.style.setProperty("--sw2", w2)
this.donBg.style.setProperty("--sh1", assets.image[asset1].height)
this.donBg.style.setProperty("--sh2", assets.image[asset2].height)
this.donBg.style.setProperty("--sh1", assets.image[prefix + asset1].height)
this.donBg.style.setProperty("--sh2", assets.image[prefix + asset2].height)
}
setDonBgHeight(){
this.donBg.style.setProperty("--h", getComputedStyle(this.donBg).height)