Users browsing this thread: 1 Guest(s)
MSU-1 Hacks
Recently a Chrono Trigger and Secret of Mana MSU-1 hacks have been released. Another guy is also working on a similar hack for FF3us, but he ran into some problems when modifying the NMI routine to fade out tracks, resulting in graphical glitches.
I'm only making this post for those who would be interested in attempting this for FF3us and the two source code could help maybe. I might do a MSU-1 version of my hack but that would means this version could only be played on Higan/bsnes and on a SD2SNES cartridge.
Here's the code for both hacks:
Secret of Mana
Chrono Trigger
I'm only making this post for those who would be interested in attempting this for FF3us and the two source code could help maybe. I might do a MSU-1 version of my hack but that would means this version could only be played on Higan/bsnes and on a SD2SNES cartridge.
Here's the code for both hacks:
Secret of Mana
Code:
arch snes.cpu
// MSU memory map I/O
constant MSU_STATUS($002000)
constant MSU_ID($002002)
constant MSU_AUDIO_TRACK_LO($002004)
constant MSU_AUDIO_TRACK_HI($002005)
constant MSU_AUDIO_VOLUME($002006)
constant MSU_AUDIO_CONTROL($002007)
// SPC communication ports
constant SPC_COMM_0($2140)
constant SPC_COMM_1($2141)
constant SPC_COMM_2($2142)
constant SPC_COMM_3($2143)
// MSU_STATUS possible values
constant MSU_STATUS_TRACK_MISSING($8)
constant MSU_STATUS_AUDIO_PLAYING(%00010000)
constant MSU_STATUS_AUDIO_REPEAT(%00100000)
constant MSU_STATUS_AUDIO_BUSY($40)
constant MSU_STATUS_DATA_BUSY(%10000000)
// SNES Multiply register
constant SNES_MUL_OPERAND_A($004202)
constant SNES_MUL_OPERAND_B($004203)
constant SNES_DIV_DIVIDEND_L($004204)
constant SNES_DIV_DIVIDEND_H($004205)
constant SNES_DIV_DIVISOR($004206)
constant SNES_DIV_QUOTIENT_L($004214)
constant SNES_DIV_QUOTIENT_H($004215)
constant SNES_MUL_DIV_RESULT_L($004216)
constant SNES_MUL_DIV_RESULT_H($004217)
// Constants
if {defined EMULATOR_VOLUME} {
constant FULL_VOLUME($60)
} else {
constant FULL_VOLUME($FF)
}
// Game variables
variable MusicCommand($7E1E00)
variable RequestedSong($7E1E01)
variable PreviousSong($7E1E05)
// My variables
variable FadeState($7E1EDD)
variable FadeVolume($7E1EDE)
variable FadeStep($7E1EE0)
variable FadeTemp($7E1EE2)
variable FadeCount($7E1EE4)
variable FrameCount($7E1EE5)
// **********
// * Macros *
// **********
// seek converts SNES HiROM address to physical address
macro seek(variable offset) {
origin (offset & $3FFFFF)
base offset
}
macro CheckMSUPresence(labelToJump) {
lda MSU_ID
cmp.b #'S'
bne {labelToJump}
}
macro WaitMulResult() {
nop
nop
nop
nop
}
macro WaitDivResult() {
nop
nop
nop
nop
nop
nop
nop
nop
}
// ********
// * Code *
// ********
seek($008008)
jml Reset_Hijack
// Override NMI vector to call a custom RAM address
// with my hijack
seek($C0FFEA)
db $22,$01
seek($C30004)
jmp MSU_Hijack
seek($C324C0)
MSU_Hijack:
jsl MSU_Main
bcc ReturnToCode
jmp $0160
ReturnToCode:
rtl
// MSU code
seek($CB3400)
scope MSU_Main: {
php
rep #$30
pha
phx
phy
sep #$20
CheckMSUPresence(OriginalCode)
lda MusicCommand
beq DoNothing
cmp #$01
bne +;
stz MusicCommand
jsr MSU_PlayMusic
bcs OriginalCode
bcc DoNothing
+;
cmp #$80
bne +;
stz MusicCommand
jsr MSU_Fade
bra OriginalCode
+;
cmp #$F1
bne +;
stz MusicCommand
jsr MSU_Stop
+;
OriginalCode:
rep #$30
ply
plx
pla
plp
sec
rtl
DoNothing:
rep #$30
ply
plx
pla
plp
clc
rtl
}
scope MSU_PlayMusic: {
// Check if the song is already playing
xba
lda $7E1E02
and #$0F
pha
lda RequestedSong
pha
plx
cpx PreviousSong
beq Exit
// Current current SPC song playing, if any
jsr Stop_SPC
// Set MSU-1 track
lda RequestedSong
sta MSU_AUDIO_TRACK_LO
lda.b #$00
sta MSU_AUDIO_TRACK_HI
IsMSUReady:
lda MSU_STATUS
and.b #MSU_STATUS_AUDIO_BUSY
bne IsMSUReady
// Check if the track is missing
lda MSU_STATUS
and.b #MSU_STATUS_TRACK_MISSING
bne TrackMissing
// Play the song and add repeat if needed
lda RequestedSong
jsr TrackNeedLooping
sta MSU_AUDIO_CONTROL
// Set volume
lda.b #FULL_VOLUME
sta MSU_AUDIO_VOLUME
sta FadeVolume+1
// Set previous song for game
lda RequestedSong
sta PreviousSong
lda $7E1E02
and #$0F
sta $7E1E06
lda $7E1E03
sta $7E1E07
Exit:
clc
rts
TrackMissing:
lda.b #$01
sta MusicCommand
lda.b #$00
sta MSU_AUDIO_VOLUME
sec
rts
}
scope TrackNeedLooping: {
// $17 / 23 = Victory ! (Jingle)
cmp.b #$17
beq noLooping
// $19 Cannon Travel Lunch (SFX)
cmp.b #$19
beq noLooping
// $1A Cannon Travel (SFX)
cmp.b #$1A
beq noLooping
// $1E New Contient Rises (SFX)
cmp.b #$1E
beq noLooping
// $21 Unused Jingle 1
cmp.b #$21
beq noLooping
// $22 Midge Mallet (SFX)
cmp.b #$22
beq noLooping
// $23 Unknown Jingle 2
cmp.b #$23
beq noLooping
// $28 Flammie Coming (SFX)
cmp.b #$28
beq noLooping
// $2D Mysterious Moaning
cmp.b #$2D
beq noLooping
// $2E Mara's Key (Jingle)
cmp.b #$2E
beq noLooping
// $2F Got an Item (Jingle)
cmp.b #$2F
beq noLooping
// $30 Elemental Acquired (Jingle)
cmp.b #$30
beq noLooping
// $35 Ally Joins (Jingle)
cmp.b #$35
beq noLooping
// Track loops
lda.b #$03
rts
noLooping:
lda #$01
rts
}
scope MSU_Fade: {
lda RequestedSong
sta FadeCount
and #$0F
sta SNES_MUL_OPERAND_A
lda FadeCount
and #$F0
sta FadeCount
lda #$11
sta SNES_MUL_OPERAND_B
WaitMulResult()
lda FadeCount
bne +;
sta FadeStep
jmp Exit
+;
lda SNES_MUL_DIV_RESULT_L
sec
sbc FadeVolume+1
bcs +;
eor #$FF
inc
+;
sta SNES_DIV_DIVIDEND_L
lda #$00
sta SNES_DIV_DIVIDEND_H
lda FadeCount
sta SNES_DIV_DIVISOR
WaitDivResult()
lda SNES_DIV_QUOTIENT_L
sta FadeTemp+1
lda #$00
sta SNES_DIV_DIVIDEND_L
lda SNES_MUL_DIV_RESULT_L
sta SNES_DIV_DIVIDEND_H
lda FadeCount
sta SNES_DIV_DIVISOR
WaitDivResult()
lda SNES_DIV_QUOTIENT_L
sta FadeTemp
bcs +;
rep #$20
lda FadeTemp
eor #$FFFF
inc
sta FadeTemp
sep #$20
+;
rep #$20
lda FadeTemp
sta FadeStep
sep #$20
lda #$00
sta FadeVolume
lda #$01
sta FadeState
Exit:
rts
}
scope MSU_Stop: {
lda #$00
sta MSU_AUDIO_CONTROL
rts
}
scope Stop_SPC: {
// Stop SPC music
lda #$F1
sta SPC_COMM_0
Handshake:
cmp SPC_COMM_0
bne Handshake
lda #$00
sta SPC_COMM_0
// Stop looping SFX
lda #$F2
sta SPC_COMM_0
Handshake2:
cmp SPC_COMM_0
bne Handshake2
lda #$00
sta SPC_COMM_0
rts
}
// NMI & Reset hijack code
scope Reset_Hijack: {
lda #$FF
sta FadeVolume
sta FadeVolume+1
lda #$00
sta FadeState
ldx #$00
hijackLoop:
lda codeData,x
sta $0122,x
inx
cpx #$04
bne hijackLoop
// Original code hijacked
jml $C10010
codeData:
jml NMI_Update
}
scope NMI_Update: {
php
rep #$20
pha
sep #$20
lda FrameCount
inc
sta FrameCount
lda FadeState
beq Exit
lda FrameCount
lsr
bcs Exit
rep #$20
clc
lda FadeVolume
adc FadeStep
sta FadeVolume
sep #$20
lda FadeVolume+1
sta MSU_AUDIO_VOLUME
lda FadeCount
dec
bne +;
lda #$00
sta FadeState
+;
sta FadeCount
Exit:
rep #$20
pla
plp
// Call actual NMI code
jml $000100
}
if (pc() > $CB3FFF) {
error "Overflow detected"
}
Chrono Trigger
Code:
arch snes.cpu
// MSU memory map I/O
constant MSU_STATUS($002000)
constant MSU_ID($002002)
constant MSU_AUDIO_TRACK_LO($002004)
constant MSU_AUDIO_TRACK_HI($002005)
constant MSU_AUDIO_VOLUME($002006)
constant MSU_AUDIO_CONTROL($002007)
// SPC communication ports
constant SPC_COMM_0($2140)
constant SPC_COMM_1($2141)
constant SPC_COMM_2($2142)
constant SPC_COMM_3($2143)
// MSU_STATUS possible values
constant MSU_STATUS_TRACK_MISSING($8)
constant MSU_STATUS_AUDIO_PLAYING(%00010000)
constant MSU_STATUS_AUDIO_REPEAT(%00100000)
constant MSU_STATUS_AUDIO_BUSY($40)
constant MSU_STATUS_DATA_BUSY(%10000000)
// SNES Multiply register
constant SNES_MUL_OPERAND_A($004202)
constant SNES_MUL_OPERAND_B($004203)
constant SNES_DIV_DIVIDEND_L($004204)
constant SNES_DIV_DIVIDEND_H($004205)
constant SNES_DIV_DIVISOR($004206)
constant SNES_DIV_QUOTIENT_L($004214)
constant SNES_DIV_QUOTIENT_H($004215)
constant SNES_MUL_DIV_RESULT_L($004216)
constant SNES_MUL_DIV_RESULT_H($004217)
// Constants
constant FULL_VOLUME($FF)
constant DUCKED_VOLUME($30)
constant BATTLE1_MUSIC($45)
constant THEME_LOOP($18)
constant THEME_ATTRACT($54)
// =============
// = Variables =
// =============
// Game Variables
variable musicCommand($1E00)
variable musicRequested($1E01)
variable targetVolume($1E02)
// My own variables
variable currentSong($1EE0)
variable fadeState($1EE1)
variable fadeVolume($1EE2)
variable fadeTarget($1EE4)
variable fadeStep($1EE6)
// fadeState possibles values
constant FADE_STATE_IDLE($00)
constant FADE_STATE_FADEOUT($01)
constant FADE_STATE_FADEIN($02)
// **********
// * Macros *
// **********
// seek converts SNES HiROM address to physical address
macro seek(variable offset) {
origin (offset & $3FFFFF)
base offset
}
macro CheckMSUPresence(labelToJump) {
lda MSU_ID
cmp.b #'S'
bne {labelToJump}
}
macro WaitMulResult() {
nop
nop
nop
nop
}
macro WaitDivResult() {
nop
nop
nop
nop
nop
nop
nop
nop
}
// ========================
// = Original code hijack =
// ========================
// NMI hijack
seek($00FF10)
jml MSU_UpdateLoop
// Wait for song to finish command
seek($C03CC6)
jsl MSU_WaitSongFinish
nop
nop
nop
nop
// Wait for song to start (found when switching characters on overworld)
seek($C2CBE0)
jsl MSU_WaitSongStart
nop
nop
nop
nop
// Wait for title screen fix
// This chunk of code is copied into RAM
// by the decompression routine, that's why
// it got a db $80 in the middle
seek($C335AF)
nop
db $80
jsl MSU_WaitSongStart
nop
nop
// Epoch 1999 AD sound check
seek($C30C28)
SoundCheckSuccessful:
// Equivalent to bra $0bb5
db $80,$8B
jsl MSU_EpochMode7Fix
bcs SoundCheckSuccessful
rts
// Epoch 1999 AD event modification
// This is a destructive modification
// Remove syncronisation with music in the event
seek($FA96B1)
// 10 10 is Event Command Jump Forward ten bytes
// This is compressed data so the modification is
// replicated 3 times
db $10, $10, 0, 0, 0
// Relevant calls to $C70004
// Found via hex editor by searching for JSL $C70004
seek($C01B73)
jsl MSU_Main
// Entering area
seek($C01B8B)
jsl MSU_Main
// Entering battle
seek($C01BCE)
jsl MSU_Main
seek($C01C2A)
jsl MSU_Main
// Exiting battle
seek($C01C3A)
jsl MSU_Main
seek($C01C52)
jsl MSU_Main
seek($C01CA9)
jsl MSU_Main
seek($C01CB7)
jsl MSU_Main
seek($C01CCF)
jsl MSU_Main
// Called during attract
seek($C03C43)
jsl MSU_Main
seek($C03C69)
jsl MSU_Main
seek($C03CB4)
jsl MSU_Main
seek($C161DF)
jsl MSU_Main
seek($C20462)
jsl MSU_Main
seek($C223F9)
jsl MSU_Main
seek($C22F49)
jsl MSU_Main
seek($C2CBF3)
jsl MSU_Main
seek($C2CC09)
jsl MSU_Main
seek($C309D1)
jsl MSU_Main
seek($C30BE9)
jsl MSU_Main
// Title Screen
seek($C31647)
jsl MSU_Main
seek($CD03AB)
jsl MSU_Main
seek($CD0D70)
jsl MSU_Main
seek($CD0D81)
jsl MSU_Main
// Hijack for music in attract mode
seek($DB6E03)
db THEME_ATTRACT
seek($FA24A4)
db THEME_ATTRACT
seek($FA28FA)
db THEME_ATTRACT
seek($FA4925)
db THEME_ATTRACT
seek($FA4962)
db THEME_ATTRACT
seek($FA659C)
db THEME_ATTRACT
// ============
// = MSU Code =
// ============
seek($C5F370)
scope MSU_Main: {
php
// Backup A and Y in 16bit mode
rep #$30
pha
phx
phy
phd
phb
sep #$30 // Set all registers to 8 bit mode
CheckMSUPresence(.CallOriginalRoutine)
lda.w musicCommand
// Play Music
cmp.b #$10
bne +
jsr MSU_PlayMusic
bcs .CallOriginalRoutine
bcc .DoNotCallSPCRoutine
+
// Resume
cmp.b #$11
bne +
if {defined RESUME_EXPERIMENT} {
jsr MSU_PlayMusic
} else {
jsr MSU_ResumeMusic
}
bcs .CallOriginalRoutine
bcc .DoNotCallSPCRoutine
+
// Interrupt
cmp.b #$14
bne +
jsr MSU_PauseMusic
bcs .CallOriginalRoutine
bcc .DoNotCallSPCRoutine
+
// Fade
cmp.b #$81
bne +
jsr MSU_PrepareFade
+
// Call original routine
.CallOriginalRoutine:
// Restore original theme when MSU-1 is not present
lda.b #$10
cmp.w musicCommand
bne Original
lda.b #THEME_ATTRACT
cmp.w musicRequested
bne Original
lda.b #THEME_LOOP
sta.w musicRequested
Original:
rep #$30
plb
pld
ply
plx
pla
plp
jsl $C70004
rtl
.DoNotCallSPCRoutine:
rep #$30
plb
pld
ply
plx
pla
plp
rtl
}
scope MSU_PlayMusic: {
lda.w musicRequested
beq .StopMSUMusic
cmp.b #$FF
beq .SongAlreadyPlaying
cmp.w currentSong
beq .SongAlreadyPlaying
sta MSU_AUDIO_TRACK_LO
lda.b #$00
sta MSU_AUDIO_TRACK_HI
.CheckAudioStatus:
lda MSU_STATUS
and.b #MSU_STATUS_AUDIO_BUSY
bne .CheckAudioStatus
// Check if track is missing
lda MSU_STATUS
and.b #MSU_STATUS_TRACK_MISSING
bne .StopMSUMusic
// Play the song
lda.w musicRequested
jsr TrackNeedLooping
if {defined RESUME_EXPERIMENT} {
ldx musicCommand
cpx #$11
bne .SetAudioControl
// Add resume flag
ora.b #$4
.SetAudioControl:
}
sta MSU_AUDIO_CONTROL
// Set volume
lda.b #FULL_VOLUME
sta.w MSU_AUDIO_VOLUME
sta.w fadeVolume
// Only store current song if we were able to play the song
lda.w musicRequested
sta currentSong
// Set SPC music to silence and disable any fade if any was active
lda #$00
sta $1E01
sta.w fadeState
sec
bra .Exit
.SongAlreadyPlaying:
clc
.Exit:
rts
.StopMSUMusic:
lda.b #$00
sta MSU_AUDIO_CONTROL
sta MSU_AUDIO_VOLUME
sta.w currentSong
sec
bra .Exit
}
scope MSU_ResumeMusic: {
lda MSU_STATUS
and.b #MSU_STATUS_TRACK_MISSING
bne .CallOriginalCode
lda.w musicRequested
cmp.w currentSong
beq +
jmp MSU_PlayMusic
+
sta currentSong
lda.b #$03
sta MSU_AUDIO_CONTROL
// Play silence after resuming music to
// reload correct SFX samples
lda.b #$10
sta.w musicCommand
lda.b #$00
sta.w musicRequested
.CallOriginalCode:
sec
rts
}
scope MSU_PauseMusic: {
if {defined RESUME_EXPERIMENT} {
lda.b #$4
sta MSU_AUDIO_CONTROL
jml MSU_PlayMusic
} else {
lda.w musicRequested
cmp.b #BATTLE1_MUSIC
beq .PauseMSUMusic
jml MSU_PlayMusic
.PauseMSUMusic:
lda MSU_STATUS
and.b #MSU_STATUS_TRACK_MISSING
bne +
lda.b #$00
sta MSU_AUDIO_CONTROL
+
sec
rts
}
}
scope MSU_PrepareFade: {
rep #$20
lda #$0000
sep #$20
// musicRequested = Fade Time
lda.w musicRequested
beq .SetVolumeImmediate
// fadeStep = (targetVolume-fadeVolume)/fadeTime
lda.w targetVolume
sta.w fadeTarget
rep #$20
sec
sbc.w fadeVolume
// If carry is set, the result is a positive number
bcs +
// Reverse sign of the result (which in two-complements)
// A negative result means a fade-out
eor #$FFFF
inc
sep #$30
ldx.b #FADE_STATE_FADEOUT
stx.w fadeState
bra .DoDivision
+
sep #$30
ldx.b #FADE_STATE_FADEIN
stx.w fadeState
.DoDivision:
// Do division using SNES division support
sta $4204 // low
stz $4205 // high byte
lda.w musicRequested // fadeTime
sta $4206
// Wait 16 CPU cycles
nop
nop
nop
nop
nop
nop
nop
nop
// Result in 4214 / 4215
lda $4214
beq .ResetToIdle
sta fadeStep
bra .Exit
.SetVolumeImmediate:
lda.w targetVolume
sta.w fadeVolume
sta MSU_AUDIO_VOLUME
.Exit:
rts
.ResetToIdle:
lda.b #FADE_STATE_IDLE
sta.w fadeState
sta.w fadeStep
bra .SetVolumeImmediate
}
scope TrackNeedLooping: {
// 1.01 A Premonition
cmp.b #48
beq .noLooping
// 1.02 Theme of Chrono Trigger (Attract)
cmp.b #THEME_ATTRACT
beq .noLooping
// 1.03 Morning Glow
cmp.b #15
beq .noLooping
// 1.10 Good Night
cmp.b #43
beq .noLooping
// 1.14 Huh ?!
cmp.b #37
beq .noLooping
// 1.16 A Prayer for the Wayfarer
cmp.b #36
beq .noLooping
// 2.02 Mystery from the Past
cmp.b #46
beq .noLooping
// 2.12 Fanfare 2
cmp.b #28
beq .noLooping
// 2.15 Fanfare 3
cmp.b #61
beq .noLooping
// 2.22 Fiedlord's Keep
cmp.b #72
beq .noLooping
lda.b #$03
rts
.noLooping:
lda.b #$01
rts
}
scope MSU_UpdateLoop: {
php
rep #$20
pha
sep #$20
CheckMSUPresence(.CallNMI)
lda.w fadeState
beq .CallNMI
cmp.b #FADE_STATE_FADEOUT
beq .FadeOutUpdate
cmp.b #FADE_STATE_FADEIN
beq .FadeInUpdate
bra .CallNMI
.FadeOutUpdate:
lda.w fadeVolume
sec
rep #$20
sbc.w fadeStep
cmp.w fadeTarget
bpl +
sep #$20
lda fadeTarget
+
sep #$20
sta.w fadeVolume
sta MSU_AUDIO_VOLUME
cmp.w fadeTarget
beq .SetToIdle
bra .CallNMI
.FadeInUpdate:
lda.w fadeVolume
clc
rep #$20
adc.w fadeStep
cmp.w fadeTarget
bcc +
sep #$20
lda fadeTarget
+
sep #$20
sta.w fadeVolume
sta MSU_AUDIO_VOLUME
cmp.w fadeTarget
beq .SetToIdle
bra .CallNMI
.SetToIdle:
lda.b #FADE_STATE_IDLE
sta.w fadeState
.CallNMI:
rep #$20
pla
plp
jml $000500
}
scope MSU_WaitSongStart: {
php
rep #$20
pha
sep #$20
CheckMSUPresence(.OriginalCode)
rep #$20
pla
plp
rtl
.OriginalCode:
rep #$20
pla
plp
// Original code
-
lda $2143
and.b #$0F
beq -
rtl
}
scope MSU_WaitSongFinish: {
php
rep #$20
pha
sep #$20
CheckMSUPresence(.OriginalCode)
lda MSU_STATUS
and.b #(MSU_STATUS_AUDIO_PLAYING|MSU_STATUS_AUDIO_REPEAT)
bne +
inx
+
rep #$20
pla
plp
rtl
.OriginalCode:
rep #$20
pla
plp
lda $2143
and.b #$0F
bne +
inx
+
rtl
}
scope MSU_EpochMode7Fix: {
rep #$20
pha
sep #$20
CheckMSUPresence(.OriginalCode)
rep #$20
pla
sec
rtl
.OriginalCode:
rep #$20
pla
-
sep #$20
lda SPC_COMM_2
cmp SPC_COMM_2
bne -
and.b #$0F
cmp ($20)
bpl .RoutineSuccessful
rep #$20
dec $20
clc
rtl
.RoutineSuccessful:
sec
rtl
}
07-11-2015, 02:05 AM
FF6 is going to require a lot more work due to battle NMI being air tight. I've already attempted to implement it, if crudely, and while it seems to work out of battle, in-battle it corrupts graphics since it hijacks the NMI routine. Further, all of the music-changing events (fading in, fading out, transitioning, hardcoded transitions for battle, et cetera) would need to be coded to handle it. It's not a simple swap job. I'm not even sure it's doable.
07-11-2015, 08:49 AM
Can it be made to only effect out of battle? Or is it a all or none type deal?
The only true wisdom is knowing you know nothing.
(07-11-2015, 08:49 AM)Catone Wrote: Can it be made to only effect out of battle? Or is it a all or none type deal?
There's no restriction. You can have it only available for out of battle songs or have the SPC-700 play the default songs if PCM files are not found in the library.
(07-11-2015, 02:05 AM)dn Wrote: I've already attempted to implement it, if crudely, and while it seems to work out of battle, in-battle it corrupts graphics since it hijacks the NMI routine.
The guy on the Qhimm forum has a proof of concept video in battle: https://www.youtube.com/watch?v=vKgSqG2Tbfc. I know it's just not a swap and several event commands would need to be edited. The problem seems to be with fading out tracks, but hey, I have nothing to lose if I attempt it.
There's also this guy who made the opera scene: https://www.youtube.com/watch?v=tGlIKAukm1U
06-26-2016, 10:04 PM
insidious611's project is still alive and has entering an open beta phase: http://forums.qhimm.com/index.php?topic=16077.0
He has not yet implemented fade in / out or used NMI for other purpose. There's a few issues on the tracker but the guy seems to want bringing this project fully enjoyable on bsnes 0.75, Higan 0.97+ and SD2SNES cartridge. The code is now public: https://bitbucket.org/insidious611/dancingmad
He has not yet implemented fade in / out or used NMI for other purpose. There's a few issues on the tracker but the guy seems to want bringing this project fully enjoyable on bsnes 0.75, Higan 0.97+ and SD2SNES cartridge. The code is now public: https://bitbucket.org/insidious611/dancingmad
I'm closing this thread and moved last post in a more fitting place:
https://www.ff6hacking.com/forums/thread...l#pid36104
https://www.ff6hacking.com/forums/thread...l#pid36104
« Next Oldest | Next Newest »
Users browsing this thread: 1 Guest(s)