Download on GitHub:
https://github.com/HardCade/hardcade/releases===========================================================================================
CRT-MAME-ARCADE-2D Perceptual Sync 0.168 V1.8
================================================================================================
Development Version — December 2025
© 2025 Hardcade — Olivier Mileo
===========================================================================================
DESCRIPTION
===============================================================================================================
CRT-MAME-ARCADE-2D Perceptual Sync is a specialized version of MAME 0.168 optimized for 2D arcade games on 15 kHz CRT monitors and modern LCD screens running WinXP-32 with an ATI or NVIDIA graphics card + crt_emu drivers or soft15kHz.
This edition focuses on minimizing input lag, minimizing file size, and
improving video synchronization for an authentic arcade experience
thanks to precise fine-tuning of the Slider Refresh Rate down to 4 decimal places.
// PHILOSOPHY:
Why "CRT-MAME-ARCADE-2D Perceptual Sync" when other emulators like GROOVYMAME already exist?
Whether you're emulating at 15kHz with new or older hardware, the synchronization between the emulation and the display
is never 100% perfect in practice. Even if the modelline is calculated to exactly match the original game's frame rate,
sometimes, even when adhering to the precise values of the MAME video drivers, the timing interpreted by your hardware will be more or less
off from the timing it should actually adopt to be perfectly aligned with the game's timing.
There are always discrepancies (large or small) due to:
- Hardware tolerances (CRT monitor, graphics card)
- Inaccuracies in clocks and oscillators
- Rounding in calculations, operating system
These discrepancies are random depending on your hardware, even if you use THE perfect modelline that mathematically respects
the values imposed by the MAME game system. Despite this, the synchronization drifts more or less over time,
creating that tearing line that "walks" slowly or quickly across the screen—it can take several minutes or even tens of
minutes to cross the entire screen. This is generally considered acceptable because:
The line moves so slowly that it's barely noticeable in-game.
It's infinitely better than classic tearing with multiple rapidly moving lines.
Adding V-sync eliminates it at the cost of one frame of input lag, but if our modelline is too far off
the perfect timing, we'll get choppy scrolling. Some users further refine their modellines or slightly adjust
the refresh rate to minimize this phenomenon, but micro-tearing often remains.
Perceptual Sync is the philosophy of a CRT display mode that prioritizes perceived visual stability
(zero mobile tearing, smooth scrolling) rather than the absolute accuracy of the theoretical refresh rate.
It's a CRT display doctrine based on human perception, not mathematical perfection.
Perceptual Sync prioritizes perceived smoothness and image stability on CRTs.
Slight variations in refresh rate (≤0.0001 to 0.5 Hz) are intentionally tolerated to eliminate mobile screen tearing.
🔴 What Perceptual Sync DOES NOT try to do
❌ Be mathematically exact
❌ Be “frame perfect”
❌ Imitate GroovyMAME
❌ Convince theoretical purists
👉 It stands by its choices.
In other words: “What the eye sees is more important than what the numbers say.”
// The fundamental principles:
- The refresh rate does NOT need to be exact if a variation of: ±0.0001 to 0.5 Hz (configurable) is tolerated
👉 Result: imperceptibly different refresh rate, stable image.
// Absolute priority on tearing stability:
- Tearing enabled or disabled with Vsync activated
But: fixed, stuck outside the visible area if possible, or always in the same place
👉 Static tearing is psychologically invisible.
/ // No chasing the “perfect modelline”:
- No dynamic calculations
- No mode creation
- No real-time adjustments
👉 Once the mode is chosen → and the refresh rate slider is fine-tuned, leave it alone!
// The player takes precedence over the timer:
- Emulation respects gameplay
- Not the atomic clock
- No perceptible drift in-game
========================================================================================
MAIN FEATURES
=================================================================================================
INPUT & LATENCE
────────────────
• Late Input Polling — Reduced input lag
• Unbuffered DirectInput — Direct polling of device state
• Removal of GPU frame queue (D3D9)
VIDEO & SYNCHRONIZATION
────────────────────────
• DirectDraw Low-Level VSync — Minimal latency on CRTs (Windows XP)
• D3D9 Real VSync — Eliminates screen tearing at no extra cost
• Disabling implicit frameskip — Smooth scrolling on CRTs
• Automatic rounding
• Rate Tick — Resolution Optimization
INTERFACE & CONFIGURATION
──────────────────────────
• Saved Screen Refresh Rate slider in CFG + precision to 4 decimal places instead of the default 3
• Optimized 2D ARCADE Build — Lightweight executable (no 3D games, mechanics, casino, mahjong, computer, consoles...)
No OpenGL, No BGFX, No Network support, No MIDI sound, No LUA (Script)
========================================================================================
DETAILED TECHNICAL MODIFICATIONS
==================================================================================== =====
┌─────────────────────────────────────────────────────────────────────────────────────────────────
│ LATE INPUT POLLING
└────────────────── ──────────────────── ─────────────────── ────────────────────
THE DirectInput inputs are polled as late as possible in the frame,
just before video rendering. This avoids using inputs from the previous frame (N-1).
Modified file: src/osd/windows/video.cpp
Function: windows_osd_interface::update(bool skip_redraw)
┌────────────────── ──────────────────── ─────────────────── ────────────────────
│ DIRECTINPUT NO BUFFERED
└────────────────────────────────────────────────────────────────────────────────────────────────
Buffer Disabled DirectInput events (DIPROP_BUFFERSIZE = 0).
Direct reading via GetDeviceState eliminates 1 to 3 ms of latency.
Modified file: src/osd/windows/input.cpp
┌───────────────────────── ──────────────────────────────────────────────────────────
│ DISABLING IMPLICIT FRAMESKIP (CRT)
└────────────────── ──────────────────── ─────────────────── ────────────────────
MAME Version 0.168 applies an internal frameskip even with `frameskip=0` when no video changes are detected. This behavior degrades CRT scrolling.
The implicit frameskip is disabled when `frameskip=0` is explicit.
Compatible with DDraw, Windows XP, and 15 kHz CRTs.
Modified file: src/emu/video.cpp
┌─────────────────────────────── ──────────────────────── ────────────────────────
│ DELETING THE GPU QUEUE FRAME (D3D9)
└────────────────── ──────────────────── ─────────────────── ────────────────────
Configuration D3D9:
• SwapEffect = D3DSWAPEFFECT_COPY
• BackBufferCount = 1
Result: -1 frame of actual display latency.
Modified file: src/osd/windows/ddrawd3d.cpp
┌──────────────────────── ───────────────────────────────────────────────────────────
│ SLIDER SCREEN REFRESH RATE – HIGH PRECISION & SAVE
└───────────────────────────────────────────────────────────────────────────────────────────
Save and Reload Automatic user frequency adjustment in
cfg/[game_name].cfg, with ultra-fine CRT refresh rate tuning down to 0.0001 Hz, display and saving to 4 decimal places.
Key Functions:
• Arrow keys only → ±1.0000 Hz
• SHIFT + arrow keys → ±0.1000 Hz
• ALT + arrow keys → ±0.0010 Hz
• SPACE + arrow keys → ±0.0001 Hz
• CTRL + arrow keys → ±1.0000 Hz (fast)
Added Functions:
• config_load_screen_refresh() — src/emu/video.cpp
• config_save_screen_refresh() — src/emu/video.cpp
Modified Functions:
• slider_refresh() — src/emu/ui/ui.cpp
• Base 10000 to Hz conversion for 4 decimal places
• Accurate rounding and saving of CFG to 4 decimal places
• Display FPS in 4 decimal places
• ui_menu_sliders::handle() — src/emu/ui/sliders.cpp
• Spacebar handling for ultra-fine increments
• slider_init() — src/emu/ui/ui.cpp
• Slider refresh increment changed to 1 (0.0001 Hz)
Affected files:
• src/emu/screen.cpp / screen.h
• src/emu/video.cpp
• src/emu/ui/ui.cpp
• src/emu/ui/sliders.cpp
┌────────────────────────── ───────────────────────── ──────────────────────────
│ D3D9 REAL VSYNC (NO (TEARING)
└─────────────────────────────────────────────────────────────────────────────────────────────
Forces Hardware VSync Real D3D9 (PresentationInterval = D3DPRESENT_INTERVAL_ONE)
Independent of classic MAME VSync. Eliminates screen tearing without CPU overhead.
INI option: crtvsync 0|1
0 — Original MAME behavior (default)
1 — Hardware D3D9 VSync enabled
Recommended use: 31kHz LCD or CRT monitors (adds ~1 frame of lag on CRTs)
Modified files:
• src/osd/windows/winmain.cpp
• src/osd/windows/video.h / video.cpp
• src/osd/windows/ddrawd3d.cpp
┌──────────────────────── ────────────────────────── ───────────────────────────
│ DIRECTDRAW LOW-LEVEL VSYNC (CRT) V2
└────────────────── ──────────────────── ─────────────────── ────────────────────
Low DirectDraw VSync mode Level for 15 kHz CRT under Windows XP.
Direct rendering in the primary surface synchronized to the Vertical Blank.
INI option: ddraw_lowlevel_vsync 0|1
0 — Classic MAME behavior (default)
1 — Low-level DirectDraw VSync
⚠ Only active if waitvsync = 0
⚠ Automatically disabled if triple buffering is enabled
Functionality:
1. Wait for VBL via WaitForVerticalBlank(DDWAITVB_BLOCKEND)
2. Direct locking of the primary surface
3. Primitive scanning (blending/alpha detection)
4. Membuffer or direct rendering as needed
5. Controlled copy of membuffer → primary surface
6. Unlock and bypass of MAME blit
Supported formats:
• 8-bit, 16-bit, and 32-bit formats
• Full blending and alpha effects
• RGB 32-bit (0x00ff0000), 16-bit 565 (0xf800), 15-bit 555 (0x7c00)
• Handling of lost surfaces (Alt+Tab)
GPU Compatibility (Windows XP):
✓ Excellent: NVIDIA TNT/GeForce 2/3/4/FX, ATI Radeon 7000-9800,
Matrox G200/G400/G450/G550
~ Partial: Intel iGPU i815/i845/i865 (emulated VBL)
✗ Untested: Vista+ / WDDM Drivers
Result: Latency reduced by approximately 1 frame, stable CRT synchronization.
Modified files:
• src/osd/modules/render/drawdd.cpp
• src/emu/emuopts.cpp / emuopts.h
┌────────────────── ──────────────────── ─────────────────── ────────────────────
│ AUTOMATIC ROUNDING OF REFRESH (ONE-SHOT)
└────────────────── ──────────────────── ─────────────────── ────────────────────
At the first At launch, if no CFG/slider exists, the refresh rate is rounded up to the nearest integer (e.g., 57.445 → 57 Hz, 59.636 → 60 Hz).
INI option: autorefreshround 1
The user slider retains priority.
Modified files:
• src/emu/machine.cpp
• src/emu/screen.cpp / screen.h
• src/emu/emuopts.cpp / emuopts.h
┌────────────────── ──────────────────── ─────────────────── ────────────────────
│ OPTIMIZED 2D BUILD — CLEANING ARCADE.LST
└──────────────────────────────────────────────────────────────────────────────────────────
Light version Specialized for classic 2D arcade games on 15 kHz CRT monitors.
Systems removed:
✗ All 3D games (Model 2/3, Naomi, Taito Type X, etc.)
✗ Casino systems (slot machines, video poker)
✗ Mahjong games
✗ Non-arcade "machine" systems (computers, consoles)
✗ Mechanical game systems, etc.
Supported systems (2D only):
✓ Capcom CPS1/CPS2/CPS3
✓ Neo Geo MVS
✓ Konami (GX, Classic)
✓ Sega System 16/18/24
✓ Taito (F2, F3)
✓ Cave (CV1000, PGM)
✓ Irem M72/M92
✓ Toaplan, Psikyo, Data East
✓ Namco System 1/2
✓ 8-bit classics (Pac-Man, Donkey Kong, Galaga, etc.)
Result: Smaller executable, faster compilation, targeted 2D CRT list.
Modified file: src/mame/arcade.lst
┌──────────────────────────── ──────────────────────── ─────────────────────────
│ DISABLING UI LUA
└──────────────────────────────────────────────────────────────────────────────────────────
Lua's periodic call The `periodic_check` and `frame_hook` lines are now commented out to avoid any impact on performance or menus.
======================================================================================
COMPATIBILITY
=================================================================================================
OS: Windows XP / 7 / 8 / 10
Renderers: DDraw (XP), D3D9, GDI
Monitors: 15 kHz CRT, 31 kHz LCD
=======================================================================================
CREDITS
============================================================================================================
Development: Olivier Mileo
Project: CRT-MAME ARCADE-2D 0.168 Edition
Base: MAME 0.168
© 2025 Hardcade — All rights reserved
=========================================================================================
Download on GitHub:
https://github.com/HardCade/hardcade/releases