Game Development Community

Fatal Error: "Out of range write" in bitStream.cc

by Nabarro · in Torque Game Engine · 12/19/2007 (8:58 pm) · 2 replies

Hello, everybody,

I came accross one fatal error when doing BitStream writing operation. I taced back and found the cause:

1> In bitStream.cc, Line 16: static U8 gPacketBuffer[MaxPacketDataSize];
So, the maximum stream size is MaxPacketDataSize(1500) bytes, that's 12000 bits.

2> But for my player data, because it has more than 100+ animations, it exceeds the maximum value. So, it will assert fatal error when doing packUpdate().

Do you have such problem, and how to solve it?

Thanks,

#1
12/20/2007 (7:23 am)
I know that Chris Calef's ragdoll pack deals with this issue, though I do not think it takes it as far as you need.

Here is some of the information on the TGE changes. I do not know about the specifics as I did what the pack said...and it worked. Since you have so many animations, you will probably need to perform some more in-depth problem solving.

(from the Ragdoll pack documentation, edited by me):
Quote:We need to get under the hood! In order to load more than forty or so sequences at a time, we have to change the way Torque loads dsq files.

This will be handled in:
engine/ts/TSShapeConstruct.h
engine/ts/TSShapeConstruct.cc


The problem is that the engine loads all these names with their complete path names and stores them as a big string array, which it has to send as a network packet (even in a single player game). That's fine for the thirty sequences provided, but it means that if you try to include something like, say 72 additional sequences, all those characters are quickly going to flood the buffer beyond the 1500 (or technically 2000) byte maximum size.

So, I had to write new versions of the TSShapeConstruct functions that deal with sequence names: packData and unpackData. In my versions I stripped off the path and other easily reproduced information, and got it down to storing only the sequence name, which in my application I then reduced to a naming convention of three characters each, as in "100.dsq", "101.dsq", etc.

(For those who like to know the limits, these changes have been tested successfully up to about 456 sequences.)

And then...

Quote:So, the first thing we need to do is open engine/ts/tsShapeConstruct.h. Go to line 27 or so, and find:
"NumSequenceBits = 7,"

3. Change that to seven to a nine:
"NumSequenceBits = 9," That changes one of the caps, from 128 to 512.

Next, go to tsShapeConstruct.cc.

Right at the top, just after the #include statements and before the "IMPLEMENT_CO_DATABLOCK" statement, around line 11,

4. Insert the following line:
#define TS_IS_RELATIVE_SEQUENCES 1

This is a toggle for what we're about to do to packData and unpackData.

And finally...

void TSShapeConstructor::packData(BitStream* stream)
{

   Parent::packData(stream);
   stream->writeString(mShape);

   S32 count = 0;
   for (S32 b=0; b<MaxSequences; b++)
      if (mSequence[b])
         count++;
   stream->writeInt(count,NumSequenceBits);

   
   for (S32 i=0; i<MaxSequences; i++)
     if (mSequence[i]) {
       if (TS_IS_RELATIVE_SEQUENCES) {
	 const char *subtext = dStrrchr(mSequence[i],'/');
	 stream->writeString(subtext);
       } else {
	 stream->writeString(mSequence[i]);
       }
     }
}

void TSShapeConstructor::unpackData(BitStream* stream)
{
   char shapePath[90],pathedSeq[90];
   Parent::unpackData(stream);
   mShape = stream->readSTString();
   
   if (TS_IS_RELATIVE_SEQUENCES) {
     dsize_t strLen = (int)dStrlen(mShape);
     const char *subtext = dStrrchr(mShape,'/');

     dsize_t endLen = (int)dStrlen(subtext);
     dsize_t pathLen = (strLen - endLen) ;
	
     dStrncpy(shapePath,mShape,pathLen);
     shapePath[pathLen] = '[[60c1da72daaa7]]';
   }

   S32 i = 0, count = stream->readInt(NumSequenceBits);
   for (; i<count; i++) {
     mSequence[i] = stream->readSTString();
     if (TS_IS_RELATIVE_SEQUENCES) {
       dSprintf(pathedSeq,90,"%s%s",shapePath,mSequence[i]);
       mSequence[i] = StringTable->insert(pathedSeq);
     }
   }
   while (i<MaxSequences)
      mSequence[i++] = NULL;
}
#2
12/21/2007 (5:00 am)
Thanks a lot, David.

It seems helpful, and I will try it ASAP.

Thanks,