Redline/source/log.cpp

291 lines
6.1 KiB
C++
Raw Permalink Normal View History

//log.cpp
//log [network] physics packets in order to replay the games
#include <stdlib.h>
#include <unistd.h>
#include "networkphysics.h"
#include "gamemem.h"
#include "log.h"
#include "gameinitexit.h"
#include "gameframe.h"
#include "network.h"
typedef struct{
int offset;
short size;
short type;
} tLogEntry;
#define kLogSize (20*1024*1024)
#define kGhostLogSize (256*1024)
#define kIndexSize (256*1024)
char* gPacketLog;
char *gGhostLog;
tLogEntry *gPacketLogIndex;
tLogEntry *gGhostIndex;
int gLogPos=0;
int gIndexPos=0;
int gGhostLogPos=0;
int gGhostIndexPos=0;
void LogInit()
{
gPacketLog=(char*)malloc(kLogSize);
gGhostLog=(char*)malloc(kGhostLogSize);
gPacketLogIndex=(tLogEntry*)malloc(kIndexSize*sizeof(tLogEntry));
gGhostIndex=(tLogEntry*)malloc(kIndexSize*sizeof(tLogEntry));
}
void GetLogs(tFileRef *logs,int *logCount)
{
*logCount=0;
for(int i=0;i<gFileTableSize;i++)
if(char *extension=FileGetExtension(i))
if(!_stricmp(extension,kFileTypeLog))
if(*logCount<kMaxLogs)
logs[(*logCount)++]=i;
}
void LogPacket(int size, void *data,int type)
{
if(gIndexPos<kIndexSize)
if(gLogPos+size<kLogSize)
{
gPacketLogIndex[gIndexPos].size=size;
gPacketLogIndex[gIndexPos].offset=gLogPos;
gPacketLogIndex[gIndexPos].type=type;
gIndexPos++;
MemoryMove(gPacketLog+gLogPos,data,size);
gLogPos+=size;
}
}
void LogToGhostLog()
{
//kLogSize>kGhostLogSize!!!!
MemoryMove(gGhostLog,gPacketLog,gLogPos>kGhostLogSize?kGhostLogSize:gLogPos);
MemoryMove(gGhostIndex,gPacketLogIndex,gIndexPos*sizeof(tLogEntry));
gGhostLogPos=gLogPos;
gGhostIndexPos=gIndexPos;
}
int LogCompare(const void *a,const void *b)
{
int aFrame=((tPhysicsMessage*)(gPacketLog+*(int*)a))->frame;
int bFrame=((tPhysicsMessage*)(gPacketLog+*(int*)b))->frame;
S32Swap(aFrame);
S32Swap(bFrame);
return aFrame-bFrame;
}
void LogSort()
{
qsort(gPacketLogIndex,gIndexPos,sizeof(tLogEntry),LogCompare);
}
void LogReset()
{
gLogPos=0;
gIndexPos=0;
}
void GhostLogReset()
{
gGhostLogPos=0;
gGhostIndexPos=0;
}
int LogGetPacket(int index,int *type,int *size,int log,void *buffer)
{
if(log==kLogReplayLog||gGhostLogPos==0){
if(index<gIndexPos)
{
*type=gPacketLogIndex[index].type;
*size=gPacketLogIndex[index].size;
memcpy(buffer,gPacketLog+gPacketLogIndex[index].offset,*size);
return true;
}
}
else
if(index<gGhostIndexPos)
if(gGhostIndex[index].offset<kGhostLogSize)
{
*type=gGhostIndex[index].type;
*size=gGhostIndex[index].size;
memcpy(buffer,gGhostLog+gGhostIndex[index].offset,*size);
return true;
}
return false;
}
void GameInfoSend(tGameInfo *gInfo);
void GameInfoReceive(tGameInfo *gInfo);
void ConvertGInfoSwap(tGameInfo *gInfo);
void LogSaveToDisk()
{
char ct[255],name[255];
time_t t;
time(&t);
ctime_r(&t,ct);
ct[19]='\0';
ct[13]='-';
ct[16]='-';
sprintf(name,"%s.redlog",ct);
CFBundleRef refMainBundle = CFBundleGetMainBundle();
if (!refMainBundle)
return;
// create a URL to the app bundle
CFURLRef refMainBundleURL = CFBundleCopyBundleURL (refMainBundle);
if(!refMainBundleURL)
return;
char path[512];
if(!CFURLGetFileSystemRepresentation(refMainBundleURL,true,(UInt8*)path,512))
return;
sprintf(path,"%s/../",path);
chdir(path);
sprintf(path,"%s/Plug-Ins/",path);
chdir(path);
FILE* f=fopen(name,"w");
if(!f)
return;
GameInfoSend(gGameInfo);
fwrite(gGameInfo,sizeof(tGameInfo),1,f);
if(gGameInfo->numLaps==-1)
{
int w=gGhostIndexPos;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
w=gGhostLogPos;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
w=gReplayOldFrameCount;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
for(int i=0;i<gGhostIndexPos;i++)
{
S32Swap(gGhostIndex[i].offset);
S16Swap(gGhostIndex[i].type);
S16Swap(gGhostIndex[i].size);
}
fwrite(gGhostIndex,sizeof(tLogEntry),gGhostIndexPos,f);
for(int i=0;i<gGhostIndexPos;i++)
{
S32Swap(gGhostIndex[i].offset);
S16Swap(gGhostIndex[i].type);
S16Swap(gGhostIndex[i].size);
}
for(int i=0;i<gGhostIndexPos;i++)
{
switch(gGhostIndex[i].type)
{
case kMessageTypePhysics:
{
tPhysicsMessage *physMessage=(tPhysicsMessage*)(gGhostLog+gGhostIndex[i].offset);
physMessage->frame-=(gBestLapTime!=0?gBestLapStart+5:gCurrentLapStart+5);
}
}
}
fwrite(gGhostLog,sizeof(char),gGhostLogPos,f);
for(int i=0;i<gGhostIndexPos;i++)
{
switch(gGhostIndex[i].type)
{
case kMessageTypePhysics:
{
tPhysicsMessage *physMessage=(tPhysicsMessage*)(gGhostLog+gGhostIndex[i].offset);
physMessage->frame+=(gBestLapTime!=0?gBestLapStart+5:gCurrentLapStart+5);
}
}
}
}
else
{
int w=gIndexPos;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
w=gLogPos;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
w=gReplayOldFrameCount;
S32Swap(w);
fwrite(&w,sizeof(int),1,f);
for(int i=0;i<gIndexPos;i++)
{
S32Swap(gPacketLogIndex[i].offset);
S16Swap(gPacketLogIndex[i].type);
S16Swap(gPacketLogIndex[i].size);
}
fwrite(gPacketLogIndex,sizeof(tLogEntry),gIndexPos,f);
for(int i=0;i<gIndexPos;i++)
{
S32Swap(gPacketLogIndex[i].offset);
S16Swap(gPacketLogIndex[i].type);
S16Swap(gPacketLogIndex[i].size);
}
fwrite(gPacketLog,sizeof(char),gLogPos,f);
}
fclose(f);
FileRescanDirectory();
}
int LogLoad(tFileRef f,tGameInfo* gInfo)
{
char *ch=(char*)FileGetDataPtr(f);
*gInfo=*(tGameInfo*)ch;
ConvertGInfoSwap(gInfo);
GameInfoReceive(gInfo);
ch+=sizeof(tGameInfo);//-sizeof(UInt32)*kMaxPlayers;
for(int i=0;i<gInfo->numPlayers;i++)
if(gInfo->playerCars[i]==-1)
return false;
if(gInfo->map==-1)
return false;
if(gInfo->environment==-1)
return false;
gIndexPos=*(int*)ch;
S32Swap(gIndexPos);
gGhostIndexPos=gIndexPos;
ch+=sizeof(int);
gLogPos=*(int*)ch;
S32Swap(gLogPos);
ch+=sizeof(int);
gReplayOldFrameCount=*(int*)ch;
S32Swap(gReplayOldFrameCount);
ch+=sizeof(int);
MemoryMove(gPacketLogIndex,ch,sizeof(tLogEntry)*gIndexPos);
for(int i=0;i<gIndexPos;i++)
{
S32Swap(gPacketLogIndex[i].offset);
S16Swap(gPacketLogIndex[i].type);
S16Swap(gPacketLogIndex[i].size);
}
ch+=sizeof(tLogEntry)*gIndexPos;
MemoryMove(gPacketLog,ch,sizeof(char)*gLogPos);
return true;
}