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.
280 lines
6.1 KiB
C++
280 lines
6.1 KiB
C++
// File: MemoryDiffKiller.hpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 10/04/00 JSE die haxorz die
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 2000, Microsoft Corp //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "MW4Headers.hpp"
|
|
|
|
#include "MemoryDiffKiller.hpp"
|
|
|
|
#include "MWApplication.hpp"
|
|
#include "MechLab.hpp"
|
|
#include "Mech.hpp"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
|
|
MemoryDiffKiller::MemoryDiffKiller():
|
|
Plug(DefaultData)
|
|
{
|
|
|
|
m_sourceCount = 0;
|
|
|
|
for (int i = 0; i < Maximum_Sources; ++i)
|
|
{
|
|
m_sourceSize[i] = 0;
|
|
}
|
|
|
|
|
|
for (i = 0; i < Maximum_Copies; ++i)
|
|
{
|
|
m_copyMemory[i] = NULL;
|
|
m_copySize[i] = 0;
|
|
m_copySourceIndex[i] = 0;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
|
|
MemoryDiffKiller::~MemoryDiffKiller()
|
|
{
|
|
for (int i = 0; i < Maximum_Copies; ++i)
|
|
{
|
|
if (m_copyMemory[i] != NULL)
|
|
{
|
|
gos_Free(m_copyMemory[i]);
|
|
m_copyMemory[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
|
|
|
|
void MemoryDiffKiller::Init()
|
|
{
|
|
|
|
#ifdef LAB_ONLY
|
|
if (!MWApplication::MoveItAndShakeIt)
|
|
return;
|
|
#endif
|
|
|
|
Uninit();
|
|
|
|
if (MWApplication::GetInstance()!=NULL)
|
|
{
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
//m_sourceData[m_sourceCount].Add(app);
|
|
//m_sourceSize[m_sourceCount] = sizeof(*app);
|
|
//++m_sourceCount;
|
|
|
|
if (app->m_serverMissionParameters)
|
|
{
|
|
m_sourceData[m_sourceCount].Add(app->m_serverMissionParameters);
|
|
m_sourceSize[m_sourceCount] = sizeof(*app->m_serverMissionParameters);
|
|
++m_sourceCount;
|
|
}
|
|
|
|
if (app->m_localMissionParameters)
|
|
{
|
|
m_sourceData[m_sourceCount].Add(app->m_localMissionParameters);
|
|
m_sourceSize[m_sourceCount] = sizeof(*app->m_localMissionParameters);
|
|
++m_sourceCount;
|
|
}
|
|
}
|
|
|
|
if (MechLab::Instance!=NULL)
|
|
{
|
|
if (MechLab::Instance->m_workingMech != NULL)
|
|
{
|
|
|
|
// we want the mech to have a higher weight...
|
|
|
|
for (int i = 0; i < 30; ++i)
|
|
{
|
|
m_sourceData[m_sourceCount].Add(MechLab::Instance->m_workingMech);
|
|
m_sourceSize[m_sourceCount] = sizeof(*MechLab::Instance->m_workingMech);
|
|
++m_sourceCount;
|
|
}
|
|
|
|
|
|
ChainIteratorOf<Subsystem *> sub_iterator(&MechLab::Instance->m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = sub_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
m_sourceData[m_sourceCount].Add(subsystem);
|
|
m_sourceSize[m_sourceCount] = sizeof(*subsystem);
|
|
++m_sourceCount;
|
|
|
|
if (m_sourceCount == Maximum_Sources)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void MemoryDiffKiller::Uninit()
|
|
{
|
|
#ifdef LAB_ONLY
|
|
if (!MWApplication::MoveItAndShakeIt)
|
|
return;
|
|
#endif
|
|
|
|
m_sourceCount = 0;
|
|
|
|
for (int i = 0; i < Maximum_Sources; ++i)
|
|
{
|
|
if (m_sourceData[i].GetCurrent())
|
|
{
|
|
m_sourceData[i].Remove();
|
|
}
|
|
|
|
m_sourceSize[i] = 0;
|
|
}
|
|
|
|
for (i = 0; i < Maximum_Copies; ++i)
|
|
{
|
|
if (m_copyMemory[i] != NULL)
|
|
{
|
|
gos_Free(m_copyMemory[i]);
|
|
m_copyMemory[i] = NULL;
|
|
m_copySize[i] = 0;
|
|
m_copySourceIndex[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
//define CHECK_ALLOC_SIZE
|
|
|
|
void MemoryDiffKiller::MoveItAndShakeIt()
|
|
{
|
|
#ifdef LAB_ONLY
|
|
if (!MWApplication::MoveItAndShakeIt)
|
|
return;
|
|
#endif
|
|
|
|
for (int i = 0; i < Maximum_Copies; ++i)
|
|
{
|
|
|
|
// if our source was deleted...
|
|
if ( m_sourceData[m_copySourceIndex[i]].GetCurrent() == NULL)
|
|
{
|
|
gos_Free(m_copyMemory[i]);
|
|
m_copyMemory[i] = NULL;
|
|
m_copySize[i] = 0;
|
|
m_copySourceIndex[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
// if the number is null we can allocate it
|
|
if (m_copyMemory[i] == NULL)
|
|
{
|
|
|
|
// this could have gone away since the init, so go
|
|
// till we find one or try 5 times
|
|
// if we don't get it this time, we'll try 5 more times next time
|
|
|
|
int counter = 0;
|
|
while (counter < 5)
|
|
{
|
|
|
|
int random_number = Random::GetLessThan(m_sourceCount);
|
|
|
|
if (m_sourceData[random_number].GetCurrent() != NULL)
|
|
{
|
|
m_copySourceIndex[i] = (BYTE)random_number;
|
|
m_copySize[i] = m_sourceSize[random_number];
|
|
m_copyMemory[i] = gos_Malloc(m_copySize[i]);
|
|
|
|
memcpy(m_copyMemory[i], m_sourceData[m_copySourceIndex[i]].GetCurrent(), m_copySize[i]);
|
|
|
|
break;
|
|
}
|
|
++counter;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
// if we churn too much we actually narrow down the real value.
|
|
|
|
//else if we may randomly decide to remove a copy...
|
|
//int random_number = Random::GetLessThan(500);
|
|
//if (random_number == 0)
|
|
//{
|
|
// gos_Free(m_copyMemory[i]);
|
|
// m_copyMemory[i] = NULL;
|
|
// m_copySize[i] = 0;
|
|
// m_copySourceIndex[i] = 0;
|
|
//}
|
|
//else
|
|
{
|
|
// we go ahead and copy the source...
|
|
memcpy(m_copyMemory[i], m_sourceData[m_copySourceIndex[i]].GetCurrent(), m_copySize[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CHECK_ALLOC_SIZE
|
|
|
|
|
|
int percentages[Maximum_Sources];
|
|
|
|
for (i = 0; i < Maximum_Sources; ++i)
|
|
{
|
|
percentages[i] = 0;
|
|
}
|
|
|
|
int total_size = 0;
|
|
for (i = 0; i < Maximum_Copies; ++i)
|
|
{
|
|
if (m_copyMemory[i] != NULL)
|
|
{
|
|
++percentages[m_copySourceIndex[i]];
|
|
|
|
total_size += m_copySize[i];
|
|
}
|
|
}
|
|
|
|
SPEWALWAYS(("jerryeds", "TOTAL SIZE USED : %d", total_size));
|
|
|
|
|
|
for (i = 0; i < Maximum_Sources; ++i)
|
|
{
|
|
float percent = ((float)percentages[i] / Maximum_Copies) * 100.0f;
|
|
SPEWALWAYS(("jerryeds","%d - %d - %f", i, percentages[i], percent));
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|