public override int SyncInput(void *values, int size) { if (_rollingback) { _last_input = _saved_frames.Peek().Input; } else { if (_sync.FrameCount == 0) { _sync.SaveCurrentFrame(); } _last_input = _current_input; } fixed(byte *ptr = _last_input.bits) { UnsafeUtility.MemCpy(values, ptr, size); } return(0); }
public bool AddLocalInput(int queue, ref GameInput input) { int frames_behind = FrameCount - _lastConfirmedFrame; if (FrameCount >= _maxPredictionFrames && frames_behind >= _maxPredictionFrames) { Debug.Log("Rejecting input from emulator: reached prediction barrier."); return(false); } if (FrameCount == 0) { SaveCurrentFrame(); } Debug.LogFormat("Sending undelayed local frame {0} to queue {1}.", FrameCount, queue); input.Frame = FrameCount; _inputQueues[queue].AddInput(ref input); return(true); }
public int SynchronizeInputs(void *values, int size) { int disconnect_flags = 0; var output = (byte *)values; Assert.IsTrue(size >= _config.NumPlayers * _config.InputSize); UnsafeUtility.MemClear(values, size); for (int i = 0; i < _config.NumPlayers; i++) { var input = new GameInput(GameInput.kNullFrame, null, (uint)_config.InputSize); if (_localConnectStatus[i].Disconnected && FrameCount > _localConnectStatus[i].LastFrame) { disconnect_flags |= (1 << i); } else { _inputQueues[i].GetInput(FrameCount, out input); } UnsafeUtility.MemCpy(output + (i * _config.InputSize), input.bits, _config.InputSize); } return(disconnect_flags); }
public void AddRemoteInput(int queue, ref GameInput input) { _inputQueues[queue].AddInput(ref input); }
public bool GetInput(int requested_frame, out GameInput input) { Debug.LogFormat("requesting input frame {}.", requested_frame); // No one should ever try to grab any input when we have a prediction // error. Doing so means that we're just going further down the wrong // path. Assert.IsTrue this to verify that it's true. Assert.IsTrue(_firstIncorrectFrame == GameInput.kNullFrame); // Remember the last requested frame number for later. We'll need // this in AddInput() to drop out of prediction mode. _lastFrameRequested = requested_frame; Assert.IsTrue(requested_frame >= _inputs[_tail].Frame); if (_prediction.Frame == GameInput.kNullFrame) { // If the frame requested is in our range, fetch it out of the queue and // return it. int offset = requested_frame - _inputs[_tail].Frame; if (offset < _length) { offset = (offset + _tail) % _inputs.Length; Assert.IsTrue(_inputs[offset].Frame == requested_frame); input = _inputs[offset]; Debug.LogFormat("returning confirmed frame number {}.", input.Frame); return(true); } // The requested frame isn't in the queue. Bummer. This means we need // to return a prediction frame. Predict that the user will do the // same thing they did last time. if (requested_frame == 0) { Debug.Log("basing new prediction frame from nothing, you're client wants frame 0."); _prediction.Clear(); } else if (_lastAddedFrame == GameInput.kNullFrame) { Debug.Log("basing new prediction frame from nothing, since we have no frames yet."); _prediction.Clear(); } else { Debug.LogFormat("basing new prediction frame from previously added frame (queue entry:{}, frame:{}).", PreviousFrame(_head), _inputs[PreviousFrame(_head)].Frame); _prediction = _inputs[PreviousFrame(_head)]; } _prediction.Frame++; } Assert.IsTrue(_prediction.Frame >= 0); // If we've made it this far, we must be predicting. Go ahead and // forward the prediction frame contents. Be sure to return the // frame number requested by the client, though. input = _prediction; input.Frame = requested_frame; Debug.LogFormat("returning prediction frame number {} ({}).", input.Frame, _prediction.Frame); return(false); }