<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>The Opponent - Technical</title><link href="https://theo.minuspoint.com/" rel="alternate"/><link href="https://theo.minuspoint.com/feeds/technical.atom.xml" rel="self"/><id>https://theo.minuspoint.com/</id><updated>2026-08-15T00:00:00-04:00</updated><subtitle>A literal barrel of sunshine.
*Contents may vary.</subtitle><entry><title>Fixing Tao Taido 6-Button Version in MAME</title><link href="https://theo.minuspoint.com/2026/08/fixing-tao-taido-6-button-version-in-mame.html" rel="alternate"/><published>2026-08-15T00:00:00-04:00</published><updated>2026-08-15T00:00:00-04:00</updated><author><name>The Opponent</name></author><id>tag:theo.minuspoint.com,2026-08-15:/2026/08/fixing-tao-taido-6-button-version-in-mame.html</id><summary type="html">&lt;p&gt;For 23 years, the mysterious 6-button version in Tao Taido did not have functioning player 2 controls. The game is so obscure that until now, no one thought to investigate if that's original behavior or a MAME bug.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The years following the release of &lt;em&gt;Street Fighter II: The World Warrior&lt;/em&gt; in 1991 saw a multitude of developers making their own fighting games to capitalize on its success. Some games chose to stand out with an experimental approach, and Video System's sole fighting game, &lt;em&gt;Tao Taido&lt;/em&gt;, is one of the most standout titles in that regard. Using only a single punch and kick button, it eschews &lt;em&gt;Street Fighter&lt;/em&gt;'s motion-and-button commands for special moves by holding both buttons down for a short time and then inputting a single direction, for a total of 12 special moves per character that are very easy to input. Unfortunately, like many of the competitors, they underestimated the importance of compelling combat design, and nowhere does it stand out more than said special moves.&lt;/p&gt;
&lt;div style="left:0;width:100%;height:0;position:relative;padding-bottom:56.25%"&gt;&lt;iframe allow="accelerometer *; clipboard-write *; encrypted-media *; gyroscope *; picture-in-picture *; web-share *;" allowfullscreen="" referrerpolicy="strict-origin" scrolling="no" src="https://www.youtube-nocookie.com/embed/wTYD9U-LpLk?rel=0" style="top:0;left:0;width:100%;height:100%;position:absolute;border:0"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;This 2-button scheme is the parent set in MAME, and therefore the one most people are familiar with. In 2003, MAME 0.65 added &lt;a href="https://adb.arcadeitalia.net/dettaglio_mame.php?game_name=taotaidoa&amp;amp;lang=en"&gt;two versions of &lt;em&gt;Tao Taido&lt;/em&gt;&lt;/a&gt;, designated as "set 1" and "set 2". Both were emulated with two buttons, as the set 1 ROM used only two buttons, and apparently it was presumed that the other set also used 2 buttons. At the time, the only noted difference between sets 1 and 2 was that set 1 allows a 2-player game to be started with a single credit and set 2 did not. In 2009, it was recognized that set 2 is actually a 6-button version in a &lt;a href="https://mametesters.org/view.php?id=2999"&gt;MAME Testers bug report&lt;/a&gt;, and the missing buttons were added in MAME 0.130u2. In MAME 0.154, released in 2014, a 3-button version that keeps the 2-button scheme but adds a separate charge button was added, and all three sets were renamed for the amount of buttons they use.&lt;/p&gt;
&lt;p&gt;The 6-button version does away with the 2-button control scheme in set 1 in favor of three punch and kick buttons per player, just like &lt;em&gt;Street Fighter II&lt;/em&gt;. Even then, the buttons don't seem to follow a consistent light-medium-heavy progression. Not that it mattered much for versus play, since player 2's kick buttons instead made player 1's character kick. Player 2 was unable to kick at all in this version. This has been the presumption among everyone who explored this version for match play in the last 17 years, and so it tends to get dismissed just as quickly as it gets opened as a curiosity of a curiosity.&lt;/p&gt;
&lt;div style="left:0;width:100%;height:0;position:relative;padding-bottom:56.25%"&gt;&lt;iframe allow="accelerometer *; clipboard-write *; encrypted-media *; gyroscope *; picture-in-picture *; web-share *;" allowfullscreen="" referrerpolicy="strict-origin" scrolling="no" src="https://www.youtube-nocookie.com/embed/m_q4dzVg4rQ?rel=0" style="top:0;left:0;width:100%;height:100%;position:absolute;border:0"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;While this flaw had some knowledge, it came up again in &lt;a href="https://www.twitch.tv/lordbbh"&gt;LordBBH's&lt;/a&gt; weekly &lt;a href="https://www.youtube.com/watch?v=kHuR2eoyiwo"&gt;&lt;em&gt;Push to Reject&lt;/em&gt; show on August 10, 2026&lt;/a&gt;, the first episode where forgotten and unpopular arcade games of 1993 were explored, starting with a selection of fighting games that included &lt;em&gt;Tao Taido&lt;/em&gt;. He played through the 2-button version, the parent set in MAME, followed by the 6-button version at 22:31 in the above video. I brought up the non-functioning player 2 kick buttons, which was news to LordBBH and many of the viewers in the chat. He then opened the game's service menu to verify that the buttons were mapped correctly, something I somehow never thought to do myself for as long as I've known about &lt;em&gt;Tao Taido&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img 6-button="" all="" alt="" buttons="" check="" i="" in="" mode="" o="" of="" pressed="" program,="" screenshot="" service="" simultaneously.""="" src="https://theo.minuspoint.com/images/taotaido-03.png" taido's="" tao="" the="" title="Screenshot of Tao Taido's service mode I/O Check program, with all buttons in the 6-button version pressed simultaneously." version="" with=""/&gt;&lt;/p&gt;
&lt;p&gt;The service mode's input test function defines controls for a player 3 and 4, which explains the game allowing for three characters on screen at once. However, no version currently dumped supports 4 fighters at once, or more than two human players. MAME has buttons 4-6, nominally kick buttons in fighting games, mapped to the Up, Down, and Left joystick directions for player 3 and 4. This is similar to kick harnesses adding extra buttons beyond what's provided in the JAMMA edge connector.&lt;/p&gt;
&lt;h2 id="examining-the-source-code"&gt;Examining the Source Code&lt;/h2&gt;
&lt;p&gt;Controls for players 3 and 4 was news to me, so the morning after the &lt;em&gt;Push to Reject&lt;/em&gt; episode, I decided to read the source for &lt;a href="https://github.com/mamedev/mame/blob/mame0289/src/mame/vsystem/taotaido.cpp"&gt;taotaido.cpp&lt;/a&gt; in MAME to determine once and for all if this is correct behavior or a long-standing MAME bug, despite having no experience editing MAME code. The driver notes at the top got my attention right away.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class="k"&gt;-&lt;/span&gt; Don't trust the test mode ! It shows inputs for 4 players as well as
    3 buttons for each player, while the game is a 2 players game with only
    2 buttons (punch and kick) for each player.
    IMO, it's a leftover from a previous game.
    If you want to test all inputs, turn TAOTAIDO_SHOW_ALL_INPUTS to 1.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first thing I tried was to do just that, set &lt;code&gt;#define TAOTAIDO_SHOW_ALL_INPUTS&lt;/code&gt; in line 96 to 1. However, doing this caused MAME to throw errors at runtime about duplicate bitmasks in the input ports, and the input mapping interface did not show any more inputs than there were before. I don't know enough about how control inputs in MAME are programmed to say whether the emulator-wide input code was changed between 0.65 or 0.130u2 and the current version, and this code wasn't updated to match. The input mapping code begins at line 363, and the buttons for the 6-button version at line 513. In the process of editing the driver, I learned that input ports are implemented as bitmasks for an 8-bit value. Each input is a single bit set high, with ports named &lt;code&gt;P1&lt;/code&gt;, &lt;code&gt;P2&lt;/code&gt;, &lt;code&gt;P3&lt;/code&gt;, and &lt;code&gt;P4&lt;/code&gt; for player controls. For clones, the buttons are defined as overrides of the parent set's control schemes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INPUT_PORTS_START&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;taotaido6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_INCLUDE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taotaido&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_MODIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"P1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_MODIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"P2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_MODIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"P3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x04&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xf8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_UNKNOWN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_MODIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"P4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x04&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xf8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_UNKNOWN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;P1&lt;/code&gt; and &lt;code&gt;P2&lt;/code&gt; ports are given a modification to bit &lt;code&gt;0x40&lt;/code&gt;, the previously unused button 3, to be a third punch button. In ports &lt;code&gt;P3&lt;/code&gt; and &lt;code&gt;P4&lt;/code&gt;, the bits &lt;code&gt;0x01&lt;/code&gt;, &lt;code&gt;0x02&lt;/code&gt;, and &lt;code&gt;0x04&lt;/code&gt; are the joystick directions Up, Left, and Down. The obvious first step was to change the values that get mapped to &lt;code&gt;PORT_PLAYER(2)&lt;/code&gt; and see what happens. I started by changing them to the rest of the &lt;code&gt;P3&lt;/code&gt; port inputs, removing the &lt;code&gt;PORT_MODIFY("P4")&lt;/code&gt; line and changing the following three lines to &lt;code&gt;0x08&lt;/code&gt;, &lt;code&gt;0x10&lt;/code&gt;, and &lt;code&gt;0x20&lt;/code&gt;. These would correspond to player 3's Right direction, button 1, and button 2. This still returned errors in runtime about duplicate bits, which I later learned was due to the final value, &lt;code&gt;IPT_UNKNOWN&lt;/code&gt;, duplicating the bits I just shifted. Changing it such that all values added up to &lt;code&gt;0xff&lt;/code&gt; fixed that, but didn't change anything in the in-game actions. The next step was to change them to other player 4 inputs, keeping the same changed bitmasks but putting them back on the &lt;code&gt;P4&lt;/code&gt; port. Player 2 now had two of their kicks, but as exciting as that development was, I was rapidly losing patience with recompiling, so my next step was copying the entirety of the parent set's input code into the &lt;code&gt;taotaido6&lt;/code&gt; port region, removing the conditional &lt;code&gt;ifdef&lt;/code&gt; lines as if &lt;code&gt;TAOTAIDO_SHOW_ALL_INPUTS&lt;/code&gt; was set to 1. It's a very crude hack and I still got the same duplicate bitmask errors, but now I was able to see every input from the service mode in MAME's input mapping screen. From there, I pressed the default MAME controls for players 3 and 4 and determined it was player 4's buttons 1-3 that were player 2's kicks.&lt;/p&gt;
&lt;video controls="" height="100%" title="Modified MAME build showing controls for player 3 and 4 in Tao Taido, followed by player 2 pressing all of their buttons without player 1 acting in response." width="100%"&gt;&lt;source src="https://theo.minuspoint.com/images/taotaido-01.mp4" type="video/mp4"/&gt;&lt;/video&gt;
&lt;p&gt;At last, the mystery of 17 years was solved, and it took an extremely simple fix that even I, a complete newcomer to MAME development, was able to implement in an hour. MAME 0.130u2 added the correct number of buttons, but the wrong ones were added to player 2, and they were never checked even as a third revision was discovered in the interim. To make a proper patch to submit to MAME's development staff, I just needed to restore the original &lt;code&gt;P4&lt;/code&gt; port code and adjust the bitmasks to the new buttons.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_MODIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"P4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_BUTTON6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PORT_PLAYER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PORT_BIT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP_ACTIVE_LOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPT_UNKNOWN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;video controls="" height="100%" title="Modified MAME build showing fixed player 2 controls, with a demonstration of player 1 and 2 pressing their buttons without overlap between ports." width="100%"&gt;&lt;source src="https://theo.minuspoint.com/images/taotaido-02.mp4" type="video/mp4"/&gt;&lt;/video&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;In these videos, I'm pressing buttons 1 through 6 in order, yet the normals don't appear to smoothly ascend in strength from light to heavy. In all versions, the attacks that come out depend on multiple factors not seen in other fighting games, such as whether the opponent is in the air or if they're in front of or behind you, as fighters don't turn around immediately if they change sides. I call the buttons Punch 1/2/3 and Kick 1/2/3 rather than Light/Medium/Heavy because of this.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Within hours of my &lt;a href="https://github.com/mamedev/mame/pull/15879"&gt;pull request&lt;/a&gt; being submitted, the fix was merged. This is my first contribution to an emulator, or any project of this scale, and thus I have officially made my mark on arcade emulation history. An experienced developer would have found and implemented the fix years ago in less than half the time I took, if &lt;em&gt;Tao Taido&lt;/em&gt; were more notable. The next step is to port this fix to Final Burn Neo, but I can't figure out how to compile it, let alone test the fix. Anyone else with more knowledge of that emulator's build process is free to adapt the MAME patch to &lt;a href="https://github.com/finalburnneo/FBNeo/blob/master/src/burn/drv/pst90s/d_taotaido.cpp#L83"&gt;src/burn/drv/pst90s/d_taotaido.cpp&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="which-version-came-first"&gt;Which Version Came First?&lt;/h2&gt;
&lt;p&gt;As noted above, MAME lists the 2-button version as the parent set and the 3-button and 6-button sets as clones, implying they came earlier. In researching the emulation history of &lt;em&gt;Tao Taido&lt;/em&gt;, I found the MAME Testers bug report from 2009, which linked a &lt;a href="https://web.archive.org/web/20030920110705/http://www12.ocn.ne.jp/~takebo/taolist.html"&gt;Japanese fansite&lt;/a&gt; as a citation that set 2 required more than two buttons. The earliest archive for this site is dated September 20, 2003, seven months after MAME 0.65 added emulation for this game, but six years before the 6-button version got 6 buttons in MAME 0.130u2. It reports that the 2-button version is a location test build and the 6-button version is the final game, and there are some hints in the game itself and the service mode to support this. The 6-button version fixes the infamous "&lt;a href="https://theo.minuspoint.com/images/taotaido-04.png"&gt;You'd be a good match for my wifw&lt;/a&gt;" typo, and some characters now have moves that resemble throws, which suggests it's a later revision. The discovery of the 3-button version in 2014 supports the theory that the game was originally designed for four players with up to three buttons each, and it has a dipswitch to disable the third button so it functions identically to the 2-button version. It would also make more logical sense that the presence of controls for players 3 and 4 in the service mode I/O check program, which exist in all versions, means that it was originally a game for four players. Then when that didn't work out in development, players 3 and 4 were deleted and their buttons repurposed as more buttons for players 1 and 2, but this is speculation on my part.&lt;/p&gt;
&lt;p&gt;The theory presented in the MAME source code comments is that this screen is a remnant of a different game for four players that's being reused for a two-player fighting game, but what game that would be is unknown. It seems that these comments were never updated to account for the information in the Japanese page, and the 2-button version is still considered the parent seemingly solely because it happened to be dumped as "set 1" back in 2003. &lt;a href="https://mamedev.emulab.it/haze/2014/05/07/other-news-part-1/"&gt;MameHaze wrote in 2014&lt;/a&gt; when the 3-button version was added to MAME, reasoning that the 6-button version may be a prototype due to the I/O check still showing controls for four players despite only supporting two players, similar to the Video System port of &lt;em&gt;Welltris&lt;/em&gt; from 1991, and the presence of dipswitches that show debug information that the 2 and 3-button versions lack. An &lt;a href="https://flyers.arcade-museum.com/videogames/show/1816"&gt;arcade flyer for the 2-button version&lt;/a&gt; has been preserved, while there has yet to be such a find for the 6-button version.&lt;/p&gt;
&lt;p&gt;With all of this said, I haven't come across other sources that corroborate the information in the Japanese site, and it contains no photos or other images aside from portraits of the characters. It also states that there's a rumored 6-button build with support for three players and one CPU opponent simultaneously with two linked cabinets, with only an unspecified issue of &lt;em&gt;Gamest&lt;/em&gt; cited for this claim. Pending definitive information from the developers (or Hamster Corporation, who have released several Video System games in Arcade Archives already), this section is all speculation. Parents and clones have exchanged roles, and revisions have been marked or unmarked as prototypes in the past when new information about their provenance was uncovered, so it remains to be seen if either will happen here. It's even possible that either a surprise Arcade Archives 2 release will include the alleged 6-button link version, or it gets dumped in MAME in the future, so everyone will get to experience the four-way free-for-all rumored in a magazine for the first time in over 33 years. &lt;/p&gt;
&lt;h2 id="the-importance-of-testing-every-single-game"&gt;The Importance of Testing Every Single Game&lt;/h2&gt;
&lt;p&gt;The contributions to preservation that MAME has offered over the years cannot be overstated, nor can the efforts of its contributors to fully understand thousands of bespoke pieces of hardware. But the average emulator user, naive to how challenging it is to emulate anything accurately, takes for granted that what's presented is the intended game behavior without the regular disclaimer of imperfect emulation. It's easy to imagine no one who tried out the 6-button version had any incentive to report this as a bug to MAME Testers, after that first report in 2009 that the number of buttons needed to be increased. That bug was fixed, but evidently not given a quick button check in versus play by either the MAME developers or the person who filed the report. Conversely, MAME Testers gets a lot of reports of "bugs that are not bugs" (BTANBs in their jargon), so reporting problematic behavior that might be present on real hardware would be counterproductive, and the average user has no way to tell if what they're reporting is a BTANB without evidence from real hardware. Yet, in hindsight it's impossible to believe that Video System would have allowed the 6-button game to ship with its primary selling point of &lt;em&gt;Street Fighter&lt;/em&gt;-like match play being totally unusable. &lt;/p&gt;
&lt;p&gt;The fighting game community is known to explore literally every title they're able to run, including anything in MAME that can be classified as a fighting game, no matter how loosely. Enough of those players have played every version of &lt;em&gt;Tao Taido&lt;/em&gt; for it to gain the notoriety it has, including match play of the 6-button version to make the player 2 input problems a known issue. Assuming the fansite is correct that the 6-button version was the final version and the 2-button version was a location test that was enough of a success to convince Video System to iterate on it rather than cancel it outright, surely they would have ensured that any given pair of players would be able to use all of those buttons, right? If player 2 in a fighting game were forced to have their legs tied behind their back, we would have rediscovered complaints about that in contemporary reviews by now, wouldn't we? If the 6-button version was the prototype, how would it have been possible for them to wire so many buttons incorrectly and not immediately destroy such a worthless build after testing it with two players? Alternatively, how did this get dumped and not the updated build that would have fixed it? &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Tao Taido&lt;/em&gt; may be a footnote in the history of arcade games, and in my opinion its reputation as a novelty at best is completely earned, but no game (or update) deserves to be misremembered via incorrect emulation, especially when it's so easily fixable, and empirical evidence is linked in a bug report to suggest that player 2 is indeed supposed to have all of their buttons to themselves. If it's going to be notorious for thoughtless combat design and poor user experience, it ought to be presented exactly as it was programmed, no better or worse. They've been wrongly blamed for asymmetric player inputs (including by myself) in an earnest &lt;em&gt;Street Fighter II&lt;/em&gt; competitor for years, and possibly even for trying to do so with only 2 buttons instead of 6 come release time, due to careless mistakes made in 2003 and 2009 that went unchecked until some viewer in a weekly Twitch stream with no C++ development experience got curious about the technical details of a bug he knew about for several years. &lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This post was intended to be a brief devlog that explained the player 2 control fix and the steps I took to implement it, but as I dug into the emulation history of &lt;em&gt;Tao Taido&lt;/em&gt; in MAME, it became an expression of disappointment over how easily games can be misrepresented after their time in the market. This can happen to any game to any degree, such as when it was &lt;a href="https://www.mamedev.org/?p=498"&gt;discovered in 2021&lt;/a&gt; that &lt;em&gt;Contra&lt;/em&gt; had not been emulated properly in the corridor shooter segments since 1998, until deep analysis of custom ICs uncovered that they were influencing enemy behavior on hardware. Even that issue, in a very popular game, isn't as severe as a whole player side in a game intended to be played by two people as frequently as possible being broken. It's not viable for every single machine that MAME emulates to get this kind of scrutiny, nor is it always possible to correctly determine the order of releases of multiple game revisions with available knowledge, but at least one blind spot has finally been addressed. It may sound like I'm being melodramatic about the emulation of a fighting game whose purpose in the modern day is to serve as an example rather than a secretly deep gameplay experience, but who knows what other faults from this era of MAME's development still persist in the codebase today, and how many could be fixed just as trivially? How much different would periphery fighting game discourse be if the 6-button version was the parent instead?&lt;a \&lt;i="" annotation="It would probably have been more boring because the 2-button version's sheer absurdity is a much more fun spectacle to behold, and even if it turns out it's not " audio="" be"="" broken="" class="annotation" earned="" emulation="" history,="" href="#" in="" it's="" its="" like="" long-standing="" much="" of="" parent="" place="" set,="" supposed="" the="" to=""&gt;Tattoo Assassins\. After its sound ROMs were redumped in 2025, the older emulation with the bad dump was kept in a clone set, a highly unusual move for any emulator, because both \&lt;i&gt;Tattoo Assassins\&lt;/i&gt; and the way it was emulated the first time were that important to arcade and emulation history. But that's for another article."&amp;gt;[a]&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;As a final note, if you want to explore these games for yourself, I've prepared a &lt;a href="https://theo.minuspoint.com/files/mame289-taotaido6fix.7z"&gt;custom MAME build for Windows&lt;/a&gt; that contains only &lt;em&gt;Tao Taido&lt;/em&gt; and the fixed 6-button build, until MAME 0.290 is released. Alternatively, automated builds for other platforms are available in the &lt;a href="https://github.com/mamedev/mame/pull/15879/checks"&gt;GitHub Actions artifacts&lt;/a&gt;. The &lt;a href="https://web.archive.org/web/20030920110705/http://www12.ocn.ne.jp/~takebo/taolist.html"&gt;Japanese site&lt;/a&gt; above has a complete movelist for it and other fighting games it describes as "cult". I believe the 6-button version plays better than the 2/3-button versions, mostly because there's no longer a need to hold down buttons and stop moving and attacking entirely in order to launch further attacks that are extremely unsafe on hit and have a high chance to whiff completely. Traditional fighting game inputs allow you to do that as quickly as you can input them. Some characters can throw, in that they have unblockable moves that only trigger at point blank, but they have startup that can be countered with a faster attack. I'm researching potential throw loops to exploit against the CPU for an easy 1CC.&lt;/p&gt;</content><category term="Technical"/><category term="gaming"/><category term="development"/></entry></feed>