News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Resuming Arkos Tracker 2 subsong

Started by Anthony Flack, 23:19, 15 October 23

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Anthony Flack

After messing around with some YM code on my own, enough to satisfy my curiosity (ugh, passing values to the YM is slow) I checked out AT2 and yeah, it's all there isn't it. So I got all my music and sound effects done in a weekend. Ok, that was really easy. 

I just have one thing I need to do for it to be perfect. I need to be able to stop a subsong, play another subsong, and then resume the first subsong from where it left off (rather than start again from the beginning). Presumably it's just a matter of storing some values.

 


Prodatron


Indeed that will require a function which is freezing the current state, so that you can restore it later. I thought about the same already.
My plan is to go through the init routine were tons of variables are reset, and use this as a reference what has to be saved.
Not sure if I have time for this during next two days, please tell me if you are already faster :)

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

Targhan

There are ways, but not built-in indeed.
  • Storing the various pointers isn't quite easy but there is probably no need to be very thorough. You could only save the main ones (where you are in the linker, the pointers at each track, the one on each instrument, plus the PSG registers).
  • A simple brute-force trick I used in Orion Prime is to count how many frames of each song has passed (don't forget to reset it when the song loops!). Then when wanting to resume, bypass the PSG output code, and play the song X times :). Raw but actually works pretty fine, and costs only a few bytes!
  • The ROM player is a bit slower, but as it doesn't automodify itself, all the data is in a single buffer of 250-ish bytes. You could save it and restore it at will.
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

Anthony Flack

Thanks for the quick response; very much appreciated. 

Because this happens during gameplay I'm looking for the fastest solution, although calling the player until it reaches the right spot does sound nice and simple, ideally I'd like to get there with the least amount of CPU time. 

So I was hoping to force-feed in the minimum number of pointers that it would need to straighten itself out (option 1). The subsong I'm jumping out of will have already finished so the player will be in a known state when I start. Resuming from the start of the chunk would also be fine.

Prodatron

I was just hacking this in:

PLY_AKG_MUSICSTATE_TAB
dw PLY_AKG_ARPEGGIOSTABLE+1:                    db 2
dw PLY_AKG_PITCHESTABLE+1:                      db 2
dw PLY_AKG_INSTRUMENTSTABLE+1:                  db 2
dw PLY_AKG_CHANNEL_READEFFECTS_EFFECTBLOCKS1+1: db 2
dw PLY_AKG_CHANNEL_READEFFECTS_EFFECTBLOCKS2+1: db 2
dw PLY_AKG_CHANNEL3_READCELLEND+1:              db 1
dw PLY_AKG_CHANNEL1_NOTE+1:                    db 1
dw PLY_AKG_READLINKER+1:                        db 2
dw PLY_AKG_PSGREG13_OLDVALUE+1:                db 1
dw PLY_AKG_ENDWITHOUTLOOP+1:                    db 2
dw PLY_AKG_CHANNEL1_PTINSTRUMENT+1:            db 2
dw PLY_AKG_CHANNEL2_PTINSTRUMENT+1:            db 2
dw PLY_AKG_CHANNEL3_PTINSTRUMENT+1:            db 2
dw PLY_AKG_CHANNEL1_SOUNDEFFECTDATA:            db 2
dw PLY_AKG_CHANNEL2_SOUNDEFFECTDATA:            db 2
dw PLY_AKG_CHANNEL3_SOUNDEFFECTDATA:            db 2
PLY_AKG_MUSICSTATE_TAB_END


;### Saves the current (sub)song state
;### Input      DE=state memory (83 bytes)

PLY_AKG_STATE_SAVE
    ld ix,PLY_AKG_MUSICSTATE_TAB
    ld iyl,16      ;(PLY_AKG_MUSICSTATE_TAB_END-PLY_AKG_MUSICSTATE_TAB)/3
    ld b,0
PLY_AKG_STATE_SAVE_LOOP1
    ld l,(ix+0)
    ld h,(ix+1)
    ld c,(iy+2)
    ldir
    ld c,3
    add ix,bc
    dec iyl
    jr nz,PLY_AKG_STATE_SAVE_LOOP1

    ld ix,PLY_AKG_INITTABLE0
    ld iyl,27      ;(PLY_AKG_INITTABLEORA_END-PLY_AKG_INITTABLE0)/2
PLY_AKG_STATE_SAVE_LOOP2
    ld l,(ix+0)
    ld h,(ix+1)
    ld c,4
    ldi
    ldi
    add ix,bc
    dec iyl
    jr nz,PLY_AKG_STATE_SAVE_LOOP2
    ret


;### Loads a (sub)song state
;### Input      HL=state memory (83 bytes)

PLY_AKG_STATE_LOAD
    ld ix,PLY_AKG_MUSICSTATE_TAB
    ld iyl,16      ;(PLY_AKG_MUSICSTATE_TAB_END-PLY_AKG_MUSICSTATE_TAB)/3
    ld b,0
PLY_AKG_STATE_LOAD_LOOP1
    ld e,(ix+0)
    ld d,(ix+1)
    ld c,(iy+2)
    ldir
    ld c,3
    add ix,bc
    dec iyl
    jr nz,PLY_AKG_STATE_LOAD_LOOP1

    ld ix,PLY_AKG_INITTABLE0
    ld iyl,27      ;(PLY_AKG_INITTABLEORA_END-PLY_AKG_INITTABLE0)/2
PLY_AKG_STATE_LOAD_LOOP2
    ld e,(ix+0)
    ld d,(ix+1)
    ld c,4
    ldi
    ldi
    add ix,bc
    dec iyl
    jr nz,PLY_AKG_STATE_LOAD_LOOP2
    ret

I didn't test it yet, so no idea if this will work.
But you should get the idea, all these are the vars, which are set in the PLY_AKG_INIT routine.
Storing/restoring the PSG registers is not included yet.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

Prodatron

sorry...

ld c,(iy+2)
should be...

ld c,(ix+2)
however still not tested...

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

Anthony Flack

I'll have to shuffle some memory before I can try this on the game as the memory bank the music lives in is very snug right now. I'll get stuck in sometime over the next couple of weekends, cheers.

Powered by SMFPacks Menu Editor Mod