diff --git a/CHANGES b/CHANGES index e80077b62..d45a92a76 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -0.3.0: (Future) +0.3.0: (2015-08-16) Features: - Ability to hide individual background layers, or OBJs - Ability to mute individual audio channels @@ -34,96 +34,98 @@ Features: - Configurable audio output sample rate Bugfixes: - ARM7: Fix SWI and IRQ timings - - GBA Audio: Force audio FIFOs to 32-bit - - GBA Memory: Improve Thumb open bus behavior - - VFS: Fix resource leaks if some allocations fail - - Video: Fix an issue with very long filenames - - GBA Video: Blended sprites should never have other effects applied - - GBA: Fix crash if a 512kb flash save is loaded when a game has a 1Mb flash override - - Qt: Better cleanup when a game crashes - - Qt: Fix open ROM dialog filtering for archive formats - ARM7: Fix Thumb MUL timing - - Qt: Cap the maximum number of multiplayer windows - - Qt: Fix maximum year in sensor override + - ARM7: Fix timing of multiplies to use N cycles + - ARM7: ARMHotplugDetach should call deinit + - Debugger: Fix use-after-free in breakpoint clearing code + - GBA: Fix crash if a 512kb flash save is loaded when a game has a 1Mb flash override - GBA: Cap audio FIFO read size during deserialization - GBA: Check for corrupted savestates when loading - GBA: Check for improperly sized savestates when loading - GBA: Check for savestates made from differently sized ROMs - - GBA Video: Fix out-of-bounds tiles in mosaic - - GBA Memory: Fix potential DMA issue when loading a savestate - - GBA Audio: Fix audio pitch changing when adjusting buffer size - - SDL: Fix SDL build when OpenGL is missing - - ARM7: Fix timing of multiplies to use N cycles - GBA: Fix calls to endian-independent loadstores - - GBA Video: Fix windows not affecting sprites - - VFS: Fix line-reading to return proper values - - GBA Memory: Fix load/store multiple video memory waitstates - GBA: Fix timing of reading from timer registers - - Util: Allow loading IPS patches that grow the ROM + - GBA: Ensure cycles never go negative + - GBA Audio: Force audio FIFOs to 32-bit + - GBA Audio: Fix audio pitch changing when adjusting buffer size - GBA Audio: Fix sample order in audio channel 3 - GBA Audio: Fix 8-bit writes to audio channel 3 frequency - - ARM7: ARMHotplugDetach should call deinit + - GBA Cheats: Fix Pro Action Replay and GameShark issues when used together + - GBA Memory: Improve Thumb open bus behavior + - GBA Memory: Fix potential DMA issue when loading a savestate + - GBA Memory: Fix load/store multiple video memory waitstates + - GBA SIO: Fix reseting when there are SIO devices attached + - GBA Video: Blended sprites should never have other effects applied + - GBA Video: Fix out-of-bounds tiles in mosaic + - GBA Video: Fix windows not affecting sprites + - GBA Video: Prevent tiles < 512 from being used in modes 3 - 5 + - GBA Video: Fix timing on first scanline + - Qt: Better cleanup when a game crashes + - Qt: Fix open ROM dialog filtering for archive formats + - Qt: Cap the maximum number of multiplayer windows + - Qt: Fix maximum year in sensor override - Qt: Fix window being too tall after exiting fullscreen - Qt: Fix a missing va_end call in the log handler lambda within the GameController constructor - - GBA Cheats: Fix Pro Action Replay and GameShark issues when used together - Qt: Fix analog buttons not getting unmapped - - GBA Video: Prevent tiles < 512 from being used in modes 3 - 5 - Qt: Fix passing command line options - Qt: Fix crashes on Windows by using using QMetaObject to do cross-thread calls - - GBA Video: Fix timing on first scanline - - GBA: Ensure cycles never go negative + - SDL: Fix SDL build when OpenGL is missing + - Util: Allow loading IPS patches that grow the ROM + - VFS: Fix resource leaks if some allocations fail + - VFS: Fix line-reading to return proper values + - Video: Fix an issue with very long filenames - Util: Fix formatting of floats Misc: - - Qt: Handle saving input settings better - - Debugger: Free watchpoints in addition to breakpoints - - Qt: Move GL frame drawing back onto its own thread - - GBA: Add status log level - - GBA Thread: Add functionality for running callbacks on the GBA thread - - Qt: Fast forward (held) option moved from Other to Emulation menu - All: Add --help flag for command line programs - - Qt: Show version info in window title - All: Fix sanitize-deb script to set file permissions properly if run as (fake)root - - GBA SIO: Add a dummy driver for Normal mode - - GBA: GBARewind now returns how many states it has rewound - All: Enable static linking for Windows - All: Enable static linking for OS X + - All: Threads are now named + - All: Proper handling of Unicode file paths + - ARM7: Add emulation for Undefined CPU mode + - ARM7: Reduce the size of the Thumb instruction table + - GBA: Add status log level + - GBA: GBARewind now returns how many states it has rewound + - GBA: SIO logging layer + - GBA BIOS: Stub out SoundBias + - GBA: More accurate cycle estimation for ROM prefetch and flash save chips + - GBA: Don't include GBACLIDebugger struct unless needed + - GBA: Savedata is now synced shortly after data finishes being written + - GBA: Process multiple timer events at once, if necessary + - GBA Audio: Implement audio reset for channels A/B + - GBA Audio: Process multiple audio events at once, if necessary + - GBA Hardware: Backport generic RTC source into core + - GBA Input: Allow axes and buttons to be mapped to the same key + - GBA Memory: Run multiple DMAs in a tight loop if they all occur before present + - GBA SIO: Add a dummy driver for Normal mode + - GBA Thread: Add functionality for running callbacks on the GBA thread + - GBA Thread: Split GBASync into a separate file + - GBA Video: Refactor software renderer into separate files + - GBA Video: Slightly optimize mode 0 mosaic rendering + - Debugger: Free watchpoints in addition to breakpoints + - Qt: Handle saving input settings better + - Qt: Move GL frame drawing back onto its own thread + - Qt: Fast forward (held) option moved from Other to Emulation menu + - Qt: Show version info in window title - Qt: Migrate multiplayer window handling into GBAApp - Qt: Unified file opening and saving with last location - Qt: Fix windows being resizable when they shouldn't have been - Qt: Only hide cursor in full screen - - Perf: Ability to load savestates immediately on launch - Qt: Replace pause-after-frame mutex with an atomic - - Util: Allow disabling the threading code entirely - - GBA: SIO logging layer - Qt: Add application icon and XDG desktop files - - GBA Thread: Split GBASync into a separate file - - SDL: Properly check for initialization - - SDL: Clean up initialization functions - - All: Threads are now named - Qt: Rename "Fullscreen" to "Toggle fullscreen" - Qt: Don't save window size when entering fullscreen - Qt: Make the default fullscreen binding for Windows be Alt-Enter - - GBA Video: Refactor software renderer into separate files - - ARM7: Add emulation for Undefined CPU mode - - GBA: More accurate cycle estimation for ROM prefetch and flash save chips - - ARM7: Reduce the size of the Thumb instruction table - - GBA: Don't include GBACLIDebugger struct unless needed - - SDL: Clean up GL context - - GBA Audio: Implement audio reset for channels A/B - - GBA Hardware: Backport generic RTC source into core - - All: Proper handling of Unicode file paths - - GBA Video: Slightly optimize mode 0 mosaic rendering - - VFS: Add sync method to force syncing with backing - - GBA: Savedata is now synced shortly after data finishes being written - - GBA Input: Allow axes and buttons to be mapped to the same key - - GBA BIOS: Stub out SoundBias - Qt: Gamepads can now have both buttons and analog axes mapped to the same key - Qt: Increase usability of key mapper - Qt: Show checkmark for window sizes - Qt: Set window path to loaded ROM - - GBA Memory: Run multiple DMAs in a tight loop if they all occur before present - - GBA Audio: Process multiple audio events at once, if necessary - - GBA: Process multiple timer events at once, if necessary + - Perf: Ability to load savestates immediately on launch + - SDL: Properly check for initialization + - SDL: Clean up initialization functions + - SDL: Clean up GL context + - Util: Allow disabling the threading code entirely + - VFS: Add sync method to force syncing with backing 0.2.1: (2015-05-13) Bugfixes: diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index f886db969..62d47680b 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -155,6 +155,7 @@ void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) if (breakpoint->address == address) { *previous = *next; free(breakpoint); + continue; } previous = next; } @@ -179,6 +180,7 @@ void ARMDebuggerClearWatchpoint(struct ARMDebugger* debugger, uint32_t address) if (watchpoint->address == address) { *previous = *next; free(watchpoint); + continue; } previous = next; } diff --git a/src/gba/gba.c b/src/gba/gba.c index a7356ad3a..2ae273760 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -163,8 +163,7 @@ void GBAReset(struct ARMCore* cpu) { GBAAudioReset(&gba->audio); GBAIOInit(gba); - GBASIODeinit(&gba->sio); - GBASIOInit(&gba->sio); + GBASIOReset(&gba->sio); gba->timersEnabled = 0; memset(gba->timers, 0, sizeof(gba->timers)); diff --git a/src/gba/hardware.c b/src/gba/hardware.c index 5d8d28020..2bfccbae1 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -59,10 +59,14 @@ void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) { } void GBAHardwareClear(struct GBACartridgeHardware* hw) { - hw->devices = HW_NONE; + hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION); hw->direction = GPIO_WRITE_ONLY; hw->pinState = 0; hw->direction = 0; + + if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) { + GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32); + } } void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) { diff --git a/src/gba/sio.c b/src/gba/sio.c index 49f66ff58..8d50cfb36 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -48,14 +48,11 @@ static void _switchMode(struct GBASIO* sio) { } void GBASIOInit(struct GBASIO* sio) { - sio->rcnt = RCNT_INITIAL; - sio->siocnt = 0; - sio->mode = -1; - sio->activeDriver = 0; sio->drivers.normal = 0; sio->drivers.multiplayer = 0; sio->drivers.joybus = 0; - _switchMode(sio); + sio->activeDriver = 0; + GBASIOReset(sio); } void GBASIODeinit(struct GBASIO* sio) { @@ -68,6 +65,17 @@ void GBASIODeinit(struct GBASIO* sio) { if (sio->drivers.joybus && sio->drivers.joybus->deinit) { sio->drivers.joybus->deinit(sio->drivers.joybus); } + if (sio->drivers.normal && sio->drivers.normal->deinit) { + sio->drivers.normal->deinit(sio->drivers.normal); + } +} + +void GBASIOReset(struct GBASIO* sio) { + GBASIODeinit(sio); + sio->rcnt = RCNT_INITIAL; + sio->siocnt = 0; + sio->mode = -1; + _switchMode(sio); } void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) { diff --git a/src/gba/sio.h b/src/gba/sio.h index 5963698d9..2707fb0e8 100644 --- a/src/gba/sio.h +++ b/src/gba/sio.h @@ -65,6 +65,7 @@ struct GBASIO { void GBASIOInit(struct GBASIO* sio); void GBASIODeinit(struct GBASIO* sio); +void GBASIOReset(struct GBASIO* sio); void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers); void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode); diff --git a/src/gba/supervisor/thread.c b/src/gba/supervisor/thread.c index 94eff4a61..901694462 100644 --- a/src/gba/supervisor/thread.c +++ b/src/gba/supervisor/thread.c @@ -225,7 +225,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { GBARRInitPlay(&gba); } - if (threadContext->skipBios) { + if (threadContext->skipBios && gba.memory.rom) { GBASkipBIOS(&cpu); } @@ -305,7 +305,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { MutexUnlock(&threadContext->stateMutex); if (resetScheduled) { ARMReset(&cpu); - if (threadContext->skipBios) { + if (threadContext->skipBios && gba.memory.rom) { GBASkipBIOS(&cpu); } } diff --git a/src/platform/qt/AboutScreen.cpp b/src/platform/qt/AboutScreen.cpp index ca53d334a..c898f2c16 100644 --- a/src/platform/qt/AboutScreen.cpp +++ b/src/platform/qt/AboutScreen.cpp @@ -21,6 +21,11 @@ AboutScreen::AboutScreen(QWidget* parent) logo.setDevicePixelRatio(devicePixelRatio()); m_ui.logo->setPixmap(logo); + QLatin1String tree(gitBranch); + if (tree == QLatin1String("(unknown)")) { + tree = QLatin1String(projectVersion); + } + m_ui.projectName->setText(QLatin1String(projectName)); m_ui.projectVersion->setText(QLatin1String(projectVersion)); QString gitInfo = m_ui.gitInfo->text(); @@ -31,6 +36,6 @@ AboutScreen::AboutScreen(QWidget* parent) description.replace("{projectName}", QLatin1String(projectName)); m_ui.description->setText(description); QString extraLinks = m_ui.extraLinks->text(); - extraLinks.replace("{gitBranch}", QLatin1String(gitBranch)); + extraLinks.replace("{gitBranch}", tree); m_ui.extraLinks->setText(extraLinks); } diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index dc0399273..ed9645ec9 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -57,7 +57,9 @@ GBAApp::GBAApp(int& argc, char* argv[]) return; } - AudioProcessor::setDriver(static_cast(m_configController.getQtOption("audioDriver").toInt())); + if (!m_configController.getQtOption("audioDriver").isNull()) { + AudioProcessor::setDriver(static_cast(m_configController.getQtOption("audioDriver").toInt())); + } Window* w = new Window(&m_configController); connect(w, &Window::destroyed, [this]() { m_windows[0] = nullptr; diff --git a/src/platform/qt/SensorView.cpp b/src/platform/qt/SensorView.cpp index 9a2edd6e4..d3757d0c8 100644 --- a/src/platform/qt/SensorView.cpp +++ b/src/platform/qt/SensorView.cpp @@ -61,6 +61,7 @@ SensorView::SensorView(GameController* controller, InputController* input, QWidg connect(m_ui.gyroSensitivity, static_cast(&QDoubleSpinBox::valueChanged), [this](double value) { m_input->setGyroSensitivity(value * 1e8f); }); + m_input->stealFocus(this); } void SensorView::jiggerer(QAbstractButton* button, void (InputController::*setter)(int)) { @@ -68,15 +69,26 @@ void SensorView::jiggerer(QAbstractButton* button, void (InputController::*sette if (!checked) { m_jiggered = nullptr; } else { + button->setFocus(); m_jiggered = [this, button, setter](int axis) { (m_input->*setter)(axis); button->setChecked(false); + button->clearFocus(); }; } }); button->installEventFilter(this); } +bool SensorView::event(QEvent* event) { + if (event->type() == QEvent::WindowActivate) { + m_input->stealFocus(this); + } else if (event->type() == QEvent::WindowDeactivate) { + m_input->releaseFocus(this); + } + return QWidget::event(event); +} + bool SensorView::eventFilter(QObject*, QEvent* event) { if (event->type() == GamepadAxisEvent::Type()) { GamepadAxisEvent* gae = static_cast(event); diff --git a/src/platform/qt/SensorView.h b/src/platform/qt/SensorView.h index 50c96ecf1..9313f89fb 100644 --- a/src/platform/qt/SensorView.h +++ b/src/platform/qt/SensorView.h @@ -30,6 +30,7 @@ public: protected: bool eventFilter(QObject*, QEvent* event) override; + bool event(QEvent* event); private slots: void updateSensors(); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index f60a43cd3..e3fd3d8f7 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -165,7 +165,7 @@ void SettingsView::saveSetting(const char* key, const QComboBox* field) { } void SettingsView::saveSetting(const char* key, const QDoubleSpinBox* field) { - saveSetting(key, field->cleanText()); + saveSetting(key, field->value()); } void SettingsView::saveSetting(const char* key, const QLineEdit* field) { @@ -173,14 +173,14 @@ void SettingsView::saveSetting(const char* key, const QLineEdit* field) { } void SettingsView::saveSetting(const char* key, const QSlider* field) { - saveSetting(key, QString::number(field->value())); + saveSetting(key, field->value()); } void SettingsView::saveSetting(const char* key, const QSpinBox* field) { - saveSetting(key, field->cleanText()); + saveSetting(key, field->value()); } -void SettingsView::saveSetting(const char* key, const QString& field) { +void SettingsView::saveSetting(const char* key, const QVariant& field) { m_controller->setOption(key, field); m_controller->updateOption(key); } diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index e47cda889..2a8d1302d 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -40,7 +40,7 @@ private: void saveSetting(const char* key, const QLineEdit*); void saveSetting(const char* key, const QSlider*); void saveSetting(const char* key, const QSpinBox*); - void saveSetting(const char* key, const QString&); + void saveSetting(const char* key, const QVariant&); void loadSetting(const char* key, QAbstractButton*); void loadSetting(const char* key, QComboBox*); diff --git a/version.cmake b/version.cmake index 69c41c4a7..22bc5e7b5 100644 --- a/version.cmake +++ b/version.cmake @@ -2,9 +2,9 @@ if(NOT PROJECT_NAME) set(PROJECT_NAME "mGBA") endif() set(LIB_VERSION_MAJOR 0) -set(LIB_VERSION_MINOR 3) +set(LIB_VERSION_MINOR 4) set(LIB_VERSION_PATCH 0) -set(LIB_VERSION_ABI 0.3) +set(LIB_VERSION_ABI 0.4) set(LIB_VERSION_STRING ${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}) execute_process(COMMAND git describe --always --abbrev=40 --dirty OUTPUT_VARIABLE GIT_COMMIT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)