/// <summary> /// Enqueues the Volplane ready event. /// </summary> /// <param name="code">Current game code.</param> private void AirConsoleReady(string code) { VolplaneAgent.GameCode = code; if (Config.DebugLog == (int)DebugState.All) { VDebug.LogFormat("[Volplane] AirConsole is ready! Game started with connect code: '{0:G}'.", code); } if (OnReady != null) { eventQueue.Enqueue(delegate { OnReady.Invoke(); }); } }
/// <summary> /// Adds a new player to the player list if it not yet exists. /// </summary> /// <returns>The player number.</returns> /// <param name="acDeviceId">AirConsole device identifier.</param> protected int AddPlayer(int acDeviceId) { if (acDeviceId < 1) { return(-1); } // Get index of this player int index = GetPlayerId(acDeviceId); // Player does not exist yet if (index == -1) { AllocateCustomStateArrays(acDeviceId); // Create new player and subscribe state change event for updating custom device state VPlayer newPlayer = new VPlayer(acDeviceId); Action <bool> updateState = delegate(bool active) { VolplaneAgent.CustomState.Active[acDeviceId] = active; VolplaneController.AirConsole.SetCustomDeviceState(VolplaneAgent.CustomState.ToJSON()); }; newPlayer.OnStateChange += updateState; // Invoke 'updateState' delegate for initialization updateState(newPlayer.State == VPlayer.PlayerState.Active); // Add player to player list index = VolplaneAgent.Players.Count; VolplaneAgent.Players.Add(newPlayer); if (Config.DebugLog == (int)DebugState.All) { VDebug.LogFormat("[Volplane] Registered new device with id: {0:D}. Added as player with id: {1:D}.", acDeviceId, index); } } return(index); }
/// <summary> /// Process inputs. /// </summary> /// <param name="playerId">Player identifier.</param> /// <param name="data">Input data as JSON formatted string.</param> public void ProcessInput(int playerId, string data) { int diffPlayerCount = playerId - VInput.Inputs.Count; // First input from this player? for (int i = 0; i <= diffPlayerCount; i++) { VInput.Inputs.Add(new Dictionary <string, ElementInput>()); } string currentElementName = null; bool stopReading = false; // Read input name identifier using (var sr = new StringReader(data)) using (var reader = new JsonTextReader(sr)) { // Use buffer reader.ArrayPool = JSONArrayPool.Instance; while (!stopReading && reader.Read()) { if ((reader.TokenType == JsonToken.PropertyName) && (reader.Path == "volplane.name")) { currentElementName = reader.ReadAsString(); stopReading = true; } } } // No volplane input if (currentElementName == null) { return; } // Get input object by name, or create new one if not specified yet if (!VInput.Inputs[playerId].TryGetValue(currentElementName, out tempInput)) { tempInput = new ElementInput(); VInput.Inputs[playerId].Add(currentElementName, tempInput); if (Config.DebugLog == (int)DebugState.All) { VDebug.LogFormat("[Volplane (Input Handling)] New input registered: '{0:G}'.", currentElementName); } } // Enqueue processing if the same input changed state in the same frame if (tempInput.Dirty) { updateQueue.Enqueue(delegate { ProcessInput(playerId, data); }); if (Config.DebugLog == (int)DebugState.All) { VDebug.Log("[Volplane (Input Handling)] Queueing multiple inputs from same element."); } return; } // Read and processing input data using (var sr = new StringReader(data)) using (var reader = new JsonTextReader(sr)) { // Use buffer reader.ArrayPool = JSONArrayPool.Instance; while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { switch (reader.Path) { // Input type case "volplane.type": reader.Read(); switch (reader.Value.ToString()) { case "dpad": tempInput.Type = ElementInput.InputType.DPad; break; case "joystick": tempInput.Type = ElementInput.InputType.Joystick; break; case "swipe": tempInput.Type = ElementInput.InputType.SwipeField; break; case "touch": tempInput.Type = ElementInput.InputType.TouchArea; break; case "motion": tempInput.Type = ElementInput.InputType.Motion; break; default: tempInput.Type = ElementInput.InputType.Button; break; } break; // Input state case "volplane.data.state": tempInput.State = reader.ReadAsBoolean() ?? false; break; // Input timestamp case "volplane.data.timeStamp": reader.Read(); tempInput.Delay = (int)(VolplaneController.AirConsole.GetServerTime() - Int64.Parse(reader.Value.ToString())); break; // Coordinate X case "volplane.data.x": tempInput.X = (float)(reader.ReadAsDouble() ?? 0d); break; // Coordinate X case "volplane.data.y": tempInput.Y = (float)(reader.ReadAsDouble() ?? 0d); break; // Trigger indicator case "volplane.data.hadDirections": tempInput.HadDirections = reader.ReadAsBoolean() ?? false; break; // Swipe distance case "volplane.data.distance": tempInput.Distance = (float)(reader.ReadAsDouble() ?? 0d); break; // Swipe angle in radians case "volplane.data.angle": tempInput.Angle = (float)(reader.ReadAsDouble() ?? 0d); break; // Swipe angle in degree case "volplane.data.degree": tempInput.Degree = (float)(reader.ReadAsDouble() ?? 0d); break; // Swipe speed case "volplane.data.speed": tempInput.Speed = (float)(reader.ReadAsDouble() ?? 0d); break; // Accelerometer X case "volplane.data.ax": tempInput.AX = (float)(reader.ReadAsDouble() ?? 0d); break; // Accelerometer Y case "volplane.data.ay": tempInput.AY = (float)(reader.ReadAsDouble() ?? 0d); break; // Accelerometer Z case "volplane.data.az": tempInput.AZ = (float)(reader.ReadAsDouble() ?? 0d); break; // Gyroscope alpha case "volplane.data.alpha": tempInput.Alpha = (float)(reader.ReadAsDouble() ?? 0d); break; // Gyroscope beta case "volplane.data.beta": tempInput.Beta = (float)(reader.ReadAsDouble() ?? 0d); break; // Gyroscope gamma case "volplane.data.gamma": tempInput.Gamma = (float)(reader.ReadAsDouble() ?? 0d); break; } } } } // Set dirty tempInput.Dirty = true; // Fire events switch (tempInput.Type) { case ElementInput.InputType.Button: // Event if (VInput.ButtonEvents && (OnButton != null)) { updateQueue.Enqueue(delegate { OnButton(playerId, currentElementName, tempInput.State); }); } break; case ElementInput.InputType.DPad: // Event if (VInput.DPadEvents && (OnDPad != null)) { updateQueue.Enqueue(delegate { OnDPad(playerId, currentElementName, new Vector2(tempInput.X, tempInput.Y)); }); } break; case ElementInput.InputType.Joystick: // Event if (VInput.JoystickEvents && (OnJoystick != null)) { updateQueue.Enqueue(delegate { OnJoystick(playerId, currentElementName, new Vector2(tempInput.X, tempInput.Y)); }); } break; case ElementInput.InputType.SwipeField: // Event if (VInput.SwipeEvents && (OnSwipe != null)) { updateQueue.Enqueue(delegate { OnSwipe(playerId, currentElementName, new Vector2(tempInput.X, tempInput.Y)); }); } break; case ElementInput.InputType.TouchArea: // Event if (VInput.TouchEvents && (OnTouch != null)) { updateQueue.Enqueue(delegate { OnTouch(playerId, currentElementName, new Vector2(tempInput.X, tempInput.Y)); }); } break; default: // Events if (VInput.MotionEvents && (OnAccelerometer != null)) { updateQueue.Enqueue(delegate { OnAccelerometer(playerId, new Vector3(tempInput.AX, tempInput.AY, tempInput.AZ)); }); } if (VInput.MotionEvents && (OnGyroscope != null)) { updateQueue.Enqueue(delegate { OnGyroscope(playerId, new Vector3(tempInput.Alpha, tempInput.Beta, tempInput.Gamma)); }); } break; } }