123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdafx.h"
- #include "EMsgBuffer.h"
- #include <Engine/Math/Functions.h>
- #include <Engine/Base/Memory.h>
- #include <Engine/Math/Quaternion.h>
- void AngleToUL(ANGLE3D &Angle,ULONG &ulResult)
- {
- Quaternion<float> qQuat;
- FLOAT3D Axis;
- float fRotAngle;
- ANGLE3D AxisAngles;
- UBYTE ubDir;
- UWORD swAngle;
- qQuat.FromEuler(Angle);
- qQuat.ToAxisAngle(Axis,fRotAngle);
- Axis.Normalize();
- DirectionVectorToAngles(Axis,AxisAngles);
- ubDir = (UBYTE) (AxisAngles(1)/360*255);
- ulResult = ubDir;
- ubDir = (UBYTE) (AxisAngles(2)/90*127);
- ulResult = ulResult << 8;
- ulResult |= ubDir;
- swAngle = (UWORD) (fRotAngle * 180); // after rounding, angle is precise up to 1/180 degrees (65536/360 ~ 180)
- ulResult = (ulResult << 16) | swAngle;
- };
- void ULToAngle(ULONG &ulResult,ANGLE3D &Angle)
- {
- Quaternion<float> qQuat;
- FLOAT3D Axis;
- float fRotAngle;
- ANGLE3D AxisAngles;
- UBYTE ubDir;
- UWORD swAngle;
- Matrix<float,3,3> mRotMatrix;
- swAngle = ulResult & 0x0000FFFF;
- fRotAngle = swAngle / 180.0f;
- ulResult = ulResult >> 16;
- ubDir = ulResult & 0x000000FF;
- AxisAngles(2) = ((FLOAT) ubDir)*90/127;
- ulResult = ulResult >> 8;
- ubDir = ulResult & 0x000000FF;
- AxisAngles(1) = ((FLOAT) ubDir)*360/255;
- AxisAngles(3) = 0;
- AnglesToDirectionVector(AxisAngles,Axis);
- qQuat.FromAxisAngle(Axis,fRotAngle);
- qQuat.ToMatrix(mRotMatrix);
- DecomposeRotationMatrixNoSnap(Angle,mRotMatrix);
- };
- void CEntityMessage::WritePlacement(ULONG &ulEntityID,CPlacement3D &plPlacement)
- {
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- em_ulType = EMT_SETPLACEMENT;
- em_ubSize = sizeof(FLOAT3D) + sizeof(ULONG);
- em_ulEntityID = ulEntityID;
- swH = (SWORD) ((plPlacement.pl_OrientationAngle(1)+180)*5);
- swP = (SWORD) ((plPlacement.pl_OrientationAngle(2)+90)*5);
- swB = (SWORD) ((plPlacement.pl_OrientationAngle(3)+180)*5);
- ulShrunkAngle = ((((ULONG) swH) & 0x000007FF) << 21);
- ulShrunkAngle |= ((((ULONG) swP) & 0x000003FF) << 11);
- ulShrunkAngle |= (((ULONG) swB) & 0x000007FF);
- pubMarker = em_aubMessage;
- memcpy(pubMarker,&(plPlacement.pl_PositionVector(1)),sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(pubMarker,&ulShrunkAngle,sizeof(ULONG));
- };
- void CEntityMessage::ReadPlacement(ULONG &ulEntityID,CPlacement3D &plPlacement)
- {
- ASSERT (em_ulType == EMT_SETPLACEMENT);
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- ulEntityID = em_ulEntityID;
- pubMarker = em_aubMessage;
- memcpy(&(plPlacement.pl_PositionVector(1)),pubMarker,sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(&ulShrunkAngle,pubMarker,sizeof(ULONG));
-
- swB = (SWORD) ulShrunkAngle & 0x000007FF;
- swP = (SWORD) (ulShrunkAngle >> 11) & 0x000003FF;
- swH = (SWORD) (ulShrunkAngle >> 21) & 0x000007FF;
-
- plPlacement.pl_OrientationAngle(1) = ((float)swH) / 5 - 180;
- plPlacement.pl_OrientationAngle(2) = ((float)swP) / 5 - 90;
- plPlacement.pl_OrientationAngle(3) = ((float)swB) / 5 - 180;
- };
- void CEntityMessage::WriteEntityEvent(ULONG &ulEntityID,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- UBYTE *pubMarker;
- em_ulType = EMT_EVENT;
- em_ubSize = sizeof(UWORD) + uwDataSize;
- em_ulEntityID = ulEntityID;
- pubMarker = em_aubMessage;
- memcpy(pubMarker,&uwEventCode,sizeof(SLONG));
- pubMarker += sizeof(UWORD);
- memcpy(pubMarker,pvEventData,uwDataSize);
- };
- void CEntityMessage::ReadEntityEvent(ULONG &ulEntityID,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- ASSERT (em_ulType == EMT_EVENT);
- UBYTE *pubMarker;
- pubMarker = em_aubMessage;
- memcpy(&uwEventCode,pubMarker,sizeof(SLONG));
- pubMarker += sizeof(UWORD);
- uwDataSize = em_ubSize - sizeof(ULONG) - sizeof(UWORD);
- memcpy(pvEventData,pubMarker,uwDataSize);
- };
- void CEntityMessage::WriteEntityCreate(ULONG &ulEntityID,CPlacement3D &plPlacement,UWORD &uwEntityClassID,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- em_ulType = EMT_CREATE;
- em_ubSize = sizeof(FLOAT3D) + sizeof(ULONG) + sizeof(UWORD) + sizeof(UWORD) + uwDataSize;
- em_ulEntityID = ulEntityID;
- swH = (SWORD) ((plPlacement.pl_OrientationAngle(1)+180)*5);
- swP = (SWORD) ((plPlacement.pl_OrientationAngle(2)+90)*5);
- swB = (SWORD) ((plPlacement.pl_OrientationAngle(3)+180)*5);
- ulShrunkAngle = ((((ULONG) swH) & 0x000007FF) << 21);
- ulShrunkAngle |= ((((ULONG) swP) & 0x000003FF) << 11);
- ulShrunkAngle |= (((ULONG) swB) & 0x000007FF);
- pubMarker = em_aubMessage;
- memcpy(pubMarker,&(plPlacement.pl_PositionVector(1)),sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(pubMarker,&ulShrunkAngle,sizeof(ULONG));
- pubMarker += sizeof(ULONG);
- memcpy(pubMarker,&uwEntityClassID,sizeof(UWORD));
- pubMarker += sizeof(UWORD);
- memcpy(pubMarker,&uwEventCode,sizeof(UWORD));
- pubMarker += sizeof(UWORD);
- memcpy(pubMarker,pvEventData,uwDataSize);
- };
- void CEntityMessage::ReadEntityCreate(ULONG &ulEntityID,CPlacement3D &plPlacement,UWORD &uwEntityClassID,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- ASSERT (em_ulType == EMT_CREATE);
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- ulEntityID = em_ulEntityID;
- pubMarker = em_aubMessage;
- memcpy(&(plPlacement.pl_PositionVector(1)),pubMarker,sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(&ulShrunkAngle,pubMarker,sizeof(ULONG));
-
- swB = (SWORD) ulShrunkAngle & 0x000007FF;
- swP = (SWORD) (ulShrunkAngle >> 11) & 0x000003FF;
- swH = (SWORD) (ulShrunkAngle >> 21) & 0x000007FF;
-
- plPlacement.pl_OrientationAngle(1) = ((float)swH) / 5 - 180;
- plPlacement.pl_OrientationAngle(2) = ((float)swP) / 5 - 90;
- plPlacement.pl_OrientationAngle(3) = ((float)swB) / 5 - 180;
- pubMarker += sizeof(ULONG);
- memcpy(&uwEntityClassID,pubMarker,sizeof(UWORD));
- pubMarker += sizeof(UWORD);
- memcpy(&uwEventCode,pubMarker,sizeof(UWORD));
- pubMarker += sizeof(UWORD);
- uwDataSize = em_ubSize - sizeof(FLOAT3D) - sizeof(ULONG) - sizeof(UWORD) - sizeof(UWORD);
- memcpy(pubMarker,pvEventData,uwDataSize);
- };
- void CEntityMessage::WriteEntityDestroy(ULONG &ulEntityID)
- {
-
- em_ulType = EMT_DESTROY;
- em_ubSize = 0;
- em_ulEntityID = ulEntityID;
- };
- void CEntityMessage::ReadEntityDestroy(ULONG &ulEntityID)
- {
- ASSERT (em_ulType == EMT_DESTROY);
- ulEntityID = em_ulEntityID;
- };
- void CEntityMessage::WriteEntityCopy(ULONG &ulSourceEntityID,ULONG &ulTargetEntityID,CPlacement3D &plPlacement,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- em_ulType = EMT_COPY;
- em_ubSize = sizeof(ULONG) + sizeof(FLOAT3D) + sizeof(ULONG) + sizeof(UWORD) + uwDataSize;
- em_ulEntityID = ulSourceEntityID;
- swH = (SWORD) ((plPlacement.pl_OrientationAngle(1)+180)*5);
- swP = (SWORD) ((plPlacement.pl_OrientationAngle(2)+90)*5);
- swB = (SWORD) ((plPlacement.pl_OrientationAngle(3)+180)*5);
- ulShrunkAngle = ((((ULONG) swH) & 0x000007FF) << 21);
- ulShrunkAngle |= ((((ULONG) swP) & 0x000003FF) << 11);
- ulShrunkAngle |= (((ULONG) swB) & 0x000007FF);
- pubMarker = em_aubMessage;
- memcpy(pubMarker,&ulTargetEntityID,sizeof(ULONG));
- pubMarker += sizeof(ULONG);
- memcpy(pubMarker,&(plPlacement.pl_PositionVector(1)),sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(pubMarker,&ulShrunkAngle,sizeof(ULONG));
- pubMarker += sizeof(ULONG);
- memcpy(pubMarker,&uwEventCode,sizeof(SLONG));
- pubMarker += sizeof(UWORD);
- memcpy(pubMarker,pvEventData,uwDataSize);
- };
- void CEntityMessage::ReadEntityCopy(ULONG &ulSourceEntityID,ULONG &ulTargetEntityID,CPlacement3D &plPlacement,UWORD &uwEventCode,void* pvEventData,UWORD &uwDataSize)
- {
- ASSERT (em_ulType == EMT_COPY);
- UBYTE *pubMarker;
- ULONG ulShrunkAngle;
- SWORD swH,swP,swB;
- ulSourceEntityID = em_ulEntityID;
- pubMarker = em_aubMessage;
- memcpy(&ulTargetEntityID,pubMarker,sizeof(ULONG));
- pubMarker += sizeof(ULONG);
- memcpy(&(plPlacement.pl_PositionVector(1)),pubMarker,sizeof(FLOAT3D));
- pubMarker += sizeof(FLOAT3D);
- memcpy(&ulShrunkAngle,pubMarker,sizeof(ULONG));
-
- swB = (SWORD) ulShrunkAngle & 0x000007FF;
- swP = (SWORD) (ulShrunkAngle >> 11) & 0x000003FF;
- swH = (SWORD) (ulShrunkAngle >> 21) & 0x000007FF;
-
- plPlacement.pl_OrientationAngle(1) = ((float)swH) / 5 - 180;
- plPlacement.pl_OrientationAngle(2) = ((float)swP) / 5 - 90;
- plPlacement.pl_OrientationAngle(3) = ((float)swB) / 5 - 180;
- pubMarker += sizeof(ULONG);
- memcpy(&uwEventCode,pubMarker,sizeof(SLONG));
- pubMarker += sizeof(UWORD);
- uwDataSize = em_ubSize - sizeof(ULONG) - sizeof(FLOAT3D) - sizeof(ULONG) - sizeof(UWORD);
- memcpy(pubMarker,pvEventData,uwDataSize);
- };
- CEMsgBuffer::CEMsgBuffer()
- {
- emb_uwNumTickMarkers = 0;
- emb_iFirstTickMarker = 0;
- emb_iCurrentTickMarker = 0;
- emb_fCurrentTickTime = -1;
- for (int i=0;i<MAX_TICKS_KEPT;i++) {
- emb_atmTickMarkers[i].tm_slTickOffset = -1;
- emb_atmTickMarkers[i].tm_fTickTime = -1;
- emb_atmTickMarkers[i].tm_ubAcknowledgesExpected = 0;
- }
- };
- CEMsgBuffer::~CEMsgBuffer ()
- {
- };
- void CEMsgBuffer::Clear(void)
- {
- emb_uwNumTickMarkers = 0;
- emb_iFirstTickMarker = 0;
- emb_iCurrentTickMarker = 0;
- emb_fCurrentTickTime = -1;
- for (int i=0;i<MAX_TICKS_KEPT;i++) {
- emb_atmTickMarkers[i].tm_slTickOffset = -1;
- emb_atmTickMarkers[i].tm_fTickTime = -1;
- emb_atmTickMarkers[i].tm_ubAcknowledgesExpected = 0;
- }
- bu_slWriteOffset = 0;
- bu_slReadOffset = 0;
- bu_slFree = bu_slSize;
- };
- void CEMsgBuffer::WriteMessage(CEntityMessage &emEntityMessage)
- {
- // a tick must have started before any messages are generated
- ASSERT (emb_uwNumTickMarkers > 0);
- ULONG ulTemp;
- int iTickMarker;
- ulTemp = emEntityMessage.em_ulEntityID | (emEntityMessage.em_ulType << 24);
- WriteBytes(&(ulTemp),sizeof(ULONG));
- WriteBytes(&(emEntityMessage.em_ubSize),sizeof(emEntityMessage.em_ubSize));
- if (emEntityMessage.em_ubSize > 0) {
- WriteBytes(emEntityMessage.em_aubMessage,emEntityMessage.em_ubSize);
- }
- iTickMarker = emb_iCurrentTickMarker-1;
- if (iTickMarker < 0) iTickMarker += MAX_TICKS_KEPT;
- emb_atmTickMarkers[iTickMarker].tm_uwNumMessages++;
- };
- int CEMsgBuffer::ReadMessage(CEntityMessage &emEntityMessage)
- {
- ULONG ulTemp;
- if (bu_slReadOffset == bu_slWriteOffset) {
- return EMB_ERR_BUFFER_EMPTY;
- }
- ReadBytes(&(ulTemp),sizeof(ULONG));
- emEntityMessage.em_ulType = ulTemp >> 24;
- emEntityMessage.em_ulEntityID = ulTemp & 0x007FFFFF;
- ReadBytes(&(emEntityMessage.em_ubSize),sizeof(emEntityMessage.em_ubSize));
- if (emEntityMessage.em_ubSize > 0) {
- ReadBytes(emEntityMessage.em_aubMessage,emEntityMessage.em_ubSize);
- }
- return EMB_SUCCESS_OK;
- };
- int CEMsgBuffer::PeekMessageAtOffset(CEntityMessage &emEntityMessage,SLONG &slTickOffset)
- {
- ASSERT(slTickOffset >= 0 && slTickOffset <= bu_slSize);
- ULONG ulTemp;
- PeekBytesAtOffset(&(ulTemp),sizeof(ULONG),slTickOffset);
- emEntityMessage.em_ulType = ulTemp >> 24;
- emEntityMessage.em_ulEntityID = ulTemp & 0x007FFFFF;
- PeekBytesAtOffset(&(emEntityMessage.em_ubSize),sizeof(emEntityMessage.em_ubSize),slTickOffset);
- if (emEntityMessage.em_ubSize > 0) {
- PeekBytesAtOffset(emEntityMessage.em_aubMessage,emEntityMessage.em_ubSize,slTickOffset);
- }
- return EMB_SUCCESS_OK;
- };
- int CEMsgBuffer::StartNewTick(float fTickTime)
- {
-
- if (emb_uwNumTickMarkers >= MAX_TICKS_KEPT) {
- return EMB_ERR_MAX_TICKS;
- }
- emb_atmTickMarkers[emb_iCurrentTickMarker].tm_fTickTime = fTickTime;
- emb_atmTickMarkers[emb_iCurrentTickMarker].tm_slTickOffset = bu_slWriteOffset;
- emb_atmTickMarkers[emb_iCurrentTickMarker].tm_ubAcknowledgesExpected = 0;
- emb_atmTickMarkers[emb_iCurrentTickMarker].tm_uwNumMessages = 0;
-
- emb_uwNumTickMarkers++;
- emb_iCurrentTickMarker++;
- emb_iCurrentTickMarker %= MAX_TICKS_KEPT;
- return EMB_SUCCESS_OK;
- };
- int CEMsgBuffer::SetCurrentTick(float fTickTime)
- {
- int iErr;
- INDEX iTickIndex;
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr != EMB_SUCCESS_OK) {
- return iErr;
- }
- emb_iCurrentTickMarker = iTickIndex;
- return EMB_SUCCESS_OK;
- };
- int CEMsgBuffer::GetTickIndex(float fTickTime,INDEX &iTickIndex)
- {
- INDEX iTickMarker;
- // 0.025 should be _pTimer->TickQuantum/2
- for (int i=0;i<emb_uwNumTickMarkers;i++) {
- iTickMarker = (i + emb_iFirstTickMarker) % MAX_TICKS_KEPT;
- if (fabs(emb_atmTickMarkers[iTickMarker].tm_fTickTime - fTickTime) < 0.025) {
- iTickIndex = iTickMarker;
- return EMB_SUCCESS_OK;
- }
- }
- iTickIndex = -1;
- return EMB_ERR_NOT_IN_BUFFER;
- };
- int CEMsgBuffer::GetTickOffset(float fTickTime,SLONG &slTickOffset)
- {
- INDEX iTickMarker;
- // 0.025 should be _pTimer->TickQuantum/2
- for (int i=0;i<emb_uwNumTickMarkers;i++) {
- iTickMarker = (i + emb_iFirstTickMarker) % MAX_TICKS_KEPT;
- if (fabs(emb_atmTickMarkers[iTickMarker].tm_fTickTime - fTickTime) < 0.025) {
- slTickOffset = emb_atmTickMarkers[iTickMarker].tm_slTickOffset;
- return EMB_SUCCESS_OK;
- }
- }
- slTickOffset = -1.0f;
- return EMB_ERR_NOT_IN_BUFFER;
- };
- int CEMsgBuffer::GetNextTickTime(float fTickTime,float &fNextTickTime)
- {
- INDEX iTickIndex;
- int iErr;
- if (fTickTime < 0) {
- if (emb_uwNumTickMarkers > 0) {
- fNextTickTime = emb_atmTickMarkers[0].tm_fTickTime;
- return EMB_SUCCESS_OK;
- } else {
- return EMB_ERR_NOT_IN_BUFFER;
- }
- }
- if (fTickTime < emb_atmTickMarkers[emb_iFirstTickMarker].tm_fTickTime) {
- fNextTickTime = emb_atmTickMarkers[emb_iFirstTickMarker].tm_fTickTime;
- return SUCCESS_OK;
- };
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr != EMB_SUCCESS_OK) {
- return iErr;
- }
- iTickIndex = (iTickIndex + 1) % MAX_TICKS_KEPT;
- fNextTickTime = emb_atmTickMarkers[iTickIndex].tm_fTickTime;
- return EMB_SUCCESS_OK;
- };
- int CEMsgBuffer::RequestTickAcknowledge(float fTickTime,UBYTE ubNumAcknowledges)
- {
- ASSERT (fTickTime >= 0);
- INDEX iTickIndex;
- int iErr;
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr == EMB_SUCCESS_OK) {
- emb_atmTickMarkers[iTickIndex].tm_ubAcknowledgesExpected += ubNumAcknowledges;
- return EMB_SUCCESS_OK;
- }
- return iErr;
- };
- int CEMsgBuffer::ReceiveTickAcknowledge(float fTickTime)
- {
- ASSERT (fTickTime >= 0);
- INDEX iTickIndex;
- INDEX iFirst;
- int iErr;
- int iNumMark = emb_uwNumTickMarkers;
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr == EMB_SUCCESS_OK) {
- iFirst = emb_iFirstTickMarker;
- emb_atmTickMarkers[iFirst].tm_ubAcknowledgesExpected--;
- while (iFirst!=iTickIndex) {
- iFirst++;
- iFirst%=MAX_TICKS_KEPT;
- emb_atmTickMarkers[iFirst].tm_ubAcknowledgesExpected--;
- }
-
- iFirst = emb_iFirstTickMarker;
- if (emb_atmTickMarkers[iFirst].tm_ubAcknowledgesExpected == 0 && iNumMark != 0) {
- while (emb_atmTickMarkers[iFirst].tm_ubAcknowledgesExpected == 0 && iNumMark != 0) {
- if (iNumMark > 0) {
- iNumMark--;
- iFirst++;
- iFirst %= MAX_TICKS_KEPT;
- }
- }
- MoveToStartOfTick(emb_atmTickMarkers[iFirst].tm_fTickTime);
- }
- return EMB_SUCCESS_OK;
- }
- return iErr;
- };
- // does not advance the read offset - access is random, not sequential
- int CEMsgBuffer::ReadTick(float fTickTime,const void *pv, SLONG &slSize)
- {
- ASSERT (slSize>0);
- ASSERT (pv != NULL);
- ASSERT (fTickTime >= 0);
- int iErr;
- INDEX iTickIndex,iNextTickIndex;
-
-
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr != EMB_SUCCESS_OK) {
- return iErr;
- }
- if (iTickIndex >= (emb_iFirstTickMarker + emb_uwNumTickMarkers - 1)) {
- return EMB_ERR_TICK_NOT_COMPLETE;
- }
- iNextTickIndex = (iTickIndex + 1) % MAX_TICKS_KEPT;
- SLONG slTickSize = emb_atmTickMarkers[iNextTickIndex].tm_slTickOffset - emb_atmTickMarkers[iTickIndex].tm_slTickOffset;
- // if not wrapping
- if ( slTickSize > 0) {
- if (slSize < slTickSize) {
- return EMB_ERR_BUFFER_TOO_SMALL;
- }
- slSize = slTickSize;
- memcpy((UBYTE*)pv,bu_pubBuffer+emb_atmTickMarkers[iTickIndex].tm_slTickOffset,slTickSize);
- } else {
- if (slSize < (bu_slSize - emb_atmTickMarkers[iTickIndex].tm_slTickOffset) + emb_atmTickMarkers[iNextTickIndex].tm_slTickOffset-1) {
- return EMB_ERR_BUFFER_TOO_SMALL;
- }
- slSize = (bu_slSize - emb_atmTickMarkers[iTickIndex].tm_slTickOffset) + emb_atmTickMarkers[iNextTickIndex].tm_slTickOffset;
- // copy data from the start of this ick to the end of the bufer
- memcpy((UBYTE*)pv,bu_pubBuffer+emb_atmTickMarkers[iTickIndex].tm_slTickOffset,bu_slSize - emb_atmTickMarkers[iTickIndex].tm_slTickOffset);
- // copy datafrom the start of the buffer to the start of next tick
- memcpy(((UBYTE*)pv)+bu_slSize - emb_atmTickMarkers[iTickIndex].tm_slTickOffset,bu_pubBuffer,emb_atmTickMarkers[iNextTickIndex].tm_slTickOffset);
- }
- return EMB_SUCCESS_OK;
- };
- void CEMsgBuffer::WriteTick(float tm_fTickTime,const void *pv, SLONG slSize)
- {
- ASSERT(slSize>=0 && pv!=NULL);
- StartNewTick(tm_fTickTime);
- WriteBytes(pv,slSize);
- };
- int CEMsgBuffer::MoveToStartOfTick(float fTickTime)
- {
- int iErr;
- INDEX iTickIndex;
- ASSERT(fTickTime >= emb_atmTickMarkers[emb_iFirstTickMarker].tm_fTickTime);
- iErr = GetTickIndex(fTickTime,iTickIndex);
- if (iErr != EMB_SUCCESS_OK) {
- return iErr;
- }
- // if not wrapping
- if (iTickIndex >= emb_iFirstTickMarker) {
- emb_uwNumTickMarkers -= iTickIndex - emb_iFirstTickMarker;
- } else {
- emb_uwNumTickMarkers -= iTickIndex + (MAX_TICKS_KEPT - emb_iFirstTickMarker);
- }
- emb_iFirstTickMarker = iTickIndex;
- if (bu_slReadOffset <= emb_atmTickMarkers[iTickIndex].tm_slTickOffset) {
- bu_slFree += emb_atmTickMarkers[iTickIndex].tm_slTickOffset - bu_slReadOffset;
- } else {
- bu_slFree += (bu_slSize - bu_slReadOffset) + emb_atmTickMarkers[iTickIndex].tm_slTickOffset;
- }
- bu_slReadOffset = emb_atmTickMarkers[iTickIndex].tm_slTickOffset;
-
- return EMB_SUCCESS_OK;
- };
- // expand buffer to be given number of bytes in size
- void CEMsgBuffer::Expand(SLONG slNewSize)
- {
- ASSERT(slNewSize>0);
- ASSERT(bu_slSize>=0);
- // if not already allocated
- if (bu_slSize==0) {
- // allocate a new empty buffer
- ASSERT(bu_pubBuffer==NULL);
- bu_pubBuffer = (UBYTE*)AllocMemory(slNewSize);
- bu_slWriteOffset = 0;
- bu_slReadOffset = 0;
- bu_slFree = slNewSize;
- bu_slSize = slNewSize;
- // if already allocated
- } else {
- ASSERT(slNewSize>bu_slSize);
- SLONG slSizeDiff = slNewSize-bu_slSize;
- ASSERT(bu_pubBuffer!=NULL);
- // grow buffer
- GrowMemory((void**)&bu_pubBuffer, slNewSize);
- cout << "EXPAND!\n";
- // if buffer is currently wrapping
- if (bu_slReadOffset>bu_slWriteOffset||bu_slFree==0) {
- cout << "WRAP!\n";
- // move part at the end of buffer to the end
- memmove(bu_pubBuffer+bu_slReadOffset+slSizeDiff, bu_pubBuffer+bu_slReadOffset,bu_slSize-bu_slReadOffset);
- for (int i=0;i<MAX_TICKS_KEPT;i++) {
- if (emb_atmTickMarkers[i].tm_slTickOffset >= bu_slReadOffset) {
- emb_atmTickMarkers[i].tm_slTickOffset += slSizeDiff;
- }
- }
- bu_slReadOffset+=slSizeDiff;
- }
- bu_slFree += slNewSize-bu_slSize;
- bu_slSize = slNewSize;
- ASSERT(bu_slReadOffset>=0 && bu_slReadOffset<bu_slSize);
- ASSERT(bu_slFree>=0 && bu_slFree<=bu_slSize);
- }
- }
- // write bytes to buffer
- void CEMsgBuffer::WriteBytes(const void *pv, SLONG slSize)
- {
- BOOL bWraping = FALSE;
- SLONG slOldReadOffset = bu_slReadOffset;
- // if buffer is currently wrapping
- ASSERT(slSize>=0 && pv!=NULL);
- // if there is nothing to write
- if (slSize==0) {
- // do nothing
- return;
- }
- // check for errors
- if (slSize<0) {
- cout << "WARNING: WriteBytes(): slSize<0\n!";
- return;
- }
- // if there is not enough free space
- if (bu_slFree<slSize) {
- SLONG slSizeDiff;
- SLONG slNewSize;
- slNewSize = bu_slSize + ((slSize-bu_slFree + bu_slAllocationStep - 1) / bu_slAllocationStep) * bu_slAllocationStep;
- slSizeDiff = slNewSize - bu_slSize;
- // if buffer is currently wrapping
- // if (bu_slReadOffset>bu_slWriteOffset||bu_slFree==0) {
- // bWraping = TRUE;
- // }
- // expand the buffer
- Expand(slNewSize);
- ASSERT(bu_slFree>=slSize);
- }
- UBYTE *pub = (UBYTE*)pv;
- // write part of block at the end of buffer
- SLONG slSizeEnd = __min(bu_slSize-bu_slWriteOffset, slSize);
- memcpy(bu_pubBuffer+bu_slWriteOffset, pub, slSizeEnd);
- pub+=slSizeEnd;
- memcpy(bu_pubBuffer, pub, slSize-slSizeEnd);
- // move write pointer
- bu_slWriteOffset+=slSize;
- bu_slWriteOffset%=bu_slSize;
- bu_slFree-=slSize;
- ASSERT(bu_slWriteOffset>=0 && bu_slWriteOffset<bu_slSize);
- ASSERT(bu_slFree>=0 && bu_slFree<=bu_slSize);
- };
- SLONG CEMsgBuffer::PeekBytes(const void *pv, SLONG slSize)
- {
- ASSERT(slSize>0 && pv!=NULL);
- UBYTE *pub = (UBYTE*)pv;
- // clamp size to amount of bytes actually in the buffer
- SLONG slUsed = bu_slSize-bu_slFree;
- if (slUsed<slSize) {
- slSize = slUsed;
- }
- // if there is nothing to read
- if (slSize==0) {
- // do nothing
- return 0;
- }
- // read part of block after read pointer to the end of buffer
- SLONG slSizeEnd = __min(bu_slSize-bu_slReadOffset, slSize);
- memcpy(pub, bu_pubBuffer+bu_slReadOffset, slSizeEnd);
- pub+=slSizeEnd;
- // if that is not all
- if (slSizeEnd<slSize) {
- // read rest from start of buffer
- memcpy(pub, bu_pubBuffer, slSize-slSizeEnd);
- }
- ASSERT(bu_slReadOffset>=0 && bu_slReadOffset<bu_slSize);
- ASSERT(bu_slFree>=0 && bu_slFree<=bu_slSize);
- return slSize;
- }
- SLONG CEMsgBuffer::PeekBytesAtOffset(const void *pv, SLONG slSize,SLONG &slTickOffset)
- {
- ASSERT(slSize>0 && pv!=NULL);
- UBYTE *pub = (UBYTE*)pv;
- // clamp size to amount of bytes actually in the buffer
- SLONG slUsed = bu_slSize-bu_slFree;
- if (slUsed<slSize) {
- slSize = slUsed;
- }
- // if there is nothing to read
- if (slSize==0) {
- // do nothing
- return 0;
- }
- // read part of block after read pointer to the end of buffer
- SLONG slSizeEnd = __min(bu_slSize-slTickOffset, slSize);
- memcpy(pub, bu_pubBuffer+slTickOffset, slSizeEnd);
- pub+=slSizeEnd;
- slTickOffset += slSizeEnd;
- // if that is not all
- if (slSizeEnd<slSize) {
- // read rest from start of buffer
- memcpy(pub, bu_pubBuffer, slSize-slSizeEnd);
- slTickOffset = slSize - slSizeEnd;
- }
- slTickOffset %= bu_slSize;
- ASSERT(slTickOffset>=0 && slTickOffset<bu_slSize);
- ASSERT(bu_slFree>=0 && bu_slFree<=bu_slSize);
- return slSize;
- }
|