WinUAE to Amiberry Merge Assistant
Help merge updates from WinUAE (Windows-only) to Amiberry (multi-platform: Linux/macOS/Android).
Overview
WinUAE is the upstream Windows-based Amiga emulator. Amiberry is a cross-platform port.
Core emulation is identical: Most emulation code (CPU, chipset, floppy, HDD) requires no changes when merging.
Platform layer differs:
- •Rendering: WinUAE uses Direct3D; Amiberry uses OpenGL + SDL2
- •Audio: WinUAE uses WASAPI; Amiberry uses SDL2 audio
- •Input: WinUAE uses DirectInput; Amiberry uses SDL2
- •Threading: WinUAE uses Win32 threads; Amiberry uses SDL2 threading
- •GUI: WinUAE uses Win32 dialogs; Amiberry uses Dear ImGui (in
src/osdep/imgui/) - •Build: WinUAE uses Visual Studio; Amiberry uses CMake (+ Gradle for Android)
- •Platforms: Amiberry targets Linux, macOS, and Android (SDL2, migrating to SDL3 eventually)
- •CI/CD: GitHub Actions builds all platforms on each commit
Merge Workflow
Follow these steps when merging WinUAE updates:
1. Identify What Changed
Get the WinUAE commit(s) to merge. This could be:
- •A specific commit hash
- •A range of commits
- •The latest upstream changes
Review the commit messages and changed files to understand:
- •What functionality was added/changed
- •Which subsystems are affected
- •Whether it's bug fixes, new features, or refactoring
2. Analyze Platform Dependencies
Use the analysis scripts to identify Windows-specific code:
# Analyze specific files or directories for Windows API usage python scripts/analyze_windows_code.py <path-to-changed-files> # Identify GUI code that needs ImGui adaptation python scripts/analyze_gui_code.py <path-to-changed-files>
The scripts will flag:
- •Direct3D code needing OpenGL adaptation
- •WASAPI audio needing SDL2 audio adaptation
- •DirectInput needing SDL2 input
- •Win32 threading needing SDL2 threading
- •Win32 API calls needing SDL2/POSIX equivalents
- •GUI code needing ImGui implementation
- •File system code needing path handling fixes
Note: Core emulation code (CPU, chipset) typically won't trigger many warnings.
3. Plan the Adaptation
For each identified issue:
Windows API → SDL2/POSIX:
- •Consult
references/platform-mappings.mdfor common API translations - •Use SDL2 when available for cross-platform abstraction (rendering, audio, input, threading)
- •Fall back to POSIX APIs only when SDL2 doesn't provide equivalent functionality
- •Add platform-specific guards using
#ifdefwhen necessary
GUI Changes:
- •Win32 dialogs → ImGui windows in
src/osdep/imgui/ - •Maintain similar layout and functionality to WinUAE for consistency
- •Use ImGui layout functions (
ImGui::SameLine(),ImGui::Spacing()) - •Keep user-facing behavior as close to WinUAE as possible
- •See the "GUI Synchronization Guide" section below for detailed instructions.
File System:
- •Replace backslashes with forward slashes or use
std::filesystem::path - •Handle platform-specific paths appropriately
- •Ensure Android file access goes through proper APIs when needed
Platform Guards:
#ifdef _WIN32
// Windows (should not appear in Amiberry)
#elif defined(__APPLE__)
// macOS-specific
#elif defined(ANDROID)
// Android-specific
#else
// Linux and other Unix-like
#endif
4. Apply Changes
Adapt the WinUAE code for Amiberry:
- •Replace Windows APIs with SDL2/POSIX equivalents
- •Implement or modify ImGui UI for any GUI changes
- •Add appropriate platform guards for macOS/Android specifics
- •Update CMakeLists.txt if new files are added
- •Ensure code follows Amiberry's existing patterns
5. Test
After applying changes:
- •Verify code compiles on all platforms (CI will check automatically)
- •Test functionality on primary development platform
- •Check that GUI changes match WinUAE behavior
- •Confirm no Windows-specific code leaked through
- •Test with different configurations if relevant
GUI Synchronization Guide
This section provides guidance for synchronizing Amiberry's ImGui GUI implementation with WinUAE's Windows GUI (win32gui.cpp). The Amiberry panels in src/osdep/imgui/ are ports of WinUAE's Windows dialog-based GUI.
WinUAE win32gui.cpp Structure
WinUAE's GUI code (mostly in od-win32/win32gui.cpp) follows a consistent pattern for each settings panel:
Key Function Types
- •
values_to_XXXdlg()- Populates dialog controls fromworkprefs- •Reads current settings and updates UI controls
- •Example:
values_to_memorydlg()sets slider positions from memory sizes
- •
values_from_XXXdlg()- Reads dialog controls intoworkprefs(if present)- •Some panels handle this in the dialog proc instead
- •
enable_for_XXXdlg()- Enables/disables controls based on configuration- •Example: Z3 controls disabled when
address_space_24 == true
- •Example: Z3 controls disabled when
- •
fix_values_XXXdlg()- Validates and fixes invalid configurations- •Example:
fix_values_memorydlg()limits Fast RAM when Chip > 2MB
- •Example:
- •
XXXDlgProc()- Windows dialog procedure- •
WM_INITDIALOG- Initialize controls, set ranges - •
WM_COMMAND- Handle button clicks, checkbox changes - •
WM_HSCROLL- Handle slider changes - •
WM_USER- Refresh dialog from settings
- •
Files Reference
| Panel | Amiberry ImGui (src/osdep/imgui/) | WinUAE Functions |
|---|---|---|
| RAM | ram.cpp | MemoryDlgProc, values_to_memorydlg, setfastram_selectmenu |
| CPU | cpu.cpp | CPUDlgProc, values_to_cpudlg |
| Chipset | chipset.cpp | ChipsetDlgProc, values_to_chipsetdlg |
| Display | display.cpp | DisplayDlgProc, values_to_displaydlg |
| Sound | sound.cpp | SoundDlgProc, values_to_sounddlg |
| Floppy | floppy.cpp | FloppyDlgProc, values_to_floppydlg |
| HD | hd.cpp | HarddiskDlgProc, values_to_harddiskdlg |
| Expansions | expansions.cpp | ExpansionDlgProc, values_to_expansiondlg |
Porting Guidelines
ImGui Equivalents for Windows Controls
| Windows Control | ImGui Equivalent |
|---|---|
Trackbar (TBM_*) | ImGui::SliderInt() |
Combo Box (CB_*) | ImGui::BeginCombo() / ImGui::Selectable() |
| Check Box | ImGui::Checkbox() or custom AmigaCheckbox() |
| Edit Control | ImGui::InputText() |
| Static Text | ImGui::Text() |
| Group Box | BeginGroupBox() / EndGroupBox() |
| Enable/Disable | ImGui::BeginDisabled() / ImGui::EndDisabled() |
Common Patterns
1. Reading slider values:
WinUAE:
v = memsizes[msi_chip[SendMessage(GetDlgItem(hDlg, IDC_CHIPMEM), TBM_GETPOS, 0, 0)]];
Amiberry ImGui:
int chip_idx = get_mem_index(changed_prefs.chipmem.size, msi_chip, 7);
if (ImGui::SliderInt("##slider", &chip_idx, 0, 6, "")) {
changed_prefs.chipmem.size = memsizes[msi_chip[chip_idx]];
}
2. Populating dropdowns:
WinUAE:
xSendDlgItemMessage(hDlg, IDC_COMBO, CB_ADDSTRING, 0, (LPARAM)text);
Amiberry ImGui:
if (ImGui::BeginCombo("##combo", current_text)) {
if (ImGui::Selectable(text, is_selected)) { /* handle selection */ }
ImGui::EndCombo();
}
Validation Checklist
When porting or updating a panel, verify:
- • All controls present in WinUAE are implemented
- • Enable/disable logic matches WinUAE's
enable_for_XXXdlg() - • Value validation matches WinUAE's
fix_values_XXXdlg()(if exists) - • Side effects (e.g., auto-enable chipset features) are implemented
- • Multiple board support where applicable
- • Dropdown items match WinUAE format (especially names with prefixes)
- • Size limits and range checks match WinUAE constants
Common Scenarios
Scenario: Core Emulation Changes
When WinUAE updates core emulation (CPU, chipset, floppy, HDD, memory):
- •Usually no platform dependencies - code is identical between projects
- •Check for timing functions if present (
QueryPerformanceCounter→SDL_GetPerformanceCounter) - •Check for file I/O if disk/ROM handling changed
- •Check for threading if multi-threaded emulation changed
- •Most core emulation merges cleanly with minimal or no changes
Scenario: Rendering/Graphics Changes
When WinUAE updates Direct3D rendering:
- •Requires significant adaptation to OpenGL
- •Check shader code (HLSL → GLSL)
- •Verify texture/buffer management
- •Test visual output carefully
- •May need expertise in both Direct3D and OpenGL
Scenario: Input System Changes
When WinUAE updates input handling:
- •DirectInput → SDL2 input system
- •May need updates to both keyboard and joystick handling
- •Check
GetAsyncKeyStateusage →SDL_GetKeyboardState - •Test on actual hardware if possible
Scenario: Audio System Changes
When WinUAE updates WASAPI audio code:
- •Adapt to SDL2 audio subsystem
- •Check buffer sizes and latency settings
- •Verify sample rate handling
- •Test audio quality and synchronization
Common Pitfalls & Troubleshooting
1. The "Black Screen" on Standard VSync
Symptom: Amiga emulation runs (Audio works) but screen is black when VSync Standard is active.
Cause: Amiberry manages frame timing differently than WinUAE. WinUAE's drawing.cpp often contains blanking limit checks that conflict with Amiberry's amiberry_gfx.cpp.
Fix:
- •Ensure
set_custom_limits(-1, -1, -1, -1, false)is called inlockscr()(seeamiberry_gfx.cpp). - •Do NOT port WinUAE's
vbcopy()changes if they enforce alpha channels incorrectly for SDL2. - •Check
show_screen_maybe()logic; Amiberry handles presentation inSDL2_renderframe.
2. Mouse Coordinate Drift
Symptom: Mouse clicks are offset from the cursor, especially on macOS or High-DPI screens. Cause: SDL2 Events report "Screen Coordinates" (Points), but OpenGL renders in "Pixels". Fix:
- •Do NOT use raw event coordinates directly for Amiga input.
- •You must apply a scaling factor using
SDL_GetWindowSizevsSDL_GL_GetDrawableSize. - •See
handle_mouse_motion_eventinamiberry.cppfor the correct implementation.
3. ImGui Scaling on Android/Touch
Symptom: Buttons are too small to touch on Android, or dialogs are huge on Desktop.
Cause: Hardcoding pixel sizes (e.g., Width(100)).
Fix:
- •ALWAYS use
BUTTON_WIDTHconstant for sizing interactive elements. - •Use
ImGui::GetContentRegionAvail().xfor dynamic widths. - •Avoid absolute pixel values for layout.
Performance Pitfalls
RTG: Dirty Rectangles
WinUAE's getwritewatch returns a list of pages. Amiberry tracks min_dirty_page_index and max_dirty_page_index.
- •Optimization: When processing RTG updates, ensure you iterate ONLY from
mintomaxpages. Scanning the entire VRAM (e.g. 8MB+) every frame will kill performance on ARM devices.
Zero Copy Hazards
If currprefs.rtg_zerocopy is true, gfx_lock_picasso() may return nullptr.
- •This means "No copy needed, surface IS the VRAM".
- •Crash Risk: If you blindly access the pointer returned by
lockvarswithout checking for nullptr, you will crash.
Quick Reference
Key Amiberry directories:
- •
src/osdep/imgui/- ImGui GUI implementation - •
src/osdep/- Platform-specific code - •Root CMakeLists.txt - Build configuration
Analysis tools:
- •
scripts/analyze_windows_code.py- Find Windows API usage - •
scripts/analyze_gui_code.py- Find GUI code needing ImGui
References:
- •
references/platform-mappings.md- API translation guide
Tips
- •Start with non-GUI changes (they're usually easier)
- •Keep commits focused on logical units
- •Preserve WinUAE's commit messages for traceability
- •When uncertain about an API translation, check how similar code is handled elsewhere in Amiberry
- •Test incrementally rather than merging everything at once