#include "common.h"
#include "patcher.h"
#include "Antennas.h"
CAntenna CAntennas::aAntennas[NUMANTENNAS];
void
CAntennas::Init(void)
{
int i;
for(i = 0; i < NUMANTENNAS; i++){
aAntennas[i].active = false;
aAntennas[i].updatedLastFrame = false;
}
}
// Free antennas that aren't used anymore
void
CAntennas::Update(void)
{
int i;
for(i = 0; i < NUMANTENNAS; i++){
if(aAntennas[i].active && !aAntennas[i].updatedLastFrame)
aAntennas[i].active = false;
aAntennas[i].updatedLastFrame = false;
}
}
// Add a new one or update an old one
void
CAntennas::RegisterOne(uint32 id, CVector dir, CVector position, float length)
{
int i, j;
for(i = 0; i < NUMANTENNAS; i++)
if(aAntennas[i].active && aAntennas[i].id == id)
break;
if(i >= NUMANTENNAS){
// not found, register new one
// find empty slot
for(i = 0; i < NUMANTENNAS; i++)
if(!aAntennas[i].active)
break;
// there is space
if(i < NUMANTENNAS){
aAntennas[i].active = true;
aAntennas[i].updatedLastFrame = true;
aAntennas[i].id = id;
aAntennas[i].segmentLength = length/6.0f;
for(j = 0; j < 6; j++){
aAntennas[i].pos[j] = position + dir*j*aAntennas[i].segmentLength;
aAntennas[i].speed[j] = CVector(0.0f, 0.0f, 0.0f);
}
}
}else{
// found, update
aAntennas[i].Update(dir, position);
aAntennas[i].updatedLastFrame = true;
}
}
static RwIm3DVertex vertexbufferA[2];
void
CAntennas::Render(void)
{
int i, j;
for(i = 0; i < NUMANTENNAS; i++){
if(!aAntennas[i].active)
continue;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
for(j = 0; j < 5; j++){
RwIm3DVertexSetRGBA(&vertexbufferA[0], 200, 200, 200, 100);
RwIm3DVertexSetPos(&vertexbufferA[0],
aAntennas[i].pos[j].x,
aAntennas[i].pos[j].y,
aAntennas[i].pos[j].z);
RwIm3DVertexSetRGBA(&vertexbufferA[1], 200, 200, 200, 100);
RwIm3DVertexSetPos(&vertexbufferA[1],
aAntennas[i].pos[j+1].x,
aAntennas[i].pos[j+1].y,
aAntennas[i].pos[j+1].z);
// LittleTest();
if(RwIm3DTransform(vertexbufferA, 2, nil, 0)){
RwIm3DRenderLine(0, 1);
RwIm3DEnd();
}
}
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
}
void
CAntenna::Update(CVector dir, CVector basepos)
{
int i;
pos[0] = basepos;
pos[1] = basepos + dir*segmentLength;
for(i = 2; i < 6; i++){
CVector basedir = pos[i-1] - pos[i-2];
CVector newdir = pos[i] - pos[i-1] + // drag along
dir*0.1f + // also drag up a bit for stiffness
speed[i]; // and keep moving
newdir.Normalise();
newdir *= segmentLength;
CVector newpos = pos[i-1] + (basedir + newdir)/2.0f;
speed[i] = (newpos - pos[i])*0.9f;
pos[i] = newpos;
}
}
STARTPATCHES
InjectHook(0x4F64D0, &CAntennas::Init, PATCH_JUMP);
InjectHook(0x4F6550, &CAntennas::Update, PATCH_JUMP);
InjectHook(0x4F66C0, &CAntennas::RegisterOne, PATCH_JUMP);
InjectHook(0x4F6590, &CAntennas::Render, PATCH_JUMP);
InjectHook(0x4F6830, &CAntenna::Update, PATCH_JUMP);
// give to cheetah for testing
// Patch<int>(0x535B50+1, 105);
// Patch<float>(0x535B57+7, -0.84);
// Patch<float>(0x535B74+7, 0.78);
// Patch<float>(0x535B69+7, 0.24);
ENDPATCHES