Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
debe21de7b
|
@ -368,6 +368,12 @@ if(NOT LIBRETRO)
|
|||
set(SDL2_FOUND 1)
|
||||
endif()
|
||||
|
||||
# SDL2::SDL2main may or may not be available. It is e.g. required by Windows GUI applications
|
||||
if(TARGET SDL2::SDL2main)
|
||||
# It has an implicit dependency on SDL2 functions, so it MUST be added before SDL2::SDL2 (or SDL2::SDL2-static)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2main)
|
||||
endif()
|
||||
|
||||
if((APPLE OR WIN32) AND TARGET SDL2::SDL2-static)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2-static)
|
||||
elseif(TARGET SDL2::SDL2)
|
||||
|
@ -514,7 +520,12 @@ if(UNIX AND NOT APPLE AND NOT ANDROID)
|
|||
target_compile_definitions(${PROJECT_NAME} PRIVATE EGL_NO_X11)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS} rt)
|
||||
find_library(LIBRT rt)
|
||||
if(LIBRT)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRT})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
if(ASAN)
|
||||
|
|
|
@ -37,10 +37,10 @@ Option<bool> FullMMU("Dreamcast.FullMMU");
|
|||
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
|
||||
Option<bool> AutoLoadState("Dreamcast.AutoLoadState");
|
||||
Option<bool> AutoSaveState("Dreamcast.AutoSaveState");
|
||||
Option<int> SavestateSlot("Dreamcast.SavestateSlot");
|
||||
Option<int, false> SavestateSlot("Dreamcast.SavestateSlot");
|
||||
Option<bool> ForceFreePlay("ForceFreePlay", true);
|
||||
Option<bool> FetchBoxart("FetchBoxart", true);
|
||||
Option<bool> BoxartDisplayMode("BoxartDisplayMode", true);
|
||||
Option<bool, false> FetchBoxart("FetchBoxart", true);
|
||||
Option<bool, false> BoxartDisplayMode("BoxartDisplayMode", true);
|
||||
|
||||
// Sound
|
||||
|
||||
|
@ -122,7 +122,7 @@ Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
|
|||
|
||||
Option<std::vector<std::string>, false> ContentPath("Dreamcast.ContentPath");
|
||||
Option<bool, false> HideLegacyNaomiRoms("Dreamcast.HideLegacyNaomiRoms", true);
|
||||
Option<bool> UploadCrashLogs("UploadCrashLogs", true);
|
||||
Option<bool, false> UploadCrashLogs("UploadCrashLogs", true);
|
||||
|
||||
// Profiler
|
||||
Option<bool> ProfilerEnabled("Profiler.Enabled");
|
||||
|
@ -183,11 +183,11 @@ std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
|
|||
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
|
||||
};
|
||||
#ifdef _WIN32
|
||||
Option<bool> UseRawInput("RawInput", false, "input");
|
||||
Option<bool, false> UseRawInput("RawInput", false, "input");
|
||||
#endif
|
||||
|
||||
#ifdef USE_LUA
|
||||
OptionString LuaFileName("LuaFileName", "flycast.lua");
|
||||
Option<std::string, false> LuaFileName("LuaFileName", "flycast.lua");
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
|
|
|
@ -157,8 +157,8 @@ public:
|
|||
T& get() { return value; }
|
||||
void set(T v) { value = v; }
|
||||
|
||||
void override(T v) {
|
||||
verify(PerGameOption);
|
||||
void override(T v)
|
||||
{
|
||||
overriddenDefault = v;
|
||||
overridden = true;
|
||||
value = v;
|
||||
|
@ -372,10 +372,10 @@ extern Option<bool> FullMMU;
|
|||
extern Option<bool> ForceWindowsCE;
|
||||
extern Option<bool> AutoLoadState;
|
||||
extern Option<bool> AutoSaveState;
|
||||
extern Option<int> SavestateSlot;
|
||||
extern Option<int, false> SavestateSlot;
|
||||
extern Option<bool> ForceFreePlay;
|
||||
extern Option<bool> FetchBoxart;
|
||||
extern Option<bool> BoxartDisplayMode;
|
||||
extern Option<bool, false> FetchBoxart;
|
||||
extern Option<bool, false> BoxartDisplayMode;
|
||||
|
||||
// Sound
|
||||
|
||||
|
@ -416,10 +416,10 @@ extern Option<bool> VmuSound;
|
|||
class RendererOption : public Option<RenderType> {
|
||||
public:
|
||||
RendererOption()
|
||||
#ifdef USE_DX9
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX9) {}
|
||||
#elif defined(USE_DX11)
|
||||
#if defined(USE_DX11)
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX11) {}
|
||||
#elif defined(USE_DX9)
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX9) {}
|
||||
#else
|
||||
: Option<RenderType>("pvr.rend", RenderType::OpenGL) {}
|
||||
#endif
|
||||
|
@ -483,7 +483,7 @@ extern Option<bool> OpenGlChecks;
|
|||
|
||||
extern Option<std::vector<std::string>, false> ContentPath;
|
||||
extern Option<bool, false> HideLegacyNaomiRoms;
|
||||
extern Option<bool> UploadCrashLogs;
|
||||
extern Option<bool, false> UploadCrashLogs;
|
||||
|
||||
// Profiling
|
||||
extern Option<bool> ProfilerEnabled;
|
||||
|
@ -526,13 +526,13 @@ extern Option<int> VirtualGamepadVibration;
|
|||
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
|
||||
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
|
||||
#ifdef _WIN32
|
||||
extern Option<bool> UseRawInput;
|
||||
extern Option<bool, false> UseRawInput;
|
||||
#else
|
||||
constexpr bool UseRawInput = false;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern OptionString LuaFileName;
|
||||
extern Option<std::string, false> LuaFileName;
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
|
|
|
@ -48,13 +48,11 @@ settings_t settings;
|
|||
|
||||
static void loadSpecialSettings()
|
||||
{
|
||||
std::string& prod_id = settings.content.gameId;
|
||||
NOTICE_LOG(BOOT, "Game ID is [%s]", prod_id.c_str());
|
||||
|
||||
if (settings.platform.isConsole())
|
||||
{
|
||||
std::string prod_id(ip_meta.product_number, sizeof(ip_meta.product_number));
|
||||
prod_id = trim_trailing_ws(prod_id);
|
||||
|
||||
NOTICE_LOG(BOOT, "Game ID is [%s]", prod_id.c_str());
|
||||
|
||||
if (ip_meta.isWindowsCE() || config::ForceWindowsCE
|
||||
|| prod_id == "T26702N") // PBA Tour Bowling 2001
|
||||
{
|
||||
|
@ -216,7 +214,9 @@ static void loadSpecialSettings()
|
|||
config::UseReios.override(false);
|
||||
}
|
||||
if (prod_id == "T-9707N" // San Francisco Rush 2049 (US)
|
||||
|| prod_id == "MK-51146") // Sega Smash Pack - Volume 1
|
||||
|| prod_id == "MK-51146" // Sega Smash Pack - Volume 1
|
||||
|| prod_id == "T-9702D-50" // Hydro Thunder (PAL)
|
||||
|| prod_id == "T41601N") // Elemental Gimmick Gear (US)
|
||||
{
|
||||
NOTICE_LOG(BOOT, "Forcing NTSC broadcasting");
|
||||
config::Broadcast.override(0);
|
||||
|
@ -235,132 +235,131 @@ static void loadSpecialSettings()
|
|||
}
|
||||
else if (settings.platform.isArcade())
|
||||
{
|
||||
NOTICE_LOG(BOOT, "Game ID is [%s]", naomi_game_id);
|
||||
if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id))
|
||||
if (prod_id == "SAMURAI SPIRITS 6")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id.c_str());
|
||||
config::ExtraDepthScale.override(1e26f);
|
||||
}
|
||||
if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id))
|
||||
if (prod_id == "COSMIC SMASH IN JAPAN")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", prod_id.c_str());
|
||||
config::TranslucentPolygonDepthMask.override(true);
|
||||
}
|
||||
if (!strcmp(naomi_game_id, "BEACH SPIKERS JAPAN"))
|
||||
if (prod_id == "BEACH SPIKERS JAPAN")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling RTT Copy to VRAM for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling RTT Copy to VRAM for game %s", prod_id.c_str());
|
||||
config::RenderToTextureBuffer.override(true);
|
||||
}
|
||||
if (!strcmp(naomi_game_id, "RADIRGY NOA"))
|
||||
if (prod_id == "RADIRGY NOA")
|
||||
{
|
||||
INFO_LOG(BOOT, "Disabling Free Play for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Disabling Free Play for game %s", prod_id.c_str());
|
||||
config::ForceFreePlay.override(false);
|
||||
}
|
||||
// Input configuration
|
||||
settings.input.JammaSetup = JVS::Default;
|
||||
if (!strcmp("DYNAMIC GOLF", naomi_game_id)
|
||||
|| !strcmp("SHOOTOUT POOL", naomi_game_id)
|
||||
|| !strcmp("SHOOTOUT POOL MEDAL", 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)
|
||||
|| !strcmp("DRIVE", naomi_game_id)) // Waiwai drive
|
||||
if (prod_id == "DYNAMIC GOLF"
|
||||
|| prod_id == "SHOOTOUT POOL"
|
||||
|| prod_id == "SHOOTOUT POOL MEDAL"
|
||||
|| prod_id == "CRACKIN'DJ ver JAPAN"
|
||||
|| prod_id == "CRACKIN'DJ PART2 ver JAPAN"
|
||||
|| prod_id == "KICK '4' CASH"
|
||||
|| prod_id == "DRIVE") // Waiwai drive
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::RotaryEncoders;
|
||||
}
|
||||
else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi
|
||||
|| !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW
|
||||
else if (prod_id == "POWER STONE 2 JAPAN" // Naomi
|
||||
|| prod_id == "GUILTY GEAR isuka") // AW
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling 4-player setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling 4-player setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::FourPlayers;
|
||||
}
|
||||
else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id)
|
||||
|| !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW
|
||||
else if (prod_id == "SEGA MARINE FISHING JAPAN"
|
||||
|| prod_id == "BASS FISHING SIMULATOR VER.A") // AW
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::SegaMarineFishing;
|
||||
}
|
||||
else if (!strcmp("RINGOUT 4X4 JAPAN", naomi_game_id)
|
||||
|| !strcmp("VIRTUA ATHLETE", naomi_game_id))
|
||||
else if (prod_id == "RINGOUT 4X4 JAPAN"
|
||||
|| prod_id == "VIRTUA ATHLETE")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::DualIOBoards4P;
|
||||
}
|
||||
else if (!strcmp("NINJA ASSAULT", naomi_game_id)
|
||||
|| !strcmp(naomi_game_id, "Sports Shooting USA") // AW
|
||||
|| !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE") // AW
|
||||
|| !strcmp(naomi_game_id, "RANGER MISSION") // AW
|
||||
|| !strcmp(naomi_game_id, "EXTREME HUNTING")) // AW
|
||||
else if (prod_id == "NINJA ASSAULT"
|
||||
|| prod_id == "Sports Shooting USA" // AW
|
||||
|| prod_id == "SEGA CLAY CHALLENGE" // AW
|
||||
|| prod_id == "RANGER MISSION" // AW
|
||||
|| prod_id == "EXTREME HUNTING") // AW
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling lightgun setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling lightgun setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::LightGun;
|
||||
}
|
||||
else if (!strcmp("MAZAN", naomi_game_id))
|
||||
else if (prod_id == "MAZAN")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::Mazan;
|
||||
}
|
||||
else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id))
|
||||
else if (prod_id == " BIOHAZARD GUN SURVIVOR2")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::GunSurvivor;
|
||||
}
|
||||
else if (!strcmp("WORLD KICKS", naomi_game_id))
|
||||
else if (prod_id == "WORLD KICKS")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::WorldKicks;
|
||||
}
|
||||
else if (!strcmp("WORLD KICKS PCB", naomi_game_id))
|
||||
else if (prod_id == "WORLD KICKS PCB")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::WorldKicksPCB;
|
||||
}
|
||||
else if (!strcmp("THE TYPING OF THE DEAD", naomi_game_id)
|
||||
|| !strcmp(" LUPIN THE THIRD -THE TYPING-", naomi_game_id)
|
||||
|| !strcmp("------La Keyboardxyu------", naomi_game_id))
|
||||
else if (prod_id == "THE TYPING OF THE DEAD"
|
||||
|| prod_id == " LUPIN THE THIRD -THE TYPING-"
|
||||
|| prod_id == "------La Keyboardxyu------")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling keyboard for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling keyboard for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::Keyboard;
|
||||
}
|
||||
else if (!strcmp("OUTTRIGGER JAPAN", naomi_game_id))
|
||||
else if (prod_id == "OUTTRIGGER JAPAN")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::OutTrigger;
|
||||
}
|
||||
else if (!strcmp(naomi_game_id, "THE MAZE OF THE KINGS")
|
||||
|| !strcmp(naomi_game_id, " CONFIDENTIAL MISSION ---------")
|
||||
|| !strcmp(naomi_game_id, "DEATH CRIMSON OX")
|
||||
|| !strncmp(naomi_game_id, "hotd2", 5) // House of the Dead 2
|
||||
|| !strcmp(naomi_game_id, "LUPIN THE THIRD -THE SHOOTING-"))
|
||||
else if (prod_id == "THE MAZE OF THE KINGS"
|
||||
|| prod_id == " CONFIDENTIAL MISSION ---------"
|
||||
|| prod_id == "DEATH CRIMSON OX"
|
||||
|| prod_id.substr(0, 5) == "hotd2" // House of the Dead 2
|
||||
|| prod_id == "LUPIN THE THIRD -THE SHOOTING-")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling lightgun as analog setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling lightgun as analog setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::LightGunAsAnalog;
|
||||
}
|
||||
else if (!strcmp("WAVE RUNNER GP", naomi_game_id))
|
||||
else if (prod_id == "WAVE RUNNER GP")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::WaveRunnerGP;
|
||||
}
|
||||
else if (!strcmp(" 18WHEELER", naomi_game_id))
|
||||
else if (prod_id == " 18WHEELER")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::_18Wheeler;
|
||||
}
|
||||
else if (!strcmp("F355 CHALLENGE JAPAN", naomi_game_id))
|
||||
else if (prod_id == "F355 CHALLENGE JAPAN", naomi_game_id)
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
settings.input.JammaSetup = JVS::F355;
|
||||
}
|
||||
else if (!strcmp("INU NO OSANPO", naomi_game_id)) // Dog Walking
|
||||
else if (prod_id == "INU NO OSANPO") // Dog Walking
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::DogWalking;
|
||||
}
|
||||
else if (!strcmp(" TOUCH DE UNOH -------------", naomi_game_id)
|
||||
|| !strcmp("POKASUKA GHOST (JAPANESE)", naomi_game_id))
|
||||
else if (prod_id == " TOUCH DE UNOH -------------"
|
||||
|| prod_id == "POKASUKA GHOST (JAPANESE)")
|
||||
{
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
|
||||
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", prod_id.c_str());
|
||||
settings.input.JammaSetup = JVS::TouchDeUno;
|
||||
}
|
||||
}
|
||||
|
@ -371,8 +370,8 @@ void dc_reset(bool hard)
|
|||
NetworkHandshake::term();
|
||||
if (hard)
|
||||
{
|
||||
addrspace::unprotectVram(0, VRAM_SIZE);
|
||||
memwatch::elanWatcher.unprotectMem(0, 0xffffffff);
|
||||
memwatch::unprotect();
|
||||
memwatch::reset();
|
||||
}
|
||||
sh4_sched_reset(hard);
|
||||
pvr::reset(hard);
|
||||
|
@ -672,6 +671,10 @@ void Emulator::stop()
|
|||
{
|
||||
if (state != Running)
|
||||
return;
|
||||
// Avoid race condition with GGPO restarting the sh4 for a new frame
|
||||
if (config::GGPOEnable)
|
||||
NetworkHandshake::term();
|
||||
// must be updated after GGPO is stopped since it may run some rollback frames
|
||||
state = Loaded;
|
||||
sh4_cpu.Stop();
|
||||
if (config::ThreadedRendering)
|
||||
|
@ -699,36 +702,30 @@ void Emulator::stop()
|
|||
void Emulator::requestReset()
|
||||
{
|
||||
resetRequested = true;
|
||||
if (config::GGPOEnable)
|
||||
NetworkHandshake::term();
|
||||
sh4_cpu.Stop();
|
||||
}
|
||||
|
||||
void loadGameSpecificSettings()
|
||||
{
|
||||
char *reios_id;
|
||||
if (settings.platform.isConsole())
|
||||
{
|
||||
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;
|
||||
settings.content.gameId = trim_trailing_ws(std::string(ip_meta.product_number, sizeof(ip_meta.product_number)));
|
||||
|
||||
char *p = reios_id + strlen(reios_id) - 1;
|
||||
while (p >= reios_id && *p == ' ')
|
||||
*p-- = '\0';
|
||||
if (*p == '\0')
|
||||
if (settings.content.gameId.empty())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
reios_id = naomi_game_id;
|
||||
settings.content.gameId = naomi_game_id;
|
||||
}
|
||||
|
||||
// Default per-game settings
|
||||
loadSpecialSettings();
|
||||
|
||||
settings.content.gameId = reios_id;
|
||||
config::Settings::instance().setGameId(reios_id);
|
||||
config::Settings::instance().setGameId(settings.content.gameId);
|
||||
|
||||
// Reload per-game settings
|
||||
config::Settings::instance().load(true);
|
||||
|
@ -944,7 +941,9 @@ void Emulator::vblank()
|
|||
if (sh4_sched_now64() - startTime <= 10000000)
|
||||
return;
|
||||
renderTimeout = true;
|
||||
if (!ggpo::active() && !config::ThreadedRendering)
|
||||
if (ggpo::active())
|
||||
ggpo::endOfFrame();
|
||||
else if (!config::ThreadedRendering)
|
||||
sh4_cpu.Stop();
|
||||
}
|
||||
|
||||
|
|
|
@ -173,40 +173,34 @@ static void AicaInternalDMA()
|
|||
template<typename T>
|
||||
void writeTimerAndIntReg(u32 reg, T data)
|
||||
{
|
||||
constexpr size_t sz = sizeof(T);
|
||||
switch (reg)
|
||||
{
|
||||
case SCIEB_addr:
|
||||
verify(sz != 1);
|
||||
SCIEB->full = data & 0x7ff;
|
||||
update_arm_interrupts();
|
||||
break;
|
||||
|
||||
case SCIPD_addr:
|
||||
verify(sz!=1);
|
||||
// other bits are read-only
|
||||
if (data & (1<<5))
|
||||
if (data & (1 << 5))
|
||||
{
|
||||
SCIPD->SCPU=1;
|
||||
SCIPD->SCPU = 1;
|
||||
update_arm_interrupts();
|
||||
}
|
||||
break;
|
||||
|
||||
case SCIRE_addr:
|
||||
verify(sz != 1);
|
||||
SCIPD->full &= ~data /*& SCIEB->full)*/; //is the & SCIEB->full needed ? doesn't seem like it
|
||||
SCIPD->full &= ~data;
|
||||
update_arm_interrupts();
|
||||
break;
|
||||
|
||||
case MCIEB_addr:
|
||||
verify(sz != 1);
|
||||
MCIEB->full = data & 0x7ff;
|
||||
if (UpdateSh4Ints())
|
||||
arm::avoidRaceCondition();
|
||||
break;
|
||||
|
||||
case MCIPD_addr:
|
||||
verify(sz != 1);
|
||||
// other bits are read-only
|
||||
if (data & (1 << 5))
|
||||
{
|
||||
|
@ -217,7 +211,6 @@ void writeTimerAndIntReg(u32 reg, T data)
|
|||
break;
|
||||
|
||||
case MCIRE_addr:
|
||||
verify(sz != 1);
|
||||
MCIPD->full &= ~data;
|
||||
UpdateSh4Ints();
|
||||
break;
|
||||
|
|
|
@ -222,8 +222,9 @@ static void CPUSwitchMode(int mode, bool saveState)
|
|||
reg[RN_SPSR].I = reg[SPSR_UND].I;
|
||||
break;
|
||||
default:
|
||||
// An illegal mode causes the processor to enter an unrecoverable state
|
||||
ERROR_LOG(AICA_ARM, "Unsupported ARM mode %02x", mode);
|
||||
die("Arm error..");
|
||||
Arm7Enabled = false;
|
||||
break;
|
||||
}
|
||||
armMode = mode;
|
||||
|
|
|
@ -845,7 +845,7 @@ maple_naomi_jamma::maple_naomi_jamma()
|
|||
io_boards.push_back(std::unique_ptr<jvs_837_13844>(new jvs_837_13844(1, this)));
|
||||
break;
|
||||
case JVS::DualIOBoards4P:
|
||||
if (!strcmp(naomi_game_id, "VIRTUA ATHLETE"))
|
||||
if (settings.content.gameId == "VIRTUA ATHLETE")
|
||||
{
|
||||
// reverse the board order so that P1 is P1
|
||||
io_boards.push_back(std::unique_ptr<jvs_837_13551>(new jvs_837_13551(1, this, 2)));
|
||||
|
@ -1752,6 +1752,9 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou
|
|||
axis_value = 0;
|
||||
if (axisDesc.inverted)
|
||||
axis_value = 0xff00u - axis_value;
|
||||
// this fixes kingrt66 immediate win
|
||||
if (axis_value == 0x8000)
|
||||
axis_value = 0x8100;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -215,8 +215,6 @@ inline static void protect()
|
|||
|
||||
inline static void unprotect()
|
||||
{
|
||||
if (!config::GGPOEnable)
|
||||
return;
|
||||
vramWatcher.unprotect();
|
||||
ramWatcher.unprotect();
|
||||
aramWatcher.unprotect();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "hw/holly/holly_intc.h"
|
||||
#include "hw/sh4/sh4_if.h"
|
||||
#include "profiler/fc_profiler.h"
|
||||
#include "network/ggpo.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
|
@ -32,6 +33,7 @@ u32 fb_watch_addr_end;
|
|||
bool fb_dirty;
|
||||
|
||||
static bool pend_rend;
|
||||
static bool rendererEnabled = true;
|
||||
|
||||
TA_context* _pvrrc;
|
||||
|
||||
|
@ -226,7 +228,7 @@ private:
|
|||
if (renderer->Present())
|
||||
{
|
||||
presented = true;
|
||||
if (!config::ThreadedRendering)
|
||||
if (!config::ThreadedRendering && !ggpo::active())
|
||||
sh4_cpu.Stop();
|
||||
#ifdef LIBRETRO
|
||||
retro_rend_present();
|
||||
|
@ -307,6 +309,7 @@ static void rend_create_renderer()
|
|||
|
||||
bool rend_init_renderer()
|
||||
{
|
||||
rendererEnabled = true;
|
||||
if (renderer == nullptr)
|
||||
rend_create_renderer();
|
||||
bool success = renderer->Init();
|
||||
|
@ -336,6 +339,7 @@ void rend_reset()
|
|||
FrameCount = 1;
|
||||
fb_w_cur = 1;
|
||||
pvrQueue.reset();
|
||||
rendererEnabled = true;
|
||||
}
|
||||
|
||||
void rend_start_render()
|
||||
|
@ -387,6 +391,9 @@ void rend_start_render()
|
|||
ctx->rend.fog_clamp_min = FOG_CLAMP_MIN;
|
||||
ctx->rend.fog_clamp_max = FOG_CLAMP_MAX;
|
||||
|
||||
if (!ctx->rend.isRTT)
|
||||
ggpo::endOfFrame();
|
||||
|
||||
if (QueueRender(ctx))
|
||||
{
|
||||
palette_update();
|
||||
|
@ -422,12 +429,15 @@ void rend_vblank()
|
|||
if (config::EmulateFramebuffer
|
||||
|| (!render_called && fb_dirty && FB_R_CTRL.fb_enable))
|
||||
{
|
||||
FramebufferInfo fbInfo;
|
||||
fbInfo.update();
|
||||
pvrQueue.enqueue(PvrMessageQueue::RenderFramebuffer, fbInfo);
|
||||
pvrQueue.enqueue(PvrMessageQueue::Present);
|
||||
if (!config::EmulateFramebuffer)
|
||||
DEBUG_LOG(PVR, "Direct framebuffer write detected");
|
||||
if (rend_is_enabled())
|
||||
{
|
||||
FramebufferInfo fbInfo;
|
||||
fbInfo.update();
|
||||
pvrQueue.enqueue(PvrMessageQueue::RenderFramebuffer, fbInfo);
|
||||
pvrQueue.enqueue(PvrMessageQueue::Present);
|
||||
if (!config::EmulateFramebuffer)
|
||||
DEBUG_LOG(PVR, "Direct framebuffer write detected");
|
||||
}
|
||||
fb_dirty = false;
|
||||
}
|
||||
render_called = false;
|
||||
|
@ -466,7 +476,7 @@ void rend_set_fb_write_addr(u32 fb_w_sof1)
|
|||
|
||||
void rend_swap_frame(u32 fb_r_sof)
|
||||
{
|
||||
if (!config::EmulateFramebuffer && fb_r_sof == fb_w_cur)
|
||||
if (!config::EmulateFramebuffer && fb_r_sof == fb_w_cur && rend_is_enabled())
|
||||
pvrQueue.enqueue(PvrMessageQueue::Present);
|
||||
}
|
||||
|
||||
|
@ -486,6 +496,14 @@ void rend_start_rollback()
|
|||
vramRollback.Wait();
|
||||
}
|
||||
|
||||
void rend_enable_renderer(bool enabled) {
|
||||
rendererEnabled = enabled;
|
||||
}
|
||||
|
||||
bool rend_is_enabled() {
|
||||
return rendererEnabled;
|
||||
}
|
||||
|
||||
void rend_serialize(Serializer& ser)
|
||||
{
|
||||
ser << fb_w_cur;
|
||||
|
|
|
@ -17,6 +17,8 @@ void rend_reset();
|
|||
void rend_disable_rollback();
|
||||
void rend_start_rollback();
|
||||
void rend_allow_rollback();
|
||||
void rend_enable_renderer(bool enabled);
|
||||
bool rend_is_enabled();
|
||||
void rend_serialize(Serializer& ser);
|
||||
void rend_deserialize(Deserializer& deser);
|
||||
|
||||
|
|
|
@ -113,7 +113,6 @@ static int spg_line_sched(int tag, int cycles, int jitter)
|
|||
SB_MDST = 0;
|
||||
}
|
||||
asic_RaiseInterrupt(holly_SCANINT1);
|
||||
ggpo::endOfFrame();
|
||||
}
|
||||
|
||||
if (SPG_VBLANK_INT.vblank_out_interrupt_line_number == prv_cur_scanline)
|
||||
|
|
|
@ -50,7 +50,7 @@ bool QueueRender(TA_context* ctx)
|
|||
{
|
||||
verify(ctx != 0);
|
||||
|
||||
bool skipFrame = settings.disableRenderer;
|
||||
bool skipFrame = !rend_is_enabled();
|
||||
if (!skipFrame)
|
||||
{
|
||||
RenderCount++;
|
||||
|
@ -67,7 +67,7 @@ bool QueueRender(TA_context* ctx)
|
|||
if (skipFrame || rqueue)
|
||||
{
|
||||
tactx_Recycle(ctx);
|
||||
if (!settings.disableRenderer)
|
||||
if (rend_is_enabled())
|
||||
fskip++;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -72,13 +72,10 @@ void sortTriangles(rend_context& ctx, RenderPass& pass, const RenderPass& previo
|
|||
const PolyParam * const pp_base = &ctx.global_param_tr[first];
|
||||
const PolyParam * const pp_end = pp_base + count;
|
||||
|
||||
int vtx_count = ctx.verts.size() - pp_base->first;
|
||||
if (vtx_count <= 0)
|
||||
return;
|
||||
|
||||
//make lists of all triangles, with their pid and vid
|
||||
static std::vector<IndexTrig> triangleList;
|
||||
|
||||
int vtx_count = ctx.verts.size() - pp_base->first;
|
||||
triangleList.reserve(vtx_count);
|
||||
triangleList.clear();
|
||||
|
||||
|
@ -147,6 +144,7 @@ void sortTriangles(rend_context& ctx, RenderPass& pass, const RenderPass& previo
|
|||
|
||||
//re-assemble them into drawing commands
|
||||
|
||||
size_t initialSize = ctx.sortedTriangles.size();
|
||||
int idx = -1;
|
||||
int idxSize = ctx.idx.size();
|
||||
|
||||
|
@ -174,7 +172,7 @@ void sortTriangles(rend_context& ctx, RenderPass& pass, const RenderPass& previo
|
|||
}
|
||||
}
|
||||
|
||||
if (!ctx.sortedTriangles.empty())
|
||||
if (!triangleList.empty())
|
||||
{
|
||||
SortedTriangle& last = ctx.sortedTriangles.back();
|
||||
last.count = idxSize + triangleList.size() * 3 - last.first;
|
||||
|
@ -184,7 +182,7 @@ void sortTriangles(rend_context& ctx, RenderPass& pass, const RenderPass& previo
|
|||
// Add a dummy one to signal we're using sorted triangles
|
||||
ctx.sortedTriangles.push_back({ pp_base, 0, 0});
|
||||
}
|
||||
pass.sorted_tr_count = ctx.sortedTriangles.size();
|
||||
pass.sorted_tr_count = ctx.sortedTriangles.size() - initialSize;
|
||||
|
||||
#if PRINT_SORT_STATS
|
||||
printf("Reassembled into %d from %d\n", (int)ctx.sortedTriangles.size(), pp_end - pp_base);
|
||||
|
|
|
@ -255,14 +255,14 @@ static bool advance_frame(int)
|
|||
{
|
||||
INFO_LOG(NETWORK, "advance_frame");
|
||||
settings.aica.muteAudio = true;
|
||||
settings.disableRenderer = true;
|
||||
rend_enable_renderer(false);
|
||||
inRollback = true;
|
||||
|
||||
emu.run();
|
||||
ggpo_advance_frame(ggpoSession);
|
||||
|
||||
settings.aica.muteAudio = false;
|
||||
settings.disableRenderer = false;
|
||||
rend_enable_renderer(true);
|
||||
inRollback = false;
|
||||
_endOfFrame = false;
|
||||
|
||||
|
@ -597,6 +597,8 @@ void stopSession()
|
|||
ggpoSession = nullptr;
|
||||
miniupnp.Term();
|
||||
emu.setNetworkState(false);
|
||||
memwatch::unprotect();
|
||||
memwatch::reset();
|
||||
}
|
||||
|
||||
void getInput(MapleInputState inputState[4])
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "naomi_network.h"
|
||||
#include "hw/naomi/naomi_cart.h"
|
||||
#include "hw/naomi/naomi_flashrom.h"
|
||||
#include "cfg/option.h"
|
||||
#include "rend/gui.h"
|
||||
|
@ -294,81 +293,81 @@ bool NaomiNetwork::receive(const sockaddr_in *addr, const Packet *packet, u32 si
|
|||
// Node 0 is master, nodes 1+ are slave
|
||||
void SetNaomiNetworkConfig(int node)
|
||||
{
|
||||
if (!strcmp("ALIEN FRONT", naomi_game_id))
|
||||
const std::string& gameId = settings.content.gameId;
|
||||
if (gameId == "ALIEN FRONT")
|
||||
{
|
||||
// no way to disable the network
|
||||
write_naomi_eeprom(0x3f, node == 0 ? 0 : 1);
|
||||
}
|
||||
else if (!strcmp("MOBILE SUIT GUNDAM JAPAN", naomi_game_id) // gundmct
|
||||
|| !strcmp("MOBILE SUIT GUNDAM DELUXE JAPAN", naomi_game_id)) // gundmxgd
|
||||
else if (gameId == "MOBILE SUIT GUNDAM JAPAN" // gundmct
|
||||
|| gameId == "MOBILE SUIT GUNDAM DELUXE JAPAN") // gundmxgd
|
||||
{
|
||||
write_naomi_eeprom(0x38, node == -1 ? 2
|
||||
: node == 0 ? 0 : 1);
|
||||
}
|
||||
else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id))
|
||||
else if (gameId == " BIOHAZARD GUN SURVIVOR2")
|
||||
{
|
||||
// FIXME need default flash
|
||||
write_naomi_flash(0x21c, node == 0 ? 0 : 1); // CPU ID - 1
|
||||
write_naomi_flash(0x22a, node == -1 ? 0 : 1); // comm link on
|
||||
}
|
||||
else if (!strcmp("HEAVY METAL JAPAN", naomi_game_id))
|
||||
else if (gameId == "HEAVY METAL JAPAN")
|
||||
{
|
||||
write_naomi_eeprom(0x31, node == -1 ? 0 : node == 0 ? 1 : 2);
|
||||
}
|
||||
else if (!strcmp("OUTTRIGGER JAPAN", naomi_game_id))
|
||||
else if (gameId == "OUTTRIGGER JAPAN")
|
||||
{
|
||||
// FIXME need default flash
|
||||
write_naomi_flash(0x21a, node == -1 ? 0 : 1); // network on
|
||||
write_naomi_flash(0x21b, node); // node id
|
||||
}
|
||||
else if (!strcmp("SLASHOUT JAPAN VERSION", naomi_game_id))
|
||||
else if (gameId == "SLASHOUT JAPAN VERSION")
|
||||
{
|
||||
write_naomi_eeprom(0x30, node + 1);
|
||||
}
|
||||
else if (!strcmp("SPAWN JAPAN", naomi_game_id))
|
||||
else if (gameId == "SPAWN JAPAN")
|
||||
{
|
||||
write_naomi_eeprom(0x44, node == -1 ? 0 : 1); // network on
|
||||
write_naomi_eeprom(0x30, node <= 0 ? 1 : 2); // node id
|
||||
}
|
||||
else if (!strcmp("SPIKERS BATTLE JAPAN VERSION", naomi_game_id))
|
||||
else if (gameId == "SPIKERS BATTLE JAPAN VERSION")
|
||||
{
|
||||
write_naomi_eeprom(0x30, node == -1 ? 0
|
||||
: node == 0 ? 1 : 2);
|
||||
}
|
||||
else if (!strcmp("VIRTUAL-ON ORATORIO TANGRAM", naomi_game_id))
|
||||
else if (gameId == "VIRTUAL-ON ORATORIO TANGRAM")
|
||||
{
|
||||
write_naomi_eeprom(0x45, node == -1 ? 3
|
||||
: node == 0 ? 0 : 1);
|
||||
write_naomi_eeprom(0x47, node == 0 ? 0 : 1);
|
||||
}
|
||||
else if (!strcmp("WAVE RUNNER GP", naomi_game_id))
|
||||
else if (gameId == "WAVE RUNNER GP")
|
||||
{
|
||||
write_naomi_eeprom(0x33, node);
|
||||
write_naomi_eeprom(0x35, node == -1 ? 2
|
||||
: node == 0 ? 0 : 1);
|
||||
}
|
||||
else if (!strcmp("WORLD KICKS", naomi_game_id))
|
||||
else if (gameId == "WORLD KICKS")
|
||||
{
|
||||
// FIXME need default flash
|
||||
write_naomi_flash(0x224, node == -1 ? 0 : 1); // network on
|
||||
write_naomi_flash(0x220, node == 0 ? 0 : 1); // node id
|
||||
}
|
||||
else if (!strcmp("CLUB KART IN JAPAN", naomi_game_id))
|
||||
else if (gameId == "CLUB KART IN JAPAN")
|
||||
{
|
||||
write_naomi_eeprom(0x34, node + 1); // also 03 = satellite
|
||||
}
|
||||
else if (!strcmp("INITIAL D", naomi_game_id)
|
||||
|| !strcmp("INITIAL D Ver.2", naomi_game_id)
|
||||
|| !strcmp("INITIAL D Ver.3", naomi_game_id))
|
||||
else if (gameId == "INITIAL D"
|
||||
|| gameId == "INITIAL D Ver.2"
|
||||
|| gameId == "INITIAL D Ver.3")
|
||||
{
|
||||
write_naomi_eeprom(0x34, node == -1 ? 0x02 : node == 0 ? 0x12 : 0x22);
|
||||
}
|
||||
else if (!strcmp("THE KING OF ROUTE66", naomi_game_id))
|
||||
else if (gameId == "THE KING OF ROUTE66")
|
||||
{
|
||||
// FIXME no input when linked
|
||||
write_naomi_eeprom(0x3d, node == -1 ? 0x44 : node == 0 ? 0x54 : 0x64);
|
||||
}
|
||||
else if (!strcmp("MAXIMUM SPEED", naomi_game_id))
|
||||
else if (gameId == "MAXIMUM SPEED")
|
||||
{
|
||||
configure_maxspeed_flash(node != -1, node == 0);
|
||||
}
|
||||
|
@ -397,7 +396,7 @@ bool NaomiNetworkSupported()
|
|||
if (!config::NetworkEnable)
|
||||
return false;
|
||||
for (auto game : games)
|
||||
if (!strcmp(game, naomi_game_id))
|
||||
if (settings.content.gameId == game)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -89,7 +89,7 @@ static inline void set_tcp_nodelay(sock_t fd)
|
|||
#if defined(_WIN32)
|
||||
struct protoent *tcp_proto = getprotobyname("TCP");
|
||||
setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, (const char *)&optval, optlen);
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen);
|
||||
#else
|
||||
struct protoent *tcp_proto = getprotobyname("TCP");
|
||||
|
|
|
@ -48,8 +48,6 @@ extern "C" {
|
|||
#include "types.h"
|
||||
#include "picoppp.h"
|
||||
#include "miniupnp.h"
|
||||
#include "reios/reios.h"
|
||||
#include "hw/naomi/naomi_cart.h"
|
||||
#include "cfg/option.h"
|
||||
#include "emulator.h"
|
||||
|
||||
|
@ -843,24 +841,14 @@ static void *pico_thread_func(void *)
|
|||
|
||||
// Find the network ports for the current game
|
||||
const GamePortList *ports = nullptr;
|
||||
std::string gameId;
|
||||
if (settings.platform.isConsole())
|
||||
{
|
||||
gameId = std::string(ip_meta.product_number, sizeof(ip_meta.product_number));
|
||||
gameId = trim_trailing_ws(gameId);
|
||||
}
|
||||
else
|
||||
{
|
||||
gameId = naomi_game_id;
|
||||
}
|
||||
for (u32 i = 0; i < ARRAY_SIZE(GamesPorts) && ports == nullptr; i++)
|
||||
{
|
||||
const auto& game = GamesPorts[i];
|
||||
for (u32 j = 0; j < ARRAY_SIZE(game.gameId) && game.gameId[j] != nullptr; j++)
|
||||
{
|
||||
if (gameId == game.gameId[j])
|
||||
if (settings.content.gameId == game.gameId[j])
|
||||
{
|
||||
NOTICE_LOG(MODEM, "Found network ports for game %s", gameId.c_str());
|
||||
NOTICE_LOG(MODEM, "Found network ports for game %s", settings.content.gameId.c_str());
|
||||
ports = &game;
|
||||
break;
|
||||
}
|
||||
|
@ -869,7 +857,8 @@ static void *pico_thread_func(void *)
|
|||
// Web TV requires the VJ compression option, which picotcp doesn't support.
|
||||
// This hack allows WebTV to connect although the correct fix would
|
||||
// be to implement VJ compression.
|
||||
dont_reject_opt_vj_hack = gameId == "6107117" || gameId == "610-7390" || gameId == "610-7391" ? 1 : 0;
|
||||
dont_reject_opt_vj_hack = settings.content.gameId == "6107117"
|
||||
|| settings.content.gameId == "610-7390" || settings.content.gameId == "610-7391" ? 1 : 0;
|
||||
|
||||
std::future<MiniUPnP> upnp =
|
||||
std::async(std::launch::async, [ports]() {
|
||||
|
|
|
@ -92,6 +92,9 @@ void flycast_term()
|
|||
|
||||
void dc_savestate(int index)
|
||||
{
|
||||
if (settings.network.online)
|
||||
return;
|
||||
|
||||
Serializer ser;
|
||||
dc_serialize(ser);
|
||||
|
||||
|
|
|
@ -1018,7 +1018,7 @@ bool OpenGL4Renderer::renderFrame(int width, int height)
|
|||
#ifndef LIBRETRO
|
||||
else {
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio();
|
||||
RenderLastFrame();
|
||||
renderLastFrame();
|
||||
}
|
||||
#endif
|
||||
glBindVertexArray(0);
|
||||
|
|
|
@ -667,7 +667,7 @@ void OpenGLRenderer::RenderFramebuffer(const FramebufferInfo& info)
|
|||
drawQuad(gl.dcfb.tex, false, true);
|
||||
}
|
||||
#ifndef LIBRETRO
|
||||
RenderLastFrame();
|
||||
renderLastFrame();
|
||||
#endif
|
||||
|
||||
DrawOSD(false);
|
||||
|
@ -752,7 +752,7 @@ void writeFramebufferToVRAM()
|
|||
glCheck();
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::RenderLastFrame()
|
||||
bool OpenGLRenderer::renderLastFrame()
|
||||
{
|
||||
GlFramebuffer *framebuffer = gl.ofbo2.ready ? gl.ofbo2.framebuffer.get() : gl.ofbo.framebuffer.get();
|
||||
if (framebuffer == nullptr)
|
||||
|
|
|
@ -1087,7 +1087,7 @@ void OpenGLRenderer::DrawOSD(bool clear_screen)
|
|||
{
|
||||
glcache.ClearColor(0.7f, 0.7f, 0.7f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
RenderLastFrame();
|
||||
renderLastFrame();
|
||||
glViewport(0, 0, settings.display.width, settings.display.height);
|
||||
}
|
||||
|
||||
|
@ -1098,7 +1098,6 @@ void OpenGLRenderer::DrawOSD(bool clear_screen)
|
|||
#endif
|
||||
SetupOSDVBO();
|
||||
|
||||
verify(glIsProgram(gl.OSD_SHADER.program));
|
||||
glcache.UseProgram(gl.OSD_SHADER.program);
|
||||
|
||||
float scale_h = settings.display.height / 480.f;
|
||||
|
@ -1401,7 +1400,7 @@ bool OpenGLRenderer::renderFrame(int width, int height)
|
|||
#ifndef LIBRETRO
|
||||
else {
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio();
|
||||
RenderLastFrame();
|
||||
renderLastFrame();
|
||||
}
|
||||
#endif
|
||||
bindVertexArray(0);
|
||||
|
|
|
@ -414,7 +414,14 @@ struct OpenGLRenderer : Renderer
|
|||
|
||||
void RenderFramebuffer(const FramebufferInfo& info) override;
|
||||
|
||||
bool RenderLastFrame() override;
|
||||
bool RenderLastFrame() override
|
||||
{
|
||||
saveCurrentFramebuffer();
|
||||
bool ret = renderLastFrame();
|
||||
restoreCurrentFramebuffer();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DrawOSD(bool clear_screen) override;
|
||||
|
||||
|
@ -451,6 +458,8 @@ protected:
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.origFbo);
|
||||
}
|
||||
|
||||
bool renderLastFrame();
|
||||
|
||||
private:
|
||||
bool renderFrame(int width, int height);
|
||||
|
||||
|
|
|
@ -2665,20 +2665,11 @@ static void gui_network_start()
|
|||
ImGui::Text("Starting...");
|
||||
try {
|
||||
if (networkStatus.get())
|
||||
{
|
||||
gui_state = GuiState::Closed;
|
||||
}
|
||||
else
|
||||
{
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
}
|
||||
gui_stop_game();
|
||||
} catch (const FlycastException& e) {
|
||||
if (NetworkHandshake::instance != nullptr)
|
||||
NetworkHandshake::instance->stop();
|
||||
emu.unloadGame();
|
||||
gui_error(e.what());
|
||||
gui_state = GuiState::Main;
|
||||
gui_stop_game(e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2700,8 +2691,7 @@ static void gui_network_start()
|
|||
}
|
||||
catch (const FlycastException& e) {
|
||||
}
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
gui_stop_game();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
@ -2759,12 +2749,10 @@ static void gui_display_loadscreen()
|
|||
}
|
||||
} catch (const FlycastException& ex) {
|
||||
ERROR_LOG(BOOT, "%s", ex.what());
|
||||
gui_error(ex.what());
|
||||
#ifdef TEST_AUTOMATION
|
||||
die("Game load failed");
|
||||
#endif
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
gui_stop_game(ex.what());
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
|
|
@ -95,7 +95,10 @@ void mainui_loop()
|
|||
fc_profiler::startThread("main");
|
||||
|
||||
mainui_rend_frame();
|
||||
imguiDriver->present();
|
||||
if (imguiDriver == nullptr)
|
||||
forceReinit = true;
|
||||
else
|
||||
imguiDriver->present();
|
||||
|
||||
if (config::RendererType != currentRenderer || forceReinit)
|
||||
{
|
||||
|
|
|
@ -578,9 +578,9 @@ void VulkanContext::CreateSwapChain()
|
|||
vk::Extent2D swapchainExtent;
|
||||
if (surfaceCapabilities.currentExtent.width == std::numeric_limits<uint32_t>::max())
|
||||
{
|
||||
// If the surface size is undefined, the size is set to the size of the images requested.
|
||||
swapchainExtent.width = std::min(std::max(640u, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
|
||||
swapchainExtent.height = std::min(std::max(480u, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
|
||||
// If the surface size is undefined, use the current display size
|
||||
swapchainExtent.width = std::min(std::max((u32)settings.display.width, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
|
||||
swapchainExtent.height = std::min(std::max((u32)settings.display.height, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
nameInfo.objectType = objectType;
|
||||
nameInfo.object = object;
|
||||
nameInfo.pObjectName = name.c_str();
|
||||
vkDebugMarkerSetObjectNameEXT((VkDevice)*device, &nameInfo);
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.vkDebugMarkerSetObjectNameEXT((VkDevice)*device, &nameInfo);
|
||||
}
|
||||
#endif
|
||||
constexpr static int VENDOR_AMD = 0x1022;
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
texCommandPool.Term();
|
||||
fbCommandPool.Term();
|
||||
framebufferTextures.clear();
|
||||
framebufferTexIndex = 0;
|
||||
shaderManager.term();
|
||||
}
|
||||
|
||||
|
@ -144,8 +145,6 @@ public:
|
|||
CheckFogTexture();
|
||||
CheckPaletteTexture();
|
||||
texCommandBuffer.end();
|
||||
if (!ctx->rend.isRTT)
|
||||
framebufferRendered = false;
|
||||
}
|
||||
|
||||
void ReInitOSD()
|
||||
|
@ -205,9 +204,11 @@ public:
|
|||
|
||||
void RenderFramebuffer(const FramebufferInfo& info) override
|
||||
{
|
||||
framebufferTexIndex = (framebufferTexIndex + 1) % GetContext()->GetSwapChainSize();
|
||||
|
||||
if (framebufferTextures.size() != GetContext()->GetSwapChainSize())
|
||||
framebufferTextures.resize(GetContext()->GetSwapChainSize());
|
||||
std::unique_ptr<Texture>& curTexture = framebufferTextures[GetContext()->GetCurrentImageIndex()];
|
||||
std::unique_ptr<Texture>& curTexture = framebufferTextures[framebufferTexIndex];
|
||||
if (!curTexture)
|
||||
{
|
||||
curTexture = std::unique_ptr<Texture>(new Texture());
|
||||
|
@ -293,13 +294,14 @@ protected:
|
|||
|
||||
bool presentFramebuffer()
|
||||
{
|
||||
if (GetContext()->GetCurrentImageIndex() >= (int)framebufferTextures.size())
|
||||
if (framebufferTexIndex >= (int)framebufferTextures.size())
|
||||
return false;
|
||||
Texture *fbTexture = framebufferTextures[GetContext()->GetCurrentImageIndex()].get();
|
||||
Texture *fbTexture = framebufferTextures[framebufferTexIndex].get();
|
||||
if (fbTexture == nullptr)
|
||||
return false;
|
||||
GetContext()->PresentFrame(fbTexture->GetImage(), fbTexture->GetImageView(), fbTexture->getSize(),
|
||||
getDCFramebufferAspectRatio());
|
||||
framebufferRendered = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -308,6 +310,7 @@ protected:
|
|||
std::unique_ptr<Texture> paletteTexture;
|
||||
CommandPool texCommandPool;
|
||||
std::vector<std::unique_ptr<Texture>> framebufferTextures;
|
||||
int framebufferTexIndex = 0;
|
||||
OSDPipeline osdPipeline;
|
||||
std::unique_ptr<Texture> vjoyTexture;
|
||||
std::unique_ptr<BufferData> osdBuffer;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
#include <SDL_video.h>
|
||||
#if defined(__APPLE__) && defined(USE_VULKAN)
|
||||
#if defined(USE_VULKAN)
|
||||
#include <SDL_vulkan.h>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@
|
|||
#endif
|
||||
|
||||
static SDL_Window* window = NULL;
|
||||
static u32 windowFlags;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
@ -287,6 +288,17 @@ void input_sdl_handle()
|
|||
|| event.window.event == SDL_WINDOWEVENT_MINIMIZED
|
||||
|| event.window.event == SDL_WINDOWEVENT_MAXIMIZED)
|
||||
{
|
||||
#ifdef USE_VULKAN
|
||||
if (windowFlags & SDL_WINDOW_VULKAN)
|
||||
SDL_Vulkan_GetDrawableSize(window, &settings.display.width, &settings.display.height);
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_OPENGL
|
||||
if (windowFlags & SDL_WINDOW_OPENGL)
|
||||
SDL_GL_GetDrawableSize(window, &settings.display.width, &settings.display.height);
|
||||
else
|
||||
#endif
|
||||
SDL_GetWindowSize(window, &settings.display.width, &settings.display.height);
|
||||
GraphicsContext::Instance()->resize();
|
||||
}
|
||||
else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
|
@ -468,6 +480,7 @@ HWND getNativeHwnd()
|
|||
|
||||
bool sdl_recreate_window(u32 flags)
|
||||
{
|
||||
windowFlags = flags;
|
||||
#ifdef _WIN32
|
||||
//Enable HiDPI mode in Windows
|
||||
typedef enum PROCESS_DPI_AWARENESS {
|
||||
|
|
|
@ -51,9 +51,14 @@
|
|||
#endif
|
||||
#include "profiler/fc_profiler.h"
|
||||
|
||||
#if defined(USE_SDL) || defined(DEF_CONSOLE)
|
||||
#include <nowide/args.hpp>
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#if !defined(USE_SDL) && !defined(DEF_CONSOLE)
|
||||
static PCHAR*
|
||||
commandLineToArgvA(
|
||||
PCHAR CmdLine,
|
||||
|
@ -147,6 +152,7 @@ static PCHAR*
|
|||
(*_argc) = argc;
|
||||
return argv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL
|
||||
|
||||
|
@ -844,10 +850,12 @@ int remove(char const *name)
|
|||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" int SDL_main(int argc, char* argv[])
|
||||
#ifdef USE_SDL
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
nowide::args _(argc, argv);
|
||||
|
||||
#elif defined(DEF_CONSOLE)
|
||||
// DEF_CONSOLE allows you to override linker subsystem and therefore default console
|
||||
|
@ -856,6 +864,7 @@ extern "C" int SDL_main(int argc, char* argv[])
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
nowide::args _(argc, argv);
|
||||
|
||||
#else
|
||||
#pragma comment(linker, "/subsystem:windows")
|
||||
|
|
|
@ -82,7 +82,7 @@ bool EGLGraphicsContext::init()
|
|||
}
|
||||
ANativeWindow_setBuffersGeometry((ANativeWindow *)window, 0, 0, format);
|
||||
#endif
|
||||
surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)window, NULL);
|
||||
surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)window, nullptr);
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ bool EGLGraphicsContext::init()
|
|||
EGLint contextAttrs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
|
||||
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
|
||||
EGL_NONE };
|
||||
context = eglCreateContext(display, config, NULL, contextAttrs);
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttrs);
|
||||
if (context != EGL_NO_CONTEXT)
|
||||
{
|
||||
makeCurrent();
|
||||
|
@ -121,7 +121,7 @@ bool EGLGraphicsContext::init()
|
|||
|
||||
EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2 , EGL_NONE };
|
||||
|
||||
context = eglCreateContext(display, config, NULL, contextAttrs);
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttrs);
|
||||
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
{
|
||||
|
@ -171,7 +171,7 @@ bool EGLGraphicsContext::init()
|
|||
void EGLGraphicsContext::term()
|
||||
{
|
||||
preTerm();
|
||||
eglMakeCurrent(display, NULL, NULL, EGL_NO_CONTEXT);
|
||||
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (context != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(display, context);
|
||||
if (surface != EGL_NO_SURFACE)
|
||||
|
|
|
@ -35,7 +35,6 @@ GraphicsContext *GraphicsContext::instance;
|
|||
|
||||
void initRenderApi(void *window, void *display)
|
||||
{
|
||||
bool dx11Failed = false;
|
||||
#ifdef USE_VULKAN
|
||||
if (isVulkan(config::RendererType))
|
||||
{
|
||||
|
@ -48,6 +47,7 @@ void initRenderApi(void *window, void *display)
|
|||
}
|
||||
#endif
|
||||
#ifdef USE_DX11
|
||||
bool dx11Failed = false;
|
||||
if (config::RendererType == RenderType::DirectX11 || config::RendererType == RenderType::DirectX11_OIT)
|
||||
{
|
||||
theDX11Context.setWindow(window, display);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.4.0' apply false
|
||||
id 'com.android.library' version '7.4.0' apply false
|
||||
id 'com.android.application' version '7.4.1' apply false
|
||||
id 'com.android.library' version '7.4.1' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
|
|
@ -341,14 +341,19 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(J
|
|||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj)
|
||||
{
|
||||
if (emu.running())
|
||||
{
|
||||
stopEmu();
|
||||
game_started = true; // restart when resumed
|
||||
if (config::AutoSaveState)
|
||||
dc_savestate(config::SavestateSlot);
|
||||
}
|
||||
gui_save();
|
||||
if (config::GGPOEnable)
|
||||
{
|
||||
stopEmu();
|
||||
gui_stop_game();
|
||||
}
|
||||
else if (emu.running())
|
||||
{
|
||||
stopEmu();
|
||||
game_started = true; // restart when resumed
|
||||
if (config::AutoSaveState)
|
||||
dc_savestate(config::SavestateSlot);
|
||||
}
|
||||
gui_save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNIEnv *env,jobject obj)
|
||||
|
@ -359,10 +364,8 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNI
|
|||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj)
|
||||
{
|
||||
stopEmu();
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
game_started = false;
|
||||
stopEmu();
|
||||
gui_stop_game();
|
||||
}
|
||||
|
||||
static void *render_thread_func(void *)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,7 +36,7 @@ Option<bool> FullMMU("");
|
|||
Option<bool> ForceWindowsCE(CORE_OPTION_NAME "_force_wince");
|
||||
Option<bool> AutoLoadState("");
|
||||
Option<bool> AutoSaveState("");
|
||||
Option<int> SavestateSlot("");
|
||||
Option<int, false> SavestateSlot("");
|
||||
Option<bool> ForceFreePlay(CORE_OPTION_NAME "_force_freeplay", true);
|
||||
|
||||
// Sound
|
||||
|
|
Loading…
Reference in New Issue