the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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};