mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-03-21 17:49:58 -05:00
Triforce: Implement save states.
This commit is contained in:
parent
63dc3b1972
commit
aaa7094442
|
|
@ -152,6 +152,10 @@ static u8 s_network_buffer[512 * 1024];
|
|||
static u8 s_allnet_buffer[4096];
|
||||
static u8 s_allnet_settings[0x8500];
|
||||
|
||||
// Fake loading the game to have a chance to enter test mode
|
||||
static u32 s_board_status = LoadingGameProgram;
|
||||
static u32 s_load_progress = 80;
|
||||
|
||||
static constexpr std::size_t MAX_IPV4_STRING_LENGTH = 15;
|
||||
|
||||
constexpr char s_allnet_reply[] = {
|
||||
|
|
@ -441,6 +445,9 @@ void Init()
|
|||
std::ranges::fill(s_allnet_buffer, 0);
|
||||
std::ranges::fill(s_allnet_settings, 0);
|
||||
|
||||
s_board_status = LoadingGameProgram;
|
||||
s_load_progress = 80;
|
||||
|
||||
s_firmware_map = false;
|
||||
s_test_menu = false;
|
||||
|
||||
|
|
@ -1746,19 +1753,15 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||
break;
|
||||
case AMMBCommand::GetMediaBoardStatus:
|
||||
{
|
||||
// Fake loading the game to have a chance to enter test mode
|
||||
static u32 status = LoadingGameProgram;
|
||||
static u32 progress = 80;
|
||||
|
||||
s_media_buffer_32[1] = status;
|
||||
s_media_buffer_32[2] = progress;
|
||||
if (progress < 100)
|
||||
s_media_buffer_32[1] = s_board_status;
|
||||
s_media_buffer_32[2] = s_load_progress;
|
||||
if (s_load_progress < 100)
|
||||
{
|
||||
progress++;
|
||||
s_load_progress++;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = LoadedGameProgram;
|
||||
s_board_status = LoadedGameProgram;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1974,6 +1977,18 @@ bool GetTestMenu()
|
|||
return s_test_menu;
|
||||
}
|
||||
|
||||
static void CloseAllSockets()
|
||||
{
|
||||
for (u32 i = FIRST_VALID_FD; i < std::size(s_sockets); ++i)
|
||||
{
|
||||
if (s_sockets[i] != SOCKET_ERROR)
|
||||
{
|
||||
closesocket(s_sockets[i]);
|
||||
s_sockets[i] = SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
s_netcfg.Close();
|
||||
|
|
@ -1983,12 +1998,63 @@ void Shutdown()
|
|||
s_dimm.Close();
|
||||
s_dimm_disc.clear();
|
||||
|
||||
// Close all sockets
|
||||
for (u32 i = FIRST_VALID_FD; i < std::size(s_sockets); ++i)
|
||||
CloseAllSockets();
|
||||
}
|
||||
|
||||
void DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(s_firmware_map);
|
||||
p.Do(s_test_menu);
|
||||
p.Do(s_timeouts);
|
||||
p.Do(s_last_error);
|
||||
p.Do(s_gcam_key_a);
|
||||
p.Do(s_gcam_key_b);
|
||||
p.Do(s_gcam_key_c);
|
||||
p.Do(s_firmware);
|
||||
p.Do(s_media_buffer_32);
|
||||
p.Do(s_network_command_buffer);
|
||||
p.Do(s_network_buffer);
|
||||
p.Do(s_allnet_buffer);
|
||||
p.Do(s_allnet_settings);
|
||||
|
||||
p.Do(s_board_status);
|
||||
p.Do(s_load_progress);
|
||||
|
||||
// TODO: Handle the files better.
|
||||
// Data corruption is probably currently possible.
|
||||
|
||||
// s_netcfg
|
||||
// s_netctrl
|
||||
// s_extra
|
||||
// s_backup
|
||||
// s_dimm
|
||||
|
||||
// TODO: Handle sockets better.
|
||||
// For now, we just recreate a TCP socket for any socket that existed.
|
||||
// We should probably re-bind sockets and handle UDP sockets.
|
||||
|
||||
GuestFdSet created_sockets{};
|
||||
if (p.IsWriteMode() || p.IsVerifyMode())
|
||||
{
|
||||
if (s_sockets[i] != SOCKET_ERROR)
|
||||
for (u32 i = FIRST_VALID_FD; i < std::size(s_sockets); ++i)
|
||||
{
|
||||
closesocket(s_sockets[i]);
|
||||
if (s_sockets[i] != SOCKET_ERROR)
|
||||
created_sockets.SetFd(GuestSocket(i));
|
||||
}
|
||||
}
|
||||
|
||||
p.Do(created_sockets);
|
||||
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
CloseAllSockets();
|
||||
|
||||
for (u32 i = FIRST_VALID_FD; i < std::size(s_sockets); ++i)
|
||||
{
|
||||
if (!created_sockets.IsFdSet(GuestSocket(i)))
|
||||
continue;
|
||||
|
||||
s_sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
enum GameType
|
||||
|
|
@ -236,6 +237,7 @@ u32 GetGameType();
|
|||
u32 GetMediaType();
|
||||
bool GetTestMenu();
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
std::optional<std::pair<std::string_view, std::string_view>> ParseIPOverride(std::string_view str);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,12 @@ void DVDInterface::DoState(PointerWrap& p)
|
|||
m_system.GetDVDThread().DoState(p);
|
||||
|
||||
m_adpcm_decoder.DoState(p);
|
||||
|
||||
if (m_system.IsTriforce())
|
||||
{
|
||||
AMMediaboard::DoState(p);
|
||||
p.DoMarker("AMMediaboard");
|
||||
}
|
||||
}
|
||||
|
||||
size_t DVDInterface::ProcessDTKSamples(s16* target_samples, size_t target_block_count,
|
||||
|
|
|
|||
|
|
@ -228,9 +228,6 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
std::array<u8, 0x80> data_out{};
|
||||
u32 data_offset = 0;
|
||||
|
||||
static u32 dip_switch_1 = 0xFE;
|
||||
static u32 dip_switch_0 = 0xFF;
|
||||
|
||||
data_out[data_offset++] = 1;
|
||||
data_out[data_offset++] = 1;
|
||||
|
||||
|
|
@ -304,18 +301,18 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
if (AMMediaboard::GetGameType() == FZeroAX ||
|
||||
AMMediaboard::GetGameType() == FZeroAXMonster)
|
||||
{
|
||||
dip_switch_0 &= ~0x20;
|
||||
m_dip_switch_0 &= ~0x20;
|
||||
}
|
||||
|
||||
// Disable camera in MKGP1/2
|
||||
if (AMMediaboard::GetGameType() == MarioKartGP ||
|
||||
AMMediaboard::GetGameType() == MarioKartGP2)
|
||||
{
|
||||
dip_switch_0 &= ~0x10;
|
||||
m_dip_switch_0 &= ~0x10;
|
||||
}
|
||||
|
||||
data_out[data_offset++] = dip_switch_0;
|
||||
data_out[data_offset++] = dip_switch_1;
|
||||
data_out[data_offset++] = m_dip_switch_0;
|
||||
data_out[data_offset++] = m_dip_switch_1;
|
||||
break;
|
||||
}
|
||||
case GCAMCommand::SerialNumber:
|
||||
|
|
@ -1656,8 +1653,6 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
|
||||
JVSIOMessage message;
|
||||
|
||||
static int delay = 0;
|
||||
|
||||
const u8* const frame = &data_in[0];
|
||||
const u8 nr_bytes = frame[3]; // Byte after E0 xx
|
||||
u32 frame_len = nr_bytes + 3; // Header(2) + length byte + payload + checksum
|
||||
|
|
@ -1694,8 +1689,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
" - jvs_io(begin={}, current={}, end={}, n={})\n"
|
||||
" - delay={}, node={}\n"
|
||||
" - frame(begin={}, len={})",
|
||||
fmt::ptr(jvs_begin), fmt::ptr(jvs_io), fmt::ptr(jvs_end), n, delay, node,
|
||||
fmt::ptr(frame), frame_len);
|
||||
fmt::ptr(jvs_begin), fmt::ptr(jvs_io), fmt::ptr(jvs_end), n, m_delay,
|
||||
node, fmt::ptr(frame), frame_len);
|
||||
jvs_io = jvs_end;
|
||||
return false;
|
||||
};
|
||||
|
|
@ -2355,7 +2350,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
INFO_LOG_FMT(SERIALINTERFACE_JVSIO,
|
||||
"JVS-IO: Command 0x32, GPO: delay=0x{:02x}, rx_reply=0x{:02x},"
|
||||
" bytes={}, buffer:\n{}",
|
||||
delay, m_rx_reply, bytes, HexDump(jvs_io, bytes));
|
||||
m_delay, m_rx_reply, bytes, HexDump(jvs_io, bytes));
|
||||
|
||||
if (bytes < 3)
|
||||
{
|
||||
|
|
@ -2370,8 +2365,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
switch (seat_state)
|
||||
{
|
||||
case 0x70:
|
||||
delay++;
|
||||
if ((delay % 10) == 0)
|
||||
m_delay++;
|
||||
if ((m_delay % 10) == 0)
|
||||
{
|
||||
m_rx_reply = 0xFB;
|
||||
}
|
||||
|
|
@ -2429,13 +2424,13 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
if (*jvs_io++ == 0xD9)
|
||||
{
|
||||
NOTICE_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Command 0xF0, Reset");
|
||||
delay = 0;
|
||||
m_delay = 0;
|
||||
m_wheel_init = 0;
|
||||
m_ic_card_state = 0x20;
|
||||
}
|
||||
message.AddData(StatusOkay);
|
||||
|
||||
dip_switch_1 |= 1;
|
||||
m_dip_switch_1 |= 1;
|
||||
break;
|
||||
case JVSIOCommand::SetAddress:
|
||||
if (!validate_jvs_io(1, "SetAddress"))
|
||||
|
|
@ -2444,7 +2439,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||
NOTICE_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Command 0xF1, SetAddress: node={}",
|
||||
node);
|
||||
message.AddData(node == 1);
|
||||
dip_switch_1 &= ~1u;
|
||||
m_dip_switch_1 &= ~1u;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Unhandled: node={}, command={:02x}",
|
||||
|
|
@ -2739,4 +2734,73 @@ GCPadStatus CSIDevice_AMBaseboard::GetPadStatus()
|
|||
return pad_status;
|
||||
}
|
||||
|
||||
void CSIDevice_AMBaseboard::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_origin);
|
||||
p.Do(m_mode);
|
||||
p.Do(m_timer_button_combo_start);
|
||||
p.Do(m_last_button_combo);
|
||||
|
||||
p.Do(m_last);
|
||||
p.Do(m_lastptr);
|
||||
|
||||
p.Do(m_coin);
|
||||
p.Do(m_coin_pressed);
|
||||
|
||||
p.Do(m_ic_card_data);
|
||||
|
||||
// Setup IC-card
|
||||
p.Do(m_ic_card_state);
|
||||
p.Do(m_ic_card_status);
|
||||
p.Do(m_ic_card_session);
|
||||
|
||||
p.Do(m_ic_write_buffer);
|
||||
p.Do(m_ic_write_offset);
|
||||
p.Do(m_ic_write_size);
|
||||
|
||||
p.Do(m_card_memory);
|
||||
p.Do(m_card_read_packet);
|
||||
p.Do(m_card_buffer);
|
||||
|
||||
// Setup CARD
|
||||
p.Do(m_card_memory_size);
|
||||
p.Do(m_card_is_inserted);
|
||||
|
||||
p.Do(m_card_command);
|
||||
p.Do(m_card_clean);
|
||||
p.Do(m_card_write_length);
|
||||
p.Do(m_card_wrote);
|
||||
p.Do(m_card_read_length);
|
||||
p.Do(m_card_read);
|
||||
p.Do(m_card_bit);
|
||||
p.Do(m_card_shutter);
|
||||
p.Do(m_card_state_call_count);
|
||||
p.Do(m_card_offset);
|
||||
|
||||
// Serial
|
||||
p.Do(m_wheel_init);
|
||||
|
||||
p.Do(m_motor_init);
|
||||
p.Do(m_motor_reply);
|
||||
p.Do(m_motor_force_y);
|
||||
|
||||
// F-Zero AX (DX)
|
||||
p.Do(m_fzdx_seatbelt);
|
||||
p.Do(m_fzdx_motion_stop);
|
||||
p.Do(m_fzdx_sensor_right);
|
||||
p.Do(m_fzdx_sensor_left);
|
||||
p.Do(m_rx_reply);
|
||||
|
||||
// F-Zero AX (CyCraft)
|
||||
p.Do(m_fzcc_seatbelt);
|
||||
p.Do(m_fzcc_sensor);
|
||||
p.Do(m_fzcc_emergency);
|
||||
p.Do(m_fzcc_service);
|
||||
|
||||
p.Do(m_dip_switch_1);
|
||||
p.Do(m_dip_switch_0);
|
||||
|
||||
p.Do(m_delay);
|
||||
}
|
||||
|
||||
} // namespace SerialInterface
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ public:
|
|||
static bool NetPlay_GetInput(int pad_num, GCPadStatus* status);
|
||||
static int NetPlay_InGamePadToLocalPad(int pad_num);
|
||||
|
||||
void DoState(PointerWrap&) override;
|
||||
|
||||
protected:
|
||||
struct SOrigin
|
||||
{
|
||||
|
|
@ -311,6 +313,11 @@ private:
|
|||
bool m_fzcc_emergency = false;
|
||||
bool m_fzcc_service = false;
|
||||
|
||||
u32 m_dip_switch_1 = 0xFE;
|
||||
u32 m_dip_switch_0 = 0xFF;
|
||||
|
||||
int m_delay = 0;
|
||||
|
||||
void ICCardSendReply(ICCommand* iccommand, u8* buffer, u32* length);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user