void InitAbility() { if (shootAbility.enabled) { shootCooldown = Time.time + shootAbility.value.cooldown; if (shootAbility.value.shootPattern == BulletPattern.Gun) { CreateWeapon(ref shootAbility.value.gunData.weapon); } else { BurstData burst = shootAbility.value.burstData; burst.positions = new Vector3[burst.numberOfBullets]; MathUtils.GenerateCircleOutlineNonAlloc(Vector3.zero, burst.radius, 0, burst.positions); burst.rotations = new Quaternion[burst.numberOfBullets]; for (int i = 0; i < burst.numberOfBullets; i++) { burst.rotations[i] = Quaternion.LookRotation(burst.positions[i].normalized, Vector3.up); } } } if (teleportAbility.enabled) { teleportAbility.value.trail = GetComponent <TrailRenderer>(); } }
private IEnumerator BurstProjectiles(BurstData burst) { audioManager.PlaySfx(burst.sfx); WaitForSeconds timeBtwWaves = new WaitForSeconds(burst.timeBtwWaves); for (int n = 0; n < burst.waves; n++) { for (int i = 0; i < burst.numberOfBullets; i++) { Projectile bullet = pooler.SpawnFromPool <Projectile>(burst.projectile, burst.positions[i] + transform.position, burst.rotations[i]); bullet.Init(burst.damage, 0, 0, true, false); bullet.SetVelocity(0); } yield return(timeBtwWaves); } }
public void BurstSpiTest() { Console.WriteLine("Starting SPI burst read test..."); List <byte> BurstTxData = new List <byte>(); ushort[] BurstData; int index; RegMapClasses.RegClass triggerReg = new RegMapClasses.RegClass(); triggerReg.NumBytes = 2; triggerReg.Address = 0x12; FX3.DrActive = false; for (int byteCount = 4; byteCount < 400; byteCount += 2) { Console.WriteLine("Testing burst read of " + byteCount.ToString() + " bytes..."); FX3.BurstByteCount = byteCount; Assert.AreEqual(byteCount, FX3.BurstByteCount, "ERROR; Byte count not applied correctly"); Assert.AreEqual((byteCount - 2) / 2, FX3.WordCount, "ERROR: FX3 burst word count not set correctly"); /* Burst trigger reg */ FX3.TriggerReg = triggerReg; /* strip header */ Console.WriteLine("Testing burst read with trigger reg and header stripped..."); FX3.StripBurstTriggerWord = true; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2) - 1, BurstData.Count(), "ERROR: Invalid burst data count"); for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(0, BurstData[i], "ERROR: Expected all burst data to be 0"); } /* No strip header */ Console.WriteLine("Testing burst read with trigger reg and header not stripped..."); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2), BurstData.Count(), "ERROR: Invalid burst data count"); Assert.AreEqual(0x1200, BurstData[0], "ERROR: Invalid burst data echoed"); for (int i = 1; i < BurstData.Count(); i++) { Assert.AreEqual(0, BurstData[i], "ERROR: Expected remainder of burst data to be 0"); } /* Burst transmit data */ BurstTxData.Clear(); for (int i = 0; i < byteCount; i++) { BurstTxData.Add((byte)(i & 0xFFU)); } FX3.BurstMOSIData = BurstTxData.ToArray(); for (int i = 0; i < BurstTxData.Count; i++) { Assert.AreEqual(BurstTxData[i], FX3.BurstMOSIData[i], "ERROR: Burst MOSI data not applied correctly"); } /* strip header */ Console.WriteLine("Testing burst read with MOSI byte array and header stripped..."); FX3.StripBurstTriggerWord = true; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2) - 1, BurstData.Count(), "ERROR: Invalid burst data count"); index = 2; for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(BurstTxData[index], BurstData[i] >> 8, "ERROR: Invalid burst data echoed"); Assert.AreEqual(BurstTxData[index + 1], BurstData[i] & 0xFF, "ERROR: Invalid burst data echoed"); index += 2; } /* No strip header */ Console.WriteLine("Testing burst read with MOSI byte array and header not stripped..."); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2), BurstData.Count(), "ERROR: Invalid burst data count"); index = 0; for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(BurstTxData[index], BurstData[i] >> 8, "ERROR: Invalid burst data echoed"); Assert.AreEqual(BurstTxData[index + 1], BurstData[i] & 0xFF, "ERROR: Invalid burst data echoed"); index += 2; } } Console.WriteLine("Testing Dr Active triggering for burst..."); FX3.DrPin = FX3.DIO3; FX3.StartPWM(100, 0.5, FX3.DIO4); FX3.BurstByteCount = 64; BurstTxData.Clear(); for (int i = 0; i < 64; i++) { BurstTxData.Add((byte)(i & 0xFFU)); } FX3.BurstMOSIData = BurstTxData.ToArray(); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.DrActive = true; double expectedTime; long drActiveTime, baseTime; Stopwatch timer = new Stopwatch(); for (uint numBuffers = 100; numBuffers <= 300; numBuffers += 100) { Console.WriteLine("Capturing " + numBuffers.ToString() + " buffers with DrActive set to false..."); FX3.DrActive = false; FX3.StartBurstStream(numBuffers, FX3.BurstMOSIData); timer.Restart(); while (FX3.GetNumBuffersRead < numBuffers) { System.Threading.Thread.Sleep(1); } baseTime = timer.ElapsedMilliseconds; Console.WriteLine("Stream time: " + baseTime.ToString() + "ms"); CheckBurstBuffers(BurstTxData.ToArray(), numBuffers); Console.WriteLine("Capturing " + numBuffers.ToString() + " buffers with DrActive set to true..."); expectedTime = 10 * numBuffers; //100Hz DR FX3.DrActive = true; FX3.StartBurstStream(numBuffers, FX3.BurstMOSIData); timer.Restart(); while (FX3.GetNumBuffersRead < numBuffers) { System.Threading.Thread.Sleep(1); } drActiveTime = timer.ElapsedMilliseconds; Console.WriteLine("Stream time: " + drActiveTime.ToString() + "ms"); Assert.AreEqual(expectedTime, drActiveTime, 0.25 * expectedTime, "ERROR: Invalid stream time"); CheckBurstBuffers(BurstTxData.ToArray(), numBuffers); Assert.Less(baseTime, drActiveTime, "ERROR: Base stream time greater than DrActive stream time"); } }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { eSuccessState success = eSuccessState.Unknown; if (IsDummy(decodedBurst)) { State = eBurstState.Idle; DummyBursts++; //CloseFiles(); /* don't treat TCHs as a reliable source for end-of-connection detection */ //DummyBurstReceived(param); if (DumpRawData) { StatusMessage = "Dummy Burst"; } return(eSuccessState.Succeeded); } EncryptionType = AssociatedSACCH.EncryptionType; ChannelEncrypted = AssociatedSACCH.ChannelEncrypted; StoreBurstContext(param, decodedBurst, TCHSeq); /* GSM 05.03 Ch 2.1 */ /* when we got 8 TCH bursts */ if (++TCHSeq == 8) { TCHSeq = 0; /* try to decrypt buffer if this is enabled, but do not try to crack the key */ if (!HandleEncryption(param, false)) { State = eBurstState.CryptedTraffic; /* encrypted but no decryptor available, silently return */ return(eSuccessState.Unknown); } /* deinterleave the 8 TCH bursts. the result is a 456 bit block. i[] to c[] */ Deinterleave(); /* * GSM-05.03 4.2.5 * was this burst stolen for a FACCH? hl(B) (in e[]) is set for the last 4 bursts */ if (IsHL(decodedBurst)) { /* pass encryption information to FACCH */ FACCH.A5Algorithm = A5Algorithm; FACCH.A5CipherKey = A5CipherKey; FACCH.ChannelEncrypted = ChannelEncrypted; /* pass c[] to FACCH handler */ success = FACCH.ParseFACCHData(param, BurstBufferC); StatusMessage = FACCH.StatusMessage; ErrorMessage = FACCH.ErrorMessage; FACCH.StatusMessage = null; FACCH.ErrorMessage = null; } else { /* TCH speech/data (data not supported yet) */ /* split up the class 1... */ Array.Copy(BurstBufferC, Class1DataConv, Class1DataConv.Length); /* ... and class 2 bits */ Array.Copy(BurstBufferC, 378, GSMFrameBufferD, 182, 78); /* use an own convolutional coder buffer for these 188 bits */ if (ConvolutionalCoder.Decode(Class1DataConv, ref Class1Data) == 0) { bool[] parityBits = new bool[53]; for (int pos = 0; pos < 91; pos++) { GSMFrameBufferD[2 * pos] = Class1Data[pos]; GSMFrameBufferD[2 * pos + 1] = Class1Data[184 - pos]; } /* calculate parity */ Array.Copy(GSMFrameBufferD, 0, parityBits, 0, 50); Array.Copy(Class1Data, 91, parityBits, 50, 3); bool[] crc = CRC.Calc(parityBits, 0, 53, CRC.PolynomialTCHFR); if (CRC.Matches(crc)) { DataBursts++; success = eSuccessState.Succeeded; if (ChannelEncrypted) { State = eBurstState.DecryptedTraffic; } else { State = eBurstState.PlainTraffic; } #if false #region Microsoft WAV49 GSM Format if (WAV49First) { BitMapping.Unmap(GSMFrameBufferD, 0, WAV49FrameBool, 0, BitMapping.g610BitOrder); } else { /* directly unmap into boolean WAV49 frame buffer */ BitMapping.Unmap(GSMFrameBufferD, 0, WAV49FrameBool, 260, BitMapping.g610BitOrder); /* convert that WAV49 frame to byte[] */ ByteUtil.BitsToBytes(WAV49FrameBool, WAV49FrameByte); try { if (OutFile == null) { string name = ("GSM_" + Name + "_" + param.FN + ".wav").Replace("/", "_"); OutFile = new FileStream(name, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); WriteHeader(OutFile); } /* and write it */ WriteBuffer(OutFile, WAV49FrameByte); WriteHeader(OutFile); StatusMessage = "GSM 06.10 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage = "GSM 06.10 Voice data (Writing file failed, " + e.GetType() + ")"; } } WAV49First = !WAV49First; #endregion #endif if (ChannelMode != 33) { #region write audio dump in RTP A/V Format /* GSM frame magic */ RTPFrameBool[0] = true; RTPFrameBool[1] = true; RTPFrameBool[2] = false; RTPFrameBool[3] = true; /* directly unmap into boolean RTP frame buffer */ BitMapping.Unmap(GSMFrameBufferD, 0, RTPFrameBool, 4, BitMapping.g610BitOrder); /* convert that RTP frame to byte[] */ ByteUtil.BitsToBytes(RTPFrameBool, RTPFrameByte); StatusMessage = ""; if (ChannelEncrypted) { StatusMessage += "======= encrypted =======" + Environment.NewLine; } try { if (OutFile == null) { string name = ("GSM_" + Name + "_" + param.FN).Replace("/", "_"); OutFile = new FileStream(name + ".gsm", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); //OutFileRaw = new FileStream(name + ".raw", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); StatusMessage += "Created file: '" + name + "'" + Environment.NewLine; } /* and write it */ OutFile.Write(RTPFrameByte, 0, RTPFrameByte.Length); OutFile.Flush(); /* * Array.Copy(GSMFrameBufferD, 0, RTPFrameBool, 4, GSMFrameBufferD.Length); * RTPFrameBool[0] = false; * RTPFrameBool[1] = false; * RTPFrameBool[2] = false; * RTPFrameBool[3] = false; * ByteUtil.BitsToBytes(RTPFrameBool, RTPFrameByte); * OutFileRaw.Write(RTPFrameByte, 0, RTPFrameByte.Length); */ StatusMessage += "GSM 06.10 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage += "GSM 06.10 Voice data (Writing file failed, " + e.GetType() + ")"; } #endregion } else { #region write audio dump in AMR Format (assume 12.2kbit/s) UnmapDToW(); UnmapWToS(); /* convert that AMR frame to byte[] */ ByteUtil.BitsToBytes(BurstBufferSpeechBits, RTPFrameByte); StatusMessage = ""; if (ChannelEncrypted) { StatusMessage += "======= encrypted =======" + Environment.NewLine; } try { if (OutFile == null) { byte[] fileHeader = new byte[] { 0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A }; string name = ("GSM_" + Name + "_" + param.FN).Replace("/", "_"); OutFile = new FileStream(name + ".amr", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); OutFile.Write(fileHeader, 0, fileHeader.Length); } /* and write it */ OutFile.WriteByte(0x3C); OutFile.Write(RTPFrameByte, 0, 31); OutFile.Flush(); StatusMessage += "GSM 06.90 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage += "GSM 06.90 Voice data (Writing file failed, " + e.GetType() + ")"; } #endregion } } else { State = eBurstState.Failed; CryptedFrames++; ErrorMessage = "(TCH/F Class Ia: CRC Error)"; } } else { State = eBurstState.Failed; CryptedFrames++; ErrorMessage = "(TCH/F Class I: Error in ConvolutionalCoder)"; } } /* trick: * first use the last 8 bursts until one block was successfully decoded. * then use the last 4 bursts as we normally would do. * this will help in finding the correct alignment within the 4 frames. */ if (success == eSuccessState.Succeeded) { BurstShiftCount = 4; } else { BurstShiftCount = 7; } /* save the last n bursts for the next block */ for (int pos = 0; pos < BurstShiftCount; pos++) { BurstData src = BurstBlock[(8 - BurstShiftCount) + pos]; BurstData dst = BurstBlock[pos]; dst.FN = src.FN; dst.Count = src.Count; Array.Copy(src.BurstBufferI, 0, dst.BurstBufferI, 0, dst.BurstBufferI.Length); Array.Copy(src.BurstBufferE, 0, dst.BurstBufferE, 0, dst.BurstBufferE.Length); } /* and continue at position n (so we will read another 8-n bursts) */ TCHSeq = BurstShiftCount; /* only when in sync, return error flag */ if (BurstShiftCount == 4) { return(success); } } return(eSuccessState.Unknown); }