Files
parallel-dc/core/nullDC.cpp

575 lines
14 KiB
C++

// nullDC.cpp : Makes magic cookies
//
//initialse Emu
#include "types.h"
#include "hw/mem/_vmem.h"
#include "hw/mem/vmem32.h"
#include "stdclass.h"
#include "types.h"
#include "hw/flashrom/flashrom.h"
#include "hw/maple/maple_cfg.h"
#include "hw/sh4/sh4_mem.h"
#include "hw/arm7/arm7.h"
#include "hw/naomi/naomi_cart.h"
#include "reios/reios.h"
#include <libretro.h>
extern RomChip sys_rom;
extern SRamChip sys_nvmem_sram;
extern DCFlashChip sys_nvmem_flash;
unsigned FLASH_SIZE;
unsigned BBSRAM_SIZE;
unsigned BIOS_SIZE;
unsigned RAM_SIZE;
unsigned ARAM_SIZE;
unsigned VRAM_SIZE;
unsigned RAM_MASK;
unsigned ARAM_MASK;
unsigned VRAM_MASK;
settings_t settings;
extern char game_dir[1024];
extern char *game_data;
extern bool boot_to_bios;
extern bool reset_requested;
extern void init_mem();
extern void arm_Init();
extern void term_mem();
/*
libndc
//initialise (and parse the command line)
ndc_init(argc,argv);
...
//run a dreamcast slice
//either a frame, or up to 25 ms of emulation
//returns 1 if the frame is ready (fb needs to be flipped -- i'm looking at you android)
ndc_step();
...
//terminate (and free everything)
ndc_term()
*/
int GetFile(char *szFileName, char *szParse=0,u32 flags=0)
{
if (!boot_to_bios)
{
strcpy(szFileName, game_data);
strcpy(settings.imgread.DefaultImage, szFileName);
}
return 1;
}
s32 plugins_Init()
{
if (s32 rv = libPvr_Init())
return rv;
if (s32 rv = libGDR_Init())
return rv;
if (settings.System != DC_PLATFORM_DREAMCAST)
{
if (!naomi_cart_SelectFile())
return -1;
}
if (s32 rv = libAICA_Init())
return rv;
init_mem();
arm_Init();
//if (s32 rv = libExtDevice_Init())
// return rv;
return 0;
}
void plugins_Term(void)
{
//term all plugins
//libExtDevice_Term();
term_mem();
//arm7_Term ?
libAICA_Term();
libGDR_Term();
libPvr_Term();
}
void plugins_Reset(bool hard)
{
libPvr_Reset(hard);
libGDR_Reset(hard);
libAICA_Reset(hard);
arm_Reset();
arm_SetEnabled(false);
//libExtDevice_Reset(Manual);
}
#include "rom_luts.h"
static void LoadSpecialSettingsCPU(void)
{
#if FEAT_SHREC != DYNAREC_NONE
if(settings.dynarec.Enable)
{
Get_Sh4Recompiler(&sh4_cpu);
INFO_LOG(DYNAREC, "Using Recompiler");
}
else
#endif
{
Get_Sh4Interpreter(&sh4_cpu);
INFO_LOG(INTERPRETER, "Using Interpreter");
}
sh4_cpu.Reset(false);
}
static void LoadSpecialSettings(void)
{
unsigned i;
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, "[LUT]: Product number: %s.", prod_id);
if (ip_meta.isWindowsCE() || settings.dreamcast.ForceWinCE
|| !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001
{
NOTICE_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game");
settings.rend.ExtraDepthScale = 0.1;
settings.dreamcast.FullMMU = true;
settings.aica.NoBatch = 1;
}
for (i = 0; i < sizeof(lut_games)/sizeof(lut_games[0]); i++)
{
if (!strncmp(lut_games[i].product_number, prod_id, sizeof(prod_id) - 1))
{
INFO_LOG(BOOT, "[LUT]: Found game in LUT database..");
if (lut_games[i].alpha_sort_mode != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying alpha sort hack.");
settings.pvr.Emulation.AlphaSortMode = lut_games[i].alpha_sort_mode;
}
if (lut_games[i].updatemode_type != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying update mode type hack.");
settings.UpdateModeForced = 1;
}
if (lut_games[i].translucentPolygonDepthMask != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying translucent polygon depth mask hack.");
settings.rend.TranslucentPolygonDepthMask = lut_games[i].translucentPolygonDepthMask;
}
if (lut_games[i].rendertotexturebuffer != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying rendertotexture hack.");
settings.rend.RenderToTextureBuffer = lut_games[i].rendertotexturebuffer;
}
if (lut_games[i].disable_div != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying Disable DIV hack.");
settings.dynarec.ForceDisableDivMatching = settings.dynarec.DisableDivMatching = lut_games[i].disable_div;
}
if (lut_games[i].extra_depth_scale != 1 && settings.rend.AutoExtraDepthScale)
{
NOTICE_LOG(BOOT, "[Hack]: Applying auto extra depth scale.");
settings.rend.ExtraDepthScale = lut_games[i].extra_depth_scale;
}
if (lut_games[i].disable_vmem32 == 1)
{
NOTICE_LOG(BOOT, "[Hack]: Disabling WinCE virtual memory.");
settings.dynarec.disable_vmem32 = true;
}
if (lut_games[i].no_rgb_component == 1)
{
NOTICE_LOG(BOOT, "Disabling RGB component output");
settings.dreamcast.cable = 3; // TV composite
}
break;
}
}
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;
}
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;
}
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;
}
break;
case 3: // Default
if (region_usa)
settings.dreamcast.region = 1;
else if (region_eu)
settings.dreamcast.region = 2;
else
settings.dreamcast.region = 0;
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;
}
}
static void LoadSpecialSettingsNaomi(const char *name)
{
unsigned i;
NOTICE_LOG(BOOT, "[LUT]: Naomi ROM name is: %s.", name);
for (i = 0; i < sizeof(lut_games_naomi)/sizeof(lut_games_naomi[0]); i++)
{
if (strstr(lut_games_naomi[i].product_number, name))
{
INFO_LOG(BOOT, "[LUT]: Found game in LUT database..");
if (lut_games_naomi[i].alpha_sort_mode != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying alpha sort hack.");
settings.pvr.Emulation.AlphaSortMode = lut_games_naomi[i].alpha_sort_mode;
}
if (lut_games_naomi[i].updatemode_type != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying update mode type hack.");
settings.UpdateModeForced = 1;
}
if (lut_games_naomi[i].translucentPolygonDepthMask != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying translucent polygon depth mask hack.");
settings.rend.TranslucentPolygonDepthMask = lut_games_naomi[i].translucentPolygonDepthMask;
}
if (lut_games_naomi[i].rendertotexturebuffer != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying rendertotexture hack.");
settings.rend.RenderToTextureBuffer = lut_games_naomi[i].rendertotexturebuffer;
}
if (lut_games_naomi[i].disable_div != -1)
{
NOTICE_LOG(BOOT, "[Hack]: Applying Disable DIV hack.");
settings.dynarec.ForceDisableDivMatching = settings.dynarec.DisableDivMatching = lut_games_naomi[i].disable_div;
}
if (lut_games_naomi[i].jamma_setup != JVS::Default)
{
NOTICE_LOG(BOOT, "[Hack]: Applying alternate Jamma I/O board setup.");
settings.mapping.JammaSetup = lut_games_naomi[i].jamma_setup;
}
if (lut_games_naomi[i].extra_depth_scale != 1 && settings.rend.AutoExtraDepthScale)
{
NOTICE_LOG(BOOT, "[Hack]: Applying auto extra depth scale.");
settings.rend.ExtraDepthScale = lut_games_naomi[i].extra_depth_scale;
}
if (lut_games_naomi[i].game_inputs != NULL)
{
NOTICE_LOG(BOOT, "Setting custom input descriptors\n");
naomi_game_inputs = lut_games_naomi[i].game_inputs;
}
break;
}
}
}
void dc_prepare_system()
{
BBSRAM_SIZE = (32*1024);
switch (settings.System)
{
case DC_PLATFORM_DREAMCAST:
//DC : 16 mb ram, 8 mb vram, 2 mb aram, 2 mb bios, 128k flash
FLASH_SIZE = (128*1024);
BIOS_SIZE = (2*1024*1024);
RAM_SIZE = (16*1024*1024);
ARAM_SIZE = (2*1024*1024);
VRAM_SIZE = (8*1024*1024);
sys_nvmem_flash.Allocate(FLASH_SIZE);
sys_rom.Allocate(BIOS_SIZE);
break;
case DC_PLATFORM_DEV_UNIT:
//Devkit : 32 mb ram, 8? mb vram, 2? mb aram, 2? mb bios, ? flash
FLASH_SIZE = (128*1024);
BIOS_SIZE = (2*1024*1024);
RAM_SIZE = (32*1024*1024);
ARAM_SIZE = (2*1024*1024);
VRAM_SIZE = (8*1024*1024);
sys_nvmem_flash.Allocate(FLASH_SIZE);
sys_rom.Allocate(BIOS_SIZE);
break;
case DC_PLATFORM_NAOMI:
//Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
BIOS_SIZE = (2*1024*1024);
RAM_SIZE = (32*1024*1024);
ARAM_SIZE = (8*1024*1024);
VRAM_SIZE = (16*1024*1024);
sys_nvmem_sram.Allocate(BBSRAM_SIZE);
sys_rom.Allocate(BIOS_SIZE);
break;
case DC_PLATFORM_NAOMI2:
//Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
BIOS_SIZE = (2*1024*1024);
RAM_SIZE = (32*1024*1024);
ARAM_SIZE = (8*1024*1024);
VRAM_SIZE = (16*1024*1024);
sys_nvmem_sram.Allocate(BBSRAM_SIZE);
sys_rom.Allocate(BIOS_SIZE);
break;
case DC_PLATFORM_ATOMISWAVE:
//Atomiswave : 16 mb ram, 8 mb vram, 8 mb aram, 128kb bios+flash, 128k BBSRAM
FLASH_SIZE = 0;
BIOS_SIZE = (128*1024);
RAM_SIZE = (16*1024*1024);
ARAM_SIZE = (8*1024*1024);
VRAM_SIZE = (8*1024*1024);
BBSRAM_SIZE = (128*1024);
sys_nvmem_flash.Allocate(BIOS_SIZE);
sys_nvmem_flash.write_protect_size = BIOS_SIZE / 2;
sys_nvmem_sram.Allocate(BBSRAM_SIZE);
break;
}
RAM_MASK = (RAM_SIZE-1);
ARAM_MASK = (ARAM_SIZE-1);
VRAM_MASK = (VRAM_SIZE-1);
}
void dc_reset(bool hard)
{
plugins_Reset(hard);
mem_Reset(hard);
sh4_cpu.Reset(hard);
}
int dc_init()
{
setbuf(stdin,0);
setbuf(stdout,0);
setbuf(stderr,0);
extern void common_libretro_setup(void);
common_libretro_setup();
if (!_vmem_reserve())
{
ERROR_LOG(VMEM, "Failed to alloc mem");
return -1;
}
reios_init();
LoadSettings();
int rv= 0;
extern char game_dir_no_slash[1024];
char new_system_dir[1024];
#ifdef _WIN32
sprintf(new_system_dir, "%s\\", game_dir_no_slash);
#else
sprintf(new_system_dir, "%s/", game_dir_no_slash);
#endif
if (settings.System == DC_PLATFORM_DREAMCAST)
{
if (settings.bios.UseReios || !LoadRomFiles(new_system_dir))
{
if (boot_to_bios)
// Booting the BIOS requires a BIOS file
return -3;
if (!LoadHle(new_system_dir))
return -3;
WARN_LOG(COMMON, "Did not load bios, using reios");
}
}
else
{
LoadRomFiles(new_system_dir);
}
LoadSpecialSettingsCPU();
sh4_cpu.Init();
mem_Init();
#ifdef _WIN64
extern void setup_seh();
setup_seh();
#endif
if (plugins_Init())
return -4;
mem_map_default();
dc_reset(true);
switch (settings.System)
{
case DC_PLATFORM_DREAMCAST:
if (libGDR_GetDiscType() == NoDisk)
{
// Content loading failed so force HLE off and boot the BIOS
settings.bios.UseReios = false;
if (!LoadRomFiles(new_system_dir))
return -3;
settings.imgread.DefaultImage[0] = '\0';
}
reios_disk_id();
LoadSpecialSettings();
break;
case DC_PLATFORM_ATOMISWAVE:
case DC_PLATFORM_NAOMI:
LoadSpecialSettingsNaomi(naomi_game_id);
break;
}
FixUpFlash();
mcfg_CreateDevices();
return rv;
}
void dc_run()
{
sh4_cpu.Run();
}
void dc_term()
{
SaveRomFiles(get_writable_data_path(""));
sh4_cpu.Term();
naomi_cart_Close();
plugins_Term();
mem_Term();
_vmem_release();
}
void dc_stop()
{
sh4_cpu.Stop();
}
void dc_start()
{
sh4_cpu.Start();
}
bool dc_is_running()
{
return sh4_cpu.IsCpuRunning();
}
// Called on the emulator thread for soft reset
void dc_request_reset()
{
reset_requested = true;
dc_stop();
}
void LoadSettings(void)
{
settings.dynarec.Enable = 1;
settings.dynarec.idleskip = 1;
settings.dynarec.unstable_opt = 0;
//settings.dynarec.DisableDivMatching = 0;
//disable_nvmem can't be loaded, because nvmem init is before cfg load
settings.dynarec.disable_vmem32 = false;
settings.UpdateModeForced = 0;
settings.dreamcast.RTC = GetRTC_now();
settings.dreamcast.FullMMU = false;
settings.aica.LimitFPS = 0;
settings.aica.NoSound = 0;
settings.pvr.subdivide_transp = 0;
//settings.pvr.Emulation.AlphaSortMode= 0;
settings.pvr.Emulation.zMin = 0.f;
settings.pvr.Emulation.zMax = 1.0f;
settings.pvr.MaxThreads = 3;
#ifndef __LIBRETRO__
settings.pvr.Emulation.ModVol = true;
settings.rend.RenderToTextureBuffer = false;
settings.rend.RenderToTextureUpscale = 1;
settings.rend.MaxFilteredTextureSize = 256;
settings.pvr.SynchronousRendering = 0;
#endif
settings.rend.Fog = true;
settings.rend.AutoExtraDepthScale = true;
settings.rend.ExtraDepthScale = 1.f;
settings.rend.Clipping = true;
settings.rend.ModifierVolumes = true;
settings.rend.TranslucentPolygonDepthMask = false;
settings.debug.SerialConsole = 0;
settings.reios.ElfFile = "";
settings.validate.OpenGlChecks = 0;
settings.network.ActAsServer = false;
settings.network.dns = "46.101.91.123"; // Dreamcast Live DNS
settings.network.server = "";
}
void SaveSettings(void)
{
}