Merge pull request #83 from meepingsnesroms/tungstenT3Support

Clean up overcomplicated launcher operation
This commit is contained in:
meepingsnesroms
2019-05-27 15:42:00 -07:00
committed by GitHub
11 changed files with 437 additions and 426 deletions

View File

@@ -43,6 +43,7 @@ static float touchCursorX;
static float touchCursorY;
static char contentPath[PATH_MAX_LENGTH];
static uint16_t mouseCursorOldArea[32 * 32];
static bool runningImgFile;
static void renderMouseCursor(int16_t screenX, int16_t screenY){
@@ -377,6 +378,7 @@ bool retro_load_game(const struct retro_game_info *info){
const char* systemDir;
time_t rawTime;
struct tm* timeInfo;
bool hasSram = false;
uint32_t error;
//updates the emulator configuration
@@ -387,11 +389,13 @@ bool retro_load_game(const struct retro_game_info *info){
if(info && !string_is_empty(info->path)){
//boot application
strlcpy(contentPath, info->path, PATH_MAX_LENGTH);
runningImgFile = string_is_equal_case_insensitive(contentPath + strlen(contentPath) - 4, ".img");
}
else{
//boot standard device image, "os5" or "os4" gets appended below
strlcpy(contentPath, systemDir, PATH_MAX_LENGTH);
strlcat(contentPath, "/default", PATH_MAX_LENGTH);
runningImgFile = false;
}
//ROM
@@ -445,70 +449,6 @@ bool retro_load_game(const struct retro_game_info *info){
if(error != EMU_ERROR_NONE)
return false;
//see if RetroArch wants something launched
if(info && !string_is_empty(info->path)){
launcher_file_t file;
struct RFILE* contentFile;
contentFile = filestream_open(contentPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(contentFile){
file.fileSize = filestream_get_size(contentFile);
file.fileData = malloc(file.fileSize);
if(file.fileData)
filestream_read(contentFile, file.fileData, file.fileSize);
else
return false;
filestream_close(contentFile);
}
else{
//no content at path, fail time
return false;
}
if(string_is_equal_case_insensitive(contentPath + strlen(contentPath) - 4, ".img")){
char infoPath[PATH_MAX_LENGTH];
struct RFILE* infoFile;
file.type = LAUNCHER_FILE_TYPE_IMG;
//TODO: need to load info file here
strlcpy(infoPath, contentPath, PATH_MAX_LENGTH);
infoPath[strlen(infoPath) - 4] = '\0';//chop off ".img"
strlcat(infoPath, ".info", PATH_MAX_LENGTH);
infoFile = filestream_open(infoPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(infoFile){
file.infoSize = filestream_get_size(infoFile);
file.infoData = malloc(file.infoSize);
if(file.infoData)
filestream_read(infoFile, file.infoData, file.infoSize);
else
file.infoSize = 0;
filestream_close(romFile);
}
else{
//no info file
file.infoData = NULL;
file.infoSize = 0;
}
}
else{
file.type = LAUNCHER_FILE_TYPE_RESOURCE_FILE;
file.infoData = NULL;
file.infoSize = 0;
}
//the SRAM and SD card are loaded after, so just pass NULL for now
error = launcherLaunch(&file, 1, NULL, 0, NULL, 0);
if(error != EMU_ERROR_NONE)
return false;
free(file.fileData);
if(file.infoData)
free(file.infoData);
}
//save RAM
strlcpy(saveRamPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
@@ -520,6 +460,7 @@ bool retro_load_game(const struct retro_game_info *info){
strlcat(saveRamPath, ".ram", PATH_MAX_LENGTH);
saveRamFile = filestream_open(saveRamPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(saveRamFile){
hasSram = true;
if(filestream_get_size(saveRamFile) == emulatorGetRamSize()){
filestream_read(saveRamFile, palmRam, emulatorGetRamSize());
swap16BufferIfLittle(palmRam, emulatorGetRamSize() / sizeof(uint16_t));
@@ -527,26 +468,28 @@ bool retro_load_game(const struct retro_game_info *info){
filestream_close(saveRamFile);
}
//SD card
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
if(!runningImgFile){
//SD card
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
uint32_t sdImgSize = filestream_get_size(sdImgFile);
//use the NULL, size, NULL method because it takes less RAM
error = emulatorInsertSdCard(NULL, sdImgSize, NULL);
if(error == EMU_ERROR_NONE)
filestream_read(sdImgFile, palmSdCard.flashChipData, sdImgSize);
filestream_close(sdImgFile);
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
uint32_t sdImgSize = filestream_get_size(sdImgFile);
//use the NULL, size, NULL method because it takes less RAM
error = emulatorInsertSdCard(NULL, sdImgSize, NULL);
if(error == EMU_ERROR_NONE)
filestream_read(sdImgFile, palmSdCard.flashChipData, sdImgSize);
filestream_close(sdImgFile);
}
}
//set RTC
@@ -554,6 +497,71 @@ bool retro_load_game(const struct retro_game_info *info){
timeInfo = localtime(&rawTime);
emulatorSetRtc(timeInfo->tm_yday, timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
//see if RetroArch wants something launched
if(info && !string_is_empty(info->path)){
struct RFILE* contentFile;
uint8_t* contentData;
uint32_t contentSize;
contentFile = filestream_open(contentPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(contentFile){
contentSize = filestream_get_size(contentFile);
contentData = malloc(contentSize);
if(contentData)
filestream_read(contentFile, contentData, contentSize);
else
return false;
filestream_close(contentFile);
}
else{
//no content at path, fail time
return false;
}
launcherBootInstantly(hasSram);
if(runningImgFile){
char infoPath[PATH_MAX_LENGTH];
struct RFILE* infoFile;
uint8_t* infoData = NULL;
uint32_t infoSize;
sd_card_info_t sdInfo;
memset(&sdInfo, 0x00, sizeof(sdInfo));
strlcpy(infoPath, contentPath, PATH_MAX_LENGTH);
infoPath[strlen(infoPath) - 4] = '\0';//chop off ".img"
strlcat(infoPath, ".info", PATH_MAX_LENGTH);
infoFile = filestream_open(infoPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(infoFile){
infoSize = filestream_get_size(infoFile);
infoData = malloc(infoSize);
if(infoData)
filestream_read(infoFile, infoData, infoSize);
filestream_close(infoFile);
}
if(infoData)
launcherGetSdCardInfoFromInfoFile(infoData, infoSize, &sdInfo);
error = emulatorInsertSdCard(contentData, contentSize, infoData ? &sdInfo : NULL);
if(infoData)
free(infoData);
}
else{
if(!hasSram)
error = launcherInstallFile(contentData, contentSize);
if(error == EMU_ERROR_NONE)
error = launcherExecute(launcherGetAppId(contentData, contentSize));
}
free(contentData);
if(error != EMU_ERROR_NONE)
return false;
}
//set mouse position
touchCursorX = palmFramebufferWidth / 2;
touchCursorY = palmFramebufferHeight / 2;
@@ -587,20 +595,22 @@ void retro_unload_game(void){
filestream_close(saveRamFile);
}
//SD card
if(palmSdCard.flashChipData){
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
if(!runningImgFile){
//SD card
if(palmSdCard.flashChipData){
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
filestream_write(sdImgFile, palmSdCard.flashChipData, palmSdCard.flashChipSize);
filestream_close(sdImgFile);
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
filestream_write(sdImgFile, palmSdCard.flashChipData, palmSdCard.flashChipSize);
filestream_close(sdImgFile);
}
}
}

View File

@@ -15,6 +15,7 @@
#include <thread>
#include <string>
#include <stdint.h>
#include <string.h>
#include "emuwrapper.h"
#include "../../src/emulator.h"
@@ -179,7 +180,7 @@ uint32_t EmuWrapper::init(const QString& assetPath, bool useOs5, uint32_t featur
emuSaveStatePath = assetPath + "/states-" + model + ".states";
//make the place to store the saves
QDir(assetPath + "states-" + model + ".states").mkdir(".");
QDir(emuSaveStatePath).mkdir(".");
//skip the boot screen
if(fastBoot)
@@ -248,97 +249,36 @@ void EmuWrapper::reset(bool hard){
}
}
uint32_t EmuWrapper::bootFromFileOrDirectory(const QString& mainPath){
uint32_t EmuWrapper::bootFromFile(const QString& mainPath){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_NONE;
QFileInfo pathInfo(mainPath);
QStringList paths;
QVector<QByteArray> fileDataBuffers;
QVector<QByteArray> fileInfoBuffers;
launcher_file_t* files;
QFile appFile(mainPath);
QFile ramFile(mainPath + "." + emuOsName + ".ram");
QFile sdCardFile(mainPath + "." + emuOsName + ".sd.img");
QString suffix = QFileInfo(mainPath).suffix().toLower();
uint32_t appId;
bool hasSaveRam;
bool hasSaveSdCard;
if(!wasPaused)
pause();
if(pathInfo.isDir()){
//get Palm file list
QDir dirInfo(mainPath);
QStringList filters;
filters += "*.prc";
filters += "*.pdb";
filters += "*.pqa";
filters += "*.img";
paths = dirInfo.entryList(filters);
//make paths full direct paths
for(int index = 0; index < paths.length(); index++)
paths[index].prepend(mainPath + "/");
}
else if(pathInfo.exists()){
//use single file
paths = QStringList(mainPath);
}
else{
//error
error = EMU_ERROR_INVALID_PARAMETER;
goto errorOccurred;
}
fileDataBuffers.resize(paths.length());
fileInfoBuffers.resize(paths.length());
files = new launcher_file_t[paths.length()];
memset(files, 0x00, sizeof(launcher_file_t) * paths.length());
for(int index = 0; index < paths.length(); index++){
QFile appFile(paths[index]);
if(appFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QString suffix = QFileInfo(paths[index]).suffix().toLower();
fileDataBuffers[index] = appFile.readAll();
appFile.close();
files[index].fileData = (uint8_t*)fileDataBuffers[index].data();
files[index].fileSize = fileDataBuffers[index].size();
if(suffix == "img"){
QFile infoFile(paths[index].remove(paths[index].size() - 3, 3) + "info");//swap "img" for "info"
if(infoFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
fileInfoBuffers[index] = infoFile.readAll();
files[index].infoData = (uint8_t*)fileInfoBuffers[index].data();
files[index].infoSize = fileInfoBuffers[index].size();
infoFile.close();
}
files[index].type = LAUNCHER_FILE_TYPE_IMG;
}
else{
files[index].type = LAUNCHER_FILE_TYPE_RESOURCE_FILE;
}
}
else{
error = EMU_ERROR_RESOURCE_LOCKED;
goto errorOccurred;
}
}
//save the current data for the last program launched, or the standard device image if none where launched
writeOutSaves();
//its OK if these fail, the buffer will just be NULL, 0 if they do
hasSaveRam = ramFile.open(QFile::ReadOnly | QFile::ExistingOnly);
hasSaveSdCard = sdCardFile.open(QFile::ReadOnly | QFile::ExistingOnly);
hasSaveSdCard = suffix != "img" ? sdCardFile.open(QFile::ReadOnly | QFile::ExistingOnly) : false;
error = launcherLaunch(files, paths.length(), hasSaveRam ? (uint8_t*)ramFile.readAll().data() : NULL, hasSaveRam ? ramFile.size() : 0, hasSaveSdCard ? (uint8_t*)sdCardFile.readAll().data() : NULL, hasSaveSdCard ? sdCardFile.size() : 0);
if(error != EMU_ERROR_NONE)
goto errorOccurred;
//fully clear the emu
emulatorEjectSdCard();
emulatorHardReset();
if(hasSaveRam)
emulatorLoadRam((uint8_t*)ramFile.readAll().data(), ramFile.size());
if(hasSaveSdCard)
emulatorInsertSdCard((uint8_t*)sdCardFile.readAll().data(), sdCardFile.size(), NULL);
//its OK if these fail
if(hasSaveRam)
@@ -346,16 +286,60 @@ uint32_t EmuWrapper::bootFromFileOrDirectory(const QString& mainPath){
if(hasSaveSdCard)
sdCardFile.close();
launcherBootInstantly(hasSaveRam);
if(appFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QByteArray fileBuffer = appFile.readAll();
appFile.close();
if(suffix == "img"){
QFile infoFile(mainPath.mid(0, mainPath.length() - 3) + "info");//swap "img" for "info"
sd_card_info_t sdInfo;
memset(&sdInfo, 0x00, sizeof(sdInfo));
if(infoFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
launcherGetSdCardInfoFromInfoFile((uint8_t*)infoFile.readAll().data(), infoFile.size(), &sdInfo);
infoFile.close();
}
error = emulatorInsertSdCard((uint8_t*)fileBuffer.data(), fileBuffer.size(), &sdInfo);
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
else{
if(!hasSaveRam){
error = launcherInstallFile((uint8_t*)fileBuffer.data(), fileBuffer.size());
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
appId = launcherGetAppId((uint8_t*)fileBuffer.data(), fileBuffer.size());
}
}
//img files just boot to the homescreen
if(suffix != "img"){
error = launcherExecute(appId);
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
//everything worked, set output save files
emuRamFilePath = mainPath + "." + emuOsName + ".ram";
emuSdCardFilePath = mainPath + "." + emuOsName + ".sd.img";
emuSaveStatePath = mainPath + "." + emuOsName + ".states";
//make the place to store the saves
QDir(mainPath + ".states").mkdir(".");
QDir(emuSaveStatePath).mkdir(".");
//need this goto because the emulator must be released before returning
errorOccurred:
if(error != EMU_ERROR_NONE){
//try and recover from error
emulatorEjectSdCard();
emulatorHardReset();
}
if(!wasPaused)
resume();
@@ -372,17 +356,8 @@ uint32_t EmuWrapper::installApplication(const QString& path){
pause();
if(appFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QByteArray appDataBuffer = appFile.readAll();
QString suffix = QFileInfo(appFile).suffix().toLower();
launcher_file_t launcherFile;
error = launcherInstallFile((uint8_t*)appFile.readAll().data(), appFile.size());
appFile.close();
launcherFile.type = LAUNCHER_FILE_TYPE_RESOURCE_FILE;
launcherFile.fileData = (uint8_t*)appDataBuffer.data();
launcherFile.fileSize = appDataBuffer.size();
error = launcherInstallFiles(&launcherFile, 1);
}
if(!wasPaused)

View File

@@ -54,7 +54,7 @@ public:
void pause();
void resume();
void reset(bool hard);
uint32_t bootFromFileOrDirectory(const QString& mainPath);
uint32_t bootFromFile(const QString& mainPath);
uint32_t installApplication(const QString& path);
const QString& getStatePath() const{return emuSaveStatePath;}//needed for looking up state pictures in the GUI
uint32_t saveState(const QString& name);

View File

@@ -260,10 +260,6 @@ void MainWindow::updateDisplay(){
//allow next frame to start
emu.frameHandled();
//update GUI
ui->display->repaint();
ui->powerButtonLed->repaint();
}
}
@@ -393,8 +389,6 @@ void MainWindow::on_ctrlBtn_clicked(){
emu.resume();
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/pause.svg"));
}
ui->ctrlBtn->repaint();
}
void MainWindow::on_install_clicked(){
@@ -425,7 +419,6 @@ void MainWindow::on_debugger_clicked(){
if(emu.isInited()){
emu.pause();
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/play.svg"));
ui->ctrlBtn->repaint();
emuDebugger->exec();
}
}
@@ -490,7 +483,7 @@ void MainWindow::on_bootApp_clicked(){
app = QFileDialog::getOpenFileName(this, "Select File", QDir::root().path(), "Palm OS File (*.prc *.pqa *.img)");
if(app != ""){
uint32_t error = emu.bootFromFileOrDirectory(app);
uint32_t error = emu.bootFromFile(app);
if(error == EMU_ERROR_NONE)
loadedNewApp = true;

View File

@@ -105,6 +105,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/calendar.svg</normaloff>:/buttons/images/calendar.svg</iconset>
@@ -119,6 +122,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Run/Pause</string>
</property>
@@ -142,6 +148,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Reset</string>
</property>
@@ -162,6 +171,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Save/Load State</string>
</property>
@@ -179,6 +191,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Settings</string>
</property>
@@ -199,6 +214,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/power.svg</normaloff>:/buttons/images/power.svg</iconset>
@@ -216,6 +234,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Boot App</string>
</property>
@@ -236,6 +257,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Install App</string>
</property>
@@ -256,6 +280,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Snapshot</string>
</property>
@@ -267,6 +294,9 @@
</item>
<item row="0" column="6">
<widget class="QLabel" name="powerButtonLed">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>This is an LED not a button.😜</string>
</property>
@@ -292,6 +322,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
@@ -309,6 +342,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
@@ -329,6 +365,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
@@ -346,6 +385,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
@@ -366,6 +408,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
@@ -383,6 +428,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
@@ -415,6 +463,9 @@
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/todo.svg</normaloff>:/buttons/images/todo.svg</iconset>
@@ -432,6 +483,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/notes.svg</normaloff>:/buttons/images/notes.svg</iconset>
@@ -449,6 +503,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Debugger</string>
</property>

View File

@@ -37,6 +37,9 @@
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLineEdit" name="homeDirectory">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
@@ -44,13 +47,22 @@
</item>
<item>
<widget class="QPushButton" name="pickHomeDirectory">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Pick Home Directory</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showOnscreenKeys">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Show Onscreen Keys</string>
</property>
@@ -58,6 +70,9 @@
</item>
<item>
<widget class="QLabel" name="label">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set Palm Button Map:</string>
</property>
@@ -80,6 +95,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -87,6 +105,9 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/notes.svg</normaloff>:/buttons/images/notes.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
@@ -97,6 +118,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -104,10 +128,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/calendar.svg</normaloff>:/buttons/images/calendar.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="selectDownKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -115,6 +145,9 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="3">
@@ -125,6 +158,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -132,6 +168,9 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/todo.svg</normaloff>:/buttons/images/todo.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
@@ -142,6 +181,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -149,10 +191,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/power.svg</normaloff>:/buttons/images/power.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="selectUpKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -160,6 +208,9 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
@@ -170,6 +221,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -177,10 +231,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="selectCenterKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -188,10 +248,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/center.svg</normaloff>:/buttons/images/center.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="selectLeftKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -199,10 +265,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/left.svg</normaloff>:/buttons/images/left.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="selectRightKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -210,6 +282,9 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/right.svg</normaloff>:/buttons/images/right.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@@ -224,13 +299,22 @@
</item>
<item>
<widget class="QPushButton" name="clearKeyBind">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Clear Key Bind</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useOs5">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Use OS 5</string>
</property>
@@ -238,6 +322,9 @@
</item>
<item>
<widget class="QCheckBox" name="fastBoot">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Fast Boot(Fastforwards Through The Boot Screen)</string>
</property>
@@ -245,6 +332,9 @@
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set Emulator Features(Restart Required):</string>
</property>
@@ -255,6 +345,9 @@
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QCheckBox" name="featureFastCpu">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Overclocking</string>
</property>
@@ -262,6 +355,9 @@
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="featureHleApis">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>HLE APIs(Speed Hack)</string>
</property>
@@ -276,6 +372,9 @@
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="featureSyncedRtc">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Sync Real Time Clock</string>
</property>

View File

@@ -8,6 +8,8 @@
#include <QFile>
#include <QDir>
#include <QListWidgetItem>
#include <QRegExp>
#include <QRegExpValidator>
#include "mainwindow.h"
@@ -21,17 +23,24 @@ StateManager::StateManager(QWidget* parent) :
ui->setupUi(this);
//this allows resizing the screenshot of the savestate
this->installEventFilter(this);
ui->statePreview->installEventFilter(this);
ui->statePreview->setObjectName("statePreview");
updateStateList();
noBadPaths = new QRegExpValidator(QRegExp("[a-z0-9_()-\\s]*"));
ui->newStateName->setValidator(noBadPaths);
}
StateManager::~StateManager(){
delete noBadPaths;
delete ui;
}
bool StateManager::eventFilter(QObject* object, QEvent* event){
if(object->objectName() == "StateManager" && event->type() == QEvent::WindowActivate){
updateStateList();
ui->states->setCurrentRow(0);
}
if(object->objectName() == "statePreview" && event->type() == QEvent::Resize)
updateStatePreview();
@@ -67,8 +76,6 @@ void StateManager::updateStatePreview(){
//remove outdated image
ui->statePreview->clear();
}
ui->statePreview->update();
}
int StateManager::getStateIndexRowByName(const QString& name){
@@ -115,6 +122,4 @@ void StateManager::on_deleteState_clicked(){
void StateManager::on_states_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous){
updateStatePreview();
ui->states->repaint();
ui->statePreview->repaint();
}

View File

@@ -5,6 +5,7 @@
#include <QEvent>
#include <QListWidgetItem>
#include <QString>
#include <QRegExpValidator>
#include "emuwrapper.h"
@@ -35,4 +36,5 @@ private slots:
private:
Ui::StateManager* ui;
EmuWrapper* emu;
QRegExpValidator* noBadPaths;
};

View File

@@ -21,12 +21,14 @@ RetroArch GUI:
*now launches content like cartridge based systems
//TODO: allow adding more content after boot
//TODO: get EMU_MANAGE_HOST_CPU_PIPELINE working on other platforms then the main 4
//TODO: when compiling with "make platform=windows_x86_64" the dll wont load(theres a really good chance its because "libgomp-1.dll"(the OpenMP handler library) is missing from the RetroArch folder)
*booting without game works again
*add multithreading and pipeline speedups
Qt GUI:
//TODO: get circleci builds for QT port on Win/Mac/Linux
//TODO: allow reiniting the emu without closing the program
*fixed state manager not loading until a state is saved
*boot button uses install button icon now, changed install button to icon a "+"
*put back left/right/center keys
*added install and boot buttons to both modes, content loaded with the boot button has separate save paths just like cartridge systems

View File

@@ -154,7 +154,7 @@ static uint32_t launcherM515CallGuestFunction(uint32_t address, uint16_t trap, c
return functionReturn;
}
static uint32_t launcherInstallAppM515(launcher_file_t* file){
static uint32_t launcherInstallAppM515(uint8_t* data, uint32_t size){
/*
#define memNewChunkFlagNonMovable 0x0200
#define memNewChunkFlagAllowLarge 0x1000 // this is not in the sdk *g*
@@ -167,7 +167,7 @@ static uint32_t launcherInstallAppM515(launcher_file_t* file){
//try and get guest memory buffer
memChunkNewArgs[0] = 1/*heapID, storage RAM*/;
memChunkNewArgs[1] = file->fileSize;
memChunkNewArgs[1] = size;
memChunkNewArgs[2] = 0x1200/*attr, seems to work without memOwnerID*/;
palmSideResourceData = launcherM515CallGuestFunction(0x00000000, MemChunkNew, "p(wlw)", memChunkNewArgs);
@@ -176,8 +176,8 @@ static uint32_t launcherInstallAppM515(launcher_file_t* file){
return false;
dbvzChipSelects[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = false;//need to unprotect storage RAM
MULTITHREAD_LOOP(count) for(count = 0; count < file->fileSize; count++)
m68k_write_memory_8(palmSideResourceData + count, file->fileData[count]);
MULTITHREAD_LOOP(count) for(count = 0; count < size; count++)
m68k_write_memory_8(palmSideResourceData + count, data[count]);
dbvzChipSelects[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = storageRamReadOnly;//restore old protection state
error = launcherM515CallGuestFunction(0x00000000, DmCreateDatabaseFromImage, "w(p)", &palmSideResourceData);//Err DmCreateDatabaseFromImage(MemPtr bufferP);//this looks best
launcherM515CallGuestFunction(0x00000000, MemChunkFree, "w(p)", &palmSideResourceData);
@@ -190,7 +190,7 @@ static uint32_t launcherInstallAppM515(launcher_file_t* file){
}
#if defined(EMU_SUPPORT_PALM_OS5)
static uint32_t launcherInstallAppTungstenT3(launcher_file_t* file){
static uint32_t launcherInstallAppTungstenT3(uint8_t* data, uint32_t size){
//TODO
return EMU_ERROR_NOT_IMPLEMENTED;
}
@@ -358,192 +358,6 @@ static void launcherPushHomeButtonTouchscreenTungstenT3(void){
}
#endif
static void launcherGetSdCardInfoFromInfoFile(launcher_file_t* file, sd_card_info_t* returnValue){
//parse a small binary file with the extra SD card data
uint32_t offset = 0;
//clear everything
memset(returnValue, 0x00, sizeof(sd_card_info_t));
//csd
if(file->infoSize < offset + 16)
return;
memcpy(returnValue->csd, file->infoData + offset, 16);
offset += 16;
//cid
if(file->infoSize < offset + 16)
return;
memcpy(returnValue->cid, file->infoData + offset, 16);
offset += 16;
//scr
if(file->infoSize < offset + 8)
return;
memcpy(returnValue->scr, file->infoData + offset, 8);
offset += 8;
//ocr
if(file->infoSize < offset + sizeof(uint32_t))
return;
returnValue->ocr = readStateValue32(file->infoData + offset);
offset += sizeof(uint32_t);
//writeProtectSwitch
if(file->infoSize < offset + sizeof(uint8_t))
return;
returnValue->writeProtectSwitch = readStateValue8(file->infoData + offset);
offset += sizeof(uint8_t);
//this can keep growing with new values but all the current values are fixed!!
}
uint32_t launcherLaunch(launcher_file_t* files, uint32_t fileCount, uint8_t* sramData, uint32_t sramSize, uint8_t* sdCardData, uint32_t sdCardSize){
bool cardImageHasBeenLoaded = false;
uint32_t cardImage;
uint32_t totalSize = 0;
uint32_t error;
uint32_t index;
bool hasBootResource = false;
uint32_t bootResource;
for(index = 0; index < fileCount; index++){
//cant load a 2 card images
if(cardImageHasBeenLoaded && files[index].type == LAUNCHER_FILE_TYPE_IMG)
return EMU_ERROR_INVALID_PARAMETER;
if(files[index].type == LAUNCHER_FILE_TYPE_IMG){
cardImageHasBeenLoaded = true;
cardImage = index;
}
else if(files[index].type == LAUNCHER_FILE_TYPE_RESOURCE_FILE){
if(files[index].fileSize > 0x4D){
//has full prc header
if(files[index].fileData[0x21] & 0x01){
//is a prc
uint32_t type = readStateValue32(files[index].fileData + 0x3C);
uint32_t creator = readStateValue32(files[index].fileData + 0x40);
if(type == 'appl'){
//is an application
hasBootResource = true;
bootResource = creator;
}
}
}
}
totalSize += files[index].fileSize;
}
//in case the installed apps store anything on the SD card
launcherSaveSdCardImage = true;
//in case the emulator is currently running with an SD card inserted
emulatorEjectSdCard();
//dont want a data leak, could cause glitches
emulatorHardReset();
//insert card if present
if(cardImageHasBeenLoaded){
if(files[cardImage].infoData){
//with info file
sd_card_info_t sdInfo;
//get SD info from file
launcherGetSdCardInfoFromInfoFile(&files[cardImage], &sdInfo);
//load card image
error = emulatorInsertSdCard(files[cardImage].fileData, files[cardImage].fileSize, &sdInfo);
if(error != EMU_ERROR_NONE)
return error;
//dont save read only card images
if(sdInfo.writeProtectSwitch)
launcherSaveSdCardImage = false;
}
else{
//without info file
error = emulatorInsertSdCard(files[0].fileData, files[0].fileSize, NULL);
if(error != EMU_ERROR_NONE)
return error;
}
}
else{
if(sdCardData){
//use existing SD card image
error = emulatorInsertSdCard(sdCardData, sdCardSize, NULL);
if(error != EMU_ERROR_NONE)
return error;
}
}
//use the existing SRAM file if available
if(sramData){
emulatorLoadRam(sramData, sramSize);
launcherBootInstantly(true);
if(hasBootResource){
//launch the app
#if defined(EMU_SUPPORT_PALM_OS5)
if(palmEmulatingTungstenT3)
error = launcherLaunchAppTungstenT3(bootResource);
else
#endif
error = launcherLaunchAppM515(bootResource);
if(error != EMU_ERROR_NONE)
return error;
}
}
else{
launcherBootInstantly(false);
//install all resource files
for(index = 0; index < fileCount; index++)
if(files[index].type == LAUNCHER_FILE_TYPE_RESOURCE_FILE)
launcherInstallFiles(&files[index], 1);
if(hasBootResource){
//launch the app
#if defined(EMU_SUPPORT_PALM_OS5)
if(palmEmulatingTungstenT3)
error = launcherLaunchAppTungstenT3(bootResource);
else
#endif
error = launcherLaunchAppM515(bootResource);
if(error != EMU_ERROR_NONE)
return error;
}
}
return EMU_ERROR_NONE;
}
uint32_t launcherInstallFiles(launcher_file_t* files, uint32_t fileCount){
uint32_t index;
for(index = 0; index < fileCount; index++){
uint32_t error;
//cant install img files
if(files[index].type != LAUNCHER_FILE_TYPE_RESOURCE_FILE)
return EMU_ERROR_INVALID_PARAMETER;
#if defined(EMU_SUPPORT_PALM_OS5)
if(palmEmulatingTungstenT3)
error = launcherInstallAppTungstenT3(&files[index]);
else
#endif
error = launcherInstallAppM515(&files[index]);
if(error != EMU_ERROR_NONE)
return error;
}
return EMU_ERROR_NONE;
}
void launcherBootInstantly(bool hasSram){
uint32_t index;
@@ -582,3 +396,92 @@ void launcherBootInstantly(bool hasSram){
emulatorSkipFrame();
}
}
uint32_t launcherInstallFile(uint8_t* data, uint32_t size){
#if defined(EMU_SUPPORT_PALM_OS5)
if(palmEmulatingTungstenT3)
return launcherInstallAppTungstenT3(data, size);
else
#endif
return launcherInstallAppM515(data, size);
}
bool launcherIsExecutable(uint8_t* data, uint32_t size){
if(size > 0x4D){
//has full prc header
if(data[0x21] & 0x01){
//is a prc
uint32_t type = readStateValue32(data + 0x3C);
if(type == 'appl')
return true;
}
}
return false;
}
uint32_t launcherGetAppId(uint8_t* data, uint32_t size){
if(size > 0x4D){
//has full prc header
if(data[0x21] & 0x01){
//is a prc
uint32_t type = readStateValue32(data + 0x3C);
uint32_t creator = readStateValue32(data + 0x40);
if(type == 'appl')
return creator;
}
}
return 0x00000000;
}
uint32_t launcherExecute(uint32_t appId){
#if defined(EMU_SUPPORT_PALM_OS5)
if(palmEmulatingTungstenT3)
return launcherLaunchAppTungstenT3(appId);
else
#endif
return launcherLaunchAppM515(appId);
}
void launcherGetSdCardInfoFromInfoFile(uint8_t* data, uint32_t size, sd_card_info_t* returnValue){
//parse a small binary file with the extra SD card data
uint32_t offset = 0;
//clear everything
memset(returnValue, 0x00, sizeof(sd_card_info_t));
//csd
if(size < offset + 16)
return;
memcpy(returnValue->csd, data + offset, 16);
offset += 16;
//cid
if(size < offset + 16)
return;
memcpy(returnValue->cid, data + offset, 16);
offset += 16;
//scr
if(size < offset + 8)
return;
memcpy(returnValue->scr, data + offset, 8);
offset += 8;
//ocr
if(size < offset + sizeof(uint32_t))
return;
returnValue->ocr = readStateValue32(data + offset);
offset += sizeof(uint32_t);
//writeProtectSwitch
if(size < offset + sizeof(uint8_t))
return;
returnValue->writeProtectSwitch = readStateValue8(data + offset);
offset += sizeof(uint8_t);
//this can keep growing with new values but all the current values are fixed!!
}

View File

@@ -11,48 +11,13 @@ extern "C" {
#include "../emulator.h"
enum{
LAUNCHER_FILE_TYPE_NONE = 0,
LAUNCHER_FILE_TYPE_RESOURCE_FILE,
LAUNCHER_FILE_TYPE_IMG
};
void launcherBootInstantly(bool hasSram);//fastforwards through the boot sequence
uint32_t launcherInstallFile(uint8_t* data, uint32_t size);//only call after the emu has booted, launcherBootInstantly() will ensure a full boot has completed otherwise this is up to the frontend to be safe
bool launcherIsExecutable(uint8_t* data, uint32_t size);
uint32_t launcherGetAppId(uint8_t* data, uint32_t size);
uint32_t launcherExecute(uint32_t appId);//must first be installed with launcherInstallFile
typedef struct{
uint8_t type;//file type
uint8_t* fileData;
uint32_t fileSize;
uint8_t* infoData;//only used with LAUNCHER_FILE_TYPE_IMG right now
uint32_t infoSize;
}launcher_file_t;
extern bool launcherSaveSdCardImage;//false if loading a read only SD card image
/*
the launcher is called after emulatorInit when its enabled
the order is:
launcher_file_t* files[...];
uint32_t fileCount;
uint8_t* saveData = NULL;
uint32_t saveSize = 0;
uint8_t* oldSdCardData = NULL;
uint32_t oldSdCardSize = 0;
uint32_t error;
error = emulatorInit(romFileData, romFileSize, bootloaderFileData(if m515), bootloaderFileSize(if m515), features);
if(error)
return error;
error = launcherLaunch(files, fileCount, saveData, saveSize, oldSdCardData, oldSdCardSize);//this can fail installing apps
if(error)
return error;
//its now safe to call emulatorFrame for frames
*/
//if first launch NULL should be passed for sramData and sdCardData
uint32_t launcherLaunch(launcher_file_t* files, uint32_t fileCount, uint8_t* sramData, uint32_t sramSize, uint8_t* sdCardData, uint32_t sdCardSize);
//only call after the emu has booted, launcherLaunch() will ensure a full boot has completed otherwise this is up to the frontend to be safe
uint32_t launcherInstallFiles(launcher_file_t* files, uint32_t fileCount);
void launcherBootInstantly(bool hasSram);
void launcherGetSdCardInfoFromInfoFile(uint8_t* data, uint32_t size, sd_card_info_t* returnValue);
#ifdef __cplusplus
}