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.
165 lines
4.1 KiB
165 lines
4.1 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.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <QTimer>
|
|
#include <QMainWindow>
|
|
|
|
#include <QFileInfo>
|
|
#include <QtEndian>
|
|
#include <QDir>
|
|
#include <QDateTime>
|
|
#include <QtGlobal>
|
|
|
|
#include "core.h"
|
|
#include "../common/input.h"
|
|
#include "../common/video.h"
|
|
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
}
|
|
|
|
Core::Core(QObject *parent) :
|
|
QObject(parent)
|
|
,m_pixFmt(RETRO_PIXEL_FORMAT_0RGB1555)
|
|
,m_info()
|
|
,m_gameInfo()
|
|
,m_imgData(nullptr)
|
|
,m_width(0)
|
|
,m_height(0)
|
|
,m_pitch(0)
|
|
,m_isAudioStreamReady(false)
|
|
,m_isMuted(false)
|
|
,m_isPaused(false)
|
|
,m_variablesChanged(false)
|
|
,m_isHWRender(false)
|
|
,m_noGame(false)
|
|
,m_bottomLeftOrigin(false)
|
|
,m_img()
|
|
,m_options()
|
|
,m_controllerInfo()
|
|
,m_library()
|
|
,m_isLoaded(false)
|
|
,m_isInited(false)
|
|
,m_isResolved(false)
|
|
,m_isRunning(false)
|
|
,m_doRender(false)
|
|
,m_path()
|
|
,m_pathArray()
|
|
,m_pathData(nullptr)
|
|
,m_extractedPath()
|
|
,m_extractedPathArray()
|
|
,m_extractedPathData(nullptr)
|
|
,m_saveStateData(nullptr)
|
|
,m_saveStateDataSize(0)
|
|
,m_elapsedTimer()
|
|
,m_timer()
|
|
,m_tempDir()
|
|
,m_gameData(nullptr)
|
|
,m_gameDataSize(0)
|
|
,m_dataDir()
|
|
,m_savePath()
|
|
,m_statePath()
|
|
,m_systemPath()
|
|
|
|
/* pointers to functions that are exported by the core which we will call later */
|
|
,m_retroInit(nullptr)
|
|
,m_retroDeinit(nullptr)
|
|
,m_retroRun(nullptr)
|
|
,m_retroReset(nullptr)
|
|
,m_retroLoadGame(nullptr)
|
|
,m_retroUnloadGame(nullptr)
|
|
,m_retroGetMemoryData(nullptr)
|
|
,m_retroGetMemorySize(nullptr)
|
|
,m_retroSerialize(nullptr)
|
|
,m_retroSerializeSize(nullptr)
|
|
,m_retroUnserialize(nullptr)
|
|
,m_retroGetSystemAVInfo(nullptr)
|
|
,m_retroGetSystemInfo(nullptr)
|
|
,m_retroSetControllerPortDevice(nullptr)
|
|
,m_retroHWContextReset(nullptr)
|
|
|
|
/* used to tell the core where our callbacks are */
|
|
,m_retroSetEnvironment(nullptr)
|
|
,m_retroSetVideoRefresh(nullptr)
|
|
,m_retroSetAudioSample(nullptr)
|
|
,m_retroSetAudioSampleBatch(nullptr)
|
|
,m_retroSetInputPoll(nullptr)
|
|
,m_retroSetInputState(nullptr)
|
|
{
|
|
QDir d;
|
|
d.mkdir("data");
|
|
d.mkdir("data/saves");
|
|
d.mkdir("data/states");
|
|
d.mkdir("data/system");
|
|
|
|
QDir saveDir("data/saves");
|
|
QDir stateDir("data/states");
|
|
QDir systemDir("data/system");
|
|
|
|
QByteArray saveDirArray = saveDir.absolutePath().toUtf8();
|
|
QByteArray stateDirArray = stateDir.absolutePath().toUtf8();
|
|
QByteArray systemDirArray = systemDir.absolutePath().toUtf8();
|
|
|
|
const char *saveDirData = saveDirArray.constData();
|
|
const char *stateDirData = stateDirArray.constData();
|
|
const char *systemDirData = systemDirArray.constData();
|
|
|
|
strncpy(m_savePath, saveDirData, qMin(saveDirArray.size(), static_cast<int>(sizeof(m_savePath) - 1)));
|
|
strncpy(m_statePath, stateDirData, qMin(stateDirArray.size(), static_cast<int>(sizeof(m_statePath) - 1)));
|
|
strncpy(m_systemPath, systemDirData, qMin(systemDirArray.size(), static_cast<int>(sizeof(m_systemPath) - 1)));
|
|
|
|
m_dataDir = QDir("data");
|
|
|
|
m_timer.setTimerType(Qt::PreciseTimer);
|
|
m_timer.setSingleShot(true);
|
|
|
|
connect(this, &Core::gotFrameSwap, this, &Core::onGotFrameSwap, Qt::DirectConnection);
|
|
}
|
|
|
|
Core::~Core() {
|
|
std::cout << "core dtor" << std::endl;
|
|
|
|
unload();
|
|
|
|
if(m_saveStateData)
|
|
delete[] m_saveStateData;
|
|
}
|
|
|
|
Core* Core::instance() {
|
|
static Core instance;
|
|
return &instance;
|
|
}
|
|
|
|
bool Core::isLoaded() const {
|
|
return m_isLoaded;
|
|
}
|
|
|
|
bool Core::isResolved() const {
|
|
return m_isResolved;
|
|
}
|
|
|
|
bool Core::isRunning() const {
|
|
return m_isRunning;
|
|
}
|
|
|
|
QMap<QString, Core::CoreOption>& Core::getCoreOptions() {
|
|
return m_options;
|
|
}
|
|
|
|
void Core::setVariablesChanged(bool changed) {
|
|
m_variablesChanged = changed;
|
|
}
|
|
|