Merge branch 'master' (early part) into medusa

This commit is contained in:
Vicki Pfau 2019-06-28 15:48:27 -07:00
commit a6ce525da1
12 changed files with 123 additions and 42 deletions

View File

@ -10,7 +10,7 @@ Up-to-date news and downloads can be found at [mgba.io](https://mgba.io/).
Features
--------
- Near full Game Boy Advance hardware support[<sup>[1]</sup>](#missing).
- Highly accurate Game Boy Advance hardware support[<sup>[1]</sup>](#missing).
- Partial DS hardware support[<sup>[1]</sup>](#missing).
- Game Boy/Game Boy Color hardware support.
- Fast emulation for Game Boy and Game Boy Advance. Known to run at full speed even on low end hardware, such as netbooks[<sup>[2]</sup>](#dscaveat).
@ -19,6 +19,7 @@ Features
- Save type detection, even for flash memory size[<sup>[3]</sup>](#flashdetect).
- Support for cartridges with motion sensors and rumble (only usable with game controllers)[<sup>[2]</sup>](#dscaveat).
- Real-time clock support, even without configuration.
- Solar sensor support for Boktai games.
- Game Boy Camera and Game Boy Printer support.
- A built-in GBA BIOS implementation, and ability to load external BIOS files. DS currently requires BIOS and firmware dumps[<sup>[2]</sup>](#dscaveat).
- Turbo/fast-forward support by holding Tab.
@ -37,6 +38,31 @@ Features
- Cores available for RetroArch/Libretro and OpenEmu.
- Many, many smaller things.
#### Game Boy mappers
The following mappers are fully supported:
- MBC1
- MBC1M
- MBC2
- MBC3
- MBC3+RTC
- MBC5
- MBC5+Rumble
- MBC7
The following mappers are partially supported:
- Pocket Cam
- TAMA5
- HuC-3
The following mappers are not currently supported:
- MBC6
- HuC-1
- MMM01
### Planned features
- Networked multiplayer link cable support.
@ -128,11 +154,11 @@ To build on Windows for development, using MSYS2 is recommended. Follow the inst
For x86 (32 bit) builds:
pacman -Sy mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libzip,pkg-config,qt5,SDL2,ntldd-git}
pacman -Sy mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
For x86_64 (64 bit) builds:
pacman -Sy mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libzip,pkg-config,qt5,SDL2,ntldd-git}
pacman -Sy mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
Check out the source code by running this command:

View File

@ -10,7 +10,7 @@ Aktuelle Neuigkeiten und Downloads findest Du auf [mgba.io](https://mgba.io).
Features
--------
- Nahzu vollständige Unterstützung der Game Boy Advance-Hardware[<sup>[1]</sup>](#missing).
- Sehr genaue Unterstützung der Game Boy Advance-Hardware[<sup>[1]</sup>](#missing).
- Unterstützung der Game Boy-/Game Boy Color-Hardware.
- Schnelle Emulation. mGBA ist dafür bekannt, auch auf schwacher Hardware wie Netbooks mit voller Geschwindigkeit zu laufen.
- Qt- und SDL-Portierungen für eine vollwertige und eine "leichtgewichtige" Benutzeroberfläche.
@ -18,6 +18,7 @@ Features
- Erkennung des Speichertypes, einschließlich der Größe des Flash-Speichers[<sup>[2]</sup>](#flashdetect).
- Unterstützung für Spielmodule mit Bewegungssensoren und Rüttel-Effekten (nur verwendbar mit Spiele-Controllern).
- Unterstützung für Echtzeituhren, selbst ohne Konfiguration.
- Unterstützung für den Lichtsensor in Boktai-Spielen
- Unterstützung für Game Boy Printer und Game Boy Camera.
- Eingebaute BIOS-Implementierung mit der Möglichkeit, externe BIOS-Dateien zu laden.
- Turbo/Vorlauf-Unterstützung durch drücken der Tab-Taste.
@ -36,6 +37,31 @@ Features
- Verfügbare Cores für RetroArch/Libretro und OpenEmu.
- Viele, viele kleinere Dinge.
### Game Boy-Mapper
Die folgenden Mapper werden vollständig unterstützt:
- MBC1
- MBC1M
- MBC2
- MBC3
- MBC3+RTC (MBC3+Echtzeituhr)
- MBC5
- MBC5+Rumble (MBC5+Rüttel-Modul)
- MBC7
Die folgenden Mapper werden teilweise unterstützt:
- Pocket Cam
- TAMA5
- HuC-3
Die folgenden Mapper werden derzeit nicht unterstützt:
- MBC6
- HuC-1
- MMM01
### Geplante Features
- Unterstützung für Link-Kabel-Multiplayer über ein Netzwerk.
@ -110,11 +136,11 @@ Um mGBA auf Windows zu kompilieren, wird MSYS2 empfohlen. Befolge die Installati
Für x86 (32 Bit):
pacman -Sy mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libzip,pkg-config,qt5,SDL2,ntldd-git}
pacman -Sy mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
Für x86_64 (64 Bit):
pacman -Sy mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libzip,pkg-config,qt5,SDL2,ntldd-git}
pacman -Sy mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
Lade den aktuellen mGBA-Quellcode mithilfe des folgenden Kommandos herunter:

View File

@ -203,8 +203,10 @@ void* mCoreGetMemoryBlock(struct mCore* core, uint32_t start, size_t* size);
#ifdef USE_ELF
struct ELF;
bool mCoreLoadELF(struct mCore* core, struct ELF* elf);
#ifdef USE_DEBUGGERS
void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF*);
#endif
#endif
CXX_GUARD_END

View File

@ -357,6 +357,7 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) {
return true;
}
#ifdef USE_DEBUGGERS
void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF* elf) {
size_t symIndex = ELFFindSection(elf, ".symtab");
size_t names = ELFFindSection(elf, ".strtab");
@ -376,5 +377,5 @@ void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF* elf) {
mDebuggerSymbolAdd(symbols, name, syms[i].st_value, -1);
}
}
#endif
#endif

View File

@ -612,6 +612,7 @@ void GBDetectModel(struct GB* gb) {
void GBUpdateIRQs(struct GB* gb) {
int irqs = gb->memory.ie & gb->memory.io[REG_IF];
if (!irqs) {
gb->cpu->irqPending = false;
return;
}
gb->cpu->halted = false;

View File

@ -738,7 +738,9 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) {
}
struct ELF* elf = ELFOpen(vf);
if (elf) {
#ifdef USE_DEBUGGERS
mCoreLoadELFSymbols(core->symbolTable, elf);
#endif
ELFClose(elf);
}
if (closeAfter) {

View File

@ -1629,7 +1629,7 @@ void _pristineCow(struct GBA* gba) {
if (!gba->isPristine) {
return;
}
#ifndef FIXED_ROM_BUFFER
#if !defined(FIXED_ROM_BUFFER) && !defined(__wii__)
void* newRom = anonymousMemoryMap(SIZE_CART0);
memcpy(newRom, gba->memory.rom, gba->memory.romSize);
memset(((uint8_t*) newRom) + gba->memory.romSize, 0xFF, SIZE_CART0 - gba->memory.romSize);

View File

@ -76,6 +76,16 @@ static void _reloadSettings(void) {
opts.skipBios = strcmp(var.value, "ON") == 0;
}
var.key = "mgba_sgb_borders";
var.value = 0;
if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
if (strcmp(var.value, "ON") == 0) {
mCoreConfigSetDefaultIntValue(&core->config, "sgb.borders", true);
} else {
mCoreConfigSetDefaultIntValue(&core->config, "sgb.borders", false);
}
}
var.key = "mgba_idle_optimization";
var.value = 0;
if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
@ -111,6 +121,7 @@ void retro_set_environment(retro_environment_t env) {
{ "mgba_allow_opposing_directions", "Allow opposing directional input; OFF|ON" },
{ "mgba_use_bios", "Use BIOS file if found (requires restart); ON|OFF" },
{ "mgba_skip_bios", "Skip BIOS intro (requires restart); OFF|ON" },
{ "mgba_sgb_borders", "Use Super Game Boy borders (requires restart); ON|OFF" },
{ "mgba_idle_optimization", "Idle loop removal; Remove Known|Detect and Remove|Don't Remove" },
{ "mgba_frameskip", "Frameskip; 0|1|2|3|4|5|6|7|8|9|10" },
{ 0, 0 }

View File

@ -83,10 +83,12 @@ bool mPythonScriptEngineLoadScript(struct mScriptEngine* se, const char* name, s
void mPythonScriptEngineRun(struct mScriptEngine* se) {
struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
#ifdef USE_DEBUGGERS
struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb);
if (debugger) {
mPythonSetDebugger(debugger);
}
#endif
mPythonRunPending();
}

View File

@ -8,12 +8,6 @@
#include "DisplayGL.h"
#include "DisplayQt.h"
#ifdef M_CORE_GB
#include <mgba/internal/gb/video.h>
#elif defined(M_CORE_GBA)
#include <mgba/internal/gba/video.h>
#endif
using namespace QGBA;
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
@ -55,11 +49,6 @@ Display::Display(QWidget* parent)
: QWidget(parent)
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
#ifdef M_CORE_GB
setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
#elif defined(M_CORE_GBA)
setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#endif
connect(&m_mouseTimer, &QTimer::timeout, this, &Display::hideCursor);
m_mouseTimer.setSingleShot(true);
m_mouseTimer.setInterval(MOUSE_DISAPPEAR_TIMER);

View File

@ -458,7 +458,9 @@ void Window::openSettingsWindow() {
connect(settingsWindow, &SettingsView::cameraDriverChanged, this, &Window::mustRestart);
connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart);
connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig);
#ifdef USE_SQLITE3
connect(settingsWindow, &SettingsView::libraryCleared, m_libraryView, &LibraryController::clear);
#endif
openView(settingsWindow);
}
@ -723,8 +725,6 @@ void Window::gameStarted() {
multiplayerChanged();
updateTitle();
QSize size = m_controller->screenDimensions();
m_display->setMinimumSize(size);
m_screenWidget->setMinimumSize(m_display->minimumSize());
m_screenWidget->setDimensions(size.width(), size.height());
m_config->updateOption("lockIntegerScaling");
m_config->updateOption("lockAspectRatio");
@ -733,6 +733,7 @@ void Window::gameStarted() {
}
attachWidget(m_display.get());
setMouseTracking(true);
m_display->setMinimumSize(size);
#ifndef Q_OS_MAC
if (isFullScreen()) {
@ -805,7 +806,6 @@ void Window::gameStopped() {
#elif defined(M_CORE_GBA)
m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#endif
m_screenWidget->setMinimumSize(m_display->minimumSize());
setMouseTracking(false);
m_videoLayers->clear();
@ -858,8 +858,7 @@ void Window::reloadDisplayDriver() {
m_shaderView.reset();
m_shaderView = std::make_unique<ShaderSelector>(m_display.get(), m_config);
#endif
m_screenWidget->setMinimumSize(m_display->minimumSize());
m_screenWidget->setSizePolicy(m_display->sizePolicy());
connect(this, &Window::shutdown, m_display.get(), &Display::stopDrawing);
connect(m_display.get(), &Display::hideCursor, [this]() {
if (static_cast<QStackedLayout*>(m_screenWidget->layout())->currentWidget() == m_display.get()) {
@ -885,6 +884,7 @@ void Window::reloadDisplayDriver() {
#endif
if (m_controller) {
m_display->setMinimumSize(m_controller->screenDimensions());
connect(m_controller.get(), &CoreController::stopping, m_display.get(), &Display::stopDrawing);
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw);
connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw);
@ -895,6 +895,12 @@ void Window::reloadDisplayDriver() {
attachWidget(m_display.get());
m_display->startDrawing(m_controller);
} else {
#ifdef M_CORE_GB
m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
#elif defined(M_CORE_GBA)
m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#endif
}
}
@ -1018,6 +1024,7 @@ void Window::openStateWindow(LoadSave ls) {
}
m_stateWindow->setAttribute(Qt::WA_DeleteOnClose);
m_stateWindow->setMode(ls);
updateFrame();
attachWidget(m_stateWindow);
}
@ -1757,6 +1764,16 @@ void Window::focusCheck() {
}
}
void Window::updateFrame() {
QSize size = m_controller->screenDimensions();
QImage currentImage(reinterpret_cast<const uchar*>(m_controller->drawContext()), size.width(), size.height(),
size.width() * BYTES_PER_PIXEL, QImage::Format_RGBX8888);
QPixmap pixmap;
pixmap.convertFromImage(currentImage);
m_screenWidget->setPixmap(pixmap);
emit paused(true);
}
void Window::setController(CoreController* controller, const QString& fname) {
if (!controller) {
return;
@ -1793,15 +1810,7 @@ void Window::setController(CoreController* controller, const QString& fname) {
});
}
connect(m_controller.get(), &CoreController::stopping, &m_inputController, &InputController::resumeScreensaver);
connect(m_controller.get(), &CoreController::paused, [this]() {
QSize size = m_controller->screenDimensions();
QImage currentImage(reinterpret_cast<const uchar*>(m_controller->drawContext()), size.width(), size.height(),
size.width() * BYTES_PER_PIXEL, QImage::Format_RGBX8888);
QPixmap pixmap;
pixmap.convertFromImage(currentImage);
m_screenWidget->setPixmap(pixmap);
emit paused(true);
});
connect(m_controller.get(), &CoreController::paused, this, &Window::updateFrame);
#ifndef Q_OS_MAC
connect(m_controller.get(), &CoreController::paused, menuBar(), &QWidget::show);
@ -1831,13 +1840,17 @@ void Window::setController(CoreController* controller, const QString& fname) {
connect(m_controller.get(), &CoreController::failed, this, &Window::gameFailed);
connect(m_controller.get(), &CoreController::unimplementedBiosCall, this, &Window::unimplementedBiosCall);
#ifdef USE_GDB_STUB
if (m_gdbController) {
m_gdbController->setController(m_controller);
}
#endif
#ifdef USE_DEBUGGERS
if (m_console) {
m_console->setController(m_controller);
}
#endif
#ifdef USE_MAGICK
if (m_gifView) {
@ -1869,11 +1882,15 @@ void Window::setController(CoreController* controller, const QString& fname) {
}
WindowBackground::WindowBackground(QWidget* parent)
: QLabel(parent)
: QWidget(parent)
{
setLayout(new QStackedLayout());
layout()->setContentsMargins(0, 0, 0, 0);
setAlignment(Qt::AlignCenter);
}
void WindowBackground::setPixmap(const QPixmap& pmap) {
m_pixmap = pmap;
update();
}
void WindowBackground::setSizeHint(const QSize& hint) {
@ -1904,11 +1921,9 @@ void WindowBackground::setLockAspectRatio(bool lock) {
m_lockAspectRatio = lock;
}
void WindowBackground::paintEvent(QPaintEvent*) {
const QPixmap* logo = pixmap();
if (!logo) {
return;
}
void WindowBackground::paintEvent(QPaintEvent* event) {
QWidget::paintEvent(event);
const QPixmap& logo = pixmap();
QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.fillRect(QRect(QPoint(), size()), Qt::black);
@ -1933,5 +1948,5 @@ void WindowBackground::paintEvent(QPaintEvent*) {
}
QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2);
QRect full(origin, ds);
painter.drawPixmap(full, *logo);
painter.drawPixmap(full, logo);
}

View File

@ -133,6 +133,8 @@ private slots:
void showFPS();
void focusCheck();
void updateFrame();
private:
static const int FPS_TIMER_INTERVAL = 2000;
static const int FRAME_LIST_SIZE = 120;
@ -218,12 +220,13 @@ private:
#endif
};
class WindowBackground : public QLabel {
class WindowBackground : public QWidget {
Q_OBJECT
public:
WindowBackground(QWidget* parent = 0);
void setPixmap(const QPixmap& pixmap);
void setSizeHint(const QSize& size);
virtual QSize sizeHint() const override;
void setDimensions(int width, int height);
@ -231,10 +234,13 @@ public:
void setLockIntegerScaling(bool lock);
void setLockAspectRatio(bool lock);
const QPixmap& pixmap() const { return m_pixmap; }
protected:
virtual void paintEvent(QPaintEvent*) override;
private:
QPixmap m_pixmap;
QSize m_sizeHint;
bool m_centered;
int m_aspectWidth;