323 lines
7.2 KiB
C++
323 lines
7.2 KiB
C++
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#pragma once
|
|
|
|
#include <QByteArray>
|
|
#include <QFile>
|
|
#include <QList>
|
|
#include <QMutex>
|
|
#include <QObject>
|
|
#include <QSize>
|
|
|
|
#include "VFileDevice.h"
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
#include <mgba/core/core.h>
|
|
#include <mgba/core/interface.h>
|
|
#include <mgba/core/thread.h>
|
|
#include <mgba/core/cache-set.h>
|
|
|
|
#ifdef M_CORE_GB
|
|
#include <mgba/internal/gb/sio/printer.h>
|
|
#endif
|
|
#ifdef M_CORE_GBA
|
|
#include <mgba/internal/gba/sio/dolphin.h>
|
|
#endif
|
|
|
|
#ifdef M_CORE_GBA
|
|
#include <mgba/gba/interface.h>
|
|
#endif
|
|
|
|
struct mCore;
|
|
|
|
namespace QGBA {
|
|
|
|
class ConfigController;
|
|
class InputController;
|
|
class LogController;
|
|
class MultiplayerController;
|
|
class Override;
|
|
|
|
class CoreController : public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
static const bool VIDEO_SYNC = false;
|
|
static const bool AUDIO_SYNC = true;
|
|
|
|
enum class Feature {
|
|
OPENGL = mCORE_FEATURE_OPENGL,
|
|
};
|
|
|
|
class Interrupter {
|
|
public:
|
|
Interrupter();
|
|
Interrupter(CoreController*);
|
|
Interrupter(std::shared_ptr<CoreController>);
|
|
Interrupter(const Interrupter&);
|
|
~Interrupter();
|
|
|
|
Interrupter& operator=(const Interrupter&);
|
|
|
|
void interrupt(CoreController*);
|
|
void interrupt(std::shared_ptr<CoreController>);
|
|
void resume();
|
|
|
|
private:
|
|
void interrupt();
|
|
void resume(CoreController*);
|
|
|
|
CoreController* m_parent;
|
|
};
|
|
|
|
CoreController(mCore* core, QObject* parent = nullptr);
|
|
~CoreController();
|
|
|
|
mCoreThread* thread() { return &m_threadContext; }
|
|
|
|
const color_t* drawContext();
|
|
QImage getPixels();
|
|
|
|
bool isPaused();
|
|
bool hasStarted();
|
|
|
|
QString title() { return m_dbTitle.isNull() ? m_internalTitle : m_dbTitle; }
|
|
QString intenralTitle() { return m_internalTitle; }
|
|
QString dbTitle() { return m_dbTitle; }
|
|
|
|
mPlatform platform() const;
|
|
QSize screenDimensions() const;
|
|
bool supportsFeature(Feature feature) const { return m_threadContext.core->supportsFeature(m_threadContext.core, static_cast<mCoreFeature>(feature)); }
|
|
bool hardwareAccelerated() const { return m_hwaccel; }
|
|
|
|
void loadConfig(ConfigController*);
|
|
|
|
mCheatDevice* cheatDevice() { return m_threadContext.core->cheatDevice(m_threadContext.core); }
|
|
|
|
#ifdef USE_DEBUGGERS
|
|
mDebugger* debugger() { return m_threadContext.core->debugger; }
|
|
void setDebugger(mDebugger*);
|
|
#endif
|
|
|
|
void setMultiplayerController(MultiplayerController*);
|
|
void clearMultiplayerController();
|
|
MultiplayerController* multiplayerController() { return m_multiplayer; }
|
|
|
|
#ifdef M_CORE_GBA
|
|
bool isDolphinConnected() const { return !SOCKET_FAILED(m_dolphin.data); }
|
|
#endif
|
|
|
|
mCacheSet* graphicCaches();
|
|
int stateSlot() const { return m_stateSlot; }
|
|
|
|
void setOverride(std::unique_ptr<Override> override);
|
|
Override* override() { return m_override.get(); }
|
|
|
|
void setInputController(InputController*);
|
|
void setLogger(LogController*);
|
|
|
|
bool audioSync() const { return m_audioSync; }
|
|
bool videoSync() const { return m_videoSync; }
|
|
|
|
void addFrameAction(std::function<void ()> callback);
|
|
uint64_t frameCounter() const { return m_frameCounter; }
|
|
|
|
public slots:
|
|
void start();
|
|
void stop();
|
|
void reset();
|
|
void setPaused(bool paused);
|
|
void frameAdvance();
|
|
void setSync(bool enable);
|
|
void showResetInfo(bool enable);
|
|
|
|
void setRewinding(bool);
|
|
void rewind(int count = 0);
|
|
|
|
void setFastForward(bool);
|
|
void forceFastForward(bool);
|
|
|
|
void changePlayer(int id);
|
|
|
|
void overrideMute(bool);
|
|
|
|
void loadState(int slot = 0);
|
|
void loadState(const QString& path, int flags = -1);
|
|
void loadState(QIODevice* iodev, int flags = -1);
|
|
void saveState(int slot = 0);
|
|
void saveState(const QString& path, int flags = -1);
|
|
void saveState(QIODevice* iodev, int flags = -1);
|
|
void loadBackupState();
|
|
void saveBackupState();
|
|
|
|
void loadSave(const QString&, bool temporary);
|
|
void loadSave(VFile*, bool temporary);
|
|
void loadPatch(const QString&);
|
|
void scanCard(const QString&);
|
|
void scanCards(const QStringList&);
|
|
void replaceGame(const QString&);
|
|
void yankPak();
|
|
|
|
void addKey(int key);
|
|
void clearKey(int key);
|
|
void setAutofire(int key, bool enable);
|
|
|
|
#ifdef USE_PNG
|
|
void screenshot();
|
|
#endif
|
|
|
|
void setRealTime();
|
|
void setFixedTime(const QDateTime& time);
|
|
void setFakeEpoch(const QDateTime& time);
|
|
|
|
void importSharkport(const QString& path);
|
|
void exportSharkport(const QString& path);
|
|
|
|
#ifdef M_CORE_GB
|
|
void attachPrinter();
|
|
void detachPrinter();
|
|
void endPrint();
|
|
#endif
|
|
|
|
#ifdef M_CORE_GBA
|
|
void attachBattleChipGate();
|
|
void detachBattleChipGate();
|
|
void setBattleChipId(uint16_t id);
|
|
void setBattleChipFlavor(int flavor);
|
|
|
|
bool attachDolphin(const Address& address);
|
|
void detachDolphin();
|
|
#endif
|
|
|
|
void setAVStream(mAVStream*);
|
|
void clearAVStream();
|
|
|
|
void clearOverride();
|
|
|
|
void startVideoLog(const QString& path, bool compression = true);
|
|
void startVideoLog(VFile* vf, bool compression = true);
|
|
void endVideoLog(bool closeVf = true);
|
|
|
|
void setFramebufferHandle(int fb);
|
|
|
|
signals:
|
|
void started();
|
|
void paused();
|
|
void unpaused();
|
|
void stopping();
|
|
void crashed(const QString& errorMessage);
|
|
void failed();
|
|
void frameAvailable();
|
|
void didReset();
|
|
void stateLoaded();
|
|
void rewound();
|
|
|
|
void rewindChanged(bool);
|
|
void fastForwardChanged(bool);
|
|
|
|
void unimplementedBiosCall(int);
|
|
void statusPosted(const QString& message);
|
|
void logPosted(int level, int category, const QString& log);
|
|
|
|
void imagePrinted(const QImage&);
|
|
|
|
private:
|
|
void updateKeys();
|
|
int updateAutofire();
|
|
void finishFrame();
|
|
|
|
void updatePlayerSave();
|
|
|
|
void updateFastForward();
|
|
|
|
void updateROMInfo();
|
|
|
|
mCoreThread m_threadContext{};
|
|
|
|
bool m_patched = false;
|
|
bool m_preload = false;
|
|
|
|
uint32_t m_crc32;
|
|
QString m_internalTitle;
|
|
QString m_dbTitle;
|
|
bool m_showResetInfo = false;
|
|
|
|
QByteArray m_activeBuffer;
|
|
QByteArray m_completeBuffer;
|
|
bool m_hwaccel = false;
|
|
|
|
std::unique_ptr<mCacheSet> m_cacheSet;
|
|
std::unique_ptr<Override> m_override;
|
|
|
|
uint64_t m_frameCounter;
|
|
QList<std::function<void()>> m_resetActions;
|
|
QList<std::function<void()>> m_frameActions;
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
QRecursiveMutex m_actionMutex;
|
|
#else
|
|
QMutex m_actionMutex{QMutex::Recursive};
|
|
#endif
|
|
int m_moreFrames = -1;
|
|
QMutex m_bufferMutex;
|
|
|
|
int m_activeKeys = 0;
|
|
int m_removedKeys = 0;
|
|
bool m_autofire[32] = {};
|
|
int m_autofireStatus[32] = {};
|
|
int m_autofireThreshold = 1;
|
|
|
|
VFileDevice m_backupLoadState;
|
|
QByteArray m_backupSaveState{nullptr};
|
|
int m_stateSlot = 1;
|
|
QString m_statePath;
|
|
VFile* m_stateVf;
|
|
int m_loadStateFlags;
|
|
int m_saveStateFlags;
|
|
|
|
bool m_audioSync = AUDIO_SYNC;
|
|
bool m_videoSync = VIDEO_SYNC;
|
|
|
|
bool m_autosave;
|
|
bool m_autoload;
|
|
int m_autosaveCounter = 0;
|
|
|
|
int m_fastForward = false;
|
|
int m_fastForwardForced = false;
|
|
int m_fastForwardVolume = -1;
|
|
int m_fastForwardMute = -1;
|
|
float m_fastForwardRatio = -1.f;
|
|
float m_fastForwardHeldRatio = -1.f;
|
|
float m_fpsTarget;
|
|
|
|
bool m_mute;
|
|
|
|
InputController* m_inputController = nullptr;
|
|
LogController* m_log = nullptr;
|
|
MultiplayerController* m_multiplayer = nullptr;
|
|
#ifdef M_CORE_GBA
|
|
GBASIODolphin m_dolphin;
|
|
#endif
|
|
|
|
mVideoLogContext* m_vl = nullptr;
|
|
VFile* m_vlVf = nullptr;
|
|
|
|
#ifdef M_CORE_GB
|
|
struct QGBPrinter {
|
|
GBPrinter d;
|
|
CoreController* parent;
|
|
} m_printer;
|
|
#endif
|
|
|
|
#ifdef M_CORE_GBA
|
|
GBASIOBattlechipGate m_battlechip;
|
|
QByteArray m_eReaderData;
|
|
#endif
|
|
};
|
|
|
|
}
|