You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

188 lines
5.6 KiB

/*
Copyright 2020-2021 Brad Parker
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __CORE_H_
#define __CORE_H_
#include <QLibrary>
#include <QImage>
#include <QElapsedTimer>
#include <QTimer>
#include <QTemporaryDir>
#include <QMap>
extern "C" {
#include "libretro.h"
}
class QAudioFormat;
class QOpenGLFramebufferObject;
class Core;
typedef void (*RetroInit)(void);
typedef void (*RetroDeinit)(void);
typedef bool (*RetroLoadGame)(const struct retro_game_info *game);
typedef void (*RetroUnloadGame)(void);
typedef void (*RetroRun)(void);
typedef void (*RetroReset)(void);
typedef void* (*RetroGetMemoryData)(unsigned id);
typedef size_t (*RetroGetMemorySize)(unsigned id);
typedef bool (*RetroSerialize)(void *data, size_t size);
typedef size_t (*RetroSerializeSize)(void);
typedef bool (*RetroUnserialize)(const void *data, size_t size);
typedef void (*RetroGetSystemAVInfo)(struct retro_system_av_info *info);
typedef void (*RetroGetSystemInfo)(struct retro_system_info *info);
typedef void (*RetroSetEnvironment)(retro_environment_t);
typedef void (*RetroSetVideoRefresh)(retro_video_refresh_t);
typedef void (*RetroSetAudioSample)(retro_audio_sample_t);
typedef void (*RetroSetAudioSampleBatch)(retro_audio_sample_batch_t);
typedef void (*RetroSetInputPoll)(retro_input_poll_t);
typedef void (*RetroSetInputState)(retro_input_state_t);
typedef void (*RetroSetControllerPortDevice)(unsigned port, unsigned device);
typedef void (*RetroHWContextReset)(void);
class Core : public QObject {
Q_OBJECT
public:
Core(QObject *parent = NULL);
~Core();
struct CoreOption {
QString key;
QString name;
QStringList values;
QString val;
QByteArray valArray;
const char *valData;
};
bool run(QString contentPath);
void reset();
bool load(QString corePath);
void unload();
bool isLoaded() const;
bool isResolved() const;
bool isRunning() const;
void setMuted(bool on);
void setPaused(bool on);
bool isMuted() const;
bool isPaused() const;
bool saveState();
bool loadState();
bool saveSRAM();
bool loadSRAM();
void setupAudio();
bool loadContentIntoMemory();
bool isHWRender();
bool supportsNoGame();
void blitFBO();
void setVariablesChanged(bool changed);
static Core* instance();
float getVideoRate();
void* getProcAddress(const char *sym);
QMap<QString, CoreOption>& getCoreOptions();
QImage* getImage();
/* callbacks used by the core, which are set with the "set" function pointers */
bool environment(unsigned cmd, void *data);
void videoRefresh(const void *data, unsigned width, unsigned height, size_t pitch);
void audioSample(int16_t left, int16_t right);
size_t audioSampleBatch(const int16_t *data, size_t frames);
void inputPoll();
int16_t inputState(unsigned port, unsigned device, unsigned index, unsigned id);
uintptr_t getCurrentFramebuffer();
signals:
void audioReady(QAudioFormat*);
void gotAudioSample(int16_t, int16_t);
void gotAudioSampleBatch(const int16_t*, size_t);
void doneRendering();
void gotFrameSwap();
void coreOptionsChanged();
void repaint();
public slots:
void onAudioStreamReady();
void onGotFrameSwap();
void render();
private:
enum retro_pixel_format m_pixFmt;
struct retro_system_info m_info;
struct retro_game_info m_gameInfo;
unsigned char *m_imgData;
unsigned m_width;
unsigned m_height;
size_t m_pitch;
bool m_isAudioStreamReady;
bool m_isMuted;
bool m_isPaused;
bool m_variablesChanged;
bool m_isHWRender;
bool m_noGame;
bool m_bottomLeftOrigin;
QImage m_img;
QMap<QString, CoreOption> m_options;
QMap<QString, unsigned> m_controllerInfo;
QLibrary m_library;
bool m_isLoaded;
bool m_isInited;
bool m_isResolved;
bool m_isRunning;
bool m_doRender;
QString m_path;
QByteArray m_pathArray;
const char *m_pathData;
QString m_extractedPath;
QByteArray m_extractedPathArray;
const char *m_extractedPathData;
char *m_saveStateData;
size_t m_saveStateDataSize;
QElapsedTimer m_elapsedTimer;
QTimer m_timer;
QTemporaryDir m_tempDir;
char *m_gameData;
int64_t m_gameDataSize;
QDir m_dataDir;
char m_savePath[4096];
char m_statePath[4096];
char m_systemPath[4096];
/* functions exported by the core that the frontend can call */
RetroInit m_retroInit;
RetroDeinit m_retroDeinit;
RetroRun m_retroRun;
RetroReset m_retroReset;
RetroLoadGame m_retroLoadGame;
RetroUnloadGame m_retroUnloadGame;
RetroGetMemoryData m_retroGetMemoryData;
RetroGetMemorySize m_retroGetMemorySize;
RetroSerialize m_retroSerialize;
RetroSerializeSize m_retroSerializeSize;
RetroUnserialize m_retroUnserialize;
RetroGetSystemAVInfo m_retroGetSystemAVInfo;
RetroGetSystemInfo m_retroGetSystemInfo;
RetroSetControllerPortDevice m_retroSetControllerPortDevice;
RetroHWContextReset m_retroHWContextReset;
/* used to tell the core where our callbacks are */
RetroSetEnvironment m_retroSetEnvironment;
RetroSetVideoRefresh m_retroSetVideoRefresh;
RetroSetAudioSample m_retroSetAudioSample;
RetroSetAudioSampleBatch m_retroSetAudioSampleBatch;
RetroSetInputPoll m_retroSetInputPoll;
RetroSetInputState m_retroSetInputState;
Q_DISABLE_COPY(Core)
};
#endif // __CORE_H_