From ad49828c4ff7c9138ca39a031eb26a340b42df38 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Jun 2018 15:39:02 -0700 Subject: [PATCH 01/10] GBA Cheats: Fix PARv3 button codes --- src/gba/cheats/parv3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gba/cheats/parv3.c b/src/gba/cheats/parv3.c index a49333568..0d74aaed4 100644 --- a/src/gba/cheats/parv3.c +++ b/src/gba/cheats/parv3.c @@ -155,6 +155,7 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) { cheat = mCheatListAppend(&cheats->d.list); cheat->type = CHEAT_ASSIGN; cheat->width = 1; + cheat->repeat = 1; cheat->address = _parAddr(op2); cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); break; @@ -166,6 +167,7 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) { cheat = mCheatListAppend(&cheats->d.list); cheat->type = CHEAT_ASSIGN; cheat->width = 2; + cheat->repeat = 1; cheat->address = _parAddr(op2); cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); break; @@ -177,6 +179,7 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) { cheat = mCheatListAppend(&cheats->d.list); cheat->type = CHEAT_ASSIGN; cheat->width = 4; + cheat->repeat = 1; cheat->address = _parAddr(op2); cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); break; From 302d4860f3101b15b64a1aa042b40d80784f853f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Jun 2018 15:52:49 -0700 Subject: [PATCH 02/10] Travis: Attempt to fix --- .travis-deps.sh | 11 ++++++----- .travis.yml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis-deps.sh b/.travis-deps.sh index b249cefee..64e45cc98 100755 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -1,16 +1,17 @@ #!/bin/sh if [ $TRAVIS_OS_NAME = "osx" ]; then brew update - brew install qt5 ffmpeg imagemagick sdl2 libzip libpng + brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip else sudo apt-get clean + sudo add-apt-repository -y ppa:beineri/opt-qt542-trusty sudo add-apt-repository -y ppa:george-edison55/cmake-3.x sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo apt-get update - sudo apt-get install -y -q cmake libedit-dev libmagickwand-dev \ - libpng-dev libsdl2-dev libzip-dev qtbase5-dev \ - libqt5opengl5-dev qtmultimedia5-dev libavcodec-dev \ - libavutil-dev libavformat-dev libavresample-dev libswscale-dev + sudo apt-get install -y -q cmake libedit-dev libelf-dev libmagickwand-dev \ + libpng-dev libsdl2-dev libzip-dev qt54base qt54multimedia \ + libavcodec-dev libavutil-dev libavformat-dev libavresample-dev \ + libswscale-dev if [ "$CC" == "gcc" ]; then sudo apt-get install -y -q gcc-5 g++-5 export CC=gcc-5 diff --git a/.travis.yml b/.travis.yml index 3f3e6077c..17bcaca87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ matrix: before_install: - source ./.travis-deps.sh -script: mkdir build && cd build && cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 .. && make -j2 +script: mkdir build && cd build && cmake -DCMAKE_PREFIX_PATH='/usr/local/opt/qt5;/opt/qt54' .. && make -j2 From 746f2b8e6a8a360289f40c6b7425abc1c07d5d91 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 11:52:43 -0700 Subject: [PATCH 03/10] GB Video: Fix initialization --- src/gb/gb.c | 2 ++ src/gb/io.c | 6 +++++- src/gb/video.c | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index d308dc977..cce40b5ce 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -547,6 +547,8 @@ void GBSkipBIOS(struct GB* gb) { mTimingDeschedule(&gb->timing, &gb->timer.event); mTimingSchedule(&gb->timing, &gb->timer.event, 0); + GBIOWrite(gb, REG_LCDC, 0x91); + if (gb->biosVf) { GBUnmapBIOS(gb); } diff --git a/src/gb/io.c b/src/gb/io.c index 75a292235..96959470a 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -182,7 +182,11 @@ void GBIOReset(struct GB* gb) { GBIOWrite(gb, REG_NR43, 0x00); GBIOWrite(gb, REG_NR50, 0x77); GBIOWrite(gb, REG_NR51, 0xF3); - GBIOWrite(gb, REG_LCDC, 0x91); + if (!gb->biosVf) { + GBIOWrite(gb, REG_LCDC, 0x91); + } else { + GBIOWrite(gb, REG_LCDC, 0x00); + } GBIOWrite(gb, REG_SCY, 0x00); GBIOWrite(gb, REG_SCX, 0x00); GBIOWrite(gb, REG_LYC, 0x00); diff --git a/src/gb/video.c b/src/gb/video.c index 26c1f25da..131c6f6b3 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -419,6 +419,7 @@ void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value) { video->mode = 2; video->modeEvent.callback = _endMode2; int32_t next = GB_VIDEO_MODE_2_LENGTH - 5; // TODO: Why is this fudge factor needed? Might be related to T-cycles for load/store differing + mTimingDeschedule(&video->p->timing, &video->modeEvent); mTimingSchedule(&video->p->timing, &video->modeEvent, next << video->p->doubleSpeed); video->ly = 0; @@ -445,6 +446,7 @@ void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value) { video->renderer->writePalette(video->renderer, 0, video->dmgPalette[0]); mTimingDeschedule(&video->p->timing, &video->modeEvent); + mTimingDeschedule(&video->p->timing, &video->frameEvent); mTimingSchedule(&video->p->timing, &video->frameEvent, GB_VIDEO_TOTAL_LENGTH); } video->p->memory.io[REG_STAT] = video->stat; From 9983cb87c93790d1383cc432b5074759b12aec44 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 11:52:59 -0700 Subject: [PATCH 04/10] Cinema: Fix pytest --output-diff --- src/platform/python/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/python/conftest.py b/src/platform/python/conftest.py index 6690268a1..06826a741 100644 --- a/src/platform/python/conftest.py +++ b/src/platform/python/conftest.py @@ -23,7 +23,7 @@ def pytest_exception_interact(node, call, report): if outroot: if not vtest: return - outdir = os.path.join(outroot, *vtest.fullPath) + outdir = os.path.join(outroot, *vtest.full_path) try: os.makedirs(outdir) except OSError as e: From c2490afe4f5e7c3c7ab8eb112935e097945e7ae6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 11:53:35 -0700 Subject: [PATCH 05/10] GB Audio: Fix initialization --- src/gb/audio.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 4b098230c..a84aad3a8 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -143,22 +143,13 @@ void GBAudioReset(struct GBAudio* audio) { audio->capLeft = 0; audio->capRight = 0; audio->clock = 0; - audio->volumeRight = 0; - audio->volumeLeft = 0; - audio->ch1Right = false; - audio->ch2Right = false; - audio->ch3Right = false; - audio->ch4Right = false; - audio->ch1Left = false; - audio->ch2Left = false; - audio->ch3Left = false; - audio->ch4Left = false; audio->playingCh1 = false; audio->playingCh2 = false; audio->playingCh3 = false; audio->playingCh4 = false; - if (audio->p && (audio->p->model == GB_MODEL_DMG || audio->p->model == GB_MODEL_CGB)) { + if (audio->p && audio->p->model != GB_MODEL_SGB) { audio->playingCh1 = true; + audio->enable = true; *audio->nr52 |= 0x01; } } From 80472c9f3a0b39dde23c893010e9b253403e08cb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 11:54:03 -0700 Subject: [PATCH 06/10] GB I/O: DMA register is R/W --- CHANGES | 1 + src/gb/io.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index c9d66057a..4291537e2 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,7 @@ Bugfixes: - GBA Serialize: Fix loading channel 3 volume (fixes mgba.io/i/1107) - GBA SIO: Fix unconnected SIOCNT for multi mode (fixes mgba.io/i/1105) - GBA BIOS: Fix BitUnPack final byte + - GB I/O: DMA register is R/W Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/src/gb/io.c b/src/gb/io.c index 96959470a..d24576333 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -190,6 +190,7 @@ void GBIOReset(struct GB* gb) { GBIOWrite(gb, REG_SCY, 0x00); GBIOWrite(gb, REG_SCX, 0x00); GBIOWrite(gb, REG_LYC, 0x00); + GBIOWrite(gb, REG_DMA, 0xFF); GBIOWrite(gb, REG_BGP, 0xFC); if (gb->model < GB_MODEL_CGB) { GBIOWrite(gb, REG_OBP0, 0xFF); @@ -618,6 +619,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_SCX: case REG_LY: case REG_LYC: + case REG_DMA: case REG_BGP: case REG_OBP0: case REG_OBP1: @@ -642,9 +644,6 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_SVBK: // Handled transparently by the registers goto success; - case REG_DMA: - mLOG(GB_IO, STUB, "Reading from unknown register FF%02X", address); - return 0; default: break; } From 781f2fbb90fa02494e40b8444a452331d843c1aa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 13:26:24 -0700 Subject: [PATCH 07/10] GB Video: Fix SCX timing --- CHANGES | 1 + include/mgba/internal/gb/video.h | 2 +- src/gb/video.c | 22 ++++++++++++---------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 4291537e2..c29b5a6a5 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,7 @@ Bugfixes: - GBA SIO: Fix unconnected SIOCNT for multi mode (fixes mgba.io/i/1105) - GBA BIOS: Fix BitUnPack final byte - GB I/O: DMA register is R/W + - GB Video: Fix SCX timing Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index ec7409af9..3f33e9383 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -128,7 +128,7 @@ struct GBVideo { struct mTimingEvent modeEvent; struct mTimingEvent frameEvent; - uint32_t dotClock; + int32_t dotClock; uint8_t* vram; uint8_t* vramBank; diff --git a/src/gb/video.c b/src/gb/video.c index 131c6f6b3..958088b3f 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -224,8 +224,7 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { GBRegisterSTAT oldStat = video->stat; video->stat = GBRegisterSTATSetLYC(video->stat, lyc == video->ly); if (video->ly < GB_VIDEO_VERTICAL_PIXELS) { - // TODO: Cache SCX & 7 in case it changes during mode 2 - next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7); + next = GB_VIDEO_MODE_2_LENGTH; video->mode = 2; video->modeEvent.callback = _endMode2; } else { @@ -262,7 +261,7 @@ void _endMode1(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS + 1) { video->ly = 0; video->p->memory.io[REG_LY] = video->ly; - next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7); + next = GB_VIDEO_MODE_2_LENGTH; video->mode = 2; video->modeEvent.callback = _endMode2; } else if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS) { @@ -290,9 +289,9 @@ void _endMode1(struct mTiming* timing, void* context, uint32_t cyclesLate) { void _endMode2(struct mTiming* timing, void* context, uint32_t cyclesLate) { struct GBVideo* video = context; _cleanOAM(video, video->ly); - video->x = 0; - video->dotClock = mTimingCurrentTime(timing) - cyclesLate; - int32_t next = GB_VIDEO_MODE_3_LENGTH_BASE + video->objMax * 6 - (video->p->memory.io[REG_SCX] & 7); + video->x = -(video->p->memory.io[REG_SCX] & 7); + video->dotClock = mTimingCurrentTime(timing) - cyclesLate + 5 - (video->x << video->p->doubleSpeed); + int32_t next = GB_VIDEO_MODE_3_LENGTH_BASE + video->objMax * 6 - video->x; video->mode = 3; video->modeEvent.callback = _endMode3; GBRegisterSTAT oldStat = video->stat; @@ -323,7 +322,8 @@ void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate) { GBUpdateIRQs(video->p); } video->p->memory.io[REG_STAT] = video->stat; - int32_t next = GB_VIDEO_MODE_0_LENGTH_BASE - video->objMax * 6; + // TODO: Cache SCX & 7 in case it changes + int32_t next = GB_VIDEO_MODE_0_LENGTH_BASE - video->objMax * 6 - (video->p->memory.io[REG_SCX] & 7); mTimingSchedule(timing, &video->modeEvent, (next << video->p->doubleSpeed) - cyclesLate); } @@ -402,12 +402,14 @@ void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate) { return; } int oldX = video->x; - video->x = (mTimingCurrentTime(&video->p->timing) - video->dotClock - cyclesLate) >> video->p->doubleSpeed; + video->x = (int32_t) (mTimingCurrentTime(&video->p->timing) - cyclesLate - video->dotClock) >> video->p->doubleSpeed; if (video->x > GB_VIDEO_HORIZONTAL_PIXELS) { video->x = GB_VIDEO_HORIZONTAL_PIXELS; } else if (video->x < 0) { - mLOG(GB, FATAL, "Video dot clock went negative!"); - video->x = oldX; + return; + } + if (oldX < 0) { + oldX = 0; } if (video->frameskipCounter <= 0) { video->renderer->drawRange(video->renderer, oldX, video->x, video->ly, video->objThisLine, video->objMax); From 9fef8ec49d559b13f9cca644b53da749b5ea52d5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Jun 2018 15:46:26 -0700 Subject: [PATCH 08/10] Python: More setup cleanup --- src/platform/python/CMakeLists.txt | 6 +++-- src/platform/python/_builder.py | 2 -- src/platform/python/setup.py.in | 35 ------------------------------ 3 files changed, 4 insertions(+), 39 deletions(-) delete mode 100644 src/platform/python/setup.py.in diff --git a/src/platform/python/CMakeLists.txt b/src/platform/python/CMakeLists.txt index a5b568813..d743e9924 100644 --- a/src/platform/python/CMakeLists.txt +++ b/src/platform/python/CMakeLists.txt @@ -5,8 +5,10 @@ include_directories(AFTER ${PYTHON_INCLUDE_DIRS}) get_property(INCLUDE_DIRECTORIES DIRECTORY PROPERTY INCLUDE_DIRECTORIES) set(INCLUDE_FLAGS) +set(INCLUDE_FLAGS_STR "") foreach(DIR IN LISTS INCLUDE_DIRECTORIES) - list(APPEND INCLUDE_FLAGS "-I${DIR}") + list(APPEND INCLUDE_FLAGS "-I${DIR}") + set(INCLUDE_FLAGS_STR "${INCLUDE_FLAGS_STR} \"-I${DIR}\"") endforeach() file(GLOB PYTHON_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) @@ -64,5 +66,5 @@ foreach(TEST IN LISTS BASE_TESTS SUBTESTS) add_test(NAME python-${TEST_NAME} COMMAND ${PYTHON_EXECUTABLE} setup.py build -b ${CMAKE_CURRENT_BINARY_DIR} pytest --extras --addopts ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - set_tests_properties(python-${TEST_NAME} PROPERTIES ENVIRONMENT "${PATH}=${CMAKE_CURRENT_BINARY_DIR}/..;BINDIR=${CMAKE_CURRENT_BINARY_DIR}/..;LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/..;CPPFLAGS=${INCLUDE_FLAGS}") + set_tests_properties(python-${TEST_NAME} PROPERTIES ENVIRONMENT "${PATH}=${CMAKE_CURRENT_BINARY_DIR}/..;BINDIR=${CMAKE_CURRENT_BINARY_DIR}/..;LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/..;CPPFLAGS=${INCLUDE_FLAGS_STR}") endforeach() diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index cdd610321..707703c5b 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -13,8 +13,6 @@ libdir = os.environ.get("LIBDIR") cpp = shlex.split(os.environ.get("CPP", "cc -E")) cppflags = shlex.split(os.environ.get("CPPFLAGS", "")) -if __name__ == "__main__": - cppflags.extend(sys.argv[1:]) cppflags.extend(["-I" + incdir, "-I" + srcdir, "-I" + bindir]) ffi.set_source("mgba._pylib", """ diff --git a/src/platform/python/setup.py.in b/src/platform/python/setup.py.in deleted file mode 100644 index 3546cb876..000000000 --- a/src/platform/python/setup.py.in +++ /dev/null @@ -1,35 +0,0 @@ -from setuptools import setup -import re -import os -import sys - -os.environ["BINDIR"] = "${CMAKE_BINARY_DIR}" -os.environ["LIBDIR"] = "${CMAKE_INSTALL_PREFIX}/${LIBDIR}" -os.environ["CPPFLAGS"] = " ".join([d for d in "${INCLUDE_FLAGS}".split(";") if d]) - -classifiers = [ - "Programming Language :: C", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", - "Topic :: Games/Entertainment", - "Topic :: System :: Emulators" -] - -setup(name="${BINARY_NAME}", - version="${LIB_VERSION_STRING}", - author="Jeffrey Pfau", - author_email="jeffrey@endrift.com", - url="http://github.com/mgba-emu/mgba/", - packages=["mgba"], - package_dir={ - "mgba": "${CMAKE_CURRENT_SOURCE_DIR}/mgba" - }, - setup_requires=['cffi>=1.6', 'pytest-runner'], - install_requires=['cffi>=1.6', 'cached-property'], - extras_require={'pil': ['Pillow>=2.3'], 'cinema': ['pyyaml', 'pytest']}, - tests_require=['pytest'], - cffi_modules=["${CMAKE_CURRENT_SOURCE_DIR}/_builder.py:ffi"], - license="MPL 2.0", - classifiers=classifiers - ) From 4d49aa095b000f2f869d53d7e1c0f527d6858e88 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 30 Jun 2018 15:51:51 -0700 Subject: [PATCH 09/10] Core: Fix threading memory leak --- src/core/thread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/thread.c b/src/core/thread.c index 7584f711f..69183d072 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -269,6 +269,9 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } core->clearCoreCallbacks(core); + if (threadContext->logger.d.filter == &filter) { + mLogFilterDeinit(&filter); + } threadContext->logger.d.filter = NULL; return 0; From e11e5ef9707163895b454fbbdcab9670244e5ae9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 2 Jul 2018 20:42:20 -0700 Subject: [PATCH 10/10] util: Formatting cleanup --- CMakeLists.txt | 13 ++++++++++--- include/mgba-util/formatting.h | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2468ec37e..d3f0c353e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,11 +311,13 @@ if(DEFINED 3DS) endif() include(CheckFunctionExists) +include(CheckIncludeFiles) check_function_exists(strdup HAVE_STRDUP) check_function_exists(strndup HAVE_STRNDUP) if(NOT DEFINED PSP2) check_function_exists(localtime_r HAVE_LOCALTIME_R) endif() +check_include_files("xlocale.h" HAVE_XLOCALE) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") check_function_exists(snprintf_l HAVE_SNPRINTF_L) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -373,9 +375,6 @@ endif() if(HAVE_NEWLOCALE AND HAVE_FREELOCALE AND HAVE_USELOCALE OR APPLE) list(APPEND FUNCTION_DEFINES HAVE_LOCALE) - if (HAVE_STRTOF_L) - list(APPEND FUNCTION_DEFINES HAVE_STRTOF_L) - endif() if (HAVE_SNPRINTF_L) list(APPEND FUNCTION_DEFINES HAVE_SNPRINTF_L) endif() @@ -385,6 +384,14 @@ if(HAVE_SETLOCALE) list(APPEND FUNCTION_DEFINES HAVE_SETLOCALE) endif() +if (HAVE_STRTOF_L) + list(APPEND FUNCTION_DEFINES HAVE_STRTOF_L) +endif() + +if(HAVE_XLOCALE) + list(APPEND FUNCTION_DEFINES HAVE_XLOCALE) +endif() + if(HAVE_CHMOD) list(APPEND FUNCTION_DEFINES HAVE_CHMOD) endif() diff --git a/include/mgba-util/formatting.h b/include/mgba-util/formatting.h index 4395879aa..6eb01ffaf 100644 --- a/include/mgba-util/formatting.h +++ b/include/mgba-util/formatting.h @@ -12,8 +12,8 @@ CXX_GUARD_START #include "locale.h" -#if defined(__APPLE__) || defined(__FreeBSD__) -#include "xlocale.h" +#ifdef HAVE_XLOCALE +#include #elif !defined(HAVE_LOCALE) typedef const char* locale_t; #endif