Editing Deep Buffering

Jump to navigation Jump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
=Introduction=
=Introduction=
Deep Buffering (originally known as "Buffering Step 2") is a slightly more advanced, more fine-grained approach to handling [[command buffering]] in the M.U.G.E.N engine co-developed by Vans and Jesuszilla. It is a direct descendant of the [[Tiny Buffering]] system by Vans. What makes Deep Buffering unique is that it completely bypasses M.U.G.E.N's command sequence interpreter in favor of its own implementation through use of bitwise arithmetic. It is based on Capcom vs. SNK 2's command buffering and interpreter.
Deep Buffering is a slightly more advanced, more fine-grained approach to handling [[command buffering]] in the M.U.G.E.N engine co-developed by Vans and Jesuszilla. It is a direct descendant of the [[Tiny Buffering]] system by Vans. What makes Deep Buffering unique is that it completely bypasses M.U.G.E.N's command sequence interpreter in favor of its own implementation through use of bitwise arithmetic. It is based on Capcom vs. SNK 2's command buffering and interpreter.


=Differences from Tiny Buffering=
=Differences from Tiny Buffering=
Line 15: Line 15:


<ul>
<ul>
<li>Press - The initial state. The corresponding bit is set to 1 as soon as M.U.G.E.N interprets the press for the button. This uses the button hold directly provided by M.U.G.E.N. and the direction hold/press directly provided by M.U.G.E.N.</li>
<li>Press - The initial state. The corresponding bit is set to 1 as soon as M.U.G.E.N interprets the press for the button. This uses the button press/hold directly provided by M.U.G.E.N.</li>
<li>Hold - Calculated at the same time as the initial press. This is determined by taking the bitwise OR of the last command in the Hold variable after its elements have been shifted by 1 tick (4 bits right for directions, and 7 bits right for buttons) and the current Hold state. This also uses the button press/hold directly provided by M.U.G.E.N.</li>
<li>Hold - Calculated at the same time as the initial press. This is determined by taking the bitwise OR of the last command in the Hold variable after its elements have been shifted by 1 tick (4 bits right for directions, and 7 bits right for buttons) and the current Hold state. This also uses the button press/hold directly provided by M.U.G.E.N.</li>
<li>Release - Calculated 1 tick later than the last hold. This is calculated by checking the bits of the last command in the Hold variable after its elements have been shifted by 1 tick (4 bits right for directions, and 7 bits right for buttons) and the current Hold state.</li>
<li>Release - Calculated 1 tick later than the last hold. This is calculated by checking the bits of the last command in the Hold variable after its elements have been shifted by 1 tick (4 bits right for directions, and 7 bits right for buttons) and the current Hold state.</li>
Line 103: Line 103:
Check if any of the inputs in any of the variables are active for the current sequence in the full command, then:
Check if any of the inputs in any of the variables are active for the current sequence in the full command, then:
<ul>
<ul>
<li>If it's active, set the upper 28 bits to the new sequence number, and set the lower 4 bits to <math>t_e</math>.</li>
<li>If it's active, zero out the current sequence bit in the command check, set the next sequence bit to 1, and set the lower 4 bits to <math>t_e</math>.</li>
<li>If the time has expired for the current sequence (all the first 4 bits are 0), then reset the entire command check to 0.</li>
<li>If the time has expired for the current sequence (all the first 4 bits are 0), then reset the entire command check to 0.</li>
</ul>
</ul>
</li>
</li>
<li>Check for whether or not the sequence number matches the final element number. If it does, then the command is complete.</li>
<li>Check for whether or not the uppermost required sequence bit is set. If it is, then the command is complete.</li>
</ol>
</ol>


Line 123: Line 123:
</syntaxhighlight>
</syntaxhighlight>


With that said, it is possible in this system to store and interpret any command sequence with 268,435,455 or fewer elements with each up to 15 ticks of buffer time.
With that said, it is possible in this system to store and interpret any command sequence with 28 or fewer elements with each up to 15 ticks of buffer time.


The sequence for interpreting a Hadouken (<code>/D,DF,F,x</code>) could go as follows, if the buffering times for buttons and directions are both 2 (<math>t_b = 2</math> and <math>t_d = 2</math>) and the element buffering time is 9 (<math>t_e = 9</math>). All bits go from least significant bit on the left to most significant bit on the right. Thus, the first bit is 1, the second is 2, the third is 4, etc.
The sequence for interpreting a Hadouken (<code>/D,DF,F,x</code>) could go as follows, if the buffering times for buttons and directions are both 2 (<math>t_b = 2</math> and <math>t_d = 2</math>) and the element buffering time is 9 (<math>t_e = 9</math>). All bits go from least significant bit on the left to most significant bit on the right. Thus, the first bit is 1, the second is 2, the third is 4, etc.
Line 238: Line 238:


Var(20) (Check):
Var(20) (Check):
1001 1100000000000000000000000000 ; Reset to 9, next element check (command considered complete)
1001 0010000000000000000000000000 ; Reset to 9, next element check (command considered complete)
</syntaxhighlight>
</syntaxhighlight>


Line 257: Line 257:


Var(20) (Check):
Var(20) (Check):
0001 1100000000000000000000000000 ; Still counting down
0001 0010000000000000000000000000 ; Still counting down
</syntaxhighlight>
</syntaxhighlight>


Line 276: Line 276:


Var(20) (Check):
Var(20) (Check):
1110 1100000000000000000000000000 ; Still counting down
1110 0010000000000000000000000000 ; Still counting down
</syntaxhighlight>
</syntaxhighlight>


Line 283: Line 283:
The logic for the Hadouken example (helper side) can thus be constructed as follows:
The logic for the Hadouken example (helper side) can thus be constructed as follows:
<syntaxhighlight lang="INI">
<syntaxhighlight lang="INI">
[State 10372, QCF Init]
[State 10380, QCF Init]
type = Null
type = Null
trigger1 = !Var(20)  && ((var(4)&240) = 32 || (var(4)&15) = 2)
trigger1 = !Var(20)  && ((var(4)&240) = 32 || (var(4)&15) = 2)
trigger1 = e||(var(20) := 9 + (2**4)*1)
trigger1 = e||(var(20) := 9 + (2**4))


trigger2 = (Var(20)/(2**4)) = 1 && ((var(3)&240) = 160 || (var(3)&15) = 10)
trigger2 = (Var(20)&(2**5 - 1)) > (2**4) && ((var(3)&240) = 160 || (var(3)&15) = 10)
trigger2 = e||(var(20) := 9 + (2**4)*2)
trigger2 = e||(var(20) := 9 + (2**5))


trigger3 = (Var(20)/(2**4)) = 2 && ((var(3)&240) = 128 || (var(3)&15) = 8)
trigger3 = (Var(20)&(2**6 - 1)) > (2**5) && ((var(3)&240) = 128 || (var(3)&15) = 8)
trigger3 = e||(var(20) := 9 + (2**4)*3)
trigger3 = e||(var(20) := 9 + (2**6))


trigger4 = Var(20) && (Var(20)&15) = 0
trigger4 = Var(20) && (Var(20)&15) = 0
Line 301: Line 301:
... and this can be used along with the following trigger:
... and this can be used along with the following trigger:
<syntaxhighlight lang="INI">
<syntaxhighlight lang="INI">
triggerall = (helper(10372), Var(20)/(2**4)) = 3
triggerall = (helper(10371), Var(20)&(2**7 - 1)) > (2**6)
triggerall = (helper(10372), var(0)&129)) > 0
triggerall = (helper(10371), var(0)&129)) > 0
</syntaxhighlight>
</syntaxhighlight>


Line 311: Line 311:
value = 1000
value = 1000
triggerall = !AILevel
triggerall = !AILevel
triggerall = numHelper(10372)
triggerall = numHelper(10371)
triggerall = (helper(10372), Var(20)/(2**4)) = 3                                                  ; Command detect
triggerall = (helper(10371), Var(20)&(2**7 - 1)) > (2**6)                                         ; Command detect
triggerall = (helper(10372), Var(0)&16383) > 0 || ((helper(10372), Var(2)&16383) > 0 && !Var(30)) ; Button detect (x,y,z,~x,~y, or ~z)
triggerall = (helper(10371), Var(0)&16383) > 0 || ((helper(10371), Var(2)&16383) > 0 && !Var(30)) ; Button detect (x,y,z,~x,~y, or ~z)
triggerall = statetype != A
triggerall = statetype != A
triggerall = roundstate = 2
triggerall = roundstate = 2
Line 343: Line 343:


==Simplifying Triggers==
==Simplifying Triggers==
By using one extra variable, readability of characters that utilize Deep Buffering can be improved. The idea is to store each command as its own bit in a separate variable, that way only one single variable needs to be checked for the command itself in the .CMD. Bitwise operators are still required, but access is much simpler than creating large masks of arbitrary command lengths. The following example is taken from Jesuszilla's CvS2 Eagle buffering.vns:
By using one extra variable, readability of characters that utilize Deep Buffering can be improved. The idea is to store each command as its own bit in a separate variable, that way only one single variable needs to be checked for the command itself in the .CMD. Bitwise operators are still required, but access is much simpler than creating large masks of arbitrary command lengths. The following example is taken from Jesuszilla's PotS-style Felicia's buffering.vns:


<syntaxhighlight lang="INI">
<syntaxhighlight lang="INI">
[State 10372, Command Active]
[State 10380, Command Active]
type = Null
type = Null
trigger1 = e||(var(59) := 0) ; INIT
trigger1 = e||(var(59) := 0) ; INIT
trigger1 = e||(var(59) := (var(59)|((2**29)*((Var(54)/(2**4)) = 1)))) ; DU
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 1, 0))*((Var(20)&(2**7  - 1)) > (2**6))))) ; QCF
trigger1 = e||(var(59) := (var(59)|((2**30)*((Var(55)/(2**4)) = 2)))) ; FF
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 0, 1))*((Var(21)&(2**7  - 1)) > (2**6))))) ; QCB
trigger1 = e||(var(59) := (var(59)|(-2147483648*((Var(56)/(2**4)) = 2)))) ; BB
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 3, 2))*((Var(22)&(2**7  - 1)) > (2**6))))) ; DP
trigger1 = !root, numProjID(131035) ; Chizuru seal
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 2, 3))*((Var(23)&(2**7  - 1)) > (2**6))))) ; rDP
trigger1 = e||(var(59) := (var(59)|((2**0)*((Var(20)/(2**4)) = 3)))) ; QCF
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 5, 4))*((Var(24)&(2**9  - 1)) > (2**8))))) ; HCB
trigger1 = e||(var(59) := (var(59)|((2**1)*((Var(21)/(2**4)) = 3)))) ; QCB
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 4, 5))*((Var(25)&(2**9  - 1)) > (2**8))))) ; HCF
trigger1 = e||(var(59) := (var(59)|((2**2)*((Var(22)/(2**4)) = 3)))) ; DP
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 7, 6))*((Var(40)&(2**10 - 1)) > (2**9))))) ; HCB,F
trigger1 = e||(var(59) := (var(59)|((2**3)*((Var(23)/(2**4)) = 3)))) ; rDP
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 6, 7))*((Var(41)&(2**10 - 1)) > (2**9))))) ; HCF,B
trigger1 = e||(var(59) := (var(59)|((2**4)*((Var(24)/(2**4)) = 5)))) ; HCB
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 9, 8))*((Var(42)&(2**9  - 1)) > (2**8))))) ; HCFx2
trigger1 = e||(var(59) := (var(59)|((2**5)*((Var(25)/(2**4)) = 5)))) ; HCF
trigger1 = e||(var(59) := (var(59)|((2**cond(P2Dist X < 0, 8, 9))*((Var(43)&(2**9  - 1)) > (2**8))))) ; HCBx2
trigger1 = e||(var(59) := (var(59)|((2**6)*((Var(40)/(2**4)) = 5)))) ; QCFx2
trigger1 = e||(var(59) := (var(59)|((2**10)*                     ((Var(53)&(2**6  - 1)) > (2**5))))) ; DD
trigger1 = e||(var(59) := (var(59)|((2**7)*((Var(41)/(2**4)) = 5)))) ; QCBx2
trigger1 = e||(var(59) := (var(59)|((2**29)*                     ((Var(54)&(2**6  - 1)) > (2**5))))) ; DU
trigger1 = e||(var(59) := (var(59)|(cond(P2Dist X < 0, -2147483648, 2**30)*((Var(55)&(2**6  - 1)) > (2**5))))) ; FF
trigger1 = e||(var(59) := (var(59)|(cond(P2Dist X < 0, 2**30, -2147483648)*((Var(56)&(2**6  - 1)) > (2**5))))) ; BB
ignorehitpause = 1
ignorehitpause = 1
</syntaxhighlight>
</syntaxhighlight>
Line 366: Line 368:
Each special command is given its own bit and reversed as necessary to indicate flipped commands. The QCF command can be checked with one simple trigger with this:
Each special command is given its own bit and reversed as necessary to indicate flipped commands. The QCF command can be checked with one simple trigger with this:
<syntaxhighlight lang="INI">
<syntaxhighlight lang="INI">
triggerall = (helper(10372), Var(59)&(2**0)) > 0
triggerall = (helper(10371), Var(59)&(2**0)) > 0
</syntaxhighlight>
</syntaxhighlight>


Please note that all contributions to mugen-net may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see Mugen-net:Copyrights for details). Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)