Files
openroller/docs/re_gc_test_mode.md
T
tsuki 831d96e562 Initial public source release
Split reusable rendering and format support into vectorail-core and vectorail-gc.
2026-08-02 17:05:27 +02:00

13 KiB

game471 test mode

This note describes the operator/test mode in the arcade game471.exe (4.74.00ENG). The structural and layout observations below come from the executable and its shipped resources, not from screenshots.

Live entry

The game exposes twenty logical cabinet inputs through FUN_00634060 (0x00634060). Logical input 0 is the TEST switch.

During normal operation, the main task at FUN_006396f0 samples input 0 on every update. Holding it for at least three updates starts the test-mode transition. The game then:

  1. stops the normal game/audio/render tasks;
  2. waits 45 updates;
  3. constructs the test-mode text renderer, sprite renderer, input adapter, SE adapter, and BGM adapter;
  4. initializes the test-mode form system and opens the main form.

The already generated game471_bootskip.exe can reach the original menu under Wine. Once the GameWare window is active, press and briefly hold Caps Lock. Caps Lock is the executable's built-in DirectInput fallback for the TEST switch; no test-mode-specific patch is needed.

The original executable's keyboard fallback table starts at 0x007840f0:

Logical input Cabinet control FAST I/O mask DirectInput fallback
0 Test switch 0x00000040 DIK_CAPITAL (Caps Lock)
1 Service switch 0x00000001 DIK_F1
2 Coin switch 0x00000004 DIK_F2
3 Select switch 0x00000010 DIK_F3
4 Enter switch 0x00000020 DIK_RBRACKET (])
5 Left booster up 0x00000100 DIK_Q
6 Left booster down 0x00000200 DIK_A
7 Left booster left 0x00000400 DIK_LCONTROL
8 Left booster right 0x00000800 DIK_S
9 Left booster button 0x00100000 DIK_LMENU (left Alt)
10..14 Right booster controls 0x00010000 through 0x00200000 raw scan codes 78,7d,7a,7b,6a

FUN_00633d00 obtains the FAST I/O bitfield and masks it with the first table above. FUN_00633de0 applies the per-input active-high/active-low table. FUN_00634060 ORs that result with the DirectInput fallback.

Test-mode input adapter

GWTestModeInput_GW is constructed by FUN_00569d00. Its update method, FUN_00569d20, translates cabinet inputs to the generic test-mode flags:

  • Test switch -> 0x20 (back/exit)
  • Select switch -> 0x02
  • Enter switch -> 0x58
  • left booster up/down/left/right/button -> 0x01, 0x02, 0x84, 0x48, 0x10

The language table describes the intended behavior:

  • booster up/down or Select moves the cursor;
  • booster buttons or Enter confirms;
  • booster left/right or Enter changes a setting;
  • Test returns/backtracks.

Short synthetic X11 key taps may be sampled for several game updates because the original runs uncapped. For automated navigation, inject an explicit cabinet state for one update instead of relying on xdotool key.

Resources

Test mode does not use the normal RVB/MTX menu assets. Its strings come from:

  • data/TestModeLaungage/Laungage_eng_sjis.csv
  • data/TestModeLaungage/Laungage_jpn_sjis.csv

Both are CP932/Shift-JIS. Laungage is the spelling used by the shipped game. The glyphs themselves come from data/font/Font.mtf and the data/font/FontXXXXXXXX.mfi atlas pages. GWTestModeRenderText_GW constructs a pool of 256 regular GameWare text objects backed by that font. It does not use a test-mode-specific bitmap font or GDI text.

Font.mtf starts with a 16-way Unicode radix table. A resolved entry stores the MFI page in its low 24 bits and the high nibble of the atlas cell in bits 28..31; the low cell nibble comes from the Unicode codepoint. Each MFI contains a 512x512 DXT5 atlas split into 16x16 cells. This is confirmed by FUN_00485f90, which creates GameWare image format 3, and by GWPCImage2D::Create, whose format table maps index 3 to D3DFMT_DXT5. The font shader uses the DXT5 alpha channel as glyph coverage. The English ASCII glyphs use page 0 and occupy the left half of each cell, producing 8x16 glyphs. The selection marker is U+2192 (), resolved by the MTF to page 27, cell 0xb2, and is 16x16.

The renderer is a separate, mostly text-based framework represented by the following RTTI classes:

  • GWTestModeWindowText, GWTestModeWindow, GWTestModeWindowList
  • GWTestModeForm, GWTestModeSelectForm
  • GWTestModeForm_YesNo, GWTestModeForm_ProcYesNo
  • GWTestModeInput_GW
  • GWTestModeRenderText_GW, GWTestModeRenderSprite_GW
  • GWTestModeBGM_GW, GWTestModeSE_GW

The framework screen is 720x1280 on black. FUN_00577940 installs a logical text size of 16x16, pure red (1,0,0,1) for the selected/help color, and pure cyan (0,1,1,1) for normal selectable entries. The three centered common title windows use normalized y coordinates -0.95, -0.925, and -0.9, which map to pixel y positions 32, 48, and 64.

The main list is anchored at normalized y -0.725 (176 px). Its default row gap is 0.01 of the 640-pixel half-height, so rows advance by 16 + 6.4 = 22.4 pixels. The selected row is red and has a separately drawn ; unselected rows are cyan. The help form is centered at normalized y 0.2 (768 px), while the main five-line build/machine/time information list is centered at y 0.4 (896 px).

Main menu in 4.74.00ENG

The live build displays:

  1. Monitor Test
  2. Input/Output Test
  3. LED Test
  4. Card Test
  5. Audio Settings
  6. Game Settings
  7. Network Info
  8. Bookkeeping
  9. System Info
  10. Restore factory settings
  11. Exit Test Mode

The CSV also contains Check Input Count, System Settings, Delete High Scores, and Machine Connection Test, but prefixes those entries with #. It contains Update Online without #, although that item is still filtered out by this build's runtime conditions.

Forms and data exposed

  • Monitor Test: color bars, white, red, green, blue, and cross-hatch patterns.
  • Input/Output Test: all cabinet switches, both five-input boosters, headphone volume/jack state, and Groove Stage connection. Booster buttons drive their lamps; the coin switch changes lockout.
  • LED Test: all lights and individual title, side, and booster light groups.
  • Card Test: card-reader status and card ID.
  • Audio Settings: test BGM, master/headphone/demo levels, five speaker channels, Groove Stage status, and normal/demo vibration intensity.
  • Game Settings: coin/song price, per-day operating hours, and score-attack mode.
  • Network Info: location identity/address/IP, cabinet IP/MAC, NESYS versions, and relay server.
  • Bookkeeping: uptime/play totals, free plays, service-switch count, player statistics, 30-week and hourly histograms, play logs, the last twenty errors, and service-switch history.
  • System Info: program/system configuration values.
  • Factory Settings: confirmation form followed by persistent-data reset.

Persistent test-mode data has separate RTTI classes for system settings, high scores, play/weekly/daily/error/service-switch logs, and game-unique data. Log paths embedded in the executable live under TestModeFile\...\Log.

Coin/song presets

CTestModeForm_GameSetting chooses its coin/song table from the Type X HKLM\SOFTWARE\taito\typex\Country registry value. Country == 0 uses eight entries, in this exact order:

  1. 1 coin, 2 songs
  2. 1 coin, 3 songs
  3. 2 coins, 2 songs
  4. 2 coins, 3 songs
  5. Free play, 1 song
  6. Free play, 2 songs
  7. Free play, 3 songs
  8. 1 coin, 1 song

For a non-zero country value it instead exposes 39 entries: every combination of 1 through 12 coins with 1 through 3 songs, followed by the three free-play variants. FUN_00570a70 and FUN_00570810 wrap the selected index forward and backward respectively.

OpenRoller mirrors the registry value with Country in openroller.cfg beside the executable. CMake creates the file on the first build but leaves an existing copy untouched. The value is reread whenever test mode is entered, so the application does not need to be rebuilt after changing it.

Useful code addresses

Address Role
0x006396f0 top-level boot/game/test-mode state machine
0x00634060 logical cabinet input + DirectInput fallback
0x00633d00 mask current FAST I/O input bitfield
0x00633de0 apply active-level table
0x00569d00 construct GWTestModeInput_GW
0x00569d20 translate game inputs to generic test-mode input flags
0x00569610 construct GWTestModeRenderText_GW
0x00569ad0 construct GWTestModeRenderSprite_GW
0x00569440 construct GWTestModeSE_GW
0x005693f0 construct GWTestModeBGM_GW
0x00577940 initialize test-mode form/render state
0x00634fd0 credit/service-credit handling and SERVICE-SW LOCKED

SERVICE-SW LOCKED is unrelated to entering test mode. It is emitted by the credit controller after repeated Service-switch credit pulses and holds the service-credit lock for 180 updates.

LED output pipeline

The LED test form's main methods are:

Address Role
0x0056e160 construct CTestModeForm_LEDTest
0x0056e390 update the selected LED test pattern
0x0056e6c0 handle the seven LED-test menu items
0x0062b0e0 set logical LED index to R,G,B,alpha
0x0062d4d0 construct all logical LED objects and their hardware mapping
0x0062a4d0 update one CLedDevice and place its value in the cabinet output buffers
0x004b3b40 write one RGB pixel into the shared board buffer
0x004b4c50 pack shared LED buffers into the FIO transfer blocks
0x004b55f0 exchange registers and transfer blocks with iDmacDrv32
0x004b6700 wrapper for iDmacDrvRegisterBufferWrite

Logical groups

There are 118 logical LED objects:

Logical indices Test-mode group Hardware coordinates
0 left booster button simple output 4
1..8 left booster RGB group 8 board 0, group 8, positions 0..7
9..40 left booster RGB groups 0..7 board 0, groups 0..7, positions 0..3
41 right booster button simple output 5
42..49 right booster RGB group 8 board 1, group 8, positions 0..7
50..81 right booster RGB groups 0..7 board 1, groups 0..7, positions 0..3
82..93 title board 2, strips 0..1, pixels 0..5
94..105 left side board 2, strips 2..3, pixels 0..5
106..117 right side board 2, strips 4..5, pixels 0..5

The menu implements the groups directly:

  • item 0 cycles all 118 LEDs through off, white, red, green, and blue;
  • items 1, 2, and 3 fill the twelve title/left/right-side LEDs white one address at a time, then clear them in the same order;
  • items 4 and 5 perform the same fill/clear sequence across 41 LEDs on the corresponding booster;
  • item 6 starts the form-exit sequence.

The LED screen itself is only the generic seven-row GWTestModeWindowList, anchored at y -0.725 with an explicit row gap of 0.05 (48 px row advance). It does not draw a schematic of the cabinet or booster rings.

The all-light loop special-cases logical LEDs 0 and 41 because the booster button lamps are single-channel. For those two, it ORs R|G|B and writes the same intensity as a simple lamp.

The executable establishes 40 independently controlled RGB positions plus one simple button lamp per booster. The group/position coordinates above describe the software/FIO mapping only; they do not establish the physical arrangement of those RGB positions inside the arcade booster's plastic assembly.

Color representation

FUN_004b3b40(board, strip, pixel, R, G, B) stores each full-color LED as three bytes in this order:

B, R, G

Each board reserves 9 * 8 * 3 = 0xd8 bytes even where fewer than eight pixels are connected. Before placing a value in the hardware buffer, CLedDevice applies the executable's integer gamma curve independently to each channel:

wire_channel = min(channel * channel / 255, 255)

The alpha/intensity field is applied by the LED object before this final conversion. Test mode always passes alpha 0xff.

iDmac/FIO transfers for board type 0x825c

The current shim reports FIO type 0x825c; the game selects its 0x25c packing branch. Each hardware update eventually makes these calls:

Register-buffer address Bytes LED content
0x5000 0x1b0 general FIO block; title bytes at offset 0x168, button lamps at offsets 4 and 5
0x5200 0x1e0 general FIO block; left/right-side bytes at offset 0x168
0x5400 0x0d8 raw board-0 buffer: left booster
0x5600 0x0d8 raw board-1 buffer: right booster

The board-2 source buffer is split as follows:

  • its first 0x30 bytes (two 8-pixel strip slots) go to 0x5000 + 0x168;
  • its following 0x60 bytes (four 8-pixel strip slots) go to 0x5200 + 0x168.

The unused bytes in those strip slots remain zero. This was confirmed both in the decompiled GWInputDeviceXioFio_BOOST update path and in the live idmac_shim.log: normal steady-state writes have sizes 1b0, 1e0, d8, and d8 respectively. Initial device negotiation first sends four 0x200 byte blocks, then switches to the exact steady-state lengths above.

The game also contains a 0x23c packing branch and generic transfer banks through 0x5e00, but those are not selected by the current emulated hardware ID.