diff --git a/.travis-deps.sh b/.travis-deps.sh index 13952a3f4..c76d4c6d6 100755 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -2,6 +2,11 @@ if [ $TRAVIS_OS_NAME = "osx" ]; then brew update brew install qt5 ffmpeg imagemagick sdl2 libzip libpng + if [ "$CC" == "gcc" ]; then + brew install gcc@4.9 + export CC=gcc-4.9 + export CXX=g++-4.9 + fi else sudo apt-get clean sudo apt-get update diff --git a/.travis.yml b/.travis.yml index da030c472..2c25e739f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,19 @@ -os: - - linux - - osx - language: c -compiler: - - gcc - - clang - sudo: required -dist: trusty +matrix: + include: + - os: linux + dist: trusty + compiler: clang + - os: linux + dist: trusty + compiler: gcc + - os: osx + compiler: clang + - os: osx + compiler: gcc before_install: - - ./.travis-deps.sh + - source ./.travis-deps.sh script: mkdir build && cd build && cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 .. && make diff --git a/CMakeLists.txt b/CMakeLists.txt index ddfb75ec5..c2842af9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,7 @@ if(WIN32) source_group("Windows-specific code" FILES ${OS_SRC}) if(MSVC) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) endif() elseif(UNIX) add_definitions(-DUSE_PTHREADS) @@ -542,10 +543,12 @@ elseif(USE_ZLIB) list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-zip.c ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/ioapi.c ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/unzip.c) - set_source_files_properties( - ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/ioapi.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/unzip.c - PROPERTIES COMPILE_FLAGS "-Wno-unused-parameter -Wno-implicit-function-declaration") + if(NOT MSVC) + set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/ioapi.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/unzip.c + PROPERTIES COMPILE_FLAGS "-Wno-unused-parameter -Wno-implicit-function-declaration") + endif() endif() if (USE_LZMA) @@ -610,7 +613,7 @@ endif() if(M_CORE_GBA) add_definitions(-DM_CORE_GBA) - list(APPEND CORE_SRC + list(APPEND CORE_SRC ${ARM_SRC} ${GBA_SRC} ${GBA_CHEATS_SRC} @@ -774,8 +777,11 @@ if(BUILD_OPENEMU) endif() if(BUILD_SDL) - add_definitions(-DBUILD_SDL) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/sdl ${CMAKE_CURRENT_BINARY_DIR}/sdl) + # The SDL platform CMakeLists could decide to disable SDL, so check again before adding the define. + if(BUILD_SDL) + add_definitions(-DBUILD_SDL) + endif() endif() if(BUILD_QT) diff --git a/README.md b/README.md index 703d9986a..61c69c8ac 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,10 @@ This will build and install mGBA into `/usr/bin` and `/usr/lib`. Dependencies th #### Windows developer building -To build on Windows for development, using MSYS2 is recommended. Follow the installation steps found on their [website](https://msys2.github.io). Make sure you're running the 32-bit version ("MinGW-w64 Win32 Shell") (or the 64-bit version "MinGW-w64 Win64 Shell" if you want to build for x86_64) and run this additional command (including the braces) to install the needed dependencies (please note that this involves downloading over 500MiB of packages, so it will take a long time): +To build on Windows for development, using MSYS2 is recommended. Follow the installation steps found on their [website](https://msys2.github.io). Make sure you're running the 32-bit version ("MSYS2 MinGW 32-bit") (or the 64-bit version "MSYS2 MinGW 64-bit" if you want to build for x86_64) and run this additional command (including the braces) to install the needed dependencies (please note that this involves downloading over 500MiB of packages, so it will take a long time): + +For x86 (32 bit) builds: -For x86 (32 bit) builds: - pacman -Sy mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libzip,pkg-config,qt5,SDL2} For x86_64 (64 bit) builds: diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 7b28a56da..4f36c0a17 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -46,6 +46,7 @@ typedef intptr_t ssize_t; #define snprintf _snprintf #define strdup _strdup #define lseek _lseek +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #elif defined(__wii__) #include typedef intptr_t ssize_t; diff --git a/include/mgba-util/png-io.h b/include/mgba-util/png-io.h index 20803303e..983992856 100644 --- a/include/mgba-util/png-io.h +++ b/include/mgba-util/png-io.h @@ -12,6 +12,10 @@ CXX_GUARD_START #ifdef USE_PNG +// png.h defines its own version of restrict which conflicts with mGBA's. +#ifdef restrict +#undef restrict +#endif #include struct VFile; diff --git a/include/mgba/core/library.h b/include/mgba/core/library.h index c2a810c7f..1408f24d3 100644 --- a/include/mgba/core/library.h +++ b/include/mgba/core/library.h @@ -39,6 +39,7 @@ void mLibraryLoadDirectory(struct mLibrary* library, const char* base); size_t mLibraryCount(struct mLibrary* library, const struct mLibraryEntry* constraints); size_t mLibraryGetEntries(struct mLibrary* library, struct mLibraryListing* out, size_t numEntries, size_t offset, const struct mLibraryEntry* constraints); +void mLibraryEntryFree(struct mLibraryEntry* entry); struct VFile* mLibraryOpenVFile(struct mLibrary* library, const struct mLibraryEntry* entry); struct NoIntroDB; diff --git a/include/mgba/core/version.h b/include/mgba/core/version.h index 048e47a27..47086618f 100644 --- a/include/mgba/core/version.h +++ b/include/mgba/core/version.h @@ -6,6 +6,10 @@ #ifndef VERSION_H #define VERSION_H +#ifdef __cplusplus +extern "C" { +#endif + extern const char* const gitCommit; extern const char* const gitCommitShort; extern const char* const gitBranch; @@ -14,4 +18,8 @@ extern const char* const binaryName; extern const char* const projectName; extern const char* const projectVersion; +#ifdef __cplusplus +} +#endif + #endif diff --git a/res/shaders/wiiu.shader/wiiu.fs b/res/shaders/wiiu.shader/wiiu.fs index 268c5d229..fcfb60bb7 100644 --- a/res/shaders/wiiu.shader/wiiu.fs +++ b/res/shaders/wiiu.shader/wiiu.fs @@ -2,21 +2,28 @@ varying vec2 texCoord; uniform sampler2D tex; uniform vec2 texSize; -const float scale[32] = float[]( - 0.0/255.0, 6.0/255.0, 12.0/255.0, 18.0/255.0, 24.0/255.0, 31.0/255.0, 37.0/255.0, 43.0/255.0, - 49.0/255.0, 55.0/255.0, 61.0/255.0, 67.0/255.0, 73.0/255.0, 79.0/255.0, 86.0/255.0, 92.0/255.0, - 98.0/255.0, 104.0/255.0, 111.0/255.0, 117.0/255.0, 123.0/255.0, 129.0/255.0, 135.0/255.0, 141.0/255.0, - 148.0/255.0, 154.0/255.0, 159.0/255.0, 166.0/255.0, 172.0/255.0, 178.0/255.0, 184.0/255.0, 191.0/255.0 -); - void main() { + float scale[32]; + scale[ 0] = 0.0/255.0; scale[ 1] = 6.0/255.0; + scale[ 2] = 12.0/255.0; scale[ 3] = 18.0/255.0; + scale[ 4] = 24.0/255.0; scale[ 5] = 31.0/255.0; + scale[ 6] = 37.0/255.0; scale[ 7] = 43.0/255.0; + scale[ 8] = 49.0/255.0; scale[ 9] = 55.0/255.0; + scale[10] = 61.0/255.0; scale[11] = 67.0/255.0; + scale[12] = 73.0/255.0; scale[13] = 79.0/255.0; + scale[14] = 86.0/255.0; scale[15] = 92.0/255.0; + scale[16] = 98.0/255.0; scale[17] = 104.0/255.0; + scale[18] = 111.0/255.0; scale[19] = 117.0/255.0; + scale[20] = 123.0/255.0; scale[21] = 129.0/255.0; + scale[22] = 135.0/255.0; scale[23] = 141.0/255.0; + scale[24] = 148.0/255.0; scale[25] = 154.0/255.0; + scale[26] = 159.0/255.0; scale[27] = 166.0/255.0; + scale[28] = 172.0/255.0; scale[29] = 178.0/255.0; + scale[30] = 184.0/255.0; scale[31] = 191.0/255.0; + vec4 color = texture2D(tex, texCoord); - color.rgb = round(color.rgb * 31.0); - color = vec4( - scale[int(color.r)], - scale[int(color.g)], - scale[int(color.b)], - 1.0 - ); + color.r = scale[int(floor(color.r * 31.0 + 0.5))]; + color.g = scale[int(floor(color.g * 31.0 + 0.5))]; + color.b = scale[int(floor(color.b * 31.0 + 0.5))]; gl_FragColor = color; -} \ No newline at end of file +} diff --git a/src/core/core.c b/src/core/core.c index 5c65297c7..025180fb4 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -158,7 +158,7 @@ bool mCoreLoadState(struct mCore* core, int slot, int flags) { if (success) { mLOG(STATUS, INFO, "State %i loaded", slot); } else { - mLOG(STATUS, INFO, "State %i failed to loaded", slot); + mLOG(STATUS, INFO, "State %i failed to load", slot); } return success; diff --git a/src/core/library.c b/src/core/library.c index 3f20d5731..d230f60a6 100644 --- a/src/core/library.c +++ b/src/core/library.c @@ -392,6 +392,12 @@ size_t mLibraryGetEntries(struct mLibrary* library, struct mLibraryListing* out, return mLibraryListingSize(out); } +void mLibraryEntryFree(struct mLibraryEntry* entry) { + free((void*) entry->title); + free((void*) entry->filename); + free((void*) entry->base); +} + struct VFile* mLibraryOpenVFile(struct mLibrary* library, const struct mLibraryEntry* entry) { struct mLibraryListing entries; mLibraryListingInit(&entries, 0); diff --git a/src/gb/core.c b/src/gb/core.c index 34dad3507..f84e58a6f 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -283,7 +283,9 @@ static void _GBCoreReset(struct mCore* core) { default: break; }; - bios = VFileOpen(configPath, O_RDONLY); + if (configPath) { + bios = VFileOpen(configPath, O_RDONLY); + } if (bios && GBIsBIOS(bios)) { found = true; } else if (bios) { diff --git a/src/gba/core.c b/src/gba/core.c index 46acc305c..69438e2c6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -311,7 +311,9 @@ static void _GBACoreReset(struct mCore* core) { } if (!found) { const char* configPath = mCoreConfigGetValue(&core->config, "gba.bios"); - bios = VFileOpen(configPath, O_RDONLY); + if (configPath) { + bios = VFileOpen(configPath, O_RDONLY); + } if (bios && GBAIsBIOS(bios)) { found = true; } else if (bios) { diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index bfd3bcd48..953f6d754 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -54,7 +54,7 @@ static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVect static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address, int segment) { struct CLIDebuggerBackend* be = debugger->backend; - struct LR35902InstructionInfo info = {}; + struct LR35902InstructionInfo info = {0}; char disassembly[48]; char* disPtr = disassembly; if (segment >= 0) { diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index cbc2adc0e..ebc007e8f 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -14,6 +14,7 @@ #include #include +#include #include #include diff --git a/src/platform/qt/LibraryModel.cpp b/src/platform/qt/LibraryModel.cpp index 1d7b64ffd..4ea208500 100644 --- a/src/platform/qt/LibraryModel.cpp +++ b/src/platform/qt/LibraryModel.cpp @@ -103,6 +103,7 @@ LibraryModel::LibraryModel(const QString& path, QObject* parent) } else { m_library = new LibraryHandle(mLibraryCreateEmpty()); } + mLibraryListingInit(&m_listings, 0); memset(&m_constraints, 0, sizeof(m_constraints)); m_constraints.platform = PLATFORM_NONE; m_columns.append(s_columns["name"]); @@ -116,6 +117,7 @@ LibraryModel::LibraryModel(const QString& path, QObject* parent) LibraryModel::~LibraryModel() { clearConstraints(); + mLibraryListingDeinit(&m_listings); if (!m_library->deref()) { s_handles.remove(m_library->path); delete m_library; @@ -128,14 +130,10 @@ void LibraryModel::loadDirectory(const QString& path) { } bool LibraryModel::entryAt(int row, mLibraryEntry* out) const { - mLibraryListing entries; - mLibraryListingInit(&entries, 0); - if (!mLibraryGetEntries(m_library->library, &entries, 1, row, &m_constraints)) { - mLibraryListingDeinit(&entries); + if (mLibraryListingSize(&m_listings) <= row) { return false; } - *out = *mLibraryListingGetPointer(&entries, 0); - mLibraryListingDeinit(&entries); + *out = *mLibraryListingGetConstPointer(&m_listings, row); return true; } @@ -234,10 +232,12 @@ void LibraryModel::attachGameDB(const NoIntroDB* gameDB) { } void LibraryModel::constrainBase(const QString& path) { + clearConstraints(); if (m_constraints.base) { free(const_cast(m_constraints.base)); } m_constraints.base = strdup(path.toUtf8().constData()); + reload(); } void LibraryModel::clearConstraints() { @@ -251,6 +251,15 @@ void LibraryModel::clearConstraints() { free(const_cast(m_constraints.title)); } memset(&m_constraints, 0, sizeof(m_constraints)); + size_t i; + for (i = 0; i < mLibraryListingSize(&m_listings); ++i) { + mLibraryEntryFree(mLibraryListingGetPointer(&m_listings, i)); + } + mLibraryListingClear(&m_listings); +} + +void LibraryModel::reload() { + mLibraryGetEntries(m_library->library, &m_listings, 0, 0, m_constraints.base ? &m_constraints : nullptr); } void LibraryModel::directoryLoaded(const QString& path) { diff --git a/src/platform/qt/LibraryModel.h b/src/platform/qt/LibraryModel.h index edfca6a56..970b08f87 100644 --- a/src/platform/qt/LibraryModel.h +++ b/src/platform/qt/LibraryModel.h @@ -52,6 +52,7 @@ public slots: void constrainBase(const QString& path); void clearConstraints(); + void reload(); private slots: void directoryLoaded(const QString& path); @@ -86,6 +87,7 @@ private: static QMap s_handles; mLibraryEntry m_constraints; + mLibraryListing m_listings; QStringList m_queue; QList m_columns; diff --git a/src/platform/qt/LibraryView.cpp b/src/platform/qt/LibraryView.cpp index 2fa050abc..44b447e0a 100644 --- a/src/platform/qt/LibraryView.cpp +++ b/src/platform/qt/LibraryView.cpp @@ -24,6 +24,7 @@ LibraryView::LibraryView(QWidget* parent) m_ui.listing->horizontalHeader()->setSectionsMovable(true); m_ui.listing->setModel(&m_model); m_ui.listing->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + m_model.reload(); resizeColumns(); } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d54201169..ae2bcb497 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -49,6 +49,10 @@ #include #include #endif +#ifdef M_CORE_GBA +#include +#include +#endif #include "feature/commandline.h" #include "feature/sqlite3/no-intro.h" #include @@ -104,7 +108,7 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent) i = m_savedScale; } #ifdef USE_SQLITE3 - m_libraryView = new LibraryView(this); + m_libraryView = new LibraryView(); ConfigOption* showLibrary = m_config->addOption("showLibrary"); showLibrary->connect([this](const QVariant& value) { if (value.toBool()) { @@ -210,6 +214,10 @@ Window::~Window() { #ifdef USE_MAGICK delete m_gifView; #endif + +#ifdef USE_SQLITE3 + delete m_libraryView; +#endif } void Window::argumentsPassed(mArguments* args) { diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 14a377f57..f4b4c37b9 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -24,6 +24,8 @@ if (NOT SDL2_FOUND AND NOT SDL_FOUND) return() endif() +add_definitions(-DBUILD_SDL) + find_feature(USE_PIXMAN "pixman-1") if(USE_PIXMAN) add_definitions(-DUSE_PIXMAN) diff --git a/src/util/vfs/vfs-fd.c b/src/util/vfs/vfs-fd.c index 39b2164ee..2b301703d 100644 --- a/src/util/vfs/vfs-fd.c +++ b/src/util/vfs/vfs-fd.c @@ -53,7 +53,7 @@ struct VFile* VFileFromFD(int fd) { } struct stat stat; - if (fstat(fd, &stat) < 0 || S_ISDIR(stat.st_mode)) { + if (fstat(fd, &stat) < 0 || (stat.st_mode & S_IFDIR)) { close(fd); return 0; }