From ee5088b3e185cb2d455cb64d2098e2a807b0ac27 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 30 May 2019 11:12:49 +0200 Subject: added CAntennas --- src/config.h | 2 + src/render/Antennas.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ src/render/Antennas.h | 25 +++++++++ src/rw.cpp | 1 + 4 files changed, 167 insertions(+) create mode 100644 src/render/Antennas.cpp create mode 100644 src/render/Antennas.h (limited to 'src') diff --git a/src/config.h b/src/config.h index ccd81023..94692fa0 100644 --- a/src/config.h +++ b/src/config.h @@ -50,4 +50,6 @@ enum Config { NUMWEATHERS = 4, NUMHOURS = 24, + + NUMANTENNAS = 8, }; diff --git a/src/render/Antennas.cpp b/src/render/Antennas.cpp new file mode 100644 index 00000000..d564c196 --- /dev/null +++ b/src/render/Antennas.cpp @@ -0,0 +1,139 @@ +#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(0x535B50+1, 105); +// Patch(0x535B57+7, -0.84); +// Patch(0x535B74+7, 0.78); +// Patch(0x535B69+7, 0.24); +ENDPATCHES diff --git a/src/render/Antennas.h b/src/render/Antennas.h new file mode 100644 index 00000000..47cb1dad --- /dev/null +++ b/src/render/Antennas.h @@ -0,0 +1,25 @@ +#pragma once + +class CAntenna +{ +public: + bool active; + bool updatedLastFrame; + uint32 id; + float segmentLength; + CVector pos[6]; + CVector speed[6]; + + void Update(CVector dir, CVector pos); +}; + +class CAntennas +{ + // no need to use game's array + static CAntenna aAntennas[NUMANTENNAS]; +public: + static void Init(void); + static void Update(void); + static void RegisterOne(uint32 id, CVector dir, CVector position, float length); + static void Render(void); +}; diff --git a/src/rw.cpp b/src/rw.cpp index b0e838ac..d202b2ce 100644 --- a/src/rw.cpp +++ b/src/rw.cpp @@ -226,6 +226,7 @@ WRAPPER RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType, RwIm2DVertex*, RwIn WRAPPER RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType, RwImVertexIndex *indices, RwInt32 numIndices) { EAXJMP(0x5B6820); } WRAPPER void *RwIm3DTransform(RwIm3DVertex *pVerts, RwUInt32 numVerts, RwMatrix *ltm, RwUInt32 flags) { EAXJMP(0x5B6720); } +WRAPPER RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2) { EAXJMP(0x5B6980); } WRAPPER RwBool RwIm3DEnd(void) { EAXJMP(0x5B67F0); } static uint32_t _rwObjectHasFrameSetFrame_A = AddressByVersion(0x5BC950, 0x5BCC10, 0x5C1820, 0x660CC0, 0x660D10, 0x65FC70); -- cgit v1.2.3