Assist with merging updates and synchronizing functionality from the upstream WinUAE repository (Windows) to Amiberry (Linux/macOS/Android/Windows). Includes a guide for porting Win32 GUI dialogs to Dear ImGui, mapping Windows controls to ImGui equivalents, analyzing platform-specific code, and preserving upstream-sync safety when Amiberry needs local divergences in WinUAE-tracked files. Use this for analyzing upstream commits, identifying Windows-specific code, adapting GUI panels, handling `#ifdef AMIBERRY` splits, and verifying feature parity.
Help merge updates from WinUAE (Windows-only, MSVC) to Amiberry (multi-platform: Linux/macOS/Android/Windows with MinGW-w64).
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:
src/osdep/imgui/)Follow these steps when merging WinUAE updates:
Get the WinUAE commit(s) to merge. This could be:
Review the commit messages and changed files to understand:
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:
Note: Core emulation code (CPU, chipset) typically won't trigger many warnings.
For each identified issue:
Windows API → SDL2/POSIX:
references/platform-mappings.md for common API translations#ifdef when necessaryGUI Changes:
src/osdep/imgui/ImGui::SameLine(), ImGui::Spacing())File System:
std::filesystem::pathPlatform Guards:
#ifdef _WIN32
// Windows-specific (both WinUAE/MSVC and Amiberry/MinGW-w64)
// Note: Amiberry on Windows DOES define _WIN32, so many WinUAE
// Windows code paths are active. Use #ifdef AMIBERRY to distinguish.
#elif defined(__APPLE__)
// macOS-specific
#elif defined(ANDROID)
// Android-specific
#else
// Linux and other Unix-like
#endif
// To distinguish Amiberry from WinUAE on Windows:
#if defined(_WIN32) && defined(AMIBERRY)
// Amiberry on Windows (MinGW-w64/GCC)
#elif defined(_WIN32)
// WinUAE (MSVC)
#endif
// Platforms without reliable symlink support:
#if defined(__ANDROID__) || defined(_WIN32)
// Use std::filesystem::copy() instead of create_symlink()
#endif
Key difference: Amiberry on Windows vs WinUAE:
unistd.h, dirent.h, etc.)_MSC_VER-specific code#ifdef _WIN32 blocks from WinUAE now activate in Amiberry on Windowssysconfig.h previously #undef _WIN32 to suppress this; that was removedWhen the fix touches a WinUAE-synced core file such as drawing.cpp, decide whether the change is:
Rules:
#ifdef AMIBERRY blocks around the local logic instead of rewriting the surrounding upstream flow.#else path when feasible. This makes future WinUAE merges either preserve the divergence or create a conflict that forces review.#ifdef AMIBERRY blocks across unrelated logic. Keep them tight around the minimum Amiberry-only state, helper, or call site.src/osdep/ instead of a synced core file, prefer moving it there.Adapt the WinUAE code for Amiberry:
After applying changes:
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's GUI code (mostly in od-win32/win32gui.cpp) follows a consistent pattern for each settings panel:
values_to_XXXdlg() - Populates dialog controls from workprefs
values_to_memorydlg() sets slider positions from memory sizesvalues_from_XXXdlg() - Reads dialog controls into workprefs (if present)
enable_for_XXXdlg() - Enables/disables controls based on configuration
address_space_24 == truefix_values_XXXdlg() - Validates and fixes invalid configurations
fix_values_memorydlg() limits Fast RAM when Chip > 2MBXXXDlgProc() - Windows dialog procedure
WM_INITDIALOG - Initialize controls, set rangesWM_COMMAND - Handle button clicks, checkbox changesWM_HSCROLL - Handle slider changesWM_USER - Refresh dialog from settings| 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 |
| 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() |
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();
}
When porting or updating a panel, verify:
enable_for_XXXdlg()fix_values_XXXdlg() (if exists)When WinUAE updates core emulation (CPU, chipset, floppy, HDD, memory):
QueryPerformanceCounter → SDL_GetPerformanceCounter)cddafs locks, requiring physical CD access open() to target character devices (/dev/rdiskX) instead of block devices (/dev/diskX). Apple's DiskArbitration framework TOC retrieval requires the block device string counterpart instead.When WinUAE updates Direct3D rendering:
When WinUAE updates input handling:
GetAsyncKeyState usage → SDL_GetKeyboardStateWhen WinUAE updates WASAPI audio code:
Symptom: Feature works in WinUAE but not in Amiberry's ImGui GUI.
Cause: WinUAE's win32gui.cpp dialog procedures contain logic (validation, auto-detection, side effects) that may not have been ported to the corresponding ImGui panel.
Example: hd.cpp was missing hardfile_testrdb() after HDF file selection — WinUAE calls this in HarddiskDlgProc to auto-detect RDB and reset geometry. The ImGui port omitted it.
Fix: When debugging GUI issues, always compare the ImGui panel code against the corresponding WinUAE dialog procedure for missing function calls, especially values_from_*, fix_values_*, and helper functions called on control changes.
Symptom: fopen() returns NULL with errno=22 (EINVAL) on Windows.
Cause: MinGW GCC links msvcrt.dll (not ucrtbase.dll). The "ccs=UTF-8" fopen mode extension is UCRT-only. WinUAE (MSVC) links ucrtbase.dll where this works.
Fix: Under #ifdef AMIBERRY, use plain modes ("w", "rt", "wt") without ccs=UTF-8. Also note: the 'e' flag (close-on-exec) is not valid on Windows — strip it.
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:
set_custom_limits(-1, -1, -1, -1, false) is called in lockscr() (see amiberry_gfx.cpp).vbcopy() changes if they enforce alpha channels incorrectly for SDL2.show_screen_maybe() logic; Amiberry handles presentation in SDL2_renderframe.Symptom: Emulation starts but screen stays black. Queue type 0/1/2 entries never processed.
Cause: JIT check_uae_p32() detects 64-bit pointers → jit_abort() → uae_reset(1,0) → quit_program=4 permanently. waitqueue() in drawing.cpp blocks all pixel-drawing queue entries when quit_program != 0.
Fix: In src/jit/x86/compemu_x86.h, check_uae_p32() logs instead of calling jit_abort() under #ifdef AMIBERRY. JIT is non-functional on 64-bit Windows; interpreter mode handles everything.
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:
SDL_GetWindowSize vs SDL_GL_GetDrawableSize.handle_mouse_motion_event in amiberry.cpp for the correct implementation.Symptom: Buttons are too small to touch on Android, or dialogs are huge on Desktop.
Cause: Hardcoding pixel sizes (e.g., Width(100)).
Fix:
BUTTON_WIDTH constant for sizing interactive elements.ImGui::GetContentRegionAvail().x for dynamic widths.WinUAE's getwritewatch returns a list of pages. Amiberry tracks min_dirty_page_index and max_dirty_page_index.
min to max pages. Scanning the entire VRAM (e.g. 8MB+) every frame will kill performance on ARM devices.If currprefs.rtg_zerocopy is true, gfx_lock_picasso() may return nullptr.
lockvars without checking for nullptr, you will crash.Key Amiberry directories:
src/osdep/imgui/ - ImGui GUI implementationsrc/osdep/ - Platform-specific codeAnalysis tools:
scripts/analyze_windows_code.py - Find Windows API usagescripts/analyze_gui_code.py - Find GUI code needing ImGuiReferences:
references/platform-mappings.md - API translation guidesrc/osdep/#ifdef AMIBERRY, make it conflict-friendly rather than convenience-driven