Compare commits

...
Author SHA1 Message Date
Yonokid 19d1fcc859 Merge branch 'main' into result-gauge-cells 2026-09-11 03:54:19 +02:00
Yonokid f5f35d6b8f Merge pull request 'Dan gauge: one 21 px cell per bar piece' (#26) from GanYiZhong/YataiDONNijiiro:dan-gauge-cells into main
Reviewed-on: Yonokid/YataiDONNijiiro#26
2026-09-11 03:54:08 +02:00
Yonokid bdfe482fe8 Merge branch 'main' into dan-gauge-cells 2026-09-11 03:53:58 +02:00
Yonokid ad52950374 Merge pull request 'Game HUD: song title on the cabinet line' (#25) from GanYiZhong/YataiDONNijiiro:result-rank-skip into main
Reviewed-on: Yonokid/YataiDONNijiiro#25
2026-09-11 03:53:51 +02:00
Yonokid 634896b4c1 Merge branch 'main' into result-rank-skip 2026-09-11 03:53:40 +02:00
TaikoZhongandClaude Fable 5.1 ed7f7224f7 Result: fill the soul gauge cell by cell on the cabinet's 50-cell grid
The result gauge stepped in 87 engine units of 8.4 px, so the fill crept
across the 50-cell / 21 px groove instead of lighting one cell at a time.
Convert the fill target to cells (points * 50 / max, floored like the game
HUD), step one cell per 7 frames (kGageSpeed_), place the norma at cell
30 / 35 / 40, and give the fill pieces the HUD's one-cell-wide art on the
groove's grid.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 09:37:40 +08:00
TaikoZhongandClaude Fable 5.1 f93a063a4a Dan gauge: one 21 px cell per bar piece, anchored on the cell grid
The dan gauge fill pieces were 12 px wide at x 726 while the border's cell
grid is 50 x 21 px from x 738; make the bar one cell wide at 738 so the
engine's per-cell stretch lands on the grid, and centre the 32 px gauge-up
glow on its cell (733).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 08:13:34 +08:00
TaikoZhongandClaude Fable 5.1 20838c114e Game HUD: song title on the cabinet's line
song_info y 58 -> 68: the cabinet's title field (y 0..98, 54 pt, border 6.5,
text vertically centred then inset by the border) puts the ink centre near
y 56; the engine anchors the text object's box, whose ink sits ~12 px above
its centre.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 08:13:26 +08:00
Yonokid e347c9d409 Update checksums.sha256 2026-09-10 14:35:16 -04:00
Yonokid 17ef685690 Merge branch 'GanYiZhong-entry-guide-title' 2026-09-10 13:39:38 -04:00
Yonokid 7c642d68ed Merge pull request 'Song select: the decided genre board stays up while its songs load' (#22) from GanYiZhong/YataiDONNijiiro:folder-open-leg into main
Reviewed-on: Yonokid/YataiDONNijiiro#22
2026-09-10 19:32:35 +02:00
Yonokid a0eedc6ae5 Merge branch 'main' into folder-open-leg 2026-09-10 19:32:18 +02:00
Yonokid bebc6fe22e Merge pull request 'Light effects: entry glow patch size, add-blended layers drawn additively' (#21) from GanYiZhong/YataiDONNijiiro:light-effects into main
Reviewed-on: Yonokid/YataiDONNijiiro#21
2026-09-10 19:32:08 +02:00
TaikoZhongandClaude Fable 5.1 44e0a5e3b2 Entry: control-guide mode per phase, mode board title centred on its band
- The top-left control guide follows the cabinet's ChangeMode: `decide` alone on
  the credit screen, the `all` loop (rim to choose + face to decide) on mode
  select when the list has more than one board, hidden during the drum select.
  entry.lua / entry/box.lua publish the phase, global/indicator.lua reads it.
- The open mode board's title sits in the middle of the dark band at the top of
  the plate; the text object's box is taller than its ink, so the nominal y is
  set for the ink (-118 -> -97).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 00:40:52 +08:00
TaikoZhongandClaude Fable 5.1 2a7a6e7f1f Song select: a furled board is drawn as crisp columns, not a squashed bitmap
Squashing the 960-wide board texture to a few px averaged the outline away and,
because the GPU picks the mip level from the larger axis, blurred every row too;
the cabinet scales a vector shape and stays sharp.  draw_board now builds a
furled board from columns: both rounded corners at 1:1 and the band / panel /
band between them scaled in proportion, each drawn from an 8 px flat slice of
itself and magnified.  Narrower than both corners it becomes a solid bar with
the outline columns on either side and the flat centre between them (squeezed
corners left two hollow strokes with nothing between).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 00:37:30 +08:00
TaikoZhongandClaude Fable 5.1 977bf23a2c Song select: the folder close leg plays the cabinet's return half
Closing a folder (もどる) had no wheel motion at all: the fly table only
covered the open leg (clip f27..150), fly_offset only ran for kind "open", and
the engine's 166 ms fade took the song boxes and the back board out right
after the press -- the cabinet keeps them solid until they fly out (f184..204)
and the board furls (f205..217).

- anim/wheel_decide now spans f27..255 (open leg + `return` leg, straight from
  the cabinet clip); fly_offset plays the return half on the close leg: song
  boxes fly out, wait off screen across the swap (f219) and the genre boxes
  fly back in f234..254.  f255 re-bases the clip, so the leg stops before it.
- The engine's box fade is ignored during the pre-swap half of the close leg
  (box_fade); the clip channels already drive the back board's title fade and
  furl.

Verified with captures: press -> boxes stay -> contents fade / boxes fly out ->
back board furls -> genre board unfurls -> contents return -> boxes fly in.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 18:35:47 +08:00
TaikoZhongandClaude Fable 5.1 1c6243baf2 Song select: the decided genre board stays up while its songs load
Opening a folder on this engine differs from the cabinet in one way that
matters for the animation: the cabinet swaps the content 69 frames into the
decide leg, this engine swaps when its loader is done, which can be a couple
of seconds for a big folder.  The leg clock parked one frame short of the swap
(f113), i.e. with the decided board already furled away and the neighbours
flown out, so the screen sat empty for the whole load -- and before that the
engine re-grows the decided box's yellow frame, which made the board close
and reopen right after the press.

- The open leg now parks one frame short of the furl (f99): the decided board
  stays up, contents faded per the clip, as the loading state.  On the swap the
  clock resumes from the furl, so furl (f100..113) and the new board's unfurl
  (f114..) play back to back; a swap that lands before the park point just lets
  the clock run.
- The neighbours' fly-out (f86..99) plays before the swap as on the cabinet;
  it used to wait for the swap and then jump straight to the off-screen hold.
- The decided board is remembered at OPEN_BEGIN and drawn fully open for the
  whole leg, past the engine's closed re-grow and past the moment the engine
  takes the box off the wheel for the loader (draw_overlays bridges it from the
  still-live box handle until it has furled).
- The new content's song / back board is not drawn before the swap frame.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 07:26:09 +08:00
16 changed files with 472 additions and 539 deletions

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 121 B

+4 -4
View File
@@ -70,19 +70,19 @@
]
},
"1p_bar": {
"x": 726,
"x": 738,
"y": 248
},
"2p_bar": {
"x": 726,
"x": 738,
"y": 248
},
"1p_bar_fade": {
"x": 716,
"x": 733,
"y": 241
},
"2p_bar_fade": {
"x": 716,
"x": 733,
"y": 241
},
"tamashii": {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 122 B

+19 -10
View File
@@ -272,21 +272,21 @@
"1p_bar": [
{
"x": 87,
"y": 241
"y": 240
},
{
"x": 1034,
"y": 241
"y": 240
}
],
"2p_bar": [
{
"x": 87,
"y": 241
"y": 240
},
{
"x": 1034,
"y": 241
"y": 240
}
],
"bar_clear_bottom": [
@@ -302,20 +302,20 @@
"bar_clear_top": [
{
"x": 87,
"y": 216
"y": 217
},
{
"x": 1034,
"y": 216
"y": 217
}
],
"bar_clear_transition": [
{
"x": 89,
"x": 87,
"y": 215
},
{
"x": 1036,
"x": 1034,
"y": 215
}
],
@@ -349,7 +349,16 @@
"y": 207
}
],
"tamashii_fire": [{"x": 794, "y": 118}, {"x": 1741, "y": 118}],
"tamashii_fire": [
{
"x": 794,
"y": 118
},
{
"x": 1741,
"y": 118
}
],
"footer": [
{
"x": 0,
@@ -464,4 +473,4 @@
"y": 210
}
]
}
}
+2 -2
View File
@@ -39,7 +39,7 @@
},
"song_info": {
"x": 1872,
"y": 58,
"y": 68,
"font_size": 54,
"outline": 4.333333
},
@@ -544,7 +544,7 @@
},
"gauge_cells": {
"x": 50
},
},
"mod_badge_grid": {
"x": 170,
"y": 77,
+235 -229
View File
@@ -1,12 +1,14 @@
-- GENERATED by scratchpad/anim_export.py -- DO NOT EDIT BY HAND.
-- Re-export: python anim_export.py enso_normal/song_select/song_select_main_genre.nulm #19 --range 27,150 --fields tx,ty --out wheel_decide.lua
-- Source: enso_normal/song_select/song_select_main_genre.nulm clip #19 frames 27..150 @ 60 fps
-- Rows are {frame, tx, ty}; every field is LINEAR between two rows.
-- GENERATED from the cabinet clip with lumen_anim_dump -- DO NOT EDIT BY HAND.
-- Re-export: lumen_anim_dump.exe enso_normal/song_select/song_select_main_genre.nulm --sprite 19 --all --range 27,255
-- Source: enso_normal/song_select/song_select_main_genre.nulm clip #19 frames 27..255 @ 60 fps
-- Rows are {frame, tx, ty}; every field is LINEAR between two rows. f27..150 is the
-- folder OPEN leg (genre_deceide f45, return f150), f150..255 the CLOSE leg (return
-- f150 .. genre_deceide2 f255); at f255 the clip re-bases for a second decide.
return {
movie = "enso_normal/song_select/song_select_main_genre.nulm",
clip = "#19",
fps = 60,
range = { 27, 150 },
range = { 27, 255 },
fields = { "tx", "ty" },
labels = {
["init"] = 0,
@@ -21,13 +23,36 @@ return {
tracks = {
["kanban_genre_1"] = {
{ 27, 5.55, 28.35 },
{ 28, 11.1, 56.65 },
{ 30, 22.2, 113.35 },
{ 31, 27.8, 141.65 },
{ 33, 38.9, 198.35 },
{ 34, 44.45, 226.65 },
{ 35, 50, 255 },
{ 36, 44.45, 226.65 },
{ 37, 38.9, 198.35 },
{ 39, 27.8, 141.65 },
{ 40, 22.2, 113.35 },
{ 42, 11.1, 56.65 },
{ 43, 5.55, 28.35 },
{ 44, 0, 0 },
{ 150, 0, 0 },
{ 254, 0, 0 },
{ 255, 50, 255 },
},
["kanban_genre_2"] = {
{ 27, -44.45, -226.65 },
{ 28, -38.9, -198.35 },
{ 30, -27.8, -141.65 },
{ 31, -22.2, -113.35 },
{ 33, -11.1, -56.65 },
{ 34, -5.55, -28.35 },
{ 35, 0, 0 },
{ 36, -5.55, -28.35 },
{ 37, -11.1, -56.65 },
{ 39, -22.2, -113.35 },
{ 40, -27.8, -141.65 },
{ 42, -38.9, -198.35 },
{ 43, -44.45, -226.65 },
{ 44, -50, -255 },
{ 86, -50, -255 },
{ 87, -50.7, -257.4 },
@@ -57,11 +82,44 @@ return {
{ 139, -52.85, -264.6 },
{ 140, -50.7, -257.4 },
{ 141, -50, -255 },
{ 150, -50, -255 },
{ 191, -50, -255 },
{ 192, -50.7, -257.4 },
{ 193, -52.85, -264.6 },
{ 194, -56.4, -276.55 },
{ 195, -61.35, -293.35 },
{ 196, -67.75, -314.9 },
{ 197, -75.55, -341.25 },
{ 198, -84.8, -372.45 },
{ 199, -95.45, -408.4 },
{ 200, -107.5, -449.1 },
{ 201, -121, -494.65 },
{ 202, -135.9, -544.95 },
{ 203, -152.25, -600.1 },
{ 204, -170, -660 },
{ 233, -170, -660 },
{ 234, -152.25, -600.1 },
{ 235, -135.9, -545 },
{ 236, -121, -494.65 },
{ 237, -107.5, -449.1 },
{ 238, -95.45, -408.4 },
{ 239, -84.8, -372.45 },
{ 240, -75.55, -341.25 },
{ 241, -67.75, -314.9 },
{ 242, -61.35, -293.35 },
{ 243, -56.4, -276.55 },
{ 244, -52.85, -264.6 },
{ 245, -50.7, -257.4 },
{ 246, -50, -255 },
{ 254, -50, -255 },
{ 255, 0, 0 },
},
["kanban_genre_3"] = {
{ 27, 54.45, 270 },
{ 30, 67.8, 315 },
{ 31, 72.2, 330 },
{ 35, 90, 390 },
{ 39, 72.2, 330 },
{ 40, 67.8, 315 },
{ 44, 50, 255 },
{ 86, 50, 255 },
{ 87, 50.7, 257.4 },
@@ -91,11 +149,44 @@ return {
{ 139, 52.85, 264.6 },
{ 140, 50.7, 257.4 },
{ 141, 50, 255 },
{ 150, 50, 255 },
{ 191, 50, 255 },
{ 192, 50.7, 257.4 },
{ 193, 52.85, 264.6 },
{ 194, 56.4, 276.55 },
{ 195, 61.35, 293.35 },
{ 196, 67.75, 314.9 },
{ 197, 75.55, 341.25 },
{ 198, 84.8, 372.45 },
{ 199, 95.45, 408.4 },
{ 200, 107.5, 449.1 },
{ 201, 121, 494.65 },
{ 202, 135.9, 544.95 },
{ 203, 152.25, 600.1 },
{ 204, 170, 660 },
{ 233, 170, 660 },
{ 234, 152.25, 600.1 },
{ 235, 135.9, 545 },
{ 236, 121, 494.65 },
{ 237, 107.5, 449.1 },
{ 238, 95.45, 408.4 },
{ 239, 84.8, 372.45 },
{ 240, 75.55, 341.25 },
{ 241, 67.75, 314.9 },
{ 242, 61.35, 293.35 },
{ 243, 56.4, 276.55 },
{ 244, 52.85, 264.6 },
{ 245, 50.7, 257.4 },
{ 246, 50, 255 },
{ 254, 50, 255 },
{ 255, 90, 390 },
},
["kanban_genre_4"] = {
{ 27, -85.55, -375 },
{ 30, -72.2, -330 },
{ 31, -67.8, -315 },
{ 35, -50, -255 },
{ 39, -67.8, -315 },
{ 40, -72.2, -330 },
{ 44, -90, -390 },
{ 82, -90, -390 },
{ 83, -90.7, -392.4 },
@@ -125,11 +216,44 @@ return {
{ 143, -92.85, -399.6 },
{ 144, -90.7, -392.4 },
{ 145, -90, -390 },
{ 150, -90, -390 },
{ 187, -90, -390 },
{ 188, -90.7, -392.4 },
{ 189, -92.85, -399.6 },
{ 190, -96.4, -411.55 },
{ 191, -101.35, -428.35 },
{ 192, -107.75, -449.9 },
{ 193, -115.55, -476.25 },
{ 194, -124.8, -507.45 },
{ 195, -135.45, -543.4 },
{ 196, -147.5, -584.1 },
{ 197, -161, -629.65 },
{ 198, -175.9, -679.95 },
{ 199, -192.25, -735.1 },
{ 200, -210, -795 },
{ 237, -210, -795 },
{ 238, -192.25, -735.1 },
{ 239, -175.9, -680 },
{ 240, -161, -629.65 },
{ 241, -147.5, -584.1 },
{ 242, -135.45, -543.4 },
{ 243, -124.8, -507.45 },
{ 244, -115.55, -476.25 },
{ 245, -107.75, -449.9 },
{ 246, -101.35, -428.35 },
{ 247, -96.4, -411.55 },
{ 248, -92.85, -399.6 },
{ 249, -90.7, -392.4 },
{ 250, -90, -390 },
{ 254, -90, -390 },
{ 255, -50, -255 },
},
["kanban_genre_5"] = {
{ 27, 94.45, 405 },
{ 30, 107.8, 450 },
{ 31, 112.2, 465 },
{ 35, 130, 525 },
{ 39, 112.2, 465 },
{ 40, 107.8, 450 },
{ 44, 90, 390 },
{ 82, 90, 390 },
{ 83, 90.7, 392.4 },
@@ -159,11 +283,44 @@ return {
{ 143, 92.85, 399.6 },
{ 144, 90.7, 392.4 },
{ 145, 90, 390 },
{ 150, 90, 390 },
{ 187, 90, 390 },
{ 188, 90.7, 392.4 },
{ 189, 92.85, 399.6 },
{ 190, 96.4, 411.55 },
{ 191, 101.35, 428.35 },
{ 192, 107.75, 449.9 },
{ 193, 115.55, 476.25 },
{ 194, 124.8, 507.45 },
{ 195, 135.45, 543.4 },
{ 196, 147.5, 584.1 },
{ 197, 161, 629.65 },
{ 198, 175.9, 679.95 },
{ 199, 192.25, 735.1 },
{ 200, 210, 795 },
{ 237, 210, 795 },
{ 238, 192.25, 735.1 },
{ 239, 175.9, 680 },
{ 240, 161, 629.65 },
{ 241, 147.5, 584.1 },
{ 242, 135.45, 543.4 },
{ 243, 124.8, 507.45 },
{ 244, 115.55, 476.25 },
{ 245, 107.75, 449.9 },
{ 246, 101.35, 428.35 },
{ 247, 96.4, 411.55 },
{ 248, 92.85, 399.6 },
{ 249, 90.7, 392.4 },
{ 250, 90, 390 },
{ 254, 90, 390 },
{ 255, 130, 525 },
},
["kanban_genre_6"] = {
{ 27, -125.55, -510 },
{ 30, -112.2, -465 },
{ 31, -107.8, -450 },
{ 35, -90, -390 },
{ 39, -107.8, -450 },
{ 40, -112.2, -465 },
{ 44, -130, -525 },
{ 78, -130, -525 },
{ 79, -130.7, -527.4 },
@@ -193,11 +350,43 @@ return {
{ 147, -132.85, -534.6 },
{ 148, -130.7, -527.4 },
{ 149, -130, -525 },
{ 150, -130, -525 },
{ 183, -130, -525 },
{ 184, -130.7, -527.4 },
{ 185, -132.85, -534.6 },
{ 186, -136.4, -546.55 },
{ 187, -141.35, -563.35 },
{ 188, -147.75, -584.9 },
{ 189, -155.55, -611.25 },
{ 190, -164.8, -642.45 },
{ 191, -175.45, -678.4 },
{ 192, -187.5, -719.1 },
{ 193, -201, -764.65 },
{ 194, -215.9, -814.95 },
{ 195, -232.25, -870.1 },
{ 196, -250, -930 },
{ 241, -250, -930 },
{ 242, -232.25, -870.1 },
{ 243, -215.9, -815 },
{ 244, -201, -764.65 },
{ 245, -187.5, -719.1 },
{ 246, -175.45, -678.4 },
{ 247, -164.8, -642.45 },
{ 248, -155.55, -611.25 },
{ 249, -147.75, -584.9 },
{ 250, -141.35, -563.35 },
{ 251, -136.4, -546.55 },
{ 252, -132.85, -534.6 },
{ 253, -130.7, -527.4 },
{ 254, -130, -525 },
{ 255, -90, -390 },
},
["kanban_genre_7"] = {
{ 27, 134.45, 540 },
{ 30, 147.8, 585 },
{ 31, 152.2, 600 },
{ 35, 170, 660 },
{ 39, 152.2, 600 },
{ 40, 147.8, 585 },
{ 44, 130, 525 },
{ 78, 130, 525 },
{ 79, 130.7, 527.4 },
@@ -227,229 +416,46 @@ return {
{ 147, 132.85, 534.6 },
{ 148, 130.7, 527.4 },
{ 149, 130, 525 },
{ 150, 130, 525 },
{ 183, 130, 525 },
{ 184, 130.7, 527.4 },
{ 185, 132.85, 534.6 },
{ 186, 136.4, 546.55 },
{ 187, 141.35, 563.35 },
{ 188, 147.75, 584.9 },
{ 189, 155.55, 611.25 },
{ 190, 164.8, 642.45 },
{ 191, 175.45, 678.4 },
{ 192, 187.5, 719.1 },
{ 193, 201, 764.65 },
{ 194, 215.9, 814.95 },
{ 195, 232.25, 870.1 },
{ 196, 250, 930 },
{ 241, 250, 930 },
{ 242, 232.25, 870.1 },
{ 243, 215.9, 815 },
{ 244, 201, 764.65 },
{ 245, 187.5, 719.1 },
{ 246, 175.45, 678.4 },
{ 247, 164.8, 642.45 },
{ 248, 155.55, 611.25 },
{ 249, 147.75, 584.9 },
{ 250, 141.35, 563.35 },
{ 251, 136.4, 546.55 },
{ 252, 132.85, 534.6 },
{ 253, 130.7, 527.4 },
{ 254, 130, 525 },
{ 255, 170, 660 },
},
["kanban_genre_8"] = {
{ 27, -165.55, -645 },
{ 30, -152.2, -600 },
{ 31, -147.8, -585 },
{ 35, -130, -525 },
{ 39, -147.8, -585 },
{ 40, -152.2, -600 },
{ 44, -170, -660 },
{ 150, -170, -660 },
},
["kanban_song_1"] = {
{ 27, 5.55, 28.35 },
{ 35, 50, 255 },
{ 44, 0, 0 },
{ 150, 0, 0 },
},
["kanban_song_2"] = {
{ 27, -44.45, -226.65 },
{ 35, 0, 0 },
{ 44, -50, -255 },
{ 86, -50, -255 },
{ 87, -50.7, -257.4 },
{ 88, -52.85, -264.6 },
{ 89, -56.4, -276.55 },
{ 90, -61.35, -293.35 },
{ 91, -67.75, -314.9 },
{ 92, -75.55, -341.25 },
{ 93, -84.8, -372.45 },
{ 94, -95.45, -408.4 },
{ 95, -107.5, -449.1 },
{ 96, -121, -494.65 },
{ 97, -135.9, -544.95 },
{ 98, -152.25, -600.1 },
{ 99, -170, -660 },
{ 128, -170, -660 },
{ 129, -152.25, -600.1 },
{ 130, -135.9, -545 },
{ 131, -121, -494.65 },
{ 132, -107.5, -449.1 },
{ 133, -95.45, -408.4 },
{ 134, -84.8, -372.45 },
{ 135, -75.55, -341.25 },
{ 136, -67.75, -314.9 },
{ 137, -61.35, -293.35 },
{ 138, -56.4, -276.55 },
{ 139, -52.85, -264.6 },
{ 140, -50.7, -257.4 },
{ 141, -50, -255 },
{ 150, -50, -255 },
},
["kanban_song_3"] = {
{ 27, 54.45, 270 },
{ 35, 90, 390 },
{ 44, 50, 255 },
{ 86, 50, 255 },
{ 87, 50.7, 257.4 },
{ 88, 52.85, 264.6 },
{ 89, 56.4, 276.55 },
{ 90, 61.35, 293.35 },
{ 91, 67.75, 314.9 },
{ 92, 75.55, 341.25 },
{ 93, 84.8, 372.45 },
{ 94, 95.45, 408.4 },
{ 95, 107.5, 449.1 },
{ 96, 121, 494.65 },
{ 97, 135.9, 544.95 },
{ 98, 152.25, 600.1 },
{ 99, 170, 660 },
{ 128, 170, 660 },
{ 129, 152.25, 600.1 },
{ 130, 135.9, 545 },
{ 131, 121, 494.65 },
{ 132, 107.5, 449.1 },
{ 133, 95.45, 408.4 },
{ 134, 84.8, 372.45 },
{ 135, 75.55, 341.25 },
{ 136, 67.75, 314.9 },
{ 137, 61.35, 293.35 },
{ 138, 56.4, 276.55 },
{ 139, 52.85, 264.6 },
{ 140, 50.7, 257.4 },
{ 141, 50, 255 },
{ 150, 50, 255 },
},
["kanban_song_4"] = {
{ 27, -85.55, -375 },
{ 35, -50, -255 },
{ 44, -90, -390 },
{ 82, -90, -390 },
{ 83, -90.7, -392.4 },
{ 84, -92.85, -399.6 },
{ 85, -96.4, -411.55 },
{ 86, -101.35, -428.35 },
{ 87, -107.75, -449.9 },
{ 88, -115.55, -476.25 },
{ 89, -124.8, -507.45 },
{ 90, -135.45, -543.4 },
{ 91, -147.5, -584.1 },
{ 92, -161, -629.65 },
{ 93, -175.9, -679.95 },
{ 94, -192.25, -735.1 },
{ 95, -210, -795 },
{ 132, -210, -795 },
{ 133, -192.25, -735.1 },
{ 134, -175.9, -680 },
{ 135, -161, -629.65 },
{ 136, -147.5, -584.1 },
{ 137, -135.45, -543.4 },
{ 138, -124.8, -507.45 },
{ 139, -115.55, -476.25 },
{ 140, -107.75, -449.9 },
{ 141, -101.35, -428.35 },
{ 142, -96.4, -411.55 },
{ 143, -92.85, -399.6 },
{ 144, -90.7, -392.4 },
{ 145, -90, -390 },
{ 150, -90, -390 },
},
["kanban_song_5"] = {
{ 27, 94.45, 405 },
{ 35, 130, 525 },
{ 44, 90, 390 },
{ 82, 90, 390 },
{ 83, 90.7, 392.4 },
{ 84, 92.85, 399.6 },
{ 85, 96.4, 411.55 },
{ 86, 101.35, 428.35 },
{ 87, 107.75, 449.9 },
{ 88, 115.55, 476.25 },
{ 89, 124.8, 507.45 },
{ 90, 135.45, 543.4 },
{ 91, 147.5, 584.1 },
{ 92, 161, 629.65 },
{ 93, 175.9, 679.95 },
{ 94, 192.25, 735.1 },
{ 95, 210, 795 },
{ 132, 210, 795 },
{ 133, 192.25, 735.1 },
{ 134, 175.9, 680 },
{ 135, 161, 629.65 },
{ 136, 147.5, 584.1 },
{ 137, 135.45, 543.4 },
{ 138, 124.8, 507.45 },
{ 139, 115.55, 476.25 },
{ 140, 107.75, 449.9 },
{ 141, 101.35, 428.35 },
{ 142, 96.4, 411.55 },
{ 143, 92.85, 399.6 },
{ 144, 90.7, 392.4 },
{ 145, 90, 390 },
{ 150, 90, 390 },
},
["kanban_song_6"] = {
{ 27, -125.55, -510 },
{ 35, -90, -390 },
{ 44, -130, -525 },
{ 78, -130, -525 },
{ 79, -130.7, -527.4 },
{ 80, -132.85, -534.6 },
{ 81, -136.4, -546.55 },
{ 82, -141.35, -563.35 },
{ 83, -147.75, -584.9 },
{ 84, -155.55, -611.25 },
{ 85, -164.8, -642.45 },
{ 86, -175.45, -678.4 },
{ 87, -187.5, -719.1 },
{ 88, -201, -764.65 },
{ 89, -215.9, -814.95 },
{ 90, -232.25, -870.1 },
{ 91, -250, -930 },
{ 136, -250, -930 },
{ 137, -232.25, -870.1 },
{ 138, -215.9, -815 },
{ 139, -201, -764.65 },
{ 140, -187.5, -719.1 },
{ 141, -175.45, -678.4 },
{ 142, -164.8, -642.45 },
{ 143, -155.55, -611.25 },
{ 144, -147.75, -584.9 },
{ 145, -141.35, -563.35 },
{ 146, -136.4, -546.55 },
{ 147, -132.85, -534.6 },
{ 148, -130.7, -527.4 },
{ 149, -130, -525 },
{ 150, -130, -525 },
},
["kanban_song_7"] = {
{ 27, 134.45, 540 },
{ 35, 170, 660 },
{ 44, 130, 525 },
{ 78, 130, 525 },
{ 79, 130.7, 527.4 },
{ 80, 132.85, 534.6 },
{ 81, 136.4, 546.55 },
{ 82, 141.35, 563.35 },
{ 83, 147.75, 584.9 },
{ 84, 155.55, 611.25 },
{ 85, 164.8, 642.45 },
{ 86, 175.45, 678.4 },
{ 87, 187.5, 719.1 },
{ 88, 201, 764.65 },
{ 89, 215.9, 814.95 },
{ 90, 232.25, 870.1 },
{ 91, 250, 930 },
{ 136, 250, 930 },
{ 137, 232.25, 870.1 },
{ 138, 215.9, 815 },
{ 139, 201, 764.65 },
{ 140, 187.5, 719.1 },
{ 141, 175.45, 678.4 },
{ 142, 164.8, 642.45 },
{ 143, 155.55, 611.25 },
{ 144, 147.75, 584.9 },
{ 145, 141.35, 563.35 },
{ 146, 136.4, 546.55 },
{ 147, 132.85, 534.6 },
{ 148, 130.7, 527.4 },
{ 149, 130, 525 },
{ 150, 130, 525 },
},
["kanban_song_8"] = {
{ 27, -165.55, -645 },
{ 35, -130, -525 },
{ 44, -170, -660 },
{ 150, -170, -660 },
{ 254, -170, -660 },
{ 255, -130, -525 },
},
},
}
+8 -1
View File
@@ -28,7 +28,11 @@ local INFO_SIZE = 34
-- text_title_instance sits at y=-106 (on) / 0 (off); inside it text_instance_1/2 at -84.5 hold the
-- 758x126 text box at (-378,2) -> box centre -20.5 (off) / -126.5 (on). Lumen dynamic text is
-- vertically centred in its box (the reference research notes 3a).
local TITLE_Y_ON, TITLE_Y_OFF = -118, 4 -- closed board: user saw the title riding the top edge (+16) -- +8 px: user asked the title slightly lower
-- TITLE_Y_ON: the open board's title sits in the middle of the dark band at the top of the
-- plate (plate rows 64..187 -> centre 104.5 above the board centre). The text object's
-- box is taller than its ink (descender room), so its ink centre lands ~16 px above the
-- nominal y; -97 nominal puts the ink on the band centre (tuned on screen).
local TITLE_Y_ON, TITLE_Y_OFF = -97, 4 -- closed board: user saw the title riding the top edge (+16)
-- text_info_instance at y=57, text_info rect (-2,-2,478,192) at (-238,-92.5) -> box -37.5..156.5,
-- centre 59.5. The cabinet renderer centres the text block in the box and advances lines by the
-- atlas line height (jp_32 fontSize 53 x scale 32/32 = 53 px) -> line centres ~33 / ~86.
@@ -348,6 +352,9 @@ function EntryBox:draw(x, left_x, right_x, is_selected, move_finished, open_attr
local now = tex.get_current_ms()
local shared = __hss_entry_mode
if shared.in_t0 == nil then shared.in_t0 = now end -- first frame the list is drawn
-- ModeSelect: the cabinet's guide shows `all` (rim to choose + face to decide) when the
-- list has more than one board, `decide` alone otherwise (entry_main.lua ChangeMode)
__hss_entry_guide = { ms = now, phase = "mode", count = #__hss_entry_boxes }
if is_selected and shared.sel ~= self.index then
shared.sel = self.index
shared.t0 = now
+11 -231
View File
@@ -1,12 +1,8 @@
-- YataiDON-HSS override of PyTaikoGreen/entry/entry.lua: cancel text centring uses cancel_info.x2[1]/y2[1];
-- sets __hss_entry_reset for the arcade mode-select list in box.lua
Entry = {}
Entry.__index = Entry
function Entry.new()
local self = setmetatable({}, Entry)
-- EntryScreen::on_screen_start creates BoxManager (4 EntryBox) then this script;
-- flag the box list so the NEXT batch of EntryBox.new starts fresh (see box.lua).
__hss_entry_reset = true
tex.load_animations("entry")
@@ -14,36 +10,11 @@ function Entry.new()
self.side_select_fade = tex.get_animation(0, "entry")
self.bg_flicker:start()
-- ROUND 11 -- the arcade "credit wait" screen (lumen entry/entry_credit) has no
-- 「どちらでつかいますか?」 box: two pills carrying 「1人プレイ」/「2人プレイ」 on the pale
-- left half and 「太鼓をたたいてスタート!」 on the yellow right half. Strings are the
-- cabinet's own wordlist rows credit_play_1p / credit_play_2p / credit_start.
-- Outline thickness is scaled by screen_scale (1.5) in OutlinedText's ctor, so the
-- arcade's DefineEditText border 7 is passed as 5 (= 7.5 px).
-- ROUND 11b: 「つかわない」 is drawn as a small CAPTION, only while side 1 is armed.
-- The arcade credit screen has no cancel widget at all (entry_main.lua leaves the screen
-- on the 60 s timer, never on a button), but the engine's side 1 is real and reachable.
self.text_cancel = text.create_text("entry_cancel", { 255, 255, 255, 255 }, { 40, 24, 12, 255 }, false, 3, 0)
self.text_credit_p = {
-- ROUND 15 -- outline thickness 0, NOT the record's border 7. ET7 is `#000000` with
-- border 7, and the cabinet's outline colour is the renderer default (black), so the
-- border on this field is a pure 7.5-screen-px BLACK-ON-BLACK dilation: it carries no
-- colour information at all, it only fattens the glyphs. On 「1人プレイ」 that is
-- invisible (kana strokes are far apart), but at font 56 it closes every counter of a
-- Latin string and「1-Player」/「2-Player」 render as an unreadable black smear
-- (`scratchpad/r15ae/z_1player_en.png`). Deliberate deviation, documented here: the
-- fill colour is unchanged, so the label still reads exactly as the cabinet's black
-- text, and it is legible in every language this skin ships.
-- black ink with the cabinet's WHITE outline (same 7 stage-px border as the message)
text.create_text("entry_credit_1p", { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, false, 7.0 / tex.get_screen_scale(), 0),
text.create_text("entry_credit_2p", { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, false, 7.0 / tex.get_screen_scale(), 0),
}
-- the message is ONE string drawn in two colourways: the arcade stacks a black-tinted
-- outline copy (ET3 via cmul (0,0,0)) under a white fill copy (ET5), and its blink
-- recolours that outline to (256,236,67). Cross-fading these two reproduces it.
-- ROUND 16 (r16-outline): `entry/entry_credit` ET3 `text_credit` carries border 7.0,
-- which is already in 1080p stage px; OutlinedText multiplies by screen_scale (1.5),
-- so it is divided out rather than rounded to 5 (which drew 7.5 px).
local CREDIT_BORDER = 7.0 / tex.get_screen_scale()
self.text_credit_msg = text.create_text("entry_credit_start", { 255, 255, 255, 255 }, { 0, 0, 0, 255 }, false, CREDIT_BORDER, 0)
self.text_credit_msg_hl = text.create_text("entry_credit_start", { 255, 255, 255, 255 }, { 255, 236, 67, 255 }, false, CREDIT_BORDER, 0)
@@ -56,19 +27,11 @@ function Entry.new()
self.bg_shops_right = tex.load_texture("entry/background/shops_right")
self.bg_lights = tex.load_texture("entry/background/lights")
-- ROUND 6 — layered arcade backdrop (lumen entry/entry, entrybg_instance MC 19).
-- Arcade display list: d0 shape1 (gold sky) / d1 MC11 twinkles / d2 shape12 (street, sky
-- transparent) / d3-6 MC16 glow x4 (blend=add) / d7 shape17 (fully lit street, opaque).
-- `bg` is byte-exact shape1+shape12, so only d3-d7 have to be re-added.
self.bg_street_lit = tex.load_texture("entry/background/street_lit")
self.bg_glow = tex.load_texture("entry/background/glow")
self.bg_twinkle = tex.load_texture("entry/background/twinkle")
self.bg_t0 = tex.get_current_ms()
-- ROUND 11: the parent's nine-slice box / 1P / 2P / cancel / footer art is no longer
-- drawn (the arcade credit screen has none of it). These four are the arcade's own
-- shapes, baked by Graphics/entry/bake_credit.py; both pills are the SAME 1160x200
-- plate placed twice (texture.json carries the two placements).
self.cr_pill = tex.load_texture("entry/side_select/credit_pill")
self.cr_flash = tex.load_texture("entry/side_select/credit_flash")
self.cr_t0 = tex.get_current_ms()
@@ -78,42 +41,12 @@ function Entry.new()
self.cr_seen_frame = nil
self.cr_decide_t0 = nil
self.cr_decide_row = nil
-- ROUND 12 -- opt-in arcade CREDIT WAIT interaction model. skin_config_entry.json's
-- `entry_credit_arcade` = 1 switches the engine (EntryScreen::handle_input) to the
-- cabinet's rule: the two rows are PROMPTS, both lit, no cursor, no 「つかわない」;
-- whichever SEAT hits its own don enters as that player. PyTaikoGreen leaves the key
-- out and keeps the kat-moved side cursor.
local arcade_cfg = tex.get_skin_config("entry_credit_arcade")
self.cr_arcade = (arcade_cfg ~= nil and (arcade_cfg.x or 0) >= 1)
self.cr_pending_decide = nil
self.global_player_entry = tex.load_texture("entry/global/player_entry")
-- ROUND 18 (r18-misc) -- the top-left control guide belongs on the CREDIT WAIT
-- screen and we were not drawing it there at all.
--
-- The cabinet's own source settles it. `entry.nulm` root (sprite 54) carries
-- `controlguide_instance` at depth 28, i.e. a sibling of `entrycredit_instance`
-- (depth 23) and drawn OVER it. `script_lua/entry/entry_main.lua` CreditWait,
-- lines 957-966:
-- if this.start_guide_ == false then
-- if PlayDataManager.GameCost1 <= PlayDataManager.GetNowCoin()
-- or PlayDataManager.IsFreePlay() == true then
-- this.control_guide_:SetVisible(true)
-- this.control_guide_:Start(1)
-- and `common/ControlGuide.lua` `Start(mode)` -> `ChangeMode(1)` ->
-- `taiko_small:GotoAndStop("decide")`. So on a free-play cabinet the guide is up
-- from the first frame of the credit screen, in its **decide** state -- exactly the
-- second half of the loop `global/indicator/background` already bakes (arcade frames
-- 420..649; see Scripts/global/indicator.lua). It is torn down again at
-- ModeSelectFinishActionWait (l.1233) and at each TaikoSelect start (l.481, l.797).
--
-- Engine-side, `Indicator` is owned by `EntryPlayer`, so it only ever draws once a
-- seat has ENTERED; before that `players` is empty and nothing draws the panel.
-- Drawing it from here is the whole fix -- same texture, same (0,0), same frames.
--
-- NOT ported: `ControlGuide.Update` slides the panel to screen centre after 3 s with
-- no input (`to_center`) and back on the next hit (`to_default`). The baked loop has
-- no centre variant, so the guide stays parked top-left.
self.guide = tex.load_texture("global/indicator/background")
self.guide_t0 = self.cr_t0
self.any_joined = false
@@ -121,23 +54,12 @@ function Entry.new()
return self
end
-- Same split as Scripts/global/indicator.lua: the bake is two guides back to back at
-- one cell per 2 arcade frames, and cells GUIDE_SPLIT..GUIDE_END-1 are the 「決定」 half.
local GUIDE_STEP = 2
local GUIDE_SPLIT = math.floor(420 / GUIDE_STEP)
local GUIDE_END = math.floor(650 / GUIDE_STEP)
-- NOTE: do NOT gate this on `tex.get_texture_info("indicator","background").frame_count`.
-- The bake is a `crop` list in texture.json, not a frame-count sheet, and
-- `get_texture_info` only reports a real count for `FramedTexture` -- for this one it
-- returns 1, so a `frame_count >= 325` guard silently drew nothing. `indicator.lua`
-- reads the same value into `self.frame_count` and never uses it, which is why the
-- discrepancy had not been noticed. `draw_texture{frame=N}` indexes the crop list fine.
function Entry:draw_control_guide()
if not self.guide then return end
-- One frame of overlap with EntryPlayer's own Indicator on the join frame is
-- possible (draw_footer publishes the join flags after this runs); both draws are
-- the same cell at the same place, so it is invisible.
if self.any_joined then return end
local n = GUIDE_END - GUIDE_SPLIT
local f = GUIDE_SPLIT + math.floor((tex.get_current_ms() - self.guide_t0) * 0.06 / GUIDE_STEP) % n
@@ -147,10 +69,6 @@ end
function Entry:update(current_ms)
self.bg_flicker:update(current_ms)
self.side_select_fade:update(current_ms)
-- ROUND 11: a frame counter is the only way Lua can see that the engine has LEFT
-- EntryState::SELECT_SIDE (draw_side_select_buttons simply stops being called), which
-- is what triggers the arcade's `choose` flash + fade_out. update() runs once per
-- frame, before draw().
self.cr_frame = (self.cr_frame or 0) + 1
end
@@ -164,8 +82,6 @@ function Entry:restart_side_select()
self:restart_credit()
end
-- credit_instance `fade_in` (sprite 11 f5..f15) restarts, and so does the row's attract
-- loop; any pending decide overlay is dropped (the 2P join re-enters SELECT_SIDE).
function Entry:restart_credit()
local now = tex.get_current_ms()
self.cr_t0 = now
@@ -181,28 +97,8 @@ function Entry:get_side_select_fade()
return self.side_select_fade.attribute
end
-- ROUND 8 -- the whole `entrybg_instance` rig (lumen `entry/entry.nulm` MC 19) is now
-- SAMPLED out of `Scripts/anim/entry_bg.lua` instead of the closed forms round 6 fitted
-- to it. See ANIM_PIPELINE.md. Tracks, in the cabinet's own display order:
-- d1 twinkles `#11@1/#5@0/#3@0` (f0), `#11@1/#8@1/#6@0` (f90),
-- `#11@1/#9@2/#3@0` (f120), `#11@1/#10@3/#6@0` (f219)
-- d3-d6 glows `#16@3/#14@0` (all four are the same 120-frame curve, in phase)
-- d7 lit street `#17@7`
-- The table covers a whole 360-frame (6 s) cycle, so every channel is just read at
-- `f % 360` -- no per-channel modulo bookkeeping.
--
-- What the export changed: the two SMALL twinkles were drawn 25 % too small at the end of
-- their burst. Round 6 modelled every burst as one envelope times a per-burst multiplier
-- (0.5 for the small pair), which gives 0.25 -> 0.5 -> 0.75. The cabinet runs them
-- 0.25 -> 0.5 -> 1.0: the multiplier applies to the GROW phase only, and the expand phase
-- adds the same absolute +0.5 to big and small alike. Alpha, the big bursts, the glow
-- triangle and the street blink were all confirmed exact.
-- ROUND 8: fail soft. `pcall` the require and use `anim.safe`, which hands back a NULL
-- clip when a generated table is missing or malformed, so every reader below falls
-- through to its `or <constant>` default instead of taking the screen down.
local _ea_ok, entry_anim = pcall(require, "anim/sampler")
if not _ea_ok then entry_anim = { safe = function()
-- sampler.lua itself is missing: hand back the same NULL clip shape it would
local n = {}
n.at = function() return nil end; n.get = function() return nil end
n.label = function() return nil end; n.has = function() return false end
@@ -210,48 +106,22 @@ if not _ea_ok then entry_anim = { safe = function()
return n
end } end
local EBG = entry_anim.safe("anim/entry_bg")
-- ROUND 11 -- entry/entry_credit.nulm, exported by scratchpad/anim_export.py:
-- CR = sprite 10 (one player row): labels init 0 / start 5 / choose 125. Tracks
-- `text_message_instance` (the white fill copy), `text_message_instance_2` (the
-- outline copy -- fields cr,cg,cb carry its black<->yellow recolour) and `#8@4`
-- (the white decide flash, shape 8, only placed from f125).
-- CF = sprite 11 (credit_instance): fade_in f5..f15, fade_out f16..f35.
local CR = entry_anim.safe("anim/credit_row")
local CF = entry_anim.safe("anim/credit_fade")
-- Layout, straight out of the lumen (stage 1920x1080; the root places credit_instance at
-- (960,432) and the row sprite is placed twice, at ty +72 and +248):
local CREDIT_CX = 960
local ROW_CY = { 432 + 72, 432 + 248 } -- 504 / 680
-- DefineEditText records (payload map: [2] text sym, [4] colour, [5] rect, byte 32 align,
-- f32@44 size, f32@60 outline -- Graphics/result/MAPPING.md ROUND 6):
-- ET7 text_player rect (-2,-2,306,94) placed at (-448,-62.5), align 0 (LEFT), size 56, border 7
-- ET3 message rect (-2,-2,638,94) placed at (-137,0)+(2,-62.5), align 2 (CENTRE), size 56, border 7
-- The cabinet text rule is pen.y = box.top + (box.h - lineHeight)/2 + border, so the INK
-- CENTRE is box.top + box.h/2 + border -- independent of which font raster is used:
local LABEL_INK_X = CREDIT_CX - 443 -- box.left(-450) + border(7), left-aligned
local MSG_INK_X = CREDIT_CX + 190 -- box.left(-137) + border(7) + box.w/2(320)
local TEXT_INK_DY = 0.5 -- box.top(-64.5) + box.h/2(48) + border(7), +10: measured
-- against the cabinet the ink sat ~10 px above the pill centre
local PAD5 = 9 -- OutlinedText pad for thickness 5: (int)(5*1.5)+2
-- ROUND 15: the two player labels are now built with thickness 0 (see `text_credit_p` above),
-- so their texture pad is (int)(0*1.5)+2 = 2, not 9. Using PAD5 here would shift the ink 7 px
-- right of the cabinet's pen at box.left + border.
local ROW_CY = { 432 + 72, 432 + 248 }
local LABEL_INK_X = CREDIT_CX - 443
local MSG_INK_X = CREDIT_CX + 190
local TEXT_INK_DY = 0.5
local PAD5 = 9
local PAD_LABEL = 2
-- The cancel widget is NOT an arcade element (MAPPING.md ROUND 11): the same pill at 0.5,
-- centred under the two rows.
local CANCEL_CX, CANCEL_CY = 960, 838
local ROW_LOOP_F0, ROW_LOOP_LEN = 5, 120 -- the row timeline loops `start`..f124
-- NOT arcade: the cabinet lights both rows equally because it has no cursor (each row is
-- armed for that side's own drum). The engine DOES have a cursor, so the row that is not
-- armed is dimmed and the armed one carries a pulse of the arcade white `choose` overlay.
local ROW_LOOP_F0, ROW_LOOP_LEN = 5, 120
local DIM_UNSELECTED = 0.72
local DECIDE_FLASH_F = 24 -- `choose` blink f125..f149
local EBG_LEN = math.max(1, EBG:last() - EBG:first() + 1) -- 360 frames = 6 s
-- `entrybg_instance` is 30 frames and STOPS at f29 (see draw_background); after that the
-- lit-street layer is gone for good. 19 is where its alpha first reaches 0.
local DECIDE_FLASH_F = 24
local EBG_LEN = math.max(1, EBG:last() - EBG:first() + 1)
local BG_LIT_END = 19
-- {json index, texture frame (0 = shape3, 1 = shape6), track}
local ENTRY_TWINKLES = {
{ 0, 0, "#11@1/#5@0/#3@0" },
{ 1, 0, "#11@1/#9@2/#3@0" },
@@ -264,10 +134,6 @@ function Entry:draw_background()
tex.draw_texture(self.bg_bg)
-- d1 twinkles (arcade draws them under the street; the street is baked into `bg`, so
-- they sit on top here -- only visible where a burst overlaps stall art). A burst is
-- only placed on the frames it is alive, so a track that has no row at `f` returns its
-- clamped end value (alpha 0) and draws nothing.
if self.bg_twinkle then
for i = 1, #ENTRY_TWINKLES do
local tw = ENTRY_TWINKLES[i]
@@ -279,31 +145,13 @@ function Entry:draw_background()
end
end
-- d3-d6 warm glows. The arcade blends these additively; each patch is pre-composited
-- (bg + glow, clamped) so a plain alpha fade reproduces `bg + a*glow` exactly. Two
-- patches only -- the left lamp, and the three right-hand lamps summed into one box --
-- because pre-composited patches must not overlap (a later patch would replace, not
-- add, the glow an earlier one already carries) and every frame of a folder texture
-- is drawn at frame 0's size.
if self.bg_glow then
local ga = EBG:get("#16@3/#14@0", f, "a") or 1.0
for i = 0, 1 do
for i = 0, 3 do
tex.draw_texture(self.bg_glow, { index = i, frame = i, fade = ga })
end
end
-- d7 lit street: a ONE-SHOT "blur in", NOT a loop. `entrybg_instance` (MC 19) is only
-- 30 frames long and carries DoAction index 0 at BOTH f4 and f29. f4 must be Stop() --
-- `entry_main.lua` StartBGIn is what starts the clip (`this.bg_:GotoAndPlay("start")`,
-- label `start` = f5), so the clip is parked at f4 until then -- and f29 carries the
-- SAME action index, therefore f29 is Stop() too. So the cabinet plays f5..f29 once and
-- holds: shape17 (the SHARP, fully-lit street, lapvar 1508) fades 1 -> 0 over f5..f19,
-- leaving shape12 (the DEPTH-OF-FIELD BLURRED street, lapvar 48) as the steady state.
-- That matches every arcade reference capture ("festival street, blurred").
-- `Scripts/anim/entry_bg.lua` was exported with `--range 0,359`, which wrapped this
-- 30-frame clip twelve times and turned the one-shot into a 2 Hz sharp/blurry strobe
-- (the user's 「背景模糊亂跳」). Only THIS channel wraps: the twinkle MCs (5/8/9/10)
-- really are 360 frames and the glow MC (16) really is 120, so `f` stays modulo for them.
if self.bg_street_lit then
local lf = (tex.get_current_ms() - self.bg_t0) * 0.06 -- monotonic, NOT wrapped
if lf < BG_LIT_END then
@@ -313,9 +161,6 @@ function Entry:draw_background()
end
end
-- ROUND 11 -- the arcade credit screen has no panel behind the buttons: the pills sit
-- straight on the festival street. The parent nine-slice box and its
-- japanese caption are therefore not drawn at all.
function Entry:draw_side_select()
end
@@ -338,25 +183,6 @@ function Entry:draw_credit_row(row, f, a)
if msg and ma > 0.002 then
local x = MSG_INK_X - msg.width / 2
local y = cy + TEXT_INK_DY - msg.height / 2
-- ROUND 26 (r26-entrytextfade): `msg`/`msg_hl` are each a whole baked
-- OutlinedText -- white fill AND its outline in ONE texture (OutlinedText
-- bakes them together; text.cpp's draw() only has a single `fade` alpha for
-- the whole quad, there is no separate fill/outline alpha). The old code
-- faded BOTH copies down independently ((1-yellow) and yellow), so around
-- the blink midpoint BOTH copies were simultaneously translucent: the white
-- fill of each stopped being opaque, the pill's yellow bled through it, and
-- the outline ring (itself fading through a yellow close to the pill's own
-- colour) lost all contrast -- exactly the reported "白字跟外框fade時機不同,
-- 出現純白字" flash (captured live at scratchpad/r26etf/before/f20_9530ms.png,
-- ~9.5s into the credit-wait loop, i.e. inside the `choose` blink f64..f95).
-- Fix: draw the black-outline copy ALWAYS fully opaque as the base (fade =
-- a*ma, no `(1-yellow)` term), then cross-dissolve the yellow-outline copy
-- ON TOP of it at fade = a*ma*yellow. Back-to-front opaque compositing means
-- the result is fully opaque at every point of the blend -- the fill stays
-- solid white throughout (yellow copy's white fill lands on the already-
-- opaque white fill beneath, a no-op), and the outline smoothly darkens from
-- black to yellow while never dropping below full alpha, so it is never
-- washed out by the pill background behind it.
msg:draw({ x = x, y = y, fade = a * ma })
if yellow > 0.001 and self.text_credit_msg_hl then
self.text_credit_msg_hl:draw({ x = x, y = y, fade = a * ma * yellow })
@@ -364,44 +190,28 @@ function Entry:draw_credit_row(row, f, a)
end
end
-- The whole credit_instance: both rows + the cancel widget, at `a` (its fade_in/out alpha).
-- `sel` is the highlighted row: 1 / 2 / 0 = the cancel widget / nil = nothing (the decide
-- overlay, where the selection has already been consumed). `flash_row`/`flash_a` drive the
-- `choose` overlay.
function Entry:draw_credit(a, sel, blink_f, flash_row, flash_a, loop_rows)
for row = 1, 2 do
local armed = (row == sel)
local ra = (sel == nil or sel == 0 or armed) and a or (a * DIM_UNSELECTED)
-- Arcade: the cabinet runs the row attract loop (`start`..f124, the yellow-outline
-- blink at f64..f95) on BOTH rows in CreditWait, because neither is "armed". The
-- cursor model only animated the armed row and froze the other at f5.
local rf = (armed or loop_rows) and blink_f or ROW_LOOP_F0
self:draw_credit_row(row, rf, ra)
end
local now = tex.get_current_ms()
if sel and sel > 0 then
-- the selected pill also carries a gentle version of the arcade white `choose`
-- overlay, standing in for a cursor the cabinet does not need (there, a row is
-- picked by hitting that side's own drum).
local pulse = 0.08 + 0.10 * math.sin((now - self.cr_blink_t0) * 0.006)
tex.draw_texture(self.cr_flash, { index = sel - 1, fade = a * pulse })
end
-- The cabinet never shows a 「つかわない」 caption on this screen (the cancel side is
-- just the un-armed state), so nothing is drawn for sel == 0.
if flash_row and flash_a and flash_a > 0.002 then
tex.draw_texture(self.cr_flash, { index = flash_row - 1, fade = a * flash_a })
end
end
-- The engine thinks in SIDES, not in a player COUNT: `side` is 0 = left/1P, 1 = cancel
-- (back to title, or back to mode select when a 2nd player is joining), 2 = right/2P,
-- moved with kat and confirmed with don. The arcade screen has no cursor at all -- each
-- row is armed for that side's own drum -- so side 0/2 map onto the upper/lower row and
-- side 1 onto the cancel widget. See Graphics/entry/MAPPING.md ROUND 11.
function Entry:draw_side_select_buttons(side)
local now = tex.get_current_ms()
__hss_entry_guide = { ms = now, phase = "side" }
if side ~= self.cr_side then
self.cr_side = side
self.cr_blink_t0 = now -- a newly armed row restarts its attract cycle
@@ -409,12 +219,9 @@ function Entry:draw_side_select_buttons(side)
self.cr_seen_frame = self.cr_frame
self.cr_decide_t0 = nil
-- credit_instance fade_in: sprite 11, f5..f15 (10 frames), clamped after
local fi = math.min(15, 5 + (now - self.cr_t0) * 0.06)
local a = CF:get("player1_text_instance", fi, "a") or 1.0
-- Arcade: no cursor at all -- `sel = nil` keeps BOTH rows at full alpha, draws no
-- selection pulse and no 「つかわない」 caption (the cabinet has neither).
local sel = (not self.cr_arcade)
and ((side == 0 and 1) or (side == 2 and 2) or 0)
or nil
@@ -422,25 +229,11 @@ function Entry:draw_side_select_buttons(side)
self:draw_credit(a, sel, blink_f, nil, nil, self.cr_arcade)
-- depth 28 > depth 23: the guide sits OVER the credit rows.
self:draw_control_guide()
-- entry_main.lua only makes `credit_side_[n]` visible in ModeSelectStartWait, i.e. AFTER
-- the credit screen is finished; coin_overlay.lua reads this to keep the 2P invite cloud
-- off the credit screen. EntryScreen::draw runs the screen scripts before the overlay.
YD_ENTRY_CREDIT_MS = now
end
-- The parent's floor band starts at y=862 (575*1.5) and is drawn AFTER the mode-select /
-- costume menu, so it would cover the arcade costume panel bottom (y<=957) and the
-- えらぶ/決定 drum hint (833..921). Squeeze it to start at y=940 (nameplate / フリープレイ
-- still sit on it). Values are screen px (1080p).
-- The arcade entry screen has no floor band: the nameplate and フリープレイ sit
-- straight on the street background. Nothing to draw.
-- ROUND 6 (2P): the engine has no "two players are in" flag Lua can read (entry.cpp resets
-- global_data.player_num to P1 when the 2nd player joins), but it does pass the two join flags
-- here, and EntryScreen::draw calls draw_footer BEFORE coin_overlay.draw() - so publish them.
function Entry:draw_footer(p1_joined, p2_joined)
YD_ENTRY_BOTH_JOINED = (p1_joined == true and p2_joined == true)
-- ROUND 18: once a seat is in, EntryPlayer's own Indicator draws the guide, so the
-- credit screen must stop drawing its own copy (see draw_control_guide).
self.any_joined = (p1_joined == true or p2_joined == true)
end
@@ -449,19 +242,6 @@ function Entry:draw_player_entry()
self:draw_credit_decide()
end
-- ROUND 11 -- the arcade decide beat. `entry_main.lua` runs CreditWait:Decide(1) ->
-- CreditDecideAction (the row plays `choose`, f125..f149: a white overlay blinking on an
-- 8-frame triangle, peak 205/256) -> CreditWait:Finish() -> `fade_out` (f16..f35) -> only
-- THEN ModeSelectStart. Our engine flips EntryState to SELECT_MODE on the same frame the
-- don lands, so the beat has to be played out from here: draw_player_entry() is called in
-- EVERY entry state (EntryScreen::draw), and the mode boxes stay invisible until each
-- player's cloud animation has finished (~1.2 s), which is longer than the 750 ms this
-- takes. The transition is detected by draw_side_select_buttons() no longer being called
-- (Entry:update bumps cr_frame once per frame).
-- ROUND 12 -- EntryScreen::join_player names the row the cabinet's CreditWait:Decide(playerId)
-- would flash (`credit_wait.tlb` plays `choose` on `text_mc_[playerId]`, i.e. the row of the
-- player who hit -- not always row 1). Called on the frame the seat enters, while the engine
-- is still in SELECT_SIDE, so draw_credit_decide() below picks it up next frame.
function Entry:decide_side_select(side)
self.cr_pending_decide = (side == 2) and 2 or 1
end
+11 -2
View File
@@ -40,6 +40,7 @@ function Indicator:update(current_ms) end
-- song-select keys are set to y=1 (see skin_config), entry/others to y=0.
local SPLIT, DECIDE_END = math.floor(420 / FRAME_STEP), math.floor(650 / FRAME_STEP) -- cells 210..324 = both sticks + 決定
__hss_costume_panel = __hss_costume_panel or {}
__hss_entry_guide = __hss_entry_guide or nil -- { ms, phase = "side" | "mode", count } from the entry scripts
-- ROUND 11 drew the 段位道場 shutter doors from HERE, purely for layering: the
-- indicator was the last skin-owned draw on SONG_SELECT and therefore the only slot
@@ -65,11 +66,19 @@ function Indicator:draw(x, y, fade)
for _, t in pairs(__hss_costume_panel) do
if now - t < 100 then return end
end
-- entry phases (published by entry.lua / entry/box.lua while they draw): TaikoSelect hides
-- the guide, ModeSelect with several boards shows the `all` loop instead of `decide`
local g = __hss_entry_guide
local show_all = false
if g and now - g.ms < 100 then
if g.phase == "side" then return end
show_all = (g.phase == "mode") and (g.count or 1) > 1
end
local elapsed = tex.get_current_ms() - self.t0
local frame
if (y or 0) >= 1 then
if (y or 0) >= 1 or show_all then
frame = math.floor(elapsed / 1000 * ARCADE_FPS / FRAME_STEP) % SPLIT
y = y - 1
if (y or 0) >= 1 then y = y - 1 end
else
local n = DECIDE_END - SPLIT
frame = SPLIT + math.floor(elapsed / 1000 * ARCADE_FPS / FRAME_STEP) % n
+15 -11
View File
@@ -10,7 +10,8 @@ ResultPlayer = {}
ResultPlayer.__index = ResultPlayer
local GAUGE_SCALE = 0.7 -- arcade places tamashii_gage at 0.7 on the result board
local GAUGE_UNIT = 12 * GAUGE_SCALE -- 12 px per YataiDON gauge unit in the plate groove (87 units)
local GAUGE_CELLS = 50 -- the cabinet's gauge is 50 cells (kMaxGage_), like the game HUD
local GAUGE_UNIT = 21 * GAUGE_SCALE -- one 21 px cell of the groove, at the board's 0.7
local OPTION_PITCH = 43
-- ROUND 15 — the whole result sequence is now the cabinet's own state machine, read out of
@@ -37,7 +38,7 @@ local OPTION_PITCH = 43
local F = 1000 / 120 -- ROUND 24 (r24-fpsaudit): Common.FPS is the cabinet's
-- 120 fps script-logic clock, not 60 -- see ENGINE_BINDINGS.md
local WAIT_GAUGE_MS = 100 * F -- 833.3 fade-in done -> the gauge starts filling
local GAUGE_MS_UNIT = 7 * F * (50 / 87) -- 33.53 ms per YataiDON unit == 7 f per arcade unit
local GAUGE_MS_UNIT = 7 * F -- 58.33 ms per cell (kGageSpeed_ = 7 f per arcade unit)
local WAIT_SCORE_MS = 100 * F -- 833.3 gauge full -> StartScoreDisplay
local SCORE_TO_CROWN = 500 * F -- 4166.7 UpdateScore state length
local CROWN_TO_ACTION = 150 * F -- 1250.0 Crown state length -> MoveResultAction
@@ -169,6 +170,9 @@ function ResultPlayer.new(player_num, is_2p, has_2p,
self.is_2p = is_2p
self.has_2p = has_2p
self.gauge_length = gauge_length
-- Fill target in cells: gauge_length is the engine's 87-unit display value
-- (points / max * 87), so cells = points * 50 / max, floored like the HUD gauge.
self.gauge_cells = math.floor(gauge_length * GAUGE_CELLS / 87 + 1e-4)
self.difficulty = difficulty
self.selected_difficulty = selected_difficulty
self.crown_type = crown_type
@@ -214,7 +218,7 @@ function ResultPlayer.new(player_num, is_2p, has_2p,
self.gauge_started = false
self.gauge_start_ms = -1
self.gauge_shown = 0 -- units currently filled (animates up to gauge_length)
self.gauge_shown = 0 -- cells currently filled (animates up to gauge_cells)
self.gauge_done = false
self.score_delay = nil
self.fade_in_started = false -- read by C++: starts the score roll
@@ -349,7 +353,7 @@ function ResultPlayer:update(current_ms, fade_in_finished,
-- isEffectSkip_ (ResultMain): every remaining state collapses at once.
if is_skipped and not self.skipped then
self.skipped = true
self.gauge_shown = math.floor(self.gauge_length)
self.gauge_shown = self.gauge_cells
-- ROUND 52: skip cuts the count-up loop (UpdateTamashiiGage's
-- isEffectSkip branch does TSound:StopSlot, ResultMain.lua:1069) and
-- lands everything on one don_big (ScoreBase UpdateScoreDisplay's
@@ -372,7 +376,7 @@ function ResultPlayer:update(current_ms, fade_in_finished,
if self.gauge_started then
self.tamashii_fire:update(current_ms)
local target = math.floor(self.gauge_length)
local target = self.gauge_cells
-- WaitUpdateTamashiiGage: 100 frames of nothing, then 7 frames per arcade unit
local elapsed = current_ms - self.gauge_start_ms - WAIT_GAUGE_MS
if self.skipped then
@@ -388,7 +392,7 @@ function ResultPlayer:update(current_ms, fade_in_finished,
self.gauge_shown = math.min(target, math.floor(elapsed / GAUGE_MS_UNIT))
-- ROUND 52: the fill reaching the rainbow top plays
-- achieve_tamashii (ResultMain.lua:1086-1088; non-skip path only).
if not self.achieve_played and self.gauge_state == 2 and self.gauge_shown >= 87 then
if not self.achieve_played and self.gauge_state == 2 and self.gauge_shown >= GAUGE_CELLS then
self.achieve_played = true
audio.play_sound("achieve_tamashii" .. self.seat_lr, "sound")
end
@@ -410,7 +414,7 @@ function ResultPlayer:update(current_ms, fade_in_finished,
if audio.stop_sound then audio.stop_sound("count_up_loop" .. self.seat_c) end
end
end
if self.gauge_state == 2 and self.gauge_shown >= 87 then
if self.gauge_state == 2 and self.gauge_shown >= GAUGE_CELLS then
if self.rainbow_start_ms < 0 then self.rainbow_start_ms = current_ms end
self.rainbow_frac = math.fmod((current_ms - self.rainbow_start_ms) / 75.0, 8.0)
end
@@ -618,7 +622,7 @@ function ResultPlayer:draw_gauge()
local gl_int = self.gauge_shown
-- ROUND 48: the clear-zone position follows the norma art tier
-- (hard = normal's segment-35 zone), see the init block above.
local clear_pts = { 52, 60, 69 }
local clear_pts = { 30, 35, 40 } -- easy / normal+hard / oni norma cells
local clear_pt = clear_pts[self.art_index + 1]
local u = GAUGE_UNIT
@@ -626,7 +630,7 @@ function ResultPlayer:draw_gauge()
tex.draw_texture(self.t_gauge_unfilled, { scale = scale, fade = base_fade, index = p_idx })
end
if self.gauge_state == 2 and gl_int >= 87 then
if self.gauge_state == 2 and gl_int >= GAUGE_CELLS then
-- ROUND 53: rainbow cycle sampled from anim/gauge_rainbow (sprite 31): 83.33 ms per
-- step, base cel at 1 with the next fading in over it — the cabinet's own display
-- list, drawn leaf by leaf in depth order. Fallback = pre-R53 75 ms hand cycle.
@@ -692,7 +696,7 @@ function ResultPlayer:draw_gauge()
-- findings stand: the flame holds local (+43,-43) scale **0.800** through the
-- `fever` loop, which is why the drawn scale stays a constant 0.8 here.
local fire_sheen = nil
if self.gauge_state == 2 and gl_int >= 87 and self.t_gauge_tamashii_fire then
if self.gauge_state == 2 and gl_int >= GAUGE_CELLS and self.t_gauge_tamashii_fire then
local ff, fa2, sheen_a = fire_state(self.rainbow_start_ms, tex.get_current_ms())
if ff then
fire_sheen = sheen_a
@@ -708,7 +712,7 @@ function ResultPlayer:draw_gauge()
if self.t_gauge_tamashii then
tex.draw_texture(self.t_gauge_tamashii, { scale = scale, fade = base_fade, index = p_idx })
end
if self.gauge_state == 2 and gl_int >= 87 and self.t_gauge_tamashii_overlay then
if self.gauge_state == 2 and gl_int >= GAUGE_CELLS and self.t_gauge_tamashii_overlay then
if fire_sheen ~= nil then
if fire_sheen > 0.0 then
tex.draw_texture(self.t_gauge_tamashii_overlay,
+140 -22
View File
@@ -361,6 +361,7 @@ function SongSelect:draw_top(dan_progress)
end
function SongSelect:draw_overlays(state)
self:draw_decided_bridge() -- decided genre board while its songs load (defined below)
if _dd_ok then dan_doors.arm(state == STATE_DAN_SELECTED) end
-- number_of_songs plate: arcade song_of_number_instance at stage (1754,270), 280x72 centred.
-- The engine draws its own song_num_bg (made transparent in this skin) and the "N曲目" text
@@ -678,6 +679,7 @@ end
-- Scrolling genre backdrop (enso_normal/song_select/song_select_bg, 2880x1080 per genre)
--------------------------------------------------------------------------------
function SongSelect:draw_background(nav)
self._frame_no = (self._frame_no or 0) + 1
self:refresh_folder_context(nav)
local info = tex.get_texture_info("box", "background")
local width = info.width
@@ -710,13 +712,17 @@ end
-- width -- exactly how the existing `y2 = h - 352` calls already drive the height. So a
-- horizontal scale is `x2 = BOARD_W * (sx - 1)` plus a re-centred x, with no engine
-- change. sx = nil/1 leaves every pre-r61 call byte-identical.
-- A furled board (sx < 1) is not a squashed copy of the 960-wide texture: squashing
-- averages the outline away and makes the GPU pick a small mip level (the LOD follows
-- the larger axis), which blurs every row. The cabinet scales a vector shape, so its
-- edges stay sharp at any width. Five columns get the same result from the bitmap:
-- the two rounded corners at 1:1 (40 px), and the coloured band / inner panel / band
-- between them scaled in proportion, each drawn from an 8 px flat slice of itself and
-- MAGNIFIED to its width. Column layout of every bar_genre frame and the back board:
-- corner 0..40 | band 40..83 | panel 83..877 | band 877..920 | corner 920..960.
local function draw_board(bar_id, frame, bx, by, cen_h, fade, crop_center, sx)
local w = BOARD_W
local x2 = nil
if sx and sx ~= 1.0 then
w = BOARD_W * sx
x2 = w - BOARD_W
end
if sx and sx ~= 1.0 then w = math.max(2, math.floor(BOARD_W * sx + 0.5)) end
local x = math.floor(bx - w / 2 + 0.5)
local top = math.floor(by - cen_h / 2 + 0.5) - CAP_H
local src_y, src_h = CAP_H, CEN_SRC_H
@@ -725,12 +731,53 @@ local function draw_board(bar_id, frame, bx, by, cen_h, fade, crop_center, sx)
src_y = CAP_H + math.floor((CEN_SRC_H - src_h) / 2)
cen_h = src_h
end
tex.draw_texture(bar_id, { frame = frame, x = x, y = top, y2 = CAP_H - 352, x2 = x2, fade = fade,
src = { x = 0, y = 0, width = BOARD_W, height = CAP_H } })
tex.draw_texture(bar_id, { frame = frame, x = x, y = top + CAP_H, y2 = cen_h - 352, x2 = x2, fade = fade,
src = { x = 0, y = src_y, width = BOARD_W, height = src_h } })
tex.draw_texture(bar_id, { frame = frame, x = x, y = top + CAP_H + cen_h, y2 = CAP_H - 352, x2 = x2, fade = fade,
src = { x = 0, y = CAP_H + CEN_SRC_H, width = BOARD_W, height = CAP_H } })
-- the three horizontal bands (top cap / centre / bottom cap) as {y, src_y, src_h, dst_h}
local bands = { { top, 0, CAP_H, CAP_H }, { top + CAP_H, src_y, src_h, cen_h },
{ top + CAP_H + cen_h, CAP_H + CEN_SRC_H, CAP_H, CAP_H } }
if w == BOARD_W then
for _, b in ipairs(bands) do
tex.draw_texture(bar_id, { frame = frame, x = x, y = b[1], y2 = b[4] - 352, fade = fade,
src = { x = 0, y = b[2], width = BOARD_W, height = b[3] } })
end
return
end
local CORNER, BAND, PANEL = 40, 43, 794 -- source widths; 40+43+794+43+40 = 960
local cols
if w >= 2 * CORNER then
local corner = CORNER
local inner = w - 2 * corner
local band = math.floor(inner * BAND / (2 * BAND + PANEL) + 0.5)
local panel = inner - 2 * band
-- columns: {src_x, src_w, dst_x, dst_w}
cols = {
{ 0, CORNER, x, corner },
{ CORNER + BAND / 2 - 4, 8, x + corner, band },
{ BOARD_W / 2 - 4, 8, x + corner + band, panel },
{ BOARD_W - CORNER - BAND / 2 - 4, 8, x + corner + band + panel, band },
{ BOARD_W - CORNER, CORNER, x + w - corner, corner },
}
else
-- narrower than both corners (the last frames of a furl / first of an unfurl): the
-- cabinet's vector shape is a solid bar with its outline all round, so draw the
-- two outline columns (texture x 13..20 / 940..947) at a few px each and fill the
-- rest from the flat centre slice -- squeezing the rounded corners instead left
-- two hollow strokes with nothing between them.
local ol = math.max(2, math.min(8, math.floor(w / 6)))
local mid = math.max(0, w - 2 * ol)
cols = {
{ 13, 8, x, ol },
{ BOARD_W / 2 - 4, 8, x + ol, mid },
{ 940, 8, x + ol + mid, ol },
}
end
for _, b in ipairs(bands) do
for _, c in ipairs(cols) do
if c[4] > 0 then
tex.draw_texture(bar_id, { frame = frame, x = c[3], y = b[1], x2 = c[4] - BOARD_W, y2 = b[4] - 352,
fade = fade, src = { x = c[1], y = b[2], width = c[2], height = b[3] } })
end
end
end
end
-- Yellow cursor glow around the board (arcade cursor_top/center/bottom): the glow's caps
@@ -979,6 +1026,7 @@ local R61 = {
-- clip landmarks (overwritten from the generated table)
open_f0 = 45, open_swap = 114, open_end = 145,
close_f0 = 150, close_swap = 219, close_end = 250,
open_furl = 100, -- first frame the decided genre board furls shut (genre_board_sx < 1)
-- event bookkeeping
seq = nil, -- last Navigator.wheel_event_seq we saw
have_events = false, -- engine actually exposes the r85 channel
@@ -993,6 +1041,12 @@ do
"close_f0", "close_swap", "close_end" }) do
if t[k] then R61[k] = t[k] end
end
local rows = t.tracks and t.tracks.genre_board_sx
if rows then
for i = 1, #rows do
if rows[i][2] < 0.999 then R61.open_furl = rows[i][1]; break end
end
end
end
end
-- Linear sampler over the generated {frame, v1, v2...} rows. Fail-soft: an absent table
@@ -1044,8 +1098,14 @@ local function leg_f()
if R61.disabled or not R61.clip or not R61.t0 then return nil end
local f = R61.f0 + (tex.get_current_ms() - R61.t0) * 0.06
if not R61.swapped then
-- hold one frame short of the swap until the engine says it happened
local hold = (R61.kind == "close") and (R61.close_swap - 1) or (R61.open_swap - 1)
-- hold until the engine says the swap happened. The close leg holds one frame
-- short of its swap; the OPEN leg holds one frame short of the FURL (f99): the
-- cabinet loads a folder inside its 69-frame decide, this engine can take a
-- couple of seconds, and parking on f113 (board already furled away, boxes
-- flown out) left the screen empty for all of that time. Parked on f99 the
-- decided board stays up as the loading state and the furl -> unfurl pair
-- plays back to back once the swap lands (see leg_event).
local hold = (R61.kind == "close") and (R61.close_swap - 1) or (R61.open_furl - 1)
if f > hold then f = hold end
return f
end
@@ -1054,6 +1114,15 @@ local function leg_f()
return f
end
-- The engine's own box fade, except during the pre-swap half of the CLOSE leg: there the
-- engine fades the song boxes and the back board out in 166 ms, while the cabinet keeps
-- them solid until they fly out (f184..204) / the board furls (f205..217) -- those come
-- from the clip channels, so the engine fade is ignored until the swap.
local function box_fade(box)
if R61.kind == "close" and R61.t0 and not R61.swapped then return 1.0 end
return box.fade.attribute
end
-- Start / advance the leg. `begin` puts the clock on the label frame; `swap` re-anchors
-- it on the cabinet's content-swap frame so the post-swap half is phase-exact no matter
-- how long the loader took.
@@ -1061,8 +1130,16 @@ local function leg_event(id)
local now = tex.get_current_ms()
if id == 3 then -- OPEN_BEGIN
R61.t0, R61.f0, R61.kind, R61.swapped = now, R61.open_f0, "open", false
R61.dec_id, R61.dec_box = R61.last_open_id, R61.last_open_box -- the decided board
elseif id == 4 then -- OPEN_SWAP
R61.t0, R61.f0, R61.kind, R61.swapped = now, R61.open_swap, "open", true
-- the clock was parked on open_furl - 1 while the loader ran: resume from the
-- furl so furl (f100..113) and unfurl (f114..) play back to back. A swap that
-- lands before the park point (tiny folder) just lets the clock keep running.
local f = (R61.kind == "open" and R61.t0) and (R61.f0 + (now - R61.t0) * 0.06) or nil
if not f or f >= R61.open_furl - 1 then
R61.t0, R61.f0 = now, R61.open_furl
end
R61.kind, R61.swapped = "open", true
R61.snap_once, R61.snap_ms = true, now -- OpenFolderState ends GotoAndPlay("on")
elseif id == 5 then -- CLOSE_BEGIN
R61.t0, R61.f0, R61.kind, R61.swapped = now, R61.close_f0, "close", false
@@ -1091,8 +1168,17 @@ local _fly_dbg = read_env("YATAIDON_R56_DEBUG") ~= nil -- log sampled offsets (
local function fly_offset(box)
if R56_DISABLED then return 0.0, 0.0 end
local f = leg_f()
if not f or not R61.swapped or R61.kind ~= "open" then return 0.0, 0.0 end
if f >= FLY_END_F then return 0.0, 0.0 end
if not f then return 0.0, 0.0 end
if R61.kind == "open" then
if f >= FLY_END_F then return 0.0, 0.0 end
elseif R61.kind == "close" then
-- the CLOSE leg is the clip's `return` half: the song boxes fly out f184..204,
-- wait off screen across the swap (f219) and the genre boxes fly back in
-- f234..254; f255 (`genre_deceide2`) re-bases the clip, so stop just before it
if f >= (WHEEL_FLY:label("genre_deceide2") or 255) - 1 then return 0.0, 0.0 end
else
return 0.0, 0.0
end
local st = box:draw_state()
if st == "open" or st == "diff_select" then return 0.0, 0.0 end -- the decided board stays
local d = box:box_y() - FLY_CENTER_Y
@@ -1109,6 +1195,25 @@ local function fly_offset(box)
return x - rx, y - ry
end
-- The decided genre board while the loader owns it (see draw_folder_open): drawn here,
-- after the wheel, whenever draw_box did not get to it this frame, until it has furled.
function SongSelect:draw_decided_bridge()
if not R61.dec_box then return end
local lf = (R61.kind == "open") and leg_f() or nil
if lf and lf < R61.open_swap - 1 then
if self._dec_frame ~= self._frame_no then
pcall(self.draw_folder_open, self, R61.dec_box)
end
else
R61.dec_id, R61.dec_box = nil, nil
end
end
-- true while `box` is the genre board the player just decided on (open leg running)
local function is_decided(box)
return R61.kind == "open" and R61.t0 ~= nil and R61.dec_id ~= nil and box_id(box) == R61.dec_id
end
-- ROUND 51: how a FRESH open animation starts is not one-size-fits-all. From the real
-- the reference build song_select_song_main.lua state machine (scratchpad dec/, verified this round):
-- * cursor move Scroll -> Main -> ProcKanbanWaitCountToSelectOn (61-tick hold,
@@ -1348,7 +1453,7 @@ end
function SongSelect:draw_song_board(box, pb, ia, ic)
local bx, by = box:box_x(), box:box_y()
local fdx, fdy = fly_offset(box); bx, by = bx + fdx, by + fdy -- r56 wheel fly-in
local fade = math.min(1.0, box.fade.attribute)
local fade = math.min(1.0, box_fade(box))
-- ROUND 61: the folder-ENTER unfurl. On the frames the cabinet is playing
-- genre_deceide f113..f145 the incoming song board is NOT growing vertically from
@@ -1375,6 +1480,9 @@ function SongSelect:draw_song_board(box, pb, ia, ic)
tostring(box:draw_state()), tostring(box.text_name)))
end)
end
if gof and R61.kind == "open" and gof < R61.open_swap - 1 and box:draw_state() == "open" then
return -- the new content's board does not exist until the swap frame
end
if gof and box:draw_state() == "open" then
local sx, ba = go_get("song_board_sx", gof, 1), go_get("song_board_sx", gof, 2)
if sx and ba then
@@ -2077,7 +2185,7 @@ function SongSelect:draw_folder_board(box, pb, ch_alpha, ch_off, ta, glow_a)
local bx, by = box:box_x(), box:box_y()
local fdx, fdy = fly_offset(box); bx, by = bx + fdx, by + fdy -- r56 wheel fly-in
local cen_h = CEN_CLOSED_H + (CEN_OPEN_H - CEN_CLOSED_H) * pb
local fade = box.fade.attribute
local fade = box_fade(box)
local frame, has_pattern = folder_frame(box)
-- ROUND 85 ---------------------------------------------------------------
@@ -2094,7 +2202,7 @@ function SongSelect:draw_folder_board(box, pb, ch_alpha, ch_off, ta, glow_a)
-- pointing at.
local ltitle = 1.0
if not R61.disabled then
local lf = (box:draw_state() == "open") and leg_f() or nil
local lf = (box:draw_state() == "open" or is_decided(box)) and leg_f() or nil
if lf then
local sx, ba = go_get("genre_board_sx", lf, 1), go_get("genre_board_sx", lf, 2)
if sx and ba then
@@ -2223,6 +2331,15 @@ function SongSelect:draw_folder_closed(box)
end
function SongSelect:draw_folder_open(box)
-- remember the decided board: the engine removes the folder box from the wheel
-- while its songs load, and draw_overlays keeps drawing it from here until it
-- has furled away (the C++ box outlives the wheel slot, so the handle stays valid)
R61.last_open_id, R61.last_open_box = box_id(box), box
if is_decided(box) then
self._dec_frame = self._frame_no
self:draw_folder_board(box, 1.0, 1.0, 440.0, 1.0, 1.0)
return
end
local key = "f\0" .. box_id(box) -- r63: per-BOX, not per-title (see box_id)
local t = wheel_open_t(key)
if t == nil then -- cabinet 508 ms pre-growth hold: fully closed
@@ -2273,7 +2390,7 @@ function SongSelect:draw_back_board(box, p)
local bx, by = box:box_x(), box:box_y()
local fdx, fdy = fly_offset(box); bx, by = bx + fdx, by + fdy -- r56 wheel fly-in
local cen_h = CEN_CLOSED_H + (CEN_OPEN_H - CEN_CLOSED_H) * p
local fade = math.min(1.0, box.fade.attribute)
local fade = math.min(1.0, box_fade(box))
-- ROUND 85: on the cabinet the panel that unfurls across the swap is the
-- newly-focused one (`GetSongKanbanMc(kSelectNumber + openOffset)`). In THIS
@@ -2286,6 +2403,7 @@ function SongSelect:draw_back_board(box, p)
local lta = 1.0
if not R61.disabled then
local lf = (box:draw_state() == "open") and leg_f() or nil
if lf and R61.kind == "open" and lf < R61.open_swap - 1 then return end -- not yet
if lf then
local sx, ba = go_get("song_board_sx", lf, 1), go_get("song_board_sx", lf, 2)
if sx and ba then
@@ -2644,7 +2762,7 @@ function SongSelect:draw_box(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)
if state == "open" or is_decided(box) 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)
@@ -2665,7 +2783,7 @@ function SongSelect:draw_box(box)
p = e and (folder_close_timeline(e)) or 0.0
end
local cen_h = CEN_CLOSED_H + (CEN_OPEN_H - CEN_CLOSED_H) * p
local fade = math.min(1.0, box.fade.attribute)
local fade = math.min(1.0, box_fade(box))
if p > 0 then self:draw_glow(bx, by, cen_h, fade * p * glow_pulse()) end
draw_board((p > 0) and self._id_bar_folder or self._id_bar_genre, 10, bx, by, cen_h, fade, p <= 0 or p >= 1) -- ROUND 5: closed = full pale panel
if p > 0 and p < 1 then draw_board(self._id_bar_genre, 10, bx, by, cen_h, fade * (1.0 - p)) end
+27 -27
View File
@@ -70,7 +70,7 @@ beafcc1a9146a1db31efab49f83fe5c076772e635625f1e562295494ebebe6cf *./Graphics/bac
9cd825ef8c220d21e03ae64a5cc2dafdb16d8e4495fb404af5d705d3569f202c *./Graphics/background/bga_bg_fever_2/s3.png
ef0c3da5d56e528cbb82e597b0e8c2625baa1128ed8447e99e56652d5c2c5e2e *./Graphics/background/bga_bg_fever_2/s5.png
3eaf190b9018644c24b889296aa15268bc4f57827ef597bd4c4331421d04b056 *./Graphics/background/bga_bg_fever_2/s9.png
42692e59d714c56aae4d46fa24dafbb583e3f52c9347b6812761d0c4a999aed7 *./Graphics/background/bga_bg_fever_2/texture.json
8fe3634c792f5e22d301d5775e61243ba4ae1d2e131a77efa6b5cb8d2257e3c0 *./Graphics/background/bga_bg_fever_2/texture.json
a7a94b9ef7b1d47df59851a30f8ff121997ad57f1a9987255549eed285a620a0 *./Graphics/background/bg_fever/bg_fever_0/background.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/background/bg_fever/bg_fever_0/corner.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/background/bg_fever/bg_fever_0/footer.png
@@ -1696,7 +1696,7 @@ e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/ent
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/entry/background/shops_left.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/entry/background/shops_right.png
c66ae3897ad679e05b07c4ba9ab4800f28c9aac7411c6286f1ddb8fae157e75e *./Graphics/entry/background/street_lit.png
671f31ba324eae4b68797ead149b72e691e158492c9541327b07c5fc2727acea *./Graphics/entry/background/texture.json
7bf2b9ac45c4ee6ce5073d910e291eb922174cba954be90696c74fda27317835 *./Graphics/entry/background/texture.json
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/entry/background/tower.png
88d921ef4f651a0660de0289bb6dfe8c0a3d79cbdc0b7eb0662b74d59e8b2156 *./Graphics/entry/background/twinkle/0.png
b89344fe65f113ee23416d253aff7772b5690df8423aeafa35d64962527a5933 *./Graphics/entry/background/twinkle/1.png
@@ -2682,7 +2682,7 @@ d21dc53600bab83b80352bad38cd598d216c6e1279a4d54a0a085ad82ad1430d *./Graphics/res
925c61b2744b0540cea4a0f4124df64bb7cd990a94834ffb219c5f05a2302485 *./Graphics/result/score/score_num.png
684c22481d2a0e4bb2d6dd67b5df87650e081edfeadffcc70c377c393334c06d *./Graphics/result/score/score_shinuchi_en.png
1c160a1a14016ea3a5f761b040db433420476363224011d615613af660e7d0e1 *./Graphics/result/score/score_shinuchi_ja.png
b309049109d5ba5a35a29b06373f13dc93ec8591e93a3267616b7b33e0b8d18e *./Graphics/result/score/texture.json
89c4d6afafb8010ec4da0b9f72f10f677ec8c87677fcb3d2c9edde923a5b5f9f *./Graphics/result/score/texture.json
2e58e24c6920473fcb992280392f418d1d6058b8933a6fdc72ec2e1b986776bd *./Graphics/skin_config.json
0dce4781f045f0cd197797f76f0914af71e748d1cd661b44c760a479fa91a71c *./Graphics/song_select/animation.json
27e427b29774e04dc739b1c58a7205565de88cea6370876b623f8e13a7106b5c *./Graphics/song_select/box/back_graphic.png
@@ -3171,7 +3171,7 @@ e08f82230e9e8f8c00deed9a7d0d0eaba6933021b9960b782a8b77eca3200b06 *./Scripts/anim
eb2bb15e87cc83d66b320e0e4cbcbd2d5385881f36eca27fe73740439055ef6c *./Scripts/anim/sort_cursor.lua
5789c13c7958010f2878f9a0b119a50af4f362e754dc06ca3683ce742d507d25 *./Scripts/anim/title_idle.lua
24e7afe3e93935774c14aebce3e635970ec045952224ea5246633ff05b37e3af *./Scripts/anim/title_idle_map.lua
a340f195886e0e372da2cca847c1a243ed56d76239597c01f6ccdf11d1779759 *./Scripts/anim/wheel_decide.lua
66797bb60d6bacde5d882136a7dee9cda2f3e02282dd2ebaf2ee37346db14f70 *./Scripts/anim/wheel_decide.lua
4e61d41a6f50228b0d320290a99c7f6658843936448c61aff89c5a1e86891121 *./Scripts/background/background.lua
1d35116ef8edb2c9acf9ccc26024e1e788cf3cb010b87a930f1f76108d3c6b69 *./Scripts/background/bg_collabs/a3.lua
784052aa0ba1881415d1468174453cbee33b2cc58c6283b0a53758759a750668 *./Scripts/background/bg_collabs/animal.lua
@@ -3183,14 +3183,14 @@ c519641b04ec00ca74a1d1ce74f5cf81ec52aa5edd52ade83469250079b81147 *./Scripts/back
5c206f19a5da213bb6437eb5806238bef3615da19370843edf83ef3eda1b0877 *./Scripts/background/bg_collabs/oshiri.lua
91295c79c701f668c367fa43da1e6886c7164d6d701d26f32f8368bcab47a8b9 *./Scripts/background/bg_collabs/practice.lua
8e4f5625a08cde1c3d935024193cb44b9227888f3ff345f1e91eef74e2937f23 *./Scripts/background/bg_collabs/tutorial.lua
5fdaf3e32df20ab01f31f1c47248e6e9322b5bb1328684163ebb3333ad3b56b8 *./Scripts/background/bg_data/bg_anim/bg_0.lua
cb9f8b43f330485e3a8a61efe6b466d8c245de21400d5e3f39bd291d7225a29c *./Scripts/background/bg_data/bg_anim/bg_1.lua
b9c69a7db45b7449be537d46d9383785ce391574d0441d31d6771a244f4ff7a3 *./Scripts/background/bg_data/bg_anim/bg_2.lua
57e7cdf3c869bfb62d7063db3fbecf0c47c6de285187d44396ab80c3b2108af6 *./Scripts/background/bg_data/bg_anim/bg_3.lua
e1bfcb2a5782ff5397c2327fa3089aec6ef4cd4188b48ac6cc2b2cc1485bbac0 *./Scripts/background/bg_data/bg_anim/bg_4.lua
2d3b9768a070c23c1eff3d5be95cc74f39b1ac1e0f17ae72118bc80c8c259176 *./Scripts/background/bg_data/bg_anim/bg_fever_0.lua
b7ca6b3ea867ce111b4d6851199942410a0c898260ab61750a0de5ef2e74ce94 *./Scripts/background/bg_data/bg_anim/bg_fever_1.lua
6bf1ff661b31052db9d3bf7be1b91ee255e15c846dffd8597e41aff041f65b22 *./Scripts/background/bg_data/bg_anim/bg_fever_2.lua
4ff647ed2d5e89b4065ea3741c897c4e5f82847803b9716a4c2738d69662f932 *./Scripts/background/bg_data/bg_anim/bg_0.lua
8903b5109295abeafd333618da1a6d8469fccc765528f8df2ecd0a66bbcecc06 *./Scripts/background/bg_data/bg_anim/bg_1.lua
3e59921fa641cdf04b95d7a88069d98bcdcc71fe152157d380fcbca6501da36d *./Scripts/background/bg_data/bg_anim/bg_2.lua
3aee9ee68b0398ae69e094d91b627371c80eb7f192053223000df95ded445fb0 *./Scripts/background/bg_data/bg_anim/bg_3.lua
b3ef868c08d9c0ba0eb21c7540a198ae6f24884cce614d74a63d93aaed70b226 *./Scripts/background/bg_data/bg_anim/bg_4.lua
707b6845d9fb2467a0b2a69ed985c5a40c05178e05a1a8923e3aaa9a90ca9189 *./Scripts/background/bg_data/bg_anim/bg_fever_0.lua
f8a08c701525496d0babe753620675f076a9a2a4a1b08250d27da923164e3b55 *./Scripts/background/bg_data/bg_anim/bg_fever_1.lua
150bdb8d419fd8859f6cf21e7e0bff24488f9fba35bc41b5ad4561814113d9be *./Scripts/background/bg_data/bg_anim/bg_fever_2.lua
2eef6d469e79072285d2e2bef30fda69e30eaefb1d314cf858d948946371fc77 *./Scripts/background/bg_data/bg_fever.lua
41ca8d897d3ad67bc4f56b0807b9527814b135033b6bc0649d38ad55641bd2ad *./Scripts/background/bg_data/donbg_anim/a_01_1p.lua
854d59cdadd48bfba15ce2b99101dbbd7692955cc56d62e789bb4953d39a5a7e *./Scripts/background/bg_data/donbg_anim/a_01_2p.lua
@@ -3208,7 +3208,7 @@ b85248097bf701da651957088fa2944b1bce90d0be89b4ad00c5561a5cbcc284 *./Scripts/back
f1a738f092b1aa4aeb869dd11ec2b3bdf4fe0788f2d1796b622038d1df530ba9 *./Scripts/background/bg_data/fever_anim/f_1.lua
f154e429cb171d7ce72b029a4803ba74051ac23a3d7489f46fdcc45da72462e8 *./Scripts/background/bg_data/fever_anim/f_2.lua
06f2a3bd86d692bf21f143df0bf2f5d5e775c23b903e01de3f7812e4129a9c83 *./Scripts/background/bg_objects/arcade_gauge.lua
735bec40edcaa27036a8b0d83ba34ac57a40ae985bf538edf98d06e95b54c3d7 *./Scripts/background/bg_objects/bg_anim.lua
8c15718242606d122b6f9766c105500b3187f6ab0f4fd01bb84946f77ac39a34 *./Scripts/background/bg_objects/bg_anim.lua
f5f817baee833398cfbb5c0ab8d7e1868474fb94390ce1de2bd7a01c088f4520 *./Scripts/background/bg_objects/bg_fever.lua
a935ef8d768cf09b43b4b20672eb2621d94fe16085798ae25812bd88dddea61b *./Scripts/background/bg_objects/bg_normal.lua
09d76920ca920ef021dd40e06dfa4c9c0e665bf392316a92f2b5855254389ee3 *./Scripts/background/bg_objects/chibi/0.lua
@@ -3232,7 +3232,7 @@ c6dad415f43ae162eeda6ddc6cccafffadb98a842a2a7ad71288502f70d1a8a3 *./Scripts/back
d375fa5fcfd156fd74968b841423fe4618a1b3046d37dacb0b1c3d399dd471f6 *./Scripts/background/bg_objects/donbg/anim_player.lua
0bb1e1b3fd82e6b525dc951313fb4df87aae96cdbb3d9cad175bcbe368e84330 *./Scripts/background/bg_objects/donbg/base.lua
63bd3b3d984c5c970fbe1a3b45aadb0eee6e1409a790889a3585b7e8fda44f4a *./Scripts/background/bg_objects/donbg.lua
a2798341597901c488120539ba791c26bdbec329d5bc8126acbca67a2e2344f2 *./Scripts/background/bg_objects/ending.lua
149dc01c612347cdfcdf439315ef68dfc29faab2ea82453f5590b5583551c0da *./Scripts/background/bg_objects/ending.lua
7421cecba17c2d02d2fa9d80fbdeab1b6235420edcef6ee75bda4fb1797aabb0 *./Scripts/background/bg_objects/enso_skip.lua
78a051013339f7b2376561baa3a5d591e1435446b06721bbc02ac4b02e2ed137 *./Scripts/background/bg_objects/fever_anim.lua
bbc5dd4b156adaf9ee014885090623937935845aea4e356bb19d5b7f85a1a46c *./Scripts/background/bg_objects/fever.lua
@@ -3246,24 +3246,24 @@ f204455c907d3e0e7affb89db3649a709a27d528d84cc58d51a7d8cfaa1d3deb *./Scripts/back
6e2b3c136611c688cdfbe44b0bbcb9d25c2ab647903246b07f2aef9baa6bab0b *./Scripts/background/dancer_data/dancer_4.lua
3a4f1f45bb54c4303dc97afcc6f67df831d6d6011a2264baed3d933c789d210e *./Scripts/background/dancer_data/dancer_5.lua
510225154288da646a6becc9df9f3e2beb00af165815c0e9545a0363dddba589 *./Scripts/dan_select/dan_select.lua
06a8e89044f740783e9ea293c1ebfe5aefe7b68fc34c38d72327e03aea75466f *./Scripts/entry/box.lua
616d72c0192f4a5a0309d4d16d481688a4c6a284faa4866b6e32ffa1608bddad *./Scripts/entry/box.lua
744599a57762ca2a669240caee885431c4216945c05bcd4e85c45850f2e931a3 *./Scripts/entry/costume_menu.lua
8b28e4ba452844cb59b0db4a6b90043a589d944ad458c4788b6cc6d31b9bd4b1 *./Scripts/entry/entry.lua
64771d8bda30f17fa8e01862e722b7398c65d314fa2482adec348074859acf7f *./Scripts/entry/entry.lua
3d8c25402fff69adbfa1f6796807665f6cd61528583d0b7c625e09af752d5160 *./Scripts/entry/player.lua
aae54e0a31c77eac3fbf7e31db7e0136e9b440115ee5433c0b632b9871f13097 *./Scripts/game/clip_player.lua
62fabd365bc0240603bc719f89bf7b42cce8324a810ccc4d63e99a1a0d49b0da *./Scripts/game/ending_anim/ending_clear.lua
3f6f738f19b6475664bdba856711517e3c3a7c868d00184722e30c8222f413b6 *./Scripts/game/ending_anim/ending_donderful.lua
282af6e13da1b6974ec2b746073feee5fab48226d8c8c6e064bec20c6e19b35f *./Scripts/game/ending_anim/ending_fail.lua
4766cb18243dbfa38c3653962a8db4dd17b8724560c15ae9c62b7339266a8507 *./Scripts/game/ending_anim/ending_fullcombo.lua
719b9279ce4787dd3a96dcd80fabe228af814bb5b438f90d8639fd83518ee168 *./Scripts/game/clip_player.lua
5749994b631898c91e246110bb4b5e67aa3fdc395c4d59b49c4ee72a44e0043d *./Scripts/game/ending_anim/ending_clear.lua
33764ed8566bf003802816710a84f7bb01ef7a6ccd549b130d896f20c6e2a3b0 *./Scripts/game/ending_anim/ending_donderful.lua
1e5c509028b1a67acc2e40eed6222b51bc0e87a3d5e7eb8a4e3a3b1da4bc319b *./Scripts/game/ending_anim/ending_fail.lua
88a006d073f226f610f77c9cb45da966532eccdf97454ccf73570f2a73520f43 *./Scripts/game/ending_anim/ending_fullcombo.lua
60aad9f07edee45abb2dca0803acc0f46a519d6a0f6e0c7625b8dd127447cfb9 *./Scripts/game/ending_anim/rank_hud_in.lua
9a55c93ebd302db1bb4c7f55093582a1743ae29b8a34b7544e2e5117f78b865d *./Scripts/game/ending_anim/rank_hud.lua
f4de8faceba1417bbdf0c408275f36b91022c93539178bd2d59018623bac759b *./Scripts/game/ending_anim/rank_hud.lua
826c02cac90412a42722d0fa23e5f08878b00f32ca564607d08bd36fdecc0de4 *./Scripts/game/ending_anim/rank_hud_out.lua
5010747253fcca353b124290d1874b8a1ef5f733b77bd1ada14fd07e0f55e57e *./Scripts/game/ending_anim/rank_result_kiwami.lua
ff7652f6d7bab5ebf7391d360a625a7cfe9a694bc40951aa7a1fa096fa4fe9a6 *./Scripts/game/ending_anim/rank_result.lua
6c885099876d77ea14d4588edb3de5105ecef7f8b83e2787a3bdb25918e5b920 *./Scripts/game/ending_anim/rank_result_kiwami.lua
02a2a424b68fce7b172807ce60df5c2b41121cb65f2edcc5a1e43b77702a4008 *./Scripts/game/ending_anim/rank_result.lua
373351a486510d5dd4c5a3249ad0421a52908ac11a36ae53ae12ed3f6f481793 *./Scripts/global/allnet_indicator.lua
690e4e84a519bc3cdc39286a433b2dbc500834022a2b8bffa7b3513156d087ca *./Scripts/global/coin_overlay.lua
1eaebfd5dc7ec74571c9872d1817cd51e360db5c02cad6bf49d3c851ef9b70dc *./Scripts/global/entry_overlay.lua
4d4d092391f7c74f270066927d84203a7b5b0011bab3db90276b2b80cba35601 *./Scripts/global/indicator.lua
bc6dea42b2183980e1112d815106b357876c18590daa831a48a113eea99c6815 *./Scripts/global/indicator.lua
ab7af813fb8d836fb6490554e11b374beb0ea1af0346ecadc3431498e91e5e02 *./Scripts/global/nameplate.lua
6b3cbc22709edf45514674830e1eb5831a6e45bb7f3b6b030a1ecda94beb5185 *./Scripts/global/result_transition.lua
cce16946fc792a3412c248d059ce4387f482f969e72e787e4770c20116c0e682 *./Scripts/global/timer.lua
@@ -3272,12 +3272,12 @@ bcd31928563102097ed1b2610f097dff26983f7209822b6a7294daa14e68d08a *./Scripts/resu
c5762b46c786d95cead9d69fda59cba844b0ebb007aca1b00fbad14a6a93d362 *./Scripts/result/high_score_indicator.lua
2a60a921314965c89ee2cdb29928955aca59c18bb691eae8f0ceceb28bed5d9d *./Scripts/result/result_background.lua
bae62b0f451139b880d57d4b214156a8deaadedb2aacc1f7421d4e21189a810d *./Scripts/result/result_bg_layers.lua
8cc680fde26a887539c6335bbf29a4ea2f96ef95164ec84580ed821f6b2355e5 *./Scripts/result/result_crown.lua
141a453f447f176f13f6c35f20335261d98f78ec97671e9bdb54cd5deece802c *./Scripts/result/result_crown.lua
18d140a70c3816578d523913b60155ea208ff91a67ded089b75ad401bd5cb625 *./Scripts/result/result_crown_message.lua
fe5bc0a6cff271012d0de9ec7fc5cc7a94b3f1268ea1aa4a18e72c38b1a0e6c3 *./Scripts/result/result_fade_in.lua
9447dea62976348429b38b22104c68708b21cfbbf61f5d37a5a8d082d69f7a1c *./Scripts/result/result_player.lua
1033652c20bd62a07f645c94961227dfe73fb49df9bc581c460739c96c109c08 *./Scripts/song_select/dan_doors.lua
d3af610009783a9cf6e044dfcee396ea7f0ee90cd059fc44feb98e6935a5afff *./Scripts/song_select/song_select.lua
093ad96b9aebc98e6b1fb2ce8f8f3f9e9ab4e0f24f7328e6eb831d8c5e90c87e *./Scripts/song_select/song_select.lua
89047ab5b642696922ca2c6e098ca288580a9c0bb3e197a08f17b821a31fc519 *./.skin-repo
40c378cdcaea2e2c9ec3da4c7fa72911d13a849a5b51e9645300f9571a7e12c8 *./Sounds/dan_result/achieve_tamashii.ogg
606f2d3558badc06e54b2c59a36f0580f4954774918d69a712ad6de45518cba0 *./Sounds/dan_result/advance_intro.ogg