Author Topic: SPC event hacking  (Read 1949 times)

Myria

  • Iokan (+1)
  • *
  • Posts: 15
    • View Profile
Re: SPC event hacking
« Reply #15 on: October 14, 2007, 10:38:00 pm »
If the FF6 format is similar and known, you could dump Frog's note data and see whether there are any unused segments...

Zakyrus

  • Entity
  • Magical Dreamer (+1250)
  • *
  • Posts: 1345
  • "Bouncy, bouncy, bouncy... --!!"
    • View Profile
Re: SPC event hacking
« Reply #16 on: October 17, 2007, 12:02:43 am »
I'm not going to pretend to understand any of this, but keep up the excellent work everyone!  8)
Looks to me like you're all doing a great job!

ZeaLitY

  • Entity
  • End of Timer (+10000)
  • *
  • Posts: 10797
  • Spring Breeze Dancin'
    • View Profile
    • My Compendium Staff Profile
Re: SPC event hacking
« Reply #17 on: October 30, 2007, 01:25:24 am »
Forgot to post Myria's notes on unlocking ripped SPCs of 02 Chrono Trigger and 22 The Hidden Truth:

Quote
If you want to change the loop count on either one to 2 instead of 3, open
the .spc file in a hex editor.  Go to byte 0xFAE.

- For song 02, change that byte from 18 to 0C.
- For song 22, change that byte from 20 to 10.

I changed both songs' lengths to 3:55 since that was long enough for me to
work with.  I don't know how to mess with ID666 tags other than that.
You'll want to change those =)  Also, your song collection's 02a file has an
ID666 tag that calls the song "Part Two" even though it's part 1.  My hacked
version says that as well because your 02a was my base.

In final Chrono Trigger songs, the "event enable" variable is at address
00D2 (SPC file address 01D2).  Set this to 01 and the event will execute
next loop.  00D2 is set by command 88 from the game.  The difficult part of
my hack is waiting X number of loops before setting that flag.  I think the
event flag in the prerelease was 00D0 (file 01D0).

The D2 flag is read in two locations:

1d05: MOVZ A,$d2
1d07: CMPZ A,$a5

1d2e: MOVZ A,$d2
1d30: CMPZ A,$a5

I couldn't figure out the meaning of A5 - it could be some kind of measure
counter.  Each of these functions appears to be called for each channel,
with X equalling the channel number times 2.  They can also be called
multiple times on a channel during playback.  However, these functions are
only called when the song is about to go a different direction with the
event flag.

My solution is to count how many times these functions are called then set
the event flag.  12 (0C) and 16 (10) were experimentally determined with
those songs.

At 1D05 and 1D2E, I replaced those opcodes with "nop" followed by "call
$0EAB".  0EAA is the handler for game command 87 (change song pitch).  I
overwrite this function with my code; I chose this location because I know
what it's for and know it's unused (for SPC playback anyway).  At 0EAA I put
a "ret" so that calling it would do nothing, but it really doesn't get
called.  I then started my code at 0EAB.

This is my replacement assembly code:

        0EAB:
E8 00      mov a, #$00
68 02      cmp a, #$02
90 06      bcc normal
E8 01      mov a, #$01
C4 D2      movz $d2, a
2F 03      bra skip_inc
        normal:
AC AC 0E   inc $0eab+1  ; 00 in mov instruction
        skip_inc:
E4 D2      movz a, $d2   ; replaced code
64 A5      cmpz a, $a5
6F         ret


I used self-modifying code since it was simpler.  I'm not good at SPC700 =)