the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at master 215 lines 6.8 kB view raw
1#pragma once 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <voice_qos.h> 7#include "Common/Network/Sony/SQRNetworkPlayer.h" 8 9static const int sc_maxVoiceDataSize = 2048; 10 11 12class VoicePacket 13{ 14 static const int MAX_LOCAL_PLAYER_COUNT = 4; 15 16public: 17 struct Flags 18 { 19 bool m_bTalking : 1; 20 bool m_bHasMicConnected : 1; 21 }; 22 23 Flags m_localPlayerFlags[MAX_LOCAL_PLAYER_COUNT]; 24 uint32_t m_frameSendIndex; 25 uint32_t m_numFrames; 26 uint32_t m_checkSum; 27 uint32_t m_playerIndexFlags; 28 char m_data[sc_maxVoiceDataSize]; 29 30 static int getPacketSize(int dataSize) { return (uint64_t)&((VoicePacket*)0)->m_data[dataSize];} 31 void setChecksum(int dataSize) 32 { 33 m_checkSum = 0; 34 for(int i=0;i<dataSize;i++) 35 m_checkSum += m_data[i]; 36 } 37 void verifyData(int packetSize, int frameSize) 38 { 39 if(m_numFrames == 0) 40 return; 41 int dataSize = m_numFrames*frameSize; 42 assert(packetSize == getPacketSize(dataSize)); 43 int checkSum = 0; 44 for(int i=0;i<dataSize;i++) 45 checkSum += m_data[i]; 46 assert(checkSum == m_checkSum); 47 } 48}; 49 50 51//-------------------------------------------------------------------------- 52// read-write-safe ring buffer implementation: does not use mutex protection 53// the writer thread changes pointer <buf_free>, 54// the reader thread changes pointer <buf_full> 55class RingBuffer 56{ 57public: 58 RingBuffer(int sizeBytes); 59 ~RingBuffer() { delete buffer; } 60 void Reset(void) { buf_full = buf_free = 0; } 61 unsigned int DataSize(void) { return (buf_free - buf_full); } 62 int Write(char* data, int len_); 63 int Read(char* data, int max_bytes_); 64 int getDataSize() { return buf_free - buf_full; } 65 void ResetByWriter(void) { buf_free = buf_full; } 66 void ResetByReader(void) { buf_full = buf_free; } 67 68private: 69 char* buffer; 70 unsigned int buf_size; 71 unsigned int buf_full; 72 unsigned int buf_free; 73}; 74 75 76static const int sc_ringBufferSize = 16384; 77 78class SQRLocalVoiceDevice 79{ 80public: 81 uint32_t m_headsetPort; 82 uint32_t m_microphonePort; 83 uint8_t m_localConnections[4]; // connection between this devices mic and other local player's headsets 84 bool m_bChatRestricted; 85 bool m_bFlaggedForShutdown; 86 SceUserServiceUserId m_localUserID; 87 88public: 89 SQRLocalVoiceDevice() 90 : m_headsetPort(SCE_VOICE_INVALID_PORT_ID) 91 , m_microphonePort(SCE_VOICE_INVALID_PORT_ID) 92 , m_localUserID(SCE_USER_SERVICE_USER_ID_INVALID) 93 { 94 for(int i=0;i<4;i++) 95 m_localConnections[i] = 0; 96 } 97 98 void init(SceUserServiceUserId localUserID, bool bChatRestricted); 99 void flagForShutdown() { m_bFlaggedForShutdown = true;} 100 void shutdownWhenFlagged(); 101 bool isValid() { return m_localUserID != SCE_USER_SERVICE_USER_ID_INVALID; } 102// void setBitRate() 103// { 104// int err = sceVoiceSetBitRate(uint32_t portId, 105// SceVoiceBitRate bitrate 106// ); 107// } 108}; 109 110#define VOICE_ENCODED_FORMAT SCE_VOICE_BITRATE_7300 111 112 113 114class SQRVoiceConnection 115{ 116 static const int MAX_LOCAL_PLAYER_COUNT = 4; 117 static const int SNP_MAX_PAYLOAD = 1346; // This is the default RUDP payload size - if we want to change this we'll need to use cellRudpSetOption to set something else & adjust segment size 118 class QueuedSendBlock 119 { 120 public: 121 unsigned char *start; 122 unsigned char *end; 123 unsigned char *current; 124 }; 125 126 std::queue<QueuedSendBlock> m_sendQueue; 127 CRITICAL_SECTION m_csQueue; 128 129public: 130 int m_rudpCtx; 131 bool m_bConnected; 132 uint32_t m_voiceInPort; // 1 input port per connection, incoming UDP packets are written to each of these, and then they're connected out to all headsets 133 int m_headsetConnectionMask; // 1 bit per player, if the headset connection has been made 134 RingBuffer m_playRingBuffer; 135 SceNpMatching2RoomMemberId m_remoteRoomMemberId; // Assigned by Matching2 lib, we can use to indicate which machine this player belongs to (note - 16 bits) 136 std::queue<VoicePacket> m_receivedVoicePackets; 137 CRITICAL_SECTION m_csPacketQueue; 138 VoicePacket::Flags m_remotePlayerFlags[MAX_LOCAL_PLAYER_COUNT]; 139 uint32_t m_nextExpectedFrameIndex; 140 bool m_bFlaggedForShutdown; 141 SQRVoiceConnection(int rudpCtx, SceNpMatching2RoomMemberId remoteRoomMemberId); 142 ~SQRVoiceConnection(); 143 144 void SendInternal(const void *data, unsigned int dataSize); 145 void SendMoreInternal(); 146 void readRemoteData(); 147 bool getNextPacket(VoicePacket& packet); 148 void addPacket(VoicePacket& packet); 149 150 151}; 152 153class SonyVoiceChat_Orbis 154{ 155public: 156 157 static void init(); 158 static void start(); 159 static void shutdown(); 160 static void tick(); 161 static void checkFinished(); 162 static void setEnabled(bool bEnabled); 163 static bool hasMicConnected(SQRNetworkPlayer* pNetPlayer); 164 static bool isTalking(SQRNetworkPlayer* pNetPlayer); 165 static void mute(bool bMute); //Turn chat audio on or off 166 static void mutePlayer(const SceNpMatching2RoomMemberId member_id, bool bMute); //Turn chat audio from a specified player on or off; 167 static void muteLocalPlayer(bool bMute); //Turn microphone input on or off; 168 169 static bool isMuted(); 170 static bool isMutedPlayer(const PlayerUID& memberUID); 171 static bool isMutedLocalPlayer(); //Turn microphone input on or off; 172 173 static void initLocalPlayer(int playerIndex); 174 175 static SQRVoiceConnection* addRemoteConnection(int RudpCxt, SceNpMatching2RoomMemberId peerMemberId); 176 static void connectPlayer(SQRVoiceConnection* pConnection, int playerIndex); 177 static void connectPlayerToAll(int playerIndex); 178 static void disconnectLocalPlayer(int localIdx); 179 static void disconnectRemoteConnection( SQRVoiceConnection* pVoice ); 180 181 static void VoiceEventCallback( SceVoiceEventData* pEvent ); 182 183 static std::vector<SQRVoiceConnection*> m_remoteConnections; 184 static void connectPorts(uint32_t inPort, uint32_t outPort); 185 static void disconnectPorts(uint32_t inPort, uint32_t outPort); 186 static void makeLocalConnections(); 187 static void breakLocalConnections(int playerIdx); 188 189 static void sendAllVoiceData(); 190 static void playAllReceivedData(); 191 192 static void sendPCMMicData(); 193 static SQRVoiceConnection* getVoiceConnectionFromRoomMemberID(SceNpMatching2RoomMemberId roomMemberID); 194 195 static SQRVoiceConnection* GetVoiceConnectionFromRudpCtx(int RudpCtx); 196 static void setConnected(int RudpCtx); 197 198private: 199 static const int MAX_LOCAL_PLAYER_COUNT = 4; 200 201 static bool m_bVoiceStarted; 202 static int m_numLocalDevicesConnected; 203 static SQRLocalVoiceDevice m_localVoiceDevices[MAX_LOCAL_PLAYER_COUNT]; 204 205 static uint32_t m_voiceOutPort; // single output port that all local devices are mixed to, and then sent out to all other remote machines 206 207 static RingBuffer m_recordRingBuffer; 208 static RingBuffer m_playRingBuffer; 209 static VoicePacket::Flags m_localPlayerFlags[MAX_LOCAL_PLAYER_COUNT]; 210 static bool m_forceSendPacket; // force a packet across the network, even if there's no data, so we can update flags 211 static bool m_bInitialised; 212 static CRITICAL_SECTION m_csRemoteConnections; 213 214 215};