From 9004e721dd27b2d1c330cf1ce35771ca3c91ac82 Mon Sep 17 00:00:00 2001 From: piernov Date: Thu, 13 Mar 2014 16:14:10 +0100 Subject: Importation du projet --- Config.lua | 7 +++ Files.lua | 102 ++++++++++++++++++++++++++++++++++++++++++++ Game.lua | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Menu.lua | 64 ++++++++++++++++++++++++++++ SMFileSchema.lua | 52 +++++++++++++++++++++++ Utils.lua | 56 ++++++++++++++++++++++++ main.lua | 36 ++++++++++++++++ 7 files changed, 444 insertions(+) create mode 100755 Config.lua create mode 100755 Files.lua create mode 100755 Game.lua create mode 100755 Menu.lua create mode 100755 SMFileSchema.lua create mode 100755 Utils.lua create mode 100755 main.lua diff --git a/Config.lua b/Config.lua new file mode 100755 index 0000000..65eb993 --- /dev/null +++ b/Config.lua @@ -0,0 +1,7 @@ +local Config = {} + +Config.width, Config.height = love.window.getDimensions() + +Config.songsPerPages = 5 + +return Config diff --git a/Files.lua b/Files.lua new file mode 100755 index 0000000..8fc19fe --- /dev/null +++ b/Files.lua @@ -0,0 +1,102 @@ +local Files = {} + +function Files.findSongs(folder, fileTree) + if folder == nil then folder = "" end + if fileTree == nil then fileTree = {} end + local filesTable = love.filesystem.getDirectoryItems(folder) + for i,v in ipairs(filesTable) do + local file = folder.."/"..v + if love.filesystem.isFile(file) and v:sub(-3) == ".sm" then + table.insert(fileTree, file) + elseif love.filesystem.isDirectory(file) then + fileTree = Files.findSongs(file, fileTree) + end + end + return fileTree +end + +function Files.readNotesInfos(smInfo) + + local pos = { mesure = 1, beat = 1, note = 1} + local state = 0 + local numNotes = 0 + + for line in love.filesystem.lines(smInfo.file) do + line = line:gsub("//.*", "") + + local info, text= line:match("^#(%u+):(.-);?%s*$") + + if info == "NOTES" then + pos = { mesure = 1, beat = 1, note = 1} + state = 1 + numNotes = numNotes + 1 + if numNotes > 1 then + smInfo["notes"][numNotes] = Utils.copyTable(SMFileSchema.FileSchema["notes"][1]) + end + + elseif state > 0 and state < SMFileSchema.NotesInfos.noteData then + + if state <= SMFileSchema.NotesInfos.difficultyMeter then + tmp = line:match("^%s*(.+):.*$") + elseif state == SMFileSchema.NotesInfos.radarValues then + tmp = {} + for i in line:gmatch("%d+%.%d+") do + table.insert(tmp,i) + end + end + + if tmp then + smInfo["notes"][numNotes][state][2] = tmp + state = state + 1 + end + elseif state == SMFileSchema.NotesInfos.noteData then + for c in line:gmatch"." do + if c == "," then + pos.beat = 1 + pos.mesure = pos.mesure + 1 + elseif c == ";" then + pos = { mesure = 1, beat = 1, note = 1} + elseif c:find("%w") then + if not smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure] then + smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure] = {} + end + if not smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure][pos.beat] then + smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure][pos.beat] = {} + end + + table.insert(smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure][pos.beat], c) + + if #smInfo["notes"][numNotes][SMFileSchema.NotesInfos.noteData][2][pos.mesure][pos.beat] >= SMFileSchema.NotesType[smInfo["notes"][numNotes][SMFileSchema.NotesInfos.notesType][2]] then + pos.beat = pos.beat + 1 + end + end + end + end + end + + return smInfo +end + +function Files.getSMInfo(file) + local smInfo = Utils.copyTable(SMFileSchema.FileSchema) + smInfo.file = file + for line in love.filesystem.lines(smInfo.file) do + line = line:gsub("//.*", "") + + local info, text= line:match("^#(%u+):(.-);?%s*$") + + if info and info ~= "NOTES" then + if type(smInfo[info:lower()]) == "table" then + for i in text:gmatch("%d+%.%d+=%d+%.%d+") do + local beat, bpm = i:match("(%d+%.%d+)=(%d+%.%d+)") + smInfo[info:lower()][beat] = bpm + end + else + smInfo[info:lower()] = text + end + end + end + return smInfo +end + +return Files diff --git a/Game.lua b/Game.lua new file mode 100755 index 0000000..c4cc8f5 --- /dev/null +++ b/Game.lua @@ -0,0 +1,127 @@ +local Game = {} + +local buttonRadius = 5 + +function Game:init() + self.button = love.graphics.newCanvas( 100, 100, "normal", 16 ) + love.graphics.setCanvas(self.button) + self.button:clear() + love.graphics.setBlendMode('alpha') + love.graphics.setColor(0, 0, 0, 255) + love.graphics.circle( "fill", 50, 50, (buttonRadius/100)*Config.height, 100 ) + love.graphics.setColor(255, 0, 0, 255) + love.graphics.circle( "fill", 50, 50, ((buttonRadius-1)/100)*Config.height, 100 ) + love.graphics.setCanvas() + + self.circle = love.graphics.newCanvas( 100, 100, "normal", 16 ) + love.graphics.setCanvas(self.circle) + self.circle:clear() + love.graphics.setBlendMode('alpha') + love.graphics.setColor(0, 0, 0, 128) + love.graphics.circle( "fill", 50, 50, (buttonRadius/100)*Config.height, 100 ) + love.graphics.setColor(255, 0, 0, 128) + love.graphics.circle( "fill", 50, 50, ((buttonRadius-1)/100)*Config.height, 100 ) + love.graphics.setCanvas() +end + +function Game:enter(previous, song, id) + self.song = song + self.level = id + for k,v in pairs(self.song.bpms) do self.beatDuration = 60000*4/v break end + --self.beatDuration = 60000*4/self.song.bpms["0.000"] + self.music = love.audio.newSource(song.file:match("(.*/)") .. song.music) + love.graphics.setBackgroundColor(104, 136, 248) +end + +local tx=0 +local ty=0 +local tp=0 + +function love.touchpressed(x, y, p) + tp = p + tx = x + ty = y +end + +local speed = 50 +local offset = -1000*45/speed +local timer = offset +local musicplaying = false +local lastnote = -1 +local beat = 0 +local noteTime = 0 +local beatTime = 0 + +local displayedNotes = {} + +function Game:update(dt) + if timer < 0 then + timer = timer + dt*1000 + else + if not musicplaying then + musicplaying = true + self.music:play() + end + timer = self.music:tell("seconds")*1000 + end + + for k, v in pairs(displayedNotes) do + if v.x > 95-buttonRadius or v.y > 95-buttonRadius or v.x < 5-buttonRadius or v.y < 5-buttonRadius then + table.remove(displayedNotes, k) + elseif v.orientation == "left" then + displayedNotes[k].y = v.y + dt*speed + elseif v.orientation == "down" then + displayedNotes[k].x = v.x + dt*speed + elseif v.orientation == "up" then + displayedNotes[k].y = v.y - dt*speed + elseif v.orientation == "right" then + displayedNotes[k].x = v.x - dt*speed + end + end + + beat = math.ceil((timer-offset)/self.beatDuration) + if beat < 1 then return end + + noteTime = self.beatDuration/#self.song.notes[self.level][SMFileSchema.NotesInfos.noteData][2][beat] + beatTime = (timer-offset)-(beat-1)*self.beatDuration + notes = math.ceil(beatTime/noteTime) + + if lastnote ~= notes then + lastnote = notes + notes = self.song.notes[self.level][SMFileSchema.NotesInfos.noteData][2][beat][notes] + if notes[1] == "1" then table.insert(displayedNotes, { x = 50-buttonRadius, y = 50-buttonRadius, orientation = "left" }) end + if notes[2] == "1" then table.insert(displayedNotes, { x = 50-buttonRadius, y = 50-buttonRadius, orientation = "down" }) end + if notes[3] == "1" then table.insert(displayedNotes, { x = 50-buttonRadius, y = 50-buttonRadius, orientation = "up" }) end + if notes[4] == "1" then table.insert(displayedNotes, { x = 50-buttonRadius, y = 50-buttonRadius, orientation = "right" }) end + end + +end + +function Game:draw() + love.graphics.clear() + love.graphics.setColor(255, 0, 0) + love.graphics.setBlendMode('alpha') + love.graphics.print(timer, 320, 300) + for k,v in pairs(self.song.bpms) do love.graphics.print(v, 200, 300) end + love.graphics.print(beat, 200, 200) + love.graphics.print(lastnote, 200, 100) + love.graphics.print(noteTime, 200, 50) + love.graphics.print(beatTime, 200, 150) + + love.graphics.print(tp, 350, 150) + love.graphics.print(tx, 370, 150) + love.graphics.print(ty, 390, 150) + + love.graphics.setBlendMode('premultiplied') + love.graphics.draw(self.circle, Utils.percentCoordinates(5-buttonRadius, 50-buttonRadius)) + love.graphics.draw(self.circle, Utils.percentCoordinates(50-buttonRadius, 95-buttonRadius)) + love.graphics.draw(self.circle, Utils.percentCoordinates(50-buttonRadius, 5-buttonRadius)) + love.graphics.draw(self.circle, Utils.percentCoordinates(95-buttonRadius, 50-buttonRadius)) + --love.graphics.draw(self.button, Utils.percentCoordinates(x, 50)) + + for k, v in pairs(displayedNotes) do + love.graphics.draw(self.button, Utils.percentCoordinates(v.x, v.y)) + end +end + +return Game diff --git a/Menu.lua b/Menu.lua new file mode 100755 index 0000000..e75fa01 --- /dev/null +++ b/Menu.lua @@ -0,0 +1,64 @@ +local Menu = {} + +function loadSongs() + local songs = {} + for _,song in pairs(Files.findSongs(nil, nil)) do + table.insert(songs, Files.getSMInfo(song)) + end + table.sort(songs, Utils.sortByArtistAndTitle) + return songs +end + +function Menu:init() + self.songs = loadSongs() + self.pageNumber = 0 +end + +function Menu:update(dt) + Gui.group{grow = "down", pos = {Utils.percentCoordinates(10, 10)}, function() + for id = (self.pageNumber*Config.songsPerPages)+1, (self.pageNumber*Config.songsPerPages)+Config.songsPerPages do + local smInfo = self.songs[id] + if smInfo and smInfo.title then + if Gui.Button{text = string.format("%s — %s", smInfo.artist, smInfo.title), size = {Utils.percentCoordinates(80, 80/Config.songsPerPages)}} then + Gamestate.switch(Menu.selectDifficulty, self.songs[id]) + end + end + end + end} + + if self.pageNumber > 0 and Gui.Button{text = "<", pos = {Utils.percentCoordinates(2, 50)}, size = {Utils.percentCoordinates(5, 5)}} then + self.pageNumber = self.pageNumber - 1 + end + + if self.pageNumber+1 < #self.songs/Config.songsPerPages and Gui.Button{text = ">", pos = {Utils.percentCoordinates(93, 50)}, size = {Utils.percentCoordinates(5, 5)}} then + self.pageNumber = self.pageNumber + 1 + end +end + +Menu.selectDifficulty = {} + +function Menu.selectDifficulty:init() + self.pageNumber = 0 +end + +function Menu.selectDifficulty:enter(previous, song) + self.song = Files.readNotesInfos(song) +end + +function Menu.selectDifficulty:update() + Gui.group{grow = "down", pos = {Utils.percentCoordinates(10, 10)}, function() + for id = (self.pageNumber*Config.songsPerPages)+1, (self.pageNumber*Config.songsPerPages)+Config.songsPerPages do + local level = self.song["notes"][id] + if level and level[SMFileSchema.NotesInfos.description][2] then + if Gui.Button{text = string.format("%s — %s", level[SMFileSchema.NotesInfos.description][2], level[SMFileSchema.NotesInfos.difficultyClass][2]), size = {Utils.percentCoordinates(80, 80/Config.songsPerPages)}} then + Gamestate.switch(Game, self.song, id) + end + end + end + end} + if Gui.Button{text = "<-", pos = {Utils.percentCoordinates(50, 93)}, size = {Utils.percentCoordinates(5, 5)}} then + Gamestate.switch(Menu) + end +end + +return Menu diff --git a/SMFileSchema.lua b/SMFileSchema.lua new file mode 100755 index 0000000..45cbe7b --- /dev/null +++ b/SMFileSchema.lua @@ -0,0 +1,52 @@ +SMFileSchema = {} + +SMFileSchema.FileSchema = { + title = "", + subtitle = "", + artist = "", + titletranslit = "", + subtitletranslit = "", + artisttranslit = "", + credit = "", + banner = "", + background = "", + cdtitle = "", + music = "", + offset = 0, + samplestart = 0, + samplelength = 0, + selectable = "", + bpms = {}, + displaybpm = {}, + stops = {}, + bgchanges = {}, + + notes = + { + { + {"notesType", ""}, + {"description", ""}, + {"difficultyClass", ""}, + {"difficultyMeter", 1}, + {"radarValues", ""}, + {"noteData", {}} + } + } +} + +SMFileSchema.NotesInfos = Utils.tuple2ToIndexHash(SMFileSchema.FileSchema["notes"][1]) + +SMFileSchema.NotesType = {} +SMFileSchema.NotesType["dance-single"] = 4 +SMFileSchema.NotesType["dance-double"] = 8 +SMFileSchema.NotesType["dance-couple"] = 8 +SMFileSchema.NotesType["dance-solo"] = 6 +SMFileSchema.NotesType["pump-single"] = 5 +SMFileSchema.NotesType["pump-double"] = 10 +SMFileSchema.NotesType["pump-couple"] = 10 +SMFileSchema.NotesType["ez2-single"] = 5 +SMFileSchema.NotesType["ez2-double"] = 10 +SMFileSchema.NotesType["ez2-real"] = 7 +SMFileSchema.NotesType["para-single"] = 5 + +return SMFileSchema diff --git a/Utils.lua b/Utils.lua new file mode 100755 index 0000000..5e06f97 --- /dev/null +++ b/Utils.lua @@ -0,0 +1,56 @@ +local Utils = {} + +function Utils.percentCoordinates(x, y) + x = (x/100)*Config.width + y = (y/100)*Config.height + return x, y +end + +function Utils.tprint(tbl, indent) +if not indent then indent = 0 end +for k, v in pairs(tbl) do +formatting = string.rep(" ", indent) .. k .. ": " +if type(v) == "table" then +print(formatting) +Utils.tprint(v, indent+1) +else +print(formatting .. v) +end +end +end + +function Utils.tuple2ToIndexHash(table) + local tmp = {} + for k,v in pairs(table) do + tmp[v[1]] = k + end + return tmp +end + +-- From http://lua-users.org/wiki/CopyTable +function Utils.copyTable(orig) + local orig_type = type(orig) + local copy + if orig_type == 'table' then + copy = {} + for orig_key, orig_value in next, orig, nil do + copy[Utils.copyTable(orig_key)] = Utils.copyTable(orig_value) + end + setmetatable(copy, Utils.copyTable(getmetatable(orig))) + else -- number, string, boolean, etc + copy = orig + end + return copy +end + +function Utils.sortByArtistAndTitle(a, b) + if a.artist:lower() < b.artist:lower() then + return true + elseif a.artist:lower() == b.artist:lower() and a.title:lower() < b.title:lower() then + return true + else + return false + end +end + +return Utils diff --git a/main.lua b/main.lua new file mode 100755 index 0000000..ed38191 --- /dev/null +++ b/main.lua @@ -0,0 +1,36 @@ +Gui = require "Quickie" +Gamestate = require "hump.gamestate" +Timer = require "hump.timer" +Config = require "Config" +Utils = require "Utils" +SMFileSchema = require "SMFileSchema" +Files = require "Files" +Config = require "Config" +Game = require "Game" +Menu = require "Menu" + +function love.load() + -- preload fonts + fonts = { + [12] = love.graphics.newFont(12), + [20] = love.graphics.newFont(20), + } + love.graphics.setBackgroundColor(17,17,17) + love.graphics.setFont(fonts[20]) + + -- group defaults + Gui.group.default.size[1] = 150 + Gui.group.default.size[2] = 25 + Gui.group.default.spacing = 5 + + Gamestate.registerEvents() + Gamestate.switch(Menu) +end + +function love.update(dt) + Config.width, Config.height = love.window.getDimensions() +end + +function love.draw() + Gui.core.draw() +end -- cgit v1.2.3-54-g00ecf