Just created a new thread actually !
Thanks for the kind words guys, I'm back into this since a few days ago and I hope to make good progress in the next few weeks !
EDIT (7th March 2019) :
I just pushed SF2TextManager-1.5.0 on SF2DISASM with this new feature :
After loading a game script from any source, you can now update it by importing ASM files which will be parsed automatically.
This way, you can easily update code, cutscenes and map setups without having to manage text back and forth between the whole game script and the places where your are referencing those lines. Just write the text line as a comment directly in the ASM file !
Examples :
- Code :
All macros named "txt" can be parsed.
Code: Select all
; ASM FILE code\specialscreens\witch\witchactions.asm :
; 0x7406..0x75C4 : Witch actions
; =============== S U B R O U T I N E =======================================
WitchNew:
txt $DE ; "What should I call you?{W2}"
move.b (SAVE_FLAGS).l,d2
andi.w #3,d2
eori.w #3,d2
lsl.w #1,d2
btst #1,d2
beq.s loc_7424
moveq #1,d0
bra.s loc_7426
loc_7424:
moveq #2,d0
loc_7426:
moveq #1,d1
loc_7428:
jsr j_WitchMainMenu
tst.w d0
bmi.s byte_73C2
subq.w #1,d0
move.w d0,((SAVE_SLOT_INDEX-$1000000)).w
jsr j_NewGame
clsTxt
clr.w d0
jsr j_NameCharacter
btst #7,(SAVE_FLAGS).l; "Game completed" bit
beq.w byte_7476
btst #INPUT_A_START_BIT,((P1_INPUT-$1000000)).w
beq.w byte_7476
moveq #1,d0
moveq #$1B,d7
loc_7464:
jsr j_NameCharacter
loc_746A:
addq.w #1,d0
cmpi.w #6,d0
beq.s loc_746A
dbf d7,loc_7464
byte_7476:
txt $DF ; "{NAME;0}....{N}Nice name, huh?{W2}"
bsr.w CheatModeConfiguration
txt $E8 ; "I'll let you decide the{N}difficulty level at this time."
clr.w d0
moveq #3,d1
moveq #$F,d2
jsr j_WitchMainMenu
tst.w d0
bpl.s loc_7494
clr.w d0
loc_7494:
btst #0,d0
beq.s loc_749E
setFlg $4E ; Difficulty bit 0
loc_749E:
btst #1,d0
beq.s loc_74A8
setFlg $4F ; Difficulty bit 1
loc_74A8:
addi.w #$E9,d0 ; HARDCODED text index for difficulty choice reactions
bsr.w DisplayText
txt $E0 ; "Now, good luck!{N}You have no time to waste!{W1}"
loc_74B4:
move.w ((SAVE_SLOT_INDEX-$1000000)).w,d0
move.b #3,((CURRENT_MAP-$1000000)).w
move.b #3,((EGRESS_MAP_INDEX-$1000000)).w
bsr.w SaveGame
disableSram
clsTxt
move.b #3,d0 ; HARDCODED new game starting map
move.w #$38,d1 ; HARDCODED main entity starting X
move.w #3,d2 ; HARDCODED main entity starting Y
move.w #3,d3 ; HARDCODED main entity starting facing
moveq #1,d4
loc_74DE:
bra.w MainLoop
; End of function WitchNew
; =============== S U B R O U T I N E =======================================
WitchLoad:
txt $E1 ; "By the way, who are you?"
move.b (SAVE_FLAGS).l,d2
andi.w #3,d2
lsl.w #1,d2
btst #1,d2
beq.s loc_74FC
moveq #1,d0
bra.s loc_74FE
loc_74FC:
moveq #2,d0
loc_74FE:
moveq #2,d1
jsr j_WitchMainMenu
tst.w d0
bmi.w byte_73C2
subq.w #1,d0
move.w d0,((SAVE_SLOT_INDEX-$1000000)).w
bsr.w LoadGame
disableSram
txt $E2 ; "{NAME;0}, yes! I knew it!{W2}"
bsr.w CheatModeConfiguration
txt $E0 ; "Now, good luck!{N}You have no time to waste!{W1}"
clsTxt
clr.b ((DEACTIVATE_WINDOW_HIDING-$1000000)).w
chkFlg $58 ; checks if a game has been saved for copying purposes ? (or if saved from battle?)
beq.s loc_753A
jsr j_BattleLoop
bra.w loc_75E0
loc_753A:
clr.w d0
move.b ((CURRENT_MAP-$1000000)).w,d0
jsr GetSavePointForMap(pc)
nop
moveq #$FFFFFFFF,d4
bra.w loc_75E0
; End of function WitchLoad
; =============== S U B R O U T I N E =======================================
WitchCopy:
txt $E3 ; "Copy? Really?"
jsr j_YesNoChoiceBox
tst.w d0
bne.w byte_73C2
move.b (SAVE_FLAGS).l,d0
andi.w #3,d0
subq.w #1,d0
bsr.w CopySave
txt $E4 ; "Hee, hee! It's done.{W2}"
bra.w byte_73C2
; End of function WitchCopy
; =============== S U B R O U T I N E =======================================
WitchDel:
txt $E5 ; "Delete which one?"
move.b (SAVE_FLAGS).l,d2
andi.w #3,d2
lsl.w #1,d2
btst #1,d2
beq.s loc_758E
moveq #1,d0
bra.s loc_7590
loc_758E:
moveq #2,d0
loc_7590:
moveq #2,d1
jsr j_WitchMainMenu
tst.w d0
bmi.w byte_73C2
subq.w #1,d0
move.w d0,((SAVE_SLOT_INDEX-$1000000)).w
txt $E6 ; "Delete? Are you sure?"
jsr j_YesNoChoiceBox
tst.w d0
bne.w byte_73C2
move.w ((SAVE_SLOT_INDEX-$1000000)).w,d0
bsr.w ClearSaveSlotFlag
txt $E7 ; "Hee, hee! It's gone!{W2}"
bra.w byte_73C2
; End of function WitchDel
Properly formatted txt commands with text line between double quotes will be parsed to update the script at indicated index.
- Cutscenes :
Cutscenes rely on 5 text-related macros :
- textCursor : defines new cursor position with a line index from the script
- nextSingleText, nextSingleTextVar, nextText, nextTextVar : displays next text lines while pushing text cursor forward.
Code: Select all
; ASM FILE data\scripting\map\cs_intro1.asm :
; 0x47F7E..0x48380 : Intro cutscene 1
IntroCutscene1: textCursor $105A
mapLoad 42,2,5
csWait 1
loadMapEntities ce_48340
setActscriptWait $0,eas_Init
setActscriptWait $83,eas_Init3
setActscriptWait $84,eas_Init3
setActscriptWait $85,eas_Init3
setActscript $82,eas_Transparent
fadeInFromBlackHalf
csWait 30
setPos $5,7,15,UP
setPos $80,7,16,UP
setPos $81,7,17,UP
entityActions $5
moveUp 6
endActions
entityActions $80
moveUp 6
endActions
entityActionsWait $81
moveUp 6
endActions
playSound SFX_INTRO_LIGHTNING
setQuake 1
setPos $83,7,12,LEFT
setPos $84,7,13,UP
setPos $85,7,14,UP
csWait 5
setQuake 0
setPos $83,63,63,LEFT
setPos $84,63,63,UP
setPos $85,63,63,UP
csWait 10
setFacing $5,DOWN
setFacing $80,DOWN
setFacing $81,DOWN
setPos $83,7,12,LEFT
setPos $84,7,13,UP
setPos $85,7,14,UP
csWait 5
setPos $83,63,63,LEFT
setPos $84,63,63,UP
setPos $85,63,63,UP
csWait 10
setPos $83,7,12,LEFT
setPos $84,7,13,UP
setPos $85,7,14,UP
csWait 5
setPos $83,63,63,LEFT
setPos $84,63,63,UP
setPos $85,63,63,UP
csWait 10
setActscript $5,eas_Jump
setActscript $80,eas_Jump
setActscriptWait $81,eas_Jump
setActscript $5,eas_Jump
setActscript $80,eas_Jump
setActscriptWait $81,eas_Jump
csWait 30
setCameraEntity $5
entityActions $5
moveUp 4
endActions
entityActions $80
moveUp 4
endActions
entityActionsWait $81
moveUp 4
endActions
setActscriptWait $80,eas_BumpUp
setActscriptWait $81,eas_BumpUp
csWait 30
setFacing $5,DOWN
nextSingleText $80,$5 ; "Stay here, OK?{D2}"
nod $80
entityActionsWait $5
moveRight 5
endActions
setFacing $80,RIGHT
setFacing $81,RIGHT
entityActionsWait $5
moveDown 3
endActions
csWait 30
shiver $5
csWait 30
nextSingleText $80,$5 ; "Oops, a dead end!{D2}"
entityActionsWait $5
moveUp 3
moveLeft 5
endActions
setFacing $80,UP
setFacing $81,UP
setFacing $5,DOWN
csWait 20
headshake $5
csWait 20
entityActionsWait $5
moveLeft 5
endActions
setFacing $80,LEFT
setFacing $81,LEFT
entityActionsWait $5
moveDown 3
endActions
csWait 40
shiver $5
csWait 40
nextSingleText $80,$5 ; "Hey! I found some hidden{N}stairs!{D2}"
entityActionsWait $5
moveUp 2
faceRight 1
endActions
nextSingleText $80,$5 ; "Hey, guys!{N}Follow me!{D2}"
nextSingleText $0,$80 ; "Alright!{D2}"
setActscript $80,eas_Jump
setActscriptWait $81,eas_Jump
setActscript $80,eas_Jump
setActscriptWait $81,eas_Jump
entityActions $80
moveUp 1
moveLeft 5
faceDown 1
endActions
entityActionsWait $81
moveUp 2
moveLeft 4
faceDown 1
endActions
setFacing $5,UP
csWait 20
entityActions $5
moveDown 3
endActions
entityActions $80
moveDown 3
endActions
entityActionsWait $81
moveLeft 1
moveDown 2
endActions
playSound SFX_WARP
fadeOutToBlackHalf
setCameraEntity $FFFF
setPos $5,19,3,DOWN
setPos $80,19,3,DOWN
setPos $81,19,3,DOWN
reloadMap 15,0
csWait 10
fadeInFromBlackHalf
setCameraEntity $5
entityActionsWait $5
moveDown 1
endActions
csWait 10
nextSingleText $80,$5 ; "Finally, I found the hidden{N}room of the Ancient Shrine!{D2}"
entityActions $5
moveDown 1
endActions
entityActionsWait $80
moveDown 1
endActions
entityActions $5
moveDown 2
endActions
entityActions $80
moveDown 2
endActions
entityActionsWait $81
moveDown 2
endActions
csWait 30
setActscriptWait $5,eas_Jump
setActscriptWait $5,eas_Jump
nextSingleText $80,$5 ; "A treasure chest!{D2}"
customActscriptWait $5
ac_setSpeed 48,48 ;
ac_jump eas_Idle ;
ac_end
customActscriptWait $80
ac_setSpeed 48,48 ;
ac_jump eas_Idle ;
ac_end
customActscriptWait $81
ac_setSpeed 48,48 ;
ac_jump eas_Idle ;
ac_end
entityActions $5
moveDown 2
endActions
entityActions $80
moveDown 2
endActions
entityActionsWait $81
moveDown 2
endActions
setCamDest 15,5
shiver $5
nextSingleText $80,$5 ; "I wonder if they're here?{D2}"
nextSingleText $FF,$FF ; "{NAME;5} the thief opened{N}the chest.{D2}"
setBlocks 7,3,1,1,19,10
nextSingleText $FF,$FF ; "He found Power Water.{D2}"
headshake $5
nextSingleText $80,$5 ; "No, I don't want this!{D2}"
nextSingleText $FF,$FF ; "{NAME;5} discarded the{N}Power Water.{D2}"
setBlocks 4,3,1,1,19,10
csWait 30
setActscriptWait $5,eas_Init
setActscriptWait $80,eas_Init
setActscriptWait $81,eas_Init
entityActionsWait $81
moveLeft 1
moveDown 2
faceRight 1
endActions
nextSingleText $0,$81 ; "Where on Earth are those{N}jewels?{D2}"
csWait 10
setFacing $5,LEFT
nextSingleText $80,$5 ; "I'm not sure.{D2}"
csWait 20
setCameraEntity $5
entityActions $5
moveRight 5
endActions
entityActions $80
moveDown 1
moveRight 4
endActions
entityActionsWait $81
eaWait 20
moveRight 4
endActions
csWait 5
setActscript $5,eas_461E4
csWait 5
setActscript $80,eas_461B6
csWait 5
setActscript $81,eas_461B6
csWait 60
entityActionsWait $5
moveRight 2
moveUp 1
endActions
nextSingleText $80,$5 ; "Something is shining over{N}there...!{D2}"
setFacing $80,UP
setFacing $81,UP
setCamDest 21,1
nextSingleText $80,$5 ; "Oh, they must be the jewels{N}of light and evil!{D2}"
csWait 20
fadeOutToBlackHalf
csc_end
ce_48340: mainEntity 63,63,UP
entity 63,63,DOWN,5,eas_Init
entity 63,63,UP,202,eas_Init
entity 63,63,UP,202,eas_Init
entity 26,4,DOWN,173,eas_Init
entity 63,63,LEFT,183,eas_Init
entity 63,63,UP,183,eas_Init
entity 63,63,UP,183,eas_Init
dc.w $FFFF
- Map setups :
Most map setup sections rely on both code and cutscenes, which you can edit as explained just above.
But area descriptions can also be edited now :
Code: Select all
; ASM FILE data\maps\entries\map03\mapsetups\s4_descriptions.asm :
; 0x512E0..0x51358 :
; =============== S U B R O U T I N E =======================================
ms_map3_AreaDescriptions:
move.w #$FC3,d3 ; "Welcome!{N}WEAPONS and ITEMS{W1}"
lea byte_512F0(pc), a0
nop
jmp DisplayAreaDescription
; End of function ms_map3_AreaDescriptions
byte_512F0: msDesc 9, 22, 2, 0 ; "{NAME} investigated{N}the sign.{W2}{CLEAR}"
; "Welcome!{N}WEAPONS and ITEMS{W1}"
msDesc 7, 4, 4, 1 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}ATTITUDE OF SOLDIERS{W1}"
msDesc 7, 9, 3, 2 ; "{NAME} investigated{N}the wash basin.{W2}{CLEAR}"
; "Soapy water...{N}(gulp, gulp)...yuck!{N}That tastes disgusting!{W1}"
msDesc 26, 13, 5, 3 ; "{NAME} looked into{N}the well.{W2}{CLEAR}"
; "A deep well.{W1}"
msDesc 40, 6, 4, 4 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}HEALING MAGIC{W1}"
msDesc 41, 6, 4, 5 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}BEGINNER SWORDSMANSHIP{W1}"
msDesc 42, 6, 6, 6 ; "{NAME} looked at{N}the paper.{W2}{CLEAR}"
; "It reads...{N}Nothing to fear but fear{N}itself.{W1}"
msDesc 43, 6, 6, 7 ; "{NAME} looked at{N}the paper.{W2}{CLEAR}"
; "It reads...{N}Look before you leap.{W1}"
msDesc 44, 6, 6, 8 ; "{NAME} looked at{N}the paper.{W2}{CLEAR}"
; "It reads...{N}No pain, no gain.{N}...is this true?{W1}"
msDesc 53, 13, 4, 9 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}THE LEGEND OF MAX{W1}"
msDesc 54, 13, 4, 10 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}BE GOOD{W1}"
msDesc 55, 13, 4, 11 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}LITTLE DINOSAURS{W1}"
msDesc 56, 13, 4, 12 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}SEGA GUIDE{N}...sounds good.{W1}"
msDesc 56, 15, 4, 13 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}AN OLD GOAT{N}...Sir Astral?{W1}"
msDesc 57, 15, 4, 14 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}GUIDE TO THE CASTLE{W1}"
msDesc 58, 15, 4, 15 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}STUDY OF YOGURT{W1}"
msDesc 59, 15, 4, 16 ; "{NAME} investigated{N}the book shelves.{W2}{CLEAR}"
; "A book...{N}SCIENCE 101{W1}"
msDescEnd
For each entry :
- First line represents the investigation line, which is generally shared by a lot of entries, so be careful about the impact
- Second line is the actual description line which you can generally edit with no impact on anything else
For a more detailed explanation on this map setup section please refer to the
map setup documentation.
You can also extend the game's script size by defining line indexes above the game's maximum ($10AA) : SF2TextManager will automatically expand the array of lines and create any number of needed textbanks. Beware though : any new textbank after textbank 16 has to be declared in the textbank entry list in disasm\data\scripting\text\entries.asm
So yeah, changing lines in existing cutscenes and code (or declaring new lines to use in new cutscenes) is now quite easy and fun.