case studyUpdated Sep 21, 202626 min read$3A

Four Players, Two Games: Cross Fever for MVC1 and MSH vs. SF

Four independent fighters now run in local MVC1 and MSH vs. SF prototypes. The shared Cross Fever project, real 2v2 footage, native controls, countdowns and the work still needed.

Jump to evidence
cps2marvel-vs-capcommarvel-super-heroes-vs-street-fighterdreamcastfour-player
CPS-2 Reverse EngineeringPart 46 of 46
Browse all writing
On this page

Four independent controllers now drive four fighters at once in local prototypes of both arcade Marvel vs. Capcom and Marvel Super Heroes vs. Street Fighter. MVC1 builds on its existing Variable Cross. MSH vs. SF gains a new timed mode: the partners land, remain in the fight and accept their own commands.

For MSH vs. SF, that changes what a team can do. One person can move while their partner attacks. Both can start their own Hypers. When the other team activates too, the match becomes sustained two-on-two fighting, with four people making decisions at the same time. The recordings below replay four input streams; a live four-person session is still a separate test.

This starts from Dreamcast MVC1's Cross Fever, then writes the behavior for each CPS-2 engine. The full target includes the dedicated mode timer and HUD, and the MVC-style meteor background during the mode. Those visible parts are part of the feature, alongside control ownership and safe entry and exit.

The MVC1 meteor background has not been ported to MSH vs. SF yet. The MSH prototype has timed 2v2. The new msh-exact-time-11 screenshots below show MVC1's original blue TIME artwork and separate depletion for both teams. The earlier combat footage still uses MSH's existing backgrounds. The graphics-space investigation below explains what remains before both games have the same presentation.

An older input-switching setup gives one person the active fighter and hands control to their teammate after a tag. That lets four friends take turns. The project here also needs both teammates to enter different commands while they are on screen together, after the entrance animation has finished.

One feature contract, two implementations

The shared command layout assigns QCB + HP + HK to the timed mode: quarter-circle back with heavy punch and heavy kick. QCF + HP + HK, quarter-circle forward with those same buttons, keeps the existing team Super. MVC1 already has Variable Cross as the foundation; MSH vs. SF needs a new sustained mode around its own partner logic. The command and feature contract are shared, not the games' addresses or code.

RequirementMVC1 evidence so farMSH vs. SF evidence so far
A human stays with their fighter through a tagNative four-controller prototype; all 15 standard characters receive all six attack buttons in sampled runsInitial ownership prototype; ordinary tags promote P3/P4 with independent six-button inputs
Both teammates remain freely controlled; both teams can create sustained 2v2Simultaneous Variable Cross captured and sampled; short-input loss still blocks acceptanceNew timed mode captured; current combined08 also passes 264/264 sampled inputs after partner entrance
QCB timed mode; QCF team Super retainedUses the existing Variable Cross path; broader command/lifecycle cases remain openQCB activates the new mode; QCF retains its prescribed team Hyper in the bounded comparison, with a measured timing difference
A mode countdown for each team, separate from the round clockAlternating countdown measured; native TIME display tracedOriginal blue MVC1 frame/masks rendered in 11; 22,900 opaque pixel comparisons across 14 screenshots match exactly
MVC-style meteor presentation while the mode runsNative activation, palette animation and final restoration traced in one ordinary-input runNot ported; the first lossless packing proposal conflicts with existing stage graphics
Clean expiry, KO and return to ordinary tag playNatural expiry, repeated cycles, joins and a rematch observed; full lifecycle matrix openIn 11, one natural point KO restores the living partner's P4 controls; the other timer continues and palettes restore after expiry. Full-round and broader KO cases remain open

This table is the implementation status, not a release checklist that has already passed. The detailed results below stay attached to the exact build that produced them.

Development report — both games remain prototypes

MVC1 has a captured four-controller prototype and a later 418-byte build with broader input, timer and save/load evidence. MSH vs. SF now has a separate timed 2v2 prototype, including independent commands and free Hypers. Neither is a finished release. Short-input preservation, MSH presentation, full lifecycle coverage, physical controls and four-player rollback remain acceptance work. This report publishes the measured progress; it does not announce a finished patch.

MSH vs. SF: four fighters stay in the fight

This is Ryu and Ken versus Spider-Man and Captain America in the new timed mode. The four panels show the controller switches and the corresponding input word received by each fighter. Different illuminated buttons mean different owners are issuing commands at the same time.

clip · loops
msh-timed-03: 771 consecutive captured frames, 5120–5890, at 59.63 fps. Ordinary input replay; silent, no interpolation. The timer numbers below the game are diagnostic annotations. This build predates the new in-game HUD and four-person selection flow, and has no meteor background.

In the full recording, all four remain active across 997 sampled callbacks. The previous ownership-only build, given the same inputs, overlaps all four for just 17 callbacks and never activates the timed mode. The longer result is not just the entrance portion of the existing team attack.

MVC1: the existing Variable Cross becomes four-player

The footage is Zangief and Ryu versus Spider-Man and Captain America, with all four fighters present during simultaneous Variable Cross. Ordinary inputs run through a local diagnostic emulator, without gameplay-memory writes or a loaded save state. This is a controller replay, not a live session recorded with four people, and it does not show the MSH vs. SF prototype.

clip · loops
Original native-freeplay-01 build (294 bytes): 620 consecutive frames, 5100–5719, at 59.63 fps. Same-frame controller overlay; silent, no interpolation. This footage predates the translated timer and later join fixes.

The video is an unaltered copy of the diagnostic render. Its game images and four-controller overlay are captured evidence, not an animated reconstruction. The two TIME bars sit above the level meters, apart from the round clock, and the meteor backdrop is visible. A later instrumented run follows the native background's activation and restoration; this older clip retains its own build identity and timer behavior.

A team is not a controller

Both arcade engines already know that two fighters belong to one team. That team identity affects much more than buttons: opponents, projectiles, meter, tags, and who can hit whom.

Giving the partner another controller must not turn them into a third team. The change needs a separate owner for each fighter's inputs while preserving the game's two-team rules. A tag changes who is active, not which human owns the character. Pressed and released buttons also need their own history; copying only the held buttons can manufacture a command at the moment of a tag.

SituationIntended four-player behavior
Ordinary playThe active fighter's owner controls that fighter.
A tagThe other fighter enters under their own owner's controls.
One team's timed modeBoth teammates can enter different directions and attacks.
Both teams' timed modesAll four owners can act independently in the same frame.
Mode expiry or a knockoutThe game's team lifecycle restores a valid point and partner.

The last row matters as much as the spectacular one. Four moving characters are only a start if the game loses control of a partner when the timer ends.

The board has four-player inputs, with a catch

The MAME CPS-2 driver describes both four-player games and six-button fighting games. Those are not the same wiring arrangement. The extra lines used for players three and four also carry kick inputs in the usual two-player fighter setup.

Both input prototypes use four direction-and-four-button groups, then repurpose start and coin lines for the remaining two buttons per person. These are active-low hardware inputs: bits 0–3 in each controller byte are Right, Left, Down and Up; bits 4–7 are LP, MP, HP and LK.

HumanDirections + LP / MP / HP / LKMKHKMVC1 fighter object
P1IN0 ($804000), low byteIN2 bit 8IN2 bit 12$FF3000
P2IN0, high byteIN2 bit 9IN2 bit 13$FF3400
P3IN1 ($804010), low byteIN2 bit 10IN2 bit 14$FF3800
P4IN1, high byteIN2 bit 11IN2 bit 15$FF3C00

IN2 is at $804020. Its service and EEPROM bits retain their meaning. Teams are P1/P3 versus P2/P4; the extra humans are partners, not extra teams.

Native control routing: P1 and P3 form team A in green; P2 and P4 form team B in cyan. Each controller passes through the native CPS-2 input sampler into its own fighter's command history. Tags change active roles while controller ownership stays with the fighter.

These MVC1 actor addresses do not carry over to MSH vs. SF; that engine uses its own object layout. The controller wiring is the shared input profile.

Consuming the start and coin lines requires a separate joining policy. MVC1 implements free play: a fresh HP+HK chord joins the team, and both buttons must be released before another join. Each human owns a character-selection cursor. The MVC1 join-fix build also permits joining during the attract demo and lets an unjoined team challenge an existing game; joined players keep ordinary combat HP+HK.

The first build had a subtle bug: holding the chord across a natural timeout could invent a Start press on the first victory frame. The new reader tracks the combat boundary and keeps that controller's latch set until both buttons release. All 14 bounded join checks pass, including partial release, fresh repress, selection, tags and held-through-reset behavior. A chord newly pressed on the exact exit boundary also needs release and repress; that conservative policy is explicit, not an inferred Dreamcast rule. The stock Test menu opens. MSH vs. SF now has its own selection and join implementation, with 44 scoped checks on the later combined build. Its combat footage above predates that integration.

The arrangement still needs an explicit cabinet pin map and a simultaneous-input check. An emulator exposing four controllers does not prove that a particular cabinet harness can carry them, especially if a coin interface stretches switch pulses instead of preserving attack-button timing.

Phoenix packaging is a different problem. Decrypted code can help a board boot without its original encryption setup. It does not add controller inputs or make Dreamcast instructions executable by a CPS-2 processor.

Bring over the behavior, then write for the target

Dreamcast and CPS-2 use different processors. A Dreamcast routine cannot simply be dropped into the arcade program. The useful things to recover are the rules: controller assignment, partner admission, command history, timer handling, knockouts and the return to ordinary tag play.

MVC1 is a promising target because its native Variable Cross already puts both teammates into the fight. The investigation follows that path, then audits the places where the arcade engine assumes both teammates share one input stream. The intended result is a ROM-side control path using the board's input ports, not an emulator watching a tag and swapping two people's buttons.

What the Dreamcast binary actually shows

The stock USA Dreamcast executable examined here is the 4,930,596-byte 0.BIN, with SHA-256 785c8691e7c2a0fcbeeef6c478db960fef7c354cd9eb9bb6d6fd7b5b92526db5. The load base is $8C010000; these are little-endian SH-4 addresses.

Static findingAddress and meaning
Four physical controllers are polled$8C0110A0 calls $8C0110C2 for all four indices. Records at $8CC91B30 + index × $20 keep separate current, previous and edge inputs.
The four-controller route preserves both teammatesIn the distributor at $8C015644, the nonzero $8C4EC06C path at $8C01583A pairs ports 0/2 and 1/3. Selector bytes $8C4EC06D/E exchange primary and other-member routes.
Input is chosen for the actor being processed$8C029E40–$8C029EB8 selects by actor side byte +3 and primary/other-member byte +$275, then passes current/previous words through the actor's command parser to +$CE/+$D0.
A menu path enables this distributionEntry 4 at $8C05529C checks four-controller availability and writes 1 to $8C4EC06C at $8C0552B0.

This short semantic excerpt describes the recovered routing; it is not portable source code or a replacement for the separate runtime observations:

poll controller[0..3], retaining each current / previous / edge record
when the four-controller flag is set:
    team A receives ports 0 and 2
    team B receives ports 1 and 3
for the actor being processed:
    choose that side's primary or other-member input stream
    run the actor's ordinary command parser

The candidate activation window at $8C02DD70–$8C02DD9E also gives a concrete timer calculation: it indexes [0, 192, 384, 576] by actor level byte +$26C, adds half the unsigned word at +$26A rounded down, and stores the result at +$50. That proves arithmetic in this binary. It does not establish seconds, hitstop behavior, the command that reaches it, or observed four-human gameplay. The separate Dreamcast diagnostic trace has observed four input streams, a tag, both-team activation and two visible TIME bars. Broader knockout and expiry variants still need captures. The donor's Cross Fever countdown uses an alternating game-counter bit, while ordinary mode decrements on each eligible call. The latest MVC1 build translates that rule and measures its executed timer path; the MVC1 video above still shows the older stock-timer candidate. This does not establish complete Dreamcast timing parity. Expiry can remove either the activator or the partner depending on state; one observed exit is not a universal rule.

The countdown and background are separate work

The mode's countdown answers a different question from the round clock: how long may this team keep both fighters active? Each team needs its own visible remaining-time display, including when one team activates later than the other. A change to countdown arithmetic alone does not establish that the right bar appears, updates, pauses and clears in every mode transition.

In the Dreamcast binary, $8C02DE14–$8C02DE24 and $8C02DEAA–$8C02DEBA mirror actor time into side words $8C4EBB3A/3C and enable side bits at $8C4EBB3E. The recovered HUD consumers use those words, and the diagnostic capture shows two TIME bars. A separate consumer at $8C05C438 appears to drive controller peripheral effects; it is not evidence of a meteor background renderer.

The sustained backdrop must also be distinguished from the short Hyper activation flash. The later CPS-2 MVC1 investigation identifies its tilemap, palette animation and background-union cleanup. Those findings come from native arcade execution and graphics analysis, separately from the Dreamcast controller and timer findings.

MVC1: build the native control path

The measured baseline is stock MVC1 Euro 980123, archive SHA-256 fbb9c9a0fc44c6f26481cc018bdd13d9aac5376806e736c428c4b54b274c032c. Its decoded opcode image is pinned separately as 7ede16dc56ffbefe899f98608c6b0a01f2304cd3e8c46da9f912ee0b9bcf7490.

The initial input spike uses 162 bytes at $3F1000 inside the existing 4 MiB program region, with no expansion ROM or additional work RAM. It replaces the sampler at $000D12 and the human-input selector at $01368E, choosing the controller by the fighter object's stable address. Team byte +02, human flag +03, point/partner role +$281, and the existing input histories at +$D0–+$DA remain part of the stock engine.

The filmed native-freeplay-01 candidate expands the native reader and menu integration to 294 bytes, still within the stock 4 MiB program region with no additional ROM or work RAM. It uses the existing free-play initialization path and retains separate join-release latches.

The next timer-only build, native-cross-fever-01, occupies 330 bytes. The pinned native-cross-fever-02 combines that timer with the join fixes in 418 bytes, still using the stock 4 MiB program and existing work RAM. It retains the stock activation, meter and exit paths. At $015F58, the new timer path preserves the debug-pause check and decrements on the odd phase of $FF4488, a counter shared by the team/game update. Existing life/freeze gates run before the hook.

The existing free-play byte $FF449B keeps bit 0 as true, uses bit 1 to remember human combat, and bits 4–7 as each controller's release latch. The recorded stock consumers test zero/nonzero. Separate configuration defines keep the older 294- and 330-byte payloads reproducible without the new join behavior.

MVC1 results by build

The filmed 294-byte build has both teams' Variable Cross active together for 425 sampled frames. Its test sequences send opposing directions and distinct attacks to the four owners. All 81 command-signature samples match exactly, including all 72 settled samples. Both timers expire naturally in the recorded run. This closes that input-signature check for this lineup and candidate; the full gameplay and release gates remain open.

Replaying the same input tape with the same game and emulator identities reproduced the compared fields across all 5,720 sampled frames: inputs, game state, phase, native port words, the free-play latch, both timers, Duo mask, fighter records, and point/bench ownership. That is repeatability of the recorded gameplay fields. It is not a comparison of full CPU state, a save/load test or proof of rollback correctness.

The captured prototype ROM SHA-256 is 1693663b93afa408c248a336bf1bba7518e1132b95e33bab37194c5e858c6c73; the diagnostic FBNeo binary is 2af29fb12f722bd4f6e558093f1d20dcfd369df7478aff37772536c06615b38f. The input tape is pinned as d603d3c5cf103afb486eed27a1f2cfb72467923d3fb6130ca5c949ddebb75337. The trace, render and source-frame identities are retained with the local evidence record. Capture callbacks do not independently establish physical hardware-frame or timer cadence.

The 330-byte timer build has a separate executed-code comparison: 1,072 odd-update decrements and 1,071 even-update holds. Both timers expire naturally, at captured frames 5949 and 6148. Both timed modes overlap for 817 callbacks, with 108/108 four-controller signature samples matching. The stock-timer control fails the alternating-countdown test. This measures a logical-update rule, not equal real-time duration through every freeze or pause.

The 418-byte current build has four further ordinary-input runs spanning all 15 standard roster characters. Each character receives all six attack buttons under ordinary point control and with both timed modes active. The sampled owner words and input-history checks have no mismatches in those four runs. These checks cover those buttons and ordinary forms. Complete buffered- command and parser-timing coverage remains open, along with every move, hidden form, throw or collision interaction.

This version also has an actual local save/load test. The emulator saves a naturally reached Duo checkpoint at frame 5170, restores it, and replays the next 300 frames. Actor state, inputs, ownership, timers and a checksum of all 64 KiB of work RAM match on each compared frame. This is evidence for the local serializer; it is not a full CPU-state comparison or GGPO integration.

A separate run completes two timed cycles, a natural match ending and a fresh rematch with each person choosing their own fighter. Follow-up input probes expose an acceptance blocker, however: a direction pressed and released entirely between actor polls can be lost.

In the measured cases, P4 Up is present at the native ports only during callback 7219, or P3 Down only during callback 7231. That actor's reader does not run in that callback. Release on the next callback leaves no held input or press edge for the actor to receive. Holding the direction longer reaches the next poll; that does not rescue the short press. These are local diagnostic-emulator observations, and a native-specific regression versus stock has not been established.

A separate comparison using the same lineup covers 280 callbacks with both timed modes active. Stock receives 107 of 108 actor pulse cases: one partner pulse is lost after the shared team cache changes before its poll. The native build receives all 108 in that different workload. These are comparable runs, not identical machine-state replays. A native-only cause and a blanket fix using cached held inputs are both unproven.

Preserving those short transitions without replaying an edge across repeated parser calls is an explicit release gate. The broader KO/double-KO, expiry-during-Hyper, hidden-form, physical-wiring and network matrices also remain open.

A rapid direction reversal was being filtered before the game saw it

The newer input investigation found a separate, reproducible defect in the local emulator profile. P3/P4 in MVC1—and all four owners in MSH—used a direction filter that could turn a quick Left → Right or Up → Down into a neutral input. The corrected profile applies the same rule to all four owners: simultaneous opposites become neutral, while a reversal on consecutive samples survives.

Ordered controller-to-port checksPrevious profileCorrected profile
MVC1, all four owners59/7777/77
MSH vs. SF, all four owners43/7777/77

During simultaneous MVC1 Duo, all 156 requested controller words now reach the physical port values, compared with 118 before. Additional read-only tracing verifies 2,461 complete sampler calls and 1,337 fighter input/history deliveries with no mismatches. These are exact-build local observations; the ROM was unchanged for this correction.

One limit remains visible: of those 156 requests, 154 were read and returned within the same video callback, one reader completed on the next callback, and one short P2 pulse had no physical actor read. The spanning read is not an input loss; the unpolled pulse still needs investigation. No unconditional input queue was added, and these results do not establish a fix for the reported Wolverine/Strider combo inputs, Fightcade rollback, or physical cabinet controls.

The latest pinned MVC1 ROM SHA-256 in this article is 9308e6d77ed9eaba7d1dc546c782ba7f5b2b7d1c7301fae7cc657229c0e12911. Its observations are kept separate from the older clip and replay identities.

GateCurrent publication status
Original four-controller video294-byte build; 81/81 input signatures for the filmed lineup
Translated timer330-byte build; measured odd-decrement/even-hold rule and natural expiry
Stock-character input ownership418-byte build; all 15 standard roster characters, all six attack buttons
Join and rematch behaviorBounded join checks and repeated-cycle/rematch observations pass; broader lifecycle matrix open
Short-input preservationOpen blocker: two isolated direction presses are lost between actor polls; not established as a stock regression
Local save/load418-byte build; 300 replayed frames match the compared state and RAM checksum
Physical CPS-2 wiringPending hardware validation
Four-player rollback integrationSeparate work; not established by these local tests

How MSH vs. SF becomes sustained 2v2

The first MSH prototype established ownership: ordinary tags promoted P3/P4, all 24 six-button owner samples matched, and benched owners' inputs stayed out of their partners' controls. That was necessary, but did not create Cross Fever.

The new msh-timed-03 build adds a separate QCB recognizer, team timers and mode-specific entry, command and departure paths. Stock MSH normally excludes the partner role from ordinary input processing, forces a Hyper when the partner lands, and sends a fighter out after the team attack. The new mode passes those gates while preserving the fighter's team and partner identity. A QCF team Super still follows the prescribed attack path.

Activation requires at least two bars and spends the available meter. The translated rule produces 192 timer units per whole bar, plus half the fractional meter. A recorded two bars plus 92 fractional units starts at 430. The team clock runs once per eligible global update, on alternate updates; processing four fighters must not make it count down four times.

The activation chord is consumed until release. Otherwise, the same HP+HK that starts Cross can become an unintended action as the partner enters. Meter gain is clamped while the mode runs, and each fighter can issue their own Hypers without needing a new bar.

Ordinary-input checkObserved result in msh-timed-03
Independent control after partner entrance264/264 sampled owner inputs match, including all six attack buttons for each of four owners
Sustained simultaneous modeFour active fighters across 997 captured callbacks; the ownership-only control overlaps for 17
Countdown arithmeticBoth teams write 576, then every descending unit through zero; 1,151 eligible global calls from activation through expiry
Independent free HypersSix native Hypers alternate between Ryu and Ken; each cost call observes zero whole and fractional meter
Point knockoutSpider-Man's KO ends only his team's mode on the next callback; Captain America takes the point role while the other team continues
Repeatable KO caseA fixed ordinary-input tape reproduces all 7,500 compared callback records from the original recorded run

These observations come from the ROM's actual command and combat routines. No observer forces a fighter into the mode or writes a timer. The video is captured from the same pinned build: bc6cb5dd907927b7a2f9dc993aa8f1f9b31309bc901df4431a769b40b9d7de73.

There are meaningful limitations. The03 mode-clear QCF comparison preserves the requests, entrances, meter costs and final fighter fields, but has 73 field differences across 70 sampled callbacks, including a one-callback departure shift. It is not an exact timing match. That build also incorrectly uses the ordinary Hyper startup-freeze path during the new mode.

Tracing both original implementations resolves the freeze rule. During a fighter's own timed Cross, native MVC1 and Dreamcast bypass the ordinary Hyper startup effects, freeze and cost. Combined08 now applies that distinction in MSH: six alternating Ryu/Ken Hypers start at zero meter without invoking the normal cost or startup-freeze helpers. The ordinary opponent path is retained; this is not a blanket removal of super-freeze.

Two input-latch bugs also needed actual transition tests. Holding activation HP+HK through expiry could leak those buttons when the activator tagged back in. A first fix then swallowed a fresh attack if that person had released while benched. Combined08 preserves the consumed chord until release and observes release even for a benched owner. The exact counterexamples now pass; this does not close every brief-input or command-history case.

The current MSH candidate is 1,822 bytes in the stock program space, with ROM SHA-256 51ba258ebe415f0a4943f31ad00a3b9e39ee50cacf146c9fcb1156966d085dd5. It repeats the 264/264 sampled ownership check and exact per-team countdown, and a fixed input recording reproduces its 7,600 compared KO/next-game records. The frozen-source rebuild and member-patch installer reproduce the same archive hash. That is reproducibility of this diagnostic, not release acceptance.

Combined08 also passes a real local save/load check. Both modes are naturally active at callback 5170, with timers at 553/553. Restoring that checkpoint and replaying the next 300 callbacks reproduces the compared fighters, inputs, timers, mode, release latches and a checksum of all 64 KiB of work RAM. It does not establish complete CPU-state identity or four-player rollback.

The later combined build adds four-person selection and free-play joining. Its 44 scoped menu checks cover assigned cursors, fresh join presses, partial release, holding the chord through entry, ordinary combat tags, and the stock Test menu. Those are separate recordings from the combat clip above. The release gate still includes the full roster, charge motions, throws, cross-ups, transformations, simultaneous KOs and expiry during every relevant Super state.

The countdown and meteor background are separate jobs

The new msh-exact-time-11 build draws MVC1's original blue TIME frame and depletion masks. The two bars use separate team timers; neither replaces the round clock. This is the original artwork and full donor color row, drawn by the game, with no video annotation or substituted MSH lettering.

msh-exact-time-11 gameplay: the original blue MVC1 TIME frame appears for both teams, with unequal remaining time.

Actual captured gameplay, callback 5500 of the staggered11-latched run. Both modes are active and the bars have different remaining lengths.

The patch allocates 27 original tiles: 11 frame tiles and 16 depletion-mask tiles. A comparison across the complete 32 MiB graphics image confirms that only those allocated blank tiles changed, and each matches the donor's encoded pixels. The display uses 20 object records and reserves 64 bytes for the palette backup within the existing HUD area. No graphics ROM expansion is involved.

A palette timing error in the first attempt produced the correct shape with MSH colors. The corrected lease holds the complete row across the native palette-copy window and restores the original rows after the observed expiry. If an existing sprite uses that row, or the hardware object list lacks capacity, the optional display is suppressed.

msh-exact-time-11 at callback 6200: the left timer has expired and only the right blue TIME bar remains.

The right team remains active after the left expires. Both bars have cleared by callback 6400 in this same run.

The read-only observer followed the physical object banks and their VBlank latch, so the comparison uses the records actually displayed. Across 14 screenshots, 22,900 opaque pixel comparisons matched exactly, with zero errors in 5,472 drawing and 6,606 commit checks. The exact-build evidence includes the candidate and screenshot hashes, allocation scope and remaining limits.

The older fixed KO sequence still fails to reach a knockout in 11: its right-side fighters never fall below 12 and 80 life. That ko11 run remains failed coverage. Added drawing work changes callback/simulation alignment, so the older tape was not assumed to preserve its result. The earlier combined06/08 HUD used MSH lettering; the combat video above retains its older build label.

A new ordinary-input scenario now reaches one natural point KO in the unchanged build11. Spider-Man is knocked out while both teams' modes are active, with 131 units on each timer. Captain America becomes the right-side point on the next callback. P4 then moves him right and starts a fresh light punch: all eight requested movement samples and all four punch samples reach the survivor. Only Spider-Man's team leaves the timed mode; the left timer continues.

The build11 KO and recovery evidence records the original input-driven run and a fixed replay. All 7,600 callback records match, excluding only the label identifying which controller method produced them. The object commits drop from two TIME bars to one, then to none at final expiry; both palette rows return to their saved values. Each run passes 5,808 draw and 6,908 commit checks. These headless runs add no screenshots or pixel comparisons, and use the pinned historical observation profile rather than extending the newer direction-filter result.

This closes one point-KO and survivor-control case. Full rounds, rematches, simultaneous KOs, the broader character matrix, palette writers, computed graphics references and worst-case object/pixel budgets remain open. It does not establish cabinet or network behavior.

The meteor scene has a separate lifetime. In the measured MVC1 run, the first activation creates one palette-animation object. The other team's activation shares it. The engine combines the active Cross flags with other fighter background effects, then restores the stage presentation when that combined state clears. Porting only a timer-controlled background switch could restore the stage in the middle of another effect.

Its art also needs room. The captured native tilemap references 866 distinct 32×32 tiles. The measured stock MSH graphics contain only 695 completely blank aligned blocks of that size, with fewer in the directly addressed scroll region. A complete direct copy does not fit that blank space. Blank space must also be checked for references before it can be allocated.

A second route splits that same art into 16×16 tiles and reuses identical or mirrored pieces. The lossless reconstruction needs 2,404 new tiles in a region with 2,474 measured blank slots. Every donor tile reconstructs exactly in the offline check. At first that looks like a narrow fit. The reference audit changes the result: 774 of those blank slots are parts of 32×32 tiles referenced by MSH's existing stage-map corpus. Adding meteor pixels there would change those stage tiles. A blank-looking quadrant is not necessarily unused space.

This is more than a conservative static concern. One ordinary stock workload loads maps and objects referencing enough blank blocks that only 2,381 candidates remain, already 23 short of the 2,404 needed. Preserving the full recovered map corpus leaves even less space. The proposed blank-only layout fails before all stages have been tested.

The meteor background is not present in the MSH footage. This packing proposal has not passed the stock-asset preservation gate. A safe relocation or different layout also needs native layer, palette and stage-restoration integration. A reduced animation would be a variant, not evidence that the full presentation was transferred.

One workspace, stronger evidence tools

Both implementations now live in MVC_4P, with one parameterized builder and separate game configurations. MVC_HARNESS supplies the shared ROM, disassembly, graphics, allocation and input-evidence tools. The builder freezes assembly includes and evidence, checks exact hook bytes and source hashes, records code/RAM/graphics claims, and produces member patches with a verifying installer. It stays within the stock program address space.

The investigation also found two harness problems worth fixing: sprite-list reads could stop at a physical ROM-member boundary, and selecting the wrong regional profile could leave a partially loaded program looking usable. The shared reader now handles cross-member lists, and a complete-program check rejects missing or wrong-sized members before this builder analyzes or patches them. Boundary fixtures and a deliberately mismatched regional profile exercise those failure cases.

Input preflights bind their results to the exact game, input profile, ROM and emulator. All 43 physical-switch cases must match, and execution observers need positive and negative controls. These checks strengthen the measurements; they do not convert an emulator run into cabinet or four-player rollback evidence. One profile builder now exposes both games' native controls without manual driver edits; its fresh two-game build passes all 43 switch cases for each game.

What would make this a release?

Both games need the complete playable contract: four independent owners, sustained 2v2, coherent short-input history, per-team countdown displays, mode backgrounds and correct entry/exit behavior. The evidence must identify the exact ROM and input profile used. A live four-person capture, physical cabinet validation and rollback integration are separate results; the diagnostic controller replays establish none of those by themselves.

Separate from Direct Hyper Cancel

The released DHC v8 patch adds cancel routes and partner handoffs. This joint four-player investigation adds independent ownership and a sustained mode in two games. A team handoff in DHC is not evidence of four-human control, and this report does not change what the existing release claims.

The diagnostic footage and synchronized overlay are available here as a public progress report. The game releases still require the remaining acceptance gates and exact patch/input-profile hashes. There is no public four-player patch download yet. These local captures establish neither cabinet compatibility nor four-player online play.

Written by Daniel Plas Rivera · 5,727 words · $3A

ShareXLinkedIn