2013-12-19 17:10:14 +00:00
|
|
|
// nullDC.cpp : Makes magic cookies
|
|
|
|
//
|
|
|
|
|
|
|
|
//initialse Emu
|
|
|
|
#include "types.h"
|
|
|
|
#include "oslib/oslib.h"
|
2015-07-17 21:58:46 +00:00
|
|
|
#include "oslib/audiostream.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
#include "hw/mem/_vmem.h"
|
|
|
|
#include "stdclass.h"
|
|
|
|
#include "cfg/cfg.h"
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "hw/maple/maple_cfg.h"
|
|
|
|
#include "hw/sh4/sh4_mem.h"
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
#include "hw/naomi/naomi_cart.h"
|
2018-05-22 13:20:37 +00:00
|
|
|
#include "reios/reios.h"
|
2018-10-29 14:11:34 +00:00
|
|
|
#include "hw/sh4/sh4_sched.h"
|
2018-09-23 14:18:35 +00:00
|
|
|
#include "hw/pvr/Renderer_if.h"
|
2018-10-29 14:11:34 +00:00
|
|
|
#include "hw/pvr/spg.h"
|
2019-02-06 18:57:13 +00:00
|
|
|
#include "hw/aica/dsp.h"
|
2019-02-17 23:25:06 +00:00
|
|
|
#include "imgread/common.h"
|
2019-02-25 16:52:53 +00:00
|
|
|
#include "rend/gui.h"
|
2019-03-03 23:32:15 +00:00
|
|
|
#include "profiler/profiler.h"
|
2019-03-29 16:19:18 +00:00
|
|
|
#include "input/gamepad_device.h"
|
2019-06-19 09:01:33 +00:00
|
|
|
#include "hw/sh4/dyna/blockmanager.h"
|
2019-06-30 19:06:46 +00:00
|
|
|
#include "log/LogManager.h"
|
2019-09-24 21:59:36 +00:00
|
|
|
#include "cheats.h"
|
2014-04-22 14:32:04 +00:00
|
|
|
|
2018-10-29 15:53:26 +00:00
|
|
|
void FlushCache();
|
2019-02-15 19:48:30 +00:00
|
|
|
void LoadCustom();
|
2019-02-25 16:52:53 +00:00
|
|
|
void* dc_run(void*);
|
|
|
|
void dc_resume();
|
2018-10-29 15:53:26 +00:00
|
|
|
|
2019-09-27 12:15:29 +00:00
|
|
|
extern bool fast_forward_mode;
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
settings_t settings;
|
2019-02-16 13:25:54 +00:00
|
|
|
// Set if game has corresponding option by default, so that it's not saved in the config
|
|
|
|
static bool rtt_to_buffer_game;
|
|
|
|
static bool safemode_game;
|
|
|
|
static bool tr_poly_depth_mask_game;
|
|
|
|
static bool extra_depth_game;
|
2019-05-09 19:47:01 +00:00
|
|
|
static bool disable_vmem32_game;
|
2019-09-01 14:35:12 +00:00
|
|
|
static int forced_game_region = -1;
|
|
|
|
static int forced_game_cable = -1;
|
2019-09-24 21:59:36 +00:00
|
|
|
static int saved_screen_stretching = -1;
|
2019-02-16 13:25:54 +00:00
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
cThread emu_thread(&dc_run, NULL);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-08-25 17:29:56 +00:00
|
|
|
#ifdef _WIN32
|
2013-12-19 17:10:14 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2018-09-02 13:49:23 +00:00
|
|
|
/**
|
|
|
|
* cpu_features_get_time_usec:
|
|
|
|
*
|
|
|
|
* Gets time in microseconds.
|
|
|
|
*
|
|
|
|
* Returns: time in microseconds.
|
|
|
|
**/
|
|
|
|
int64_t get_time_usec(void)
|
|
|
|
{
|
2019-08-25 17:29:56 +00:00
|
|
|
#ifdef _WIN32
|
2018-09-02 13:49:23 +00:00
|
|
|
static LARGE_INTEGER freq;
|
|
|
|
LARGE_INTEGER count;
|
|
|
|
|
|
|
|
/* Frequency is guaranteed to not change. */
|
|
|
|
if (!freq.QuadPart && !QueryPerformanceFrequency(&freq))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!QueryPerformanceCounter(&count))
|
|
|
|
return 0;
|
|
|
|
return count.QuadPart * 1000000 / freq.QuadPart;
|
2019-08-25 16:38:36 +00:00
|
|
|
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(__ANDROID__) || defined(__MACH__) || HOST_OS==OS_LINUX
|
2018-09-02 13:49:23 +00:00
|
|
|
struct timespec tv = {0};
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
|
|
|
|
return 0;
|
|
|
|
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
|
|
|
|
#elif defined(EMSCRIPTEN)
|
|
|
|
return emscripten_get_now() * 1000;
|
|
|
|
#elif defined(__mips__) || defined(DJGPP)
|
|
|
|
struct timeval tv;
|
|
|
|
gettimeofday(&tv,NULL);
|
|
|
|
return (1000000 * tv.tv_sec + tv.tv_usec);
|
|
|
|
#else
|
|
|
|
#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue."
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-02-17 23:25:06 +00:00
|
|
|
int GetFile(char *szFileName, char *szParse /* = 0 */, u32 flags /* = 0 */)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-03-13 18:59:59 +00:00
|
|
|
cfgLoadStr("config", "image", szFileName, "");
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-03-13 18:59:59 +00:00
|
|
|
return szFileName[0] != '\0' ? 1 : 0;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s32 plugins_Init()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (s32 rv = libPvr_Init())
|
|
|
|
return rv;
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
#ifndef TARGET_DISPFRAME
|
2013-12-19 17:10:14 +00:00
|
|
|
if (s32 rv = libGDR_Init())
|
|
|
|
return rv;
|
2019-02-25 16:52:53 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
if (s32 rv = libAICA_Init())
|
|
|
|
return rv;
|
2018-08-20 11:36:34 +00:00
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
if (s32 rv = libARM_Init())
|
|
|
|
return rv;
|
2018-08-20 11:36:34 +00:00
|
|
|
|
2019-09-01 21:10:04 +00:00
|
|
|
return 0;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void plugins_Term()
|
|
|
|
{
|
|
|
|
//term all plugins
|
|
|
|
libARM_Term();
|
|
|
|
libAICA_Term();
|
|
|
|
libGDR_Term();
|
|
|
|
libPvr_Term();
|
|
|
|
}
|
|
|
|
|
2019-07-10 15:25:11 +00:00
|
|
|
void plugins_Reset(bool hard)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-10 15:25:11 +00:00
|
|
|
libPvr_Reset(hard);
|
|
|
|
libGDR_Reset(hard);
|
|
|
|
libAICA_Reset(hard);
|
|
|
|
libARM_Reset(hard);
|
2013-12-19 17:10:14 +00:00
|
|
|
//libExtDevice_Reset(Manual);
|
|
|
|
}
|
|
|
|
|
2018-05-22 13:20:37 +00:00
|
|
|
void LoadSpecialSettings()
|
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
2019-03-20 15:31:12 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
char prod_id[sizeof(ip_meta.product_number) + 1] = {0};
|
|
|
|
memcpy(prod_id, ip_meta.product_number, sizeof(ip_meta.product_number));
|
|
|
|
|
|
|
|
NOTICE_LOG(BOOT, "Game ID is [%s]", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
rtt_to_buffer_game = false;
|
|
|
|
safemode_game = false;
|
|
|
|
tr_poly_depth_mask_game = false;
|
|
|
|
extra_depth_game = false;
|
|
|
|
disable_vmem32_game = false;
|
2019-09-01 14:35:12 +00:00
|
|
|
forced_game_region = -1;
|
|
|
|
forced_game_cable = -1;
|
2019-07-09 21:52:19 +00:00
|
|
|
|
2019-09-01 14:35:12 +00:00
|
|
|
if (ip_meta.isWindowsCE() || settings.dreamcast.ForceWindowsCE
|
|
|
|
|| !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game");
|
2019-09-27 12:15:29 +00:00
|
|
|
settings.rend.ExtraDepthScale = 0.1; // taxi 2 needs 0.01 for FMV (amd, per-tri)
|
2019-07-09 21:52:19 +00:00
|
|
|
extra_depth_game = true;
|
|
|
|
settings.dreamcast.FullMMU = true;
|
|
|
|
settings.aica.NoBatch = true;
|
|
|
|
}
|
2019-03-20 15:31:12 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
// Tony Hawk's Pro Skater 2
|
2019-09-01 14:35:12 +00:00
|
|
|
if (!strncmp("T13008D", prod_id, 7) || !strncmp("T13006N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Tony Hawk's Pro Skater 1
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T40205N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Tony Hawk's Skateboarding
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T40204D", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Skies of Arcadia
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("MK-51052", prod_id, 8)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Eternal Arcadia (JP)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("HDR-0076", prod_id, 8)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Flag to Flag (US)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("MK-51007", prod_id, 8)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Super Speed Racing (JP)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("HDR-0013", prod_id, 8)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Yu Suzuki Game Works Vol. 1
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("6108099", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// L.O.L
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T2106M", prod_id, 6)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Miss Moonlight
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T18702M", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Tom Clancy's Rainbow Six (US)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T40401N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Tom Clancy's Rainbow Six incl. Eagle Watch Missions (EU)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T-45001D05", prod_id, 10))
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Enabling render to texture buffer for game %s", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
settings.rend.RenderToTextureBuffer = 1;
|
|
|
|
rtt_to_buffer_game = true;
|
|
|
|
}
|
2019-09-01 14:35:12 +00:00
|
|
|
if (!strncmp("HDR-0176", prod_id, 8) || !strncmp("RDC-0057", prod_id, 8))
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
// Cosmic Smash
|
|
|
|
settings.rend.TranslucentPolygonDepthMask = 1;
|
|
|
|
tr_poly_depth_mask_game = true;
|
|
|
|
}
|
|
|
|
// Demolition Racer
|
2019-09-01 14:35:12 +00:00
|
|
|
if (!strncmp("T15112N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Ducati World - Racing Challenge (NTSC)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T-8113N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Ducati World (PAL)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T-8121D-50", prod_id, 10))
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
settings.dynarec.safemode = 1;
|
|
|
|
safemode_game = true;
|
|
|
|
}
|
|
|
|
// NHL 2K2
|
2019-09-01 14:35:12 +00:00
|
|
|
if (!strncmp("MK-51182", prod_id, 8))
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id);
|
2019-09-24 21:59:36 +00:00
|
|
|
settings.rend.ExtraDepthScale = 1000000; // Mali needs 1M, 10K is enough for others
|
2019-07-09 21:52:19 +00:00
|
|
|
extra_depth_game = true;
|
|
|
|
}
|
|
|
|
// Re-Volt (US, EU)
|
2019-09-01 14:35:12 +00:00
|
|
|
else if (!strncmp("T-8109N", prod_id, 7) || !strncmp("T8107D 50", prod_id, 10))
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
settings.rend.ExtraDepthScale = 100;
|
|
|
|
extra_depth_game = true;
|
|
|
|
}
|
|
|
|
// Super Producers
|
2019-09-01 14:35:12 +00:00
|
|
|
if (!strncmp("T14303M", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Giant Killers
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T45401D 50", prod_id, 10)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Wild Metal (US)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T42101N 00", prod_id, 10)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Wild Metal (EU)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T40501D-50", prod_id, 10)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Resident Evil 2 (US)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T1205N", prod_id, 6)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Resident Evil 2 (EU)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T7004D 50", prod_id, 10)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Rune Jade
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T14304M", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Marionette Company
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T5202M", prod_id, 6)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Marionette Company 2
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T5203M", prod_id, 6)
|
2019-07-09 21:52:19 +00:00
|
|
|
// Maximum Pool (for online support)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T11010N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// StarLancer (US) (for online support)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T40209N", prod_id, 7)
|
2019-07-09 21:52:19 +00:00
|
|
|
// StarLancer (EU) (for online support)
|
2019-09-01 14:35:12 +00:00
|
|
|
|| !strncmp("T17723D 05", prod_id, 10)
|
2019-07-09 21:52:19 +00:00
|
|
|
)
|
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", prod_id);
|
2019-07-09 21:52:19 +00:00
|
|
|
settings.dynarec.disable_vmem32 = true;
|
|
|
|
disable_vmem32_game = true;
|
|
|
|
}
|
2019-09-01 14:35:12 +00:00
|
|
|
std::string areas(ip_meta.area_symbols, sizeof(ip_meta.area_symbols));
|
|
|
|
bool region_usa = areas.find('U') != std::string::npos;
|
|
|
|
bool region_eu = areas.find('E') != std::string::npos;
|
|
|
|
bool region_japan = areas.find('J') != std::string::npos;
|
|
|
|
if (region_usa || region_eu || region_japan)
|
|
|
|
{
|
|
|
|
switch (settings.dreamcast.region)
|
|
|
|
{
|
|
|
|
case 0: // Japan
|
|
|
|
if (!region_japan)
|
|
|
|
{
|
|
|
|
NOTICE_LOG(BOOT, "Japan region not supported. Using %s instead", region_usa ? "USA" : "Europe");
|
|
|
|
settings.dreamcast.region = region_usa ? 1 : 2;
|
|
|
|
forced_game_region = settings.dreamcast.region;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1: // USA
|
|
|
|
if (!region_usa)
|
|
|
|
{
|
|
|
|
NOTICE_LOG(BOOT, "USA region not supported. Using %s instead", region_eu ? "Europe" : "Japan");
|
|
|
|
settings.dreamcast.region = region_eu ? 2 : 0;
|
|
|
|
forced_game_region = settings.dreamcast.region;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2: // Europe
|
|
|
|
if (!region_eu)
|
|
|
|
{
|
|
|
|
NOTICE_LOG(BOOT, "Europe region not supported. Using %s instead", region_usa ? "USA" : "Japan");
|
|
|
|
settings.dreamcast.region = region_usa ? 1 : 0;
|
|
|
|
forced_game_region = settings.dreamcast.region;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: // Default
|
|
|
|
if (region_usa)
|
|
|
|
settings.dreamcast.region = 1;
|
|
|
|
else if (region_eu)
|
|
|
|
settings.dreamcast.region = 2;
|
|
|
|
else
|
|
|
|
settings.dreamcast.region = 0;
|
|
|
|
forced_game_region = settings.dreamcast.region;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
WARN_LOG(BOOT, "No region specified in IP.BIN");
|
|
|
|
if (settings.dreamcast.cable <= 1 && !ip_meta.supportsVGA())
|
|
|
|
{
|
|
|
|
NOTICE_LOG(BOOT, "Game doesn't support VGA. Using TV Composite instead");
|
|
|
|
settings.dreamcast.cable = 3;
|
|
|
|
forced_game_cable = settings.dreamcast.cable;
|
|
|
|
}
|
2019-07-08 14:31:50 +00:00
|
|
|
}
|
2019-07-09 21:52:19 +00:00
|
|
|
else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
2019-05-09 19:47:01 +00:00
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
NOTICE_LOG(BOOT, "Game ID is [%s]", naomi_game_id);
|
2019-04-05 20:22:46 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", naomi_game_id);
|
|
|
|
settings.dynarec.safemode = 1;
|
|
|
|
safemode_game = true;
|
|
|
|
}
|
|
|
|
if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id);
|
|
|
|
settings.rend.ExtraDepthScale = 1e26;
|
|
|
|
extra_depth_game = true;
|
|
|
|
}
|
|
|
|
if (!strcmp("DYNAMIC GOLF", naomi_game_id)
|
|
|
|
|| !strcmp("SHOOTOUT POOL", naomi_game_id)
|
|
|
|
|| !strcmp("OUTTRIGGER JAPAN", naomi_game_id)
|
|
|
|
|| !strcmp("CRACKIN'DJ ver JAPAN", naomi_game_id)
|
|
|
|
|| !strcmp("CRACKIN'DJ PART2 ver JAPAN", naomi_game_id)
|
|
|
|
|| !strcmp("KICK '4' CASH", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 2;
|
|
|
|
}
|
|
|
|
else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi
|
|
|
|
|| !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling 4-player setup for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 1;
|
|
|
|
}
|
|
|
|
else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id)
|
|
|
|
|| !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 3;
|
|
|
|
}
|
|
|
|
else if (!strcmp("RINGOUT 4X4 JAPAN", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 4;
|
|
|
|
}
|
|
|
|
else if (!strcmp("NINJA ASSAULT", naomi_game_id)
|
|
|
|
|| !strcmp(naomi_game_id, "Sports Shooting USA") // AW
|
|
|
|
|| !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE")) // AW
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling lightgun setup for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 5;
|
|
|
|
}
|
|
|
|
else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
|
|
|
settings.input.JammaSetup = 7;
|
|
|
|
}
|
|
|
|
if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id))
|
|
|
|
{
|
|
|
|
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id);
|
|
|
|
settings.rend.TranslucentPolygonDepthMask = true;
|
|
|
|
tr_poly_depth_mask_game = true;
|
|
|
|
}
|
2018-10-21 00:48:24 +00:00
|
|
|
}
|
2018-05-22 13:20:37 +00:00
|
|
|
}
|
|
|
|
|
2019-07-10 15:25:11 +00:00
|
|
|
void dc_reset(bool hard)
|
2018-10-28 11:35:19 +00:00
|
|
|
{
|
2019-07-10 15:25:11 +00:00
|
|
|
plugins_Reset(hard);
|
|
|
|
mem_Reset(hard);
|
2018-10-28 11:35:19 +00:00
|
|
|
|
2019-07-10 15:25:11 +00:00
|
|
|
sh4_cpu.Reset(hard);
|
2018-10-28 11:35:19 +00:00
|
|
|
}
|
|
|
|
|
2019-03-26 10:54:03 +00:00
|
|
|
static bool reset_requested;
|
2019-02-17 23:25:06 +00:00
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
int reicast_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);
|
|
|
|
#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
|
|
|
}
|
2019-02-25 16:52:53 +00:00
|
|
|
InitSettings();
|
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();
|
2019-02-25 16:52:53 +00:00
|
|
|
LoadSettings(false);
|
2019-06-30 19:06:46 +00:00
|
|
|
}
|
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();
|
|
|
|
|
|
|
|
// Needed to avoid crash calling dc_is_running() in gui
|
|
|
|
Get_Sh4Interpreter(&sh4_cpu);
|
|
|
|
sh4_cpu.Init();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
void set_platform(int platform)
|
|
|
|
{
|
2019-08-15 08:48:39 +00:00
|
|
|
if (VRAM_SIZE != 0)
|
|
|
|
_vmem_unprotect_vram(0, VRAM_SIZE);
|
2019-07-09 21:52:19 +00:00
|
|
|
switch (platform)
|
|
|
|
{
|
|
|
|
case DC_PLATFORM_DREAMCAST:
|
|
|
|
settings.platform.ram_size = 16 * 1024 * 1024;
|
|
|
|
settings.platform.vram_size = 8 * 1024 * 1024;
|
|
|
|
settings.platform.aram_size = 2 * 1024 * 1024;
|
|
|
|
settings.platform.bios_size = 2 * 1024 * 1024;
|
|
|
|
settings.platform.flash_size = 128 * 1024;
|
|
|
|
settings.platform.bbsram_size = 0;
|
|
|
|
break;
|
|
|
|
case DC_PLATFORM_NAOMI:
|
|
|
|
settings.platform.ram_size = 32 * 1024 * 1024;
|
|
|
|
settings.platform.vram_size = 16 * 1024 * 1024;
|
|
|
|
settings.platform.aram_size = 8 * 1024 * 1024;
|
|
|
|
settings.platform.bios_size = 2 * 1024 * 1024;
|
|
|
|
settings.platform.flash_size = 0;
|
|
|
|
settings.platform.bbsram_size = 32 * 1024;
|
|
|
|
break;
|
|
|
|
case DC_PLATFORM_ATOMISWAVE:
|
|
|
|
settings.platform.ram_size = 16 * 1024 * 1024;
|
|
|
|
settings.platform.vram_size = 8 * 1024 * 1024;
|
|
|
|
settings.platform.aram_size = 8 * 1024 * 1024;
|
|
|
|
settings.platform.bios_size = 128 * 1024;
|
|
|
|
settings.platform.flash_size = 0;
|
|
|
|
settings.platform.bbsram_size = 128 * 1024;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
die("Unsupported platform");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
settings.platform.system = platform;
|
|
|
|
settings.platform.ram_mask = settings.platform.ram_size - 1;
|
|
|
|
settings.platform.vram_mask = settings.platform.vram_size - 1;
|
|
|
|
settings.platform.aram_mask = settings.platform.aram_size - 1;
|
|
|
|
_vmem_init_mappings();
|
|
|
|
}
|
|
|
|
|
2019-11-04 20:37:16 +00:00
|
|
|
void dc_init()
|
2019-02-25 16:52:53 +00:00
|
|
|
{
|
2019-07-08 16:10:43 +00:00
|
|
|
static bool init_done;
|
2019-02-25 16:52:53 +00:00
|
|
|
|
|
|
|
if (init_done)
|
2019-07-11 17:23:21 +00:00
|
|
|
return;
|
2019-07-09 21:52:19 +00:00
|
|
|
|
|
|
|
// Default platform
|
|
|
|
set_platform(DC_PLATFORM_DREAMCAST);
|
|
|
|
|
2019-07-11 17:23:21 +00:00
|
|
|
plugins_Init();
|
|
|
|
|
2015-07-25 06:39:35 +00:00
|
|
|
#if FEAT_SHREC != DYNAREC_NONE
|
2018-11-11 22:49:41 +00:00
|
|
|
Get_Sh4Recompiler(&sh4_cpu);
|
|
|
|
sh4_cpu.Init(); // Also initialize the interpreter
|
2013-12-19 17:10:14 +00:00
|
|
|
if(settings.dynarec.Enable)
|
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(DYNAREC, "Using Recompiler");
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
Get_Sh4Interpreter(&sh4_cpu);
|
2018-11-11 22:49:41 +00:00
|
|
|
sh4_cpu.Init();
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(INTERPRETER, "Using Interpreter");
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2018-08-20 16:28:16 +00:00
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
mem_Init();
|
2019-09-19 09:49:19 +00:00
|
|
|
reios_init();
|
2019-07-08 16:10:43 +00:00
|
|
|
|
|
|
|
init_done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool game_started;
|
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
static int get_game_platform(const char *path)
|
|
|
|
{
|
|
|
|
if (path == NULL)
|
|
|
|
// Dreamcast BIOS
|
|
|
|
return DC_PLATFORM_DREAMCAST;
|
|
|
|
|
|
|
|
const char *dot = strrchr(path, '.');
|
|
|
|
if (dot == NULL)
|
|
|
|
return DC_PLATFORM_DREAMCAST; // unknown
|
|
|
|
if (!stricmp(dot, ".zip") || !stricmp(dot, ".7z"))
|
|
|
|
return naomi_cart_GetPlatform(path);
|
2019-08-15 08:48:39 +00:00
|
|
|
if (!stricmp(dot, ".bin") || !stricmp(dot, ".dat") || !stricmp(dot, ".lst"))
|
2019-07-09 21:52:19 +00:00
|
|
|
return DC_PLATFORM_NAOMI;
|
|
|
|
|
|
|
|
return DC_PLATFORM_DREAMCAST;
|
|
|
|
}
|
|
|
|
|
2019-07-11 17:23:21 +00:00
|
|
|
void dc_start_game(const char *path)
|
2019-07-08 16:10:43 +00:00
|
|
|
{
|
|
|
|
if (path != NULL)
|
|
|
|
cfgSetVirtual("config", "image", path);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-11 17:23:21 +00:00
|
|
|
dc_init();
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
set_platform(get_game_platform(path));
|
|
|
|
mem_map_default();
|
|
|
|
|
2019-07-08 16:10:43 +00:00
|
|
|
InitSettings();
|
|
|
|
dc_reset(true);
|
|
|
|
LoadSettings(false);
|
2019-07-24 16:53:09 +00:00
|
|
|
|
|
|
|
std::string data_path = get_readonly_data_path(DATA_PATH);
|
2019-09-19 09:49:19 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
2019-07-08 16:10:43 +00:00
|
|
|
{
|
2019-09-19 09:49:19 +00:00
|
|
|
if (settings.bios.UseReios || !LoadRomFiles(data_path))
|
2019-07-08 16:10:43 +00:00
|
|
|
{
|
2019-08-13 15:12:29 +00:00
|
|
|
if (!LoadHle(data_path))
|
|
|
|
throw ReicastException("Failed to initialize HLE BIOS");
|
|
|
|
|
|
|
|
NOTICE_LOG(BOOT, "Did not load BIOS, using reios");
|
|
|
|
}
|
2019-07-08 16:10:43 +00:00
|
|
|
}
|
2019-09-19 09:49:19 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
LoadRomFiles(data_path);
|
|
|
|
}
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
2019-07-08 16:10:43 +00:00
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
mcfg_CreateDevices();
|
|
|
|
|
|
|
|
if (path == NULL)
|
|
|
|
{
|
|
|
|
// Boot BIOS
|
|
|
|
TermDrive();
|
|
|
|
InitDrive();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (DiscSwap())
|
|
|
|
LoadCustom();
|
|
|
|
}
|
2019-09-01 14:35:12 +00:00
|
|
|
FixUpFlash();
|
2019-07-08 16:10:43 +00:00
|
|
|
}
|
2019-07-09 21:52:19 +00:00
|
|
|
else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
2019-07-08 16:10:43 +00:00
|
|
|
{
|
2019-07-11 17:23:21 +00:00
|
|
|
naomi_cart_LoadRom(path);
|
2019-07-09 21:52:19 +00:00
|
|
|
LoadCustom();
|
|
|
|
if (settings.platform.system == DC_PLATFORM_NAOMI)
|
|
|
|
mcfg_CreateNAOMIJamma();
|
|
|
|
else if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
|
|
|
mcfg_CreateAtomisWaveControllers();
|
2019-07-08 16:10:43 +00:00
|
|
|
}
|
2019-09-24 21:59:36 +00:00
|
|
|
if (cheatManager.Reset())
|
|
|
|
{
|
|
|
|
gui_display_notification("Widescreen cheat activated", 1000);
|
|
|
|
if (saved_screen_stretching == -1)
|
|
|
|
saved_screen_stretching = settings.rend.ScreenStretching;
|
|
|
|
settings.rend.ScreenStretching = 133; // 4:3 -> 16:9
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (saved_screen_stretching != -1)
|
|
|
|
{
|
|
|
|
settings.rend.ScreenStretching = saved_screen_stretching;
|
|
|
|
saved_screen_stretching = -1;
|
|
|
|
}
|
|
|
|
}
|
2019-09-27 12:15:29 +00:00
|
|
|
fast_forward_mode = false;
|
2019-02-25 16:52:53 +00:00
|
|
|
game_started = true;
|
|
|
|
dc_resume();
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
2018-09-02 13:49:23 +00:00
|
|
|
bool dc_is_running()
|
|
|
|
{
|
|
|
|
return sh4_cpu.IsCpuRunning();
|
|
|
|
}
|
|
|
|
|
2018-10-02 16:29:29 +00:00
|
|
|
#ifndef TARGET_DISPFRAME
|
2019-02-25 16:52:53 +00:00
|
|
|
void* dc_run(void*)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-03-03 23:32:15 +00:00
|
|
|
#if FEAT_HAS_NIXPROF
|
|
|
|
install_prof_handler(0);
|
|
|
|
#endif
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
InitAudio();
|
|
|
|
|
|
|
|
if (settings.dynarec.Enable)
|
|
|
|
{
|
|
|
|
Get_Sh4Recompiler(&sh4_cpu);
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(DYNAREC, "Using Recompiler");
|
2019-02-25 16:52:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Get_Sh4Interpreter(&sh4_cpu);
|
2019-06-30 19:06:46 +00:00
|
|
|
INFO_LOG(DYNAREC, "Using Interpreter");
|
2019-02-25 16:52:53 +00:00
|
|
|
}
|
2019-03-26 10:54:03 +00:00
|
|
|
do {
|
|
|
|
reset_requested = false;
|
|
|
|
|
2019-06-21 11:33:55 +00:00
|
|
|
sh4_cpu.Run();
|
2019-03-26 10:54:03 +00:00
|
|
|
|
2019-07-24 16:24:58 +00:00
|
|
|
SaveRomFiles(get_writable_data_path(DATA_PATH));
|
2019-03-26 10:54:03 +00:00
|
|
|
if (reset_requested)
|
|
|
|
{
|
2019-07-08 14:31:50 +00:00
|
|
|
dc_reset(false);
|
2019-03-26 10:54:03 +00:00
|
|
|
}
|
|
|
|
} while (reset_requested);
|
2019-02-25 16:52:53 +00:00
|
|
|
|
|
|
|
TermAudio();
|
|
|
|
|
|
|
|
return NULL;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2018-07-16 15:19:45 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
void dc_term()
|
|
|
|
{
|
|
|
|
sh4_cpu.Term();
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
|
|
|
|
naomi_cart_Close();
|
2013-12-19 17:10:14 +00:00
|
|
|
plugins_Term();
|
2019-07-01 08:28:31 +00:00
|
|
|
mem_Term();
|
2013-12-19 17:10:14 +00:00
|
|
|
_vmem_release();
|
|
|
|
|
2018-10-29 15:31:44 +00:00
|
|
|
mcfg_DestroyDevices();
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
SaveSettings();
|
|
|
|
}
|
|
|
|
|
2018-07-23 17:47:24 +00:00
|
|
|
void dc_stop()
|
|
|
|
{
|
2019-02-25 16:52:53 +00:00
|
|
|
sh4_cpu.Stop();
|
|
|
|
rend_cancel_emu_wait();
|
|
|
|
emu_thread.WaitToEnd();
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
2019-03-26 10:54:03 +00:00
|
|
|
// Called on the emulator thread for soft reset
|
|
|
|
void dc_request_reset()
|
|
|
|
{
|
|
|
|
reset_requested = true;
|
|
|
|
sh4_cpu.Stop();
|
|
|
|
}
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
void dc_exit()
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2019-02-25 16:52:53 +00:00
|
|
|
dc_stop();
|
|
|
|
rend_stop_renderer();
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
void InitSettings()
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.dynarec.Enable = true;
|
|
|
|
settings.dynarec.idleskip = true;
|
|
|
|
settings.dynarec.unstable_opt = false;
|
|
|
|
settings.dynarec.safemode = true;
|
2019-04-29 16:23:00 +00:00
|
|
|
settings.dynarec.disable_vmem32 = false;
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.dreamcast.cable = 3; // TV composite
|
|
|
|
settings.dreamcast.region = 3; // default
|
|
|
|
settings.dreamcast.broadcast = 4; // default
|
|
|
|
settings.dreamcast.language = 6; // default
|
2019-03-17 21:59:18 +00:00
|
|
|
settings.dreamcast.FullMMU = false;
|
2019-08-28 18:47:47 +00:00
|
|
|
settings.dreamcast.ForceWindowsCE = false;
|
2019-09-10 19:56:58 +00:00
|
|
|
settings.dreamcast.HideLegacyNaomiRoms = true;
|
2019-05-15 12:00:36 +00:00
|
|
|
settings.aica.DSPEnabled = false;
|
2019-05-20 17:12:28 +00:00
|
|
|
settings.aica.LimitFPS = LimitFPSEnabled;
|
2019-05-15 12:00:36 +00:00
|
|
|
settings.aica.NoBatch = false;
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.aica.NoSound = false;
|
2019-04-05 20:22:46 +00:00
|
|
|
settings.audio.backend = "auto";
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.rend.UseMipmaps = true;
|
|
|
|
settings.rend.WideScreen = false;
|
|
|
|
settings.rend.ShowFPS = false;
|
|
|
|
settings.rend.RenderToTextureBuffer = false;
|
|
|
|
settings.rend.RenderToTextureUpscale = 1;
|
|
|
|
settings.rend.TranslucentPolygonDepthMask = false;
|
|
|
|
settings.rend.ModifierVolumes = true;
|
|
|
|
settings.rend.Clipping = true;
|
|
|
|
settings.rend.TextureUpscale = 1;
|
|
|
|
settings.rend.MaxFilteredTextureSize = 256;
|
|
|
|
settings.rend.ExtraDepthScale = 1.f;
|
|
|
|
settings.rend.CustomTextures = false;
|
|
|
|
settings.rend.DumpTextures = false;
|
2019-02-18 23:49:24 +00:00
|
|
|
settings.rend.ScreenScaling = 100;
|
2019-04-07 22:21:06 +00:00
|
|
|
settings.rend.ScreenStretching = 100;
|
2019-04-04 17:26:15 +00:00
|
|
|
settings.rend.Fog = true;
|
2019-04-08 13:54:37 +00:00
|
|
|
settings.rend.FloatVMUs = false;
|
2019-04-09 13:18:48 +00:00
|
|
|
settings.rend.Rotate90 = false;
|
2019-05-17 17:48:25 +00:00
|
|
|
settings.rend.PerStripSorting = false;
|
2019-09-09 12:58:53 +00:00
|
|
|
settings.rend.DelayFrameSwapping = false;
|
2019-09-24 21:59:36 +00:00
|
|
|
settings.rend.WidescreenGameHacks = false;
|
2019-02-16 13:25:54 +00:00
|
|
|
|
|
|
|
settings.pvr.ta_skip = 0;
|
|
|
|
settings.pvr.rend = 0;
|
|
|
|
|
|
|
|
settings.pvr.MaxThreads = 3;
|
|
|
|
settings.pvr.SynchronousRender = true;
|
|
|
|
|
|
|
|
settings.debug.SerialConsole = false;
|
|
|
|
|
2019-07-30 17:04:51 +00:00
|
|
|
settings.bios.UseReios = false;
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.reios.ElfFile = "";
|
|
|
|
|
|
|
|
settings.validate.OpenGlChecks = false;
|
|
|
|
|
|
|
|
settings.input.MouseSensitivity = 100;
|
|
|
|
settings.input.JammaSetup = 0;
|
2019-03-04 23:54:01 +00:00
|
|
|
settings.input.VirtualGamepadVibration = 20;
|
2019-02-16 13:25:54 +00:00
|
|
|
for (int i = 0; i < MAPLE_PORTS; i++)
|
|
|
|
{
|
|
|
|
settings.input.maple_devices[i] = i == 0 ? MDT_SegaController : MDT_None;
|
|
|
|
settings.input.maple_expansion_devices[i][0] = i == 0 ? MDT_SegaVMU : MDT_None;
|
|
|
|
settings.input.maple_expansion_devices[i][1] = i == 0 ? MDT_SegaVMU : MDT_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if SUPPORT_DISPMANX
|
|
|
|
settings.dispmanx.Width = 640;
|
|
|
|
settings.dispmanx.Height = 480;
|
|
|
|
settings.dispmanx.Keep_Aspect = true;
|
|
|
|
#endif
|
|
|
|
|
2019-08-25 16:38:36 +00:00
|
|
|
#if (HOST_OS != OS_LINUX || defined(__ANDROID__) || defined(TARGET_PANDORA))
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.aica.BufferSize = 2048;
|
|
|
|
#else
|
|
|
|
settings.aica.BufferSize = 1024;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_OMX
|
|
|
|
settings.omx.Audio_Latency = 100;
|
|
|
|
settings.omx.Audio_HDMI = true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoadSettings(bool game_specific)
|
|
|
|
{
|
|
|
|
const char *config_section = game_specific ? cfgGetGameId() : "config";
|
|
|
|
const char *input_section = game_specific ? cfgGetGameId() : "input";
|
2019-04-05 20:22:46 +00:00
|
|
|
const char *audio_section = game_specific ? cfgGetGameId() : "audio";
|
2019-02-16 13:25:54 +00:00
|
|
|
|
|
|
|
settings.dynarec.Enable = cfgLoadBool(config_section, "Dynarec.Enabled", settings.dynarec.Enable);
|
|
|
|
settings.dynarec.idleskip = cfgLoadBool(config_section, "Dynarec.idleskip", settings.dynarec.idleskip);
|
|
|
|
settings.dynarec.unstable_opt = cfgLoadBool(config_section, "Dynarec.unstable-opt", settings.dynarec.unstable_opt);
|
|
|
|
settings.dynarec.safemode = cfgLoadBool(config_section, "Dynarec.safe-mode", settings.dynarec.safemode);
|
2019-04-29 16:23:00 +00:00
|
|
|
settings.dynarec.disable_vmem32 = cfgLoadBool(config_section, "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32);
|
2015-08-11 22:58:50 +00:00
|
|
|
//disable_nvmem can't be loaded, because nvmem init is before cfg load
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.dreamcast.cable = cfgLoadInt(config_section, "Dreamcast.Cable", settings.dreamcast.cable);
|
|
|
|
settings.dreamcast.region = cfgLoadInt(config_section, "Dreamcast.Region", settings.dreamcast.region);
|
|
|
|
settings.dreamcast.broadcast = cfgLoadInt(config_section, "Dreamcast.Broadcast", settings.dreamcast.broadcast);
|
|
|
|
settings.dreamcast.language = cfgLoadInt(config_section, "Dreamcast.Language", settings.dreamcast.language);
|
2019-03-17 21:59:18 +00:00
|
|
|
settings.dreamcast.FullMMU = cfgLoadBool(config_section, "Dreamcast.FullMMU", settings.dreamcast.FullMMU);
|
2019-08-28 18:47:47 +00:00
|
|
|
settings.dreamcast.ForceWindowsCE = cfgLoadBool(config_section, "Dreamcast.ForceWindowsCE", settings.dreamcast.ForceWindowsCE);
|
|
|
|
if (settings.dreamcast.ForceWindowsCE)
|
2019-06-19 20:52:19 +00:00
|
|
|
settings.aica.NoBatch = true;
|
2019-05-20 17:12:28 +00:00
|
|
|
settings.aica.LimitFPS = (LimitFPSEnum)cfgLoadInt(config_section, "aica.LimitFPS", (int)settings.aica.LimitFPS);
|
2019-05-15 12:00:36 +00:00
|
|
|
settings.aica.DSPEnabled = cfgLoadBool(config_section, "aica.DSPEnabled", settings.aica.DSPEnabled);
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.aica.NoSound = cfgLoadBool(config_section, "aica.NoSound", settings.aica.NoSound);
|
2019-04-05 20:22:46 +00:00
|
|
|
settings.audio.backend = cfgLoadStr(audio_section, "backend", settings.audio.backend.c_str());
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.rend.UseMipmaps = cfgLoadBool(config_section, "rend.UseMipmaps", settings.rend.UseMipmaps);
|
|
|
|
settings.rend.WideScreen = cfgLoadBool(config_section, "rend.WideScreen", settings.rend.WideScreen);
|
|
|
|
settings.rend.ShowFPS = cfgLoadBool(config_section, "rend.ShowFPS", settings.rend.ShowFPS);
|
|
|
|
settings.rend.RenderToTextureBuffer = cfgLoadBool(config_section, "rend.RenderToTextureBuffer", settings.rend.RenderToTextureBuffer);
|
|
|
|
settings.rend.RenderToTextureUpscale = cfgLoadInt(config_section, "rend.RenderToTextureUpscale", settings.rend.RenderToTextureUpscale);
|
|
|
|
settings.rend.TranslucentPolygonDepthMask = cfgLoadBool(config_section, "rend.TranslucentPolygonDepthMask", settings.rend.TranslucentPolygonDepthMask);
|
|
|
|
settings.rend.ModifierVolumes = cfgLoadBool(config_section, "rend.ModifierVolumes", settings.rend.ModifierVolumes);
|
|
|
|
settings.rend.Clipping = cfgLoadBool(config_section, "rend.Clipping", settings.rend.Clipping);
|
|
|
|
settings.rend.TextureUpscale = cfgLoadInt(config_section, "rend.TextureUpscale", settings.rend.TextureUpscale);
|
|
|
|
settings.rend.MaxFilteredTextureSize = cfgLoadInt(config_section,"rend.MaxFilteredTextureSize", settings.rend.MaxFilteredTextureSize);
|
|
|
|
std::string extra_depth_scale_str = cfgLoadStr(config_section,"rend.ExtraDepthScale", "");
|
|
|
|
if (!extra_depth_scale_str.empty())
|
|
|
|
{
|
|
|
|
settings.rend.ExtraDepthScale = atof(extra_depth_scale_str.c_str());
|
|
|
|
if (settings.rend.ExtraDepthScale == 0)
|
|
|
|
settings.rend.ExtraDepthScale = 1.f;
|
|
|
|
}
|
|
|
|
settings.rend.CustomTextures = cfgLoadBool(config_section, "rend.CustomTextures", settings.rend.CustomTextures);
|
|
|
|
settings.rend.DumpTextures = cfgLoadBool(config_section, "rend.DumpTextures", settings.rend.DumpTextures);
|
2019-02-18 23:49:24 +00:00
|
|
|
settings.rend.ScreenScaling = cfgLoadInt(config_section, "rend.ScreenScaling", settings.rend.ScreenScaling);
|
|
|
|
settings.rend.ScreenScaling = min(max(1, settings.rend.ScreenScaling), 100);
|
2019-04-07 22:21:06 +00:00
|
|
|
settings.rend.ScreenStretching = cfgLoadInt(config_section, "rend.ScreenStretching", settings.rend.ScreenStretching);
|
2019-04-04 17:26:15 +00:00
|
|
|
settings.rend.Fog = cfgLoadBool(config_section, "rend.Fog", settings.rend.Fog);
|
2019-04-08 13:54:37 +00:00
|
|
|
settings.rend.FloatVMUs = cfgLoadBool(config_section, "rend.FloatVMUs", settings.rend.FloatVMUs);
|
2019-04-09 13:18:48 +00:00
|
|
|
settings.rend.Rotate90 = cfgLoadBool(config_section, "rend.Rotate90", settings.rend.Rotate90);
|
2019-05-17 17:48:25 +00:00
|
|
|
settings.rend.PerStripSorting = cfgLoadBool(config_section, "rend.PerStripSorting", settings.rend.PerStripSorting);
|
2019-09-09 12:58:53 +00:00
|
|
|
settings.rend.DelayFrameSwapping = cfgLoadBool(config_section, "rend.DelayFrameSwapping", settings.rend.DelayFrameSwapping);
|
2019-09-24 21:59:36 +00:00
|
|
|
settings.rend.WidescreenGameHacks = cfgLoadBool(config_section, "rend.WidescreenGameHacks", settings.rend.WidescreenGameHacks);
|
2019-02-16 13:25:54 +00:00
|
|
|
|
|
|
|
settings.pvr.ta_skip = cfgLoadInt(config_section, "ta.skip", settings.pvr.ta_skip);
|
2019-12-13 11:27:43 +00:00
|
|
|
if (!game_specific)
|
|
|
|
// crashes if switching gl <-> vulkan
|
|
|
|
settings.pvr.rend = cfgLoadInt(config_section, "pvr.rend", settings.pvr.rend);
|
2015-02-25 19:56:58 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.pvr.MaxThreads = cfgLoadInt(config_section, "pvr.MaxThreads", settings.pvr.MaxThreads);
|
|
|
|
settings.pvr.SynchronousRender = cfgLoadBool(config_section, "pvr.SynchronousRendering", settings.pvr.SynchronousRender);
|
2015-08-07 23:36:58 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.debug.SerialConsole = cfgLoadBool(config_section, "Debug.SerialConsoleEnabled", settings.debug.SerialConsole);
|
2015-03-22 00:16:28 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.bios.UseReios = cfgLoadBool(config_section, "bios.UseReios", settings.bios.UseReios);
|
|
|
|
settings.reios.ElfFile = cfgLoadStr(game_specific ? cfgGetGameId() : "reios", "ElfFile", settings.reios.ElfFile.c_str());
|
2015-04-12 20:48:16 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.validate.OpenGlChecks = cfgLoadBool(game_specific ? cfgGetGameId() : "validate", "OpenGlChecks", settings.validate.OpenGlChecks);
|
2018-09-18 07:27:16 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.input.MouseSensitivity = cfgLoadInt(input_section, "MouseSensitivity", settings.input.MouseSensitivity);
|
|
|
|
settings.input.JammaSetup = cfgLoadInt(input_section, "JammaSetup", settings.input.JammaSetup);
|
2019-03-04 23:54:01 +00:00
|
|
|
settings.input.VirtualGamepadVibration = cfgLoadInt(input_section, "VirtualGamepadVibration", settings.input.VirtualGamepadVibration);
|
2019-02-12 10:30:24 +00:00
|
|
|
for (int i = 0; i < MAPLE_PORTS; i++)
|
|
|
|
{
|
|
|
|
char device_name[32];
|
|
|
|
sprintf(device_name, "device%d", i + 1);
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.input.maple_devices[i] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_devices[i]);
|
2019-02-12 10:30:24 +00:00
|
|
|
sprintf(device_name, "device%d.1", i + 1);
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.input.maple_expansion_devices[i][0] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_expansion_devices[i][0]);
|
2019-02-12 10:30:24 +00:00
|
|
|
sprintf(device_name, "device%d.2", i + 1);
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.input.maple_expansion_devices[i][1] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_expansion_devices[i][1]);
|
2019-02-12 10:30:24 +00:00
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2016-03-02 05:48:34 +00:00
|
|
|
#if SUPPORT_DISPMANX
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.dispmanx.Width = cfgLoadInt(game_specific ? cfgGetGameId() : "dispmanx", "width", settings.dispmanx.Width);
|
|
|
|
settings.dispmanx.Height = cfgLoadInt(game_specific ? cfgGetGameId() : "dispmanx", "height", settings.dispmanx.Height);
|
|
|
|
settings.dispmanx.Keep_Aspect = cfgLoadBool(game_specific ? cfgGetGameId() : "dispmanx", "maintain_aspect", settings.dispmanx.Keep_Aspect);
|
2016-03-02 05:48:34 +00:00
|
|
|
#endif
|
|
|
|
|
2019-08-25 16:38:36 +00:00
|
|
|
#if (HOST_OS != OS_LINUX || defined(__ANDROID__) || defined(TARGET_PANDORA))
|
2013-12-19 17:10:14 +00:00
|
|
|
settings.aica.BufferSize=2048;
|
|
|
|
#else
|
|
|
|
settings.aica.BufferSize=1024;
|
|
|
|
#endif
|
|
|
|
|
2016-03-02 05:48:34 +00:00
|
|
|
#if USE_OMX
|
2019-02-16 13:25:54 +00:00
|
|
|
settings.omx.Audio_Latency = cfgLoadInt(game_specific ? cfgGetGameId() : "omx", "audio_latency", settings.omx.Audio_Latency);
|
|
|
|
settings.omx.Audio_HDMI = cfgLoadBool(game_specific ? cfgGetGameId() : "omx", "audio_hdmi", settings.omx.Audio_HDMI);
|
2016-03-02 05:48:34 +00:00
|
|
|
#endif
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
if (!game_specific)
|
|
|
|
{
|
|
|
|
settings.dreamcast.ContentPath.clear();
|
|
|
|
std::string paths = cfgLoadStr(config_section, "Dreamcast.ContentPath", "");
|
|
|
|
std::string::size_type start = 0;
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
std::string::size_type end = paths.find(';', start);
|
|
|
|
if (end == std::string::npos)
|
|
|
|
end = paths.size();
|
|
|
|
if (start != end)
|
|
|
|
settings.dreamcast.ContentPath.push_back(paths.substr(start, end - start));
|
|
|
|
if (end == paths.size())
|
|
|
|
break;
|
|
|
|
start = end + 1;
|
|
|
|
}
|
2019-09-10 19:56:58 +00:00
|
|
|
settings.dreamcast.HideLegacyNaomiRoms = cfgLoadBool(config_section, "Dreamcast.HideLegacyNaomiRoms", settings.dreamcast.HideLegacyNaomiRoms);
|
2019-02-25 16:52:53 +00:00
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
/*
|
|
|
|
//make sure values are valid
|
2018-09-20 15:24:26 +00:00
|
|
|
settings.dreamcast.cable = min(max(settings.dreamcast.cable, 0),3);
|
|
|
|
settings.dreamcast.region = min(max(settings.dreamcast.region, 0),3);
|
|
|
|
settings.dreamcast.broadcast = min(max(settings.dreamcast.broadcast,0),4);
|
2013-12-19 17:10:14 +00:00
|
|
|
*/
|
|
|
|
}
|
2018-08-19 03:40:26 +00:00
|
|
|
|
2019-02-15 19:48:30 +00:00
|
|
|
void LoadCustom()
|
2018-08-19 03:40:26 +00:00
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
char *reios_id;
|
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
|
|
|
{
|
2019-09-01 14:35:12 +00:00
|
|
|
static char _disk_id[sizeof(ip_meta.product_number) + 1];
|
|
|
|
|
|
|
|
reios_disk_id();
|
|
|
|
memcpy(_disk_id, ip_meta.product_number, sizeof(ip_meta.product_number));
|
|
|
|
reios_id = _disk_id;
|
2019-07-09 21:52:19 +00:00
|
|
|
|
|
|
|
char *p = reios_id + strlen(reios_id) - 1;
|
|
|
|
while (p >= reios_id && *p == ' ')
|
|
|
|
*p-- = '\0';
|
|
|
|
if (*p == '\0')
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
|
|
|
{
|
|
|
|
reios_id = naomi_game_id;
|
|
|
|
char *reios_software_name = naomi_game_id;
|
|
|
|
}
|
2018-09-21 15:47:21 +00:00
|
|
|
|
2019-02-16 15:59:27 +00:00
|
|
|
// Default per-game settings
|
|
|
|
LoadSpecialSettings();
|
2018-09-20 15:28:41 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSetGameId(reios_id);
|
2018-08-20 16:28:16 +00:00
|
|
|
|
2019-02-16 15:59:27 +00:00
|
|
|
// Reload per-game settings
|
2019-02-16 13:25:54 +00:00
|
|
|
LoadSettings(true);
|
2018-08-19 03:40:26 +00:00
|
|
|
}
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
void SaveSettings()
|
|
|
|
{
|
2019-10-29 13:34:29 +00:00
|
|
|
cfgSetAutoSave(false);
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "Dynarec.Enabled", settings.dynarec.Enable);
|
2019-09-01 14:35:12 +00:00
|
|
|
if (forced_game_cable == -1 || forced_game_cable != settings.dreamcast.cable)
|
|
|
|
cfgSaveInt("config", "Dreamcast.Cable", settings.dreamcast.cable);
|
|
|
|
if (forced_game_region == -1 || forced_game_region != settings.dreamcast.region)
|
|
|
|
cfgSaveInt("config", "Dreamcast.Region", settings.dreamcast.region);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("config", "Dreamcast.Broadcast", settings.dreamcast.broadcast);
|
2019-08-28 18:47:47 +00:00
|
|
|
cfgSaveBool("config", "Dreamcast.ForceWindowsCE", settings.dreamcast.ForceWindowsCE);
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "Dynarec.idleskip", settings.dynarec.idleskip);
|
|
|
|
cfgSaveBool("config", "Dynarec.unstable-opt", settings.dynarec.unstable_opt);
|
|
|
|
if (!safemode_game || !settings.dynarec.safemode)
|
|
|
|
cfgSaveBool("config", "Dynarec.safe-mode", settings.dynarec.safemode);
|
2019-07-30 17:04:51 +00:00
|
|
|
cfgSaveBool("config", "bios.UseReios", settings.bios.UseReios);
|
2019-03-29 18:23:37 +00:00
|
|
|
|
2019-05-25 16:03:18 +00:00
|
|
|
// if (!disable_vmem32_game || !settings.dynarec.disable_vmem32)
|
|
|
|
// cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language);
|
2019-05-20 17:12:28 +00:00
|
|
|
cfgSaveInt("config", "aica.LimitFPS", (int)settings.aica.LimitFPS);
|
2019-05-15 12:00:36 +00:00
|
|
|
cfgSaveBool("config", "aica.DSPEnabled", settings.aica.DSPEnabled);
|
2019-03-03 23:32:15 +00:00
|
|
|
cfgSaveBool("config", "aica.NoSound", settings.aica.NoSound);
|
2019-04-05 20:22:46 +00:00
|
|
|
cfgSaveStr("audio", "backend", settings.audio.backend.c_str());
|
2019-04-24 19:41:38 +00:00
|
|
|
|
|
|
|
// Write backend specific settings
|
|
|
|
// std::map<std::string, std::map<std::string, std::string>>
|
2019-10-29 13:34:29 +00:00
|
|
|
for (const auto& pair : settings.audio.options)
|
2019-04-24 19:41:38 +00:00
|
|
|
{
|
2019-10-29 13:34:29 +00:00
|
|
|
const std::string& section = pair.first;
|
|
|
|
const auto& options = pair.second;
|
|
|
|
for (const auto& option : options)
|
|
|
|
cfgSaveStr(section.c_str(), option.first.c_str(), option.second.c_str());
|
2019-04-24 19:41:38 +00:00
|
|
|
}
|
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "rend.WideScreen", settings.rend.WideScreen);
|
|
|
|
cfgSaveBool("config", "rend.ShowFPS", settings.rend.ShowFPS);
|
|
|
|
if (!rtt_to_buffer_game || !settings.rend.RenderToTextureBuffer)
|
|
|
|
cfgSaveBool("config", "rend.RenderToTextureBuffer", settings.rend.RenderToTextureBuffer);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("config", "rend.RenderToTextureUpscale", settings.rend.RenderToTextureUpscale);
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "rend.ModifierVolumes", settings.rend.ModifierVolumes);
|
|
|
|
cfgSaveBool("config", "rend.Clipping", settings.rend.Clipping);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("config", "rend.TextureUpscale", settings.rend.TextureUpscale);
|
|
|
|
cfgSaveInt("config", "rend.MaxFilteredTextureSize", settings.rend.MaxFilteredTextureSize);
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "rend.CustomTextures", settings.rend.CustomTextures);
|
|
|
|
cfgSaveBool("config", "rend.DumpTextures", settings.rend.DumpTextures);
|
2019-02-18 23:49:24 +00:00
|
|
|
cfgSaveInt("config", "rend.ScreenScaling", settings.rend.ScreenScaling);
|
2019-09-24 21:59:36 +00:00
|
|
|
if (saved_screen_stretching != -1)
|
|
|
|
cfgSaveInt("config", "rend.ScreenStretching", saved_screen_stretching);
|
|
|
|
else
|
|
|
|
cfgSaveInt("config", "rend.ScreenStretching", settings.rend.ScreenStretching);
|
2019-04-04 17:26:15 +00:00
|
|
|
cfgSaveBool("config", "rend.Fog", settings.rend.Fog);
|
2019-04-08 13:54:37 +00:00
|
|
|
cfgSaveBool("config", "rend.FloatVMUs", settings.rend.FloatVMUs);
|
2019-04-09 13:18:48 +00:00
|
|
|
cfgSaveBool("config", "rend.Rotate90", settings.rend.Rotate90);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("config", "ta.skip", settings.pvr.ta_skip);
|
|
|
|
cfgSaveInt("config", "pvr.rend", settings.pvr.rend);
|
2019-05-17 17:48:25 +00:00
|
|
|
cfgSaveBool("config", "rend.PerStripSorting", settings.rend.PerStripSorting);
|
2019-09-09 12:58:53 +00:00
|
|
|
cfgSaveBool("config", "rend.DelayFrameSwapping", settings.rend.DelayFrameSwapping);
|
2019-09-24 21:59:36 +00:00
|
|
|
cfgSaveBool("config", "rend.WidescreenGameHacks", settings.rend.WidescreenGameHacks);
|
2019-02-06 18:57:13 +00:00
|
|
|
|
|
|
|
cfgSaveInt("config", "pvr.MaxThreads", settings.pvr.MaxThreads);
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "pvr.SynchronousRendering", settings.pvr.SynchronousRender);
|
2019-02-06 18:57:13 +00:00
|
|
|
|
2019-02-16 13:25:54 +00:00
|
|
|
cfgSaveBool("config", "Debug.SerialConsoleEnabled", settings.debug.SerialConsole);
|
2019-02-06 18:57:13 +00:00
|
|
|
cfgSaveInt("input", "MouseSensitivity", settings.input.MouseSensitivity);
|
2019-03-15 18:55:01 +00:00
|
|
|
cfgSaveInt("input", "VirtualGamepadVibration", settings.input.VirtualGamepadVibration);
|
2019-02-12 10:30:24 +00:00
|
|
|
for (int i = 0; i < MAPLE_PORTS; i++)
|
|
|
|
{
|
|
|
|
char device_name[32];
|
|
|
|
sprintf(device_name, "device%d", i + 1);
|
|
|
|
cfgSaveInt("input", device_name, (s32)settings.input.maple_devices[i]);
|
|
|
|
sprintf(device_name, "device%d.1", i + 1);
|
|
|
|
cfgSaveInt("input", device_name, (s32)settings.input.maple_expansion_devices[i][0]);
|
|
|
|
sprintf(device_name, "device%d.2", i + 1);
|
|
|
|
cfgSaveInt("input", device_name, (s32)settings.input.maple_expansion_devices[i][1]);
|
|
|
|
}
|
2019-02-25 16:52:53 +00:00
|
|
|
// FIXME This should never be a game-specific setting
|
|
|
|
std::string paths;
|
2019-06-08 11:04:35 +00:00
|
|
|
for (auto& path : settings.dreamcast.ContentPath)
|
2018-09-23 14:18:35 +00:00
|
|
|
{
|
2019-02-25 16:52:53 +00:00
|
|
|
if (!paths.empty())
|
|
|
|
paths += ";";
|
|
|
|
paths += path;
|
2018-09-23 14:18:35 +00:00
|
|
|
}
|
2019-02-25 16:52:53 +00:00
|
|
|
cfgSaveStr("config", "Dreamcast.ContentPath", paths.c_str());
|
2019-09-10 19:56:58 +00:00
|
|
|
cfgSaveBool("config", "Dreamcast.HideLegacyNaomiRoms", settings.dreamcast.HideLegacyNaomiRoms);
|
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-10-29 13:34:29 +00:00
|
|
|
|
|
|
|
cfgSetAutoSave(true);
|
2019-02-06 18:57:13 +00:00
|
|
|
}
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
void dc_resume()
|
2019-02-06 18:57:13 +00:00
|
|
|
{
|
2019-02-25 16:52:53 +00:00
|
|
|
emu_thread.Start();
|
2018-11-11 22:49:41 +00:00
|
|
|
}
|
|
|
|
|
2019-02-06 18:57:13 +00:00
|
|
|
static void cleanup_serialize(void *data)
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
|
|
|
if ( data != NULL )
|
|
|
|
free(data) ;
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
dc_resume();
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2018-09-20 20:41:10 +00:00
|
|
|
static string get_savestate_file_path()
|
|
|
|
{
|
2019-02-16 13:25:54 +00:00
|
|
|
string state_file = cfgLoadStr("config", "image", "noname.chd");
|
2019-09-07 12:37:39 +00:00
|
|
|
size_t lastindex = state_file.find_last_of('/');
|
2018-09-20 20:41:10 +00:00
|
|
|
if (lastindex != -1)
|
|
|
|
state_file = state_file.substr(lastindex + 1);
|
2019-09-07 12:37:39 +00:00
|
|
|
lastindex = state_file.find_last_of('.');
|
2018-09-20 20:41:10 +00:00
|
|
|
if (lastindex != -1)
|
|
|
|
state_file = state_file.substr(0, lastindex);
|
|
|
|
state_file = state_file + ".state";
|
2019-07-24 16:24:58 +00:00
|
|
|
return get_writable_data_path(DATA_PATH) + state_file;
|
2018-09-20 20:41:10 +00:00
|
|
|
}
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
void dc_savestate()
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2018-09-20 20:41:10 +00:00
|
|
|
string filename;
|
2018-09-02 13:49:23 +00:00
|
|
|
unsigned int total_size = 0 ;
|
|
|
|
void *data = NULL ;
|
|
|
|
void *data_ptr = NULL ;
|
|
|
|
FILE *f ;
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
dc_stop();
|
2018-09-02 13:49:23 +00:00
|
|
|
|
|
|
|
if ( ! dc_serialize(&data, &total_size) )
|
|
|
|
{
|
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);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data = malloc(total_size) ;
|
|
|
|
if ( data == NULL )
|
|
|
|
{
|
2019-06-30 19:06:46 +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);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data_ptr = data ;
|
|
|
|
|
|
|
|
if ( ! dc_serialize(&data_ptr, &total_size) )
|
|
|
|
{
|
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);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2018-09-20 20:41:10 +00:00
|
|
|
filename = get_savestate_file_path();
|
|
|
|
f = 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);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fwrite(data, 1, total_size, f) ;
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
cleanup_serialize(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
|
|
|
}
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
void dc_loadstate()
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2018-09-20 20:41:10 +00:00
|
|
|
string filename;
|
2018-09-02 13:49:23 +00:00
|
|
|
unsigned int total_size = 0 ;
|
|
|
|
void *data = NULL ;
|
|
|
|
void *data_ptr = NULL ;
|
|
|
|
FILE *f ;
|
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
dc_stop();
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2019-02-03 16:56:43 +00:00
|
|
|
filename = get_savestate_file_path();
|
|
|
|
f = fopen(filename.c_str(), "rb") ;
|
|
|
|
|
|
|
|
if ( f == NULL )
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to load state - could not open %s for reading", filename.c_str()) ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Save state not found", 2000);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
2019-02-03 16:56:43 +00:00
|
|
|
fseek(f, 0, SEEK_END);
|
|
|
|
total_size = ftell(f);
|
|
|
|
fseek(f, 0, SEEK_SET);
|
2018-09-02 13:49:23 +00:00
|
|
|
data = malloc(total_size) ;
|
|
|
|
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);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
|
|
|
|
2019-07-12 15:20:43 +00:00
|
|
|
size_t read_size = fread(data, 1, total_size, f) ;
|
2018-09-02 13:49:23 +00:00
|
|
|
fclose(f);
|
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);
|
|
|
|
cleanup_serialize(data) ;
|
|
|
|
return;
|
|
|
|
}
|
2018-09-02 13:49:23 +00:00
|
|
|
|
|
|
|
data_ptr = data ;
|
|
|
|
|
2018-10-29 14:11:34 +00:00
|
|
|
#if FEAT_AREC == DYNAREC_JIT
|
|
|
|
FlushCache();
|
|
|
|
#endif
|
2019-04-15 17:02:10 +00:00
|
|
|
#ifndef NO_MMU
|
|
|
|
mmu_flush_table();
|
|
|
|
#endif
|
2019-06-21 11:17:34 +00:00
|
|
|
bm_Reset();
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2019-07-12 15:20:43 +00:00
|
|
|
u32 unserialized_size = 0;
|
|
|
|
if ( ! dc_unserialize(&data_ptr, &unserialized_size) )
|
2018-09-02 13:49:23 +00:00
|
|
|
{
|
2019-06-30 19:06:46 +00:00
|
|
|
WARN_LOG(SAVESTATE, "Failed to load state - could not unserialize data") ;
|
2019-02-27 22:02:25 +00:00
|
|
|
gui_display_notification("Invalid save state", 2000);
|
2018-09-02 13:49:23 +00:00
|
|
|
cleanup_serialize(data) ;
|
2019-02-25 16:52:53 +00:00
|
|
|
return;
|
2018-09-02 13:49:23 +00:00
|
|
|
}
|
2019-07-12 15:20:43 +00:00
|
|
|
if (unserialized_size != total_size)
|
|
|
|
WARN_LOG(SAVESTATE, "Save state error: read %d bytes but used %d", total_size, unserialized_size);
|
2018-09-02 13:49:23 +00:00
|
|
|
|
2019-03-17 21:59:18 +00:00
|
|
|
mmu_set_state();
|
2019-05-25 16:03:18 +00:00
|
|
|
sh4_cpu.ResetCache();
|
2019-02-06 18:57:13 +00:00
|
|
|
dsp.dyndirty = true;
|
2018-10-29 14:11:34 +00:00
|
|
|
sh4_sched_ffts();
|
|
|
|
CalculateSync();
|
|
|
|
|
|
|
|
cleanup_serialize(data) ;
|
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
|
|
|
}
|