Skip to content

Commit 64ae08f

Browse files
committed
fix: continue screen end sequence and music
Fixes #2966
1 parent ed18070 commit 64ae08f

4 files changed

Lines changed: 118 additions & 18 deletions

File tree

src/iniutils.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,36 @@ func (h *BgmProperties) maxSize() int {
25892589
return maxLen
25902590
}
25912591

2592+
// Split a [Music] key into (prefix, property) while allowing dots in prefix.
2593+
func splitMusicKey(rawKey string) (prefix string, property string) {
2594+
k := strings.TrimSpace(rawKey)
2595+
if k == "" {
2596+
return "", ""
2597+
}
2598+
kl := strings.ToLower(k)
2599+
2600+
// Find the last occurrence of a known music anchor so that prefixes can contain dots.
2601+
anchors := []string{".bgmusic", ".music", ".bgm"}
2602+
best := -1
2603+
for _, a := range anchors {
2604+
if i := strings.LastIndex(kl, a); i > best {
2605+
best = i
2606+
}
2607+
}
2608+
2609+
if best >= 0 {
2610+
prefix = strings.TrimSpace(k[:best])
2611+
property = strings.TrimSpace(kl[best+1:]) // without leading dot
2612+
return prefix, property
2613+
}
2614+
2615+
// Fallback
2616+
if dotIdx := strings.Index(k, "."); dotIdx >= 0 {
2617+
return strings.TrimSpace(k[:dotIdx]), strings.TrimSpace(strings.ToLower(k[dotIdx+1:]))
2618+
}
2619+
return "", strings.ToLower(k)
2620+
}
2621+
25922622
func parseMusicSection(section *ini.Section) Music {
25932623
// If section is nil, just return empty Music
25942624
if section == nil {
@@ -2615,16 +2645,12 @@ func parseMusicSection(section *ini.Section) Music {
26152645
continue
26162646
}
26172647

2618-
// Split into prefix and property
2619-
prefix := ""
2620-
property := rawKey
2621-
if dotIdx := strings.Index(rawKey, "."); dotIdx >= 0 {
2622-
prefix = strings.ToLower(rawKey[:dotIdx])
2623-
property = strings.ToLower(rawKey[dotIdx+1:])
2624-
} else {
2625-
// entire rawKey is the property
2626-
property = strings.ToLower(rawKey)
2627-
}
2648+
// Split into prefix and property, allowing dots inside prefix.
2649+
prefixRaw, property := splitMusicKey(rawKey)
2650+
2651+
// Normalize prefix: lower-case + flatten dots to underscores
2652+
prefix := strings.ToLower(prefixRaw)
2653+
prefix = strings.ReplaceAll(prefix, ".", "_")
26282654

26292655
// Split comma-separated values
26302656
values := strings.Split(rawVal, ",")

src/motif.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,6 +3023,7 @@ type MotifContinue struct {
30233023
initialized bool
30243024
counter int32
30253025
endTimer int32
3026+
showEndAnim bool
30263027
credits int32
30273028
yesSide bool
30283029
selected bool
@@ -3037,6 +3038,7 @@ func (co *MotifContinue) reset(m *Motif) {
30373038
co.yesSide = true
30383039
co.selected = false
30393040
co.endTimer = -1
3041+
co.showEndAnim = false
30403042
sys.applyFightAspect()
30413043
}
30423044

@@ -3105,6 +3107,7 @@ func (co *MotifContinue) init(m *Motif) {
31053107
co.counter = 0
31063108
co.active = true
31073109
co.initialized = true
3110+
co.showEndAnim = false
31083111
}
31093112

31103113
func (co *MotifContinue) processSelection(m *Motif, continueSelected bool) {
@@ -3168,8 +3171,21 @@ func (co *MotifContinue) step(m *Motif) {
31683171
}
31693172
}
31703173

3171-
if !co.selected {
3174+
// Keep the counter anim running while showing the integrated end/gameover tail.
3175+
if !co.selected || co.showEndAnim {
31723176
m.ContinueScreen.Counter.AnimData.Update()
3177+
}
3178+
3179+
// If we're showing the integrated end/gameover tail (gameover.enabled = 0),
3180+
// defer fadeout until the counter animation reaches endtime.
3181+
if co.selected && co.showEndAnim && co.endTimer == -1 &&
3182+
m.ContinueScreen.Counter.EndTime > 0 &&
3183+
co.counter >= m.ContinueScreen.Counter.EndTime {
3184+
startFadeOut(m.ContinueScreen.FadeOut.FadeData, m.fadeOut, false, m.fadePolicy)
3185+
co.endTimer = co.counter + m.fadeOut.timeRemaining
3186+
}
3187+
3188+
if !co.selected {
31733189
if m.ContinueScreen.LegacyMode.Enabled {
31743190
if m.button(m.ContinueScreen.Move.Key, co.pn-1) {
31753191
m.Snd.play(m.ContinueScreen.Move.Snd, 100, 0, 0, 0, 0)
@@ -3190,7 +3206,23 @@ func (co *MotifContinue) step(m *Motif) {
31903206
co.playCounterSounds(m)
31913207
} else if co.counter == m.ContinueScreen.Counter.End.SkipTime {
31923208
m.Snd.play(m.ContinueScreen.Counter.End.Snd, 100, 0, 0, 0, 0)
3193-
co.processSelection(m, false)
3209+
m.Music.Play("continue.end", sys.motif.Def)
3210+
// If separate gameover screen is disabled, the end/gameover portion is integrated into the same counter animation.
3211+
// Let it play to endtime, then fade out.
3212+
if !m.ContinueScreen.GameOver.Enabled {
3213+
cs := m.ContinueScreen
3214+
m.processStateTransitions(
3215+
cs.P2.No.State,
3216+
cs.P2.Teammate.No.State,
3217+
cs.P1.No.State,
3218+
cs.P1.Teammate.No.State,
3219+
)
3220+
co.selected = true
3221+
co.showEndAnim = true
3222+
// fadeout will be started when counter reaches Counter.EndTime
3223+
} else {
3224+
co.processSelection(m, false)
3225+
}
31943226
}
31953227
}
31963228
}
@@ -3234,7 +3266,7 @@ func (co *MotifContinue) draw(m *Motif, layerno int16) {
32343266
// Mugen style
32353267
if m.ContinueScreen.LegacyMode.Enabled {
32363268
co.drawLegacyMode(m, layerno)
3237-
} else if !co.selected {
3269+
} else if !co.selected || co.showEndAnim {
32383270
// Arcade style Counter
32393271
m.ContinueScreen.Counter.AnimData.Draw(layerno)
32403272
}

src/music.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ func (m Music) Override(other Music) {
180180
}
181181
}
182182

183+
// flattens dotted prefixes to underscore form, matching parseMusicSection.
184+
func normalizeMusicPrefix(prefix string) string {
185+
return strings.ReplaceAll(prefix, ".", "_")
186+
}
187+
183188
// AppendParams parses comma-separated "key=value" pairs (as passed from
184189
// Lua addChar/addStage/loadStart) and appends to the proper prefix list.
185190
func (m Music) AppendParams(entries []string) {
@@ -190,10 +195,27 @@ func (m Music) AppendParams(entries []string) {
190195
value := strings.TrimSpace(c[eqPos+1:])
191196
prefix := ""
192197
field := key
193-
if dotPos := strings.Index(key, "."); dotPos != -1 {
198+
199+
// Allow dots in prefix: split using the last ".<music anchor>" if present,
200+
// otherwise fall back to last dot.
201+
kl := strings.ToLower(key)
202+
anchors := []string{".bgmusic", ".music", ".bgm"}
203+
best := -1
204+
for _, a := range anchors {
205+
if i := strings.LastIndex(kl, a); i > best {
206+
best = i
207+
}
208+
}
209+
if best >= 0 {
210+
prefix = strings.TrimSpace(key[:best])
211+
field = strings.TrimSpace(key[best+1:]) // without leading dot
212+
} else if dotPos := strings.LastIndex(key, "."); dotPos != -1 {
194213
prefix = key[:dotPos]
195214
field = key[dotPos+1:]
196215
}
216+
217+
// Flatten dotted prefixes to match storage in parseMusicSection.
218+
prefix = normalizeMusicPrefix(prefix)
197219
//fmt.Printf("[music] AppendParams: normalized key='%s' -> prefix='%s', field='%s', value='%s'\n", key, prefix, field, value)
198220

199221
// Ignore non-music fields
@@ -261,10 +283,20 @@ func (m Music) Read(key, def string) (string, int, int, int, int, int, float32,
261283
var loop, volume, loopstart, loopend, startposition, loopcount int = 1, 100, 0, 0, 0, -1
262284
var freqmul float32 = 1.0
263285
//fmt.Printf("[music] Read: key='%s' def='%s'\n", key, def)
286+
// Support dotted prefixes by only stripping a suffix when the key actually targets a music field.
264287
prefix := key
265-
if dotPos := strings.Index(key, "."); dotPos != -1 {
266-
prefix = key[:dotPos]
288+
kl := strings.ToLower(key)
289+
anchors := []string{".bgmusic", ".music", ".bgm"}
290+
best := -1
291+
for _, a := range anchors {
292+
if i := strings.LastIndex(kl, a); i > best {
293+
best = i
294+
}
295+
}
296+
if best >= 0 {
297+
prefix = key[:best]
267298
}
299+
prefix = normalizeMusicPrefix(prefix)
268300
if len(m[prefix]) > 0 {
269301
idx := int(RandI(0, int32(len(m[prefix]))-1))
270302
bgm = SearchFile(m[prefix][idx].bgmusic, []string{def, "", "sound/"})
@@ -314,7 +346,8 @@ func (m Music) tryPlay(key, def string) bool {
314346
//if dot := strings.Index(key, "."); dot != -1 {
315347
// key = key[:dot]
316348
//}
317-
lst, ok := m[key]
349+
nkey := normalizeMusicPrefix(key)
350+
lst, ok := m[nkey]
318351
if !ok || len(lst) == 0 {
319352
//fmt.Printf("[music] tryPlay: prefix '%s' not found or empty\n", key)
320353
return false
@@ -331,7 +364,7 @@ func (m Music) tryPlay(key, def string) bool {
331364
//fmt.Printf("[music] tryPlay: prefix '%s' has no defined bgmusic entries\n", key)
332365
return false
333366
}
334-
ok = m.Play(key+".bgmusic", def)
367+
ok = m.Play(nkey+".bgmusic", def)
335368
//fmt.Printf("[music] tryPlay: Play('%s.bgmusic') -> %v\n", key, ok)
336369
return ok
337370
}

src/resources/defaultMotif.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,15 @@
168168
continue.bgm.freqmul = 1.0
169169
continue.bgm.loopcount = -1
170170

171+
continue.end.bgm =
172+
continue.end.bgm.loop = 1
173+
continue.end.bgm.volume = 100
174+
continue.end.bgm.loopstart = 0
175+
continue.end.bgm.loopend = 0
176+
continue.end.bgm.startposition = 0
177+
continue.end.bgm.freqmul = 1.0
178+
continue.end.bgm.loopcount = -1
179+
171180
results.bgm =
172181
results.bgm.loop = 1
173182
results.bgm.volume = 100

0 commit comments

Comments
 (0)