MAMEWorld >> EmuChat
Previous thread Previous  View all threads Index   Next thread Next   Flat Mode Flat  

Rotwang
Life is too short to be little...
Reged: 03/21/17
Posts: 109
Send PM
Digging into the secrets of SFII: Rainbow Edition
01/01/21 08:41 PM


I have always been curious about what exactly is going on beneath the hood of some of these SFII:CE bootlegs. Seems to me that the best place to start would be the king of bootlegs, SFII: Rainbow Edition. The romset sf2rb seems to be based on a World region build of revision 920322. No known official World release of 920322 exists, but the Japanese romset sf2ceja shares this revision date, and apart from the new code inserted by the hackers and the region switch itself, the code and data all seems to be in the same locations. I did a file compare in a hex editor to see where the hackers made changes.

The first differences appear at $C84 which is in a part of the program used to skip frames. This effect can be seen when pressing a button during the region warning text screen to make it draw faster, and while holding down buttons during victory poses to speed up the arrival of the next round. This is where the hackers have injected their own code for a rudimentary turbo mode. To be clear, this is different from the walking speed increases that each character received.

I have only heard scattered anecdotes that Rainbow Edition even HAS a turbo mode, but never a definitive explanation of how it works. Here is that definitive explanation. What the hackers have done is hijack the game's existing frame skip code and add a counter-based system that will run the frame skip code in controlled bursts.


Code:

rb_turbomode:
0E5478 clr.w D4
0E547A move.w ($9c0,A5), D0 ; Matches Cleared counter
0E547E move.w D0, D3 ; Preserve Matches Cleared counter to d3
0E5480 move.b ($64c,A5), D1 ; 1P human (0) or CPU (1)
0E5484 or.b ($94c,A5), D1 ; 2P human (0) or CPU (1)
0E5488 beq rb_turbo_noturbo ; $e54dc ; branch out of turbo if this is a PVP game
0E548C move.b ($87,A5), D4 ; load DIP switch bank B
0E5490 lsr.b #4, D4 ; Shift switches 5 through 8 right.
; Bit mask according to switch numbers:
; XXXX 8765
; These switches are documented as
; unused in SFII:CE manual.
0E5492 andi.w #$f, D4
0E5496 btst #$3, D4 ; Test highest bit of DIP bank B (switch 8)
0E549A beq rb_turbo_fixed ; $e554c ; Branch to Fixed Turbo mode if switch 8 is off
0E549E bclr #$3, D4 ; Switch 8 is on, and we are in Variable Turbo mode
; Clear switch 8 from our dip read
0E54A2 move.w (-$6f2e,A5), D1 ; Load preserved round clear counter
0E54A6 cmpi.b #$7, D4 ; A comparison with no action taken after.
0E54AA move.w #$0, D1
0E54AE sub.b D1, D0 ; A weird way of checking if matches cleared counter is zero.
0E54B0 bls rb_turbo_noturbo ; Branch out of turbo if this is the first match
0E54B4 mulu.w #$c, D4 ; Multiply dip B 5,6,7 values to create turbo table base offset
0E54B8 add.w D4, D0 ; Add to rounds cleared counter to create final offset
0E54BA move.b ($30,PC,D0.w), D1 ; Load turbo counter max value
0E54BE move.b (-$6f30,A5), D0 ; Load turbo counter current value
0E54C2 cmp.b D1, D0 ; Compare current turbo value to max
0E54C4 bhi rb_turbo_clearcounter ;$e54d2 ; Branch if turbo counter max exceeded

rb_turbo_incrementcounter
0E54C8 addq.b #1, (-$6f30,A5) ; Increment turbo counter
0E54CC movem.l (A7)+, D0-D4/A1 ; Pull register values from stack and return
0E54D0 rts

rb_turbo_clearcounter
0E54D2 clr.b (-$6f30,A5) ; reset turbo counter (returns with Z flag set, frame skip will run)
0E54D6 movem.l (A7)+, D0-D4/A1
0E54DA rts

rb_turbo_noturbo
0E54DC move.w D3, (-$6f2e,A5) ; Store matches cleared counter
0E54E0 move.b #$1, (-$6f30,A5) ; Store 1 at turbo counter
0E54E6 movem.l (A7)+, D0-D4/A1 ; Pull register values from stack and return
0E54EA rts

rb_turbo_fixed:
0E554C tst.b D4 ; Test D4 to see if any of switches 5,6,7 are set
0E554E beq $e54dc ; Branch out of turbo if no switches set.
0E5550 move.b ($10,PC,D4.w), D1 ; This turbo mode doesn't use the matches cleared counter.
; Dip B 5,6,7 control the turbo counter max values.
0E5554 move.b (-$6f30,A5), D0
0E5558 cmp.b D1, D0
0E555A bhi rb_turbo_clearcounter ;$e54d2 ; Clear turbo counter
0E555E bra rb_turbo_incrementcounter ;$e54c8 ; Increment turbo counter



First thing sf2rb's turbo code does is check if both players are human controlled. If so, it will return out of turbo mode and not speed up the game. The hackers wanted their turbo feature to only work during CPU battles.

Sf2rb has utilized four dip switches that were unused in the original SFII:CE. Dip bank B, switches 5, 6, 7, and 8 now control sf2rb's turbo mode. In fact, sf2rb has added two different turbo modes for operators to choose between. Turbo mode will not run at all if Dip B SW 5,6,7,8 are all off. SW 8 controls which of the two turbo modes will run. Since nobody else has given these a name, I will call these modes Fixed Turbo and Variable Turbo.

Fixed Turbo is enabled by setting DIP B SW 8 to OFF and any of DIP B SW 5,6,7 (let's call these the turbo intensity switches) to ON. The turbo intensity switches is used as an offset to a table of values that control how fast the game runs. The full list of turbo values for Fixed Turbo mode are:


Code:

80 50 40 30 28 18 10 08 04 02



However, since Fixed Turbo mode can only run if any of the turbo intensity switches are set, the first value #$80 goes entirely unused. Likewise, the highest value we can get from that table with the 3 switches is #$08, and the last 2 values can never be read.

Variable Turbo makes the game go faster based on a combination of which Turbo Intensity switches are set, and how many matches the player has cleared. The player has to clear at least one match (flag crossed out on world map) for Variable Turbo to run. The higher the turbo intensity switches, and the more matches have been cleared, the faster the game will run. After a certain point it becomes virtually unplayable.

Now, how does this actually affect the game itself?

RB's turbo code controls a counter that the hackers set aside in an unused section of RAM. Whenever either of sf2rb's turbo modes runs, it will check this counter against the turbo value, and if the counter has exceeded the turbo value, the counter will be reset. Otherwise, the counter is incremented. What's happening is when this new subroutine returns back to SFII:CE's existing turbo code, it uses the zero flag to determine whether it will skip a frame or not using the original game's turbo mode where this hijack was inserted into. If the turbo counter was reset, then it returns with the zero flag set, and the frame gets skipped. The lower the turbo value, the more often the code will return zero and a frame will get skipped. Sort of like a controlled trickle of the game's existing turbo function.

So, to summarize the rules of Street Fighter II: Rainbow Edition's turbo modes:

- Only works during a fight against a CPU opponent.
- DIP bank B switch 8 selects between Fixed Turbo (OFF) and Variable Turbo (ON)
- DIP bank B switches 5, 6 and 7 control the intensity of the turbo modes.
- Variable Turbo only works after you have cleared at least one match off the world map.
- Variable Turbo becomes faster the more matches you clear.
- Fixed Turbo's speed is controlled solely by the turbo intensity switches and works even if you haven't cleared any matches yet.


Here is a dip switch setting table for Rainbow Edition's turbo modes:


Code:


DIP SWITCH BANK B
5 6 7 8
============================
OFF OFF OFF OFF | Turbo Disabled
ON OFF OFF OFF | Fixed Turbo 1
OFF ON OFF OFF | Fixed Turbo 2
ON ON OFF OFF | Fixed Turbo 3
OFF OFF ON OFF | Fixed Turbo 4
ON OFF ON OFF | Fixed Turbo 5
OFF ON ON OFF | Fixed Turbo 6
ON ON ON OFF | Fixed Turbo 7
OFF OFF OFF ON | Variable Turbo 1
ON OFF OFF ON | Variable Turbo 2
OFF ON OFF ON | Variable Turbo 3
ON ON OFF ON | Variable Turbo 4
OFF OFF ON ON | Variable Turbo 5
ON OFF ON ON | Variable Turbo 6
OFF ON ON ON | Variable Turbo 7
ON ON ON ON | Variable Turbo 8



I can show my work for all this, but I'm not sure what the rules are concerning posting disassembled code here.

EDIT: Included disassembly of Rainbow Edition's turbo code with comments

Edited by Rotwang (01/02/21 09:41 PM)







Entire thread
Subject Posted by Posted on
* Digging into the secrets of SFII: Rainbow Edition Rotwang 01/01/21 08:41 PM
. * Re: Secrets of SFII' Rainbow (CPU opponents, in-air moves, title colors) Rotwang  01/28/21 08:48 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition fortuna_chan  01/13/21 09:25 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition Rotwang  01/14/21 05:07 AM
. * Re: Digging into the secrets of SFII: Rainbow Edition fortuna_chan  01/14/21 11:58 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition Vas Crabb  01/11/21 06:41 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition (Fireballs) Rotwang  01/12/21 08:24 AM
. * Re: Digging into the secrets of SFII: Rainbow Edition (Fireballs) Vas Crabb  01/12/21 10:32 AM
. * Re: Digging into the secrets of SFII: Rainbow Edition (Fireballs) CiroConsentino  01/14/21 01:02 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition Vas Crabb  01/02/21 05:33 AM
. * Re: Digging into the secrets of SFII: Rainbow Edition Rotwang  01/02/21 10:06 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition Haze  01/02/21 10:24 PM
. * Re: Digging into the secrets of SFII: Rainbow Edition Rotwang  01/03/21 07:37 AM
. * Re: Digging into the secrets of SFII: Rainbow Edition RobbbertModerator  01/05/21 01:07 PM

Extra information Permissions
Moderator:  Robbbert, Tafoid 
0 registered and 211 anonymous users are browsing this forum.
You cannot start new topics
You cannot reply to topics
HTML is enabled
UBBCode is enabled
Thread views: 1190