mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-25 11:46:27 +00:00
bring exi slippi up to date
add desync recovery bits and some other clean up
This commit is contained in:
parent
2757adcbc7
commit
5e61a477cf
2 changed files with 79 additions and 84 deletions
|
@ -1600,7 +1600,7 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool should_skip)
|
|||
// Get pad data for each remote player and write each of their latest frame nums to the buf
|
||||
for (int i = 0; i < remote_player_count; i++)
|
||||
{
|
||||
results[i] = slippi_netplay->GetSlippiRemotePad(i, ROLLBACK_MAX_FRAMES);
|
||||
// results[i] = slippi_netplay->GetSlippiRemotePad(i, ROLLBACK_MAX_FRAMES);
|
||||
// results[i] = slippi_netplay->GetFakePadOutput(frame);
|
||||
|
||||
// determine offset from which to copy data
|
||||
|
@ -1658,6 +1658,8 @@ void CEXISlippi::handleCaptureSavestate(u8* payload)
|
|||
|
||||
s32 frame = payload[0] << 24 | payload[1] << 16 | payload[2] << 8 | payload[3];
|
||||
|
||||
// u64 startTime = Common::Timer::GetTimeUs();
|
||||
|
||||
// Grab an available savestate
|
||||
std::unique_ptr<SlippiSavestate> ss;
|
||||
if (!available_savestates.empty())
|
||||
|
@ -1683,7 +1685,7 @@ void CEXISlippi::handleCaptureSavestate(u8* payload)
|
|||
ss->Capture();
|
||||
active_savestates[frame] = std::move(ss);
|
||||
|
||||
// u32 timeDiff = (u32)(Common::Timer::NowUs() - startTime);
|
||||
// u32 timeDiff = static_cast<u32>(Common::Timer::NowUs() - startTime);
|
||||
// INFO_LOG_FMT(SLIPPI_ONLINE, "SLIPPI ONLINE: Captured savestate for frame {} in: {} ms", frame,
|
||||
// ((double)timeDiff) / 1000);
|
||||
}
|
||||
|
@ -1700,6 +1702,8 @@ void CEXISlippi::handleLoadSavestate(u8* payload)
|
|||
return;
|
||||
}
|
||||
|
||||
// u64 startTime = Common::Timer::GetTimeUs();
|
||||
|
||||
// Fetch preservation blocks
|
||||
std::vector<SlippiSavestate::PreserveBlock> blocks;
|
||||
|
||||
|
@ -1724,7 +1728,7 @@ void CEXISlippi::handleLoadSavestate(u8* payload)
|
|||
|
||||
active_savestates.clear();
|
||||
|
||||
// u32 timeDiff = (u32)(Common::Timer::NowUs() - startTime);
|
||||
// u32 timeDiff = static_cast<u32>(Common::Timer::NowUs() - startTime);
|
||||
// INFO_LOG_FMT(SLIPPI_ONLINE, "SLIPPI ONLINE: Loaded savestate for frame {} in: %f ms", frame,
|
||||
// ((double)timeDiff) / 1000);
|
||||
}
|
||||
|
@ -1740,18 +1744,19 @@ void CEXISlippi::startFindMatch(u8* payload)
|
|||
shift_jis_code.end());
|
||||
|
||||
// Log the direct code to file.
|
||||
if (search.mode == SlippiMatchmaking::DIRECT)
|
||||
{
|
||||
// Make sure to convert to UTF8, otherwise json library will fail when
|
||||
// calling dump().
|
||||
std::string utf8_code = SHIFTJISToUTF8(shift_jis_code);
|
||||
if (search.mode == SlippiMatchmaking::DIRECT)
|
||||
{
|
||||
direct_codes->AddOrUpdateCode(utf8_code);
|
||||
}
|
||||
else if (search.mode == SlippiMatchmaking::TEAMS)
|
||||
{
|
||||
std::string utf8_code = SHIFTJISToUTF8(shift_jis_code);
|
||||
teams_codes->AddOrUpdateCode(utf8_code);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make this work so we dont have to pass shiftJis to mm server
|
||||
// search.connect_code = SHIFTJISToUTF8(shift_jis_code).c_str();
|
||||
|
@ -1925,65 +1930,6 @@ void CEXISlippi::handleNameEntryLoad(u8* payload)
|
|||
appendWordToBuffer(&m_read_queue, curr_idx);
|
||||
}
|
||||
|
||||
// team_id 0 = red, 1 = blue, 2 = green
|
||||
int CEXISlippi::getCharColor(u8 char_id, u8 team_id)
|
||||
{
|
||||
switch (char_id)
|
||||
{
|
||||
case 0x0: // Falcon
|
||||
switch (team_id)
|
||||
{
|
||||
case 0:
|
||||
return 2;
|
||||
case 1:
|
||||
return 5;
|
||||
case 2:
|
||||
return 4;
|
||||
}
|
||||
case 0x2: // Fox
|
||||
switch (team_id)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 3;
|
||||
}
|
||||
case 0xC: // Peach
|
||||
switch (team_id)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return 3;
|
||||
case 2:
|
||||
return 4;
|
||||
}
|
||||
case 0x13: // Sheik
|
||||
switch (team_id)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 3;
|
||||
}
|
||||
case 0x14: // Falco
|
||||
switch (team_id)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEXISlippi::prepareOnlineMatchState()
|
||||
{
|
||||
// This match block is a VS match with P1 Red Falco vs P2 Red Bowser vs P3 Young Link vs P4 Young
|
||||
|
@ -2052,6 +1998,18 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
// reporting a match. So let's copy the results.
|
||||
recent_mm_result = matchmaking->GetMatchmakeResult();
|
||||
allowed_stages = recent_mm_result.stages;
|
||||
if (allowed_stages.empty())
|
||||
{
|
||||
allowed_stages = {
|
||||
0x2, // FoD
|
||||
0x3, // Pokemon
|
||||
0x8, // Yoshi's Story
|
||||
0x1C, // Dream Land
|
||||
0x1F, // Battlefield
|
||||
0x20, // Final Destination
|
||||
};
|
||||
}
|
||||
|
||||
// Clear stage pool so that when we call getRandomStage it will use full list
|
||||
stage_pool.clear();
|
||||
local_selections.stageId = getRandomStage();
|
||||
|
@ -2089,10 +2047,6 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
m_remote_player_idx = is_decider ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto is_decider = slippi_netplay->IsDecider();
|
||||
m_local_player_idx = is_decider ? 0 : 1;
|
||||
m_remote_player_idx = is_decider ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2134,6 +2088,27 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
opp_name = p2_name = "Player 2";
|
||||
#endif
|
||||
|
||||
SlippiDesyncRecoveryResp desync_recovery;
|
||||
if (slippi_netplay)
|
||||
{
|
||||
desync_recovery = slippi_netplay->GetDesyncRecoveryState();
|
||||
}
|
||||
|
||||
// If we have an active desync recovery and haven't received the opponent's state, wait
|
||||
if (desync_recovery.is_recovering && desync_recovery.is_waiting)
|
||||
{
|
||||
remote_players_ready = 0;
|
||||
}
|
||||
|
||||
if (desync_recovery.is_error)
|
||||
{
|
||||
// If desync recovery failed, just disconnect connection. Hopefully this will almost never
|
||||
// happen
|
||||
handleConnectionCleanup();
|
||||
prepareOnlineMatchState(); // run again with new state
|
||||
return;
|
||||
}
|
||||
|
||||
m_read_queue.push_back(local_player_ready); // Local player ready
|
||||
m_read_queue.push_back(remote_players_ready); // Remote players ready
|
||||
m_read_queue.push_back(m_local_player_idx); // Local player index
|
||||
|
@ -2223,8 +2198,8 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
}
|
||||
|
||||
// TODO: Ideally remotePlayerSelections would just include everyone including the local player
|
||||
// the local player
|
||||
// TODO: Would also simplify some logic in the Netplay class
|
||||
|
||||
// Here we are storing pointers to the player selections. That means that we can technically
|
||||
// modify the values from here, which is probably not the cleanest thing since they're coming
|
||||
// from the netplay class. Unfortunately, I think it might be required for the overwrite stuff
|
||||
|
@ -2396,13 +2371,27 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
right_team_players.resize(4, 0);
|
||||
left_team_players[3] = static_cast<u8>(left_team_size);
|
||||
right_team_players[3] = static_cast<u8>(right_team_size);
|
||||
|
||||
// Handle desync recovery. The default values in desync_recovery.state are 480 seconds (8 min
|
||||
// timer) and 4-stock/0 percent damage for the fighters. That means if we are not in a desync
|
||||
// recovery state, the state of the timer and fighters will be restored to the defaults
|
||||
u32* seconds_remaining = reinterpret_cast<u32*>(&online_match_block[0x10]);
|
||||
*seconds_remaining = Common::swap32(desync_recovery.state.seconds_remaining);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
online_match_block[0x62 + i * 0x24] = desync_recovery.state.fighters[i].stocks_remaining;
|
||||
|
||||
u16* current_health = reinterpret_cast<u16*>(&online_match_block[0x70 + i * 0x24]);
|
||||
*current_health = Common::swap16(desync_recovery.state.fighters[i].current_health);
|
||||
}
|
||||
}
|
||||
|
||||
// Add rng offset to output
|
||||
appendWordToBuffer(&m_read_queue, rng_offset);
|
||||
|
||||
// Add delay frames to output
|
||||
m_read_queue.push_back(static_cast<int>(Config::Get(Config::SLIPPI_ONLINE_DELAY)));
|
||||
m_read_queue.push_back(static_cast<u8>(Config::Get(Config::SLIPPI_ONLINE_DELAY)));
|
||||
|
||||
// Add chat messages id
|
||||
m_read_queue.push_back(static_cast<u8>(sent_chat_message_id));
|
||||
|
@ -2488,8 +2477,8 @@ void CEXISlippi::prepareOnlineMatchState()
|
|||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
std::string uid = i < player_info.size() ? player_info[i].uid :
|
||||
""; // UIDs are 28 characters + 1 null terminator
|
||||
// UIDs are 28 characters + 1 null terminator
|
||||
std::string uid = i < player_info.size() ? player_info[i].uid : "";
|
||||
#ifdef LOCAL_TESTING
|
||||
uid = default_uids[i];
|
||||
#endif
|
||||
|
@ -2615,6 +2604,15 @@ void CEXISlippi::prepareGctLoad(u8* payload)
|
|||
// This is the address where the codes will be written to
|
||||
auto address = Common::swap32(&payload[0]);
|
||||
|
||||
// SLIPPITODO: do we still need this?
|
||||
// // Overwrite the instructions which load address pointing to codeset
|
||||
// PowerPC::HostWrite_U32(0x3DE00000 | (address >> 16),
|
||||
// 0x80001f58); // lis r15, 0xXXXX # top half of address
|
||||
// PowerPC::HostWrite_U32(0x61EF0000 | (address & 0xFFFF),
|
||||
// 0x80001f5C); // ori r15, r15, 0xXXXX # bottom half of
|
||||
// address
|
||||
// PowerPC::ppcState.iCache.Invalidate(0x80001f58); // This should invalidate both instructions
|
||||
|
||||
INFO_LOG_FMT(SLIPPI, "Preparing to write gecko codes at: {:#x}", address);
|
||||
|
||||
m_read_queue.insert(m_read_queue.end(), gct.begin(), gct.end());
|
||||
|
@ -2745,6 +2743,7 @@ void CEXISlippi::handleLogInRequest()
|
|||
bool log_in_res = user->AttemptLogin();
|
||||
if (!log_in_res)
|
||||
{
|
||||
// no easy way to raise and lower the window
|
||||
user->OpenLogInPage();
|
||||
user->ListenForLogIn();
|
||||
}
|
||||
|
@ -2779,12 +2778,8 @@ void CEXISlippi::prepareOnlineStatus()
|
|||
m_read_queue.insert(m_read_queue.end(), player_name.begin(), player_name.end());
|
||||
|
||||
// Write connect code (10 bytes)
|
||||
std::string connect_code = user_info.connect_code;
|
||||
char shift_jis_hashtag[] = {'\x81', '\x94', '\x00'};
|
||||
connect_code.resize(CONNECT_CODE_LENGTH);
|
||||
connect_code = ReplaceAll(connect_code, "#", shift_jis_hashtag);
|
||||
auto code_buf = connect_code.c_str();
|
||||
m_read_queue.insert(m_read_queue.end(), code_buf, code_buf + CONNECT_CODE_LENGTH + 2);
|
||||
std::string connect_code = ConvertConnectCodeForGame(user_info.connect_code);
|
||||
m_read_queue.insert(m_read_queue.end(), connect_code.begin(), connect_code.end());
|
||||
}
|
||||
|
||||
void doConnectionCleanup(std::unique_ptr<SlippiMatchmaking> mm,
|
||||
|
@ -3264,6 +3259,7 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
WARN_LOG_FMT(SLIPPI, "default command byte case: {}", byte);
|
||||
writeToFileAsync(&mem_ptr[buf_loc], payload_len + 1, "");
|
||||
SlippiSpectateServer::getInstance().write(&mem_ptr[buf_loc], payload_len + 1);
|
||||
slprs_exi_device_reporter_push_replay_data(slprs_exi_device_ptr, &mem_ptr[buf_loc],
|
||||
|
|
|
@ -244,7 +244,6 @@ private:
|
|||
bool doesTagMatchInput(u8* input, u8 input_len, std::string tag);
|
||||
|
||||
std::vector<u8> loadPremadeText(u8* payload);
|
||||
int getCharColor(u8 char_id, u8 team_id);
|
||||
|
||||
void FileWriteThread(void);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue