Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

824 lines
21 KiB
C++

ReplicatorID ReplicatorID::Null;
char AssetsDirectory1[MAX_PATH];
HWND hWindow;
MemoryStream::MemoryStream(
void *stream_start,
DWORD stream_size,
DWORD initial_offset
)
{
Check_Pointer(this);
streamStart = static_cast<BYTE*>(stream_start);
highWaterByte = streamStart;
streamSize = stream_size;
Verify(initial_offset <= stream_size);
currentPosition = streamStart + initial_offset;
currentBit = Empty_Bit_Buffer;
}
MemoryStream::~MemoryStream()
{
}
MemoryStream&
MemoryStream::ReadBytes(
void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Check_Pointer(ptr);
Verify(number_of_bytes > 0);
#if defined(_ARMOR)
DWORD remaining = GetBytesRemaining();
Verify(remaining >= number_of_bytes);
#endif
memcpy(ptr, GetPointer(), number_of_bytes);
AdvancePointer(number_of_bytes);
return *this;
}
MemoryStream&
MemoryStream::WriteBytes(
const void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Check_Pointer(ptr);
Verify(number_of_bytes > 0);
memcpy(GetPointer(), ptr, number_of_bytes);
AdvancePointer(number_of_bytes);
return *this;
}
void
MemoryStream::WriteByteAlign()
{
if (currentBit == 0 || currentBit == Empty_Bit_Buffer)
{
return;
}
Check_Object(this);
//SPEW(("jerryeds", "WRITE : %x", workingBitBuffer));
WriteBytes(&workingBitBuffer, 1);
workingBitBuffer = 0x00;
currentBit = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MemoryStream::ReadByteAlign()
{
if (currentBit == Empty_Bit_Buffer)
{
return;
}
Check_Object(this);
// we just read this byte but didn't read any bits..
// so unread it.
if (currentBit == 0)
{
RewindPointer(1);
}
// this will trigger the next read...
currentBit = Empty_Bit_Buffer;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::ReadBit(bool &bit_value)
{
Check_Object(this);
int result = 0;
if (currentBit == Empty_Bit_Buffer)
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
currentBit = 0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
result = (0x01 & (workingBitBuffer >> currentBit));
bit_value = (result)?true:false;
currentBit++;
if (currentBit > 7)
{
if (GetBytesRemaining())
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
currentBit = 0;
}
else
{
currentBit = Empty_Bit_Buffer;
}
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::WriteBit(const bool &bit_value)
{
Check_Object(this);
int int_bit_value = (bit_value)?1:0;
if (currentBit == Empty_Bit_Buffer)
{
currentBit = 0;
workingBitBuffer = 0x0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
workingBitBuffer |= (int_bit_value << currentBit);
currentBit++;
if (currentBit > 7)
{
WriteBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "WRITE : %x", workingBitBuffer));
workingBitBuffer = 0x00;
currentBit = 0;
}
return *this;
}
Adept::AdeptNetMissionParameters::AdeptNetMissionParameters()
{
ResetParameters();
}
void Adept::AdeptNetMissionParameters::ResetParameters(void)
{
m_runDedicated = 0;
m_closedGame = 0;
m_playerLimit = 16;
m_visibility = 0;
}
void Adept::AdeptNetMissionParameters::SaveParameters(DynamicMemoryStream *stream)
{
stream->WriteBits(&m_runDedicated, 1);
stream->WriteBits(&m_closedGame, 1);
stream->WriteBits(&m_playerLimit, 8); // 256
stream->WriteBits(&m_visibility,3);//5
}
void Adept::AdeptNetMissionParameters::LoadParameters(MemoryStream *stream)
{
stream->ReadBits(&m_runDedicated, 1);
stream->ReadBits(&m_closedGame, 1);
stream->ReadBits(&m_playerLimit, 8);// 256
stream->ReadBits(&m_visibility,3);//5
}
NetMissionParameters::TeamParameters::TeamParameters()
{
ResetParameters(0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::TeamParameters::ResetParameters(int index)
{
m_maxPlayersOnTeam = 16;
m_minimumTonnage = 0;
m_maximumTonnage = 100;
m_maximumTotalTonnage = 1600;
m_currentTotalTonnage = 0;
m_skin = (int)'0';
m_skin += index;
m_alignment = index;
m_allowedMech[0] = 0xffffffff;
m_allowedBeam[0] = 0xfffffffd;
m_allowedMissile[0] = 0xff3bffff;
m_allowedProjectile[0] = 0xffffdfff;
m_allowedSubsystem[0] = 0xffffffff;
m_allowedMech[1] = 0xffffffff;
m_allowedBeam[1] = 0xffffffff;
m_allowedMissile[1] = 0xffffffff;
m_allowedProjectile[1] = 0xffffffff;
m_allowedSubsystem[1] = 0xffffffff;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::TeamParameters::SaveParameters(DynamicMemoryStream *stream)
{
stream->WriteBits(&m_maxPlayersOnTeam,7);
stream->WriteBits(&m_minimumTonnage,8);
stream->WriteBits(&m_maximumTonnage,8);
stream->WriteBits(&m_maximumTotalTonnage,16);
stream->WriteBits(&m_currentTotalTonnage,8*sizeof(Scalar));
stream->WriteBits(&m_skin,8);
stream->WriteBits(&m_alignment,4);
stream->WriteBits(&m_allowedMech[0],32);
stream->WriteBits(&m_allowedBeam[0],32);
stream->WriteBits(&m_allowedMissile[0],32);
stream->WriteBits(&m_allowedProjectile[0],32);
stream->WriteBits(&m_allowedSubsystem[0],32);
stream->WriteBits(&m_allowedMech[1],32);
stream->WriteBits(&m_allowedBeam[1],32);
stream->WriteBits(&m_allowedMissile[1],32);
stream->WriteBits(&m_allowedProjectile[1],32);
stream->WriteBits(&m_allowedSubsystem[1],32);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::TeamParameters::LoadParameters(MemoryStream *stream)
{
stream->ReadBits(&m_maxPlayersOnTeam,7);
stream->ReadBits(&m_minimumTonnage,8);
stream->ReadBits(&m_maximumTonnage,8);
stream->ReadBits(&m_maximumTotalTonnage,16);
stream->ReadBits(&m_currentTotalTonnage,8*sizeof(Scalar));
stream->ReadBits(&m_skin,8);
stream->ReadBits(&m_alignment,4);
stream->ReadBits(&m_allowedMech[0],32);
stream->ReadBits(&m_allowedBeam[0],32);
stream->ReadBits(&m_allowedMissile[0],32);
stream->ReadBits(&m_allowedProjectile[0],32);
stream->ReadBits(&m_allowedSubsystem[0],32);
stream->ReadBits(&m_allowedMech[1],32);
stream->ReadBits(&m_allowedBeam[1],32);
stream->ReadBits(&m_allowedMissile[1],32);
stream->ReadBits(&m_allowedProjectile[1],32);
stream->ReadBits(&m_allowedSubsystem[1],32);
}
NetMissionParameters::MWNetMissionParameters::MWNetMissionParameters()
{
m_mapID = 0;
m_mapName[0] = '\0';
m_scenarioName[0] = '\0';
m_scenarioPath[0] = '\0';
m_serverName[0] = '\0';
m_serverIP[0] = '\0';
m_scriptName[0] = '\0';
m_scenarioText[0] = '\0';
m_mapClientCRC = 0;
ResetParameters();
}
void NetMissionParameters::MWNetMissionParameters::ResetParameters(void)
{
AdeptNetMissionParameters::ResetParameters();
m_joinInProgress = 1;
m_joinInProgressCutOff = false;
m_joinInProgressCutOffTime = 0;
m_heatOn = true;
m_killLimit = false;
m_killLimitNumber = 0;
m_respawnLimit = false;
m_respawnLimitNumber = 0;
m_forceRespawn = true;
m_splashOn = false;
m_weaponjamOn = false;
m_ammobayfireOn = false;
// MSL 5.05 Advance Mode
m_advancemodeOn = false;
// MSL 5.06 Armor Mode
m_armormodeOn = false;
m_splashPercentage = 100;
m_unlimitedAmmo = false;
m_friendlyFirePercentage = 100;
m_allowZoom = true;
m_allow3rdPerson = true;
m_allowAutoAim = true;
m_allowDeadToChat = false;
m_invulnerableDrop = false;
m_isNight = false;
m_weather = false;
m_radarMode = 0;
m_reportStats = true;
m_serverConnection = MWApplication::LAN;
m_serverBandwidth = MWApplication::c_10_Mbps;
m_onlyStockMech = false;
m_minimumTonnage = 0;
m_maximumTonnage = 100;
m_allowedMech[0] = 0xffffffff;
m_allowedBeam[0] = 0xfffffffd;
m_allowedMissile[0] = 0xff3bffff;
m_allowedProjectile[0] = 0xffffdfff;
m_allowedSubsystem[0] = 0xffffffff;
m_allowedMech[1] = 0xffffffff;
m_allowedBeam[1] = 0xffffffff;
m_allowedMissile[1] = 0xffffffff;
m_allowedProjectile[1] = 0xffffffff;
m_allowedSubsystem[1] = 0xffffffff;
m_gameLength = 10;
m_serverRecycle = 0;
m_recycleDelay = 60;
m_playMissionReview = 0;
m_ruleType = CustomAttrition; //StockAttrition;
m_deadMechCantSee = false;
m_deadMechCantSeeOtherTeam = false;
m_teamAllowed = false;
m_teamCount = 8;
m_allowdecaltransfer = false;
m_useMapCycle = false;
m_pureMapCycle = false;
for (int i = 0; i < 8; ++i)
{
m_teamParams[i].ResetParameters(i);
}
m_maxPlayers = 0;
m_maxBots = 0;
strcpy(m_serverCPU, "cpu");
//SPEW(("jerryeds", "RESET TIME : %d", m_gameLength));
}
void NetMissionParameters::MWNetMissionParameters::SaveParameters(DynamicMemoryStream *stream)
{
AdeptNetMissionParameters::SaveParameters(stream);
stream->WriteBits(&m_joinInProgress, 1);
stream->WriteBits(&m_joinInProgressCutOff, 1);
stream->WriteBits(&m_joinInProgressCutOffTime, 8); // minutes 256
stream->WriteBits(&m_heatOn, 1);
stream->WriteBits(&m_killLimit, 1);
stream->WriteBits(&m_killLimitNumber, 8); //256
stream->WriteBits(&m_respawnLimit, 1);
stream->WriteBits(&m_respawnLimitNumber, 8); //256
stream->WriteBits(&m_forceRespawn, 1);
stream->WriteBits(&m_splashOn, 1);
stream->WriteBits(&m_weaponjamOn, 1);
stream->WriteBits(&m_ammobayfireOn, 1);
// MSL 5.05 Advance Mode
stream->WriteBits(&m_advancemodeOn, 1);
// MSL 5.06 Armor Mode
stream->WriteBits(&m_armormodeOn, 1);
stream->WriteBits(&m_splashPercentage, 8); //256
stream->WriteBits(&m_unlimitedAmmo, 1);
stream->WriteBits(&m_friendlyFirePercentage, 8); //256
stream->WriteBits(&m_allowZoom, 1);
stream->WriteBits(&m_allow3rdPerson, 1);
stream->WriteBits(&m_allowAutoAim, 1);
stream->WriteBits(&m_allowDeadToChat, 1);
stream->WriteBits(&m_invulnerableDrop, 1);
stream->WriteBits(&m_onlyStockMech,1);
stream->WriteBits(&m_minimumTonnage,8);
stream->WriteBits(&m_maximumTonnage,8);
stream->WriteBits(&m_allowedMech[0],32);
stream->WriteBits(&m_allowedBeam[0],32);
stream->WriteBits(&m_allowedMissile[0],32);
stream->WriteBits(&m_allowedProjectile[0],32);
stream->WriteBits(&m_allowedSubsystem[0],32);
stream->WriteBits(&m_allowedMech[1],32);
stream->WriteBits(&m_allowedBeam[1],32);
stream->WriteBits(&m_allowedMissile[1],32);
stream->WriteBits(&m_allowedProjectile[1],32);
stream->WriteBits(&m_allowedSubsystem[1],32);
stream->WriteBits(&m_gameLength, 8); // 256 minutes
stream->WriteBits(&m_serverRecycle, 1);
stream->WriteBits(&m_recycleDelay, 16); //65535 seconds
stream->WriteBits(&m_playMissionReview, 1);
stream->WriteBits(&m_isNight, 1);
stream->WriteBits(&m_weather,1);
stream->WriteBits(&m_radarMode,2);
stream->WriteBits(&m_reportStats,1);
stream->WriteBits(&m_serverConnection,5);//32
stream->WriteBits(&m_serverBandwidth,5);//32
stream->WriteBits(&m_ruleType, 5);//32
stream->WriteBits(&m_deadMechCantSee,1);
stream->WriteBits(&m_deadMechCantSeeOtherTeam,1);
stream->WriteBits(&m_teamAllowed,1);
stream->WriteBits(&m_teamCount, 4);
stream->WriteBits(&m_allowdecaltransfer,1);
stream->WriteBits(&m_useMapCycle,1);
stream->WriteBits(&m_pureMapCycle,1);
stream->WriteBits(&m_maxPlayers, 5); // 16 players maximum
stream->WriteBits(&m_maxBots, 5); // 16 players maximum
stream->WriteBits(&m_mapID, 16); // 65535 maps available
stream->WriteBits(&m_mapClientCRC, 64);
for (int i = 0; i < 8; ++i)
{
m_teamParams[i].SaveParameters(stream);
}
stream->WriteByteAlign();
int map_length = strlen(&m_mapName[0]);
stream->WriteBytes(&map_length, 1);
if (map_length > 0)
stream->WriteBytes(&m_mapName[0], map_length);
int scn_length = strlen(&m_scenarioName[0]);
stream->WriteBytes(&scn_length, 1);
if (scn_length > 0)
stream->WriteBytes(&m_scenarioName[0], scn_length);
int scp_length = strlen(&m_scenarioPath[0]);
stream->WriteBytes(&scp_length, 1);
if (scp_length > 0)
stream->WriteBytes(&m_scenarioPath[0], scp_length);
int srn_length = strlen(&m_serverName[0]);
stream->WriteBytes(&srn_length, 1);
if (srn_length > 0)
stream->WriteBytes(&m_serverName[0], srn_length);
int sip_length = strlen(&m_serverIP[0]);
stream->WriteBytes(&sip_length, 1);
if (sip_length > 0)
stream->WriteBytes(&m_serverIP[0], sip_length);
int cpu_length = strlen(&m_serverCPU[0]);
stream->WriteBytes(&cpu_length, 1);
if (cpu_length > 0)
stream->WriteBytes(&m_serverCPU[0], cpu_length);
int scriptname_length = strlen(&m_scriptName[0]);
stream->WriteBytes(&scriptname_length,1);
if (scriptname_length > 0)
stream->WriteBytes(&m_scriptName[0],scriptname_length);
int scenariotext_length = strlen(&m_scenarioText[0]); //_mbstrlen(&m_scenarioText[0]);
++scenariotext_length;
stream->WriteBytes(&scenariotext_length,4);
if (scenariotext_length > 0)
stream->WriteBytes(&m_scenarioText[0],scenariotext_length);
}
void NetMissionParameters::MWNetMissionParameters::LoadParameters(MemoryStream *stream)
{
AdeptNetMissionParameters::LoadParameters(stream);
stream->ReadBits(&m_joinInProgress, 1);
stream->ReadBits(&m_joinInProgressCutOff, 1);
stream->ReadBits(&m_joinInProgressCutOffTime, 8); // minutes 256
stream->ReadBits(&m_heatOn, 1);
stream->ReadBits(&m_killLimit, 1);
stream->ReadBits(&m_killLimitNumber, 8); //256
stream->ReadBits(&m_respawnLimit, 1);
stream->ReadBits(&m_respawnLimitNumber, 8); //256
stream->ReadBits(&m_forceRespawn, 1);
stream->ReadBits(&m_splashOn, 1);
stream->ReadBits(&m_weaponjamOn, 1);
stream->ReadBits(&m_ammobayfireOn, 1);
// MSL 5.05 Advance Mode
stream->ReadBits(&m_advancemodeOn, 1);
// MSL 5.06 Armor Mode
stream->ReadBits(&m_armormodeOn, 1);
stream->ReadBits(&m_splashPercentage, 8); //256
stream->ReadBits(&m_unlimitedAmmo, 1);
stream->ReadBits(&m_friendlyFirePercentage, 8); //256
stream->ReadBits(&m_allowZoom, 1);
stream->ReadBits(&m_allow3rdPerson, 1);
stream->ReadBits(&m_allowAutoAim, 1);
stream->ReadBits(&m_allowDeadToChat, 1);
stream->ReadBits(&m_invulnerableDrop, 1);
stream->ReadBits(&m_onlyStockMech,1);
stream->ReadBits(&m_minimumTonnage,8);
stream->ReadBits(&m_maximumTonnage,8);
stream->ReadBits(&m_allowedMech[0],32);
stream->ReadBits(&m_allowedBeam[0],32);
stream->ReadBits(&m_allowedMissile[0],32);
stream->ReadBits(&m_allowedProjectile[0],32);
stream->ReadBits(&m_allowedSubsystem[0],32);
stream->ReadBits(&m_allowedMech[1],32);
stream->ReadBits(&m_allowedBeam[1],32);
stream->ReadBits(&m_allowedMissile[1],32);
stream->ReadBits(&m_allowedProjectile[1],32);
stream->ReadBits(&m_allowedSubsystem[1],32);
stream->ReadBits(&m_gameLength, 8); // 256 minutes
stream->ReadBits(&m_serverRecycle, 1);
stream->ReadBits(&m_recycleDelay, 16); //65535 seconds
stream->ReadBits(&m_playMissionReview, 1);
stream->ReadBits(&m_isNight, 1);
stream->ReadBits(&m_weather,1);
stream->ReadBits(&m_radarMode,2);
stream->ReadBits(&m_reportStats,1);
stream->ReadBits(&m_serverConnection,5);//32
stream->ReadBits(&m_serverBandwidth,5);//32
stream->ReadBits(&m_ruleType, 5);//32
stream->ReadBits(&m_deadMechCantSee,1);
stream->ReadBits(&m_deadMechCantSeeOtherTeam,1);
stream->ReadBits(&m_teamAllowed,1);
stream->ReadBits(&m_teamCount, 4);
stream->ReadBits(&m_allowdecaltransfer,1);
stream->ReadBits(&m_useMapCycle,1);
stream->ReadBits(&m_pureMapCycle,1);
stream->ReadBits(&m_maxPlayers, 5); // 16 players max
stream->ReadBits(&m_maxBots, 5); // 16 players max
stream->ReadBits(&m_mapID, 16); // 65535 maps available
stream->ReadBits(&m_mapClientCRC, 64);
for (int i = 0; i < 8; ++i)
{
m_teamParams[i].LoadParameters(stream);
}
stream->ReadByteAlign();
int map_length = 0;
stream->ReadBytes(&map_length, 1);
if (map_length > 0)
stream->ReadBytes(&m_mapName[0], map_length);
m_mapName[map_length] = '\0';
int scn_length = 0;
stream->ReadBytes(&scn_length, 1);
if (scn_length > 0)
stream->ReadBytes(&m_scenarioName[0], scn_length);
m_scenarioName[scn_length] = '\0';
int scp_length = 0;
stream->ReadBytes(&scp_length, 1);
if (scp_length > 0)
stream->ReadBytes(&m_scenarioPath[0], scp_length);
m_scenarioPath[scp_length] = '\0';
int srn_length = 0;
stream->ReadBytes(&srn_length, 1);
if (srn_length > 0)
stream->ReadBytes(&m_serverName[0], srn_length);
m_serverName[srn_length] = '\0';
int sip_length = 0;
stream->ReadBytes(&sip_length, 1);
if (sip_length > 0)
stream->ReadBytes(&m_serverIP[0], sip_length);
m_serverIP[sip_length] = '\0';
int cpu_length = 0;
stream->ReadBytes(&cpu_length, 1);
if (cpu_length > 0)
stream->ReadBytes(&m_serverCPU[0], cpu_length);
m_serverCPU[cpu_length] = '\0';
int scriptname_length = 0;
stream->ReadBytes(&scriptname_length,1);
if (scriptname_length > 0)
stream->ReadBytes(&m_scriptName[0],scriptname_length);
int scenariotext_length = 0;
stream->ReadBytes(&scenariotext_length,4);
if (scenariotext_length > 0)
stream->ReadBytes(&m_scenarioText[0],scenariotext_length);
}
MemoryStream&
MemoryStream::WriteBits(
const void *ptr,
DWORD number_of_bits
)
{
Check_Object(this);
Check_Pointer(ptr);
if (currentBit == Empty_Bit_Buffer)
{
workingBitBuffer = 0x00;
currentBit = 0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
int total_number_of_bytes = (int)(number_of_bits/8.0f);
int total_remainder_bits = number_of_bits - (total_number_of_bytes*8);
if ( total_remainder_bits != 0)
{
total_number_of_bytes += 1;
}
const BYTE *source_array = (const BYTE *)ptr;
int source_byte_counter = 0;
int bits_remaining = number_of_bits;
while (bits_remaining > 0)
{
// if we are writing the full byte
const BYTE *source = &source_array[source_byte_counter];
int total_bits_to_be_written = 8;
Max_Clamp(total_bits_to_be_written, bits_remaining);
int bits_in_first_destination_byte = total_bits_to_be_written;
Max_Clamp(bits_in_first_destination_byte, 8-currentBit);
// make sure our destination is empty
workingBitBuffer &= (0xff >> (8-currentBit));
// move the source data to the correct bit location
BYTE new_source = (BYTE)(*source << currentBit);
// put the adjusted source into the destination
workingBitBuffer |= new_source;
currentBit += bits_in_first_destination_byte;
if (currentBit == 8)
{
int bits_in_second_destination_byte = total_bits_to_be_written - bits_in_first_destination_byte;
//SPEW(("jerryeds", "WRITE : %x", workingBitBuffer));
WriteBytes(&workingBitBuffer, 1);
++source_byte_counter;
workingBitBuffer = 0x00;
currentBit = 0;
if (bits_in_second_destination_byte)
{
// remove bits we have already used
workingBitBuffer = (BYTE)(*source >> bits_in_first_destination_byte);
currentBit = bits_in_second_destination_byte;
}
}
bits_remaining -= total_bits_to_be_written;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
return *this;
}
MemoryStream&
MemoryStream::ReadUnsafeBits(
void *ptr,
DWORD number_of_bits
)
{
Check_Object(this);
Check_Pointer(ptr);
if (currentBit == Empty_Bit_Buffer)
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
currentBit = 0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
int total_number_of_bytes = (int)(number_of_bits/8.0f);
int total_remainder_bits = number_of_bits - (total_number_of_bytes*8);
if ( total_remainder_bits != 0)
{
total_number_of_bytes += 1;
}
BYTE *dest_array = (BYTE *)ptr;
int dest_byte_counter = 0;
int bits_remaining = number_of_bits;
while (bits_remaining > 0)
{
BYTE *dest = &dest_array[dest_byte_counter];
// empy out destination
*dest = 0x00;
int total_bits_to_be_read = 8;
Max_Clamp(total_bits_to_be_read, bits_remaining);
int bits_in_first_source_byte = total_bits_to_be_read;
Max_Clamp(bits_in_first_source_byte, 8-currentBit);
// make a mask of bits to be used
int bit_mask = 0xff >> (8-bits_in_first_source_byte);
// shift past the used bits in the buffer
*dest = (BYTE)(workingBitBuffer >> currentBit);
// remove any bits from the next set that tagged along
*dest &= bit_mask;
currentBit += bits_in_first_source_byte;
if (currentBit == 8)
{
int bits_in_second_source_byte = total_bits_to_be_read - bits_in_first_source_byte;
if (GetBytesRemaining())
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
}
++dest_byte_counter;
currentBit = 0;
if (bits_in_second_source_byte)
{
// make a bitmask of the used bits
bit_mask = 0xff >> (8-bits_in_second_source_byte);
// mask the used bits out of the buffer and then shift the buffer to the correct
// bit location. Then combine it with the destination
*dest |= ((workingBitBuffer & bit_mask) << bits_in_first_source_byte);
currentBit = bits_in_second_source_byte;
}
}
bits_remaining -= total_bits_to_be_read;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
return *this;
}