mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
3304a448ed
|
@ -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 @@ 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
|
||||
|
|
2
CHANGES
2
CHANGES
|
@ -59,6 +59,8 @@ 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
|
||||
- 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 @@ 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")
|
||||
|
@ -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()
|
||||
|
@ -390,6 +389,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()
|
||||
|
|
|
@ -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 GBVideo {
|
|||
struct mTimingEvent modeEvent;
|
||||
struct mTimingEvent frameEvent;
|
||||
|
||||
uint32_t dotClock;
|
||||
int32_t dotClock;
|
||||
|
||||
uint8_t* vram;
|
||||
uint8_t* vramBank;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
11
src/gb/io.c
11
src/gb/io.c
|
@ -182,10 +182,15 @@ 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);
|
||||
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 @@ 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:
|
||||
|
@ -638,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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -419,6 +421,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 +448,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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 @@ 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:
|
||||
|
|
|
@ -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
|
||||
)
|
Loading…
Reference in New Issue