Welcome to the Shining Force Central Forums!
SFC Forums Index Shining Forums Shining Force II
Register for your free forum account now or Login to remove this advert.

"Is it feasible?" thread

with disasm and stuff

Discussion about this classic Genesis/Mega Drive game.

"Is it feasible?" thread

Postby DiegoMM » Sat Feb 10 2018 12:23pm

The great progress of Shining 2 DISASM make me wonder if some things are feasible and could be implemented in future hacks. Its no need to be feasible right now, but if you guys think it would be in the future.

1 - Get rid of random battles spots: we all know they are annoying, so you could wander freely without worrying about a unwanted battle.

2 - Change events locations: Mainly the ones that not matter much for the story, like secret characters: for example, I want to put Claude in a town early in the game and the arm of golem in another location so you could get him early. Or place the event that skreech joins in another town. I mean the same dialogue would happens and stuff, just a location change, like a crtl +c, ctrl +v of the event. Another idea is to place the creed four choice in another place.

3- Battles in another map: Instead a battle in world map, like battle 6, makes it happens in galam, the trigger would be before leaving galam and when we win and leave the battle dont trigger anymore in the world map.

4 - Place more chests in battle maps?

:shifty:
I learned english playing Shining Force 2!
I learned english playing Shining Force 2!
DiegoMM

User avatar
Shining Member
Shining Member
 
Posts: 413
Joined: Wed May 05 2010 2:48pm

Re: "Is it feasible?" thread

Postby Wiz » Sun Feb 11 2018 8:24pm

1 - Get rid of random battles spots
Well, I must say I don't know yet how this works exactly.
But from what I can see quickly :
- the triggering data seems to be stored in map setup section 3 : zone-activated events.
- I think I just found the "random battle" subroutine at location 0x47856.
It is currently named "sub_47856" but I'll rename it for next SF2DISASM update.
Here's the subroutines code :
Code: Select all
ROM:00047856 ; =============== S U B R O U T I N E =======================================
ROM:00047856
ROM:00047856
ROM:00047856 sub_47856:                              ; CODE XREF: sub_4FAD4+4p
ROM:00047856                                         ; sub_4FB58+4p
ROM:00047856                                         ; sub_4FD70+4p
ROM:00047856                                         ; sub_4FDB2+4p
ROM:00047856                                         ; sub_4FE12+4p
ROM:00047856                                         ; sub_4FE8C+4p
ROM:00047856                                         ; sub_4FF06+Ap
ROM:00047856                                         ; sub_4FF06+16p
ROM:00047856                 movem.l d1/d6-d7,-(sp)
ROM:0004785A                 move.w  #$1F4,d1        ; Battle completed flags
ROM:0004785E                 add.w   d0,d1
ROM:00047860                 jsr     j_CheckFlag
ROM:00047866                 bne.s   loc_4786E
ROM:00047868                 moveq   #$FFFFFFFF,d1
ROM:0004786A                 bra.w   loc_47896
ROM:0004786E ; ---------------------------------------------------------------------------
ROM:0004786E
ROM:0004786E loc_4786E:                              ; CODE XREF: sub_47856+10j
ROM:0004786E                 tst.w   ((word_FFB196-$1000000)).w
ROM:00047872                 beq.s   loc_4787A
ROM:00047874                 clr.w   d1
ROM:00047876                 bra.w   loc_47896
ROM:0004787A ; ---------------------------------------------------------------------------
ROM:0004787A
ROM:0004787A loc_4787A:                              ; CODE XREF: sub_47856+1Cj
ROM:0004787A                 moveq   #8,d6
ROM:0004787C                 jsr     (UpdateRandomSeed).w ; d6 determines the random number max value
ROM:0004787C                                         ; (number of seed upper bits)
ROM:00047880                 tst.w   d7
ROM:00047882                 bne.s   loc_47888
ROM:00047884                 moveq   #$FFFFFFFF,d1
ROM:00047886                 bra.s   loc_47896
ROM:00047888 ; ---------------------------------------------------------------------------
ROM:00047888
ROM:00047888 loc_47888:                              ; CODE XREF: sub_47856+2Cj
ROM:00047888                 clr.w   d1
ROM:0004788A                 moveq   #4,d6
ROM:0004788C                 jsr     (UpdateRandomSeed).w ; d6 determines the random number max value
ROM:0004788C                                         ; (number of seed upper bits)
ROM:00047890                 addq.l  #2,d7
ROM:00047892                 move.w  d7,((word_FFB196-$1000000)).w
ROM:00047896
ROM:00047896 loc_47896:                              ; CODE XREF: sub_47856+14j
ROM:00047896                                         ; sub_47856+20j
ROM:00047896                                         ; sub_47856+30j
ROM:00047896                 tst.w   d1
ROM:00047898                 beq.s   loc_478C0
ROM:0004789A                 move.w  #$190,d1
ROM:0004789E                 add.w   d0,d1
ROM:000478A0                 jsr     j_SetFlag
ROM:000478A6                 move.l  #$100FF,((MAP_EVENT_TYPE-$1000000)).w
ROM:000478AE                 move.w  #$7530,((word_FFB196-$1000000)).w
ROM:000478B4                 jsr     (WaitForCameraToCatchUp).w ; wait for end of scrolling
ROM:000478B8                 trap    #SOUND_COMMAND
ROM:000478B8 ; ---------------------------------------------------------------------------
ROM:000478BA                 dc.w SFX_BOOST          ; boost effect ?
ROM:000478BC ; ---------------------------------------------------------------------------
ROM:000478BC                 bsr.w   ExecuteFlashScreenScript
ROM:000478C0
ROM:000478C0 loc_478C0:                              ; CODE XREF: sub_47856+42j
ROM:000478C0                 movem.l (sp)+,d1/d6-d7
ROM:000478C4                 rts
ROM:000478C4 ; End of function sub_47856
So I think that just making this subroutine do nothing would do the trick : remove the routine's code by just keeping the "rts" instruction at the end ("return from subroutine").
Subroutine location : 'disasm\code\common\scripting\map\mapsetupsfunctions_1.asm'


2 - Change events locations
This may be more tricky, with specific actions depending on what you want to do exactly, but here's what's important :
- Item locations are contained in map data. So for the Golem arm you can already edit map data from SF2MapEditor to put it anywhere you want.
- Join events happen during cutscenes, which generally are triggered from map setups.
Unfortunately, map setups are still in a very raw state, with almost no documentation and proper formatting, so this is going to be hard to edit for the moment.
Here's the map setup tiny doc :
https://github.com/ShiningForceCentral/SF2DISASM/blob/master/disasm/data/maps/mapsetups.txt
You'll find map setups in each map entry folder.
About your examples :
- Claude : declare Claude's entity in first section of map setup (like he can be declared in his original map), then declare the associated entity event in the second section. You should be able to copy stuff from the original map 63 quite easily.
Original entity declaration :
https://github.com/ShiningForceCentral/SF2DISASM/blob/master/disasm/data/maps/entries/map63/mapsetups/s1.asm
Original entity event :
https://github.com/ShiningForceCentral/SF2DISASM/blob/master/disasm/data/maps/entries/map63/mapsetups/s2.asm
Beware though, having Claude join you may imply that you want him to disappear from the map when you visit it again, so you'll have to declare a new map setup which will be triggered when the "Claude joined" flag is set. Once again, you can copy map 63's behaviour.
- Skreech : I believe skreech's event is a zone-activated event, so it's map setup section 3 for map 15. But skreech's cutscene makes him fly around before approaching Bowie so you might have to make cutscene adaptations here !
https://github.com/ShiningForceCentral/SF2DISASM/blob/master/disasm/data/maps/entries/map15/mapsetups/s3_212.asm
- Creed's four choice :
Wow, this one may be even trickier ... let's see the map's setups ... looks like the Yes/No choices are there :
https://github.com/ShiningForceCentral/SF2DISASM/blob/master/disasm/data/maps/entries/map33/mapsetups/s2.asm
So you can declare entities as they are in section 1, then use the associated events from this section 2. Good luck on this one. ;)


3- Battles in another map
Well, you can change a battle's map by editing it's properties in The Caravan, but SF2DISASM currently doesn't have any tool for that, so you'd have to hex edit following file :
'disasm\data\battles\global\battlemapcoords.bin'
I had never looked into it yet but it looks simple :
- 45 battles ==> 45 entries
- 7 bytes per entry
- byte 0 : map index
- 6 remaining bytes to figure out.
About the actual triggering of the battle, I must say I have no idea how this happens at the moment, and I don't know where to search for that ... but maybe it's again related to map setups with something you could copy from a map to another, like zone-activated events ?
I'll have to look into it at some point to get a good understanding of the whole game's flow.


4 - Place more chests in battle maps
You can use SF2MapEditor to change the layout and add a chest block anywhere you want, and then declare a chest item at the same coordinates. That should do it I believe ...
Oh, err ... I just tried to edit Battle 1 and it appears that the chest block isn't always available in existing map blocksets, so I'll have to work on it and make blocks editable at some point.
Aaaand just adding a non-chest item doesn't seem to work either. :shock: What the ...
Well, I'll have to investigate this too at some point, but I see no reason for this not to happen in the future ! ;)

EDIT :
Ok, so I've just discovered that battle search only works on CHEST items, not other items ... I'll have to check the engine code to confirm this but if this is really the case, this is a silly limitation.
EDIT :
I confirm that this game only checks if we're in front of a closed chest.
Code: Select all
ROM:00024756                 bsr.w   GetEntityPositionAfterApplyingFacing ; In: D0 = combatant idx
ROM:00024756                                         ; Out: D0 = new X
ROM:00024756                                         ;      D1 = new Y
ROM:0002475A                 jsr     (CheckIfChestOpened).w
ROM:0002475E                 move.w  d2,((byte_FFB180-$1000000)).w ; item index from chest ?
ROM:00024762                 cmpi.w  #$FFFF,d2
ROM:00024766                 bne.s   loc_2476C       ; if d2 != FFFF, then there is an item
ROM:00024768                 moveq   #1,d2           ; Battle menu with STAY option
ROM:0002476A                 bra.s   loc_2476E
ROM:0002476C ; ---------------------------------------------------------------------------
ROM:0002476C
ROM:0002476C loc_2476C:                              ; CODE XREF: sub_24662+104j
ROM:0002476C                 moveq   #2,d2           ; Battle menu with SEARCH option
Also checking for non-chest items would be a matter of a few additionnal instructions only ...
Last edited by Wiz on Thu Feb 15 2018 10:06pm, edited 1 time in total.
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Re: "Is it feasible?" thread

Postby SirHedge » Tue Feb 13 2018 11:46pm

For #1, the Caravan v0.6 from BNC allowed you to move the trigger locations for battles. I'm not 100% sure if that functionality actually worked or was still in beta testing, but you could test it out if you wanted. Remember to use the Fix Maps patch beforehand to ensure that the changed map saves appropriately.
SirHedge

User avatar
Shining Hero
Shining Hero
 
Posts: 842
Joined: Sat Mar 15 2008 4:10am

Re: "Is it feasible?" thread

Postby Wiz » Thu Feb 15 2018 12:35am

This made me realize that SF2MapEditor didn't manage those "Trigger" flags yet.
These flags are meant for zone events which point to code, so anything is possible from there : random battles, cutscenes, invisible actions, etc.

I've just updated SF2MapEditor to version 1.1.0, it's available on SF2DISASM's last revision.

Now you can remove those trigger flags with a right click :
Image
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Re: "Is it feasible?" thread

Postby Arc_the_Lad » Fri Feb 16 2018 1:25pm

I notice with a lot of hacks that raise difficulty and maintain the games normal character join rate, most people have to pick Karna to compensate for the difficulty. I was wondering if you can make it possible to switch Karna with Janet, so Karna joins for sure and Janet is one of the four. Yes, in terms of story it messes things up, but for gameplay, you pick between four types of damage dealers instead of three DPS and a healer, I think this would make the choice not as easy.

That or switch their classes, that might be easier, make Karna an archer and Janet the priest.
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Arc_the_Lad

User avatar
Restless Dreams
Shining Legend
 
Posts: 3177
Joined: Fri Sep 17 2004 1:07am
Location: Canada

Re: "Is it feasible?" thread

Postby DiegoMM » Fri Feb 16 2018 6:59pm

Replacing characters can be done with caravan, just transform a character in another: replacing sprites, class, portrait and stats. You can edit the text for complete the process. Yes, making the second healer being optional was not a good design idea, because 90% of people wants a second healer making the choice unnecessary.

Wiz, thank you for all the explanation, very detailed. Hope my questions dont annoys you.
I learned english playing Shining Force 2!
I learned english playing Shining Force 2!
DiegoMM

User avatar
Shining Member
Shining Member
 
Posts: 413
Joined: Wed May 05 2010 2:48pm

Re: "Is it feasible?" thread

Postby SirHedge » Fri Feb 16 2018 9:27pm

If you know hex editing, you can simply change directly the time characters join. Here's the summary:

Look for 00 08 00 xx, where xx is the character ID.
Character IDs are from 00 (Bowie) to 1D (Claude).
Note that this isn't class specific. You just say the character who's joining and they join.
Note also that 80 is used for Sarah + Chester (who join simultaneously). This means that if you want to change the join times for Sarah or Chester you'll only have places for 29 people to join, will be one character short on early battles, or will have to learn how to edit in an extra join command.

Search for the hex code above. Change it as needed.

A few characters have their join flags tied up in storyline events, so if you have Zynk before you're supposed to it may skip certain scenes, and skipping those might prevent you from triggering other flags that are needed to progress.

Without looking, I would guess Zynk, Lemon, Peter, Higins, Slade, Frayja.


You can see more in my Hacking Resources thread of long ago.
SirHedge

User avatar
Shining Hero
Shining Hero
 
Posts: 842
Joined: Sat Mar 15 2008 4:10am

Re: "Is it feasible?" thread

Postby Wiz » Sat Feb 17 2018 12:16am

DiegoMM wrote:Wiz, thank you for all the explanation, very detailed. Hope my questions dont annoys you.

Are you kidding ? You are showing interest and asking good questions which motivate me to update my tool suite and push my understanding of things here and there. That's all I'm asking for ! :D
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Re: "Is it feasible?" thread

Postby DiegoMM » Sun Feb 18 2018 9:21pm

So lets get one more:

About the weapon graphics. Its possible reassign them? example: theres only 1 halberd in the game and its assigned to the halberd item, can I change it to more than 1 weapon use the same sprite so I can have multiple halberds in the game? Or 2 weapons that use fire axe sprite. Using the same feature we could change taros sword and iron ball to other weapon sprites that not a staff.
I learned english playing Shining Force 2!
I learned english playing Shining Force 2!
DiegoMM

User avatar
Shining Member
Shining Member
 
Posts: 413
Joined: Wed May 05 2010 2:48pm

Re: "Is it feasible?" thread

Postby Wiz » Sun Feb 18 2018 11:51pm

Ok let's see ...

The "weapon -> graphics" information is stored in a dedicated table : "disasm\data\stats\items\weaponsprites.bin"
Here's the functionnal idea :
Weapon index -> Weapon Sprite index, palette index

Now here's the function using this table :
Code: Select all
ROM:00019DB0 ; =============== S U B R O U T I N E =======================================
ROM:00019DB0
ROM:00019DB0 ; get battle sprite # and palette # for entity D0's equipped weapon -> D2 (sprite), D3 (palette)
ROM:00019DB0
ROM:00019DB0 GetWeaponSpriteAndPalette:              ; CODE XREF: InitializeBattleScene+46p
ROM:00019DB0                                         ; bsc07_switchAllies+46p
ROM:00019DB0                                         ; bsc07_switchAllies+9Ap
ROM:00019DB0                 movem.l d1/a0,-(sp)
ROM:00019DB4                 cmp.w   #$80,d0
ROM:00019DB8                 bcc.w   loc_19DF2
ROM:00019DBC                 jsr     j_GetEquippedWeapon
ROM:00019DC2                 and.w   #$7F,d1
ROM:00019DC6                 cmp.w   #$1A,d1
ROM:00019DCA                 bcs.w   loc_19DF2
ROM:00019DCE                 cmp.w   #$6D,d1
ROM:00019DD2                 bhi.w   loc_19DF2
ROM:00019DD6                 lea     WeaponBattleSprites(pc), a0
ROM:00019DDA                 sub.w   #$1A,d1
ROM:00019DDE                 add.w   d1,d1
ROM:00019DE0                 move.b  (a0,d1.w),d2
ROM:00019DE4                 ext.w   d2
ROM:00019DE6                 move.b  1(a0,d1.w),d3
ROM:00019DEA                 ext.w   d3
ROM:00019DEC                 movem.l (sp)+,d1/a0
ROM:00019DF0                 rts
ROM:00019DF2 ; ---------------------------------------------------------------------------
ROM:00019DF2
ROM:00019DF2 loc_19DF2:                              ; CODE XREF: GetWeaponSpriteAndPalette+8j
ROM:00019DF2                                         ; GetWeaponSpriteAndPalette+1Aj
ROM:00019DF2                                         ; GetWeaponSpriteAndPalette+22j
ROM:00019DF2                 move.w  #$FFFF,d2
ROM:00019DF6                 move.w  d2,d3
ROM:00019DF8                 movem.l (sp)+,d1/a0
ROM:00019DFC                 rts
ROM:00019DFC ; End of function GetWeaponSpriteAndPalette
Let's decompose it a bit :
- Get the Force member's equipped weapon. It's an item index. There are 128 items in the game, here's the index list :
Code: Select all
$H0, Medical Herb
&H1, Healing Seed
&H2, Healing Drop
&H3, Antidote
&H4, Angel Wing
&H5, Fairy Powder
&H6, Healing Water
&H7, Fairy Tear
&H8, Healing Rain
&H9, Power Water
&HA, Protect Milk
&HB, Quick Chicken
&HC, Running Pimento
&HD, Cheerful Bread
&HE, Bright Honey
&HF, Brave Apple
&H10, Shining Ball
&H11, Blizzard
&H12, Holy Thunder
&H13, Power Ring
&H14, Protect Ring
&H15, Quick Ring
&H16, Running Ring
&H17, White Ring
&H18, Black Ring
&H19, Evil Ring
&H1A, Leather Glove
&H1B, Power Glove
&H1C, Brass Knuckles
&H1D, Iron Knuckles
&H1E, Misty Knuckles
&H1F, Giant Knuckles
&H20, Evil Knuckles
&H21, Short Axe
&H22, Hand Axe
&H23, Middle Axe
&H24, Power Axe
&H25, Battle Axe
&H26, Large Axe
&H27, Great Axe
&H28, Heat Axe
&H29, Atlas Axe
&H2A, Ground Axe
&H2B, Rune Axe
&H2C, Evil Axe
&H2D, Wooden Arrow
&H2E, Iron Arrow
&H2F, Steel Arrow
&H30, Robin Arrow
&H31, Assault Shell
&H32, Great Shot
&H33, Nazca Cannon
&H34, Buster Shot
&H35, Hyper Cannon
&H36, Grand Cannon
&H37, Evil Shot
&H38, Wooden Stick
&H39, Short Sword
&H3A, Middle Sword
&H3B, Long Sword
&H3C, Steel Sword
&H3D, Achilles Sword
&H3E, Broad Sword
&H3F, Buster Sword
&H40, Great Sword
&H41, Critical Sword
&H42, Battle Sword
&H43, Force Sword
&H44, Counter Sword
&H45, Levanter
&H46, Dark Sword
&H47, Wooden Sword
&H48, Short Spear
&H49, Bronze Lance
&H4A, Spear
&H4B, Steel Lance
&H4C, Power Spear
&H4D, Heavy Lance
&H4E, Javelin
&H4F, Chrome Lance
&H50, Valkyrie
&H51, Holy Lance
&H52, Mist Javelin
&H53, Halberd
&H54, Evil Lance
&H55, Wooden Rod
&H56, Short Rod
&H57, Bronze Rod
&H58, Iron Rod
&H59, Power Stick
&H5A, Flail
&H5B, Guardian Staff
&H5C, Indra Staff
&H5D, Mage Staff
&H5E, Wish Staff
&H5F, Great Rod
&H60, Supply Staff
&H61, Holy Staff
&H62, Freeze Staff
&H63, Goddess Staff
&H64, Mystery Staff
&H65, Demon Rod
&H66, Iron Ball
&H67, Short Knife
&H68, Dagger
&H69, Knife
&H6A, Thieve's Dagger
&H6B, Katana
&H6C, Ninja Katana
&H6D, Gisarme
&H6E, Taros Sword
&H6F, Right of Hope
&H70, Wooden Pannel
&H71, Sky Orb
&H72, Cannon
&H73, Dry Stone
&H74, Dynamite
&H75, Arm of Golem
&H76, Pegasus Wing
&H77, Warrior's Pride
&H78, Silver Tank
&H79, Secret Book
&H7A, Vigor Ball
&H7B, Mithril
&H7C, Life Ring
&H7D, Cotton Balloon
&H7E, Chirrup Sandles
&H7F, Empty
- if weapon index is between values $1A and $6D, then there's an entry in the table. Else, this is not an equippable weapon, no sprite. So this function contains hardcoded indexes defining the index range for weapons having battle sprites, this is something to keep in mind in case we'd want to extend the weapon list by replacing other items.
- The table will only contain $6D-$1A=$53 (83) entries corresponding to these weapons only. So substract $1A from the item index to get the corresponding entry index in the table.
- Two bytes per entry, put them in d2 and d3 : weapon sprite index, palette index.

So now let's find the halberd entry for example ...
- Halberd item index : $53
- $53-$1A=$39th entry in the table
- $39*2=$72=114th byte in weaponsprites.bin should be the start of the halberd entry.
- weaponsprites.bin's content :
Code: Select all
00000000h: FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 00 00 ; ÿ.ÿ.ÿ.ÿ.ÿ.ÿ.ÿ...
00000010h: 00 00 01 01 01 01 01 01 02 02 02 02 02 03 03 04 ; ................
00000020h: 03 05 03 06 03 07 FF 00 FF 00 FF 00 FF 00 FF 00 ; ......ÿ.ÿ.ÿ.ÿ.ÿ.
00000030h: FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 0A 13 05 09 ; ÿ.ÿ.ÿ.ÿ.ÿ.ÿ.....
00000040h: 05 09 06 0A 06 0A 06 0B 06 0A 07 0D 07 0D 08 0F ; ................
00000050h: 07 0D 09 12 06 0C 07 0E 08 10 04 08 0C 1A 0A 14 ; ................
00000060h: 0C 1A 0A 15 0C 1A 0A 16 0D 1B 0B 17 0D 1C 0B 18 ; ................
00000070h: 0D 1B 0E 1D 0B 19 0F 1E 12 25 12 25 12 25 14 27 ; .........%.%.%.'
00000080h: 14 27 10 1F 10 1F 10 1F 10 1F 13 26 11 20 11 21 ; .'.........&. .!
00000090h: 11 22 11 23 11 24 13 26 13 26 15 28 16 29 15 28 ; .".#.$.&.&.(.).(
000000a0h: 16 29 08 11 08 11 08 11                         ; .)......
Indeed, position $72 shows values $0E and $1D : $0E/15 is the halberd's weapon sprite, you can check it with SF2WeaponSpriteManager here :
disasm\data\graphics\battles\weapons\
- Now let's use it for Chester's base weapon for fun : wooden stick index = $38, ($38-$1A)*2=$3C is the place to edit with values $0E $1D instead of values $0A $13.
- Result : Image

Voilà ! :D

So yeah, it's only 2 bytes to change in a hex editor really.
Also, be aware that you can try any other palette index : all weapon sprites palettes are available for any weapon sprite, so have fun trying halberd palette variations !
You can even use SF2WeaponSpriteEditor to try thoses palettes first. :)
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Re: "Is it feasible?" thread

Postby Corsair » Mon Feb 19 2018 2:36am

Would it be possible to, given an expanded rom, add additional weapon sprites to the game?

I've always wanted to see unique sprites for the Heat Axe and Levanter instead of weirdly colored regular axes.
...and may have drawn a couple at one point >.>
Corsair

User avatar
Shining Legend
Shining Legend
 
Posts: 7063
Joined: Mon Apr 21 2008 2:52am

Re: "Is it feasible?" thread

Postby Wiz » Mon Feb 19 2018 2:34pm

Oh yes it's possible, please Corsair draw new weapons, I'll show you how ! :)

Directory "disasm\data\graphics\battles\weapons\" contains :
- graphics entries : weaponspriteXX.bin
- SF2WeaponSpriteManager-1.0.0.jar : allows you to import/export binary data from/to PNG format
- entries.asm : this is the entry list that you can edit to add new entries
- weaponpalettes.bin : all 2-color entries are stored in this file sequentially, so you can edit existing entries with "disasm\data\graphics\SF2PaletteManager-1.0.0.jar", or you can add new entries by adding new bytes at the end of the file with an hex editor.

So if you want to create new weapon grahics, my suggestion would be to start from an exported PNG file from an existing entry, preferably with the palette you're planning to use already. This would ensure you that you're working on a compatible PNG format.
Of course you could create a new PNG file from scratch but you'd have to comply with several constraints in terms of dimensions and precise PNG format.
Here are the details :
Code: Select all
Imported PNG files have to be "4 bits per pixel" / 16 indexed colors.
5 colors available :
- Index 0-1,2 -> 3 basic colors from battle sprite palette : transparency, white and black
- Index 14-15 -> 2 specific colors picked from the weapon sprite palette entries.
Dimensions per frame : 64*64 (8*8 tiles)
PNG Dimensions : 256*64 (32*8 tiles)


So yeah, let's try this ! :D
I'll change Bowie's base weapon with some new proof-of-concept shitty drawing.

1. Optional new palette
Let's create a new silly 2-color palette first by hex-editing weaponpalettes.bin :
Code: Select all
00000000h: 00 48 0A 66 00 48 0A 66 00 48 0A 66 00 48 00 4E ; .H.f.H.f.H.f.H.N
00000010h: 00 48 0A 66 00 48 00 62 00 48 00 62 00 48 0E 24 ; .H.f.H.b.H.b.H.$
00000020h: 00 48 08 88 00 48 08 88 00 48 08 88 06 66 04 64 ; .H.ˆ.H.ˆ.H.ˆ.f.d
00000030h: 06 66 04 AC 00 48 08 88 06 66 0C 8E 06 20 08 88 ; .f.¬.H.ˆ.f.Ž. .ˆ
00000040h: 06 20 0E 8A 06 20 0E C8 06 66 02 E4 04 68 00 48 ; . .Š. .È.f.ä.h.H
00000050h: 04 68 0A 88 04 68 0A 88 04 68 04 44 04 68 08 66 ; .h.ˆ.h.ˆ.h.D.h.f
00000060h: 04 68 0C AA 04 68 0E 64 04 68 0A A8 04 68 0A A8 ; .h.ª.h.d.h.¨.h.¨
00000070h: 0A 88 0E AA 0A 88 0E AA 00 68 04 2A 00 68 04 2A ; .ˆ.ª.ˆ.ª.h.*.h.*
00000080h: 00 68 04 2A 00 68 0C 40 00 68 04 A2 00 68 02 8E ; .h.*.h.@.h.¢.h.Ž
00000090h: 00 68 0E 4E 08 A8 08 4E 08 A8 04 E8 08 A8 04 E8 ; .h.N.¨.N.¨.è.¨.è
000000a0h: 08 24 08 88 02 26 0A 88 00 48 0A 66             ; .$.ˆ.&.ˆ.H.f
I just added bytes "00 48 0A 66" at the end by copying first entry bytes (2 bytes per color).
Then, open weaponpalettes.bin with SF2PaletteManager-1.0.0.jar and edit the last 2 colors to your liking :
Image
Don't forget to save it by exporting to the same file.
I can notice that now my new palette entry has hex values "00 CE 00 4E".

2. Export a PNG file to work on
With SF2WeaponSpriteManager, export the weapon-palette combination of your choice to use as a base working file :
Image

3. Edit your exported PNG file with your favorite program.
Just make sure to save your work with the same 4bpp color-scheme.
Also make sure the 16-color palette hasn't been altered. I'm currently struggling with GIMP for my own demo right now ... looks like GIMP saves transparency color at index 15, shifting everything, GAH.
Oh well, couldn't find a solution with GIMP so I went back to Pixelformer.

4. Convert PNG back into binary data.
Reverse process with SF2WeaponSpriteManager : open PNG file from the "Import PNG" tab, then export graphics in binary data from the disassembly tab. Just use a new filename of course ! ;)

5. Update the entry list with your new weapon sprite.
Code: Select all
; ASM FILE data\graphics\battles\weapons\entries.asm :
; 0x1B9A9A..0x1BEE38 : Weapons
pt_WeaponSprites:
      dc.l WeaponSprite00
      dc.l WeaponSprite01
      dc.l WeaponSprite02
      dc.l WeaponSprite03
      dc.l WeaponSprite04
      dc.l WeaponSprite05
      dc.l WeaponSprite06
      dc.l WeaponSprite07
      dc.l WeaponSprite08
      dc.l WeaponSprite09
      dc.l WeaponSprite10
      dc.l WeaponSprite11
      dc.l WeaponSprite12
      dc.l WeaponSprite13
      dc.l WeaponSprite14
      dc.l WeaponSprite15
      dc.l WeaponSprite16
      dc.l WeaponSprite17
      dc.l WeaponSprite18
      dc.l WeaponSprite19
      dc.l WeaponSprite20
      dc.l WeaponSprite21
      dc.l WeaponSprite22
      dc.l NewWeaponSpriteDemo
WeaponSprite00: incbin "data/graphics/battles/weapons/weaponsprite00.bin"
WeaponSprite01: incbin "data/graphics/battles/weapons/weaponsprite01.bin"
WeaponSprite02: incbin "data/graphics/battles/weapons/weaponsprite02.bin"
WeaponSprite03: incbin "data/graphics/battles/weapons/weaponsprite03.bin"
WeaponSprite04: incbin "data/graphics/battles/weapons/weaponsprite04.bin"
WeaponSprite05: incbin "data/graphics/battles/weapons/weaponsprite05.bin"
WeaponSprite06: incbin "data/graphics/battles/weapons/weaponsprite06.bin"
WeaponSprite07: incbin "data/graphics/battles/weapons/weaponsprite07.bin"
WeaponSprite08: incbin "data/graphics/battles/weapons/weaponsprite08.bin"
WeaponSprite09: incbin "data/graphics/battles/weapons/weaponsprite09.bin"
WeaponSprite10: incbin "data/graphics/battles/weapons/weaponsprite10.bin"
WeaponSprite11: incbin "data/graphics/battles/weapons/weaponsprite11.bin"
WeaponSprite12: incbin "data/graphics/battles/weapons/weaponsprite12.bin"
WeaponSprite13: incbin "data/graphics/battles/weapons/weaponsprite13.bin"
WeaponSprite14: incbin "data/graphics/battles/weapons/weaponsprite14.bin"
WeaponSprite15: incbin "data/graphics/battles/weapons/weaponsprite15.bin"
WeaponSprite16: incbin "data/graphics/battles/weapons/weaponsprite16.bin"
WeaponSprite17: incbin "data/graphics/battles/weapons/weaponsprite17.bin"
WeaponSprite18: incbin "data/graphics/battles/weapons/weaponsprite18.bin"
WeaponSprite19: incbin "data/graphics/battles/weapons/weaponsprite19.bin"
WeaponSprite20: incbin "data/graphics/battles/weapons/weaponsprite20.bin"
WeaponSprite21: incbin "data/graphics/battles/weapons/weaponsprite21.bin"
WeaponSprite22: incbin "data/graphics/battles/weapons/weaponsprite22.bin"
NewWeaponSpritedemo: incbin "data/graphics/battles/weapons/newweaponspritedemo.bin"
You new weapon sprite is now available to be associated to any weapon item.

6. Edit "disasm\data\stats\items\weaponsprites.bin" to assign your new weapon sprite.
Same process as my previous post.
Bowie's wooden sword item index : $47
($47-$1A)*2=$5A=90th and 91st bytes to edit.
New weapon sprite entry index : 23=$17
New palette entry : 42=$2A
So edit weaponsprites.bin entry with hex values "17 2A" instead of "04 08".

7. Build an expanded ROM to test.
ImageImage

8. Alternative test : use SF2BattleSpriteAnimationEditor !
"disasm\data\graphics\battles\battlesprites\SF2BattleSpriteAnimationEditor-1.1.0.jar"
This also allows you to adjust weapon position for each animation frame, if needed.
Image

So yeah, it works, but keeping the original PNG palette may be more or less easy depending on your image editing software. Please let me know if you have any difficulties.
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Re: "Is it feasible?" thread

Postby SirHedge » Wed Feb 21 2018 1:23am

You're really making me wish I had more time right now, Wiz, so that I could play with all your cool tools....
SirHedge

User avatar
Shining Hero
Shining Hero
 
Posts: 842
Joined: Sat Mar 15 2008 4:10am

Re: "Is it feasible?" thread

Postby DiegoMM » Mon Mar 19 2018 12:17am

Now to good stuff:
Its possible expand content? I mean, max number of itens, enemies, magic, battle sprites, hero sprites. Normally a hack works replacing stuff or using some unused space (like 2 extra enemies, unused items, magic), but with the extra space the rom provides, we can expand the tables?
Other example: animation frames. Some class uses 1 or 2 sprites for some animations, promoted bowie uses 3 for attack. Imagine if more class can use more frames for animations.
I learned english playing Shining Force 2!
I learned english playing Shining Force 2!
DiegoMM

User avatar
Shining Member
Shining Member
 
Posts: 413
Joined: Wed May 05 2010 2:48pm

Re: "Is it feasible?" thread

Postby xenometal » Thu Mar 22 2018 6:56am

Image

Good stuff indeed! ;)
xenometal

User avatar
Shining Member
Shining Member
 
Posts: 431
Joined: Tue Mar 28 2006 3:05am
Location: Canada

Re: "Is it feasible?" thread

Postby Arc_the_Lad » Thu Mar 22 2018 8:16am

Can you raise the maximum force roster number? (Add characters without having to replace others)
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Arc_the_Lad

User avatar
Restless Dreams
Shining Legend
 
Posts: 3177
Joined: Fri Sep 17 2004 1:07am
Location: Canada

Re: "Is it feasible?" thread

Postby xenometal » Thu Mar 22 2018 11:29pm

Image

Well, that wasn't too hard.

As it is, there are 2 dummied out character slots that can be restored with minimal effort (thanks to the disassembly, of course!)

I reckon there's enough space in RAM to expand beyond 32 characters, as long as you're willing to reduce the maximum number of enemies in a given battle which is already (sort of) pratically limited to 20 due to the 32 sprites limit.

But a more pressing matter to attend to before this can be released as a proper patch would be to rewrite the map sprites and portraits assignment routines to refer a table, instead of the current hardcoded method.
xenometal

User avatar
Shining Member
Shining Member
 
Posts: 431
Joined: Tue Mar 28 2006 3:05am
Location: Canada

Re: "Is it feasible?" thread

Postby MXC » Fri Mar 23 2018 1:01pm

Speaking of the 32 sprite limit, could there be a change so that the Force is a different number? This could be an increase or a decrease, but I was mostly thinking about it capping the number of Force members per battle to the 8-10 range. This would add a challenge of reducing character slots but also in increasing enemy slots.
MXC

User avatar
1090
Shining Legend
 
Posts: 25339
Joined: Fri Sep 17 2004 1:48am
Location: Cincinnati, Ohio

Re: "Is it feasible?" thread

Postby Arc_the_Lad » Fri Mar 23 2018 7:47pm

xenometal wrote:Image

Well, that wasn't too hard.

As it is, there are 2 dummied out character slots that can be restored with minimal effort (thanks to the disassembly, of course!)

I reckon there's enough space in RAM to expand beyond 32 characters, as long as you're willing to reduce the maximum number of enemies in a given battle which is already (sort of) pratically limited to 20 due to the 32 sprites limit.

But a more pressing matter to attend to before this can be released as a proper patch would be to rewrite the map sprites and portraits assignment routines to refer a table, instead of the current hardcoded method.


Well, maybe I'll dip my toe into a hack, see how it is. I still have that idea to add a Prince to the kingdom of Galam and make him serve as Elis's true love.
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Its being invaded by the Otherworld.

A world of nightmarish delusions come to life.

My youtube channel of terrible video game talkthroughs.
Arc_the_Lad

User avatar
Restless Dreams
Shining Legend
 
Posts: 3177
Joined: Fri Sep 17 2004 1:07am
Location: Canada

Re: "Is it feasible?" thread

Postby Wiz » Fri Mar 23 2018 10:32pm

DiegoMM wrote:Now to good stuff:
Its possible expand content? I mean, max number of itens, enemies, magic, battle sprites, hero sprites. Normally a hack works replacing stuff or using some unused space (like 2 extra enemies, unused items, magic), but with the extra space the rom provides, we can expand the tables?
Other example: animation frames. Some class uses 1 or 2 sprites for some animations, promoted bowie uses 3 for attack. Imagine if more class can use more frames for animations.

I see that xenometal has already made some great Proof-of-Concept experiments which should help you feel the potential, so I'll just try to make a more generic answer for a global understanding of the matter. :)

First, let's keep things simple and consider that ROM space is just not a limitation anymore :
- We can now double the original ROM size and arrange its layout to give more space for any type of content.
- When (or should I say "if" !) the time comes for someone to reach the 4MB limit for real, then implementing ROM bankswitching would push the limits even further.

In that case, here are the most immediate limitations we'll have to face :
- Indexing
- RAM
- VRAM
- SRAM

1. Indexing limitations :
Text is indexed on two bytes, allowing potentially up to 65535 lines to be defined in 256 text banks of 256 lines each.
Apart from text, I believe all other major types of content are generally indexed on a single byte, which gives a first natural limitation of 256 entries, which would be more than enough for any type of content.
BUT : depending on which type of content you're willing to expand, be aware that more limitations can happen because of the way the game handles those index values !
For instance, sometimes the programmers knew very well the exact number of entries the game would have of a given type of content, so they just used that information as a hardcoded limit to browse data, instead of managing some kind of "end of data" code more dynamically.
Example of a function which loops on battle data with the hardcoded number of battles (see commented line with value 44) :
Code: Select all
; =============== S U B R O U T I N E =======================================

; In: D0 = map idx (if not supplied, will be pulled from CURRENT_MAP)
;     D1 = player X coord to check
;     D2 = player Y coord to check
; Out: D7 = battle idx to trigger (FFFF if none)
; ...more

GetNextBattleOnMap:
      
      movem.l d1-d6/a0,-(sp)
      move.w  d1,d4
      move.w  d2,d5
      move.w  d0,-(sp)
      cmpi.b  #$FF,d0
      bne.s   loc_79B2
      clr.w   d0
      move.b  ((CURRENT_MAP-$1000000)).w,d0
loc_79B2:
      conditionalPc lea,BattleMapCoords,a0
      moveq   #44,d6          ; HARDCODED number of battles
      clr.w   d7
loc_79BA:
      cmp.b   (a0),d0
      bne.s   loc_7A24
      move.w  #FLAGIDX_BATTLE0,d1
      add.w   d7,d1
      jsr     j_CheckFlag
      beq.s   loc_7A24
      cmpi.b  #$FF,5(a0)
      beq.w   loc_79DE
      cmp.b   5(a0),d4
      bne.w   loc_7A24
loc_79DE:
      cmpi.b  #$FF,6(a0)
      beq.w   loc_79F0
      cmp.b   6(a0),d5        ; if player is not on specified coords (bytes 5/6), then don't return battle index.
      bne.w   loc_7A24
loc_79F0:
      move.b  1(a0),((CAMERA_LOCK_START_X-$1000000)).w
      move.b  2(a0),((CAMERA_LOCK_START_Y-$1000000)).w
      move.b  3(a0),((CAMERA_LOCK_END_X-$1000000)).w
      move.b  4(a0),((CAMERA_LOCK_END_Y-$1000000)).w
      addi.w  #$64,d1 ; "Battle completed" flags
      jsr     j_CheckFlag
      beq.s   loc_7A1E
      subi.w  #$64,d1
      jsr     j_ClearFlag
loc_7A1E:
      move.w  (sp)+,d1
      bra.w   loc_7A30
loc_7A24:
      addq.l  #7,a0
      addq.w  #1,d7
loc_7A28:
      dbf     d6,loc_79BA
      moveq   #$FFFFFFFF,d7
      move.w  (sp)+,d0
loc_7A30:
      movem.l (sp)+,d1-d6/a0
      rts

   ; End of function GetNextBattleOnMap
Some other times, programmers might save space by storing other information along with the index value, on the most significant bits of the same byte !
So these are limitations that will have to be discovered case by case by studying exhaustively how the game works with a given type of content.
This will then imply some programming work to unlock such limitations. Some of them may be easy to fix (just change the battle number value in the example above ! :D), but some others may be not so easy (make the game browse a data structure without knowing the limit, dynamically up to the end) ... Let's hope xenometal will continue to produce nice Proofs-of-Concept like that ! ;)

- RAM limitations :
Some types of content require to have only one or two entries loaded at the same time (maps, portraits, battlesprites, etc.), but other kinds of data require to have everything loaded at the same time : characters most notably !
RAM space is already well occupied with space for character/enemy data, and multi-purposed spaces for graphics decompression, map layouts, IA, etc.
So anything requiring more RAM space, like new characters with their stats, implies to make sure there is actual free space for that at the end of this RAM data structure. If there isn't, then this would imply to re-arrange the way RAM space is organized for the game, which may imply quite major modifications in the game engine. Good luck with that. ;)

- VRAM limitations :
I suppose the 32-sprite limitation you guys are talking about must be related to the limited RAM space for the VDP, so yeah, this is the kind of thing that implies to modify the game engine even more deeply than just managing RAM allocations. Nothing impossible, but quite a complex task !

- SRAM limitations :
Well, adding more characters implies more space for your saves, so yeah, don't forget that part ! ;) But it's not such a problem actually : for SF2, SRAM space can be doubled from 16KB to 32KB quite easily.


Now about battle sprite animation frames : SF2BattleSpriteAnimationEditor allows up to 16 frames per animation.
If I remember correctly, there was no real limitation and you could make up to 256 frames if you wanted to, but I decided to make a 16-frames limitation just to avoid too silly things. Let's make normal things first ! :D
Wiz

User avatar
Shining Member
Shining Member
 
Posts: 147
Joined: Sun Mar 18 2007 2:43pm
Location: Blois, France

Next

Return to Shining Force II

Who is online

Users viewing this topic: No registered users and 0 guests