Merge branch 'master' (early part) into medusa
jump to
@@ -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
@@ -11,4 +11,4 @@
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
@@ -59,6 +59,8 @@ - Qt: Improve FPS timer stability
- 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 + - 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)
@@ -316,11 +316,13 @@ add_definitions(-D_GNU_SOURCE)
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")@@ -378,9 +380,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()@@ -388,6 +387,14 @@ endif()
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)
@@ -12,8 +12,8 @@ CXX_GUARD_START
#include "locale.h" -#if defined(__APPLE__) || defined(__FreeBSD__) -#include "xlocale.h" +#ifdef HAVE_XLOCALE +#include <xlocale.h> #elif !defined(HAVE_LOCALE) typedef const char* locale_t; #endif
@@ -128,7 +128,7 @@
struct mTimingEvent modeEvent; struct mTimingEvent frameEvent; - uint32_t dotClock; + int32_t dotClock; uint8_t* vram; uint8_t* vramBank;
@@ -269,6 +269,9 @@ threadContext->cleanCallback(threadContext);
} core->clearCoreCallbacks(core); + if (threadContext->logger.d.filter == &filter) { + mLogFilterDeinit(&filter); + } threadContext->logger.d.filter = NULL; return 0;
@@ -143,22 +143,13 @@ audio->lastRight = 0;
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; } }
@@ -547,6 +547,8 @@
mTimingDeschedule(&gb->timing, &gb->timer.event); mTimingSchedule(&gb->timing, &gb->timer.event, 0); + GBIOWrite(gb, REG_LCDC, 0x91); + if (gb->biosVf) { GBUnmapBIOS(gb); }
@@ -182,10 +182,15 @@ GBIOWrite(gb, REG_NR42, 0x00);
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); + GBIOWrite(gb, REG_DMA, 0xFF); GBIOWrite(gb, REG_BGP, 0xFC); if (gb->model < GB_MODEL_CGB) { GBIOWrite(gb, REG_OBP0, 0xFF);@@ -614,6 +619,7 @@ case REG_SCY:
case REG_SCX: case REG_LY: case REG_LYC: + case REG_DMA: case REG_BGP: case REG_OBP0: case REG_OBP1:@@ -638,9 +644,6 @@ case REG_OCPD:
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; }
@@ -224,8 +224,7 @@ video->p->memory.io[REG_LY] = video->ly;
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 @@ int32_t next;
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 _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 @@ video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT);
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 @@ if (video->mode != 3) {
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);@@ -419,6 +421,7 @@ if (!GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC]) && GBRegisterLCDCIsEnable(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 +448,7 @@ video->p->memory.io[REG_LY] = 0;
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;
@@ -155,6 +155,7 @@ cheat->negativeRepeat = 0;
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 @@ cheat->negativeRepeat = 0;
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 @@ cheat->negativeRepeat = 0;
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;
@@ -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 @@ string(REPLACE ".py" "" TEST_NAME "${TEST_NAME}")
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()
@@ -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", """
@@ -23,7 +23,7 @@ vtest = node.funcargs.get('vtest')
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:
@@ -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 - )