Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
Flyinghead 2024-09-16 11:16:04 +02:00
commit 64d7199107
13 changed files with 529 additions and 410 deletions

View File

@ -18,7 +18,7 @@ jobs:
matrix:
config:
- {name: i686-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x86, cmakeArgs: -G Ninja, buildType: Release}
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DAPPLE_BREAKPAD=ON -DUSE_DISCORD=ON, destDir: osx, buildType: RelWithDebInfo}
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DUSE_DISCORD=ON, destDir: osx, buildType: RelWithDebInfo}
- {name: apple-ios, os: macos-latest, shell: sh, cmakeArgs: -DCMAKE_SYSTEM_NAME=iOS -G Xcode, destDir: ios, buildType: Release}
- {name: x86_64-pc-linux-gnu, os: ubuntu-20.04, shell: sh, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, destDir: linux, buildType: RelWithDebInfo}
- {name: x86_64-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x64, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, buildType: Release}

View File

@ -65,7 +65,7 @@ option(USE_DX11 "Build with Direct3D 11 support" ON)
option(LIBRETRO "Build libretro core" OFF)
option(USE_OPENGL "Use OpenGL API" ON)
option(USE_VIDEOCORE "RPI: use the legacy Broadcom GLES libraries" OFF)
option(APPLE_BREAKPAD "macOS: Build breakpad client and dump symbols" OFF)
option(USE_BREAKPAD "Build and link with breakpad library" ON)
option(ENABLE_GDB_SERVER "Build with GDB debugging support" OFF)
option(ENABLE_DC_PROFILER "Build with support for target machine (SH4) profiler" OFF)
option(ENABLE_FC_PROFILER "Build with support for host app (Flycast) profiler" OFF)
@ -266,7 +266,7 @@ if(NINTENDO_SWITCH)
target_include_directories(${PROJECT_NAME} PRIVATE shell/switch)
endif()
if(NOT LIBRETRO)
if(USE_BREAKPAD AND NOT LIBRETRO)
find_program(SH_EXECUTABLE sh)
if((ANDROID AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") OR (MINGW AND SH_EXECUTABLE) OR (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
add_subdirectory(core/deps/breakpad)
@ -275,7 +275,7 @@ if(NOT LIBRETRO)
endif()
target_link_libraries(${PROJECT_NAME} PUBLIC breakpad_client)
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_BREAKPAD)
elseif(APPLE AND NOT IOS AND APPLE_BREAKPAD)
elseif(APPLE AND NOT IOS)
target_sources(${PROJECT_NAME} PRIVATE
core/deps/breakpad/src/client/minidump_file_writer-inl.h
core/deps/breakpad/src/client/minidump_file_writer.cc

View File

@ -454,31 +454,6 @@ void CheatManager::reset(const std::string& gameId)
else if (gameId == "THE KING OF ROUTE66") {
cheats.emplace_back(Cheat::Type::setValue, "ignore drive error", true, 32, 0x00023ee0, 0x0009000B, true); // rts, nop
}
else if (gameId.substr(0, 8) == "MKG TKOB")
{
const auto& setMushikingCheats = [this](u32 addr) {
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 error", true, 32, addr, 0, true); // rfid[0].error = 0
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 error", true, 32, addr + 0x48, 0, true); // rfid[1].error = 0
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 status", true, 32, addr + 8, 0, true); // rfid[0].data18 = 0
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 status", true, 32, addr + 0x50, 0, true); // rfid[1].data18 = 0
};
if (gameId == "MKG TKOB 2 EXP VER1.001-") // mushi2eo
setMushikingCheats(0x6fe1bc);
else if (gameId == "MKG TKOB 2 JPN VER2.001-") // mushik2e
setMushikingCheats(0x6ffe54);
else if (gameId == "MKG TKOB 2K3 2ND VER1.003-")// mushike
setMushikingCheats(0x4ad7ec);
else if (gameId == "MKG TKOB 4 JPN VER2.000-") // mushik4e
setMushikingCheats(0xb0e538);
else if (gameId == "MKG TKOB 2K3 2ND VER1.002-")// mushikeo
setMushikingCheats(0x4ad56c);
else if (gameId == "MKG TKOB 2K3 2ND KOR VER1.000-") // mushikk
setMushikingCheats(0x4ac9b8);
else if (gameId == "MKG TKOB 2K3 2ND CHN VER1.000-") // mushikc
setMushikingCheats(0x4aa9b8);
else if (gameId == "MKG TKOB 2 KOR VER1.000-") // mushik2k
setMushikingCheats(0x706084);
}
else if (gameId == "T-8120N") { // Dave Mirra BMX (US)
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x0030b8cc, 0x42040000, true); // 33.0 ms
}

View File

@ -528,6 +528,7 @@ struct ChannelEx
enabled=false;
SetAegState(EG_Release);
AEG.SetValue(0x3FF);
CA = 0;
}
void enable()
@ -611,9 +612,12 @@ struct ChannelEx
clip_verify((s64)sample*oDsp>=0);
StepAEG(this);
StepFEG(this);
StepStream(this);
lfo.Step(this);
if (enabled)
{
StepFEG(this);
StepStream(this);
lfo.Step(this);
}
return true;
}
}
@ -854,8 +858,8 @@ struct ChannelEx
{
switch (offset)
{
case 0x00:
case 0x01:
case 0x00: // PCMS, SA
case 0x01: // KYONEX, KYONB, SSCTL, LPCTL, PCMS
UpdateStreamStep();
if (offset == 0 || size == 2)
UpdateSA();
@ -872,8 +876,8 @@ struct ChannelEx
}
break;
case 0x04:
case 0x05:
case 0x04: // SA
case 0x05: // SA
UpdateSA();
break;
@ -1219,7 +1223,7 @@ void AegStep(ChannelEx* ch)
if (ch->AEG.GetValue() >= 0x3FF)
{
aeg_printf("[%d]AEG_step : EG_Release End @ %x", ch->ChannelNumber, ch->AEG.GetValue());
ch->AEG.SetValue(0x3FF);
ch->disable();
}
break;
}
@ -1440,8 +1444,8 @@ void ReadCommonReg(u32 reg,bool byte)
CommonData->EG = aeg; //AEG is only 10 bits, FEG is 13 bits
CommonData->SGC=Chans[chan].AEG.state;
if (! (byte && reg==0x2810))
Chans[chan].loop.looped=0;
if (!byte || reg == 0x2811)
Chans[chan].loop.looped = 0;
}
break;
case 0x2814: //CA

View File

@ -241,6 +241,10 @@ static void createNaomiDevices()
{
mcfg_Create(MDT_RFIDReaderWriter, 1, 5, 0);
mcfg_Create(MDT_RFIDReaderWriter, 2, 5, 1);
if (gameId.substr(0, 8) == "MKG TKOB") {
insertRfidCard(0);
insertRfidCard(1);
}
}
else
{

View File

@ -1729,21 +1729,22 @@ struct RFIDReaderWriter : maple_base
DEBUG_LOG(MAPLE, "RFID card read (data? %d)", d4Seen);
w32(getStatus());
if (!d4Seen)
w32(0x12345678); // arbitrary value (unknown)
// serial0 and serial1 only
wptr(cardData, 8);
else
wptr(cardData, sizeof(cardData));
return (MapleDeviceRV)0xfe;
case 0xD9: // lock card
w32(getStatus());
cardLocked = true;
w32(getStatus());
INFO_LOG(MAPLE, "RFID card %d locked", player_num);
return (MapleDeviceRV)0xfe;
case 0xDA: // unlock card
w32(getStatus());
cardLocked = false;
cardInserted = false;
w32(getStatus());
NOTICE_LOG(MAPLE, "RFID card %d unlocked", player_num);
os_notify("Card ejected", 2000);
return (MapleDeviceRV)0xfe;
@ -1760,6 +1761,34 @@ struct RFIDReaderWriter : maple_base
return (MapleDeviceRV)0xfe;
}
case 0xD1: // decrement counter
{
int counter = r8();
switch (counter) {
case 0x03:
counter = 0;
break;
case 0x0c:
counter = 1;
break;
case 0x30:
counter = 2;
break;
case 0xc0:
counter = 3;
break;
default:
WARN_LOG(MAPLE, "Unknown counter selector %x", counter);
counter = 0;
break;
}
DEBUG_LOG(MAPLE, "RFID decrement %d", counter);
cardData[19 - counter]--;
saveCard();
w32(getStatus());
return (MapleDeviceRV)0xfe;
}
default:
INFO_LOG(MAPLE, "RFIDReaderWriter: unknown MAPLE COMMAND %d", cmd);
return MDRE_UnknownCmd;
@ -1795,24 +1824,62 @@ struct RFIDReaderWriter : maple_base
FILE *fp = nowide::fopen(path.c_str(), "rb");
if (fp == nullptr)
{
static u8 blankCard[128] = {
0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,0x6c, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xff
};
// Generate random bytes used by vf4 vanilla to make the card id
srand(time(0));
blankCard[2] = rand() & 0xff;
blankCard[4] = rand() & 0xff;
blankCard[5] = rand() & 0xff;
blankCard[6] = rand() & 0xff;
blankCard[7] = rand() & 0xff;
memcpy(cardData, blankCard, sizeof(blankCard));
if (settings.content.gameId.substr(0, 8) == "MKG TKOB")
{
constexpr u8 MUSHIKING_CHIP_DATA[128] = {
0x12, 0x34, 0x56, 0x78, // Serial No.0
0x31, 0x00, 0x86, 0x07, // Serial No.1
0x00, 0x00, 0x00, 0x00, // Key
0x04, 0xf6, 0x00, 0xAA, // Extend Extend Access Mode
0x23, 0xFF, 0xFF, 0xFF, // Counter4 Counter3 Counter2 Counter1
0x00, 0x00, 0x00, 0x00, // User Data (first set date: day bits 0-4, month bits 5-8, year bits 9-... + 2000)
0x00, 0x00, 0x00, 0x00, // User Data
0x00, 0x00, 0x00, 0x00, // User Data
0x00, 0x00, 0x00, 0x00, // User Data
0x00, 0x00, 0x00, 0x00, // User Data
0x00, 0x00, 0x00, 0x00, // User Data
0x23, 0xFF, 0xFF, 0xFF, // User Data (max counters)
};
memcpy(cardData, MUSHIKING_CHIP_DATA, sizeof(MUSHIKING_CHIP_DATA));
for (int i = 0; i < 8; i++)
cardData[i] = rand() & 0xff;
u32 mask = 0;
if (settings.content.gameId == "MKG TKOB 2 JPN VER2.001-" // mushik2e
|| settings.content.gameId == "MKG TKOB 4 JPN VER2.000-") // mushik4e
mask = 0x40;
cardData[4] &= ~0xc0;
cardData[4] |= mask;
u32 serial1 = (cardData[4] << 24) | (cardData[5] << 16) | (cardData[6] << 8) | cardData[7];
u32 key = ~serial1;
key = ((key >> 4) & 0x0f0f0f0f)
| ((key << 4) & 0xf0f0f0f0);
cardData[8] = key >> 24;
cardData[9] = key >> 16;
cardData[10] = key >> 8;
cardData[11] = key;
}
else
{
constexpr u8 VF4_CARD_DATA[128] = {
0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,0x6c, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xff
};
memcpy(cardData, VF4_CARD_DATA, sizeof(VF4_CARD_DATA));
// Generate random bytes used by vf4 vanilla to make the card id
srand(time(0));
cardData[2] = rand() & 0xff;
cardData[4] = rand() & 0xff;
cardData[5] = rand() & 0xff;
cardData[6] = rand() & 0xff;
cardData[7] = rand() & 0xff;
}
INFO_LOG(NAOMI, "Card P%d initialized", player_num + 1);
}
else

View File

@ -2267,7 +2267,7 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou
}
else
{
axis_value = read_analog_axis(player_num, axisDesc.axis, axisDesc.inverted);
axis_value = read_analog_axis(player_num, axisDesc.axis, axisDesc.inverted);
}
}
else
@ -2280,6 +2280,12 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou
axis_value = read_analog_axis(player_num, player_axis, false);
}
LOGJVS("%d:%4x ", axis, axis_value);
// Strangely, the least significant byte appears to be handled as signed,
// so we compensate when it's negative.
// Avoid overflow (wild riders)
axis_value = std::min<u16>(0xff7f, axis_value);
if (axis_value & 0x80)
axis_value += 0x100;
JVS_OUT(axis_value >> 8);
JVS_OUT(axis_value);
}

View File

@ -2492,7 +2492,7 @@ const Game Games[] =
nullptr,
// no free play with eeprom
},
// Mushiking The King Of Beetles - Mushiking IV / V / VI (World)
// Mushiking The King Of Beetles 2004 Second (Japan)
{
"mushi2k4",
NULL,
@ -4725,7 +4725,7 @@ const Game Games[] =
{ NULL, 0, 0 },
}
},
// MushiKing II - The King Of Beetle II ENG (Ver. 1.001)
// Mushiking The King Of Beetles - Mushiking II / III / III+ (World, Ver. 2.001)
{
"mushik2e",
NULL,
@ -4749,6 +4749,7 @@ const Game Games[] =
},
// Mushiking The King Of Beetles - Mushiking IV / V / VI (World)
// change game version (4/5/6): in BACKUP DATA CLEAR menu hold P1 and P2 buttons 1 for 3 seconds, then change version number in appeared menu and select YES(CLEAR)
// ~equivalent of Japanese 2K6 versions
{
"mushik4e",
NULL,
@ -4759,14 +4760,31 @@ const Game Games[] =
M4,
ROT0,
{
{ "fpr-24417.ic8", 0x0000000, 0x4000000 },
{ "fpr-24418.ic9", 0x4000000, 0x4000000 },
{ "fpr-24417.ic8", 0x0000000, 0x4000000, 0x01278cbb },
{ "fpr-24418.ic9", 0x4000000, 0x4000000, 0x7c8d7687 },
//ROM_REGION( 0x800, "pic_readout", 0 )
//ROM_LOAD( "317-0437-com.ic3", 0, 0x800, CRC(3b6fcee8) SHA1(65fbdd3b8c61a4b5ccb6389b25483a7ecdc0794d) )
{ "317-0437-com.ic3", 0, 0x800, 0x0000000, Key },
{ "317-0437-com.ic3", 0, 0x800, 0x3b6fcee8, Key },
}
},
// Mushiking The King Of Beetles - Mushiking IV / V / VI (Taiwan)
// change game version (4/5/6): in BACKUP DATA CLEAR menu hold P1 and P2 buttons 1 for 3 seconds, then change version number in appeared menu and select YES(CLEAR)
// ~equivalent of Japanese 2K6 versions
{
"mushik4t",
"mushik4e",
"Mushiking The King Of Beetles - Mushiking IV / V / VI (Taiwan)",
0x8000000,
0x5502,
"naomi",
M4,
ROT0,
{
{ "fpr-24420.ic8", 0x0000000, 0x4000000, 0x4a44a604 },
{ "fpr-24421.ic9", 0x4000000, 0x4000000, 0xaf137021 }, // BAD DUMP
{ NULL, 0, 0 },
//ROM_REGION( 0x800, "pic_readout", 0 )
{ "317-0437-com.ic3", 0, 0x800, 0x3b6fcee8, Key },
}
},
{

View File

@ -138,9 +138,10 @@ public:
void Init(SamplerManager *samplerManager, OITShaderManager *shaderManager, OITBuffers *oitBuffers,
const vk::Extent2D& viewport)
{
if (!screenPipelineManager)
if (!screenPipelineManager) {
screenPipelineManager = std::make_unique<OITPipelineManager>();
screenPipelineManager->Init(shaderManager, oitBuffers);
screenPipelineManager->Init(shaderManager, oitBuffers);
}
OITDrawer::Init(samplerManager, screenPipelineManager.get(), oitBuffers);
MakeFramebuffers(viewport);

View File

@ -28,10 +28,10 @@ vk::UniqueRenderPass RenderPasses::MakeRenderPass(bool initial, bool last, bool
attach0,
// OP+PT color attachment
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::Format::eR8G8B8A8Unorm, vk::SampleCountFlagBits::e1,
initial ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,
loadClear && initial ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,
last ? vk::AttachmentStoreOp::eDontCare : vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
initial ? vk::ImageLayout::eUndefined : attach0.finalLayout, attach0.finalLayout), // initial layout is eUndefined for rtt, so use final layout instead
loadClear && initial ? vk::ImageLayout::eUndefined : attach0.finalLayout, attach0.finalLayout), // initial layout is eUndefined for rtt, so use final layout instead
// OP+PT depth attachment
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), GetContext()->GetDepthFormat(), vk::SampleCountFlagBits::e1,
initial ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,

View File

@ -44,7 +44,7 @@ protected:
virtual vk::AttachmentDescription GetAttachment0Description(bool initial, bool last, bool loadClear) const
{
return vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::Format::eR8G8B8A8Unorm, vk::SampleCountFlagBits::e1,
loadClear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore,
initial && loadClear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
config::EmulateFramebuffer && initial ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eShaderReadOnlyOptimal,
config::EmulateFramebuffer && last ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eShaderReadOnlyOptimal);

View File

@ -694,13 +694,16 @@ void VulkanContext::CreateSwapChain()
framebuffers.reserve(imageViews.size());
drawFences.reserve(imageViews.size());
renderCompleteSemaphores.reserve(imageViews.size());
imageAcquiredSemaphores.reserve(imageViews.size());
for (auto const& view : imageViews)
{
framebuffers.push_back(device->createFramebufferUnique(vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(), *renderPass,
view.get(), width, height, 1)));
drawFences.push_back(device->createFenceUnique(vk::FenceCreateInfo(vk::FenceCreateFlagBits::eSignaled)));
}
renderCompleteSemaphores.reserve(imageViews.size() + 1);
imageAcquiredSemaphores.reserve(imageViews.size() + 1);
for (unsigned i = 0; i < imageViews.size() + 1; i++)
{
renderCompleteSemaphores.push_back(device->createSemaphoreUnique(vk::SemaphoreCreateInfo()));
imageAcquiredSemaphores.push_back(device->createSemaphoreUnique(vk::SemaphoreCreateInfo()));
}
@ -865,14 +868,14 @@ void VulkanContext::Present() noexcept
DoSwapAutomation();
vk::Result res = presentQueue.presentKHR(vk::PresentInfoKHR(1, &(*renderCompleteSemaphores[currentSemaphore]), 1, &(*swapChain), &currentImage));
(void)res;
currentSemaphore = (currentSemaphore + 1) % imageViews.size();
currentSemaphore = (currentSemaphore + 1) % renderCompleteSemaphores.size();
if (lastFrameView && IsValid() && !gui_is_open())
for (int i = 1; i < swapInterval; i++)
{
PresentFrame(vk::Image(), lastFrameView, lastFrameExtent, lastFrameAR);
res = presentQueue.presentKHR(vk::PresentInfoKHR(1, &(*renderCompleteSemaphores[currentSemaphore]), 1, &(*swapChain), &currentImage));
currentSemaphore = (currentSemaphore + 1) % imageViews.size();
currentSemaphore = (currentSemaphore + 1) % renderCompleteSemaphores.size();
}
} catch (const vk::SystemError& e) {
// Happens when resizing the window

File diff suppressed because it is too large Load Diff