Skip to content

Commit

Permalink
Added slide note support
Browse files Browse the repository at this point in the history
- For beatmap maker which uses MIDI, use normal note and set velocity to < 64

Added `IsRenderingMode` storyboard function.
  • Loading branch information
MikuAuahDark committed Apr 16, 2017
1 parent 3827a33 commit 9701b5f
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 42 deletions.
8 changes: 8 additions & 0 deletions docs/Storyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ Parameters:

> This function can only be called inside `Initialize` function.
*************************************************

### `boolean IsRenderingMode()`

Check for current rendering type.

Returns: `true` if currently in rendering mode (offline drawing), `false` if currently in live mode (online drawing).

Additional Storyboard Functions
===============================

Expand Down
42 changes: 42 additions & 0 deletions livesim.lua
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,12 @@ function DEPLS.StoryboardFunctions.ForceNewNoteStyle(new_style)
DEPLS.ForceNoteStyle = new_style and 2 or 1
end

--! @brief Check if current storyboard is under rendering mode
--! @returns In rendering mode (true) or live mode (false)
function DEPLS.StoryboardFunctions.IsRenderingMode()
return not(not(DEPLS.RenderingMode))
end

-----------------------------
-- The Live simuator logic --
-----------------------------
Expand Down Expand Up @@ -1082,19 +1088,27 @@ AUTOPLAY = %s
end

-- LOVE2D mouse/touch pressed
local TouchTracking = {}
local isMousePress = false
function love.mousepressed(x, y, button, touch_id)
if touch_id == true then return end
if DEPLS.ElapsedTime <= 0 then return end

touch_id = touch_id or 0
x, y = CalculateTouchPosition(x, y)

isMousePress = touch_id == 0 and button == 1

-- Calculate idol
for i = 1, 9 do
local idolpos = DEPLS.IdolPosition[i]

if distance(x - (idolpos[1] + 64), y - (idolpos[2] + 64)) <= 77 then
print("Press", i)
TouchTracking[touch_id] = i
DEPLS.NoteManager.SetTouch(i, touch_id)

break
end
end
end
Expand All @@ -1104,13 +1118,41 @@ function love.mousereleased(x, y, button, touch_id)
if touch_id == true then return end
if DEPLS.ElapsedTime <= 0 then return end

if isMousePress and touch_id == false and button == 1 then
isMousePress = false
end

touch_id = touch_id or 0
x, y = CalculateTouchPosition(x, y)

-- Send unset touch message
TouchTracking[touch_id] = nil
DEPLS.NoteManager.SetTouch(nil, touch_id, true)
end

function love.mousemoved(x, y, dx, dy, touch_id)
if touch_id == true then return end

if isMousePress or touch_id then
touch_id = touch_id or 0

local lastpos = TouchTracking[touch_id]

x, y = CalculateTouchPosition(x, y)

for i = 1, 9 do
local idolpos = DEPLS.IdolPosition[i]

if i ~= lastpos and distance(x - (idolpos[1] + 64), y - (idolpos[2] + 64)) <= 77 then
TouchTracking[touch_id] = i
DEPLS.NoteManager.SetTouch(i, touch_id, false, lastpos)

break
end
end
end
end

local function update_audio_volume()
if DEPLS.Sound.LiveAudio then
DEPLS.Sound.LiveAudio:setVolume(DEPLS.BeatmapAudioVolume)
Expand Down
2 changes: 1 addition & 1 deletion main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

local JSON = require("JSON")
local Yohane = require("Yohane")
DEPLS_VERSION = "20170404"
DEPLS_VERSION = "20170416"

FontManager = require("font_manager")
LogicalScale = {
Expand Down
50 changes: 47 additions & 3 deletions note.lua
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ end

local SingleNoteObject = {}
local LongNoteObject = {}
local PreviousSlideNote = nil
local PredefinedSlideRotation = {
math.rad(-90),
math.rad(-67.5),
math.rad(-45),
math.rad(-22.5),
0,
math.rad(22.5),
math.rad(45),
math.rad(67.5),
math.rad(90)
}

--! @brief Creates new SingleNoteObject
--! @param note_data SIF-compilant note data
Expand Down Expand Up @@ -120,7 +132,22 @@ local function NewNoteObject(note_data)
elseif note_data.effect == 4 then
-- Star note
noteobj.StarNote = true
elseif note_data.effect == 11 then
-- Slide note
noteobj.SlideNote = true

if PreviousSlideNote then
noteobj.Rotation =
(PreviousSlideNote.Position - note_data.position > 0 and 0 or math.pi) + PredefinedSlideRotation[note_data.position]
noteobj.PreviousChain = PreviousSlideNote

PreviousSlideNote.NextChain = noteobj
end

PreviousSlideNote = noteobj
elseif note_data.effect == 3 then
PreviousSlideNote = nil

-- Long note. Use LongNoteObject metatable
noteobj.Audio2 = {
Perfect = DEPLS.Sound.PerfectTap:clone(),
Expand All @@ -146,6 +173,10 @@ local function NewNoteObject(note_data)
return noteobj
end

if note_data.effect ~= 11 then
PreviousSlideNote = nil
end

-- SingleNoteObject in here
noteobj.Audio.StarExplode = DEPLS.Sound.StarExplode:clone()
noteobj.ScoreMultipler2 = 1
Expand Down Expand Up @@ -198,7 +229,6 @@ function SingleNoteObject.Update(this, deltaT)
Note.Miss = Note.Miss + 1
return
end

end

local setBlendMode = love.graphics.setBlendMode
Expand All @@ -207,7 +237,7 @@ function SingleNoteObject.Draw(this)
local setColor = love.graphics.setColor

setColor(255, 255, 255, DEPLS.LiveOpacity)
draw(this.NoteImage, this.FirstCircle[1], this.FirstCircle[2], 0, this.CircleScale, this.CircleScale, 64, 64)
draw(this.NoteImage, this.FirstCircle[1], this.FirstCircle[2], this.Rotation or 0, this.CircleScale, this.CircleScale, 64, 64)

if DEPLS.DebugNoteDistance then
local dist = distance(this.FirstCircle[1] - this.CenterIdol[1], this.FirstCircle[2] - this.CenterIdol[2])
Expand Down Expand Up @@ -596,6 +626,15 @@ local function initnote_pos(a)
local obj = Note[a][i]

obj.NoteImage = DEPLS.NoteImageLoader.LoadNoteImage(obj.Attribute, obj.TokenNote, obj.SimulNote, obj.StarNote, obj.SlideNote)

if obj.SlideNote and obj.Rotation == nil then
-- Use from next chain to determine position
if obj.NextChain then
obj.Rotation = (obj.Position - obj.NextChain.Position > 0 and 0 or math.pi) + PredefinedSlideRotation[obj.Position]
else
obj.Rotation = PredefinedSlideRotation[obj.Position]
end
end
end
end

Expand Down Expand Up @@ -680,7 +719,8 @@ end
--! @param pos The idol position. nil if `release` is true
--! @param touchid The touch ID
--! @param release Is this a touch release message?
function Note.SetTouch(pos, touchid, release)
--! @param previous The previous position, used for slide notes (or nil)
function Note.SetTouch(pos, touchid, release, previous)
if DEPLS.AutoPlay then return end

local ElapsedTime = DEPLS.ElapsedTime
Expand Down Expand Up @@ -719,6 +759,10 @@ function Note.SetTouch(pos, touchid, release)

noteobj = Note[pos][1]

if not(noteobj.SlideNote) and previous then
return
end

if noteobj and ElapsedTime >= noteobj.ZeroAccuracyTime - DEPLS.NotesSpeed then
noteobj:SetTouchID(touchid)

Expand Down
21 changes: 8 additions & 13 deletions noteimage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function NoteImageLoader.CreateNoteV5Style(attribute, is_token, is_simultaneous,
noteimg = assert(new_style[attribute], "Invalid note attribute")
end

local cache_name = string.format("new_%08x%d%d%d%d", attribute,
local cache_name = string.format("new_%08x%d%d%d%d%d", attribute,
cbf_ext and 1 or 0,
is_token and 1 or 0,
is_simultaneous and 1 or 0,
Expand Down Expand Up @@ -111,10 +111,10 @@ function NoteImageLoader.CreateNoteV5Style(attribute, is_token, is_simultaneous,
if is_simultaneous then
love.graphics.draw(note_icons, note_icons_quad.simultaneous)
end
elseif is_star then
love.graphics.draw(noteimg, is_simultaneous and new_style_quad.star_simultaneous or new_style_quad.star)
elseif is_slide then
love.graphics.draw(noteimg, is_simultaneous and new_style_quad.slide_simultaneous or new_style_quad.slide)
elseif is_star then
love.graphics.draw(noteimg, is_simultaneous and new_style_quad.star_simultaneous or new_style_quad.star)
else
love.graphics.draw(noteimg, new_style_quad.normal)

Expand All @@ -134,7 +134,7 @@ end
function NoteImageLoader.CreateNoteOldStyle(attribute, is_token, is_simultaneous, is_star, is_slide)
local noteimg
local cbf_ext = bit.band(attribute, 15) == 15
local cache_name = string.format("old_%08x%d%d%d%d", attribute,
local cache_name = string.format("old_%08x%d%d%d%d%d", attribute,
cbf_ext and 1 or 0,
is_token and 1 or 0,
is_simultaneous and 1 or 0,
Expand Down Expand Up @@ -174,8 +174,8 @@ function NoteImageLoader.CreateNoteOldStyle(attribute, is_token, is_simultaneous
love.graphics.draw(DEPLS.Images.Note.Token)
elseif is_star then
love.graphics.draw(DEPLS.Images.Note.Star)
elseif is_star then
love.graphics.draw(DEPLS.Images.Note.Slide)
elseif is_slide then
love.graphics.draw(DEPLS.Images.Note.Slide, 0, 0, 0, 2, 2)
end

if is_simultaneous then
Expand All @@ -189,14 +189,9 @@ function NoteImageLoader.CreateNoteOldStyle(attribute, is_token, is_simultaneous
return canvas_composition
end

local notes_handler = {NoteImageLoader.CreateNoteOldStyle, NoteImageLoader.CreateNoteV5Style}
function NoteImageLoader.LoadNoteImage(attribute, is_token, is_simultaneous, is_star, is_slide)
if DEPLS.ForceNoteStyle == 2 then
return NoteImageLoader.CreateNoteV5Style(attribute, is_token, is_simultaneous, is_star, is_slide)
elseif DEPLS.ForceNoteStyle == 1 then
return NoteImageLoader.CreateNoteOldStyle(attribute, is_token, is_simultaneous, is_star, is_slide)
else
assert(false, "Invalid note style. Only 1 (old) or 2 (new) note styles are allowed")
end
return assert(notes_handler[DEPLS.ForceNoteStyle], "Invalid note style. Only 1 (old) or 2 (new) note styles are allowed")(attribute, is_token, is_simultaneous, is_star, is_slide)
end

return NoteImageLoader
37 changes: 13 additions & 24 deletions noteloader/load_mid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,8 @@ end

-- returns table, not JSON-encoded file.
local function midi2sif(stream)
if stream:read(4) ~= "MThd" then
error("Not MIDI")
end

if str2dword_be(stream:read(4)) ~= 6 then
error("Header size not 6")
end

assert(stream:read(4) == "MThd", "Not MIDI")
assert(str2dword_be(stream:read(4)) == 6, "Header size not 6")
stream:read(2)

local mtrk_count = str2dword_be("\0\0"..stream:read(2))
Expand All @@ -45,9 +39,7 @@ local function midi2sif(stream)
local tempo = 120 -- Default tempo, 120 BPM
local event_list = {} -- Will be analyzed later. For now, just collect all of it

if ppqn > 32768 then
error("PPQN is negative")
end
assert(ppqn < 32768, "PPQN is negative")

local function insert_event(tick, data)
if event_list[tick] then
Expand All @@ -58,43 +50,41 @@ local function midi2sif(stream)
end

for i = 1, mtrk_count do
if stream:read(4) ~= "MTrk" then
error("Not MIDI Track")
end
assert(stream:read(4) == "MTrk", "Not MIDI Track")

local mtrk_len = str2dword_be(stream:read(4))
local ss = stringstream.create(stream:read(mtrk_len))
local timing_total = 0

if ss:seek("end") ~= mtrk_len then
error("Unexpected EOF")
end
assert(ss:seek("end") == mtrk_len, "Unexpected EOF")
ss:seek("set")

while ss:seek() < mtrk_len do
local timing = read_varint(ss)
local event_byte = ss:read(1):byte()
local event_type = math.floor(event_byte / 16)
local note
local note, velocity

timing_total = timing_total + timing

if event_type == 8 then
note = ss:read(1):byte()
ss:seek("cur", 1)
velocity = ss:read(1):byte()

insert_event(timing_total, {
note = false, -- false = off, true = on.
pos = note,
velocity = velocity,
channel = event_byte % 16
})
elseif event_type == 9 then
note = ss:read(1):byte()
ss:seek("cur", 1)
velocity = ss:read(1):byte()

insert_event(timing_total, {
note = true, -- false = off, true = on.
pos = note,
velocity = velocity,
channel = event_byte % 16
})
elseif event_byte == 255 then
Expand Down Expand Up @@ -126,6 +116,7 @@ local function midi2sif(stream)
data = b.data,
note = b.note,
pos = b.pos,
vel = b.velocity,
channel = b.channel
})
end
Expand All @@ -150,9 +141,7 @@ local function midi2sif(stream)

local mid_idx = top_index - bottom_index + 1

if mid_idx > 9 or mid_idx % 2 == 0 then
error("Failed to analyze note position. Make sure you only use 9 note keys or odd amount of note keys")
end
assert(mid_idx <= 9 and mid_idx % 2 == 1, "Failed to analyze note position. Make sure you only use 9 note keys or odd amount of note keys")

-- If it's not 9 and it's odd, automatically adjust
if mid_idx ~= 9 and midi_idx % 2 == 1 then
Expand Down Expand Up @@ -193,7 +182,7 @@ local function midi2sif(stream)
timing_sec = v.tick * 60 / ppqn / tempo,
notes_attribute = attribute,
notes_level = 1,
effect = effect,
effect = v.vel < 64 and 11 or effect,
effect_value = 2,
position = position
}
Expand Down
2 changes: 1 addition & 1 deletion render_livesim.lua
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ function RenderMode.Start(arg)

-- Init DEPLS
RenderMode.DEPLS = love.filesystem.load("livesim.lua")()
RenderMode.DEPLS.RenderingMode = true
RenderMode.DEPLS.Start({arg[3], arg[4]})
--RenderMode.DEPLS.DebugDisplay = true

-- Set audio
RenderMode.DEPLS.Sound.BeatmapAudio = AudioMixer.SourceList[RenderMode.DEPLS.Sound.LiveAudio].SoundData
Expand Down
4 changes: 4 additions & 0 deletions touch_manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ end
function love.touchreleased(id, x, y, dx, dy, pressure)
return love.mousereleased(x, y, 1, id)
end

function love.touchmoved(id, x, y, dx, dy)
return love.mousemoved(x, y, dx, dy, id)
end

0 comments on commit 9701b5f

Please sign in to comment.