2021-07-05 17:44:08 +00:00
|
|
|
#ifndef LIBRETRO
|
|
|
|
#include "types.h"
|
2020-04-20 16:52:02 +00:00
|
|
|
#include "emulator.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
#include "hw/mem/_vmem.h"
|
|
|
|
#include "cfg/cfg.h"
|
2021-03-01 09:13:40 +00:00
|
|
|
#include "cfg/option.h"
|
2019-06-30 19:06:46 +00:00
|
|
|
#include "log/LogManager.h"
|
2021-07-05 17:44:08 +00:00
|
|
|
#include "rend/gui.h"
|
|
|
|
#include "oslib/oslib.h"
|
2021-03-23 13:49:19 +00:00
|
|
|
#include "debug/gdb_server.h"
|
2021-07-05 17:44:08 +00:00
|
|
|
#include "archive/rzip.h"
|
|
|
|
#include "rend/mainui.h"
|
|
|
|
#include "input/gamepad_device.h"
|
2021-10-03 16:34:27 +00:00
|
|
|
#include "lua/lua.h"
|
2014-04-22 14:32:04 +00:00
|
|
|
|
2021-07-20 17:21:11 +00:00
|
|
|
int flycast_init(int argc, char* argv[])
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-08-15 08:48:39 +00:00
|
|
|
#if defined(TEST_AUTOMATION)
|
2019-02-25 18:15:59 +00:00
|
|
|
setbuf(stdout, 0);
|
|
|
|
setbuf(stderr, 0);
|
2021-10-10 14:26:36 +00:00
|
|
|
settings.aica.muteAudio = true;
|
2019-02-25 18:15:59 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
if (!_vmem_reserve())
|
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
ERROR_LOG(VMEM, "Failed to alloc mem");
|
2013-12-19 17:10:14 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2019-02-25 16:52:53 +00:00
|
|
|
if (ParseCommandLine(argc, argv))
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2018-08-26 11:39:32 +00:00
|
|
|
return 69;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2021-03-01 09:13:40 +00:00
|
|
|
config::Settings::instance().reset();
|
2019-06-30 19:06:46 +00:00
|
|
|
LogManager::Shutdown();
|
2019-02-25 16:52:53 +00:00
|
|
|
if (!cfgOpen())
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
LogManager::Init();
|
|
|
|
NOTICE_LOG(BOOT, "Config directory is not set. Starting onboarding");
|
2019-02-25 16:52:53 +00:00
|
|
|
gui_open_onboarding();
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-02-25 16:52:53 +00:00
|
|
|
else
|
2019-06-30 19:06:46 +00:00
|
|
|
{
|
|
|
|
LogManager::Init();
|
2021-03-01 09:13:40 +00:00
|
|
|
config::Settings::instance().load(false);
|
2019-06-30 19:06:46 +00:00
|
|
|
}
|
2021-03-01 11:49:41 +00:00
|
|
|
// Force the renderer type now since we're not switching
|
2021-03-03 08:40:52 +00:00
|
|
|
config::RendererType.commit();
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-02-15 19:48:30 +00:00
|
|
|
os_CreateWindow();
|
2019-02-25 16:52:53 +00:00
|
|
|
os_SetupInput();
|
|
|
|
|
2021-03-23 13:49:19 +00:00
|
|
|
debugger::init();
|
2021-10-03 16:34:27 +00:00
|
|
|
lua::init();
|
2019-02-25 16:52:53 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dc_exit()
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2021-10-02 09:30:40 +00:00
|
|
|
emu.stop();
|
2020-12-15 14:09:42 +00:00
|
|
|
mainui_stop();
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
void SaveSettings()
|
|
|
|
{
|
2021-03-01 09:13:40 +00:00
|
|
|
config::Settings::instance().save();
|
2019-03-29 16:19:18 +00:00
|
|
|
GamepadDevice::SaveMaplePorts();
|
|
|
|
|
2019-08-25 16:38:36 +00:00
|
|
|
#ifdef __ANDROID__
|
2019-02-25 16:52:53 +00:00
|
|
|
void SaveAndroidSettings();
|
|
|
|
SaveAndroidSettings();
|
2018-11-11 22:49:41 +00:00
|
|
|
#endif
|
2019-02-06 18:57:13 +00:00
|
|
|
}
|
|
|
|
|
2021-10-02 09:30:40 +00:00
|
|
|
void flycast_term()
|
2018-09-20 20:41:10 +00:00
|
|
|
{
|
2021-10-02 09:30:40 +00:00
|
|
|
gui_cancel_load();
|
2021-10-03 16:34:27 +00:00
|
|
|
lua::term();
|
2021-09-29 08:22:58 +00:00
|
|
|
emu.term();
|
2018-09-20 20:41:10 +00:00
|
|
|
}
|
|
|
|
|
2021-06-03 11:22:40 +00:00
|
|
|
void dc_savestate(int index)
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2021-07-05 17:44:08 +00:00
|
|
|
unsigned int total_size = 0;
|
|
|
|
void *data = nullptr;
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
if (!dc_serialize(&data, &total_size))
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - could not initialize total size") ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Save state failed", 2000);
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
data = malloc(total_size);
|
|
|
|
if (data == nullptr)
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2021-07-05 17:44:08 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - could not malloc %d bytes", total_size);
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Save state failed - memory full", 2000);
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2020-12-26 08:58:53 +00:00
|
|
|
void *data_ptr = data;
|
2021-09-02 15:51:23 +00:00
|
|
|
total_size = 0;
|
2021-07-05 17:44:08 +00:00
|
|
|
if (!dc_serialize(&data_ptr, &total_size))
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - could not serialize data") ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Save state failed", 2000);
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
std::string filename = hostfs::getSavestatePath(index, true);
|
2020-12-26 08:58:53 +00:00
|
|
|
#if 0
|
2021-01-19 10:11:01 +00:00
|
|
|
FILE *f = nowide::fopen(filename.c_str(), "wb") ;
|
2018-09-02 13:49:23 +00:00
|
|
|
|
|
|
|
if ( f == NULL )
|
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - could not open %s for writing", filename.c_str()) ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Cannot open save file", 2000);
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fwrite(data, 1, total_size, f) ;
|
|
|
|
std::fclose(f);
|
2020-12-26 08:58:53 +00:00
|
|
|
#else
|
|
|
|
RZipFile zipFile;
|
|
|
|
if (!zipFile.Open(filename, true))
|
|
|
|
{
|
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - could not open %s for writing", filename.c_str());
|
|
|
|
gui_display_notification("Cannot open save file", 2000);
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2020-12-26 08:58:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (zipFile.Write(data, total_size) != total_size)
|
|
|
|
{
|
|
|
|
WARN_LOG(SAVESTATE, "Failed to save state - error writing %s", filename.c_str());
|
|
|
|
gui_display_notification("Error saving state", 2000);
|
|
|
|
zipFile.Close();
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2020-12-26 08:58:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
zipFile.Close();
|
|
|
|
#endif
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(SAVESTATE, "Saved state to %s size %d", filename.c_str(), total_size) ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("State saved", 1000);
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2021-06-03 11:22:40 +00:00
|
|
|
void dc_loadstate(int index)
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2020-12-26 08:58:53 +00:00
|
|
|
u32 total_size = 0;
|
|
|
|
FILE *f = nullptr;
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2021-09-29 08:22:58 +00:00
|
|
|
emu.stop();
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
std::string filename = hostfs::getSavestatePath(index, false);
|
2020-12-26 08:58:53 +00:00
|
|
|
RZipFile zipFile;
|
|
|
|
if (zipFile.Open(filename, false))
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2020-12-26 08:58:53 +00:00
|
|
|
total_size = (u32)zipFile.Size();
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
2020-12-26 08:58:53 +00:00
|
|
|
else
|
|
|
|
{
|
2021-01-19 10:11:01 +00:00
|
|
|
f = nowide::fopen(filename.c_str(), "rb") ;
|
2020-12-26 08:58:53 +00:00
|
|
|
|
|
|
|
if ( f == NULL )
|
|
|
|
{
|
|
|
|
WARN_LOG(SAVESTATE, "Failed to load state - could not open %s for reading", filename.c_str()) ;
|
|
|
|
gui_display_notification("Save state not found", 2000);
|
|
|
|
return;
|
|
|
|
}
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fseek(f, 0, SEEK_END);
|
|
|
|
total_size = (u32)std::ftell(f);
|
|
|
|
std::fseek(f, 0, SEEK_SET);
|
2020-12-26 08:58:53 +00:00
|
|
|
}
|
|
|
|
void *data = malloc(total_size);
|
2018-09-02 13:49:23 +00:00
|
|
|
if ( data == NULL )
|
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to load state - could not malloc %d bytes", total_size) ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Failed to load state - memory full", 2000);
|
2020-12-26 08:58:53 +00:00
|
|
|
if (f != nullptr)
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(f);
|
2020-12-26 08:58:53 +00:00
|
|
|
else
|
|
|
|
zipFile.Close();
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2020-12-26 08:58:53 +00:00
|
|
|
size_t read_size;
|
|
|
|
if (f == nullptr)
|
|
|
|
{
|
|
|
|
read_size = zipFile.Read(data, total_size);
|
|
|
|
zipFile.Close();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
read_size = fread(data, 1, total_size, f) ;
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(f);
|
2020-12-26 08:58:53 +00:00
|
|
|
}
|
2019-07-12 15:20:43 +00:00
|
|
|
if (read_size != total_size)
|
|
|
|
{
|
|
|
|
WARN_LOG(SAVESTATE, "Failed to load state - I/O error");
|
|
|
|
gui_display_notification("Failed to load state - I/O error", 2000);
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2019-07-12 15:20:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
const void *data_ptr = data;
|
2021-07-10 15:39:16 +00:00
|
|
|
dc_loadstate(&data_ptr, total_size);
|
2018-10-29 14:11:34 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
free(data);
|
2021-01-19 20:31:48 +00:00
|
|
|
EventManager::event(Event::LoadState);
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(SAVESTATE, "Loaded state from %s size %d", filename.c_str(), total_size) ;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
2020-04-20 16:52:02 +00:00
|
|
|
|
2021-07-05 17:44:08 +00:00
|
|
|
#endif
|