Files
firestorm/Gameleap/code/mw4/Tools/PatchIT/Span.cpp
T
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

232 lines
5.0 KiB
C++

// Span.cpp: implementation of the Span class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PatchIT.h"
#include "Span.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void Span::DeleteChildren()
{
if(Next) Next->DeleteChildren();
delete Next;
Next=NULL;
}
void Span::InsertNodeAfter(Span *span)
{
if(Next)
{
Next->Prev=span;
}
span->Next=Next;
span->Prev=this;
Next=span;
}
int Span::FindLargestSpan(Span *comspan,DWORD *pos1,DWORD *pos2,DWORD minsize)
{
DWORD maxspan=minsize;
BYTE *comsbuf=comspan->Buffer;
DWORD pos,cspos,dpos;
for(pos=0;pos<Size && (pos+maxspan)<=Size;pos++)
{
for(cspos=0;cspos<comspan->Size && (cspos+maxspan)<=comspan->Size;cspos++)
{
if(Buffer[pos]==comsbuf[cspos] &&
Buffer[pos+(maxspan-1)]==comsbuf[cspos+(maxspan-1)]
)
{
//Check First and Last for Early out
for(dpos=1;(cspos+dpos)<comspan->Size &&
(pos+dpos)<Size &&
Buffer[pos+dpos]==comsbuf[cspos+dpos];dpos++);
if(dpos>maxspan)
{
maxspan=dpos;
*pos1=pos;
*pos2=cspos;
}
}
}
}
return maxspan;
} //End of Find Span
int Span::MapLargestSpan(Span *comspan,DWORD minsize)
{
DWORD spansize;
DWORD pos,cspos;
spansize=FindLargestSpan(comspan,&pos,&cspos,minsize);
if(spansize>minsize)
{ // Missed creeping up Take Last One
Span *new_span1,*new_span2;
new_span1=AddSpanAt(Buffer+pos,spansize);
new_span2=comspan->AddSpanAt(comspan->Buffer+cspos,spansize);
new_span1->MappedTo=new_span2;
new_span2->MappedTo=new_span1;
if(new_span1->Prev!=NULL && new_span1->Prev->MappedTo==NULL &&
new_span2->Prev!=NULL && new_span2->Prev->MappedTo==NULL) //Map the left
new_span1->Prev->MapLargestSpan(new_span2->Prev,minsize);
if(new_span1->Next!=NULL && new_span1->Next->MappedTo==NULL &&
new_span2->Next!=NULL && new_span2->Next->MappedTo==NULL) //Map the right
new_span1->Next->MapLargestSpan(new_span2->Next,minsize);
return spansize;
}
return spansize;
} //End of Find Span
Span *Span::AddSpanAt(BYTE * loc,DWORD size)
{
/* // This will put it in the right place
if(loc<Buffer)
{ // Location is in a forward Box
ASSERT(Next);
Next->AddSpanAt(loc,size,map);
return;
}
*/
ASSERT(loc>=Buffer && (loc+size)<=(Buffer+Size)); //Must Be a Sub Span
ASSERT(MappedTo==NULL); //Cannot Split a Mapped Span
DWORD endsize;
Span *new_span;
if((loc-Buffer)==0) //Don't Need a new one Adjust them
{
endsize=Size-size;
Size=size;
new_span=this;
}
else
{
new_span= new Span(loc,size); // Make our Span
InsertNodeAfter(new_span);
endsize=Size-((loc-Buffer)+size);
Size=(loc-Buffer);
}
ASSERT(endsize>=0);
if(endsize>0)
{
new_span->InsertNodeAfter(new Span(loc+size,endsize)); // At end span if needed;
}
return new_span;
}
void Span::SpanInfo(CString &fstr,BYTE *base1,BYTE *base2)
{
CString str;
str.Format("Location = %i Size = %i ",Buffer-base1,Size);
if(MappedTo)
{
CString str2;
str2.Format(" -> Location = %i",MappedTo->Buffer-base2);
str+=str2;
}
str+="\n";
fstr+=str;
if(Next) Next->SpanInfo(fstr,base1,base2);
}
void Span::BuildOps(Span *sspan,CPatchOperation *OpList,const BYTE *base1,const BYTE *base2)
{
Span *cur_node1,*cur_node2;
DWORD lastloc=0;
cur_node1=this;
cur_node2=sspan;
while(cur_node1 && cur_node2)
{
if(cur_node2->MappedTo==NULL)
{
OpList->Next=new CInsert(cur_node1->Buffer-base1,cur_node2->Size,cur_node2->Buffer-base2);
OpList=OpList->Next;
cur_node2=cur_node2->Next;
}
if(cur_node1->MappedTo==NULL)
{
OpList->Next=new CDelete(cur_node1->Buffer-base1,cur_node1->Size);
OpList=OpList->Next;
lastloc=cur_node1->Buffer-base1+cur_node1->Size;
cur_node1=cur_node1->Next;
}
ASSERT((!cur_node1 || cur_node1->MappedTo!=NULL));
ASSERT((!cur_node2 || cur_node2->MappedTo!=NULL));
if(cur_node1 || cur_node2)
{
ASSERT(cur_node2 && cur_node1);
lastloc=cur_node1->Buffer-base1+cur_node1->Size;
cur_node1=cur_node1->Next;
cur_node2=cur_node2->Next;
}
}
if(cur_node1)
{
ASSERT(cur_node1->MappedTo==NULL);
OpList->Next=new CDelete(cur_node1->Buffer-base1,cur_node1->Size);
OpList=OpList->Next;
lastloc=cur_node1->Buffer-base1+cur_node1->Size;
cur_node1=cur_node1->Next;
}
if(cur_node2)
{
ASSERT(cur_node2->MappedTo==NULL);
OpList->Next=new CInsert(lastloc,cur_node2->Size,cur_node2->Buffer-base2);
OpList=OpList->Next;
cur_node2=cur_node2->Next;
}
ASSERT(!cur_node1 && !cur_node2);
}
Span::~Span()
{
DeleteChildren();
}