forked from Yonokid/PyTaikoGreen
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e694d4952 | ||
|
|
6330aebefd | ||
|
|
8f0c4f69bc | ||
|
|
f7f7d5cb4e | ||
|
|
45ed83d19c | ||
|
|
565c6e4eae | ||
|
|
d31a03ab58 | ||
|
|
4011ce9f60 | ||
|
|
5d6967ec47 | ||
|
|
5d9fd60406 | ||
|
|
48a33b09d5 | ||
|
|
7a58faf27c | ||
|
|
6dea3a00b5 | ||
|
|
2081847b4f | ||
|
|
c911cc29de | ||
|
|
6b12833bea | ||
|
|
1a762ee396 | ||
|
|
613a750706 | ||
|
|
080bd0b5d4 | ||
|
|
5490fdd94f |
No files matched your search
+814
-731
File diff suppressed because it is too large.
Load diff
Binary file not shown.
@@ -1,90 +1,114 @@
|
||||
{
|
||||
"judge_bad": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"judge_ok": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"judge_good": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"hit_effect_good_big": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_good_big": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"hit_effect_good": {
|
||||
"x": 342
|
||||
},
|
||||
"hit_effect_ok": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_good": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"outer_ok": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"hit_effect_ok_big": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_ok_big": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"explosion": [
|
||||
{
|
||||
"crop": [
|
||||
[0, 0, 192, 192],
|
||||
[192, 0, 192, 192],
|
||||
[384, 0, 192, 192],
|
||||
[576, 0, 192, 192],
|
||||
[0, 192, 192, 192],
|
||||
[192, 192, 192, 192],
|
||||
[384, 192, 192, 192],
|
||||
[576, 192, 192, 192],
|
||||
[0, 384, 192, 192],
|
||||
[192, 384, 192, 192],
|
||||
[384, 384, 192, 192],
|
||||
[576, 384, 192, 192],
|
||||
[0, 576, 192, 192],
|
||||
[192, 576, 192, 192],
|
||||
[384, 576, 192, 192],
|
||||
[576, 576, 192, 192],
|
||||
[0, 768, 192, 192],
|
||||
[192, 768, 192, 192],
|
||||
[384, 768, 192, 192],
|
||||
[576, 768, 192, 192],
|
||||
[0, 960, 192, 192],
|
||||
[192, 960, 192, 192],
|
||||
[384, 960, 192, 192]]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"judge_bad": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"judge_ok": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"judge_good": {
|
||||
"x": 370,
|
||||
"y": -40
|
||||
},
|
||||
"hit_effect_good_big": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_good_big": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"hit_effect_good": {
|
||||
"x": 342
|
||||
},
|
||||
"hit_effect_ok": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_good": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"outer_ok": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"hit_effect_ok_big": {
|
||||
"x": 342
|
||||
},
|
||||
"outer_ok_big": {
|
||||
"x": 304,
|
||||
"y": -41,
|
||||
"crop": [
|
||||
[0, 0, 224, 224],
|
||||
[224, 0, 224, 224],
|
||||
[448, 0, 224, 224],
|
||||
[672, 0, 224, 224]]
|
||||
},
|
||||
"explosion": [
|
||||
{
|
||||
"crop": [
|
||||
[0, 0, 192, 192],
|
||||
[192, 0, 192, 192],
|
||||
[384, 0, 192, 192],
|
||||
[576, 0, 192, 192],
|
||||
[0, 192, 192, 192],
|
||||
[192, 192, 192, 192],
|
||||
[384, 192, 192, 192],
|
||||
[576, 192, 192, 192],
|
||||
[0, 384, 192, 192],
|
||||
[192, 384, 192, 192],
|
||||
[384, 384, 192, 192],
|
||||
[576, 384, 192, 192],
|
||||
[0, 576, 192, 192],
|
||||
[192, 576, 192, 192],
|
||||
[384, 576, 192, 192],
|
||||
[576, 576, 192, 192],
|
||||
[0, 768, 192, 192],
|
||||
[192, 768, 192, 192],
|
||||
[384, 768, 192, 192],
|
||||
[576, 768, 192, 192],
|
||||
[0, 960, 192, 192],
|
||||
[192, 960, 192, 192],
|
||||
[384, 960, 192, 192]]
|
||||
}
|
||||
],
|
||||
"outer_effect_ok": {
|
||||
"x": 304,
|
||||
"y": -41
|
||||
},
|
||||
"outer_effect_good": {
|
||||
"x": 304,
|
||||
"y": -41
|
||||
},
|
||||
"firework": {
|
||||
"crop": [
|
||||
[0, 0, 256, 256],
|
||||
[256, 0, 256, 256],
|
||||
[512, 0, 256, 256],
|
||||
[768, 0, 256, 256],
|
||||
[0, 256, 256, 256],
|
||||
[256, 256, 256, 256],
|
||||
[512, 256, 256, 256],
|
||||
[768, 256, 256, 256],
|
||||
[0, 512, 256, 256],
|
||||
[256, 512, 256, 256],
|
||||
[512, 512, 256, 256],
|
||||
[768, 512, 256, 256],
|
||||
[0, 768, 256, 256]]
|
||||
}
|
||||
}
|
||||
@@ -1565,6 +1565,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"device": {
|
||||
"path": "audio/device",
|
||||
"name": {
|
||||
"en": "Audio Device",
|
||||
"ja": "オーディオデバイス",
|
||||
"zh": "音频设备",
|
||||
"ko": "오디오 장치"
|
||||
},
|
||||
"description": {
|
||||
"en": "Output device to use for the selected backend. Default uses the system default device.",
|
||||
"ja": "選択したバックエンドで使用する出力デバイス。デフォルトはシステムの既定デバイスを使用します。",
|
||||
"zh": "为所选后端使用的输出设备。默认使用系统默认设备。",
|
||||
"ko": "선택한 백엔드에서 사용할 출력 장치. 기본값은 시스템 기본 장치를 사용합니다."
|
||||
},
|
||||
"type": "audiodevice",
|
||||
"values": {
|
||||
"": {
|
||||
"en": "Default",
|
||||
"ja": "デフォルト",
|
||||
"zh": "默认",
|
||||
"ko": "기본값"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sample_rate": {
|
||||
"path": "audio/sample_rate",
|
||||
"name": {
|
||||
|
||||
@@ -13,15 +13,14 @@
|
||||
"dan_select_rank_plate": false,
|
||||
"entry_credit_arcade": false,
|
||||
"dan_confirm_yes_left": false,
|
||||
"songselect_2p_join": false,
|
||||
"costume_preset_slots": false,
|
||||
"dan_title_horizontal": false,
|
||||
"dan_chip_name_black": false,
|
||||
"dan_exam_grid": false,
|
||||
"dan_select_total_notes": true,
|
||||
"combo_color_tiers": false,
|
||||
"gauge_cell_fade_in": false,
|
||||
"dan_exam_value_center": false
|
||||
"dan_exam_value_center": false,
|
||||
"disable_chara_3d": false
|
||||
},
|
||||
"chara_3d": {
|
||||
"scale": 650.0,
|
||||
|
||||
@@ -12,11 +12,6 @@
|
||||
"y": 129
|
||||
},
|
||||
"background": {},
|
||||
"background_static": {},
|
||||
"bar_genre": {},
|
||||
"bar_genre_back": {},
|
||||
"bar_genre_overlay": {},
|
||||
"box_chara": {},
|
||||
"folder_texture_left": {
|
||||
"y": 95
|
||||
},
|
||||
@@ -41,32 +36,6 @@
|
||||
"x": 483,
|
||||
"y": 189
|
||||
},
|
||||
"folder_text": {
|
||||
"x": 650,
|
||||
"y": 125,
|
||||
"frame_order": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
18
|
||||
]
|
||||
},
|
||||
"folder_graphic": {
|
||||
"x": 470,
|
||||
"y": 180,
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
{
|
||||
"difficulty_back": {},
|
||||
"difficulty_crown": {},
|
||||
"difficulty_star": {},
|
||||
"difficulty_bar": {},
|
||||
"difficulty_select_bar": {},
|
||||
"difficulty_select_bar2": {},
|
||||
"1p_outline": {
|
||||
"x": 461,
|
||||
"y": 132
|
||||
|
||||
@@ -11,22 +11,10 @@
|
||||
"x": 20,
|
||||
"y": 64
|
||||
},
|
||||
"frame_score": {},
|
||||
"level_number": {},
|
||||
"score_rank": {},
|
||||
"crown_badge": {},
|
||||
"song_count_back": {
|
||||
"x": 470,
|
||||
"y": 125
|
||||
},
|
||||
"song_count_num": {
|
||||
"x": 475,
|
||||
"y": 125
|
||||
},
|
||||
"song_count_songs": {
|
||||
"x": 600,
|
||||
"y": 125
|
||||
},
|
||||
"s_crown_dfc": {
|
||||
"x": 473,
|
||||
"y": 175
|
||||
|
||||
@@ -98,8 +98,6 @@ function Background.new(player_num, bpm, scene_preset)
|
||||
self.scene_preset = scene_preset
|
||||
self.is_2p = (player_num == 3) -- PlayerNum::TWO_PLAYER
|
||||
|
||||
tex.load_animations("background")
|
||||
|
||||
local entry = scene_preset and COLLABS[scene_preset]
|
||||
if entry then
|
||||
local ctor, path, max_dancers = entry[1], entry[2], entry[3]
|
||||
|
||||
@@ -38,7 +38,7 @@ function A3BGNormal.new()
|
||||
local self = setmetatable({}, A3BGNormal)
|
||||
self.name = "bg_0"
|
||||
tex.load_folder(COLLAB_PATH, "bg_normal/" .. self.name)
|
||||
self.flicker = tex.get_animation(9)
|
||||
self.flicker = tex.get_animation(9, "background")
|
||||
self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "background") or 0
|
||||
self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
self._id_curtain = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "curtain") or 0
|
||||
@@ -70,8 +70,8 @@ function A3BGFever.new()
|
||||
self.name = "bg_fever_0"
|
||||
tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name)
|
||||
self.transitioned = false
|
||||
self.horizontal_move = tex.get_animation(16)
|
||||
self.bg_texture_move = tex.get_animation(17)
|
||||
self.horizontal_move = tex.get_animation(16, "background")
|
||||
self.bg_texture_move = tex.get_animation(17, "background")
|
||||
local petal_info = tex.get_texture_info(self.name, "petals")
|
||||
self.petal_width = petal_info and petal_info.width or 0
|
||||
self.vertical_move = anim.move(1300, { total_distance = self.petal_width, loop = true })
|
||||
|
||||
@@ -13,7 +13,7 @@ function DanDonBG.new(player_num)
|
||||
local self = setmetatable({}, DanDonBG)
|
||||
local base = DonBGBase.new(1, player_num, COLLAB_PATH)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
self.overlay_move = tex.get_animation(2)
|
||||
self.overlay_move = tex.get_animation(2, "background")
|
||||
local bg_overlay_info = tex.get_texture_info(self.name, "bg_overlay")
|
||||
self.bg_overlay_width = bg_overlay_info and bg_overlay_info.width or 0
|
||||
local bg_overlay_2_info = tex.get_texture_info(self.name, "bg_overlay_2")
|
||||
|
||||
@@ -18,8 +18,8 @@ function FunassyiBGFever.new()
|
||||
self.name = "bg_fever_0"
|
||||
tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name)
|
||||
self.transitioned = false
|
||||
self.horizontal_move = tex.get_animation(16)
|
||||
self.bg_texture_move = tex.get_animation(17)
|
||||
self.horizontal_move = tex.get_animation(16, "background")
|
||||
self.bg_texture_move = tex.get_animation(17, "background")
|
||||
local overlay_info = tex.get_texture_info(self.name, "overlay")
|
||||
self.overlay_width = overlay_info and overlay_info.width or 0
|
||||
self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "background") or 0
|
||||
|
||||
@@ -12,7 +12,7 @@ function TutorialDonBG.new(index, player_num, path)
|
||||
end
|
||||
self.move = anim.move(6000, { total_distance = -self.bg_texture.width, loop = true })
|
||||
self.move:start()
|
||||
self.overlay_move = tex.get_animation(2)
|
||||
self.overlay_move = tex.get_animation(2, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self.footer_texture = tex.get_texture_info(self.name, "footer")
|
||||
self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
|
||||
@@ -46,8 +46,8 @@ function BGFever0.new(index, path)
|
||||
self.overlay_move_up = anim.move(133, {total_distance = 360, ease_out = "quadratic", delay = 300})
|
||||
self.overlay_move_down = anim.move(133, {total_distance = 160, ease_in = "quadratic", delay = 433})
|
||||
|
||||
self.wave_spin = tex.get_animation(28)
|
||||
self.bg_move = tex.get_animation(16)
|
||||
self.wave_spin = tex.get_animation(28, "background")
|
||||
self.bg_move = tex.get_animation(16, "background")
|
||||
|
||||
self.circle = {
|
||||
center_x = 100 * self.screen_scale,
|
||||
@@ -162,10 +162,10 @@ function BGFever1.new(index, path)
|
||||
local base = BGFeverBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
|
||||
self.fadein = tex.get_animation(19)
|
||||
self.bg_texture_change = tex.get_animation(20)
|
||||
self.ship_rotation = tex.get_animation(21)
|
||||
self.move_in = tex.get_animation(22)
|
||||
self.fadein = tex.get_animation(19, "background")
|
||||
self.bg_texture_change = tex.get_animation(20, "background")
|
||||
self.ship_rotation = tex.get_animation(21, "background")
|
||||
self.move_in = tex.get_animation(22, "background")
|
||||
|
||||
local ship_info = tex.get_texture_info(self.name, "ship")
|
||||
self.ship_origin = {
|
||||
@@ -226,13 +226,13 @@ function BGFever2.new(index, path)
|
||||
|
||||
self.screen_scale = tex.get_screen_scale()
|
||||
|
||||
self.fadein = tex.get_animation(19)
|
||||
self.move_in = tex.get_animation(24)
|
||||
self.footer_move_up = tex.get_animation(26)
|
||||
self.bird_tc = tex.get_animation(20)
|
||||
self.overlay_tc = tex.get_animation(25)
|
||||
self.circle_rotate = tex.get_animation(27)
|
||||
self.fish_spin = tex.get_animation(28)
|
||||
self.fadein = tex.get_animation(19, "background")
|
||||
self.move_in = tex.get_animation(24, "background")
|
||||
self.footer_move_up = tex.get_animation(26, "background")
|
||||
self.bird_tc = tex.get_animation(20, "background")
|
||||
self.overlay_tc = tex.get_animation(25, "background")
|
||||
self.circle_rotate = tex.get_animation(27, "background")
|
||||
self.fish_spin = tex.get_animation(28, "background")
|
||||
|
||||
self.circle = {
|
||||
center_x = 500 * self.screen_scale,
|
||||
@@ -366,9 +366,9 @@ function BGFever3.new(index, path)
|
||||
local base = BGFeverBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
|
||||
self.vertical_move = tex.get_animation(15)
|
||||
self.horizontal_move = tex.get_animation(16)
|
||||
self.bg_texture_move = tex.get_animation(17)
|
||||
self.vertical_move = tex.get_animation(15, "background")
|
||||
self.horizontal_move = tex.get_animation(16, "background")
|
||||
self.bg_texture_move = tex.get_animation(17, "background")
|
||||
|
||||
self._id_bg = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "background") or 0
|
||||
self._id_overlay_1 = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay_1") or 0
|
||||
|
||||
@@ -28,7 +28,7 @@ function BGNormal01.new(index, path)
|
||||
local self = setmetatable({}, BGNormal01)
|
||||
local base = BGNormalBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
self.flicker = tex.get_animation(9)
|
||||
self.flicker = tex.get_animation(9, "background")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
return self
|
||||
end
|
||||
@@ -50,7 +50,7 @@ function BGNormal2.new(index, path)
|
||||
local self = setmetatable({}, BGNormal2)
|
||||
local base = BGNormalBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
self.flicker = tex.get_animation(10)
|
||||
self.flicker = tex.get_animation(10, "background")
|
||||
self._id_center = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "center") or 0
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
self._id_lamps = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "lamps") or 0
|
||||
@@ -114,9 +114,9 @@ function BGNormal3.new(index, path)
|
||||
local self = setmetatable({}, BGNormal3)
|
||||
local base = BGNormalBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
self.flicker = tex.get_animation(11)
|
||||
self.turtle_move = tex.get_animation(12)
|
||||
self.turtle_change = tex.get_animation(13)
|
||||
self.flicker = tex.get_animation(11, "background")
|
||||
self.turtle_move = tex.get_animation(12, "background")
|
||||
self.turtle_change = tex.get_animation(13, "background")
|
||||
self.screen_scale = tex.get_screen_scale()
|
||||
self.screen_width = tex.get_screen_width()
|
||||
self.screen_height = tex.get_screen_height()
|
||||
@@ -171,7 +171,7 @@ function BGNormal4.new(index, path)
|
||||
local self = setmetatable({}, BGNormal4)
|
||||
local base = BGNormalBase.new(index, path)
|
||||
for k, v in pairs(base) do self[k] = v end
|
||||
self.flicker = tex.get_animation(14)
|
||||
self.flicker = tex.get_animation(14, "background")
|
||||
self._id_paper_lamp = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "paper_lamp") or 0
|
||||
self._id_light_overlay= tex.get_texture(self.path .. "/" .. self.name .. "/" .. "light_overlay") or 0
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
|
||||
@@ -10,7 +10,7 @@ function DonBG1.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.overlay_move = tex.get_animation(2)
|
||||
self.overlay_move = tex.get_animation(2, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self.footer_texture = tex.get_texture_info(self.name, "footer")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
|
||||
@@ -9,7 +9,7 @@ function DonBG2.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.overlay_move = tex.get_animation(3)
|
||||
self.overlay_move = tex.get_animation(3, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
return self
|
||||
|
||||
@@ -8,10 +8,10 @@ function DonBG3.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.bounce = tex.get_animation(4)
|
||||
self.bounce = tex.get_animation(4, "background")
|
||||
self.bounce:start()
|
||||
self.overlay_move = tex.get_animation(6)
|
||||
self.overlay_move_2 = tex.get_animation(7)
|
||||
self.overlay_move = tex.get_animation(6, "background")
|
||||
self.overlay_move_2 = tex.get_animation(7, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
return self
|
||||
|
||||
@@ -8,7 +8,7 @@ function DonBG4.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.overlay_move = tex.get_animation(2)
|
||||
self.overlay_move = tex.get_animation(2, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
return self
|
||||
|
||||
@@ -8,9 +8,9 @@ function DonBG5.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.bounce = tex.get_animation(4)
|
||||
self.bounce = tex.get_animation(4, "background")
|
||||
self.bounce:start()
|
||||
self.adjust = tex.get_animation(8)
|
||||
self.adjust = tex.get_animation(8, "background")
|
||||
self.overlay_texture = tex.get_texture_info(self.name, "overlay")
|
||||
self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay") or 0
|
||||
return self
|
||||
|
||||
@@ -8,7 +8,7 @@ function DonBG6.new(index, player_num, path)
|
||||
for k, v in pairs(base) do
|
||||
self[k] = v
|
||||
end
|
||||
self.overlay_move = tex.get_animation(2)
|
||||
self.overlay_move = tex.get_animation(2, "background")
|
||||
self.overlay_1_texture = tex.get_texture_info(self.name, "overlay_1")
|
||||
self.overlay_2_texture = tex.get_texture_info(self.name, "overlay_2")
|
||||
self._id_overlay_1 = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay_1") or 0
|
||||
|
||||
@@ -16,7 +16,7 @@ function DonBGBase.new(index, player_num, path)
|
||||
self.move:start()
|
||||
|
||||
self.is_clear = false
|
||||
self.clear_fade = tex.get_animation(1)
|
||||
self.clear_fade = tex.get_animation(1, "background")
|
||||
|
||||
self._id_bg = tex.get_texture(self.path .. "/" .. self.name .. "/" .. "background") or 0
|
||||
|
||||
|
||||
@@ -0,0 +1,487 @@
|
||||
-- DanSelect scene rendering. Mirrors src/scenes/dan_select.cpp + DanBox
|
||||
-- (src/objects/song_select/file_navigator/box_dan.cpp).
|
||||
-- The DanBox draw methods (draw_chip / draw_open / draw_exam_box / draw_exam_grid) are
|
||||
-- ported here; the C++ side only prepares the data (load_text) and hands the box over.
|
||||
|
||||
DanSelect = {}
|
||||
DanSelect.__index = DanSelect
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Texture / config helpers (the dan_select screen has its own box/yellow_box subsets).
|
||||
-- ---------------------------------------------------------------------------
|
||||
local _tex = {}
|
||||
local function T(subset, name)
|
||||
local key = subset .. "/" .. name
|
||||
local id = _tex[key]
|
||||
if id == nil then
|
||||
id = tex.get_texture("dan_select/" .. subset .. "/" .. name)
|
||||
_tex[key] = id
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
local function cfg(name)
|
||||
return tex.get_skin_config(name)
|
||||
end
|
||||
|
||||
local function opt(name)
|
||||
return tex.get_option(name)
|
||||
end
|
||||
|
||||
-- Texture draw-offset at index 0 (TextureObject::x[0] / y[0] / x2[0]).
|
||||
local function tex_x0(subset, name)
|
||||
local info = tex.get_texture_info(subset, name)
|
||||
if info and info.x and info.x[1] then return info.x[1] end
|
||||
return 0
|
||||
end
|
||||
local function tex_y0(subset, name)
|
||||
local info = tex.get_texture_info(subset, name)
|
||||
if info and info.y and info.y[1] then return info.y[1] end
|
||||
return 0
|
||||
end
|
||||
local function tex_x2(subset, name)
|
||||
local info = tex.get_texture_info(subset, name)
|
||||
if info and info.x2 and info.x2[1] then return info.x2[1] end
|
||||
return 0
|
||||
end
|
||||
|
||||
-- exam.type -> icon texture name (exam_icon_id in box_dan.cpp). "renda" resolves to
|
||||
-- exam_roll, falling back to exam_drumroll in older skins. Returns the resolved name.
|
||||
local EXAM_ICON = {
|
||||
gauge = "exam_gauge", combo = "exam_combo",
|
||||
hit = "exam_hit", judgebad = "exam_judgebad",
|
||||
judgegood = "exam_judgegood", judgeperfect = "exam_judgeperfect",
|
||||
score = "exam_score", renda = "exam_roll",
|
||||
}
|
||||
local function exam_icon_name(type)
|
||||
local name = EXAM_ICON[type]
|
||||
if not name then return nil end
|
||||
if T("yellow_box", name) then return name end
|
||||
if T("yellow_box", "exam_drumroll") then return "exam_drumroll" end
|
||||
return nil
|
||||
end
|
||||
|
||||
local yb_box = { path = nil, state = "closed" }
|
||||
|
||||
function DanSelect.new()
|
||||
local self = setmetatable({}, DanSelect)
|
||||
yb_box.path, yb_box.state = nil, "closed"
|
||||
return self
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Yellow box (the 9-slice board the course details sit on). The dan box is always in
|
||||
-- diff-select once open, so it uses the diff-select animation set (13..18); the engine no
|
||||
-- longer drives them, so the skin advances them here (see DanSelect:update / track).
|
||||
-- ---------------------------------------------------------------------------
|
||||
local YB_DIFF_ANIMS = { 13, 14, 15, 16, 17, 18 }
|
||||
|
||||
local function draw_dan_yellow_box(is_diff, fade)
|
||||
local right_x = tex.get_animation(is_diff and 14 or 10).attribute
|
||||
local left_x = tex.get_animation(is_diff and 13 or 9).attribute
|
||||
local center_width = tex.get_animation(is_diff and 15 or 11).attribute
|
||||
local top_y = tex.get_animation(16).attribute
|
||||
local center_height = tex.get_animation(17).attribute
|
||||
local bottom_y = (cfg("yellow_box_bottom") or { y = 0 }).y
|
||||
local info = tex.get_texture_info("yellow_box", "yellow_box_bottom_right")
|
||||
local eh = (info and info.height) or 0
|
||||
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom_right"), { x = right_x, y = bottom_y, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom_left"), { x = left_x, y = bottom_y, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top_right"), { x = right_x, y = top_y, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top_left"), { x = left_x, y = top_y, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom"), { x = left_x + eh, y = bottom_y, x2 = center_width, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_right"), { x = right_x, y = top_y + eh, y2 = center_height, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_left"), { x = left_x, y = top_y + eh, y2 = center_height, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top"), { x = left_x + eh, y = top_y, x2 = center_width, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_center"), { x = left_x + eh, y = top_y + eh, x2 = center_width, y2 = center_height, fade = fade })
|
||||
end
|
||||
|
||||
-- Track the open box and start the diff-select expansion on the closed -> diff_select
|
||||
-- transition (the dan box never passes through the "open" draw_state).
|
||||
local function track_dan_yellow_box(box)
|
||||
local state = box:draw_state()
|
||||
local path = box:path()
|
||||
if state == "closed" then
|
||||
if yb_box.path == path then
|
||||
yb_box.path, yb_box.state = nil, "closed"
|
||||
end
|
||||
return
|
||||
end
|
||||
if yb_box.path ~= path then
|
||||
yb_box.path, yb_box.state = path, state
|
||||
for _, id in ipairs(YB_DIFF_ANIMS) do tex.get_animation(id):reset() end
|
||||
for _, id in ipairs(YB_DIFF_ANIMS) do tex.get_animation(id):start() end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_dan_yellow_box(ms)
|
||||
for _, id in ipairs(YB_DIFF_ANIMS) do tex.get_animation(id):update(ms) end
|
||||
end
|
||||
|
||||
function DanSelect:update(ms)
|
||||
update_dan_yellow_box(ms)
|
||||
end
|
||||
|
||||
-- Draw a texture at an absolute position, ignoring its own x[0]/y[0] anchor (draw_abs).
|
||||
local function draw_abs(subset, name, X, Y, fade, frame)
|
||||
local id = T(subset, name)
|
||||
if not id then return end
|
||||
tex.draw_texture(id, {
|
||||
frame = frame or 0,
|
||||
x = X - tex_x0(subset, name),
|
||||
y = Y - tex_y0(subset, name),
|
||||
fade = fade,
|
||||
})
|
||||
end
|
||||
|
||||
function DanSelect:draw_box(box)
|
||||
track_dan_yellow_box(box)
|
||||
local state = box:draw_state()
|
||||
if state == "closed" then
|
||||
self:draw_dan_closed(box)
|
||||
else
|
||||
self:draw_dan_open(box)
|
||||
end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- draw_chip (closed): folder board + vertical chip name.
|
||||
-- ---------------------------------------------------------------------------
|
||||
function DanSelect:draw_dan_closed(box)
|
||||
local bx = box:box_x()
|
||||
local fade = box.fade.attribute
|
||||
|
||||
tex.draw_texture(T("box", "folder"), { frame = box.dan_color, x = bx, fade = fade })
|
||||
|
||||
local name = box:chip_name()
|
||||
if name then
|
||||
local nb = cfg("dan_chip_name") or cfg("song_box_name") or { x = 0, y = 0, height = 0 }
|
||||
name:draw({
|
||||
x = bx + nb.x - name.width / 2,
|
||||
y = nb.y,
|
||||
y2 = math.min(name.height, nb.height or name.height) - name.height,
|
||||
fade = fade,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- draw_open: chip + song ribbon + total notes + rank + exam box.
|
||||
-- ---------------------------------------------------------------------------
|
||||
function DanSelect:draw_dan_open(box)
|
||||
self:draw_dan_closed(box)
|
||||
local f = box.open_fade.attribute
|
||||
|
||||
-- The yellow box board the course details sit on (opaque; its growth is driven by
|
||||
-- the diff-select animations, matching the song-select wheel).
|
||||
draw_dan_yellow_box(true, 1.0)
|
||||
|
||||
local off = cfg("dan_yellow_box_offset") or { x = 0, y = 0 }
|
||||
local offset_x = off.x or 0
|
||||
local offset_y = off.y or 0
|
||||
|
||||
local n = box:song_count()
|
||||
for i = 0, n - 1 do
|
||||
local x = i * offset_x
|
||||
local y = i * offset_y
|
||||
|
||||
tex.draw_texture(T("yellow_box", "genre_banner"), { frame = box:song_genre(i), x = x, y = y, fade = f })
|
||||
|
||||
local song_label = T("yellow_box", "song_label")
|
||||
if song_label then
|
||||
tex.draw_texture(song_label, { frame = math.min(i, 2), x = x, y = y, fade = f })
|
||||
end
|
||||
|
||||
tex.draw_texture(T("yellow_box", "difficulty"), { frame = box:song_difficulty(i), x = x, y = y, fade = f })
|
||||
tex.draw_texture(T("yellow_box", "difficulty_x"), { x = x, y = y, fade = f })
|
||||
tex.draw_texture(T("yellow_box", "difficulty_star"), { x = x, y = y, fade = f })
|
||||
|
||||
-- Level counter
|
||||
local lvl = tostring(box:song_level(i))
|
||||
local margin = (cfg("dan_level_counter_margin") or { x = 0 }).x
|
||||
local total_w = #lvl * margin
|
||||
for j = 1, #lvl do
|
||||
local digit = string.byte(lvl, j) - 48
|
||||
tex.draw_texture(T("yellow_box", "difficulty_num"), {
|
||||
frame = digit, x = x - total_w / 2 + (j - 1) * margin, y = y, fade = f })
|
||||
end
|
||||
|
||||
-- Song title + subtitle
|
||||
local title_text = box:song_title_text(i)
|
||||
local sub_text = box:song_subtitle_text(i)
|
||||
local td = cfg("dan_title") or { x = 0, y = 0, height = 0 }
|
||||
local sd = cfg("dan_subtitle") or { x = 0, y = 0, height = 0 }
|
||||
if title_text then
|
||||
title_text:draw({
|
||||
x = td.x + x, y = td.y + y,
|
||||
y2 = math.min(title_text.height, td.height or title_text.height) - title_text.height,
|
||||
fade = f })
|
||||
end
|
||||
if sub_text then
|
||||
sub_text:draw({
|
||||
x = sd.x + x,
|
||||
y = sd.y + y - math.min(sub_text.height, sd.height or sub_text.height),
|
||||
y2 = math.min(sub_text.height, sd.height or sub_text.height) - sub_text.height,
|
||||
fade = f })
|
||||
end
|
||||
end
|
||||
|
||||
-- Total notes
|
||||
tex.draw_texture(T("yellow_box", "total_notes_bg"), { fade = f })
|
||||
local tn_slot = cfg("dan_select_total_notes")
|
||||
if not tn_slot or tn_slot.x >= 1.0 then
|
||||
tex.draw_texture(T("yellow_box", "total_notes"), { fade = f })
|
||||
local tn = tostring(box.total_notes)
|
||||
local tn_margin = (cfg("total_notes_counter_margin") or { x = 0 }).x
|
||||
for i = 1, #tn do
|
||||
local digit = string.byte(tn, i) - 48
|
||||
tex.draw_texture(T("yellow_box", "total_notes_counter"), { frame = digit, x = (i - 1) * tn_margin, fade = f })
|
||||
end
|
||||
end
|
||||
|
||||
-- Rank plate / frame
|
||||
if box.dan_rank >= 0 and opt("dan_select_rank_plate") then
|
||||
tex.draw_texture(T("yellow_box", "rank_plate"), { frame = box.dan_rank, fade = f })
|
||||
else
|
||||
tex.draw_texture(T("yellow_box", "frame"), { frame = box.dan_color, fade = f })
|
||||
local hori = box:hori_name()
|
||||
if hori then
|
||||
local hn = cfg("dan_hori_name") or { x = 0, y = 0, width = 0 }
|
||||
hori:draw({
|
||||
x = hn.x - hori.width / 2,
|
||||
y = hn.y,
|
||||
x2 = math.min(hori.width, hn.width or hori.width) - hori.width,
|
||||
fade = f })
|
||||
end
|
||||
end
|
||||
|
||||
self:draw_exam_box(box, f)
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Exam board (the default "condition rows" layout).
|
||||
-- ---------------------------------------------------------------------------
|
||||
function DanSelect:draw_exam_box(box, f)
|
||||
if opt("dan_exam_grid") then
|
||||
self:draw_exam_grid(box, f)
|
||||
return
|
||||
end
|
||||
|
||||
tex.draw_texture(T("yellow_box", "exam_box_bottom_right"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_bottom_left"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_top_right"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_top_left"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_bottom"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_right"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_left"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_top"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_box_center"), { fade = f })
|
||||
tex.draw_texture(T("yellow_box", "exam_header"), { fade = f })
|
||||
|
||||
local offset_y = (cfg("dan_exam_info") or { y = 0 }).y
|
||||
local margin = (cfg("exam_counter_margin") or { x = 0 }).x
|
||||
|
||||
-- Four or more conditions do not fit the board: drop the soul-gauge row.
|
||||
local exam_count = box:exam_count()
|
||||
local shown = {}
|
||||
for i = 0, exam_count - 1 do
|
||||
if not (exam_count >= 4 and box:exam_type(i) == "gauge") then
|
||||
shown[#shown + 1] = i
|
||||
end
|
||||
end
|
||||
if #shown > 3 then
|
||||
while #shown > 3 do shown[#shown] = nil end
|
||||
end
|
||||
|
||||
for idx = 1, #shown do
|
||||
local i = shown[idx]
|
||||
local y = (idx - 1) * offset_y
|
||||
local etype = box:exam_type(i)
|
||||
local range = box:exam_range(i)
|
||||
|
||||
tex.draw_texture(T("yellow_box", "judge_box"), { y = y, fade = f })
|
||||
|
||||
local icon_name = exam_icon_name(etype)
|
||||
if icon_name then tex.draw_texture(T("yellow_box", icon_name), { y = y, fade = f }) end
|
||||
|
||||
if opt("dan_exam_value_center") then
|
||||
-- Centre the whole value (digits, %, suffix) on dan_exam_value_center.x.
|
||||
local vc = cfg("dan_exam_value_center") or { x = 0, width = 0 }
|
||||
local digits = tostring(box:exam_red(i))
|
||||
local pct = (etype == "gauge") and T("yellow_box", "exam_percent") or nil
|
||||
local suf = (range == "more") and T("yellow_box", "exam_more")
|
||||
or (range == "less") and T("yellow_box", "exam_less") or nil
|
||||
|
||||
local digits_w = (#digits - 1) * margin + tex_x2("yellow_box", "judge_num")
|
||||
local pct_w = pct and tex_x2("yellow_box", "exam_percent") or 0
|
||||
local suf_w = suf and tex_x2("yellow_box", (range == "more") and "exam_more" or "exam_less") or 0
|
||||
local gap = vc.width or 0
|
||||
local parts = 1 + (pct and 1 or 0) + (suf and 1 or 0)
|
||||
local total = digits_w + pct_w + suf_w + gap * (parts - 1)
|
||||
local cx = (vc.x or 0) - total / 2
|
||||
|
||||
for j = 1, #digits do
|
||||
local digit = string.byte(digits, j) - 48
|
||||
tex.draw_texture(T("yellow_box", "judge_num"),
|
||||
{ frame = digit, x = cx + (j - 1) * margin - tex_x0("yellow_box", "judge_num"), y = y, fade = f })
|
||||
end
|
||||
cx = cx + digits_w + gap
|
||||
if pct then
|
||||
tex.draw_texture(pct, { x = cx - tex_x0("yellow_box", "exam_percent"), y = y, fade = f })
|
||||
cx = cx + pct_w + gap
|
||||
end
|
||||
if suf then
|
||||
local suf_name = (range == "more") and "exam_more" or "exam_less"
|
||||
tex.draw_texture(suf, { x = cx - tex_x0("yellow_box", suf_name), y = y, fade = f })
|
||||
end
|
||||
else
|
||||
local x_offset = 0
|
||||
if etype == "gauge" then
|
||||
tex.draw_texture(T("yellow_box", "exam_percent"), { y = y, fade = f })
|
||||
x_offset = (cfg("exam_gauge_offset") or { x = 0 }).x
|
||||
end
|
||||
|
||||
local counter = tostring(box:exam_red(i))
|
||||
for j = 1, #counter do
|
||||
local digit = string.byte(counter, j) - 48
|
||||
local x = x_offset - (#counter - j + 1) * margin
|
||||
tex.draw_texture(T("yellow_box", "judge_num"), { frame = digit, x = x, y = y, fade = f })
|
||||
end
|
||||
|
||||
if range == "more" then
|
||||
tex.draw_texture(T("yellow_box", "exam_more"), { x = -x_offset * 1.7, y = y, fade = f })
|
||||
elseif range == "less" then
|
||||
tex.draw_texture(T("yellow_box", "exam_less"), { x = -x_offset * 1.7, y = y, fade = f })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Exam board grid mode (dan_exam_grid option): a two-column gauge/score layout.
|
||||
-- ---------------------------------------------------------------------------
|
||||
local function caption(self, str, font_size, outline)
|
||||
self._captions = self._captions or {}
|
||||
local key = str .. "\0" .. tostring(font_size) .. "\0" .. tostring(outline)
|
||||
local cap = self._captions[key]
|
||||
if cap == nil then
|
||||
cap = text.create_raw_text(str, font_size, { 255, 255, 255, 255 }, { 0, 0, 0, 255 }, false, outline)
|
||||
self._captions[key] = cap
|
||||
end
|
||||
return cap
|
||||
end
|
||||
|
||||
local function draw_value_text(self, cap_str, bt, right_x, top_y, f)
|
||||
if not bt then return false end
|
||||
local ol = (bt.outline and bt.outline >= 0) and bt.outline or (3.0 / tex.get_screen_scale())
|
||||
local size = (bt.font_size and bt.font_size > 0) and bt.font_size or 28
|
||||
local cap = caption(self, cap_str, size, ol)
|
||||
if not cap then return false end
|
||||
local pad = math.floor(ol * tex.get_screen_scale()) + 2
|
||||
cap:draw({ x = right_x - cap.width + pad, y = top_y - pad, fade = f })
|
||||
return true
|
||||
end
|
||||
|
||||
-- draw_value (grid mode): centred digits + optional percent/suffix, absolute anchors.
|
||||
local function draw_value(self, red, etype, range, centre_x, top_y, f)
|
||||
local digits = tostring(red)
|
||||
local margin = (cfg("exam_counter_margin") or { x = 0 }).x
|
||||
|
||||
local pct_w = 0
|
||||
if etype == "gauge" and T("yellow_box", "exam_percent") then
|
||||
pct_w = tex_x2("yellow_box", "exam_percent")
|
||||
end
|
||||
local suffix = (range == "less") and "exam_less" or (range == "more") and "exam_more" or nil
|
||||
local suf_w = 0
|
||||
if suffix and T("yellow_box", suffix) then
|
||||
suf_w = tex_x2("yellow_box", suffix)
|
||||
end
|
||||
|
||||
local total = #digits * margin + pct_w + suf_w
|
||||
local cx = centre_x - total * 0.5
|
||||
for j = 1, #digits do
|
||||
local digit = string.byte(digits, j) - 48
|
||||
draw_abs("yellow_box", "judge_num", cx, top_y, f, digit)
|
||||
cx = cx + margin
|
||||
end
|
||||
if pct_w > 0 then
|
||||
draw_abs("yellow_box", "exam_percent", cx, top_y + 8, f)
|
||||
cx = cx + pct_w
|
||||
end
|
||||
if suf_w > 0 then
|
||||
draw_abs("yellow_box", suffix, cx, top_y + 6, f)
|
||||
end
|
||||
end
|
||||
|
||||
function DanSelect:draw_exam_grid(box, f)
|
||||
local exam_frame = T("yellow_box", "exam_frame")
|
||||
if exam_frame then tex.draw_texture(exam_frame, { fade = f }) end
|
||||
tex.draw_texture(T("yellow_box", "exam_header"), { fade = f })
|
||||
|
||||
local gb = cfg("dan_exam_gauge_box")
|
||||
local sb = cfg("dan_exam_score_box")
|
||||
local gx = (gb and gb.x) or 436.0
|
||||
local gy = (gb and gb.y) or 615.0
|
||||
local sx = (sb and sb.x) or 769.0
|
||||
local sy = (sb and sb.y) or 615.0
|
||||
local pitch = (sb and sb.height and sb.height > 0) and sb.height or 132.0
|
||||
|
||||
local sg = cfg("dan_exam_seg")
|
||||
local seg_x = (sg and sg.x) or 14.0
|
||||
local seg_y = (sg and sg.y) or 48.0
|
||||
local seg_dx = (sg and sg.width and sg.width > 0) and sg.width or 327.0
|
||||
local vp = cfg("dan_exam_value")
|
||||
local val_x = (vp and vp.x) or 185.0
|
||||
local val_y = (vp and vp.y) or 40.0
|
||||
local pp = cfg("dan_exam_label_pill")
|
||||
local pill_x = (pp and pp.x) or 26.0
|
||||
local pill_y = (pp and pp.y) or 2.0
|
||||
|
||||
local seg_bt = cfg("dan_select_exam_border_text")
|
||||
local gauge_bt = cfg("dan_select_gauge_border_text")
|
||||
|
||||
local right_row = 0
|
||||
local gauge_used = false
|
||||
local exam_count = box:exam_count()
|
||||
for i = 0, exam_count - 1 do
|
||||
local etype = box:exam_type(i)
|
||||
local range = box:exam_range(i)
|
||||
local left = (etype == "gauge" and not gauge_used)
|
||||
if left then gauge_used = true end
|
||||
-- The cabinet has three right-side slots; skip (don't stop) further right rows.
|
||||
if left or right_row < 3 then
|
||||
local BX = left and gx or sx
|
||||
local BY = left and gy or (sy + pitch * right_row)
|
||||
|
||||
draw_abs("yellow_box", left and "exam_gauge_box" or "judge_box",
|
||||
BX - (left and 0 or 3), BY - (left and 0 or 2), f)
|
||||
|
||||
local icon_name = exam_icon_name(etype)
|
||||
if icon_name then draw_abs("yellow_box", icon_name, BX + pill_x, BY + pill_y, f) end
|
||||
|
||||
if left then
|
||||
if not draw_value_text(self, box:exam_caption(i), gauge_bt,
|
||||
BX + ((gauge_bt and gauge_bt.x) or 0),
|
||||
BY + ((gauge_bt and gauge_bt.y) or 0), f) then
|
||||
draw_value(self, box:exam_red(i), etype, range, BX + 181.0, BY + 45.0, f)
|
||||
end
|
||||
else
|
||||
local gothrough = box:exam_gothrough(i)
|
||||
local segs = gothrough and 1 or math.min(box:song_count(), 3)
|
||||
for k = 0, segs - 1 do
|
||||
local frame = gothrough and 0 or (k + 1)
|
||||
draw_abs("yellow_box", "exam_seg_label", BX + seg_x + seg_dx * k, BY + seg_y, f, frame)
|
||||
|
||||
local red = gothrough and box:exam_red(i) or box:exam_song_red(i, k)
|
||||
if not draw_value_text(self, box:exam_song_caption(i, k), seg_bt,
|
||||
BX + ((seg_bt and seg_bt.x) or 0) + seg_dx * k,
|
||||
BY + ((seg_bt and seg_bt.y) or 0), f) then
|
||||
draw_value(self, red, etype, range, BX + val_x + seg_dx * k, BY + val_y, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not left then right_row = right_row + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,7 +3,6 @@ Entry.__index = Entry
|
||||
|
||||
function Entry.new()
|
||||
local self = setmetatable({}, Entry)
|
||||
tex.load_animations("entry")
|
||||
|
||||
self.bg_flicker = tex.get_animation(1, "entry")
|
||||
self.side_select_fade = tex.get_animation(0, "entry")
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
ClearAnimation = {}
|
||||
ClearAnimation.__index = ClearAnimation
|
||||
|
||||
function ClearAnimation.new(is_2p)
|
||||
local self = setmetatable({}, ClearAnimation)
|
||||
|
||||
self.is_2p = is_2p
|
||||
self.idx = is_2p and 1 or 0
|
||||
self.draw_clear_full = false
|
||||
self.name = "in"
|
||||
self.frame = 0
|
||||
|
||||
self.bachio_fade_in = tex.get_animation(46, "game")
|
||||
self.bachio_texture_change = tex.get_animation(47, "game")
|
||||
self.bachio_out = tex.get_animation(55, "game")
|
||||
self.bachio_move_out = tex.get_animation(66, "game")
|
||||
self.clear_highlight_fade_in = tex.get_animation(56, "game")
|
||||
|
||||
self.bachio_fade_in:start()
|
||||
self.bachio_texture_change:start()
|
||||
self.bachio_out:start()
|
||||
self.bachio_move_out:start()
|
||||
self.clear_highlight_fade_in:start()
|
||||
|
||||
self.clear_separate_fade_in = {}
|
||||
self.clear_separate_stretch = {}
|
||||
for i = 0, 4 do
|
||||
local fade = anim.fade(100, { initial_opacity = 0.0, final_opacity = 1.0, delay = i * 50 })
|
||||
fade:start()
|
||||
self.clear_separate_fade_in[i + 1] = fade
|
||||
|
||||
local stretch = anim.text_stretch(200, { delay = i * 50 })
|
||||
stretch:start()
|
||||
self.clear_separate_stretch[i + 1] = stretch
|
||||
end
|
||||
|
||||
audio.play_sound("clear", "sound")
|
||||
|
||||
self.t_clear = tex.get_texture("game/ending_anim/clear")
|
||||
self.t_clear_separated = tex.get_texture("game/ending_anim/clear_separated")
|
||||
self.t_clear_highlight = tex.get_texture("game/ending_anim/clear_highlight")
|
||||
self.t_bachio_l_in = tex.get_texture("game/ending_anim/bachio_l_in")
|
||||
self.t_bachio_l_out = tex.get_texture("game/ending_anim/bachio_l_out")
|
||||
self.t_bachio_r_in = tex.get_texture("game/ending_anim/bachio_r_in")
|
||||
self.t_bachio_r_out = tex.get_texture("game/ending_anim/bachio_r_out")
|
||||
|
||||
local spacing = tex.get_skin_config("clear_animation_x_spacing")
|
||||
self.clear_anim_x_spacing = (spacing and spacing.x) or 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ClearAnimation:update(current_ms)
|
||||
self.bachio_fade_in:update(current_ms)
|
||||
self.bachio_texture_change:update(current_ms)
|
||||
self.bachio_out:update(current_ms)
|
||||
self.bachio_move_out:update(current_ms)
|
||||
self.clear_highlight_fade_in:update(current_ms)
|
||||
|
||||
if self.clear_highlight_fade_in.is_finished or self.clear_highlight_fade_in.attribute >= 1.0 then
|
||||
self.draw_clear_full = true
|
||||
end
|
||||
|
||||
for i = 1, 5 do
|
||||
self.clear_separate_fade_in[i]:update(current_ms)
|
||||
self.clear_separate_stretch[i]:update(current_ms)
|
||||
end
|
||||
|
||||
if self.bachio_texture_change.is_finished then
|
||||
self.name = "out"
|
||||
self.frame = math.floor(self.bachio_out.attribute)
|
||||
else
|
||||
self.frame = math.floor(self.bachio_texture_change.attribute)
|
||||
end
|
||||
end
|
||||
|
||||
function ClearAnimation:draw()
|
||||
if self.draw_clear_full then
|
||||
tex.draw_texture(self.t_clear, { index = self.idx })
|
||||
else
|
||||
for i = 5, 1, -1 do
|
||||
local j = i - 1
|
||||
tex.draw_texture(self.t_clear_separated, {
|
||||
frame = j,
|
||||
x = j * self.clear_anim_x_spacing,
|
||||
y = -self.clear_separate_stretch[i].attribute,
|
||||
y2 = self.clear_separate_stretch[i].attribute,
|
||||
fade = self.clear_separate_fade_in[i].attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
tex.draw_texture(self.t_clear_highlight, {
|
||||
fade = self.clear_highlight_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
|
||||
local ltex = (self.name == "in") and self.t_bachio_l_in or self.t_bachio_l_out
|
||||
local rtex = (self.name == "in") and self.t_bachio_r_in or self.t_bachio_r_out
|
||||
|
||||
tex.draw_texture(ltex, {
|
||||
frame = self.frame,
|
||||
x = -self.bachio_move_out.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(rtex, {
|
||||
frame = self.frame,
|
||||
x = self.bachio_move_out.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
FailAnimation = {}
|
||||
FailAnimation.__index = FailAnimation
|
||||
|
||||
function FailAnimation.new(is_2p)
|
||||
local self = setmetatable({}, FailAnimation)
|
||||
|
||||
self.is_2p = is_2p
|
||||
self.idx = is_2p and 1 or 0
|
||||
self.name = "in"
|
||||
self.frame = 0
|
||||
|
||||
self.bachio_fade_in = tex.get_animation(46, "game")
|
||||
self.bachio_texture_change = tex.get_animation(47, "game")
|
||||
self.bachio_fall = tex.get_animation(48, "game")
|
||||
self.bachio_move_out = tex.get_animation(49, "game")
|
||||
self.bachio_boom_fade_in = tex.get_animation(50, "game")
|
||||
self.bachio_boom_scale = tex.get_animation(51, "game")
|
||||
self.bachio_up = tex.get_animation(52, "game")
|
||||
self.bachio_down = tex.get_animation(53, "game")
|
||||
self.text_fade_in = tex.get_animation(54, "game")
|
||||
|
||||
self.text_fade_in:start()
|
||||
self.bachio_fade_in:start()
|
||||
self.bachio_texture_change:start()
|
||||
self.bachio_fall:start()
|
||||
self.bachio_move_out:start()
|
||||
self.bachio_boom_fade_in:start()
|
||||
self.bachio_boom_scale:start()
|
||||
self.bachio_up:start()
|
||||
self.bachio_down:start()
|
||||
|
||||
audio.play_sound("fail", "sound")
|
||||
|
||||
self.t_fail = tex.get_texture("game/ending_anim/fail")
|
||||
self.t_bachio_boom = tex.get_texture("game/ending_anim/bachio_boom")
|
||||
self.t_bachio_l_in = tex.get_texture("game/ending_anim/bachio_l_in")
|
||||
self.t_bachio_l_fall = tex.get_texture("game/ending_anim/bachio_l_fall")
|
||||
self.t_bachio_r_in = tex.get_texture("game/ending_anim/bachio_r_in")
|
||||
self.t_bachio_r_fall = tex.get_texture("game/ending_anim/bachio_r_fall")
|
||||
|
||||
local offset2p = tex.get_skin_config("offset_2p")
|
||||
self.offset_2p_y = (offset2p and offset2p.y) or 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function FailAnimation:update(current_ms)
|
||||
self.bachio_fade_in:update(current_ms)
|
||||
self.bachio_texture_change:update(current_ms)
|
||||
self.bachio_fall:update(current_ms)
|
||||
self.bachio_move_out:update(current_ms)
|
||||
self.bachio_boom_fade_in:update(current_ms)
|
||||
self.bachio_boom_scale:update(current_ms)
|
||||
self.bachio_up:update(current_ms)
|
||||
self.bachio_down:update(current_ms)
|
||||
self.text_fade_in:update(current_ms)
|
||||
|
||||
if self.bachio_texture_change.is_finished then
|
||||
self.name = "fall"
|
||||
self.frame = math.floor(self.bachio_fall.attribute)
|
||||
else
|
||||
self.frame = math.floor(self.bachio_texture_change.attribute)
|
||||
end
|
||||
end
|
||||
|
||||
function FailAnimation:draw()
|
||||
tex.draw_texture(self.t_fail, {
|
||||
fade = self.text_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
|
||||
local ltex = (self.name == "in") and self.t_bachio_l_in or self.t_bachio_l_fall
|
||||
local rtex = (self.name == "in") and self.t_bachio_r_in or self.t_bachio_r_fall
|
||||
|
||||
tex.draw_texture(ltex, {
|
||||
frame = self.frame,
|
||||
x = -self.bachio_move_out.attribute - (self.bachio_up.attribute / 2),
|
||||
y = self.bachio_down.attribute - self.bachio_up.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(rtex, {
|
||||
frame = self.frame,
|
||||
x = self.bachio_move_out.attribute + (self.bachio_up.attribute / 2),
|
||||
y = self.bachio_down.attribute - self.bachio_up.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
|
||||
tex.draw_texture(self.t_bachio_boom, {
|
||||
scale = self.bachio_boom_scale.attribute,
|
||||
center = true,
|
||||
y = self.idx * self.offset_2p_y,
|
||||
fade = self.bachio_boom_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,194 @@
|
||||
FCAnimation = {}
|
||||
FCAnimation.__index = FCAnimation
|
||||
|
||||
function FCAnimation.new(is_2p, donderful)
|
||||
local self = setmetatable({}, FCAnimation)
|
||||
|
||||
self.is_2p = is_2p
|
||||
self.idx = is_2p and 1 or 0
|
||||
self.draw_clear_full = false
|
||||
self.name = "in"
|
||||
self.frame = 0
|
||||
|
||||
local has_dfc_tex = donderful
|
||||
and tex.get_texture("game/ending_donderful/full_combo") ~= nil
|
||||
and tex.get_texture("game/ending_donderful/full_combo_highlight") ~= nil
|
||||
and tex.get_texture("game/ending_donderful/full_combo_overlay") ~= nil
|
||||
|
||||
local subset = has_dfc_tex and "ending_donderful/" or "ending_anim/"
|
||||
self.combo_tex = tex.get_texture("game/" .. subset .. "full_combo")
|
||||
self.combo_highlight_tex = tex.get_texture("game/" .. subset .. "full_combo_highlight")
|
||||
self.combo_overlay_tex = tex.get_texture("game/" .. subset .. "full_combo_overlay")
|
||||
|
||||
self.has_panel = has_dfc_tex and tex.get_texture("game/ending_donderful/background") ~= nil
|
||||
self.panel_tex = self.has_panel and tex.get_texture("game/ending_donderful/background") or nil
|
||||
self.panel_fade_in = anim.fade(250, { initial_opacity = 0.0, final_opacity = 1.0, delay = 0 })
|
||||
|
||||
local has_dfc_sound = donderful and audio.has_sound("donderful_combo")
|
||||
self.combo_sound = has_dfc_sound and "donderful_combo" or "full_combo"
|
||||
self.combo_voice = (donderful and audio.has_sound("donderful_combo_voice")) and "donderful_combo_voice" or "full_combo_voice"
|
||||
|
||||
self.bachio_fade_in = tex.get_animation(46, "game")
|
||||
self.bachio_texture_change = tex.get_animation(47, "game")
|
||||
self.bachio_out = tex.get_animation(55, "game")
|
||||
self.bachio_move_out = tex.get_animation(49, "game")
|
||||
|
||||
self.bachio_fade_in:start()
|
||||
self.bachio_texture_change:start()
|
||||
self.bachio_out:start()
|
||||
self.bachio_move_out:start()
|
||||
|
||||
self.clear_separate_fade_in = {}
|
||||
self.clear_separate_stretch = {}
|
||||
for i = 0, 4 do
|
||||
local fade = anim.fade(100, { initial_opacity = 1.0, final_opacity = 0.0, delay = i * 50 })
|
||||
fade:start()
|
||||
self.clear_separate_fade_in[i + 1] = fade
|
||||
|
||||
local stretch = anim.text_stretch(200, { delay = i * 50 })
|
||||
stretch:start()
|
||||
self.clear_separate_stretch[i + 1] = stretch
|
||||
end
|
||||
|
||||
self.clear_highlight_fade_in = tex.get_animation(56, "game")
|
||||
self.fc_highlight_up = tex.get_animation(57, "game")
|
||||
self.fc_highlight_fade_out = tex.get_animation(58, "game")
|
||||
self.bachio_move_out_2 = tex.get_animation(59, "game")
|
||||
self.bachio_move_up = tex.get_animation(60, "game")
|
||||
self.fan_fade_in = tex.get_animation(61, "game")
|
||||
self.fan_texture_change = tex.get_animation(62, "game")
|
||||
|
||||
self.clear_highlight_fade_in:start()
|
||||
self.fc_highlight_up:start()
|
||||
|
||||
audio.play_sound(self.combo_sound, "sound")
|
||||
|
||||
self.t_fan_l = tex.get_texture("game/ending_anim/fan_l")
|
||||
self.t_fan_r = tex.get_texture("game/ending_anim/fan_r")
|
||||
self.t_clear_separated = tex.get_texture("game/ending_anim/clear_separated")
|
||||
self.t_clear_highlight = tex.get_texture("game/ending_anim/clear_highlight")
|
||||
self.t_bachio_l_in = tex.get_texture("game/ending_anim/bachio_l_in")
|
||||
self.t_bachio_l_out = tex.get_texture("game/ending_anim/bachio_l_out")
|
||||
self.t_bachio_r_in = tex.get_texture("game/ending_anim/bachio_r_in")
|
||||
self.t_bachio_r_out = tex.get_texture("game/ending_anim/bachio_r_out")
|
||||
|
||||
local spacing = tex.get_skin_config("clear_animation_x_spacing")
|
||||
self.clear_anim_x_spacing = (spacing and spacing.x) or 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function FCAnimation:update(current_ms)
|
||||
self.bachio_fade_in:update(current_ms)
|
||||
self.bachio_texture_change:update(current_ms)
|
||||
self.bachio_out:update(current_ms)
|
||||
self.bachio_move_out:update(current_ms)
|
||||
self.clear_highlight_fade_in:update(current_ms)
|
||||
self.fc_highlight_up:update(current_ms)
|
||||
self.fc_highlight_fade_out:update(current_ms)
|
||||
self.bachio_move_out_2:update(current_ms)
|
||||
self.bachio_move_up:update(current_ms)
|
||||
self.fan_fade_in:update(current_ms)
|
||||
self.fan_texture_change:update(current_ms)
|
||||
|
||||
if self.fc_highlight_up.is_finished and not self.fc_highlight_fade_out.is_started then
|
||||
self.fc_highlight_fade_out:start()
|
||||
self.bachio_move_out_2:start()
|
||||
self.bachio_move_up:start()
|
||||
self.fan_fade_in:start()
|
||||
self.fan_texture_change:start()
|
||||
audio.play_sound(self.combo_voice, "voice")
|
||||
end
|
||||
|
||||
if self.clear_highlight_fade_in.is_finished then
|
||||
if not self.draw_clear_full and self.has_panel then
|
||||
self.panel_fade_in:start()
|
||||
end
|
||||
self.draw_clear_full = true
|
||||
end
|
||||
self.panel_fade_in:update(current_ms)
|
||||
|
||||
for i = 1, 5 do
|
||||
self.clear_separate_fade_in[i]:update(current_ms)
|
||||
self.clear_separate_stretch[i]:update(current_ms)
|
||||
end
|
||||
|
||||
if self.bachio_texture_change.is_finished then
|
||||
self.name = "out"
|
||||
self.frame = math.floor(self.bachio_out.attribute)
|
||||
else
|
||||
self.frame = math.floor(self.bachio_texture_change.attribute)
|
||||
end
|
||||
end
|
||||
|
||||
function FCAnimation:draw()
|
||||
if self.draw_clear_full then
|
||||
if self.has_panel then
|
||||
tex.draw_texture(self.panel_tex, {
|
||||
fade = self.panel_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
|
||||
tex.draw_texture(self.t_fan_l, {
|
||||
frame = math.floor(self.fan_texture_change.attribute),
|
||||
fade = self.fan_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(self.t_fan_r, {
|
||||
frame = math.floor(self.fan_texture_change.attribute),
|
||||
fade = self.fan_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
|
||||
tex.draw_texture(self.combo_overlay_tex, {
|
||||
y = -self.fc_highlight_up.attribute,
|
||||
fade = 0.5,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(self.combo_tex, {
|
||||
y = -self.fc_highlight_up.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(self.combo_highlight_tex, {
|
||||
y = -self.fc_highlight_up.attribute,
|
||||
fade = self.fc_highlight_fade_out.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
else
|
||||
for i = 5, 1, -1 do
|
||||
local j = i - 1
|
||||
tex.draw_texture(self.t_clear_separated, {
|
||||
frame = j,
|
||||
x = j * self.clear_anim_x_spacing,
|
||||
y = -self.clear_separate_stretch[i].attribute,
|
||||
y2 = self.clear_separate_stretch[i].attribute,
|
||||
fade = self.clear_separate_fade_in[i].attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
tex.draw_texture(self.t_clear_highlight, {
|
||||
fade = self.clear_highlight_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
|
||||
local ltex = (self.name == "in") and self.t_bachio_l_in or self.t_bachio_l_out
|
||||
local rtex = (self.name == "in") and self.t_bachio_r_in or self.t_bachio_r_out
|
||||
|
||||
tex.draw_texture(ltex, {
|
||||
frame = self.frame,
|
||||
x = (-self.bachio_move_out.attribute - self.bachio_move_out_2.attribute) * 1.15,
|
||||
y = -self.bachio_move_up.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
tex.draw_texture(rtex, {
|
||||
frame = self.frame,
|
||||
x = (self.bachio_move_out.attribute + self.bachio_move_out_2.attribute) * 1.15,
|
||||
y = -self.bachio_move_up.attribute,
|
||||
fade = self.bachio_fade_in.attribute,
|
||||
index = self.idx,
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
ResultTransition = {}
|
||||
ResultTransition.__index = ResultTransition
|
||||
|
||||
function ResultTransition.new(player_num)
|
||||
local self = setmetatable({}, ResultTransition)
|
||||
self.player_num = player_num
|
||||
self.move = tex.get_animation(5, "global") -- result shutter move in
|
||||
|
||||
local screen_w = tex.get_screen_width()
|
||||
if player_num == 3 then -- PlayerNum.TWO_PLAYER
|
||||
self.t_shutter_1p = tex.get_texture("global/result_transition/1p_shutter")
|
||||
self.t_shutter_2p = tex.get_texture("global/result_transition/2p_shutter")
|
||||
self.t_footer_1p = tex.get_texture("global/result_transition/1p_shutter_footer")
|
||||
self.t_footer_2p = tex.get_texture("global/result_transition/2p_shutter_footer")
|
||||
self.has_footer = self.t_footer_1p ~= nil and self.t_footer_2p ~= nil
|
||||
|
||||
local f1 = tex.get_texture_info("result_transition", "1p_shutter_footer")
|
||||
local f2 = tex.get_texture_info("result_transition", "2p_shutter_footer")
|
||||
self.tex_height = (f1 and f1.height) or 0
|
||||
self.tex_height_2p = (f2 and f2.height) or 0
|
||||
|
||||
local s = tex.get_texture_info("result_transition", "1p_shutter")
|
||||
self.shutter_width = (s and s.width) or (screen_w / 5)
|
||||
else
|
||||
local ps = (player_num == 2) and "2p" or "1p" -- PlayerNum.P2, else 1p
|
||||
self.t_shutter = tex.get_texture("global/result_transition/" .. ps .. "_shutter")
|
||||
self.t_footer = tex.get_texture("global/result_transition/" .. ps .. "_shutter_footer")
|
||||
self.has_footer = self.t_footer ~= nil
|
||||
|
||||
local f = tex.get_texture_info("result_transition", ps .. "_shutter_footer")
|
||||
self.tex_height = (f and f.height) or 0
|
||||
|
||||
local s = tex.get_texture_info("result_transition", ps .. "_shutter")
|
||||
self.shutter_width = (s and s.width) or (screen_w / 5)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function ResultTransition:start()
|
||||
self.move:start()
|
||||
end
|
||||
|
||||
function ResultTransition:update(current_ms)
|
||||
self.move:update(current_ms)
|
||||
end
|
||||
|
||||
function ResultTransition:is_finished()
|
||||
return false -- the engine's move animation and result_transition voice decide
|
||||
end
|
||||
|
||||
function ResultTransition:draw()
|
||||
if not self.has_footer then return end
|
||||
|
||||
local attr = self.move.attribute
|
||||
local screen_h = tex.get_screen_height()
|
||||
local screen_w = tex.get_screen_width()
|
||||
local x = 0
|
||||
while x < screen_w do
|
||||
if self.player_num == 3 then
|
||||
tex.draw_texture(self.t_shutter_1p, { x = x, y = -screen_h + attr })
|
||||
tex.draw_texture(self.t_shutter_2p, { x = x, y = screen_h - attr })
|
||||
tex.draw_texture(self.t_footer_1p, { x = x, y = -(self.tex_height * 3) + attr })
|
||||
tex.draw_texture(self.t_footer_2p, { x = x, y = screen_h + (self.tex_height_2p * 2) - attr })
|
||||
else
|
||||
tex.draw_texture(self.t_shutter, { x = x, y = -screen_h + attr })
|
||||
tex.draw_texture(self.t_shutter, { x = x, y = screen_h - attr })
|
||||
tex.draw_texture(self.t_footer, { x = x, y = -(self.tex_height * 3) + attr })
|
||||
tex.draw_texture(self.t_footer, { x = x, y = screen_h + (self.tex_height * 2) - attr })
|
||||
end
|
||||
x = x + self.shutter_width
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
SongTransition = {}
|
||||
SongTransition.__index = SongTransition
|
||||
|
||||
function SongTransition.new(title, subtitle, is_second)
|
||||
local self = setmetatable({}, SongTransition)
|
||||
self.is_second = is_second and true or false
|
||||
|
||||
self.t_rainbow_bg_bottom = tex.get_texture("global/rainbow_transition/rainbow_bg_bottom")
|
||||
self.t_rainbow_bg_top = tex.get_texture("global/rainbow_transition/rainbow_bg_top")
|
||||
self.t_rainbow_bg = tex.get_texture("global/rainbow_transition/rainbow_bg")
|
||||
self.t_chara_left = tex.get_texture("global/rainbow_transition/chara_left")
|
||||
self.t_chara_right = tex.get_texture("global/rainbow_transition/chara_right")
|
||||
self.t_chara_center = tex.get_texture("global/rainbow_transition/chara_center")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SongTransition:draw_bg(total_offset, rainbow_up, mini_up, chara_down)
|
||||
tex.draw_texture(self.t_rainbow_bg_bottom, { y = -rainbow_up - total_offset })
|
||||
tex.draw_texture(self.t_rainbow_bg_top, { y = -rainbow_up - total_offset })
|
||||
tex.draw_texture(self.t_rainbow_bg, { y = -rainbow_up - total_offset })
|
||||
|
||||
local offset = chara_down
|
||||
local chara_offset = 0
|
||||
if self.is_second then
|
||||
offset = chara_down - mini_up / 3
|
||||
local cfg = tex.get_skin_config("transition_chara_offset")
|
||||
chara_offset = (cfg and cfg.y) or 0
|
||||
end
|
||||
|
||||
tex.draw_texture(self.t_chara_left, { x = -mini_up / 2 - chara_offset, y = -mini_up + offset - total_offset })
|
||||
tex.draw_texture(self.t_chara_right, { x = mini_up / 2 + chara_offset, y = -mini_up + offset - total_offset })
|
||||
tex.draw_texture(self.t_chara_center, { y = -rainbow_up + offset - total_offset })
|
||||
end
|
||||
@@ -3,7 +3,6 @@ BottomCharacters.__index = BottomCharacters
|
||||
|
||||
function BottomCharacters.new()
|
||||
local self = setmetatable({}, BottomCharacters)
|
||||
tex.load_animations("result")
|
||||
|
||||
self.move_up = tex.get_animation(7, "result")
|
||||
self.move_down = tex.get_animation(8, "result")
|
||||
|
||||
@@ -3,7 +3,6 @@ HighScoreIndicator.__index = HighScoreIndicator
|
||||
|
||||
function HighScoreIndicator.new(score_diff, is_2p)
|
||||
local self = setmetatable({}, HighScoreIndicator)
|
||||
tex.load_animations("result")
|
||||
|
||||
self.move_anim = tex.get_animation(18, "result")
|
||||
self.fade_anim = tex.get_animation(19, "result")
|
||||
|
||||
@@ -3,7 +3,6 @@ ResultCrown.__index = ResultCrown
|
||||
|
||||
function ResultCrown.new(crown_type, is_2p)
|
||||
local self = setmetatable({}, ResultCrown)
|
||||
tex.load_animations("result")
|
||||
|
||||
self.resize = tex.get_animation(2, "result")
|
||||
self.resize_fix = tex.get_animation(3, "result")
|
||||
|
||||
@@ -3,7 +3,6 @@ ResultCrownMessage.__index = ResultCrownMessage
|
||||
|
||||
function ResultCrownMessage.new(frame, is_2p)
|
||||
local self = setmetatable({}, ResultCrownMessage)
|
||||
tex.load_animations("result")
|
||||
|
||||
self.scale_in = tex.get_animation(21, "result")
|
||||
self.scale_fix = tex.get_animation(22, "result")
|
||||
|
||||
@@ -38,7 +38,6 @@ ResultFadeIn.__index = ResultFadeIn
|
||||
function ResultFadeIn.new(player_num)
|
||||
local self = setmetatable({}, ResultFadeIn)
|
||||
self.player_num = player_num
|
||||
tex.load_animations("result")
|
||||
self.fade_in = tex.get_animation(15, "result")
|
||||
self.fade_in:start()
|
||||
return self
|
||||
|
||||
@@ -6,7 +6,6 @@ function ResultPlayer.new(player_num, is_2p, has_2p,
|
||||
crown_type, score_diff, score_method,
|
||||
mod_display, mod_inverse, mod_random, mod_speed)
|
||||
local self = setmetatable({}, ResultPlayer)
|
||||
tex.load_animations("result")
|
||||
|
||||
self.player_num = player_num
|
||||
self.is_2p = is_2p
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
-- BackBox rendering ("back" brown board + vertical label), split out of song_select.lua.
|
||||
-- Mirrors src/objects/song_select/file_navigator/box_back.cpp.
|
||||
|
||||
local base = require("song_select/file_navigator/box_base")
|
||||
|
||||
local T = base.T
|
||||
local draw_shadows = base.draw_shadows
|
||||
local draw_yellow_box = base.draw_yellow_box
|
||||
local draw_base_closed = base.draw_base_closed
|
||||
|
||||
local WHITE = { 255, 255, 255, 255 }
|
||||
local BLACK = { 0, 0, 0, 255 }
|
||||
local OUTLINE_COLOR = { 77, 39, 0, 255 }
|
||||
|
||||
-- back_text / back_text_highlight (vertical), cached on self.
|
||||
local function back_texts(self)
|
||||
if self._back_texts then return self._back_texts end
|
||||
local cfg = tex.get_skin_config("box_back_text") or { font_size = 40 }
|
||||
local label = tex.skin_text("box_back_text")
|
||||
if label == "" then label = "Back" end
|
||||
local back_text = text.create_raw_text(label, cfg.font_size or 40, WHITE, OUTLINE_COLOR, true, 5.0, 2.0, 1.0)
|
||||
local back_text_highlight = text.create_raw_text(label, cfg.font_size or 40, WHITE, BLACK, true, 5.0, 2.0, 1.0)
|
||||
self._back_texts = { back_text = back_text, back_text_highlight = back_text_highlight }
|
||||
return self._back_texts
|
||||
end
|
||||
|
||||
function SongSelect:draw_back_closed(box)
|
||||
draw_base_closed(box)
|
||||
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local fade = box.fade.attribute
|
||||
tex.draw_texture(T("box", "back_icon"), { x = bx, y = by, fade = fade })
|
||||
|
||||
local texts = back_texts(self)
|
||||
local cfg = tex.get_skin_config("box_back_text") or { x = 47, y = 173 }
|
||||
texts.back_text:draw({
|
||||
x = bx + cfg.x - texts.back_text.width / 2.0,
|
||||
y = by + cfg.y,
|
||||
fade = fade
|
||||
})
|
||||
end
|
||||
|
||||
function SongSelect:draw_back_open(box)
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local mfade = math.min(box.fade.attribute, box.open_fade.attribute)
|
||||
|
||||
draw_shadows(bx, by, mfade, 1)
|
||||
|
||||
local right_out = tex.get_animation(10)
|
||||
local right_out_2 = tex.get_animation(14)
|
||||
local x = bx
|
||||
draw_yellow_box(false, mfade, by)
|
||||
x = x + (right_out.attribute * 0.85 - right_out.start_position * 0.85)
|
||||
+ right_out_2.attribute - right_out_2.start_position
|
||||
|
||||
tex.draw_texture(T("box", "back_icon_highlight"), { x = x, y = by, fade = mfade })
|
||||
|
||||
local texts = back_texts(self)
|
||||
local cfg = tex.get_skin_config("box_back_text") or { x = 47, y = 173 }
|
||||
texts.back_text_highlight:draw({
|
||||
x = x + cfg.x - texts.back_text_highlight.width / 2.0,
|
||||
y = by + cfg.y,
|
||||
fade = mfade
|
||||
})
|
||||
tex.draw_texture(T("box", "back_graphic"), { x = x, y = by, fade = mfade })
|
||||
end
|
||||
@@ -0,0 +1,232 @@
|
||||
-- Shared BaseBox + YellowBox draw code and text helpers, split out of song_select.lua.
|
||||
-- Mirrors src/objects/song_select/file_navigator/box_base.cpp and box_yellow.cpp.
|
||||
-- All positions are in the skin's own pixels (1280x720 for PyTaikoGreen); box positions
|
||||
-- and engine animations are already in screen pixels.
|
||||
|
||||
local M = {}
|
||||
|
||||
-- TextureIndex (box/folder_texture colour frame) — must match enums.h.
|
||||
local TI_NONE, TI_VOCALOID, TI_DEFAULT, TI_RECOMMENDED, TI_FAVORITE, TI_RECENT = 0, 1, 2, 3, 4, 5
|
||||
-- GenreIndex (raw enum; folder_graphic / diff_overlay frame) — must match enums.h.
|
||||
local GI_DIFFICULTY = 14
|
||||
|
||||
M.TI_NONE, M.TI_DEFAULT = TI_NONE, TI_DEFAULT
|
||||
M.GI_DIFFICULTY = GI_DIFFICULTY
|
||||
|
||||
-- Lazy texture cache: tex.get_texture returns nil on a miss, and the C++ board code
|
||||
-- dereferences these unconditionally, so cache the resolved id (or nil) once.
|
||||
local _tex = {}
|
||||
local function T(subset, name)
|
||||
local key = subset .. "/" .. name
|
||||
local id = _tex[key]
|
||||
if id == nil then
|
||||
id = tex.get_texture("song_select/" .. subset .. "/" .. name)
|
||||
_tex[key] = id
|
||||
end
|
||||
return id
|
||||
end
|
||||
M.T = T
|
||||
|
||||
-- Lazy skin_config geometry.
|
||||
local _song_box_bg_width, _yellow_box_bottom_y, _edge_height
|
||||
local function song_box_bg_width()
|
||||
if _song_box_bg_width == nil then
|
||||
local c = tex.get_skin_config("song_box_bg")
|
||||
_song_box_bg_width = (c and c.width) or 0
|
||||
end
|
||||
return _song_box_bg_width
|
||||
end
|
||||
local function yellow_box_bottom_y()
|
||||
if _yellow_box_bottom_y == nil then
|
||||
local c = tex.get_skin_config("yellow_box_bottom")
|
||||
_yellow_box_bottom_y = (c and c.y) or 0
|
||||
end
|
||||
return _yellow_box_bottom_y
|
||||
end
|
||||
local function edge_height()
|
||||
if _edge_height == nil then
|
||||
local info = tex.get_texture_info("yellow_box", "yellow_box_bottom_right")
|
||||
_edge_height = (info and info.height) or 0
|
||||
end
|
||||
return _edge_height
|
||||
end
|
||||
M.song_box_bg_width = song_box_bg_width
|
||||
|
||||
-- Count UTF-8 codepoints (== Lua string length for ASCII; handles multibyte genres).
|
||||
function M.utf8_char_count(s)
|
||||
local count = 0
|
||||
local i = 1
|
||||
while i <= #s do
|
||||
local c = s:byte(i)
|
||||
if not c then break end
|
||||
if (c & 0xC0) ~= 0x80 then count = count + 1 end
|
||||
i = i + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
-- The five yellow_box shadow strips. index 0 = closed (1p), index 1 = open (2p/highlight).
|
||||
function M.draw_shadows(bx, by, fade, index)
|
||||
tex.draw_texture(T("yellow_box", "shadow_bottom_left"), { x = bx, y = by, fade = fade, index = index })
|
||||
tex.draw_texture(T("yellow_box", "shadow_bottom"), { x = bx, y = by, fade = fade, index = index })
|
||||
tex.draw_texture(T("yellow_box", "shadow_bottom_right"), { x = bx, y = by, fade = fade, index = index })
|
||||
tex.draw_texture(T("yellow_box", "shadow_right"), { x = bx, y = by, fade = fade, index = index })
|
||||
tex.draw_texture(T("yellow_box", "shadow_top_right"), { x = bx, y = by, fade = fade, index = index })
|
||||
end
|
||||
|
||||
-- The 9-slice yellow frame (YellowBox::draw). is_diff picks the diff-select animation set.
|
||||
function M.draw_yellow_box(is_diff, fade, y_offset)
|
||||
y_offset = y_offset or 0
|
||||
local right_x = tex.get_animation(is_diff and 14 or 10).attribute
|
||||
local left_x = tex.get_animation(is_diff and 13 or 9).attribute
|
||||
local center_width = tex.get_animation(is_diff and 15 or 11).attribute
|
||||
local top_y = tex.get_animation(16).attribute
|
||||
local center_height = tex.get_animation(17).attribute
|
||||
local bottom_y = yellow_box_bottom_y()
|
||||
local eh = edge_height()
|
||||
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom_right"), { x = right_x, y = bottom_y + y_offset, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom_left"), { x = left_x, y = bottom_y + y_offset, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top_right"), { x = right_x, y = top_y + y_offset, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top_left"), { x = left_x, y = top_y + y_offset, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_bottom"), { x = left_x + eh, y = bottom_y + y_offset, x2 = center_width, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_right"), { x = right_x, y = top_y + eh + y_offset, y2 = center_height, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_left"), { x = left_x, y = top_y + eh + y_offset, y2 = center_height, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_top"), { x = left_x + eh, y = top_y + y_offset, x2 = center_width, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "yellow_box_center"), { x = left_x + eh, y = top_y + eh + y_offset, x2 = center_width, y2 = center_height, fade = fade })
|
||||
end
|
||||
|
||||
-- BaseBox::draw_closed — the generic folder_texture board (colour frame = texture_index).
|
||||
-- BackBox and DanBox reuse this; SongBox/FolderBox call it before their own closed content.
|
||||
function M.draw_base_closed(box)
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local fade = box.fade.attribute
|
||||
local tex_index = box:texture_index()
|
||||
local use_shader = box:has_recolor()
|
||||
|
||||
M.draw_shadows(bx, by, fade, 0)
|
||||
|
||||
if use_shader then box:begin_recolor() end
|
||||
tex.draw_texture(T("box", "folder_texture_left"), { frame = tex_index, x = bx, y = by, fade = fade })
|
||||
tex.draw_texture(T("box", "folder_texture"), { frame = tex_index, x = bx, y = by, x2 = song_box_bg_width(), fade = fade })
|
||||
tex.draw_texture(T("box", "folder_texture_right"), { frame = tex_index, x = bx, y = by, fade = fade })
|
||||
if use_shader then box:end_recolor() end
|
||||
|
||||
if tex_index == TI_DEFAULT then
|
||||
tex.draw_texture(T("box", "genre_overlay"), { x = bx, y = by, fade = fade })
|
||||
end
|
||||
if box:genre_index() == GI_DIFFICULTY then
|
||||
tex.draw_texture(T("box", "diff_overlay"), { x = bx, y = by, fade = fade })
|
||||
end
|
||||
end
|
||||
|
||||
-- The vertical song/folder title (BaseBox::load_text name). text_color is always white for
|
||||
-- song/folder/back; the outline is the genre's fore_color. Cached per box on `self`.
|
||||
function M.vertical_name(self, box)
|
||||
self._name_cache = self._name_cache or {}
|
||||
local name = box.text_name or ""
|
||||
local fc = box:fore_color() or { r = 0, g = 0, b = 0, a = 255 }
|
||||
local key = box:path() .. "\0" .. tostring(fc.r or 0) .. "." .. tostring(fc.g or 0) .. "." .. tostring(fc.b or 0)
|
||||
local t = self._name_cache[key]
|
||||
if t == nil then
|
||||
local cfg = tex.get_skin_config("song_box_name")
|
||||
local font_size = (cfg and cfg.font_size) or 40
|
||||
if M.utf8_char_count(name) >= 30 then
|
||||
font_size = font_size - 10 * tex.get_screen_scale()
|
||||
end
|
||||
local outline = { fc.r or 0, fc.g or 0, fc.b or 0, fc.a or 255 }
|
||||
t = text.create_raw_text(name, font_size, { 255, 255, 255, 255 }, outline, true, 5.0, 2.0, 1.0)
|
||||
self._name_cache[key] = t
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Highest-crown helper shared by SongBox/FolderBox closed states.
|
||||
-- Returns frame (min(diff, URA)) and the crown value, or nil.
|
||||
function M.highest_crown(map)
|
||||
local highest_key = -1
|
||||
for k in pairs(map) do
|
||||
if type(k) == "number" and k > highest_key then highest_key = k end
|
||||
end
|
||||
if highest_key < 0 then return nil end
|
||||
local frame = math.min(4, highest_key) -- Difficulty::URA == 4
|
||||
return map[highest_key], frame
|
||||
end
|
||||
|
||||
-- Draw a single crown icon (crown_dfc/crown_fc/crown_clear) at frame, position px, y.
|
||||
-- crowns: {0=none,1=clear,2=fc,3=dfc}
|
||||
function M.draw_crown(crown, frame, px, y, fade)
|
||||
if crown == 3 then
|
||||
tex.draw_texture(T("yellow_box", "crown_dfc"), { frame = frame, x = px, y = y, fade = fade })
|
||||
elseif crown == 2 then
|
||||
tex.draw_texture(T("yellow_box", "crown_fc"), { frame = frame, x = px, y = y, fade = fade })
|
||||
elseif crown and crown >= 1 then
|
||||
tex.draw_texture(T("yellow_box", "crown_clear"), { frame = frame, x = px, y = y, fade = fade })
|
||||
end
|
||||
end
|
||||
|
||||
-- Localized song count ("全{0}曲" / "{0} Songs").
|
||||
function M.format_song_count(count)
|
||||
local template = tex.skin_text("song_count")
|
||||
if template == "" then template = "全{0}曲" end
|
||||
local out, n = template:gsub("{0}", tostring(count))
|
||||
if n == 0 then out = template .. tostring(count) end
|
||||
return out
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Yellow-box animation driving. The engine no longer starts/advances the shared
|
||||
-- yellow-box animations (9..18); the skin does it, keyed off the box draw_state.
|
||||
-- ---------------------------------------------------------------------------
|
||||
local YB_OPEN_ANIMS = { 9, 10, 11 }
|
||||
local YB_DIFF_ANIMS = { 13, 14, 15, 16, 17, 18 }
|
||||
local YB_RESET_ANIMS = { 9, 10, 11, 14, 16, 17 }
|
||||
|
||||
local function yb_anim(id) return tex.get_animation(id) end
|
||||
|
||||
local function yb_open() -- expand_box reset + create_anim (start 9/10/11)
|
||||
for _, id in ipairs(YB_RESET_ANIMS) do yb_anim(id):reset() end
|
||||
for _, id in ipairs(YB_OPEN_ANIMS) do yb_anim(id):start() end
|
||||
end
|
||||
local function yb_diff() -- create_anim_2 (start 13..18)
|
||||
for _, id in ipairs(YB_DIFF_ANIMS) do yb_anim(id):start() end
|
||||
end
|
||||
local function yb_back() -- exit_box -> create_anim (reset 14/16/17 + start 9/10/11)
|
||||
yb_anim(14):reset(); yb_anim(16):reset(); yb_anim(17):reset()
|
||||
for _, id in ipairs(YB_OPEN_ANIMS) do yb_anim(id):start() end
|
||||
end
|
||||
|
||||
-- Per-open-box state (only one box is open at a time).
|
||||
local yb_box = { path = nil, state = "closed" }
|
||||
|
||||
function M.reset_yellow_box()
|
||||
yb_box.path, yb_box.state = nil, "closed"
|
||||
end
|
||||
|
||||
-- Call once per box from draw_box; detects open/enter/exit transitions.
|
||||
function M.track_yellow_box(box)
|
||||
local state = box:draw_state()
|
||||
local path = box:path()
|
||||
if state == "closed" then
|
||||
if yb_box.path == path then
|
||||
yb_box.path, yb_box.state = nil, "closed"
|
||||
end
|
||||
return
|
||||
end
|
||||
if yb_box.path ~= path then
|
||||
yb_box.path, yb_box.state = path, state
|
||||
yb_open()
|
||||
elseif yb_box.state ~= state then
|
||||
yb_box.state = state
|
||||
if state == "diff_select" then yb_diff() else yb_back() end
|
||||
end
|
||||
end
|
||||
|
||||
-- Call once per frame from SongSelect:update; advances the shared yellow-box animations.
|
||||
function M.update_yellow_box(current_ms)
|
||||
for _, id in ipairs(YB_OPEN_ANIMS) do yb_anim(id):update(current_ms) end
|
||||
for _, id in ipairs(YB_DIFF_ANIMS) do yb_anim(id):update(current_ms) end
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,232 @@
|
||||
-- FolderBox rendering (genre folder closed/open), split out of song_select.lua.
|
||||
-- Mirrors src/objects/song_select/file_navigator/box_folder.cpp.
|
||||
|
||||
local base = require("song_select/file_navigator/box_base")
|
||||
|
||||
local T = base.T
|
||||
local draw_shadows = base.draw_shadows
|
||||
local draw_base_closed = base.draw_base_closed
|
||||
local vertical_name = base.vertical_name
|
||||
|
||||
local WHITE = { 255, 255, 255, 255 }
|
||||
local BLACK = { 0, 0, 0, 255 }
|
||||
|
||||
local function is_2p_screen()
|
||||
return (tex.current_screen and tex.current_screen() or "") == "SONG_SELECT_2P"
|
||||
end
|
||||
|
||||
local function make_count_text(count)
|
||||
local count_cfg = tex.get_skin_config("song_tja_count") or { font_size = 35 }
|
||||
return text.create_raw_text(base.format_song_count(count), count_cfg.font_size or 35, WHITE, BLACK, false, 5.0, 2.0, 1.0)
|
||||
end
|
||||
|
||||
-- Folder text objects (hori_name, tja_count_text, explanation) from FolderBox::load_text,
|
||||
-- cached per box on self. The song count is filled in by a background scan after the box is
|
||||
-- first drawn, so its text is rebuilt whenever the count changes (it stayed at 0 otherwise).
|
||||
local function folder_texts(self, box)
|
||||
self._folder_texts = self._folder_texts or {}
|
||||
local key = box:path()
|
||||
local t = self._folder_texts[key]
|
||||
if t == nil then
|
||||
local name = box.text_name or ""
|
||||
|
||||
local hori_cfg = tex.get_skin_config("song_hori_name") or { font_size = 40 }
|
||||
local hori_name = text.create_raw_text(name, hori_cfg.font_size or 40, WHITE, BLACK, false, 5.0, 2.0, 1.0)
|
||||
|
||||
local count = box.tja_count or 0
|
||||
local tja_count_text = make_count_text(count)
|
||||
|
||||
local explanation = box:explanation() or {}
|
||||
local exp_cfg = tex.get_skin_config("box_folder_explanation") or { font_size = 34 }
|
||||
local exp_box = tex.get_skin_config("box_folder_explanation_box") or { width = 160 }
|
||||
local lang = tex.language()
|
||||
local is_cjk = text.language_is_cjk(lang)
|
||||
local exp_texts = {}
|
||||
for i = 1, 3 do
|
||||
local s = explanation[i]
|
||||
if s and s ~= "" then
|
||||
local content = s
|
||||
if not is_cjk then
|
||||
content = text.word_wrap(s, exp_cfg.font_size or 34, 2.0, (exp_box.width or 160) - 20.0)
|
||||
end
|
||||
exp_texts[i] = text.create_raw_text(content, exp_cfg.font_size or 34, WHITE, BLACK, is_cjk, 5.0, 2.0, 1.0)
|
||||
end
|
||||
end
|
||||
|
||||
t = { hori_name = hori_name, tja_count_text = tja_count_text, count = count, explanation = exp_texts }
|
||||
self._folder_texts[key] = t
|
||||
else
|
||||
local count = box.tja_count or 0
|
||||
if count ~= t.count then
|
||||
t.tja_count_text = make_count_text(count)
|
||||
t.count = count
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- FolderBox::draw_closed crown badge (best crown, no fade).
|
||||
local function draw_folder_crown(box, bx, by)
|
||||
local function draw_one(info, px)
|
||||
if not info then return end
|
||||
base.draw_crown(info.crown, info.frame, px, by, 1.0)
|
||||
end
|
||||
local crown_1p = box:highest_crown()
|
||||
local crown_2p
|
||||
if is_2p_screen() then crown_2p = box:highest_crown_p2() end
|
||||
|
||||
if crown_2p then
|
||||
local info = tex.get_texture_info("yellow_box", "crown_dfc")
|
||||
local half = (info and info.width or 0) * 0.35
|
||||
draw_one(crown_1p, bx - half)
|
||||
draw_one(crown_2p, bx + half)
|
||||
elseif crown_1p then
|
||||
draw_one(crown_1p, bx)
|
||||
end
|
||||
end
|
||||
|
||||
function SongSelect:draw_folder_closed(box)
|
||||
draw_base_closed(box)
|
||||
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local fade = box.fade.attribute
|
||||
local tex_index = box:texture_index()
|
||||
local use_shader = box:has_recolor()
|
||||
|
||||
if use_shader then box:begin_recolor() end
|
||||
tex.draw_texture(T("box", "folder_clip"), { frame = tex_index, x = bx - (1.0 * tex.get_screen_scale()), y = by, fade = fade })
|
||||
if use_shader then box:end_recolor() end
|
||||
|
||||
local name = vertical_name(self, box)
|
||||
local name_cfg = tex.get_skin_config("song_box_name") or { x = 47, y = 129, height = 417 }
|
||||
local name_h = math.min(name.height, name_cfg.height)
|
||||
name:draw({
|
||||
x = bx + name_cfg.x - math.floor(name.width / 2),
|
||||
y = name_cfg.y + by,
|
||||
y2 = name_h - name.height,
|
||||
fade = fade
|
||||
})
|
||||
|
||||
draw_folder_crown(box, bx, by)
|
||||
end
|
||||
|
||||
local function draw_open_bg(self, box, fade)
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local shadow_fade = math.min(fade, box.open_fade.attribute)
|
||||
draw_shadows(bx, by, shadow_fade, 1)
|
||||
|
||||
local tex_index = box:texture_index()
|
||||
local use_shader = box:has_recolor()
|
||||
local open_anim = box.open_anim.attribute
|
||||
|
||||
if open_anim >= (100.0 * tex.get_screen_scale()) then
|
||||
if use_shader then box:begin_recolor() end
|
||||
tex.draw_texture(T("box", "folder_top_edge"), { frame = tex_index, mirror = "horizontal", y = by - open_anim, fade = fade })
|
||||
tex.draw_texture(T("box", "folder_top"), { frame = tex_index, y = by - open_anim, fade = fade })
|
||||
local top_cfg = tex.get_skin_config("song_folder_top") or { x = 268 }
|
||||
tex.draw_texture(T("box", "folder_top_edge"), { frame = tex_index, x = top_cfg.x, y = by - open_anim, fade = fade })
|
||||
if use_shader then box:end_recolor() end
|
||||
end
|
||||
|
||||
if use_shader then box:begin_recolor() end
|
||||
tex.draw_texture(T("box", "folder_texture_left"), { frame = tex_index, x = bx - open_anim, y = by, fade = fade })
|
||||
tex.draw_texture(T("box", "folder_texture"), { frame = tex_index, x = bx - open_anim, y = by, x2 = (open_anim * 2.0) + base.song_box_bg_width(), fade = fade })
|
||||
tex.draw_texture(T("box", "folder_texture_right"), { frame = tex_index, x = bx + open_anim, y = by, fade = fade })
|
||||
if use_shader then box:end_recolor() end
|
||||
end
|
||||
|
||||
local function draw_open_fg(self, box, fade)
|
||||
local texts = folder_texts(self, box)
|
||||
local open_anim = box.open_anim.attribute
|
||||
|
||||
if open_anim >= (100.0 * tex.get_screen_scale()) then
|
||||
local hori_cfg = tex.get_skin_config("song_hori_name") or { x = 642, y = 204, width = 300 }
|
||||
local dest_width = math.min(hori_cfg.width, texts.hori_name.width)
|
||||
texts.hori_name:draw({
|
||||
x = hori_cfg.x - dest_width / 2.0,
|
||||
y = hori_cfg.y - open_anim,
|
||||
x2 = dest_width - texts.hori_name.width,
|
||||
fade = fade
|
||||
})
|
||||
end
|
||||
|
||||
if box:texture_index() == base.TI_DEFAULT then
|
||||
tex.draw_texture(T("box", "genre_overlay_large"), { fade = fade })
|
||||
end
|
||||
if box:genre_index() == base.GI_DIFFICULTY then
|
||||
tex.draw_texture(T("box", "diff_overlay_large"), { fade = fade })
|
||||
end
|
||||
|
||||
if box:genre_index() ~= base.GI_DIFFICULTY then
|
||||
tex.draw_texture(T("yellow_box", "song_count_back"), { fade = math.min(fade, 0.5) })
|
||||
local count_cfg = tex.get_skin_config("song_tja_count") or { x = 560, y = 130, width = 184 }
|
||||
local dest_width = math.min(count_cfg.width, texts.tja_count_text.width)
|
||||
texts.tja_count_text:draw({
|
||||
x = count_cfg.x - dest_width / 2.0,
|
||||
y = count_cfg.y,
|
||||
x2 = dest_width - texts.tja_count_text.width,
|
||||
fade = fade
|
||||
})
|
||||
end
|
||||
|
||||
if box:has_box_texture() then
|
||||
local box_cfg = tex.get_skin_config("box_texture") or { x = 48, y = 330 }
|
||||
local max_size = tex.get_skin_config("box_folder_max_size") or { width = 344, height = 424 }
|
||||
box:draw_box_texture({
|
||||
cx = box:box_x() + box_cfg.x,
|
||||
cy = box_cfg.y + box:box_y(),
|
||||
max_w = max_size.width,
|
||||
max_h = max_size.height,
|
||||
fade = fade
|
||||
})
|
||||
elseif box:texture_index() ~= base.TI_DEFAULT then
|
||||
tex.draw_texture(T("box", "folder_graphic"), { frame = box:genre_index(), fade = fade })
|
||||
|
||||
local exp_cfg = tex.get_skin_config("box_folder_explanation") or { x = 776, y = 131, width = 43, height = 73 }
|
||||
local exp_box = tex.get_skin_config("box_folder_explanation_box") or { x = 650, y = 125, width = 160, height = 400 }
|
||||
local lang = tex.language()
|
||||
local is_cjk = text.language_is_cjk(lang)
|
||||
if is_cjk then
|
||||
for i = 1, 3 do
|
||||
local t = texts.explanation[i]
|
||||
if t then
|
||||
local idx = i - 1
|
||||
local center_x = exp_cfg.x - exp_cfg.width * idx
|
||||
t:draw({ x = center_x - t.width / 2.0, y = exp_cfg.y + exp_cfg.height * idx, fade = fade })
|
||||
end
|
||||
end
|
||||
else
|
||||
local total_h = 0.0
|
||||
for i = 1, 3 do
|
||||
if texts.explanation[i] then total_h = total_h + texts.explanation[i].height end
|
||||
end
|
||||
local scale = total_h > exp_box.height and (exp_box.height / total_h) or 1.0
|
||||
local y = exp_box.y
|
||||
for i = 1, 3 do
|
||||
local t = texts.explanation[i]
|
||||
if t then
|
||||
local dest_h = t.height * scale
|
||||
t:draw({
|
||||
x = exp_box.x + (exp_box.width - t.width) / 2.0,
|
||||
y = y,
|
||||
y2 = dest_h - t.height,
|
||||
fade = fade
|
||||
})
|
||||
y = y + dest_h
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SongSelect:draw_folder_open(box)
|
||||
if box.entered then
|
||||
draw_open_bg(self, box, 0.0)
|
||||
draw_open_fg(self, box, box:enter_fade().attribute)
|
||||
else
|
||||
draw_open_bg(self, box, math.min(1.0, box.fade.attribute))
|
||||
draw_open_fg(self, box, math.min(box.open_fade.attribute, box.fade.attribute))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,366 @@
|
||||
-- SongBox rendering (song board closed/open/diff-select), split out of song_select.lua.
|
||||
-- Mirrors src/objects/song_select/file_navigator/box_song.cpp.
|
||||
|
||||
local base = require("song_select/file_navigator/box_base")
|
||||
|
||||
local T = base.T
|
||||
local utf8_char_count = base.utf8_char_count
|
||||
local draw_shadows = base.draw_shadows
|
||||
local draw_yellow_box = base.draw_yellow_box
|
||||
local draw_base_closed = base.draw_base_closed
|
||||
local vertical_name = base.vertical_name
|
||||
|
||||
-- Difficulty enum (must match enums.h).
|
||||
local DIFF_EASY, DIFF_NORMAL, DIFF_HARD, DIFF_ONI, DIFF_URA = 0, 1, 2, 3, 4
|
||||
|
||||
local BLACK = { 0, 0, 0, 255 }
|
||||
local WHITE = { 255, 255, 255, 255 }
|
||||
local BLANK = { 0, 0, 0, 0 }
|
||||
|
||||
local function is_2p_screen()
|
||||
return (tex.current_screen and tex.current_screen() or "") == "SONG_SELECT_2P"
|
||||
end
|
||||
|
||||
-- Build a set of vertical OutlinedText labels sized to fit one shared box (mirrors
|
||||
-- build_vertical_label_set in box_song.cpp).
|
||||
local function build_vertical_labels(keys, box_cfg, v_advance, font_bonus, fills, outlines, thickness)
|
||||
local labels = {}
|
||||
local max_chars = 1
|
||||
for i, key in ipairs(keys) do
|
||||
labels[i] = tex.skin_text(key)
|
||||
if labels[i] == "" then labels[i] = "?" end
|
||||
max_chars = math.max(max_chars, utf8_char_count(labels[i]))
|
||||
end
|
||||
local width_cap = box_cfg.width - 4.0
|
||||
local height_cap = (box_cfg.height - 4.0) / (1.0 + (max_chars - 1) * v_advance)
|
||||
local font_size = math.floor(math.min(width_cap, height_cap) + font_bonus)
|
||||
local out = {}
|
||||
for i = 1, #keys do
|
||||
out[i] = text.create_raw_text(labels[i], font_size, fills[i], outlines[i], true, thickness, 2.0, v_advance)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- diff_tower_label (5 diffs) — static cache in C++, cached on self here.
|
||||
local function diff_tower_labels(self)
|
||||
if self._diff_tower_labels then return self._diff_tower_labels end
|
||||
local cfg = tex.get_skin_config("diff_tower_label_box") or { x = 475, y = 158, width = 53, height = 152 }
|
||||
local keys = { "diff_tower_easy", "diff_tower_normal", "diff_tower_hard", "diff_tower_oni", "diff_tower_ura" }
|
||||
local fills = { BLACK, BLACK, BLACK, BLACK, WHITE }
|
||||
local outlines = { BLANK, BLANK, BLANK, BLANK, { 0, 73, 90, 255 } }
|
||||
self._diff_tower_labels = build_vertical_labels(keys, cfg, 0.9, 5.0, fills, outlines, 3.0)
|
||||
return self._diff_tower_labels
|
||||
end
|
||||
|
||||
-- difficulty_bar_label (4 diffs).
|
||||
local function difficulty_bar_labels(self)
|
||||
if self._difficulty_bar_labels then return self._difficulty_bar_labels end
|
||||
local cfg = tex.get_skin_config("difficulty_bar_label_box") or { x = 481, y = 256, width = 26, height = 96 }
|
||||
local keys = { "diff_tower_easy", "diff_tower_normal", "diff_tower_hard", "diff_tower_oni" }
|
||||
local colors = { BLACK, BLACK, BLACK, BLACK }
|
||||
self._difficulty_bar_labels = build_vertical_labels(keys, cfg, 0.9, 7.0, colors, colors, 0.0)
|
||||
return self._difficulty_bar_labels
|
||||
end
|
||||
|
||||
-- The three song text objects (name, name_black, subtitle) from BaseBox::load_text +
|
||||
-- SongBox::load_text, cached per box on self.
|
||||
local function song_texts(self, box)
|
||||
self._song_texts = self._song_texts or {}
|
||||
local name = box.text_name or ""
|
||||
local fc = box:fore_color() or { r = 0, g = 0, b = 0, a = 255 }
|
||||
local key = box:path() .. "\0" .. tostring(fc.r or 0) .. "." .. tostring(fc.g or 0) .. "." .. tostring(fc.b or 0)
|
||||
local t = self._song_texts[key]
|
||||
if t == nil then
|
||||
local sub = box.text_subtitle or ""
|
||||
local fore = { fc.r or 0, fc.g or 0, fc.b or 0, fc.a or 255 }
|
||||
|
||||
local name_cfg = tex.get_skin_config("song_box_name") or { font_size = 40 }
|
||||
local base_name_font = name_cfg.font_size or 40
|
||||
local name_font = base_name_font
|
||||
local name_outline = 5.0
|
||||
if utf8_char_count(name) >= 30 then
|
||||
name_font = base_name_font - 10 * tex.get_screen_scale()
|
||||
name_outline = 5.0 * (name_font / base_name_font)
|
||||
end
|
||||
local name_text = text.create_raw_text(name, name_font, WHITE, fore, true, 5.0, 2.0, 1.0)
|
||||
local name_black = text.create_raw_text(name, name_font, WHITE, BLACK, true, name_outline, 2.0, 1.0)
|
||||
|
||||
local sub_cfg = tex.get_skin_config("yb_subtitle") or { font_size = 30 }
|
||||
local base_sub_font = sub_cfg.font_size or 30
|
||||
local sub_font = base_sub_font
|
||||
local sub_outline = 5.0
|
||||
if utf8_char_count(sub) >= 30 then
|
||||
sub_font = base_sub_font - 10 * tex.get_screen_scale()
|
||||
sub_outline = 5.0 * (sub_font / base_sub_font)
|
||||
end
|
||||
local subtitle = text.create_raw_text(sub, sub_font, WHITE, BLACK, true, sub_outline, 2.0, 1.0)
|
||||
|
||||
t = { name = name_text, name_black = name_black, subtitle = subtitle }
|
||||
self._song_texts[key] = t
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- draw_diff_outline (small crown outline; doubled in 2P).
|
||||
local function draw_diff_outline(x, y, fade)
|
||||
if is_2p_screen() then
|
||||
local half = tex.get_texture_info("yellow_box", "s_crown_dfc")
|
||||
half = (half and half.width or 0) * 0.35
|
||||
tex.draw_texture(T("yellow_box", "s_crown_outline"), { x = x - half, y = y, fade = fade })
|
||||
tex.draw_texture(T("yellow_box", "s_crown_outline"), { x = x + half, y = y, fade = fade })
|
||||
else
|
||||
tex.draw_texture(T("yellow_box", "s_crown_outline"), { x = x, y = y, fade = fade })
|
||||
end
|
||||
end
|
||||
|
||||
-- draw_diff_crown (small crown per diff; uses p1/p2 scores in 2P).
|
||||
local function draw_diff_crown(box, diff, x, y, fade)
|
||||
local function draw_one(info, px)
|
||||
if not info.has_score then return end
|
||||
if info.crown == 3 then
|
||||
tex.draw_texture(T("yellow_box", "s_crown_dfc"), { x = px, y = y, fade = fade })
|
||||
elseif info.crown == 2 then
|
||||
tex.draw_texture(T("yellow_box", "s_crown_fc"), { x = px, y = y, fade = fade })
|
||||
elseif info.crown >= 1 then
|
||||
tex.draw_texture(T("yellow_box", "s_crown_clear"), { x = px, y = y, fade = fade })
|
||||
end
|
||||
end
|
||||
if is_2p_screen() then
|
||||
local half = tex.get_texture_info("yellow_box", "s_crown_dfc")
|
||||
half = (half and half.width or 0) * 0.35
|
||||
draw_one(box:course_info(diff), x - half)
|
||||
draw_one(box:course_info_p2(diff), x + half)
|
||||
else
|
||||
draw_one(box:course_info(diff), x)
|
||||
end
|
||||
end
|
||||
|
||||
-- draw_box_crown (the closed-state best crown; highest-difficulty score wins).
|
||||
local function draw_box_crown(box, x, y, fade)
|
||||
local function highest(info_fn)
|
||||
local best_key = -1
|
||||
local best_crown = 0
|
||||
for d = 0, 4 do
|
||||
local info = info_fn(d)
|
||||
if info.has_course and info.has_score then
|
||||
if d > best_key then best_key = d; best_crown = info.crown end
|
||||
end
|
||||
end
|
||||
if best_key < 0 then return nil, nil end
|
||||
return best_crown, math.min(DIFF_URA, best_key)
|
||||
end
|
||||
|
||||
local crown_1p, frame_1p = highest(function(d) return box:course_info(d) end)
|
||||
local crown_2p, frame_2p
|
||||
if is_2p_screen() then
|
||||
crown_2p, frame_2p = highest(function(d) return box:course_info_p2(d) end)
|
||||
end
|
||||
|
||||
if crown_2p then
|
||||
local info = tex.get_texture_info("yellow_box", "crown_dfc")
|
||||
local half = (info and info.width or 0) * 0.35
|
||||
if crown_1p then base.draw_crown(crown_1p, frame_1p, x - half, y, fade) end
|
||||
base.draw_crown(crown_2p, frame_2p, x + half, y, fade)
|
||||
elseif crown_1p then
|
||||
base.draw_crown(crown_1p, frame_1p, x, y, fade)
|
||||
end
|
||||
end
|
||||
|
||||
-- draw_text (the open-state name/subtitle, tracking the yellow box's expansion).
|
||||
local function draw_text(box, texts)
|
||||
local right_out = tex.get_animation(10)
|
||||
local right_out_2 = tex.get_animation(14)
|
||||
local top_y_out = tex.get_animation(16)
|
||||
local x = box:box_x()
|
||||
+ (right_out.attribute * 0.90 - right_out.start_position * 0.90)
|
||||
+ right_out_2.attribute - right_out_2.start_position
|
||||
|
||||
local sub_cfg = tex.get_skin_config("yb_subtitle") or { x = -15, y = 545, height = 410 }
|
||||
local h = math.min(texts.subtitle.height, sub_cfg.height)
|
||||
texts.subtitle:draw({
|
||||
x = x + sub_cfg.x,
|
||||
y = sub_cfg.y - h + top_y_out.attribute - top_y_out.start_position,
|
||||
y2 = h - texts.subtitle.height,
|
||||
fade = box.open_fade.attribute
|
||||
})
|
||||
|
||||
local name_cfg = tex.get_skin_config("song_box_name") or { x = 47, y = 129, height = 417 }
|
||||
local name_h = math.min(texts.name.height, name_cfg.height) - texts.name.height
|
||||
local name_x = x + name_cfg.x - math.floor(texts.name.width / 2)
|
||||
local name_y = name_cfg.y + top_y_out.attribute - top_y_out.start_position
|
||||
texts.name_black:draw({ x = name_x, y = name_y, y2 = name_h, fade = box.open_fade.attribute })
|
||||
texts.name:draw({ x = name_x, y = name_y, y2 = name_h, fade = 1 - box.open_fade.attribute })
|
||||
end
|
||||
|
||||
function SongSelect:draw_song_closed(box)
|
||||
draw_base_closed(box)
|
||||
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local fade = box.fade.attribute
|
||||
|
||||
local name = vertical_name(self, box)
|
||||
local name_cfg = tex.get_skin_config("song_box_name") or { x = 47, y = 129, height = 417 }
|
||||
local name_x = bx + name_cfg.x - math.floor(name.width / 2)
|
||||
local name_y = name_cfg.y + by
|
||||
local name_h = math.min(name.height, name_cfg.height)
|
||||
name:draw({ x = name_x, y = name_y, y2 = name_h - name.height, fade = fade })
|
||||
|
||||
if box:has_preimage() then
|
||||
tex.draw_texture(T("yellow_box", "preimage_bg"), { x = bx, y = by, fade = fade })
|
||||
box:draw_preimage(bx, by, fade)
|
||||
elseif box:ex_data_flag() == 3 then -- limited_time
|
||||
tex.draw_texture(T("yellow_box", "ex_data_limited_time_balloon"), { x = bx, y = by, fade = fade })
|
||||
elseif box.is_new then
|
||||
tex.draw_texture(T("yellow_box", "ex_data_new_song_balloon"), { x = bx, y = by, fade = fade })
|
||||
end
|
||||
|
||||
draw_box_crown(box, bx, by, fade)
|
||||
end
|
||||
|
||||
function SongSelect:draw_song_open(box)
|
||||
local bx = box:box_x()
|
||||
local by = box:box_y()
|
||||
local open_fade = box.open_fade.attribute
|
||||
|
||||
draw_shadows(bx, by, open_fade, 1)
|
||||
draw_yellow_box(false, 1.0, 0.0)
|
||||
|
||||
local offset = (tex.get_skin_config("yb_diff_offset") or { x = 60 }).x
|
||||
local texts = song_texts(self, box)
|
||||
|
||||
-- diff outlines + crowns (diff < URA)
|
||||
for d = 0, 3 do
|
||||
local info = box:course_info(d)
|
||||
if info.has_course then
|
||||
draw_diff_outline(d * offset, 0.0, math.min(open_fade, 0.25))
|
||||
draw_diff_crown(box, d, d * offset, 0.0, open_fade)
|
||||
end
|
||||
end
|
||||
|
||||
-- ex_data / new icon
|
||||
local exd = box:ex_data_flag()
|
||||
if exd == 1 then
|
||||
tex.draw_texture(T("yellow_box", "ex_data_new_audio"), { fade = open_fade })
|
||||
elseif exd == 2 then
|
||||
tex.draw_texture(T("yellow_box", "ex_data_old_audio"), { fade = open_fade })
|
||||
elseif exd == 3 then
|
||||
tex.draw_texture(T("yellow_box", "ex_data_limited_time"), { fade = open_fade })
|
||||
elseif box.is_new then
|
||||
tex.draw_texture(T("yellow_box", "ex_data_new_song"), { fade = open_fade })
|
||||
end
|
||||
|
||||
if tex.display_bpm() then
|
||||
local bpm = box:bpm_text()
|
||||
local cfg = tex.get_skin_config("song_box_bpm") or { x = 628, y = 120 }
|
||||
if bpm then bpm:draw({ x = cfg.x, y = cfg.y, fade = open_fade }) end
|
||||
end
|
||||
|
||||
if box.is_favorite then
|
||||
tex.draw_texture(T("yellow_box", "favorite_" .. tex.player_num() .. "p"), { fade = open_fade })
|
||||
end
|
||||
|
||||
-- difficulty bars (4)
|
||||
for i = 0, 3 do
|
||||
tex.draw_texture(T("yellow_box", "difficulty_bar"), { frame = i, x = i * offset, fade = open_fade })
|
||||
if not box:course_info(i).has_course then
|
||||
tex.draw_texture(T("yellow_box", "difficulty_bar_shadow"), { frame = i, x = i * offset, fade = math.min(open_fade, 0.25) })
|
||||
end
|
||||
end
|
||||
|
||||
-- difficulty bar labels
|
||||
local labels = difficulty_bar_labels(self)
|
||||
local box_cfg = tex.get_skin_config("difficulty_bar_label_box") or { x = 481, y = 256, width = 26, height = 96 }
|
||||
for i = 0, 3 do
|
||||
local label = labels[i + 1]
|
||||
label:draw({
|
||||
x = box_cfg.x + i * offset + box_cfg.width / 2 - label.width / 2,
|
||||
y = box_cfg.y,
|
||||
y2 = math.min(label.height, box_cfg.height) - label.height,
|
||||
fade = open_fade
|
||||
})
|
||||
end
|
||||
|
||||
-- stars + branch indicator (diff < URA)
|
||||
local offset_y = (tex.get_skin_config("yb_diff_offset") or { y = -17 }).y
|
||||
for d = 0, 3 do
|
||||
local info = box:course_info(d)
|
||||
if info.has_course then
|
||||
for j = 0, info.level - 1 do
|
||||
tex.draw_texture(T("yellow_box", "star"), { x = d * offset, y = j * offset_y, fade = open_fade })
|
||||
end
|
||||
if info.is_branching and (math.floor(tex.get_current_ms() / 1000) % 2 == 0) then
|
||||
tex.draw_texture(T("yellow_box", "branch_indicator"), { x = d * offset, fade = open_fade })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
draw_text(box, texts)
|
||||
end
|
||||
|
||||
function SongSelect:draw_song_diff_select(box)
|
||||
draw_yellow_box(true, 1.0, 0.0)
|
||||
|
||||
local diff_fade = box.diff_fade_in.attribute
|
||||
tex.draw_texture(T("diff_select", "back"), { fade = diff_fade })
|
||||
tex.draw_texture(T("diff_select", "option"), { fade = diff_fade })
|
||||
tex.draw_texture(T("diff_select", "neiro"), { fade = diff_fade })
|
||||
|
||||
local offset_x = (tex.get_skin_config("yb_diff_offset_diff_select") or { x = 115 }).x
|
||||
local offset_y = (tex.get_skin_config("yb_diff_offset_diff_select") or { y = -120 }).y
|
||||
local crown_offset = (tex.get_skin_config("yb_diff_offset_crown") or { x = 8 }).x
|
||||
|
||||
-- diff crowns (diff < URA)
|
||||
for d = 0, 3 do
|
||||
local info = box:course_info(d)
|
||||
if info.has_course then
|
||||
local cx = d * offset_x + crown_offset
|
||||
draw_diff_outline(cx, offset_y, math.min(diff_fade, 0.25))
|
||||
draw_diff_crown(box, d, cx, offset_y, diff_fade)
|
||||
end
|
||||
end
|
||||
|
||||
-- diff towers + labels
|
||||
local tower_labels = diff_tower_labels(self)
|
||||
local box_cfg = tex.get_skin_config("diff_tower_label_box") or { x = 475, y = 158, width = 53, height = 152 }
|
||||
for i = 0, 3 do
|
||||
local label_index = i
|
||||
if i == DIFF_ONI and box.is_ura then
|
||||
tex.draw_texture(T("diff_select", "diff_tower"), { frame = 4, x = i * offset_x, fade = diff_fade })
|
||||
tex.draw_texture(T("diff_select", "ura_oni_plate"), { fade = diff_fade })
|
||||
label_index = 4
|
||||
else
|
||||
tex.draw_texture(T("diff_select", "diff_tower"), { frame = i, x = i * offset_x, fade = diff_fade })
|
||||
end
|
||||
if not box:course_info(i).has_course then
|
||||
tex.draw_texture(T("diff_select", "diff_tower_shadow"), { frame = i, x = i * offset_x, fade = math.min(diff_fade, 0.25) })
|
||||
end
|
||||
local label = tower_labels[label_index + 1]
|
||||
label:draw({
|
||||
x = box_cfg.x + i * offset_x + (box_cfg.width - label.width) / 2,
|
||||
y = box_cfg.y,
|
||||
fade = diff_fade
|
||||
})
|
||||
end
|
||||
|
||||
-- ura stars + branch indicator
|
||||
local star_offset_y = (tex.get_skin_config("yb_diff_offset_crown") or { y = -20 }).y
|
||||
for d = 0, 4 do
|
||||
local info = box:course_info(d)
|
||||
if info.has_course then
|
||||
if (d == DIFF_URA and not box.is_ura) or (d == DIFF_ONI and box.is_ura) then
|
||||
-- skip
|
||||
else
|
||||
for j = 0, info.level - 1 do
|
||||
tex.draw_texture(T("yellow_box", "star_ura"), { x = math.min(d, DIFF_ONI) * offset_x, y = j * star_offset_y, fade = diff_fade })
|
||||
end
|
||||
if info.is_branching and (math.floor(tex.get_current_ms() / 1000) % 2 == 0) then
|
||||
local bt = (d == DIFF_URA) and T("yellow_box", "branch_indicator_ura") or T("yellow_box", "branch_indicator_diff")
|
||||
tex.draw_texture(bt, { x = math.min(d, DIFF_ONI) * offset_x, fade = diff_fade })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
draw_text(box, song_texts(self, box))
|
||||
end
|
||||
@@ -0,0 +1,184 @@
|
||||
-- Inline-list background (GenreBG) drawing, split out of song_select.lua.
|
||||
-- Mirrors src/objects/song_select/file_navigator/genre_bg.cpp.
|
||||
|
||||
local function T(name)
|
||||
return tex.get_texture("song_select/box/" .. name)
|
||||
end
|
||||
|
||||
local _bg_edge_width, _bg_folder_edge_width
|
||||
local function bg_edge_width()
|
||||
if _bg_edge_width == nil then
|
||||
local info = tex.get_texture_info("box", "folder_background_edge")
|
||||
_bg_edge_width = (info and info.width) or 0
|
||||
end
|
||||
return _bg_edge_width
|
||||
end
|
||||
local function bg_folder_edge_width()
|
||||
if _bg_folder_edge_width == nil then
|
||||
local info = tex.get_texture_info("box", "folder_background_folder_edge")
|
||||
_bg_folder_edge_width = (info and info.width) or 0
|
||||
end
|
||||
return _bg_folder_edge_width
|
||||
end
|
||||
|
||||
-- draw_anim (folder still entering; box's bounds drive the growing span).
|
||||
local function draw_anim(gb, box)
|
||||
if not box then return end
|
||||
local s = gb.scale.attribute
|
||||
local offset = 5 * s
|
||||
local edge_width = bg_edge_width() * s
|
||||
local center = (box.left_bound + box.right_bound) / 2.0
|
||||
local half_width = (box.right_bound - box.left_bound) / 2.0
|
||||
local base_start = center - half_width * s
|
||||
local base_end = center + half_width * s
|
||||
local exiting = (gb.move_left ~= nil and gb.move_right ~= nil)
|
||||
local start_position = exiting and (base_start + gb.move_left.attribute) or base_start
|
||||
local end_position = exiting and (base_end + gb.move_right.attribute) or (base_end + gb.move.attribute)
|
||||
|
||||
local frame = gb:texture_frame()
|
||||
local fade = gb.fade.attribute
|
||||
local sy = -(gb.stretch.attribute * s)
|
||||
local recolor = gb:has_recolor()
|
||||
|
||||
if recolor then gb:begin_recolor() end
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, scale = s, center = true, mirror = "horizontal", x = start_position - offset, y = sy, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, scale = s, center = true, x = start_position + edge_width - offset, y = sy, x2 = end_position - start_position - edge_width - offset, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, scale = s, center = true, x = end_position - edge_width + offset, y = sy, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
|
||||
local edge_width_top = bg_folder_edge_width() * s
|
||||
local title_cfg = tex.get_skin_config("genre_bg_title") or { y = 0, width = 300 }
|
||||
local name = gb:name()
|
||||
local dest_width = math.min(title_cfg.width, name.width) * s
|
||||
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, scale = s, center = true, mirror = "horizontal", x = center - dest_width / 2 - edge_width_top, y = sy, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder"), { frame = frame, scale = s, center = true, x = center - dest_width / 2, y = sy, x2 = dest_width, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, scale = s, center = true, x = center + dest_width / 2, y = sy, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
if recolor then gb:end_recolor() end
|
||||
|
||||
name:draw({ center = true, x = center - dest_width / 2, y = title_cfg.y - gb.stretch.attribute * s, x2 = dest_width - name.width, y2 = gb.stretch.attribute * s, fade = fade })
|
||||
end
|
||||
|
||||
-- draw_exit_anim (folder closing; move_left/move_right drive the shrink).
|
||||
local function draw_exit_anim(gb)
|
||||
local s = gb.scale.attribute
|
||||
local offset = 5 * s
|
||||
local edge_width = bg_edge_width() * s
|
||||
local anim_start = gb.move_left.attribute
|
||||
local anim_end = gb.move_right.attribute
|
||||
local frame = gb:texture_frame()
|
||||
local fade = gb.fade.attribute
|
||||
local recolor = gb:has_recolor()
|
||||
|
||||
if recolor then gb:begin_recolor() end
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, scale = s, mirror = "horizontal", x = anim_start - offset, fade = fade })
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, scale = s, x = anim_start + edge_width - offset, x2 = anim_end - anim_start - edge_width - offset, fade = fade })
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, scale = s, x = anim_end - edge_width + offset, fade = fade })
|
||||
|
||||
local edge_width_top = bg_folder_edge_width()
|
||||
local title_cfg = tex.get_skin_config("genre_bg_title") or { width = 300 }
|
||||
local name = gb:name()
|
||||
local dest_width = math.min(title_cfg.width, name.width)
|
||||
local center = (tex.get_skin_config("genre_bg_center_x") or { x = 638.5 }).x
|
||||
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, mirror = "horizontal", x = center - dest_width / 2 - edge_width_top, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder"), { frame = frame, x = center - dest_width / 2, x2 = dest_width, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, x = center + dest_width / 2, fade = fade })
|
||||
if recolor then gb:end_recolor() end
|
||||
|
||||
name:draw({ x = center - dest_width / 2, y = title_cfg.y, x2 = dest_width - name.width, fade = fade })
|
||||
end
|
||||
|
||||
function SongSelect:draw_genre_bg(gb, start_position, end_position, folder)
|
||||
if not gb:is_finished() then
|
||||
draw_anim(gb, folder)
|
||||
return
|
||||
elseif not gb:is_complete() then
|
||||
draw_exit_anim(gb)
|
||||
return
|
||||
end
|
||||
|
||||
-- Steady state: fill the span between the first and last song's bounds.
|
||||
local screen_width = tex.get_screen_width()
|
||||
local frame = gb:texture_frame()
|
||||
local fade = gb.fade.attribute
|
||||
local name = gb:name()
|
||||
local title_cfg = tex.get_skin_config("genre_bg_title") or { y = 0, width = 300 }
|
||||
local center_cfg = tex.get_skin_config("genre_bg_center_x") or { x = 638.5 }
|
||||
local boundary = tex.get_skin_config("genre_bg_select_boundary") or { x = 442, width = 835 }
|
||||
|
||||
local edge_width_top = bg_folder_edge_width()
|
||||
local dest_width = math.min(title_cfg.width, name.width)
|
||||
local center = center_cfg.x
|
||||
|
||||
local bg_start_pos = start_position
|
||||
local bg_end_pos = end_position
|
||||
if boundary.x < start_position and start_position < center then
|
||||
bg_start_pos = boundary.x
|
||||
end
|
||||
if center < end_position and end_position < boundary.width then
|
||||
bg_end_pos = boundary.width
|
||||
end
|
||||
|
||||
local recolor = gb:has_recolor()
|
||||
if recolor then gb:begin_recolor() end
|
||||
|
||||
if bg_start_pos > bg_end_pos then
|
||||
-- wraps around: two segments
|
||||
local offset = 5
|
||||
local edge_width = bg_edge_width()
|
||||
local draw_end_l = math.min(bg_end_pos, screen_width)
|
||||
if 0 < draw_end_l then
|
||||
if bg_end_pos < screen_width then
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, x = 0, x2 = draw_end_l - edge_width + offset, fade = fade })
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, x = draw_end_l - edge_width + offset, fade = fade })
|
||||
else
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, x = 0, x2 = draw_end_l, fade = fade })
|
||||
end
|
||||
end
|
||||
local draw_start_r = math.max(bg_start_pos, 0)
|
||||
if draw_start_r < screen_width then
|
||||
if bg_start_pos > 0 then
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, x = draw_start_r + edge_width - offset, x2 = screen_width, fade = fade })
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, mirror = "horizontal", x = draw_start_r - offset, fade = fade })
|
||||
else
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, x = draw_start_r, x2 = screen_width, fade = fade })
|
||||
end
|
||||
end
|
||||
else
|
||||
local offset = 5
|
||||
local edge_width = bg_edge_width()
|
||||
local draw_start = math.max(bg_start_pos, 0)
|
||||
local draw_end = math.min(bg_end_pos, screen_width)
|
||||
if draw_start < draw_end then
|
||||
local fill_start = draw_start
|
||||
local fill_end = draw_end
|
||||
if bg_start_pos > 0 then
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, mirror = "horizontal", x = draw_start - offset, fade = fade })
|
||||
fill_start = draw_start + edge_width - offset
|
||||
end
|
||||
if bg_end_pos < screen_width then
|
||||
tex.draw_texture(T("folder_background_edge"), { frame = frame, x = draw_end - edge_width + offset, fade = fade })
|
||||
fill_end = draw_end - edge_width + offset
|
||||
end
|
||||
if fill_start < fill_end then
|
||||
tex.draw_texture(T("folder_background"), { frame = frame, x = fill_start, x2 = fill_end - fill_start, fade = fade })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local center_not_covered = (start_position <= end_position)
|
||||
and (center < start_position or end_position < center)
|
||||
or (end_position < center and center < start_position)
|
||||
if center_not_covered then
|
||||
if recolor then gb:end_recolor() end
|
||||
return
|
||||
end
|
||||
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, mirror = "horizontal", x = center - dest_width / 2 - edge_width_top, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder"), { frame = frame, x = center - dest_width / 2, x2 = dest_width, fade = fade })
|
||||
tex.draw_texture(T("folder_background_folder_edge"), { frame = frame, x = center + dest_width / 2, fade = fade })
|
||||
|
||||
if recolor then gb:end_recolor() end
|
||||
|
||||
name:draw({ x = center - dest_width / 2, y = title_cfg.y, x2 = dest_width - name.width, fade = fade })
|
||||
end
|
||||
@@ -0,0 +1,123 @@
|
||||
|
||||
ScoreHistory = {}
|
||||
ScoreHistory.__index = ScoreHistory
|
||||
|
||||
local DIFF_URA = 4
|
||||
|
||||
function ScoreHistory.new(available, is_shinuchi, current_ms)
|
||||
local self = setmetatable({}, ScoreHistory)
|
||||
|
||||
self.available = available
|
||||
self.is_shinuchi = is_shinuchi
|
||||
self.last_ms = current_ms
|
||||
self.curr_index = #available > 0 and ((1 % #available) + 1) or 0
|
||||
|
||||
local offset = tex.get_skin_config("score_info_bg_offset")
|
||||
local margin = tex.get_skin_config("score_info_counter_margin")
|
||||
self.offset_y = offset and offset.y or 0
|
||||
self.margin_w = margin and margin.width or 0
|
||||
self.margin_x = margin and margin.x or 0
|
||||
|
||||
local title_cfg = tex.get_skin_config("leaderboard_title_long")
|
||||
self.title_pos = title_cfg or {}
|
||||
self.title = nil
|
||||
local label = tex.skin_text("leaderboard_title")
|
||||
if label ~= "" and title_cfg then
|
||||
local font_size = title_cfg.height
|
||||
while font_size > 8 do
|
||||
local t = text.create_raw_text(label, font_size, { 0, 0, 0, 255 }, { 0, 0, 0, 0 }, false, 0, 2.0)
|
||||
if t.width <= title_cfg.width then
|
||||
self.title = t
|
||||
break
|
||||
end
|
||||
font_size = font_size - 1
|
||||
end
|
||||
if not self.title then
|
||||
self.title = text.create_raw_text(label, 8, { 0, 0, 0, 255 }, { 0, 0, 0, 0 }, false, 0, 2.0)
|
||||
end
|
||||
end
|
||||
|
||||
self.t_background_2 = tex.get_texture("song_select/leaderboard/background_2")
|
||||
self.t_shinuchi = tex.get_texture("song_select/leaderboard/shinuchi")
|
||||
self.t_shinuchi_ura = tex.get_texture("song_select/leaderboard/shinuchi_ura")
|
||||
self.t_pts = tex.get_texture("song_select/leaderboard/pts")
|
||||
self.t_normal = tex.get_texture("song_select/leaderboard/normal")
|
||||
self.t_difficulty = tex.get_texture("song_select/leaderboard/difficulty")
|
||||
self.t_judge_good = tex.get_texture("song_select/leaderboard/judge_good")
|
||||
self.t_judge_ok = tex.get_texture("song_select/leaderboard/judge_ok")
|
||||
self.t_judge_bad = tex.get_texture("song_select/leaderboard/judge_bad")
|
||||
self.t_judge_drumroll = tex.get_texture("song_select/leaderboard/judge_drumroll")
|
||||
self.t_counter = tex.get_texture("song_select/leaderboard/counter")
|
||||
self.t_judge_num = tex.get_texture("song_select/leaderboard/judge_num")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ScoreHistory:update(current_ms)
|
||||
if #self.available == 0 then return end
|
||||
if current_ms >= self.last_ms + 1000.0 then
|
||||
self.last_ms = current_ms
|
||||
self.curr_index = (self.curr_index % #self.available) + 1
|
||||
end
|
||||
end
|
||||
|
||||
function ScoreHistory:draw()
|
||||
if #self.available == 0 then return end
|
||||
|
||||
local entry = self.available[self.curr_index]
|
||||
local diff = entry.diff
|
||||
|
||||
if self.t_background_2 then tex.draw_texture(self.t_background_2) end
|
||||
if self.title then self.title:draw({ x = self.title_pos.x, y = self.title_pos.y }) end
|
||||
|
||||
if self.is_shinuchi then
|
||||
if diff == DIFF_URA then
|
||||
if self.t_shinuchi_ura then tex.draw_texture(self.t_shinuchi_ura, { index = 1 }) end
|
||||
else
|
||||
if self.t_shinuchi then tex.draw_texture(self.t_shinuchi, { index = 1 }) end
|
||||
end
|
||||
if self.t_pts then tex.draw_texture(self.t_pts, { color = { 255, 255, 255, 255 }, index = 1 }) end
|
||||
else
|
||||
if self.t_normal then tex.draw_texture(self.t_normal, { index = 1 }) end
|
||||
if self.t_pts then tex.draw_texture(self.t_pts, { color = { 0, 0, 0, 255 }, index = 1 }) end
|
||||
end
|
||||
|
||||
if self.t_difficulty then tex.draw_texture(self.t_difficulty, { frame = diff, index = 1 }) end
|
||||
|
||||
for i = 0, 3 do
|
||||
if self.t_normal then
|
||||
tex.draw_texture(self.t_normal, { y = self.offset_y + i * self.offset_y, index = 1 })
|
||||
end
|
||||
end
|
||||
|
||||
if self.t_judge_good then tex.draw_texture(self.t_judge_good) end
|
||||
if self.t_judge_ok then tex.draw_texture(self.t_judge_ok) end
|
||||
if self.t_judge_bad then tex.draw_texture(self.t_judge_bad) end
|
||||
if self.t_judge_drumroll then tex.draw_texture(self.t_judge_drumroll) end
|
||||
|
||||
local values = { entry.score, entry.good, entry.ok, entry.bad, entry.drumroll }
|
||||
local score_color = self.is_shinuchi and { 255, 255, 255, 255 } or { 0, 0, 0, 255 }
|
||||
|
||||
for j = 1, 5 do
|
||||
local counter = tostring(values[j])
|
||||
local len = #counter
|
||||
if j == 1 then
|
||||
for i = 1, len do
|
||||
local digit = tonumber(string.sub(counter, i, i)) or 0
|
||||
local x = -((len * self.margin_w) / 2.0) + ((i - 1) * self.margin_w)
|
||||
if self.t_counter then
|
||||
tex.draw_texture(self.t_counter, { color = score_color, frame = digit, x = x, index = 1 })
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 1, len do
|
||||
local digit = tonumber(string.sub(counter, i, i)) or 0
|
||||
local x = -(len - i + 1) * self.margin_x
|
||||
local y = (j - 1) * self.offset_y
|
||||
if self.t_judge_num then
|
||||
tex.draw_texture(self.t_judge_num, { frame = digit, x = x, y = y })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,10 +8,23 @@ local STATE_DAN_SELECTED = 4
|
||||
SongSelect = {}
|
||||
SongSelect.__index = SongSelect
|
||||
|
||||
-- The wheel box drawing (BaseBox/YellowBox/SongBox/FolderBox/BackBox) lives in
|
||||
-- file_navigator/, mirroring src/objects/song_select/file_navigator/. Each module adds
|
||||
-- its draw_* methods onto SongSelect as a side effect of being required.
|
||||
require("song_select/file_navigator/box_base")
|
||||
require("song_select/file_navigator/box_song")
|
||||
require("song_select/file_navigator/box_folder")
|
||||
require("song_select/file_navigator/box_back")
|
||||
require("song_select/file_navigator/genre_bg")
|
||||
local base = require("song_select/file_navigator/box_base")
|
||||
|
||||
function SongSelect.new()
|
||||
local self = setmetatable({}, SongSelect)
|
||||
tex.load_animations("song_select")
|
||||
base.reset_yellow_box()
|
||||
tex.load_folder("song_select", "global")
|
||||
tex.load_folder("song_select", "box")
|
||||
tex.load_folder("song_select", "yellow_box")
|
||||
tex.load_folder("song_select", "diff_select")
|
||||
|
||||
-- Animations (IDs from song_select/animation.json)
|
||||
self.text_fade_in = tex.get_animation(4) -- fade in/out the top-left label text
|
||||
@@ -36,6 +49,7 @@ function SongSelect:update(current_ms)
|
||||
self.text_fade_in:update(current_ms)
|
||||
self.blue_arrow_fade:update(current_ms)
|
||||
self.blue_arrow_move:update(current_ms)
|
||||
base.update_yellow_box(current_ms)
|
||||
end
|
||||
|
||||
-- Call whenever the screen state changes so the label cross-fades correctly.
|
||||
@@ -69,3 +83,30 @@ function SongSelect:draw_overlays(state)
|
||||
tex.draw_texture(self._id_song_select, { fade = label_fade })
|
||||
end
|
||||
end
|
||||
|
||||
function SongSelect:draw_box(box)
|
||||
base.track_yellow_box(box)
|
||||
local kind = box:lua_kind()
|
||||
local state = box:draw_state()
|
||||
if kind == "song" then
|
||||
if state == "diff_select" then
|
||||
self:draw_song_diff_select(box)
|
||||
elseif state == "open" then
|
||||
self:draw_song_open(box)
|
||||
else
|
||||
self:draw_song_closed(box)
|
||||
end
|
||||
elseif kind == "folder" then
|
||||
if state == "open" then
|
||||
self:draw_folder_open(box)
|
||||
else
|
||||
self:draw_folder_closed(box)
|
||||
end
|
||||
elseif kind == "back" then
|
||||
if state == "open" then
|
||||
self:draw_back_open(box)
|
||||
else
|
||||
self:draw_back_closed(box)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
UraSwitchAnimation = {}
|
||||
UraSwitchAnimation.__index = UraSwitchAnimation
|
||||
|
||||
function UraSwitchAnimation.new()
|
||||
local self = setmetatable({}, UraSwitchAnimation)
|
||||
|
||||
self.texture_change = tex.get_animation(7, "song_select")
|
||||
self.fade_out = tex.get_animation(8, "song_select")
|
||||
self.t_ura_switch = tex.get_texture("song_select/diff_select/ura_switch")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function UraSwitchAnimation:start(is_backwards)
|
||||
self.texture_change = tex.get_animation(is_backwards and 6 or 7, "song_select")
|
||||
self.texture_change:start()
|
||||
self.fade_out:start()
|
||||
end
|
||||
|
||||
function UraSwitchAnimation:update(current_ms)
|
||||
self.texture_change:update(current_ms)
|
||||
self.fade_out:update(current_ms)
|
||||
end
|
||||
|
||||
function UraSwitchAnimation:draw()
|
||||
tex.draw_texture(self.t_ura_switch, {
|
||||
frame = math.floor(self.texture_change.attribute),
|
||||
fade = self.fade_out.attribute,
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
AttractCamera = {}
|
||||
AttractCamera.__index = AttractCamera
|
||||
|
||||
function AttractCamera.new()
|
||||
local self = setmetatable({}, AttractCamera)
|
||||
self.start_ms = tex.get_current_ms()
|
||||
self.finished = false
|
||||
|
||||
camera.open()
|
||||
audio.play_sound("camera", "attract_mode")
|
||||
|
||||
self.live_icon_texture_change = tex.get_animation(36, "title")
|
||||
self.live_icon_texture_change:start()
|
||||
|
||||
local ok, timer = pcall(tex.get_animation, 37, "title")
|
||||
self.scene_timer = ok and timer or nil
|
||||
if self.scene_timer then self.scene_timer:start() end
|
||||
|
||||
self.t_background = tex.get_texture("title/camera/background")
|
||||
self.t_live_icon = tex.get_texture("title/camera/live_icon")
|
||||
self.t_live_text = tex.get_texture("title/camera/live_text")
|
||||
|
||||
self.viewport = tex.get_skin_config("attract_camera_viewport")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function AttractCamera:update(current_ms)
|
||||
camera.update()
|
||||
self.live_icon_texture_change:update(current_ms)
|
||||
if self.scene_timer then
|
||||
self.scene_timer:update(current_ms)
|
||||
self.finished = self.scene_timer.is_finished
|
||||
else
|
||||
self.finished = (current_ms - self.start_ms >= 30000)
|
||||
end
|
||||
end
|
||||
|
||||
function AttractCamera:draw()
|
||||
tex.draw_texture(self.t_background)
|
||||
if self.viewport then
|
||||
camera.draw(self.viewport.x, self.viewport.y, self.viewport.width, self.viewport.height)
|
||||
end
|
||||
tex.draw_texture(self.t_live_icon, { frame = math.floor(self.live_icon_texture_change.attribute) })
|
||||
tex.draw_texture(self.t_live_text)
|
||||
end
|
||||
|
||||
function AttractCamera:is_finished()
|
||||
return self.finished
|
||||
end
|
||||
|
||||
function AttractCamera:close()
|
||||
camera.close()
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
require("title/attract_camera")
|
||||
require("title/camera_cloud")
|
||||
require("title/bana_advert")
|
||||
|
||||
AttractScene = {}
|
||||
AttractScene.__index = AttractScene
|
||||
|
||||
function AttractScene.new()
|
||||
local self = setmetatable({}, AttractScene)
|
||||
self.attract_camera = AttractCamera.new()
|
||||
self.camera_cloud = CameraCloud.new()
|
||||
self.bana_advert_1 = BanaAdvertisement.new()
|
||||
self.bana_advert_2 = BanaAdvertisement.new()
|
||||
return self
|
||||
end
|
||||
|
||||
function AttractScene:update(current_ms)
|
||||
self.attract_camera:update(current_ms)
|
||||
self.camera_cloud:update(current_ms)
|
||||
self.bana_advert_1:update(current_ms)
|
||||
self.bana_advert_2:update(current_ms)
|
||||
end
|
||||
|
||||
function AttractScene:draw()
|
||||
self.attract_camera:draw()
|
||||
self.camera_cloud:draw()
|
||||
self.bana_advert_1:draw(33, 136)
|
||||
self.bana_advert_2:draw(1023, 136)
|
||||
end
|
||||
|
||||
function AttractScene:is_finished()
|
||||
return self.attract_camera:is_finished()
|
||||
end
|
||||
|
||||
function AttractScene:close()
|
||||
self.attract_camera:close()
|
||||
end
|
||||
@@ -1,4 +1,3 @@
|
||||
-- Ported 1:1 from src/objects/title/bana_advert.cpp (pure visual, no input).
|
||||
BanaAdvertisement = {}
|
||||
BanaAdvertisement.__index = BanaAdvertisement
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
CameraCloud = {}
|
||||
CameraCloud.__index = CameraCloud
|
||||
|
||||
function CameraCloud.new()
|
||||
local self = setmetatable({}, CameraCloud)
|
||||
|
||||
self.fade_in = tex.get_animation(32, "title")
|
||||
self.fade_in:start()
|
||||
self.text_fade = tex.get_animation(33, "title")
|
||||
self.text_fade:start()
|
||||
self.move_up = tex.get_animation(34, "title")
|
||||
self.move_up:start()
|
||||
self.breathing = tex.get_animation(35, "title")
|
||||
self.breathing:start()
|
||||
|
||||
self.t_cloud = tex.get_texture("title/camera/camera_cloud")
|
||||
self.t_cloud_text_1 = tex.get_texture("title/camera/camera_cloud_text_1")
|
||||
self.t_cloud_text_2 = tex.get_texture("title/camera/camera_cloud_text_2")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function CameraCloud:update(current_ms)
|
||||
self.fade_in:update(current_ms)
|
||||
self.text_fade:update(current_ms)
|
||||
self.move_up:update(current_ms)
|
||||
self.breathing:update(current_ms)
|
||||
end
|
||||
|
||||
function CameraCloud:draw()
|
||||
tex.draw_texture(self.t_cloud, {
|
||||
scale = self.breathing.attribute, center = true, y = self.move_up.attribute, fade = self.fade_in.attribute,
|
||||
})
|
||||
tex.draw_texture(self.t_cloud_text_1, {
|
||||
scale = self.breathing.attribute, center = true, y = self.move_up.attribute,
|
||||
fade = math.min(self.fade_in.attribute, 1 - self.text_fade.attribute),
|
||||
})
|
||||
tex.draw_texture(self.t_cloud_text_2, {
|
||||
scale = self.breathing.attribute, center = true, y = self.move_up.attribute,
|
||||
fade = math.min(self.fade_in.attribute, self.text_fade.attribute),
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,218 @@
|
||||
local WarningX = {}
|
||||
WarningX.__index = WarningX
|
||||
|
||||
function WarningX.new()
|
||||
local self = setmetatable({}, WarningX)
|
||||
self.resize = tex.get_animation(0, "title")
|
||||
self.resize:start()
|
||||
self.fade_in = tex.get_animation(1, "title")
|
||||
self.fade_in:start()
|
||||
self.fade_in_2 = tex.get_animation(2, "title")
|
||||
self.fade_in_2:start()
|
||||
self.sound_played = false
|
||||
|
||||
self.t_x_lightred = tex.get_texture("title/warning/x_lightred")
|
||||
self.t_x_red = tex.get_texture("title/warning/x_red")
|
||||
return self
|
||||
end
|
||||
|
||||
function WarningX:update(current_ms)
|
||||
self.resize:update(current_ms)
|
||||
self.fade_in:update(current_ms)
|
||||
self.fade_in_2:update(current_ms)
|
||||
|
||||
if self.resize.attribute > 1 and not self.sound_played then
|
||||
audio.play_sound("error", "attract_mode")
|
||||
self.sound_played = true
|
||||
end
|
||||
end
|
||||
|
||||
function WarningX:draw_bg()
|
||||
tex.draw_texture(self.t_x_lightred, { fade = self.fade_in_2.attribute })
|
||||
end
|
||||
|
||||
function WarningX:draw_fg()
|
||||
tex.draw_texture(self.t_x_red, { scale = self.resize.attribute, center = true, fade = self.fade_in.attribute })
|
||||
end
|
||||
|
||||
function WarningX:is_finished()
|
||||
return self.resize.is_finished and self.fade_in.is_finished and self.fade_in_2.is_finished
|
||||
end
|
||||
|
||||
local WarningBachiHit = {}
|
||||
WarningBachiHit.__index = WarningBachiHit
|
||||
|
||||
function WarningBachiHit.new()
|
||||
local self = setmetatable({}, WarningBachiHit)
|
||||
self.resize = tex.get_animation(3, "title")
|
||||
self.fade_in = tex.get_animation(4, "title")
|
||||
self.sound_played = false
|
||||
|
||||
self.t_bachi_hit = tex.get_texture("title/warning/bachi_hit")
|
||||
self.t_bachi = tex.get_texture("title/warning/bachi")
|
||||
return self
|
||||
end
|
||||
|
||||
function WarningBachiHit:update(current_ms)
|
||||
if not self.sound_played then
|
||||
audio.play_sound("bachi_hit", "attract_mode")
|
||||
self.sound_played = true
|
||||
self.fade_in:start()
|
||||
self.resize:start()
|
||||
end
|
||||
self.resize:update(current_ms)
|
||||
self.fade_in:update(current_ms)
|
||||
end
|
||||
|
||||
function WarningBachiHit:draw()
|
||||
tex.draw_texture(self.t_bachi_hit, { scale = self.resize.attribute, center = true, fade = self.fade_in.attribute })
|
||||
if self.resize.attribute > 0 and self.sound_played then
|
||||
tex.draw_texture(self.t_bachi)
|
||||
end
|
||||
end
|
||||
|
||||
function WarningBachiHit:is_finished()
|
||||
return self.fade_in.is_finished and self.sound_played and self.resize.is_finished
|
||||
end
|
||||
|
||||
local WarningCharacters = {}
|
||||
WarningCharacters.__index = WarningCharacters
|
||||
|
||||
function WarningCharacters.new()
|
||||
local self = setmetatable({}, WarningCharacters)
|
||||
self.shadow_fade = tex.get_animation(5, "title")
|
||||
self.chara_0_frame = tex.get_animation(7, "title")
|
||||
self.chara_1_frame = tex.get_animation(6, "title")
|
||||
self.chara_0_frame:start()
|
||||
self.chara_1_frame:start()
|
||||
self.saved_frame = 0
|
||||
|
||||
self.t_chara_0_shadow = tex.get_texture("title/warning/chara_0_shadow")
|
||||
self.t_chara_0 = tex.get_texture("title/warning/chara_0")
|
||||
self.t_chara_1_shadow = tex.get_texture("title/warning/chara_1_shadow")
|
||||
self.t_chara_1 = tex.get_texture("title/warning/chara_1")
|
||||
return self
|
||||
end
|
||||
|
||||
function WarningCharacters:update(current_ms)
|
||||
self.shadow_fade:update(current_ms)
|
||||
self.chara_1_frame:update(current_ms)
|
||||
self.chara_0_frame:update(current_ms)
|
||||
|
||||
if self.chara_1_frame.attribute ~= self.saved_frame then
|
||||
self.saved_frame = math.floor(self.chara_1_frame.attribute)
|
||||
if not self.shadow_fade.is_started then
|
||||
self.shadow_fade:start()
|
||||
else
|
||||
self.shadow_fade:restart()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function WarningCharacters:draw(fade, fade_2, y_pos)
|
||||
tex.draw_texture(self.t_chara_0_shadow, { y = y_pos, fade = fade_2 })
|
||||
tex.draw_texture(self.t_chara_0, { frame = math.floor(self.chara_0_frame.attribute), y = y_pos, fade = fade })
|
||||
|
||||
tex.draw_texture(self.t_chara_1_shadow, { y = y_pos, fade = fade_2 })
|
||||
if -1 < self.chara_1_frame.attribute - 1 and self.chara_1_frame.attribute - 1 < 7 then
|
||||
tex.draw_texture(self.t_chara_1, {
|
||||
frame = math.floor(self.chara_1_frame.attribute) - 1, y = y_pos, fade = self.shadow_fade.attribute,
|
||||
})
|
||||
end
|
||||
tex.draw_texture(self.t_chara_1, { frame = math.floor(self.chara_1_frame.attribute), y = y_pos, fade = fade })
|
||||
end
|
||||
|
||||
function WarningCharacters:is_finished()
|
||||
return self.chara_1_frame.is_finished
|
||||
end
|
||||
|
||||
local Board = {}
|
||||
Board.__index = Board
|
||||
|
||||
function Board.new()
|
||||
local self = setmetatable({}, Board)
|
||||
self.move_down = tex.get_animation(10, "title")
|
||||
self.move_down:start()
|
||||
self.move_up = tex.get_animation(11, "title")
|
||||
self.move_up:start()
|
||||
self.move_center = tex.get_animation(12, "title")
|
||||
self.move_center:start()
|
||||
self.y_pos = 0
|
||||
|
||||
self.t_warning_box = tex.get_texture("title/warning/warning_box")
|
||||
return self
|
||||
end
|
||||
|
||||
function Board:update(current_ms)
|
||||
self.move_down:update(current_ms)
|
||||
self.move_up:update(current_ms)
|
||||
self.move_center:update(current_ms)
|
||||
if self.move_up.is_finished then
|
||||
self.y_pos = self.move_center.attribute
|
||||
elseif self.move_down.is_finished then
|
||||
self.y_pos = self.move_up.attribute
|
||||
else
|
||||
self.y_pos = self.move_down.attribute
|
||||
end
|
||||
end
|
||||
|
||||
function Board:draw()
|
||||
tex.draw_texture(self.t_warning_box, { y = self.y_pos })
|
||||
end
|
||||
|
||||
WarningScreen = {}
|
||||
WarningScreen.__index = WarningScreen
|
||||
|
||||
function WarningScreen.new(current_ms)
|
||||
local self = setmetatable({}, WarningScreen)
|
||||
self.start_ms = current_ms
|
||||
|
||||
self.fade_in = tex.get_animation(8, "title")
|
||||
self.fade_out = tex.get_animation(9, "title")
|
||||
self.fade_in:start()
|
||||
|
||||
self.board = Board.new()
|
||||
self.warning_x = WarningX.new()
|
||||
self.warning_bachi_hit = WarningBachiHit.new()
|
||||
self.characters = WarningCharacters.new()
|
||||
|
||||
self.t_warning_background = tex.get_texture("title/warning/background")
|
||||
self.t_movie_background = tex.get_texture("title/movie/background")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function WarningScreen:update(current_ms)
|
||||
self.board:update(current_ms)
|
||||
self.fade_in:update(current_ms)
|
||||
self.fade_out:update(current_ms)
|
||||
local delay = 533.33
|
||||
local elapsed_time = current_ms - self.start_ms
|
||||
self.warning_x:update(current_ms)
|
||||
self.characters:update(current_ms)
|
||||
|
||||
if self.characters:is_finished() then
|
||||
self.warning_bachi_hit:update(current_ms)
|
||||
else
|
||||
self.fade_out:start()
|
||||
if delay <= elapsed_time and not audio.is_sound_playing("bachi_swipe") then
|
||||
audio.play_sound("warning_voiceover", "attract_mode")
|
||||
audio.play_sound("bachi_swipe", "attract_mode")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function WarningScreen:is_finished()
|
||||
return self.fade_out.is_finished
|
||||
end
|
||||
|
||||
function WarningScreen:draw()
|
||||
tex.draw_texture(self.t_warning_background)
|
||||
self.board:draw()
|
||||
self.warning_x:draw_bg()
|
||||
self.characters:draw(self.fade_in.attribute, math.min(self.fade_in.attribute, 0.75), self.board.y_pos)
|
||||
self.warning_x:draw_fg()
|
||||
self.warning_bachi_hit:draw()
|
||||
|
||||
tex.draw_texture(self.t_movie_background, { fade = self.fade_out.attribute })
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+50
-31
@@ -7183,7 +7183,7 @@ ec22711f72132b837a6522269a014cc713c7c935e998875fb22360a189a2967b *./Graphics/gam
|
||||
06fe1e3fa447d26ec0048e6ae6b5ec8b48612e0ca8ae52f0358189c21e4f1af8 *./Graphics/game/ai_battle/section_text.png
|
||||
d559d1c557b1eb6c5060833d7ffc575a430e2870542b6e5f886e3004440b8ef0 *./Graphics/game/ai_battle/section_win.png
|
||||
e3e9b341cefc71c014ed1e3516a24810e514329ebe6f1525d70967f09eccf946 *./Graphics/game/ai_battle/texture.json
|
||||
83421b95cdb48489c75189c1dc9bc94c40cc4b9ab3a1d885e859fe674d7ac439 *./Graphics/game/animation.json
|
||||
b85dea08ad9363e76bf0caa2df33ae87ec706b36565bb2732e9cb6d86cb82e7f *./Graphics/game/animation.json
|
||||
73bf74fada6ff0e5dc6637b185f5c5d32afd60b8944f43d540d00c80000a944c *./Graphics/game/balloon/bubble.png
|
||||
2b14b07611a63758d2e6082ea56e7eb16472db7372afb52aa54eeb28f93c7690 *./Graphics/game/balloon/counter.png
|
||||
ec3282ce743cdf67b5687dfd500e79107fff450878549f223a68522a33a38c76 *./Graphics/game/balloon/explosion.png
|
||||
@@ -7379,6 +7379,7 @@ db99e39129f2e44f565fca9c218aff2f824ae9b7044d5315bc538654b07943e7 *./Graphics/gam
|
||||
67815c99eed1c22b5befe318ca399a4a2cd449d0ff149b536db29e208b279591 *./Graphics/game/gogo_time/fire.png
|
||||
c314c3c7413611465757586b739fc6c10745807cd9eabec2658545c2146b8b34 *./Graphics/game/gogo_time/texture.json
|
||||
bbd5a5061a53d18f6a8644b5b20ca12dc6fb8bd7d8ec0ed0fe3d3bb13045d761 *./Graphics/game/hit_effect/explosion.png
|
||||
6ea89c726cc649ea9d73f1d5967df3e7ba5aea185b11ba1875b0963c181eec80 *./Graphics/game/hit_effect/firework.png
|
||||
f6bedd2f88bf307fc74dd5bd07a81138cfc0a1a2c4f518156450532b973cd0df *./Graphics/game/hit_effect/hit_effect_good_big.png
|
||||
f629e3fc5b85a3e0efbd715e757e2424f09242ddf287eafe8ae4ab9ea276b14d *./Graphics/game/hit_effect/hit_effect_good.png
|
||||
c43c31d9863b46ecd90b8afbc50af9a21e00ee60286d338e8fef012413c60efe *./Graphics/game/hit_effect/hit_effect_ok_big.png
|
||||
@@ -7392,7 +7393,7 @@ de425fbaa86f180075798976c0c13e1409499058b29d5107b7a0c27ad3180d90 *./Graphics/gam
|
||||
ff6b64321a92f4fc79d6e315d0913a4f9e9684f673d09d954f6acd7cb0ccb56a *./Graphics/game/hit_effect/outer_good.png
|
||||
e74d70db802bcf58f47e1605a0429031e79812fc8a909382c19fb82ff682e29a *./Graphics/game/hit_effect/outer_ok_big.png
|
||||
430407a54fb50bb51873401731f4fe29ed5b680a0a80d3bf7aa4cdda1e87e40c *./Graphics/game/hit_effect/outer_ok.png
|
||||
f5a0e9e5260288b4810e2f5c9e87bc8ad4aa22e6cf36cd41a8135d04619bc143 *./Graphics/game/hit_effect/texture.json
|
||||
d92f635e690cef7ff7dd17eca98a0675af50f3340e3ec88c0c15ca5bb54b2235 *./Graphics/game/hit_effect/texture.json
|
||||
1f5298d88bdc570c3acc0f069fc7c0426144f1ef3fbb352afd96962e77f6ddf0 *./Graphics/game/judge_counter/bg.png
|
||||
c96c90add5c561470fe26a52ab6b439e09ec3cd61bb390fdc19e0bce8c787122 *./Graphics/game/judge_counter/counter.png
|
||||
51de40cea517e72dbc2cbdd4949c04bc9bc086198374b94589843a5ffd476b26 *./Graphics/game/judge_counter/drumrolls.png
|
||||
@@ -7713,8 +7714,8 @@ b47abc211bb29186bfb7303f8495f3a48b6e65b60dd10d92a7ae9625b372734c *./Graphics/set
|
||||
04622b407745197ace032eeaf81b66a7fef7daeee0e46693b5c55f7d22ad1425 *./Graphics/settings/option/button_off.png
|
||||
67474d69d95b8f3bec5e42c8b93e6d6ff5569abb13c6a32235c265c135c6e9d7 *./Graphics/settings/option/button_on.png
|
||||
82c2a2804f77b2e12c4dd0a46f7ac669e60b1ad92225432729bcc0a321387e79 *./Graphics/settings/option/texture.json
|
||||
7d7a166df0fbd966d4e2f2ff9b1eb427ac6ce4f23b0b8383aab78db11f771cac *./Graphics/settings_template.json
|
||||
4627a2fbde5152765248ec18947c79e0e2afa63891e68acbad36141856454bf5 *./Graphics/skin_config.json
|
||||
4cc4e7e785417812939bfcf710d4d883c0b264fb11cfce6fb0a71f95623ac9f0 *./Graphics/settings_template.json
|
||||
de3c661eddf8d1e992f23c3a7def29e759b600a1076bf897bea82a5a3efaf8f2 *./Graphics/skin_config.json
|
||||
179393f86dc603a103e240879b952c363f2f06d48fba7b320f6215b645bea110 *./Graphics/song_select/ai_battle/1p.png
|
||||
c7bae3649859b1033d9b1a56a04c1c5c3f39b172b8660374a94d40f257de7790 *./Graphics/song_select/ai_battle/2p.png
|
||||
f26377ce7459cb2a76d56d051be50c0b41f2ee13a1a5b87200fb53de60a7b264 *./Graphics/song_select/ai_battle/background_overlay_2.png
|
||||
@@ -7847,7 +7848,7 @@ ea2a69c8d0adec73c74aa38d3b413cbd2b7f7719eb348adf50965cedfbc121c3 *./Graphics/son
|
||||
03e4e191fdd811fc582bc4f0bd9aeb750e87c3250953b8ca7d7231ec5ce7c3bf *./Graphics/song_select/box/folder_top_edge/5.png
|
||||
5b41ddf36b11bbea7cc6020242509509492969a21c23e51825258a25b1333c0b *./Graphics/song_select/box/genre_overlay_large.png
|
||||
80c269126421c31972cd9bdec7018dfb5a4ef5217ea63d8d62702093f5d8faac *./Graphics/song_select/box/genre_overlay.png
|
||||
187cef20577d6f879e9164ee4c473803035a0ec5b9df9f1fdfc438204da34dfe *./Graphics/song_select/box/texture.json
|
||||
b4aef881789c1e3ca0b59ec707268fd64cd0d7b3420a392a99d90894eb24304b *./Graphics/song_select/box/texture.json
|
||||
db40896e4c182e849aa2e8ab32d3908bc065d07c04aeb40ed74ee90b718505f1 *./Graphics/song_select/dan_transition/background.png
|
||||
a2af149c9018d929f95322661cace991a284b33a24451db1ae915e80a0aaf8a2 *./Graphics/song_select/dan_transition/texture.json
|
||||
97cd5cd60ab1685243fb8c5ce4507eaa02dd49f83a2238a7bdf87f4711a1fd9d *./Graphics/song_select/diff_select/1p2p_outline.png
|
||||
@@ -7885,7 +7886,7 @@ b3db527d5615f79e6ce392b41da8f39d7b253826fe3cb4d92868e9711bd205a6 *./Graphics/son
|
||||
8448bf0f9e0e97165fe62689fae021da5aeb444a1ab29b839c5702495c85be02 *./Graphics/song_select/diff_select/neiro_ja.png
|
||||
aaef148da3ec49db52d6608b44fa6f1a339f20068f2eb0fba8448aaa6cf29f60 *./Graphics/song_select/diff_select/option_en.png
|
||||
3951843f5e2a686b63e42376e23b08a2d34a6a943e5bc0dac3491fb267faa9de *./Graphics/song_select/diff_select/option_ja.png
|
||||
fa364540fc4c2b04fc033ce894b71eb897054791b52802e43f4f0876f0e18e14 *./Graphics/song_select/diff_select/texture.json
|
||||
57ceaa0012c4e23d27feee077e91d18aa5b89bf69c5b02d1c15dad656bc97161 *./Graphics/song_select/diff_select/texture.json
|
||||
de18b6cda60689780194bb7cf3352fc3e580a7569d6634b35f3bb6de3ec78f74 *./Graphics/song_select/diff_select/ura_oni_plate.png
|
||||
b5fac3ff36f4e782c6a332fdf6c68fa573c15ed5ee311903ce3734c835168cdf *./Graphics/song_select/diff_select/ura_switch/0.png
|
||||
da76351a327504b87c3b41489fa91d8fc4cfd573b72ca27d59e8b3eeb6e5ca36 *./Graphics/song_select/diff_select/ura_switch/1.png
|
||||
@@ -8090,7 +8091,7 @@ b105727879d67808c29432ed76804be6671474c0475ff3efa0b49e28af5eb3a5 *./Graphics/son
|
||||
2defaf1f501f723418a820c053ee7e835443630589f89e41b95f1a23ff1aba3e *./Graphics/song_select/yellow_box/song_count_back.png
|
||||
2fae896b776d2fc4bb803da39a782b3d3baac6036ab40502f2bb0ce568183037 *./Graphics/song_select/yellow_box/star.png
|
||||
85ba22108eb709e13b3478bd716a81746bdd5a51068fc2ce005b796860661aeb *./Graphics/song_select/yellow_box/star_ura.png
|
||||
5b59a818436479699a1c6506df33477506fdaa57c7ef373d4c74428f01246b12 *./Graphics/song_select/yellow_box/texture.json
|
||||
7e1de82961268ad64aa78df4e89e8577cfc69ddab92f7eaf525f8ff1a5d30e53 *./Graphics/song_select/yellow_box/texture.json
|
||||
0bcfb5d2ecf7b6d90401b3800231e8ff813c5a8706082b1703a9551962128c29 *./Graphics/song_select/yellow_box/yellow_box_bottom_left.png
|
||||
49fd2d19d41ab1634ece2f95260acd5bc28ed39fe50e5841d93609321c365c2c *./Graphics/song_select/yellow_box/yellow_box_bottom.png
|
||||
6f4d392bfa2fd02557a6d98d2f7e4633ce62222b1589b0018351e15fa830ee68 *./Graphics/song_select/yellow_box/yellow_box_bottom_right.png
|
||||
@@ -9397,13 +9398,13 @@ f59099edce8feeaac2f45064d02730cd8450d83722389c3becc0ca91bea27041 *./Models/paint
|
||||
4ef33adf5d02ff2d9890794b55239a52357250b533ed8a69e8d3f09275080693 *./Models/paint/paint_055000.png
|
||||
0a82b9087600457ee8aa507ebcb3048c70effa95a83d63cac4eccc30c75efc6b *./Models/paint/paint_056000.png
|
||||
57ab9d3072d32051eef5483db883362518c7cf402799c63d0bc792a52429c1a8 *./Models/paint/paint_057000.png
|
||||
e3d8a05b9a6ddf886caf99adbf24296c1d712b9ab68c209cdc10ab7b69ff91b7 *./Scripts/background/background.lua
|
||||
9c1e1e38b5f4936c6a6c46f76931f5cda86029cbccc84619144b4980dea02814 *./Scripts/background/bg_collabs/a3.lua
|
||||
e1b70b28b4233377c9e077d83964fe50423d4afac8b90961242fd4924a7650ba *./Scripts/background/background.lua
|
||||
b97f4ede34f9e042912df23a38c3231c2d15cc615f53071fb0e5ccc21e60fb1d *./Scripts/background/bg_collabs/a3.lua
|
||||
7a7c675f7b906396dc7f743bad887a0f4fa617f37faa2887a762fecb017375ab *./Scripts/background/bg_collabs/animal.lua
|
||||
dab3a2f285242d8e77296697650fc6a0822fd1f2a43f5db29653cc7a569accd6 *./Scripts/background/bg_collabs/buttoburst.lua
|
||||
799740087cc746f90f4a889a72503806f3d8dc3277445b3fdcdbde1b16a2c3b9 *./Scripts/background/bg_collabs/dan.lua
|
||||
4aa90019064f93e5073569b4bebb25fcff611aa60f983fbe518b054041fdd8a1 *./Scripts/background/bg_collabs/dan.lua
|
||||
b6036a69641a0e2feaa7d530e2a20664accfe407aa471d70bf6b62a8706f6b6d *./Scripts/background/bg_collabs/dq10.lua
|
||||
8efe92bc22d236714560d41cf672141c4b3597b1afbebae1ceb89b9c5a0db79e *./Scripts/background/bg_collabs/funassyi.lua
|
||||
4bcaea3a618e9e2961e94819d7997fe05451b3e1b56d43e3b9b7461e7c9b34b2 *./Scripts/background/bg_collabs/funassyi.lua
|
||||
480a18fdfa78f0e34fc479a232fa684993bdad883d61e9b4a97ccd104c587cf5 *./Scripts/background/bg_collabs/gb.lua
|
||||
b3722520f22d01bc605c85fa129d1c20ea58f0459a82a46dcbe47455d4e87cbf *./Scripts/background/bg_collabs/gmt.lua
|
||||
32c145cec643cab6b13aa5bbb701b897894c5a44b84c670de38af7a8eba7daa3 *./Scripts/background/bg_collabs/gumi.lua
|
||||
@@ -9428,15 +9429,15 @@ e63a9e706e8644968b689e9685fcc772415ebd00133e39f5887f6f76817630ed *./Scripts/back
|
||||
79845f0df65c8d27b1c44a102cabf0c12d8d66c90f9666dbf0e1640d6563b26d *./Scripts/background/bg_collabs/toho.lua
|
||||
9f6e0f0d2e16738d224fc4b15c666bef970a084865da93a89f1f9ab37700beab *./Scripts/background/bg_collabs/tonkatsudj.lua
|
||||
c2b495c1a24d5ad132a8fa53f6634b570fae5f08410fa30a39aa8e9875f2e6d4 *./Scripts/background/bg_collabs/touken.lua
|
||||
d5e200b0506bec44b6e8e0ed1319076a8a653fcea35617fb1368bdf835ad3f42 *./Scripts/background/bg_collabs/tutorial.lua
|
||||
afd2a748135b6a9666dfbb3595d055747919e4ed78c64ef5e0013b090c0975eb *./Scripts/background/bg_collabs/tutorial.lua
|
||||
33fc6edae8530cf54a5ce5d41032e8836ebe216bb21f68e6655140dd3731193a *./Scripts/background/bg_collabs/ymck.lua
|
||||
00328555c6ef8ee293497af40ae00b1a6236cc80c53199e12b297fb1d0ac791a *./Scripts/background/bg_collabs/yokai_hatsukoi.lua
|
||||
8b4b45900cd72e1a216dc48fb0a5551e2a82a44611c306747478c07d27a6e74c *./Scripts/background/bg_collabs/yokai.lua
|
||||
3c9360694b8d579ee8ace8088113948866340d11b8c8ac8df521d1d7a3d504ee *./Scripts/background/bg_collabs/yokai_matsuri.lua
|
||||
c146e82e7315f2962d33c0457c87aa65ca97e5ac9c0569684bb2f69efb8dcb24 *./Scripts/background/bg_collabs/yokai_tokoroten.lua
|
||||
13876795d050284dc656b016a786419108d6cca44e3df67e7ec39910ff389f85 *./Scripts/background/bg_collabs/yokai_yougota.lua
|
||||
10acae2c2553289faccd6454137a98ce6e1627d4a2b8edd64c6959ae4fa21dcd *./Scripts/background/bg_objects/bg_fever.lua
|
||||
b56662a706ccd159b2e7d66383114c41ed0d233612729eff6297e546cda8191b *./Scripts/background/bg_objects/bg_normal.lua
|
||||
0e29a01e037fe9e3ce501a971088fcd8094dbe646d4999cf0f7140b98b79b056 *./Scripts/background/bg_objects/bg_fever.lua
|
||||
c54aa6cc8f39569990571f760060a56038d38bfc14b7559ff59d8ac13a0f4a40 *./Scripts/background/bg_objects/bg_normal.lua
|
||||
29d4674757cd0d6e94dc05cc31b5409471a9d123272b537807a21eade1be4bf3 *./Scripts/background/bg_objects/chibi/0.lua
|
||||
d75c5ff40da942078abf7287c5bc39c2cf048fc01be5727d1d6a334572a42c91 *./Scripts/background/bg_objects/chibi/13.lua
|
||||
3ef303e55bb9ef39cec84dee91ec19186c6f77468b1f382a2dc789f7b84284b1 *./Scripts/background/bg_objects/chibi/2.lua
|
||||
@@ -9447,39 +9448,56 @@ ed026aa86fa6a89190bf5d40c2e2262cec192c8a2bd7b11c11d3013bf9ed24ff *./Scripts/back
|
||||
aa5fd5410a8c09337164d5fe462943199ef069558a9696ea34ce6b7c5b0397bb *./Scripts/background/bg_objects/chibi/base.lua
|
||||
b5e6feee78ae5550fb95769f73b4f5daf2d438795fa1c5799195a5b01489ea97 *./Scripts/background/bg_objects/chibi.lua
|
||||
e17386ec247b369ccf6012a82b0204b5942f09022a3d25c4e9294f2fde014d20 *./Scripts/background/bg_objects/dancer.lua
|
||||
c26b717e4eab21cd6c9ef8130f455c386cd4292dd9ad64dc6f5ce3bcbd2472a0 *./Scripts/background/bg_objects/donbg/1.lua
|
||||
545799c5826be896d4f557efe38d5ec824664422b17256004e06e44b71e8d8fd *./Scripts/background/bg_objects/donbg/2.lua
|
||||
5c40f347670f86e18973905baa25b88a7313ceb0ae826abe33f732fe0c14c343 *./Scripts/background/bg_objects/donbg/3.lua
|
||||
ff39cbf53938208c5b938292eca7c617424ce42078cd5d5dd5118c05d3ef784e *./Scripts/background/bg_objects/donbg/4.lua
|
||||
9bb9af0d12c5fee21fde44c3ad1dec7873d0ad0c73e22db8154b0e1e7bc4809d *./Scripts/background/bg_objects/donbg/5.lua
|
||||
2ed31ade85ee6fae6f4d14d8b3861b780f5dbc8640fed872254782742006f6e5 *./Scripts/background/bg_objects/donbg/6.lua
|
||||
e1f1fb711a02282ead83f22f80abe669e40a3cd3da3204311ea5183bde932843 *./Scripts/background/bg_objects/donbg/base.lua
|
||||
13c128386df378b19c68b06b66618ad2672d6755be2545ea56e46bbfb228db85 *./Scripts/background/bg_objects/donbg/1.lua
|
||||
174623720acc4cfea845936bfe65431545a4d4c19911dacb0b7b5b7a71fd3305 *./Scripts/background/bg_objects/donbg/2.lua
|
||||
3ad8d298f3abf8b7767d73e28ade6df71984d9edaa894539c7d708e3ee01ff16 *./Scripts/background/bg_objects/donbg/3.lua
|
||||
84cdb3d84bb825f2eb51533013aef62677547c745994e5bd17f3dfdb0ad08c6e *./Scripts/background/bg_objects/donbg/4.lua
|
||||
d192fb5918ab1f36fdf1c894e658cabcf0da9182713bba364321cd2c7e2b7b55 *./Scripts/background/bg_objects/donbg/5.lua
|
||||
5d311aa24fd2e265ff497893c35d7e73be2d959a62a728952c3c822870680c36 *./Scripts/background/bg_objects/donbg/6.lua
|
||||
2ef847c7cad3b82bbd2bc5ba0b86bfaff63a46fa760f1c52719808eed16cd3bb *./Scripts/background/bg_objects/donbg/base.lua
|
||||
63bd3b3d984c5c970fbe1a3b45aadb0eee6e1409a790889a3585b7e8fda44f4a *./Scripts/background/bg_objects/donbg.lua
|
||||
bd01b4301d3c9326f4c6326ec127f08106d9061f816f14d7b410a9e0ef76cf91 *./Scripts/background/bg_objects/fever.lua
|
||||
78f73786c14818861403bb9a0ecc158ecded5f03fc47bc859ed88b4ede5b01eb *./Scripts/background/bg_objects/footer.lua
|
||||
3a4ee9f50497a8140a5371da69158f86909dd291df2cd80229c9eb4d658cd597 *./Scripts/background/bg_objects/renda.lua
|
||||
43c5a3e745d0677f350be1150942f1f01b296bd84cf209cda92d1d0b828c8afb *./Scripts/dan_select/dan_select.lua
|
||||
72b69fdfa1ea00202b7ef8f1b65220a73c3ea5e74116054acec6e61ce0ba7256 *./Scripts/entry/box.lua
|
||||
a6c89e3b8c5654487c345dcc95a226ee3f7a2951329a88227c4e50374ff93ed2 *./Scripts/entry/costume_menu.lua
|
||||
ba92fb9f70cbc1bcb12d9382ce2edc3e06e1c1e526a5069098b401b233e7fabe *./Scripts/entry/entry.lua
|
||||
a126611332f4ea9b1638aec79dbe8a284ce1b89410d988216a7fe4c0f58b5a87 *./Scripts/entry/entry.lua
|
||||
869ba2c149387ff5f44c505cfe261453abe4112017c7ca586fd4dc4233752213 *./Scripts/entry/player.lua
|
||||
460bd5339860be5abbf9b1f1db2f36a4a4be77de73c4f933a2fb1be5386250bb *./Scripts/game/clear_animation.lua
|
||||
a2004e6df3bc3105fc2401662c38ed94cf5f45b05a20175f227d3e19f80b653f *./Scripts/game/combo_announce.lua
|
||||
5cb0047469951863e3e2fee62ffde3afc62e91974add5764c7783deb2d35d721 *./Scripts/game/fail_animation.lua
|
||||
2caf735860515a66f3c1305ebe40df2f22fe2ff9837d4f385ad0f480040b34cf *./Scripts/game/fc_animation.lua
|
||||
66ad0c99972d48e4b613951bd3532cb59b12f164c7562ff52a01d8b26d882f10 *./Scripts/game_over/game_over.lua
|
||||
5c643bc0c522ca69e9611696c78117c6bf8c96b2e3767bb56ecc459e8e7d4e09 *./Scripts/global/allnet_indicator.lua
|
||||
381cfe3e402d076f4cbbc89b7763a034bc5086e486058e1339adc6199f029cd3 *./Scripts/global/coin_overlay.lua
|
||||
38b2e25f67245044589d3dec14abadc6b115b6be87490c2fbc075a8cedafd00f *./Scripts/global/entry_overlay.lua
|
||||
1e5760785aff98db26e649b5493cd0ee8ddf8a46b2c59afcbf5da39d49bfd703 *./Scripts/global/indicator.lua
|
||||
977e8a64929eb9557c409e8230dfbaeb3d032b9b64a8d25bbb3cd5655c0d2994 *./Scripts/global/nameplate.lua
|
||||
0fd986d17090c7e1d3c4d7a949a606d8780f52ff6c5c90746f1fccc2f7462635 *./Scripts/global/result_transition.lua
|
||||
d0d202a05d7e94f900b49b1cd50b56c5d55426439cb746689b87d645660076bc *./Scripts/global/timer.lua
|
||||
12afbce120fa933331efd27d5eb2b2c87367ef5b3d761930ec7ab154e12343ba *./Scripts/result/bottom_characters.lua
|
||||
9c44dbc951eaf076824422733562f77c97b9c4cd01788663094f344ff297fa49 *./Scripts/global/transition.lua
|
||||
cba4e6940f37bb2fdd124acb9242e3147397660471a62d547d0a30ad06598a0c *./Scripts/result/bottom_characters.lua
|
||||
7fe28b74da62b99d430ae9045f10abd0804652a1940f4a0de24d34b96a228b84 *./Scripts/result/dan_result_draw.lua
|
||||
6ebddd307fddb708bf592aec3383fa8944c39d14af640eb51ff6ffaac10e2bd6 *./Scripts/result/high_score_indicator.lua
|
||||
8f176d535096b666910500b390c69073c22e8745a49e040cad89cdccf3f5d3ba *./Scripts/result/high_score_indicator.lua
|
||||
f91f76d652457ad3987d00729f3af415b0270d0cd765234bfd7531c145befa59 *./Scripts/result/result_background.lua
|
||||
c8a4a8b57ad3f4c2b9018ce493f63ecdfae2f318af7fcef37aaa513c94a10c96 *./Scripts/result/result_crown.lua
|
||||
28de4bd17f383b117ce3cf0e570a7fbb4c0f0a8c9843c13c908c27653e6bf784 *./Scripts/result/result_crown_message.lua
|
||||
0ae5263aa53b9454d843c49c495fc956e11afd2f1a5cdaa34bf1c082f82f23fd *./Scripts/result/result_fade_in.lua
|
||||
5f80977b72d37ad7cc5f03cf29e3684fe8f8aaa2cb24417ee8d26f77cbaf99b2 *./Scripts/result/result_player.lua
|
||||
4451d2d3d0b11d4296bbd410f3147072bebcfb0f06a51a59362b901896898cd6 *./Scripts/song_select/song_select.lua
|
||||
6b1cd4fa907aaa87fd734c980dc11210069619dd9baaa81e487265f5ed53ebb2 *./Scripts/title/bana_advert.lua
|
||||
f57648d9d50f9524c9d70601f4fe0a870d7397fafdf1dd9c6873644d3d4b6d0a *./Scripts/result/result_crown.lua
|
||||
078c8226626462c9409f40deb680208a79c67fc6f9c00ce2168fa54c4c622498 *./Scripts/result/result_crown_message.lua
|
||||
b230f98362a7ffb936b4cf877bb6f43da506fbe519db780a260ef0a669d5af31 *./Scripts/result/result_fade_in.lua
|
||||
45645c3ab0703b1a988c4b29657d83a0dc28c0b2148b755f120084f30f145187 *./Scripts/result/result_player.lua
|
||||
572b381758ea394312bab5f87d23dd1e2d839fedcc64452d4ba5991774d84540 *./Scripts/song_select/file_navigator/box_back.lua
|
||||
8de3941867d2ba1a45b2191eaafb82eb43f28aef6253d00954367df95e01f1f7 *./Scripts/song_select/file_navigator/box_base.lua
|
||||
935157086cee5116056ab0765293e4742377a2ddd18c84d3c7168a99f79c9a1c *./Scripts/song_select/file_navigator/box_folder.lua
|
||||
74967f50f67b75f8ed6fb491d324cf4e599503012e714f2a129892d092d3cdf0 *./Scripts/song_select/file_navigator/box_song.lua
|
||||
2888c36c94622669f5d29c3b15b852ea0e4c95562f983b2c9e8114f626e8bc2d *./Scripts/song_select/file_navigator/genre_bg.lua
|
||||
211a2d44aa1fd75ba51ddd21bacf65384cc08601c68ead7d431091c210950ba4 *./Scripts/song_select/score_history.lua
|
||||
602f624bca93141410ddfaa87cd6112cedca639d17432abecb558fc67fda9178 *./Scripts/song_select/song_select.lua
|
||||
a51f83e335365b7b0ef6cb09bf600af31ae5483f49fedc8e8426e9a18ef644a7 *./Scripts/song_select/ura_switch.lua
|
||||
dcf22728819b568733320c61091ad6a646a925dd2207769b760b56edc0d21092 *./Scripts/title/attract_camera.lua
|
||||
0ed0bce45846756c096ac787a8f590071b8c93416aee1f8cf0774a38f8006b52 *./Scripts/title/attract_scene.lua
|
||||
b0e1e379d68422efda99d6641585827ce92f91b07c1a4af0d6fed4db41512742 *./Scripts/title/bana_advert.lua
|
||||
78280c263d0ce372ec5e2e5c872ae978b894bf174896f4e8833b4e09f1cc85cb *./Scripts/title/camera_cloud.lua
|
||||
a4b7febf5d36106c41d957bfdb1e4f0f565782fb57c28e699b29960508578bd9 *./Scripts/title/warning_screen.lua
|
||||
990d75d13855e5bea9bce66f709c67e7f352cedbee6e2956e0cf7bc85ea563d1 *./.skin-repo
|
||||
9bfea0be2634c99786f3372e854b296ccb68693d1121bf70a8aa05b22406948e *./Sounds/dan_result/bgm.ogg
|
||||
537962311370ff5553118cb7e1ebbf098723e110100e6a531f03dc159e235616 *./Sounds/dan_result/num_up.ogg
|
||||
@@ -9792,12 +9810,13 @@ c7f9bf9959ec984ae34e4063acbb4cf3bb1622986cfff33eab9cb1cccd5e84b2 *./Videos/attra
|
||||
fb84815f727a5f39cc192a863455815319da8187b4d8b3af5c6e87270f7cf330 *./Videos/attract_videos/attract_cm_154.mp4
|
||||
2783d99ed2484dda532eec15ee4178bb2f4b821a73983d011ec9a6ca00bc12e4 *./Videos/attract_videos/attract_cm_155.mp4
|
||||
84dbaa9da9a4455023598976f0d040c3a5f37b378f11e80072c46917a2848e21 *./Videos/attract_videos/attract_cm_156.mp4
|
||||
87627559e70b07b65e681c60b2fa79d0351fef7684294828fa64a4a5fe33f820 *./Videos/attract_videos/attract_cm_157.mp4
|
||||
4e01deb35ecf00435482cc5b423adc702e12e5663b559983c4dc83317d09a118 *./Videos/attract_videos/attract_cm_158.mp4
|
||||
e9bd01e74725875474d0de1ffb2819923d8cd28e9b64fce68586e4f14ebc6d95 *./Videos/attract_videos/attract_cm_159.mp4
|
||||
bd0f8656e58c524265d98a0e08955984825416e72d42655e3934df11bf8c177d *./Videos/attract_videos/attract_cm_160.mp4
|
||||
a90f7bed9ec0a39627f9fd046ad465de9cd800138d0f373f592a60a1734ac1fe *./Videos/attract_videos/attract_cm_161.mp4
|
||||
1b5d8ff0af9b0d34657b04d1963d52066c5e6399034cbf7635df53dc7ce218a6 *./Videos/op_videos/2011_OP.mp4
|
||||
34871603e997026022f96a8ff71f3611638f34c32269cba53c57aacc39983608 *./Videos/op_videos/Blue_OP.mp4
|
||||
6ea1d57749ad98e93ca35b67370bf615353615d1961b5bfb4ad2fe89f1897910 *./Videos/op_videos/Green_OP.mp4
|
||||
c210215e5869c76c5ae620c61a1bad739a4dde30736b4850c9ca7c21ca08a29d *./Videos/op_videos/KATSU-DON_OP.mp4
|
||||
d25f7bd967c1f45286fb20a579119fe3e8dd7125d1bd18ba5731066fe2d96c17 *./Videos/op_videos/Kimidori_OP.mp4
|
||||
a9bcf14f216cfbab3cf2adf11f3bce3ffc885d11855b337e1ba225f3cc12fa33 *./Videos/op_videos/Momoiro_OP.mp4
|
||||
|
||||
Reference in new issue
Block a user