diff --git a/inc/meta/meta.assets.lua b/inc/meta/meta.assets.lua index 55768d1..a97fea2 100644 --- a/inc/meta/meta.assets.lua +++ b/inc/meta/meta.assets.lua @@ -397,13 +397,13 @@ -- -- -- 000:060006400600064006000640060006400600060006000600060006000600060006000600060006000600060006000600060006000600060006000600300000000900 --- 016:05000500050005400540054005700570057005400540054005700570057005c005c005c005c005c005c005c005c005c005c005c005c005c005c005c0470000000000 --- 017:040004000400040004000400046004600460046004600460146024c034c054c064c084c0a4c0b4c0c4c0c4c0d4c0d4c0e4c0f4c0f4c0f4c0f4c0f4c0400000000000 --- 018:04c004c004c004c004c004c0046004600460046004600460240034005400640084009400a400b400c400d400d400e400e400e400f400f400f400f400300000000000 --- 019:0400040004000400040004d014d014d024d034d054d074d094d0b4d0c4d0e4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0f4d0400000000000 +-- 016:00000000000000400040004000700070007000400040004000700070007000c000c000c000c000c000c000c000c000c000c000c000c000c000c000c0470000000000 +-- 017:000000000000000000000000006000600060006000600060106020c030c050c060c080c0a0c0b0c0c0c0c0c0d0c0d0c0e0c0f0c0f0c0f0c0f0c0f0c0400000000000 +-- 018:00c000c000c000c000c000c0006000600060006000600060200030005000600080009000a000b000c000d000d000e000e000e000f000f000f000f000500000000000 +-- 019:0000000000000000000000d010d010d020d030d050d070d090d0b0d0c0d0e0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0f0d0500000000000 -- 020:090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900500000000000 --- 021:01000100010001000100f10001100110011001100110f11001200120012001200120f1201130113011302130213021302130313041308130a130d130380000000000 --- 032:010001100100011001000110010001100100010001000100010001000100010001000100010001000100010001000100010001000100010001000100301000000800 +-- 021:01000100010001000100f10001100110011001100110f11001200120012001200120f1201130113011302130213021302130313041308130a130d130580000000000 +-- 032:010001100100011001000110010001100100010001000100010001000100010001000100010001000100010001000100010001000100010001000100400000000800 -- 033:000000010002000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d40000000004 -- 044:0600f6000620f6000600f6000610f600f600f6000600f600f600f600f6000600060006000600060006000600060006000600060006000600060006004600000f0f00 -- 045:0000f0000020f0000000f0000010f000f000f0000000f000f000f000f0000000000000000000000000000000000000000000000000000000000000004600000f0f00 @@ -433,10 +433,10 @@ -- 000:4008b50000000000000000001008c10000004008b50000001008c1000000000000000000e008b30000004008b50000001008c10000000008c10000000008c10000000000000000000000000000000000000000000000000000000000000000004008b50000000000000000001008c10000004008b50000001008c10000000008c1000000e008b30000004008b50000001008c10000000008c10000000008c10000000008c10000000008c10000000008c1000000000000000000000000000000 -- 001:4008b50000000000000000001008c10000004008b50000001008c1000000000000000000e008b30000004008b50000001008c10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007008b50000007008b50000001008c10000007008b50000001008c10000000008c10000007008b50000009008b50000001008c10000009008b50000001008c10000009008b50000009008b50000001008c10000009008b50000001008c1000000 -- 003:4008d30000000000000000000000000000000000000000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000004008d30000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000000000000000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000004008d30000004008d9000000000000000000000000000000000000000000 --- 004:40088d000000e0088b000000b0088b000881e0088b00000040088d000000e0088b000881b0088b000000e0088b00000040088d000000e0088b000000b0088b000000e0088b00000040088d000000e0088b000000b0088b000000e0088b00000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e00889000000 +-- 004:49998d000000e0088b000000b0088b000881e0088b00000040088d000000e0088b000881b0088b000000e0088b00000040088d000000e0088b000000b0088b000000e0088b00000040088d000000e0088b000000b0088b000000e0088b00000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e0088900000040088b000000e00889000000b00889000000e00889000000 -- 005:400881000000000881000000000881000000000000000000400883000000000000000000000000000000000000000000400881000000000000000000000000000000000000000000400883000000000000000000000000000000000000000000400881000000000000000000000000000000000000000000400883000000000000000000000000000000000000000000400881000000000000000000000000000000000000000000400883000000000000000000000000000000000000000000 -- -- --- 000:100001200001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +-- 000:1000012000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff -- 001:581000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- diff --git a/inc/window/window.menu.lua b/inc/window/window.menu.lua index 80dbe99..2c33637 100644 --- a/inc/window/window.menu.lua +++ b/inc/window/window.menu.lua @@ -81,6 +81,14 @@ function MenuWindow.continued() GameWindow.set_state("continued") end +--- Opens the minigame ddr test menu. +--- @within MenuWindow +function MenuWindow.ddr_test() + AudioTestWindow.init() + GameWindow.set_state("minigame_ddr") + MinigameDDRWindow.start("menu", nil) +end + --- Refreshes menu items. --- @within MenuWindow function MenuWindow.refresh_menu_items() @@ -95,6 +103,7 @@ function MenuWindow.refresh_menu_items() table.insert(_menu_items, {label = "Configuration", decision = MenuWindow.configuration}) table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test}) table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued}) + table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test}) table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit}) Context.current_menu_item = 1 diff --git a/inc/window/window.minigame.ddr.lua b/inc/window/window.minigame.ddr.lua index ea2694b..439ca4a 100644 --- a/inc/window/window.minigame.ddr.lua +++ b/inc/window/window.minigame.ddr.lua @@ -140,17 +140,17 @@ local function draw_arrow(x, y, direction, color) local size = 12 local half = size / 2 if direction == "left" then - tri(x + half, y, x, y + half, x + half, y + size, color) - rect(x + half, y + half - 2, half, 4, color) + trib(x + half, y, x, y + half, x + half, y + size, color) + rectb(x + half, y + half - 2, half, 4, color) elseif direction == "right" then - tri(x + half, y, x + size, y + half, x + half, y + size, color) - rect(x, y + half - 2, half, 4, color) + trib(x + half, y, x + size, y + half, x + half, y + size, color) + rectb(x, y + half - 2, half, 4, color) elseif direction == "up" then - tri(x, y + half, x + half, y, x + size, y + half, color) - rect(x + half - 2, y + half, 4, half, color) + trib(x, y + half, x + half, y, x + size, y + half, color) + rectb(x + half - 2, y + half, 4, half, color) elseif direction == "down" then - tri(x, y + half, x + half, y + size, x + size, y + half, color) - rect(x + half - 2, y, 4, half, color) + trib(x, y + half, x + half, y + size, x + size, y + half, color) + rectb(x + half - 2, y, 4, half, color) end end diff --git a/tools/musicator/musicator.lua b/tools/musicator/musicator.lua new file mode 100644 index 0000000..8da1ea4 --- /dev/null +++ b/tools/musicator/musicator.lua @@ -0,0 +1,130 @@ +unpack = unpack or table.unpack + +function build_markov_model(sequence, order) + local function make_key(tbl) + return table.concat(tbl, "|") + end + + local function unmake_key(k) + local result = {} + for t in string.gmatch(k, "[^|]+") do + result[#result + 1] = t + end + + return result + end + + local function add_key(str, value) + return str .. "|" .. value + end + + local function split_last(full) + local i = full:match(".*()|") + return full:sub(1, i-1), full:sub(i+1) + end + + local counts = {} + local totals = {} + + -- count + for i = 1, #sequence - order do + local notes = make_key({unpack(sequence, i, i + order - 1)}) + totals[notes] = (totals[notes] or 0) + 1 + + local notes_full = add_key(notes, sequence[i + order]) + counts[notes_full] = (counts[notes_full] or 0) + 1 + end + + -- build model + local model = {} + + for notes_full,count in pairs(counts) do + local notes, _ = split_last(notes_full) + + model[notes_full] = count[notes_full] / total[notes] + end + + return { + order = order, + model = model, + counts = counts -- keep raw counts (useful!) + } +end + +function generate_sequence(model_data, length) + local model = model_data.model + local order = model_data.order + + -- helper: split key into parts + local function split(k) + local t = {} + for part in string.gmatch(k, "[^|]+") do + t[#t+1] = part + end + return t + end + + -- pick random starting state + local start_key + for k,_ in pairs(model) do + start_key = k + break + end + + -- (optional: better random start) + for k,_ in pairs(model) do + if math.random() < 0.1 then + start_key = k + end + end + + local parts = split(start_key) + + -- initial sequence = first `order` items + local seq = {} + for i = 1, order do + seq[i] = parts[i] + end + + -- generation loop + while #seq < length do + -- build current state key + local state = table.concat({unpack(seq, #seq - order + 1, #seq)}, "|") + + -- collect matching transitions + local matches = {} + for full,prob in pairs(model) do + if full:sub(1, #state) == state and full:sub(#state+1, #state+1) == "|" then + matches[#matches+1] = {key=full, prob=prob} + end + end + + if #matches == 0 then break end + + -- weighted pick + local r = math.random() + local sum = 0 + + local chosen + for _,m in ipairs(matches) do + sum = sum + m.prob + if r <= sum then + chosen = m.key + break + end + end + + if not chosen then + chosen = matches[#matches].key + end + + -- extract next symbol (after last '|') + local next_symbol = chosen:match("|([^|]+)$") + + seq[#seq+1] = next_symbol + end + + return seq +end + +-- todo: feed samples diff --git a/tools/musicator/sample_1.lua b/tools/musicator/sample_1.lua new file mode 100644 index 0000000..b5b909e --- /dev/null +++ b/tools/musicator/sample_1.lua @@ -0,0 +1 @@ +-- todo