Triforce: Code cleanups.

This commit is contained in:
Jordan Woyak 2025-10-26 21:53:53 -05:00
parent 083faa8b21
commit be2da8dc7b
9 changed files with 390 additions and 456 deletions

View File

@ -38,17 +38,20 @@
#include <unistd.h>
#define closesocket close
#define ioctlsocket ioctl
static constexpr auto* closesocket = close;
static auto ioctlsocket(auto... args)
{
return ioctl(args...);
}
#define WSAEWOULDBLOCK 10035L
#define SOCKET_ERROR (-1)
static constexpr int WSAEWOULDBLOCK = 10035;
static constexpr int SOCKET_ERROR = -1;
typedef int SOCKET;
using SOCKET = int;
#define INVALID_SOCKET (SOCKET)(~0)
static constexpr auto INVALID_SOCKET = SOCKET(~0);
static int WSAGetLastError(void)
static int WSAGetLastError()
{
switch (errno)
{
@ -69,12 +72,12 @@ namespace AMMediaboard
static bool s_firmware_map = false;
static bool s_test_menu = false;
static SOCKET s_namco_cam = 0;
static u32 s_timeouts[3] = {20000, 20000, 20000};
static std::array<u32, 3> s_timeouts = {20000, 20000, 20000};
static u32 s_last_error = SSC_SUCCESS;
static u32 s_GCAM_key_a = 0;
static u32 s_GCAM_key_b = 0;
static u32 s_GCAM_key_c = 0;
static u32 s_gcam_key_a = 0;
static u32 s_gcam_key_b = 0;
static u32 s_gcam_key_c = 0;
static File::IOFile s_netcfg;
static File::IOFile s_netctrl;
@ -82,7 +85,7 @@ static File::IOFile s_extra;
static File::IOFile s_backup;
static File::IOFile s_dimm;
Common::UniqueBuffer<u8> s_dimm_disc;
static Common::UniqueBuffer<u8> s_dimm_disc;
static u8 s_firmware[2 * 1024 * 1024];
static u32 s_media_buffer_32[192];
@ -103,6 +106,15 @@ constexpr char s_allnet_reply[] = {
static SOCKET s_sockets[64];
static constexpr u32 SocketCheck(u32 x)
{
if (x < std::size(s_sockets))
return x;
WARN_LOG_FMT(AMMEDIABOARD, "Bad SOCKET value: {}", x);
return 0;
}
static SOCKET socket_(int af, int type, int protocol)
{
for (u32 i = 1; i < 64; ++i)
@ -118,13 +130,13 @@ static SOCKET socket_(int af, int type, int protocol)
return SOCKET_ERROR;
}
static SOCKET accept_(int fd, sockaddr* addr, int* len)
static SOCKET accept_(int fd, sockaddr* addr, socklen_t* len)
{
for (u32 i = 1; i < 64; ++i)
{
if (s_sockets[i] == SOCKET_ERROR)
{
s_sockets[i] = accept(fd, addr, (socklen_t*)len);
s_sockets[i] = accept(fd, addr, len);
if (s_sockets[i] == SOCKET_ERROR)
return SOCKET_ERROR;
return i;
@ -155,9 +167,9 @@ void FirmwareMap(bool on)
void InitKeys(u32 key_a, u32 key_b, u32 key_c)
{
s_GCAM_key_a = key_a;
s_GCAM_key_b = key_b;
s_GCAM_key_c = key_c;
s_gcam_key_a = key_a;
s_gcam_key_b = key_b;
s_gcam_key_c = key_c;
}
static File::IOFile OpenOrCreateFile(const std::string& filename)
@ -185,9 +197,9 @@ void Init()
s_last_error = SSC_SUCCESS;
s_GCAM_key_a = 0;
s_GCAM_key_b = 0;
s_GCAM_key_c = 0;
s_gcam_key_a = 0;
s_gcam_key_b = 0;
s_gcam_key_c = 0;
const std::string base_path = File::GetUserPath(D_TRIUSER_IDX);
@ -236,48 +248,48 @@ u8* InitDIMM(u32 size)
if (size == 0)
return nullptr;
if (!s_dimm_disc.size())
if (s_dimm_disc.empty())
{
s_dimm_disc.reset(size);
if (!s_dimm_disc.size())
if (s_dimm_disc.empty())
{
PanicAlertFmt("Failed to allocate DIMM memory.");
return nullptr;
}
}
s_firmware_map = 0;
s_firmware_map = false;
return s_dimm_disc.data();
}
static s32 NetDIMMAccept(int fd, sockaddr* addr, int* len)
static s32 NetDIMMAccept(int fd, sockaddr* addr, socklen_t* len)
{
SOCKET clientSock = INVALID_SOCKET;
SOCKET client_sock = INVALID_SOCKET;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 10000; // 10 milliseconds
timeval timeout{
.tv_sec = 0,
.tv_usec = 10000, // 10 milliseconds
};
const int result = select(fd + 1, &readfds, nullptr, nullptr, &timeout);
if (result > 0 && FD_ISSET(fd, &readfds))
{
clientSock = accept_(fd, addr, len);
if (clientSock != INVALID_SOCKET)
client_sock = accept_(fd, addr, len);
if (client_sock != INVALID_SOCKET)
{
s_last_error = SSC_SUCCESS;
return clientSock;
}
else
{
s_last_error = SOCKET_ERROR;
return SOCKET_ERROR;
return client_sock;
}
s_last_error = SOCKET_ERROR;
return SOCKET_ERROR;
}
else if (result == 0)
if (result == 0)
{
// Timeout
s_last_error = SSC_EWOULDBLOCK;
@ -336,7 +348,7 @@ static s32 NetDIMMConnect(int fd, sockaddr_in* addr, int len)
FD_ZERO(&writefds);
FD_SET(fd, &writefds);
timeval timeout;
timeval timeout{};
timeout.tv_sec = 0;
timeout.tv_usec = s_timeouts[0];
@ -394,26 +406,26 @@ static void FileWriteData(File::IOFile* file, u32 seek_pos, const u8* data, std:
file->Flush();
}
u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32 length)
u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length)
{
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
DICMDBUF[0] ^= s_GCAM_key_a;
DICMDBUF[1] ^= s_GCAM_key_b;
DICMDBUF[2] ^= s_GCAM_key_c;
dicmd_buf[0] ^= s_gcam_key_a;
dicmd_buf[1] ^= s_gcam_key_b;
dicmd_buf[2] ^= s_gcam_key_c;
const u32 seed = DICMDBUF[0] >> 16;
const u32 seed = dicmd_buf[0] >> 16;
s_GCAM_key_a *= seed;
s_GCAM_key_b *= seed;
s_GCAM_key_c *= seed;
s_gcam_key_a *= seed;
s_gcam_key_b *= seed;
s_gcam_key_c *= seed;
// Key setup for Triforce IPL:
// These RAM offsets always hold the key for the next command. Since two dummy commands are sent
// before any real ones, you can just use the key from RAM without missing a real command.
if (s_GCAM_key_a == 0)
if (s_gcam_key_a == 0)
{
if (memory.Read_U32(0))
{
@ -424,12 +436,12 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
}
const u32 command = DICMDBUF[0] << 24;
const u32 offset = DICMDBUF[1] << 2;
const u32 command = dicmd_buf[0] << 24;
const u32 offset = dicmd_buf[1] << 2;
DEBUG_LOG_FMT(AMMEDIABOARD,
"GC-AM: {:08x} {:08x} DMA=addr:{:08x},len:{:08x} Keys: {:08x} {:08x} {:08x}",
command, offset, address, length, s_GCAM_key_a, s_GCAM_key_b, s_GCAM_key_c);
command, offset, address, length, s_gcam_key_a, s_gcam_key_b, s_gcam_key_c);
// Test mode
if (offset == 0x0002440)
@ -440,7 +452,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
// Don't map firmware while in SegaBoot
if (memory.Read_U32(0x8006BF70) != 0x0A536567)
{
s_firmware_map = 1;
s_firmware_map = true;
}
}
}
@ -457,14 +469,14 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
switch (GetGameType())
{
default:
*DIIMMBUF = Version1;
*diimm_buf = Version1;
return 0;
case VirtuaStriker4_2006:
case KeyOfAvalon:
case MarioKartGP:
case MarioKartGP2:
case FirmwareUpdate:
*DIIMMBUF = Version2;
*diimm_buf = Version2;
return 0;
}
break;
@ -629,8 +641,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
if (offset == DIMMCommandExecute2)
{
const AMMBCommand ammb_command =
static_cast<AMMBCommand>(*reinterpret_cast<u16*>(s_media_buffer + 0x202));
const AMMBCommand ammb_command = Common::BitCastPtr<AMMBCommand>(s_media_buffer + 0x202);
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Execute command: (2){0:04X}",
static_cast<u16>(ammb_command));
@ -661,10 +672,10 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Accept:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
int ret = -1;
sockaddr addr;
int len = 0;
socklen_t len = 0;
// Handle optional parameters
if (s_media_buffer_32[3] == 0 || s_media_buffer_32[4] == 0)
@ -691,13 +702,12 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Bind:
{
sockaddr_in addr;
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
const u32 len = s_media_buffer_32[4];
memcpy((void*)&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
sockaddr_in addr;
memcpy(&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
addr.sin_family = Common::swap16(addr.sin_family);
@ -708,7 +718,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
addr.sin_addr.s_addr = INADDR_ANY;
const int ret = bind(fd, (const sockaddr*)&addr, len);
const int ret = bind(fd, reinterpret_cast<const sockaddr*>(&addr), len);
const int err = WSAGetLastError();
if (ret < 0)
@ -724,7 +734,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Closesocket:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const int ret = closesocket(fd);
@ -739,13 +749,12 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Connect:
{
sockaddr_in addr;
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
const u32 len = s_media_buffer_32[4];
memcpy((void*)&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
sockaddr_in addr;
memcpy(&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
const int ret = NetDIMMConnect(fd, &addr, len);
@ -759,9 +768,10 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::InetAddr:
{
const u32 ip = inet_addr((char*)s_network_command_buffer);
const u32 ip = inet_addr(reinterpret_cast<char*>(s_network_command_buffer));
// TODO: This expects null termination?
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: InetAddr( {} )\n",
(char*)s_network_command_buffer);
reinterpret_cast<char*>(s_network_command_buffer));
s_media_buffer[1] = s_media_buffer[8];
s_media_buffer_32[1] = Common::swap32(ip);
@ -769,7 +779,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Listen:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 backlog = s_media_buffer_32[3];
const int ret = listen(fd, backlog);
@ -782,20 +792,15 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Recv:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 off = s_media_buffer_32[3];
u32 len = s_media_buffer_32[4];
const auto len = std::min<u32>(s_media_buffer_32[4], sizeof(s_network_buffer));
if (len >= sizeof(s_network_buffer))
{
len = sizeof(s_network_buffer);
}
u8* buffer = reinterpret_cast<u8*>(s_network_buffer + off);
u8* buffer = s_network_buffer + off;
if (off >= NetworkBufferAddress4 && off < NetworkBufferAddress4 + sizeof(s_network_buffer))
{
buffer = reinterpret_cast<u8*>(s_network_buffer + off - NetworkBufferAddress4);
buffer = s_network_buffer + off - NetworkBufferAddress4;
}
else
{
@ -814,7 +819,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Send:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
u32 off = s_media_buffer_32[3];
const u32 len = s_media_buffer_32[4];
@ -853,7 +858,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::Select:
{
u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2] - 1)];
auto fd = s_sockets[SocketCheck(s_media_buffer_32[2] - 1)];
// BUG: NAMCAM is hardcoded to call this with socket ID 0x100 which might be some magic
// thing? A valid value is needed so we use the socket from the connect.
@ -869,43 +874,41 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
fd_set* readfds = nullptr;
fd_set* writefds = nullptr;
fd_set* exceptfds = nullptr;
timeval timeout = {};
timeval* timeout_src = nullptr;
u8* timeout_src = nullptr;
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
// Only one of 3, 4, 5 is ever set alongside 6
if (s_media_buffer_32[3] && s_media_buffer_32[6])
if (s_media_buffer_32[6] != 0)
{
const u32 ROffset = s_media_buffer_32[6] - NetworkCommandAddress2;
readfds = reinterpret_cast<fd_set*>(s_network_command_buffer + ROffset);
FD_ZERO(readfds);
FD_SET(fd, readfds);
const u32 fd_offset = s_media_buffer_32[6] - NetworkCommandAddress2;
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer + s_media_buffer_32[3] -
NetworkCommandAddress2);
}
else if (s_media_buffer_32[4] && s_media_buffer_32[6])
{
const u32 WOffset = s_media_buffer_32[6] - NetworkCommandAddress2;
writefds = reinterpret_cast<fd_set*>(s_network_command_buffer + WOffset);
FD_ZERO(writefds);
FD_SET(fd, writefds);
// TODO: Check that fd_offset is in bounds of of s_network_command_buffer.
Common::BitCastPtr<fd_set>(s_network_command_buffer + fd_offset) = fds;
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer + s_media_buffer_32[4] -
NetworkCommandAddress2);
}
else if (s_media_buffer_32[5] && s_media_buffer_32[6])
{
const u32 EOffset = s_media_buffer_32[6] - NetworkCommandAddress2;
exceptfds = reinterpret_cast<fd_set*>(s_network_command_buffer + EOffset);
FD_ZERO(exceptfds);
FD_SET(fd, exceptfds);
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer + s_media_buffer_32[5] -
NetworkCommandAddress2);
if (s_media_buffer_32[3] != 0)
{
readfds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[3] - NetworkCommandAddress2;
}
else if (s_media_buffer_32[4] != 0)
{
writefds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[4] - NetworkCommandAddress2;
}
else if (s_media_buffer_32[5] != 0)
{
exceptfds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[5] - NetworkCommandAddress2;
}
}
// Copy timeout if set
if (timeout_src)
if (timeout_src != nullptr)
{
std::memcpy(&timeout, timeout_src, sizeof(timeval));
}
@ -935,11 +938,11 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::SetSockOpt:
{
const SOCKET fd = (SOCKET)(s_sockets[SocketCheck(s_media_buffer_32[2])]);
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const int level = (int)(s_media_buffer_32[3]);
const int optname = (int)(s_media_buffer_32[4]);
const char* optval =
(char*)(s_network_command_buffer + s_media_buffer_32[5] - NetworkCommandAddress2);
const char* optval = reinterpret_cast<char*>(s_network_command_buffer +
s_media_buffer_32[5] - NetworkCommandAddress2);
const int optlen = (int)(s_media_buffer_32[6]);
const int ret = setsockopt(fd, level, optname, optval, optlen);
@ -956,34 +959,36 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::SetTimeOuts:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 timeoutA = s_media_buffer_32[3];
const u32 timeoutB = s_media_buffer_32[4];
const u32 timeoutC = s_media_buffer_32[5];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const u32 timeout_a = s_media_buffer_32[3];
const u32 timeout_b = s_media_buffer_32[4];
const u32 timeout_c = s_media_buffer_32[5];
s_timeouts[0] = timeoutA;
s_timeouts[1] = timeoutB;
s_timeouts[2] = timeoutC;
s_timeouts[0] = timeout_a;
s_timeouts[1] = timeout_b;
s_timeouts[2] = timeout_c;
int ret = 0;
if (fd != INVALID_SOCKET)
{
ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeoutB, sizeof(int));
ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&timeout_b),
sizeof(int));
if (ret < 0)
{
ret = WSAGetLastError();
}
else
{
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeoutC, sizeof(int));
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&timeout_c),
sizeof(int));
if (ret < 0)
ret = WSAGetLastError();
}
}
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: SetTimeOuts( {}, {}, {}, {} ):{}\n", fd, timeoutA,
timeoutB, timeoutC, ret);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: SetTimeOuts( {}, {}, {}, {} ):{}\n", fd, timeout_a,
timeout_b, timeout_c, ret);
s_media_buffer[1] = s_media_buffer[8];
s_media_buffer_32[1] = ret;
@ -1001,16 +1006,18 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
}
case AMMBCommand::ModifyMyIPaddr:
{
const u32 NetBufferOffset = *(u32*)(s_media_buffer + 8) - NetworkCommandAddress2;
const u32 net_buffer_offset = s_media_buffer_32[2] - NetworkCommandAddress2;
const char* IP = (char*)(s_network_command_buffer + NetBufferOffset);
// TODO: Not checked for null termination.
const char* ip_address =
reinterpret_cast<char*>(s_network_command_buffer + net_buffer_offset);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: modifyMyIPaddr({})\n", IP);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: modifyMyIPaddr({})\n", ip_address);
break;
}
case AMMBCommand::GetLastError:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: GetLastError( {}({}) ):{}\n", fd,
s_media_buffer_32[2], s_last_error);
@ -1239,8 +1246,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
if (dimm_offset == 0x40 && cmd_flag == 1)
{
const AMMBCommand ammb_command =
static_cast<AMMBCommand>(*reinterpret_cast<u16*>(s_media_buffer + 0x22));
const AMMBCommand ammb_command = Common::BitCastPtr<AMMBCommand>(s_media_buffer + 0x22);
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Execute command (2):{0:04X}",
static_cast<u16>(ammb_command));
@ -1297,10 +1303,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
ExpansionInterface::GenerateInterrupt(0x04);
return 0;
}
else
{
memcpy(s_media_buffer + dimm_offset, memory.GetSpanForAddress(address).data(), length);
}
memcpy(s_media_buffer + dimm_offset, memory.GetSpanForAddress(address).data(), length);
return 0;
}
@ -1311,7 +1315,6 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
PrintMBBuffer(address, length);
memcpy(s_media_buffer + dimm_offset, memory.GetSpanForAddress(address).data(), length);
return 0;
}
@ -1347,7 +1350,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBDICommand::Execute:
{
const AMMBCommand ammb_command = static_cast<AMMBCommand>(s_media_buffer_32[8] >> 16);
const auto ammb_command = static_cast<AMMBCommand>(s_media_buffer_32[8] >> 16);
if (ammb_command == AMMBCommand::Unknown_000)
break;
@ -1432,7 +1435,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Closesocket:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const int ret = closesocket(fd);
@ -1447,13 +1450,12 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Connect:
{
sockaddr_in addr;
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const u32 off = s_media_buffer_32[11] - NetworkCommandAddress;
const u32 len = s_media_buffer_32[12];
memcpy((void*)&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
sockaddr_in addr;
memcpy(&addr, s_network_command_buffer + off, sizeof(sockaddr_in));
const int ret = NetDIMMConnect(fd, &addr, len);
@ -1467,27 +1469,22 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Recv:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const u32 off = s_media_buffer_32[11];
u32 len = s_media_buffer_32[12];
const auto len = std::min<u32>(s_media_buffer_32[12], sizeof(s_network_buffer));
if (len >= sizeof(s_network_buffer))
{
len = sizeof(s_network_buffer);
}
char* buffer = (char*)(s_network_buffer + off);
auto* buffer = s_network_buffer + off;
if (off >= NetworkBufferAddress5 && off < NetworkBufferAddress5 + sizeof(s_network_buffer))
{
buffer = (char*)(s_network_buffer + off - NetworkBufferAddress5);
buffer = s_network_buffer + off - NetworkBufferAddress5;
}
else
{
PanicAlertFmt("RECV: Buffer overrun:{0} {1} ", off, len);
}
const int ret = recv(fd, buffer, len, 0);
const int ret = recv(fd, reinterpret_cast<char*>(buffer), len, 0);
const int err = WSAGetLastError();
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv( {}, 0x{:08x}, {} ):{} {}\n", fd, off, len,
@ -1499,7 +1496,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Send:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
u32 off = s_media_buffer_32[11];
const u32 len = s_media_buffer_32[12];
@ -1512,7 +1509,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: send(error) unhandled destination:{:08x}\n", off);
}
const int ret = send(fd, (char*)(s_network_buffer + off), len, 0);
const int ret = send(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
const int err = WSAGetLastError();
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: send( {}({}), 0x{:08x}, {} ): {} {}\n", fd,
@ -1538,48 +1535,46 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::Select:
{
const u32 fd = s_sockets[SocketCheck(s_media_buffer_32[10] - 1)];
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10] - 1)];
fd_set* readfds = nullptr;
fd_set* writefds = nullptr;
fd_set* exceptfds = nullptr;
timeval timeout = {};
timeval* timeout_src = nullptr;
u8* timeout_src = nullptr;
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
// Only one of 11, 12, 13 is ever set alongside 14
if (s_media_buffer_32[11] && s_media_buffer_32[14])
if (s_media_buffer_32[14] != 0)
{
const u32 ROffset = s_media_buffer_32[14] - NetworkCommandAddress;
readfds = reinterpret_cast<fd_set*>(s_network_command_buffer + ROffset);
FD_ZERO(readfds);
FD_SET(fd, readfds);
const u32 fd_offset = s_media_buffer_32[14] - NetworkCommandAddress;
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer +
s_media_buffer_32[11] - NetworkCommandAddress);
}
else if (s_media_buffer_32[12] && s_media_buffer_32[14])
{
const u32 WOffset = s_media_buffer_32[14] - NetworkCommandAddress;
writefds = reinterpret_cast<fd_set*>(s_network_command_buffer + WOffset);
FD_ZERO(writefds);
FD_SET(fd, writefds);
// TODO: Check that fd_offset is in bounds of of s_network_command_buffer.
Common::BitCastPtr<fd_set>(s_network_command_buffer + fd_offset) = fds;
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer +
s_media_buffer_32[12] - NetworkCommandAddress);
}
else if (s_media_buffer_32[13] && s_media_buffer_32[14])
{
const u32 EOffset = s_media_buffer_32[14] - NetworkCommandAddress;
exceptfds = reinterpret_cast<fd_set*>(s_network_command_buffer + EOffset);
FD_ZERO(exceptfds);
FD_SET(fd, exceptfds);
timeout_src = reinterpret_cast<timeval*>(s_network_command_buffer +
s_media_buffer_32[13] - NetworkCommandAddress);
if (s_media_buffer_32[11] != 0)
{
readfds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[11] - NetworkCommandAddress;
}
else if (s_media_buffer_32[12] != 0)
{
writefds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[12] - NetworkCommandAddress;
}
else if (s_media_buffer_32[13] != 0)
{
exceptfds = &fds;
timeout_src = s_network_command_buffer + s_media_buffer_32[13] - NetworkCommandAddress;
}
}
// Copy timeout if set
if (timeout_src)
if (timeout_src != nullptr)
{
std::memcpy(&timeout, timeout_src, sizeof(timeval));
}
@ -1608,11 +1603,11 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::SetSockOpt:
{
const SOCKET fd = (SOCKET)(s_sockets[SocketCheck(s_media_buffer_32[10])]);
const auto fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
const int level = (int)(s_media_buffer_32[11]);
const int optname = (int)(s_media_buffer_32[12]);
const char* optval =
(char*)(s_network_command_buffer + s_media_buffer_32[13] - NetworkCommandAddress);
const char* optval = reinterpret_cast<char*>(s_network_command_buffer +
s_media_buffer_32[13] - NetworkCommandAddress);
const int optlen = (int)(s_media_buffer_32[14]);
const int ret = setsockopt(fd, level, optname, optval, optlen);
@ -1628,11 +1623,13 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
break;
case AMMBCommand::ModifyMyIPaddr:
{
const u32 NetBufferOffset = s_media_buffer_32[10] - NetworkCommandAddress;
const u32 net_buffer_offset = s_media_buffer_32[10] - NetworkCommandAddress;
const char* IP = (char*)(s_network_command_buffer + NetBufferOffset);
// TODO: Not checked for null termination.
const char* ip_address =
reinterpret_cast<char*>(s_network_command_buffer + net_buffer_offset);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: modifyMyIPaddr({})\n", IP);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: modifyMyIPaddr({})\n", ip_address);
}
break;
// Empty reply
@ -1650,9 +1647,9 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
addra.sin_addr.s_addr = s_media_buffer_32[12];
addrb.sin_addr.s_addr = s_media_buffer_32[13];
u16 size = s_media_buffer[0x24] | s_media_buffer[0x25] << 8;
u16 port = Common::swap16(s_media_buffer[0x27] | s_media_buffer[0x26] << 8);
u16 unknown = s_media_buffer[0x2D] | s_media_buffer[0x2C] << 8;
const u16 size = s_media_buffer[0x24] | s_media_buffer[0x25] << 8;
const u16 port = Common::swap16(s_media_buffer[0x27] | s_media_buffer[0x26] << 8);
const u16 unknown = s_media_buffer[0x2D] | s_media_buffer[0x2C] << 8;
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: SetupLink:");
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Size: ({}) ", size);
@ -1682,12 +1679,13 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 address, u32
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Offset: ({:04x})", off);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: ({:08x})", addr);
const u8* data = (u8*)(s_network_buffer + off + addr - NetworkBufferAddress2);
const u8* data = s_network_buffer + off + addr - NetworkBufferAddress2;
for (u32 i = 0; i < 0x20; i += 0x10)
{
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: {:08x} {:08x} {:08x} {:08x}", *(u32*)(data + i),
*(u32*)(data + i + 4), *(u32*)(data + i + 8), *(u32*)(data + i + 12));
const std::array<u32, 4> data_u32 = Common::BitCastPtr<std::array<u32, 4>>(data + i);
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: {:08x} {:08x} {:08x} {:08x}", data_u32[0],
data_u32[1], data_u32[2], data_u32[3]);
}
s_media_buffer_32[1] = 0;
@ -1760,7 +1758,7 @@ u32 GetGameType()
else
{
// Convert game ID into hex
sscanf(SConfig::GetInstance().GetGameID().c_str(), "%s", (char*)&game_id);
sscanf(SConfig::GetInstance().GetGameID().c_str(), "%s", reinterpret_cast<char*>(&game_id));
}
// This is checking for the real game IDs (See boot.id within the game)
@ -1831,11 +1829,7 @@ void Shutdown()
s_extra.Close();
s_backup.Close();
s_dimm.Close();
if (s_dimm_disc.size())
{
s_dimm_disc.clear();
}
s_dimm_disc.clear();
// Close all sockets
for (u32 i = 1; i < 64; ++i)

View File

@ -3,25 +3,10 @@
#pragma once
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <array>
#include "Common/CommonTypes.h"
class PointerWrap;
namespace Core
{
class System;
}
namespace File
{
class IOFile;
}
enum GameType
{
FZeroAX = 1,
@ -67,8 +52,6 @@ enum InquiryType
Version2 = 0x29484100,
};
#define SocketCheck(x) (x <= 0x3F ? x : 0)
namespace AMMediaboard
{
@ -228,8 +211,8 @@ enum SocketStatusCodes
void Init();
void FirmwareMap(bool on);
u8* InitDIMM(u32 size);
void InitKeys(u32 KeyA, u32 KeyB, u32 KeyC);
u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32* DIIMMBUF, u32 Address, u32 Length);
void InitKeys(u32 key_a, u32 key_b, u32 key_c);
u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length);
u32 GetGameType();
u32 GetMediaType();
bool GetTestMenu();

View File

@ -3,28 +3,19 @@
#include "Core/HW/EXI/EXI_DeviceBaseboard.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <numeric>
#include <string>
#include <vector>
#include <fmt/format.h>
#include "Common/Buffer.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Common/IOFile.h"
#include "Common/IniFile.h"
#include "Common/Logging/Log.h"
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/ConfigLoaders/BaseConfigLoader.h"
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HW/DVD/AMMediaboard.h"
@ -35,30 +26,18 @@
#include "Core/HW/Memmap.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Sram.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/Movie.h"
#include "Core/NetPlayProto.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "Core/WiiRoot.h"
#include "DiscIO/Enums.h"
static bool s_interrupt_set = false;
static u32 s_irq_timer = 0;
static u32 s_irq_status = 0;
static u16 CheckSum(u8* data, u32 length)
static u16 CheckSum(const u8* data, u32 length)
{
u16 check = 0;
for (u32 i = 0; i < length; i++)
{
check += data[i];
}
return check;
return std::accumulate(data, data + length, 0);
}
namespace ExpansionInterface
@ -75,7 +54,7 @@ void GenerateInterrupt(int flag)
system.GetExpansionInterface().UpdateInterrupts();
}
CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system), m_position(0)
CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system)
{
std::string backup_filename(fmt::format("{}tribackup_{}.bin", File::GetUserPath(D_TRIUSER_IDX),
SConfig::GetInstance().GetGameID()));
@ -110,12 +89,12 @@ CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system), m_posit
m_backup.ReadBytes(data.data(), data.size());
// Set FIRM version
reinterpret_cast<u16&>(data[0x12]) = 0x1703;
reinterpret_cast<u16&>(data[0x212]) = 0x1703;
Common::BitCastPtr<u16>(data.data() + 0x12) = 0x1703;
Common::BitCastPtr<u16>(data.data() + 0x212) = 0x1703;
// Update checksum
reinterpret_cast<u16&>(data[0x0A]) = Common::swap16(CheckSum(&data[0xC], 0x1F4));
reinterpret_cast<u16&>(data[0x20A]) = Common::swap16(CheckSum(&data[0x20C], 0x1F4));
Common::BitCastPtr<u16>(data.data() + 0x0A) = Common::swap16(CheckSum(&data[0xC], 0x1F4));
Common::BitCastPtr<u16>(data.data() + 0x20A) = Common::swap16(CheckSum(&data[0x20C], 0x1F4));
m_backup.Seek(0, File::SeekOrigin::Begin);
m_backup.WriteBytes(data.data(), data.size());
@ -148,12 +127,10 @@ bool CEXIBaseboard::IsInterruptSet()
DEBUG_LOG_FMT(SP1, "AM-BB: IRQ");
if (++s_irq_timer > 12)
s_interrupt_set = false;
return 1;
}
else
{
return 0;
return true;
}
return false;
}
void CEXIBaseboard::DMAWrite(u32 addr, u32 size)

View File

@ -16,11 +16,11 @@ namespace ExpansionInterface
{
void GenerateInterrupt(int flag);
class CEXIBaseboard : public IEXIDevice
class CEXIBaseboard final : public IEXIDevice
{
public:
explicit CEXIBaseboard(Core::System& system);
virtual ~CEXIBaseboard();
~CEXIBaseboard() override;
void SetCS(int cs) override;
bool IsInterruptSet() override;
@ -46,11 +46,11 @@ private:
WriteLANCNT = 0xFF,
};
u32 m_position;
u32 m_backup_dma_offset;
u32 m_backup_dma_length;
u8 m_command[4];
u16 m_backup_offset;
u32 m_position = 0;
u32 m_backup_dma_offset = 0;
u32 m_backup_dma_length = 0;
std::array<u8, 4> m_command{};
u16 m_backup_offset = 0;
File::IOFile m_backup;
protected:

View File

@ -4,21 +4,14 @@
#include "Core/HW/SI/SI_DeviceAMBaseboard.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <fmt/format.h>
#include "Common/Buffer.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Common/Hash.h"
#include "Common/IOFile.h"
#include "Common/IniFile.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"
@ -26,9 +19,6 @@
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/ConfigLoaders/BaseConfigLoader.h"
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
@ -42,28 +32,16 @@
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/SI/SI_DeviceGCController.h"
#include "Core/HW/Sram.h"
#include "Core/HW/SystemTimers.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/Movie.h"
#include "Core/NetPlayProto.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "Core/WiiRoot.h"
#include "DiscIO/Enums.h"
#include "InputCommon/GCPadStatus.h"
namespace SerialInterface
{
JVSIOMessage::JVSIOMessage()
{
m_ptr = 0;
m_last_start = 0;
}
void JVSIOMessage::Start(int node)
{
m_last_start = m_ptr;
@ -287,7 +265,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
for (u32 i = 0; i < buffer_length; ++i)
checksum += buffer[i];
u8 data_out[0x80]{};
std::array<u8, 0x80> data_out{};
u32 data_offset = 0;
static u32 dip_switch_1 = 0xFE;
@ -315,11 +293,11 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
// We read Test/Service from the JVS-I/O SwitchesInput instead
//
// const GCPadStatus PadStatus = Pad::GetStatus(ISIDevice::m_device_number);
// const GCPadStatus pad_status = Pad::GetStatus(ISIDevice::m_device_number);
// baseboard test/service switches
// if (PadStatus.button & PAD_BUTTON_Y) // Test
// if (pad_status.button & PAD_BUTTON_Y) // Test
// dip_switch_0 &= ~0x80;
// if (PadStatus.button & PAD_BUTTON_X) // Service
// if (pad_status.button & PAD_BUTTON_X) // Service
// dip_switch_0 &= ~0x40;
// Horizontal Scanning Frequency switch
@ -348,7 +326,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
data_out[data_offset++] = gcam_command;
data_out[data_offset++] = 16;
memcpy(data_out + data_offset, "AADE-01B98394904", 16);
memcpy(data_out.data() + data_offset, "AADE-01B98394904", 16);
data_offset += 16;
break;
@ -509,7 +487,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
// Serial - Unknown
if (AMMediaboard::GetGameType() == GekitouProYakyuu)
{
u32 serial_command = *(u32*)(data_in);
const u32 serial_command = Common::BitCastPtr<u32>(data_in);
if (serial_command == 0x00001000)
{
@ -582,7 +560,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
icco.command = WritePages;
ICCardSendReply(&icco, data_out, &data_offset);
ICCardSendReply(&icco, data_out.data(), &data_offset);
}
data_in += length;
break;
@ -646,7 +624,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
case ICCARDCommand::ReadPage:
case ICCARDCommand::ReadUseCount:
{
const u16 page = Common::swap16(*(u16*)(data_in + 6));
const u16 page = Common::swap16(data_in + 6);
icco.extlen = 8;
icco.length += icco.extlen;
@ -660,7 +638,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
case ICCARDCommand::WritePage:
{
const u16 page = Common::swap16(*(u16*)(data_in + 8));
const u16 page = Common::swap16(data_in + 8);
// Write only one page
if (page == 4)
@ -678,13 +656,14 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
case ICCARDCommand::DecreaseUseCount:
{
const u16 page = Common::swap16(*(u16*)(data_in + 6));
const u16 page = Common::swap16(data_in + 6);
icco.extlen = 2;
icco.length += icco.extlen;
icco.pktlen += icco.extlen;
*(u16*)(m_ic_card_data + 0x28) = *(u16*)(m_ic_card_data + 0x28) - 1;
auto ic_card_data = Common::BitCastPtr<u16>(m_ic_card_data + 0x28);
ic_card_data = ic_card_data - 1;
// Counter
icco.extdata[0] = m_ic_card_data[0x28];
@ -696,8 +675,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
case ICCARDCommand::ReadPages:
{
const u16 page = Common::swap16(*(u16*)(data_in + 6));
const u16 count = Common::swap16(*(u16*)(data_in + 8));
const u16 page = Common::swap16(data_in + 6);
const u16 count = Common::swap16(data_in + 8);
const u32 offs = page * 8;
u32 cnt = count * 8;
@ -721,9 +700,9 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
case ICCARDCommand::WritePages:
{
const u16 pksize = length;
const u16 size = Common::swap16(*(u16*)(data_in + 2));
const u16 page = Common::swap16(*(u16*)(data_in + 6));
const u16 count = Common::swap16(*(u16*)(data_in + 8));
const u16 size = Common::swap16(data_in + 2);
const u16 page = Common::swap16(data_in + 6);
const u16 count = Common::swap16(data_in + 8);
// We got a complete packet
if (pksize - 5 == size)
@ -872,7 +851,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
break;
}
ICCardSendReply(&icco, data_out, &data_offset);
ICCardSendReply(&icco, data_out.data(), &data_offset);
data_in += length;
break;
@ -884,8 +863,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
{
// All commands are OR'd with 0x80
// Last byte is checksum which we don't care about
const u32 serial_command =
Common::swap32(*(u32*)(data_in + command_offset)) ^ 0x80000000;
const u32 serial_command = Common::swap32(data_in + command_offset) ^ 0x80000000;
if (AMMediaboard::GetGameType() == FZeroAX ||
AMMediaboard::GetGameType() == FZeroAXMonster)
@ -914,7 +892,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
}
command_offset += 4;
command_offset += sizeof(u32);
if (AMMediaboard::GetGameType() == FZeroAX ||
AMMediaboard::GetGameType() == FZeroAXMonster)
@ -929,9 +907,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
switch (serial_command >> 24)
{
case 0:
break;
case 1: // Set Maximum?
break;
case 2:
break;
@ -955,8 +931,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
{
if (serial_interface.GetDeviceType(1) == SerialInterface::SIDEVICE_GC_STEERING)
{
const GCPadStatus PadStatus = Pad::GetStatus(1);
if (PadStatus.isConnected)
const GCPadStatus pad_status = Pad::GetStatus(1);
if (pad_status.isConnected)
{
const ControlState mapped_strength = (double)(m_motor_force_y >> 8) / 127.f;
@ -1003,7 +979,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
m_motor_reply[0] = gcam_command;
m_motor_reply[1] = length; // Same out as in size
memcpy(data_out + data_offset, m_motor_reply, m_motor_reply[1] + 2);
memcpy(data_out.data() + data_offset, m_motor_reply, m_motor_reply[1] + 2);
data_offset += m_motor_reply[1] + 2;
}
}
@ -1027,13 +1003,13 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
if (AMMediaboard::GetGameType() == FZeroAX)
{
if (read_length > 0x2F)
read_length = 0x2F;
read_length = std::min<u32>(read_length, 0x2F);
}
data_out[data_offset++] = read_length; // 0x2F (max size per packet)
memcpy(data_out + data_offset, m_card_read_packet + m_card_read, read_length);
memcpy(data_out.data() + data_offset, m_card_read_packet + m_card_read,
read_length);
data_offset += read_length;
m_card_read += read_length;
@ -1082,9 +1058,6 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
data_out[data_offset++] = 0x00; // 0x03
break;
case CARDCommand::SetPrintParam:
data_out[data_offset++] = 0x00; // 0x02
data_out[data_offset++] = 0x00; // 0x03
break;
case CARDCommand::RegisterFont:
data_out[data_offset++] = 0x00; // 0x02
data_out[data_offset++] = 0x00; // 0x03
@ -1093,6 +1066,9 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
data_out[data_offset++] = 0x02; // 0x02
data_out[data_offset++] = 0x00; // 0x03
break;
// TODO: CARDCommand::Erase is not handled.
ERROR_LOG_FMT(SERIALINTERFACE_AMBB, "CARDCommand::Erase is not handled.");
break;
case CARDCommand::Eject:
if (AMMediaboard::GetGameType() == FZeroAX)
{
@ -1322,9 +1298,9 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
"GC-AM: Command CARD Write: {:02X} {:02X} {:02X} {}", mode,
bitmode, track, m_card_memory_size);
const std::string card_filename(
File::GetUserPath(D_TRIUSER_IDX) + "tricard_" +
SConfig::GetInstance().GetGameID().c_str() + ".bin");
const std::string card_filename(File::GetUserPath(D_TRIUSER_IDX) +
"tricard_" +
SConfig::GetInstance().GetGameID() + ".bin");
File::IOFile card(card_filename, "wb+");
card.WriteBytes(m_card_memory, m_card_memory_size);
@ -1409,6 +1385,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
const u8 nr_bytes = frame[3]; // Byte after E0 xx
const u32 frame_len = nr_bytes + 3; // Header(2) + length byte + payload + checksum
// TODO: frame_len isn't checked for buffer overflow.
u8 jvs_buf[0x80];
memcpy(jvs_buf, frame, frame_len);
@ -1500,59 +1478,59 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
//
// DX Version: 2 Player (22bit) (p2=paddles), 2 Coin slot, 8 Analog-in,
// 22 Driver-out
message.AddData((void*)"\x01\x02\x12\x00", 4);
message.AddData((void*)"\x02\x02\x00\x00", 4);
message.AddData((void*)"\x03\x08\x0A\x00", 4);
message.AddData((void*)"\x12\x16\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x02\x12\x00", 4);
message.AddData("\x02\x02\x00\x00", 4);
message.AddData("\x03\x08\x0A\x00", 4);
message.AddData("\x12\x16\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
case VirtuaStriker3:
// 2 Player (13bit), 2 Coin slot, 4 Analog-in, 1 CARD, 8 Driver-out
message.AddData((void*)"\x01\x02\x0D\x00", 4);
message.AddData((void*)"\x02\x02\x00\x00", 4);
message.AddData((void*)"\x10\x01\x00\x00", 4);
message.AddData((void*)"\x12\x08\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x02\x0D\x00", 4);
message.AddData("\x02\x02\x00\x00", 4);
message.AddData("\x10\x01\x00\x00", 4);
message.AddData("\x12\x08\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
case GekitouProYakyuu:
// 2 Player (13bit), 2 Coin slot, 4 Analog-in, 1 CARD, 8 Driver-out
message.AddData((void*)"\x01\x02\x0D\x00", 4);
message.AddData((void*)"\x02\x02\x00\x00", 4);
message.AddData((void*)"\x03\x04\x00\x00", 4);
message.AddData((void*)"\x10\x01\x00\x00", 4);
message.AddData((void*)"\x12\x08\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x02\x0D\x00", 4);
message.AddData("\x02\x02\x00\x00", 4);
message.AddData("\x03\x04\x00\x00", 4);
message.AddData("\x10\x01\x00\x00", 4);
message.AddData("\x12\x08\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
case VirtuaStriker4:
case VirtuaStriker4_2006:
// 2 Player (13bit), 1 Coin slot, 4 Analog-in, 1 CARD
message.AddData((void*)"\x01\x02\x0D\x00", 4);
message.AddData((void*)"\x02\x01\x00\x00", 4);
message.AddData((void*)"\x03\x04\x00\x00", 4);
message.AddData((void*)"\x10\x01\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x02\x0D\x00", 4);
message.AddData("\x02\x01\x00\x00", 4);
message.AddData("\x03\x04\x00\x00", 4);
message.AddData("\x10\x01\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
case KeyOfAvalon:
// 1 Player (15bit), 1 Coin slot, 3 Analog-in, Touch, 1 CARD, 1 Driver-out
// (Unconfirmed)
message.AddData((void*)"\x01\x01\x0F\x00", 4);
message.AddData((void*)"\x02\x01\x00\x00", 4);
message.AddData((void*)"\x03\x03\x00\x00", 4);
message.AddData((void*)"\x06\x10\x10\x01", 4);
message.AddData((void*)"\x10\x01\x00\x00", 4);
message.AddData((void*)"\x12\x01\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x01\x0F\x00", 4);
message.AddData("\x02\x01\x00\x00", 4);
message.AddData("\x03\x03\x00\x00", 4);
message.AddData("\x06\x10\x10\x01", 4);
message.AddData("\x10\x01\x00\x00", 4);
message.AddData("\x12\x01\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
case MarioKartGP:
case MarioKartGP2:
default:
// 1 Player (15bit), 1 Coin slot, 3 Analog-in, 1 CARD, 1 Driver-out
message.AddData((void*)"\x01\x01\x0F\x00", 4);
message.AddData((void*)"\x02\x01\x00\x00", 4);
message.AddData((void*)"\x03\x03\x00\x00", 4);
message.AddData((void*)"\x10\x01\x00\x00", 4);
message.AddData((void*)"\x12\x01\x00\x00", 4);
message.AddData((void*)"\x00\x00\x00\x00", 4);
message.AddData("\x01\x01\x0F\x00", 4);
message.AddData("\x02\x01\x00\x00", 4);
message.AddData("\x03\x03\x00\x00", 4);
message.AddData("\x10\x01\x00\x00", 4);
message.AddData("\x12\x01\x00\x00", 4);
message.AddData("\x00\x00\x00\x00", 4);
break;
}
NOTICE_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Command 0x14, CheckFunctionality");
@ -1573,10 +1551,10 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
message.AddData(StatusOkay);
GCPadStatus PadStatus = Pad::GetStatus(0);
GCPadStatus pad_status = Pad::GetStatus(0);
// Test button
if (PadStatus.switches & SWITCH_TEST)
if (pad_status.switches & SWITCH_TEST)
{
// Trying to access the test menu without SegaBoot present will cause a crash
if (AMMediaboard::GetTestMenu())
@ -1585,7 +1563,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
else
{
PanicAlertFmt("Test menu is disabled due missing SegaBoot");
PanicAlertFmt("Test menu is disabled due to missing SegaBoot");
}
}
else
@ -1595,10 +1573,10 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
for (u32 i = 0; i < player_count; ++i)
{
u8 player_data[3] = {0, 0, 0};
u8 player_data[3]{};
// Service button
if (PadStatus.switches & SWITCH_SERVICE)
if (pad_status.switches & SWITCH_SERVICE)
player_data[0] |= 0x40;
switch (AMMediaboard::GetGameType())
@ -1613,32 +1591,32 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Boost
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[0] |= 0x02;
// View Change 1
if (PadStatus.button & PAD_BUTTON_RIGHT)
if (pad_status.button & PAD_BUTTON_RIGHT)
player_data[0] |= 0x20;
// View Change 2
if (PadStatus.button & PAD_BUTTON_LEFT)
if (pad_status.button & PAD_BUTTON_LEFT)
player_data[0] |= 0x10;
// View Change 3
if (PadStatus.button & PAD_BUTTON_UP)
if (pad_status.button & PAD_BUTTON_UP)
player_data[0] |= 0x08;
// View Change 4
if (PadStatus.button & PAD_BUTTON_DOWN)
if (pad_status.button & PAD_BUTTON_DOWN)
player_data[0] |= 0x04;
player_data[1] = m_rx_reply & 0xF0;
}
else if (i == 1)
{
// Paddle left
if (PadStatus.button & PAD_BUTTON_X)
if (pad_status.button & PAD_BUTTON_X)
player_data[0] |= 0x20;
// Paddle right
if (PadStatus.button & PAD_BUTTON_Y)
if (pad_status.button & PAD_BUTTON_Y)
player_data[0] |= 0x10;
if (m_fzdx_motion_stop)
@ -1667,22 +1645,22 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Boost
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[0] |= 0x02;
// View Change 1
if (PadStatus.button & PAD_BUTTON_RIGHT)
if (pad_status.button & PAD_BUTTON_RIGHT)
player_data[0] |= 0x20;
// View Change 2
if (PadStatus.button & PAD_BUTTON_LEFT)
if (pad_status.button & PAD_BUTTON_LEFT)
player_data[0] |= 0x10;
// View Change 3
if (PadStatus.button & PAD_BUTTON_UP)
if (pad_status.button & PAD_BUTTON_UP)
player_data[0] |= 0x08;
// View Change 4
if (PadStatus.button & PAD_BUTTON_DOWN)
if (pad_status.button & PAD_BUTTON_DOWN)
player_data[0] |= 0x04;
player_data[1] = m_rx_reply & 0xF0;
@ -1690,10 +1668,10 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
else if (i == 1)
{
// Paddle left
if (PadStatus.button & PAD_BUTTON_X)
if (pad_status.button & PAD_BUTTON_X)
player_data[0] |= 0x20;
// Paddle right
if (PadStatus.button & PAD_BUTTON_Y)
if (pad_status.button & PAD_BUTTON_Y)
player_data[0] |= 0x10;
if (m_fzcc_seatbelt)
@ -1712,60 +1690,60 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
break;
// Controller configuration for Virtua Striker 3 games
case VirtuaStriker3:
PadStatus = Pad::GetStatus(i);
pad_status = Pad::GetStatus(i);
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Shoot
if (PadStatus.button & PAD_BUTTON_B)
if (pad_status.button & PAD_BUTTON_B)
player_data[0] |= 0x01;
// Short Pass
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[1] |= 0x80;
// Long Pass
if (PadStatus.button & PAD_BUTTON_X)
if (pad_status.button & PAD_BUTTON_X)
player_data[0] |= 0x02;
// Left
if (PadStatus.button & PAD_BUTTON_LEFT)
if (pad_status.button & PAD_BUTTON_LEFT)
player_data[0] |= 0x08;
// Up
if (PadStatus.button & PAD_BUTTON_UP)
if (pad_status.button & PAD_BUTTON_UP)
player_data[0] |= 0x20;
// Right
if (PadStatus.button & PAD_BUTTON_RIGHT)
if (pad_status.button & PAD_BUTTON_RIGHT)
player_data[0] |= 0x04;
// Down
if (PadStatus.button & PAD_BUTTON_DOWN)
if (pad_status.button & PAD_BUTTON_DOWN)
player_data[0] |= 0x10;
break;
// Controller configuration for Virtua Striker 4 games
case VirtuaStriker4:
case VirtuaStriker4_2006:
{
PadStatus = Pad::GetStatus(i);
pad_status = Pad::GetStatus(i);
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Long Pass
if (PadStatus.button & PAD_BUTTON_X)
if (pad_status.button & PAD_BUTTON_X)
player_data[0] |= 0x01;
// Short Pass
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[0] |= 0x02;
// Shoot
if (PadStatus.button & PAD_BUTTON_B)
if (pad_status.button & PAD_BUTTON_B)
player_data[1] |= 0x80;
// Dash
if (PadStatus.button & PAD_BUTTON_Y)
if (pad_status.button & PAD_BUTTON_Y)
player_data[1] |= 0x40;
// Tactics (U)
if (PadStatus.button & PAD_BUTTON_LEFT)
if (pad_status.button & PAD_BUTTON_LEFT)
player_data[0] |= 0x20;
// Tactics (M)
if (PadStatus.button & PAD_BUTTON_UP)
if (pad_status.button & PAD_BUTTON_UP)
player_data[0] |= 0x08;
// Tactics (D)
if (PadStatus.button & PAD_BUTTON_RIGHT)
if (pad_status.button & PAD_BUTTON_RIGHT)
player_data[0] |= 0x04;
if (i == 0)
@ -1773,37 +1751,37 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
player_data[0] |= 0x10; // IC-Card Switch ON
// IC-Card Lock
if (PadStatus.button & PAD_BUTTON_DOWN)
if (pad_status.button & PAD_BUTTON_DOWN)
player_data[1] |= 0x20;
}
}
break;
// Controller configuration for Gekitou Pro Yakyuu
case GekitouProYakyuu:
PadStatus = Pad::GetStatus(i);
pad_status = Pad::GetStatus(i);
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// A
if (PadStatus.button & PAD_BUTTON_B)
if (pad_status.button & PAD_BUTTON_B)
player_data[0] |= 0x01;
// B
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[0] |= 0x02;
// Gekitou
if (PadStatus.button & PAD_TRIGGER_L)
if (pad_status.button & PAD_TRIGGER_L)
player_data[1] |= 0x80;
// Left
if (PadStatus.button & PAD_BUTTON_LEFT)
if (pad_status.button & PAD_BUTTON_LEFT)
player_data[0] |= 0x08;
// Up
if (PadStatus.button & PAD_BUTTON_UP)
if (pad_status.button & PAD_BUTTON_UP)
player_data[0] |= 0x20;
// Right
if (PadStatus.button & PAD_BUTTON_RIGHT)
if (pad_status.button & PAD_BUTTON_RIGHT)
player_data[0] |= 0x04;
// Down
if (PadStatus.button & PAD_BUTTON_DOWN)
if (pad_status.button & PAD_BUTTON_DOWN)
player_data[0] |= 0x10;
break;
// Controller configuration for Mario Kart and other games
@ -1812,29 +1790,29 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
case MarioKartGP2:
{
// Start
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Item button
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[1] |= 0x20;
// VS-Cancel button
if (PadStatus.button & PAD_BUTTON_B)
if (pad_status.button & PAD_BUTTON_B)
player_data[1] |= 0x02;
}
break;
case KeyOfAvalon:
{
// Debug On
if (PadStatus.button & PAD_BUTTON_START)
if (pad_status.button & PAD_BUTTON_START)
player_data[0] |= 0x80;
// Switch 1
if (PadStatus.button & PAD_BUTTON_A)
if (pad_status.button & PAD_BUTTON_A)
player_data[0] |= 0x04;
// Switch 2
if (PadStatus.button & PAD_BUTTON_B)
if (pad_status.button & PAD_BUTTON_B)
player_data[0] |= 0x08;
// Toggle inserted card
if (PadStatus.button & PAD_TRIGGER_L)
if (pad_status.button & PAD_TRIGGER_L)
{
m_ic_card_status ^= ICCARDStatus::NoCard;
}
@ -1853,12 +1831,12 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
message.AddData(StatusOkay);
for (u32 i = 0; i < slots; i++)
{
GCPadStatus PadStatus = Pad::GetStatus(i);
if ((PadStatus.switches & SWITCH_COIN) && !m_coin_pressed[i])
GCPadStatus pad_status = Pad::GetStatus(i);
if ((pad_status.switches & SWITCH_COIN) && !m_coin_pressed[i])
{
m_coin[i]++;
}
m_coin_pressed[i] = PadStatus.switches & SWITCH_COIN;
m_coin_pressed[i] = pad_status.switches & SWITCH_COIN;
message.AddData((m_coin[i] >> 8) & 0x3f);
message.AddData(m_coin[i] & 0xff);
}
@ -1870,7 +1848,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
message.AddData(StatusOkay);
const u32 analogs = *jvs_io++;
GCPadStatus PadStatus = Pad::GetStatus(0);
GCPadStatus pad_status = Pad::GetStatus(0);
DEBUG_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Command 0x22, AnalogInput: {}",
analogs);
@ -1892,16 +1870,16 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
}
message.AddData((u8)0);
message.AddData(PadStatus.stickY);
message.AddData(pad_status.stickY);
message.AddData((u8)0);
}
else
{
// The center for the Y axis is expected to be 78h this adjusts that
message.AddData(PadStatus.stickX - 12);
message.AddData(pad_status.stickX - 12);
message.AddData((u8)0);
message.AddData(PadStatus.stickY);
message.AddData(pad_status.stickY);
message.AddData((u8)0);
}
@ -1912,11 +1890,11 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
message.AddData((u8)0);
// Gas
message.AddData(PadStatus.triggerRight);
message.AddData(pad_status.triggerRight);
message.AddData((u8)0);
// Brake
message.AddData(PadStatus.triggerLeft);
message.AddData(pad_status.triggerLeft);
message.AddData((u8)0);
message.AddData((u8)0x80); // Motion Stop
@ -1929,16 +1907,16 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
case VirtuaStriker4:
case VirtuaStriker4_2006:
{
message.AddData(-PadStatus.stickY);
message.AddData(-pad_status.stickY);
message.AddData((u8)0);
message.AddData(PadStatus.stickX);
message.AddData(pad_status.stickX);
message.AddData((u8)0);
PadStatus = Pad::GetStatus(1);
pad_status = Pad::GetStatus(1);
message.AddData(-PadStatus.stickY);
message.AddData(-pad_status.stickY);
message.AddData((u8)0);
message.AddData(PadStatus.stickX);
message.AddData(pad_status.stickX);
message.AddData((u8)0);
}
break;
@ -1946,15 +1924,15 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
case MarioKartGP:
case MarioKartGP2:
// Steering
message.AddData(PadStatus.stickX);
message.AddData(pad_status.stickX);
message.AddData((u8)0);
// Gas
message.AddData(PadStatus.triggerRight);
message.AddData(pad_status.triggerRight);
message.AddData((u8)0);
// Brake
message.AddData(PadStatus.triggerLeft);
message.AddData(pad_status.triggerLeft);
message.AddData((u8)0);
break;
}
@ -1964,17 +1942,17 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
{
const u32 channel = *jvs_io++;
const GCPadStatus PadStatus = Pad::GetStatus(0);
const GCPadStatus pad_status = Pad::GetStatus(0);
if (PadStatus.button & PAD_TRIGGER_R)
if (pad_status.button & PAD_TRIGGER_R)
{
// Tap at center of screen (~320,240)
message.AddData((void*)"\x01\x00\x8C\x01\x95",
message.AddData("\x01\x00\x8C\x01\x95",
5); // X=320 (0x0140), Y=240 (0x00F0)
}
else
{
message.AddData((void*)"\x01\xFF\xFF\xFF\xFF", 5);
message.AddData("\x01\xFF\xFF\xFF\xFF", 5);
}
DEBUG_LOG_FMT(SERIALINTERFACE_JVSIO, "JVS-IO: Command 0x25, PositionInput:{}",
@ -2035,10 +2013,10 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
SERIALINTERFACE_JVSIO,
"JVS-IO: Command 0x32, GPO: {:02x} {:02x} {} {:02x}{:02x}{:02x} ({:02x})",
delay, m_rx_reply, bytes, buf[0], buf[1], buf[2],
Common::swap16(*reinterpret_cast<u16*>(&buf[1])) >> 2);
Common::swap16(buf.data() + 1) >> 2);
// Handling of the motion seat used in F-Zero AXs DX version
switch (Common::swap16(*reinterpret_cast<u16*>(&buf[1])) >> 2)
switch (Common::swap16(buf.data() + 1) >> 2)
{
case 0x70:
delay++;
@ -2117,7 +2095,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
data_out[data_offset++] = gcam_command;
const u8* buf = message.m_msg;
const u8* buf = message.m_msg.data();
const u32 len = message.m_ptr;
data_out[data_offset++] = len;

View File

@ -19,12 +19,11 @@ namespace SerialInterface
class JVSIOMessage
{
public:
u32 m_ptr;
u32 m_last_start;
u32 m_csum;
u8 m_msg[0x80];
u32 m_ptr = 0;
u32 m_last_start = 0;
u32 m_csum = 0;
std::array<u8, 0x80> m_msg;
JVSIOMessage();
void Start(int node);
void AddData(const u8* dst, std::size_t len, int sync);
void AddData(const void* data, std::size_t len);

View File

@ -28,9 +28,9 @@ std::string VolumeDisc::GetGameID(const Partition& partition) const
// Construct game ID from the BTID
id[0] = 'G';
memcpy(id + 1, boot_id->gameId + 2, 2);
memcpy(id + 1, boot_id->game_id.data() + 2, 2);
switch (boot_id->regionFlags)
switch (boot_id->region_flags)
{
default:
case 0x02: // JAPAN
@ -83,7 +83,7 @@ Country VolumeDisc::GetCountry(const Partition& partition) const
{
const BootID* boot_id = static_cast<const VolumeGC*>(this)->GetTriforceBootID();
switch (boot_id->regionFlags)
switch (boot_id->region_flags)
{
default:
case 0x02: // JAPAN
@ -166,7 +166,7 @@ std::string VolumeDisc::GetInternalName(const Partition& partition) const
if (GetVolumeType() == Platform::Triforce)
{
const BootID* boot_id = static_cast<const VolumeGC*>(this)->GetTriforceBootID();
return DecodeString(boot_id->gameName);
return DecodeString(boot_id->game_name);
}
if (!Read(0x20, sizeof(name), reinterpret_cast<u8*>(&name), partition))

View File

@ -3,6 +3,7 @@
#pragma once
#include <array>
#include <optional>
#include <string>
@ -18,25 +19,25 @@ public:
struct BootID
{
u32 magic; // 0x00 (Always BTID)
uint32_t unknown0[3];
uint32_t unknown1[4];
char mediaboardType[4]; // 0x20 (GCAM for Triforce)
std::array<uint32_t, 3> unknown0;
std::array<uint32_t, 4> unknown1;
std::array<char, 4> mediaboard_type; // 0x20 (GCAM for Triforce)
uint32_t unknown2;
uint16_t year; // 0x28
uint8_t month; // 0x2A
uint8_t day; // 0x2B
uint8_t videoMode; // 0x2C unknown bitmask, resolutions + horizontal/vertical
uint16_t year; // 0x28
uint8_t month; // 0x2A
uint8_t day; // 0x2B
uint8_t video_mode; // 0x2C unknown bitmask, resolutions + horizontal/vertical
uint8_t unknown3;
uint8_t type3Compatible; // 0x2E (Type-3 compatible titles have this set to 1)
uint8_t type_3_compatible; // 0x2E (Type-3 compatible titles have this set to 1)
uint8_t unknown4;
char gameId[8]; // 0x30
uint32_t regionFlags; // 0x38
uint32_t unknown6[9];
char manufacturer[0x20]; // 0x60
char gameName[0x20]; // 0x80
char gameExecutable[0x20]; // 0xA0
char testExecutable[0x20]; // 0xC0
char creditTypes[8][0x20]; // 0xE0
std::array<char, 8> game_id; // 0x30
uint32_t region_flags; // 0x38
std::array<uint32_t, 9> unknown6;
std::array<char, 0x20> manufacturer; // 0x60
std::array<char, 0x20> game_name; // 0x80
std::array<char, 0x20> game_executable; // 0xA0
std::array<char, 0x20> test_executable; // 0xC0
std::array<std::array<char, 0x20>, 8> credit_types; // 0xE0
};
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
@ -53,4 +54,6 @@ protected:
void AddGamePartitionToSyncHash(Common::SHA1::Context* context) const;
};
static_assert(sizeof(VolumeDisc::BootID) == 480);
} // namespace DiscIO

View File

@ -92,7 +92,7 @@ Region VolumeGC::GetRegion() const
{
if (m_is_triforce)
{
switch (m_triforce_header.regionFlags)
switch (m_triforce_header.region_flags)
{
default:
case 0x02: // JAPAN