aboutsummaryrefslogtreecommitdiff
path: root/src/parsec/net_prediction.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
commitc068f22329d5cc722622a2183bbb22eef2093df7 (patch)
tree12d56c1aede67988a55e241364606bfbb4dba933 /src/parsec/net_prediction.cpp
downloadopenparsec-c068f22329d5cc722622a2183bbb22eef2093df7.tar.xz
openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.zip
initial importHEADmain
Diffstat (limited to 'src/parsec/net_prediction.cpp')
-rw-r--r--src/parsec/net_prediction.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/parsec/net_prediction.cpp b/src/parsec/net_prediction.cpp
new file mode 100644
index 0000000..bec7e4e
--- /dev/null
+++ b/src/parsec/net_prediction.cpp
@@ -0,0 +1,194 @@
+/*
+ * PARSEC -
+ *
+ * $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:30 $
+ *
+ * Orginally written by:
+ * Copyright (c) Clemens Beer <cbx@parsec.org> 2002-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// C library
+#include <stdio.h>
+#include <string.h>
+
+// compilation flags/debug support
+#include "config.h"
+#include "debug.h"
+
+// general definitions
+#include "general.h"
+#include "objstruc.h"
+
+// global externals
+#include "globals.h"
+
+// subsystem headers
+#include "net_defs.h"
+
+// utility modules
+#include "utl_list.h"
+
+// local module header
+#include "net_prediction.h"
+
+// proprietary module headers
+#include "con_aux.h"
+#include "e_record.h"
+#include "g_extra.h"
+#include "h_supp.h"
+#include "net_game.h"
+#include "net_stream.h"
+#include "g_sfx.h"
+
+
+// special implementation for a extra collect prediction event ----------------
+//
+G_PredEventExtraCollect::G_PredEventExtraCollect( ExtraObject* pExtra ) :
+ m_pExtra( pExtra )
+{
+ ASSERT( pExtra != NULL );
+}
+
+// do the extra collection ----------------------------------------------------
+//
+void G_PredEventExtraCollect::Do()
+{
+ char* pszMessage = TheGameExtraManager->CollectExtra( MyShip, m_pExtra );
+
+ // show message saying what type of extra has been collected
+ if ( m_nDoCount == 0 ) {
+ if ( pszMessage != NULL ) {
+//#ifdef PARSEC_DEBUG
+// WriteExtraCollectMessage( "G_PredEventExtraCollect::Do()" );
+//#else // !PARSEC_DEBUG
+ WriteExtraCollectMessage( pszMessage );
+//#endif // !PARSEC_DEBUG
+ } else {
+ MSGOUT( "CheckShipExtraCollision(): invalid extra type: %0x.", m_pExtra->ObjectType );
+ }
+ }
+
+#ifdef PARSEC_DEBUG
+ MSGOUT( "G_PredEventExtraCollect::Do()" );
+#endif // PARSEC_DEBUG
+ NET_PredEvent::Do();
+}
+
+
+//NOTE: stores information about events that were predicted in the game-engine
+// whenever the game-engine modifies the local world, we save a prediction
+// that includes a checkpoint ( = next outgoing message id )
+// whenever we receive a packet, we clear all predictions inserted before
+// the ACK checkpoint and we re-apply all pending predictions not yet
+// ACK ( checkpoint # is synonym for message id )
+
+// standard ctor --------------------------------------------------------------
+//
+NET_PredictionManager::NET_PredictionManager( NET_Stream* pStream )
+{
+ ASSERT( pStream != NULL );
+
+ m_predictions = new UTL_List<NET_PredEvent*>;
+ m_pStream = pStream;
+}
+
+
+// standard dtor --------------------------------------------------------------
+//
+NET_PredictionManager::~NET_PredictionManager()
+{
+ Reset();
+ delete m_predictions;
+}
+
+
+// reset ----------------------------------------------------------------------
+//
+void NET_PredictionManager::Reset()
+{
+ // remove all predictions
+ for( LE_PredEvt* entry = m_predictions->GetHead(); entry != NULL; entry = entry->m_pNext ) {
+ delete entry->m_data;
+ }
+ m_predictions->Clear();
+}
+
+
+// clear all predictions up to the message# and reapply all predictions after the message#
+//
+void NET_PredictionManager::DoCheckpoint( dword MessageId )
+{
+ for( LE_PredEvt* pEntry = m_predictions->GetHead(); pEntry != NULL; ) {
+ LE_PredEvt* pNext = pEntry->m_pNext;
+ NET_PredEvent* pPred = pEntry->m_data;
+ if ( pPred->GetMessageId() <= MessageId ) {
+#ifdef PARSEC_DEBUG
+ MSGOUT( "NET_PredictionManager::DoCheckpoint(): removing ACK prediction ( pred-msgid %d <= msgid %d)", pPred->GetMessageId(), MessageId );
+#endif // PARSEC_DEBUG
+ delete m_predictions->RemoveEntry( pEntry );
+ } else {
+#ifdef PARSEC_DEBUG
+ int nDoCountBefore = pPred->GetDoCount();
+ MSGOUT( "NET_PredictionManager::DoCheckpoint(): reapplying prediction ( pred-msgid %d > msgid %d)", pPred->GetMessageId(), MessageId );
+#endif // PARSEC_DEBUG
+
+ pPred->Do();
+
+#ifdef PARSEC_DEBUG
+ ASSERT( pPred->GetDoCount() == ( nDoCountBefore + 1 ) );
+#endif // PARSEC_DEBUG
+ }
+ pEntry = pNext;
+ }
+}
+
+
+// add a predictionevent ------------------------------------------------------
+// ensures that MAX_NUM_PREDICTIONS is not exceeded
+void NET_PredictionManager::_AddPrediction( NET_PredEvent* pEvent )
+{
+ // check for prediction choke ( server does not send ACKs for checkpoints fast enough )
+ if ( m_predictions->GetNumEntries() >= MAX_NUM_PREDICTIONS ) {
+ MSGOUT( "NET_PredictionManager::_AddPrediction(): prediction list overflow" );
+ return;
+ } else {
+ m_predictions->AppendTail( pEvent );
+ pEvent->SetMessageId( m_pStream->GetNextOutMessageId() );
+#ifdef PARSEC_DEBUG
+ int nDoCountBefore = pEvent->GetDoCount();
+
+ MSGOUT( "NET_PredictionManager::_AddPrediction() at msgid: %d", m_pStream->GetNextOutMessageId() );
+
+#endif // PARSEC_DEBUG
+
+ pEvent->Do();
+
+#ifdef PARSEC_DEBUG
+ ASSERT( pEvent->GetDoCount() == ( nDoCountBefore + 1 ) );
+#endif // PARSEC_DEBUG
+ }
+}
+
+
+// add a prediction event for collecting an extra -----------------------------
+//
+void NET_PredictionManager::PredictExtraCollect( ExtraObject* pExtra )
+{
+ ASSERT( pExtra != NULL );
+ _AddPrediction( new G_PredEventExtraCollect( pExtra ) );
+}
+