RetroArch CMake corrections; Implement loading from ZIP files which contain PRCs and PDBs.

This commit is contained in:
Stephanie Gawroriski
2022-10-02 17:34:57 -04:00
parent aadb0a29ff
commit 4d084a03d7
4 changed files with 210 additions and 78 deletions

View File

@@ -1,4 +1,4 @@
add_library(mu-libretro SHARED
add_library(mu_libretro SHARED
libretro.c
cursors.c
miniz.c
@@ -11,17 +11,15 @@ add_library(mu-libretro SHARED
libretro-common/string/stdstring.c
libretro-common/vfs/vfs_implementation.c)
# Remove the "lib" prefix on Windows, it is incorrect
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
set_target_properties(mu-libretro PROPERTIES PREFIX "")
endif()
# Remove the "lib" prefix always, RetroArch does not name in this way
set_target_properties(mu_libretro PROPERTIES PREFIX "")
# Bring all the sub-modules as needed
target_link_libraries(mu-libretro
target_link_libraries(mu_libretro
MuCore)
# Include the required includes
target_include_directories(mu-libretro PUBLIC
target_include_directories(mu_libretro PUBLIC
"${PROJECT_SOURCE_DIR}/include"
"libretro-common/include")
@@ -40,8 +38,8 @@ endif()
## Target to run RetroArch with the Mu Core
if(DEFINED MU_LIBRETRO_DIR)
add_custom_target(RetroArch
DEPENDS mu-libretro
COMMAND "${MU_LIBRETRO_DIR}/retroarch${MU_LIBRETRO_EXTENSION}" "-v" "-L" "$<TARGET_FILE:mu-libretro>"
DEPENDS mu_libretro
COMMAND "${MU_LIBRETRO_DIR}/retroarch${MU_LIBRETRO_EXTENSION}" "-v" "-L" "$<TARGET_FILE:mu_libretro>"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
COMMENT "Starting RetroArch with Mu")
endif()

View File

@@ -18,7 +18,7 @@
#include "silkscreen.h"
#include "fileLauncher/launcher.h"
#include "cursors.h"
#include "miniz.h"
#define JOYSTICK_DEADZONE 4000
#define JOYSTICK_MULTIPLIER 0.0001
@@ -213,7 +213,7 @@ void retro_get_system_info(struct retro_system_info *info){
#ifndef GIT_VERSION
#define GIT_VERSION ""
#endif
info->library_version = "v1.3.0" GIT_VERSION;
info->library_version = "v1.3.1" GIT_VERSION;
info->need_fullpath = true;
info->valid_extensions = "prc|pqa|img|pdb|zip";
@@ -430,6 +430,198 @@ void retro_run(void){
unrenderMouseCursor(touchCursorX, touchCursorY);
}
/**
* Tries to load a non-SRAM based content file, it will be installed into the
* system. This will handle the case where the content is a ZIP file in which
* if it is then it will load all of the contained PRCs and PDBs accordingly.
*
* @param error The error possibly.
* @param contentData The data being loaded.
* @param contentSize The size of the loaded content.
* @since 2022/10/02
*/
bool loadContentFileNonSRAM(uint32_t *error, uint8_t *contentData,
uint32_t contentSize) {
mz_zip_archive zipArchive;
mz_zip_archive_file_stat stat;
uint32_t appId = 0, maybeAppId, newError;
uint32_t numFiles, index, lookStage;
uint32_t fileNameLen;
void* entryBuf;
// Detect if this is a ZIP file, if it is
memset(&zipArchive, 0, sizeof(zipArchive));
if (mz_zip_reader_init_mem(&zipArchive,
contentData, contentSize,
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY |
MZ_ZIP_FLAG_ASCII_FILENAME))
{
// Notice
log_cb(RETRO_LOG_INFO, "Loading from ZIP...\n");
// Process every file in the ZIP looking for PDBs, then PRCs
numFiles = mz_zip_reader_get_num_files(&zipArchive);
for (lookStage = 0; lookStage < 2; lookStage++)
for (index = 0; index < numFiles; index++)
{
// If we are failing then just fail here
if ((*error) != EMU_ERROR_NONE)
{
lookStage = 9999;
index = numFiles;
break;
}
// Get file information, only care about valid ones
memset(&stat, 0, sizeof(stat));
if (!mz_zip_reader_file_stat(&zipArchive,
index, &stat))
continue;
// Ignore directories and anything MiniZ does not support
if (!stat.m_is_supported || stat.m_is_directory)
continue;
// How long is the file name?
fileNameLen = strlen(stat.m_filename);
// Too short?
if (fileNameLen < 4)
continue;
// Not a PDB or PRC?
if (0 != strcasecmp((lookStage == 0 ? ".pdb" : ".prc"),
&stat.m_filename[fileNameLen - 4]))
continue;
// Allocate buffer for the data
entryBuf = malloc(stat.m_uncomp_size);
if (entryBuf == NULL)
return false;
// Load in data
memset(entryBuf, 0, stat.m_uncomp_size);
if (mz_zip_reader_extract_to_mem_no_alloc(&zipArchive,
index, entryBuf, stat.m_uncomp_size,
0, NULL, 0))
{
// Notice
log_cb(RETRO_LOG_INFO, "Installing from ZIP: %s\n",
stat.m_filename);
// Install the file
newError = launcherInstallFile(entryBuf,
stat.m_uncomp_size);
// Fill in error state
if (newError != EMU_ERROR_NONE)
(*error) = newError;
// If we are loading a PRC, get the appId of it so that we
// can launch it accordingly
if (lookStage == 1)
{
maybeAppId = launcherGetAppId(entryBuf,
stat.m_uncomp_size);
if (maybeAppId != 0)
appId = maybeAppId;
}
}
// Clear allocated data
free(entryBuf);
}
// Stop reading the ZIP
mz_zip_end(&zipArchive);
}
// Otherwise, not a ZIP at all... load it directly
else
{
// Notice
log_cb(RETRO_LOG_INFO, "Loading single PRC/PDB...\n");
// Install the file
(*error) = launcherInstallFile(contentData, contentSize);
// Get the app ID to launch
appId = launcherGetAppId(contentData, contentSize);
}
// Notice
log_cb(RETRO_LOG_INFO, "Completed load!\n");
// Try to the launch the app, if it even is one...
if ((*error) == EMU_ERROR_NONE && appId != 0)
(*error) = launcherExecute(appId);
}
bool loadContentFile(bool hasSram, uint32_t* error) {
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 = 0;
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)
loadContentFileNonSRAM(error, contentData, contentSize);
}
free(contentData);
if ((*error) != EMU_ERROR_NONE)
return false;
return true;
}
bool retro_load_game(const struct retro_game_info *info){
uint8_t* romData;
uint32_t romSize;
@@ -555,68 +747,10 @@ bool retro_load_game(const struct retro_game_info *info){
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 = 0;
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;
if(info && !string_is_empty(info->path)) {
if (!loadContentFile(hasSram, &error)) {
return false;
}
}
//set the time callback

View File

@@ -119,7 +119,7 @@
If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */
/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
/*#define MINIZ_NO_STDIO */
#define MINIZ_NO_STDIO
/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */
/* get/set file times, and the C run-time funcs that get/set times won't be called. */
@@ -130,13 +130,13 @@
/*#define MINIZ_NO_ARCHIVE_APIS */
/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */
/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */
#define MINIZ_NO_ARCHIVE_WRITING_APIS
/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */
/*#define MINIZ_NO_ZLIB_APIS */
#define MINIZ_NO_ZLIB_APIS
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */
/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc

View File

@@ -5,7 +5,7 @@ supported_extensions = "prc|pqa|img|pdb|zip"
corename = "Mu"
license = "CC BY-NC 3.0 US (Non-commercial)"
permissions = ""
display_version = "v1.3.0"
display_version = "v1.3.1"
categories = "Emulator"
# Hardware Information