неразрешенный внешний символ rwim3dend и другие
я создаю ASI плагин для игры GTA SA, и у меня есть 11 ошибок, решение которых я не могу выяснить. Будьте любезны, помогите пожалуйста...
Rubbish.cpp
#include "stdafx.h"
#include "Rubbish.h"
#include "Game.h"
#include "TxdStore.h"
#include "Camera.h"
#include "World.h"
#include "Weather.h"
#include "Timer.h"
#include "Vehicle.h"
#include "debugmenu_public.h"
int CRubbish::RubbishVisibility;
bool CRubbish::bRubbishInvisible;
COneSheet CRubbish::aSheets[CRubbish::NUMSHEETS];
COneSheet CRubbish::StartEmptyList, CRubbish::EndEmptyList;
COneSheet CRubbish::StartStaticsList, CRubbish::EndStaticsList;
COneSheet CRubbish::StartMoversList, CRubbish::EndMoversList;
RwTexture* CRubbish::gpRubbishTexture[4];
void
COneSheet::AddToList(COneSheet * list)
{
this->prev = list;
this->next = list->next;
list->next = this;
this->next->prev = this;
}
void
COneSheet::RemoveFromList(void)
{
this->next->prev = this->prev;
this->prev->next = this->next;
}
void
CRubbish::Init(void)
{
int i;
for (i = 0; i < NUMSHEETS; i++) {
aSheets[i].type = 0;
if (i == 0)
aSheets[i].prev = &StartEmptyList;
else
aSheets[i].prev = &aSheets[i - 1];
if (i + 1 >= NUMSHEETS)
aSheets[i].next = &EndEmptyList;
else
aSheets[i].next = &aSheets[i + 1];
}
StartEmptyList.next = &aSheets[0];
StartEmptyList.prev = NULL;
EndEmptyList.next = NULL;
EndEmptyList.prev = &aSheets[NUMSHEETS - 1];
StartStaticsList.next = &EndStaticsList;
StartStaticsList.prev = NULL;
EndStaticsList.next = NULL;
CRubbish::EndStaticsList.prev = &CRubbish::StartStaticsList;
CRubbish::StartMoversList.next = &CRubbish::EndMoversList;
CRubbish::StartMoversList.prev = NULL;
CRubbish::EndMoversList.next = NULL;
CRubbish::EndMoversList.prev = &CRubbish::StartMoversList;
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("rubbish"));
gpRubbishTexture[0] = RwTextureRead("gameleaf01_64", NULL);
gpRubbishTexture[1] = RwTextureRead("gameleaf02_64", NULL);
gpRubbishTexture[2] = RwTextureRead("newspaper01_64", NULL);
gpRubbishTexture[3] = RwTextureRead("newspaper02_64", NULL);
CTxdStore::PopCurrentTxd();
CRubbish::RubbishVisibility = 255;
CRubbish::bRubbishInvisible = false;
}
void
CRubbish::StirUp(CVehicle * vehicle)
{
if ((CTimer::m_FrameCounter ^ vehicle->RandomSeed) & 3)
return;
CVector campos = TheCamera.GetCoords();
CVector vehpos = vehicle->GetCoords();
if (abs(campos.x - vehpos.x) > 20.0f ||
abs(campos.y - vehpos.y) > 20.0f)
return;
CVector speedvec = vehicle->GetLinearVelocity();
if (abs(speedvec.x) <= 0.05f && abs(speedvec.y) <= 0.05f)
return;
float speed = CVector(speedvec.x, speedvec.y, 0.0f).Magnitude();
if (speed <= 0.05f)
return;
CVector* up = vehicle->GetMatrix()->GetUp();
CVector* right = vehicle->GetMatrix()->GetRight();
float speed_dot_up = speedvec.x * up->x + speedvec.y * up->y;
CColModel* col = CModelInfo::GetModelInfo(vehicle->GetModelIndex())->GetColModel();
float length = col->boundingBox.vecMax.y;
float width = col->boundingBox.vecMax.x;
COneSheet* sheet, * next;
for (sheet = StartStaticsList.next; sheet != &EndStaticsList; sheet = next) {
next = sheet->next;
float dx = sheet->vec1.x - vehpos.x;
float dy = sheet->vec1.y - vehpos.y;
float dist_dot_up = dx * up->x + dy * up->y;
float dist_dot_right = abs(dx * right->x + dy * right->y);
// this is all weird
if (speed_dot_up > 0.0f && dist_dot_up < -0.5f * length && dist_dot_up > -1.5f * length ||
speed_dot_up <= 0.0f && dist_dot_up > 0.5f * length && dist_dot_up < 1.5f * length) {
float s = dist_dot_right >= width ? 0.5f * speed : speed;
if (dist_dot_right < 1.5f * width && s > 0.05f) {
sheet->type = 2;
sheet->movementType = s <= 0.15f ? 1 : 2;
sheet->duration = 2000;
float l = sqrt(speedvec.x * speedvec.x + speedvec.y * speedvec.y);
sheet->moveOffsetX = speedvec.x / l * speed * 25.0f;
sheet->moveOffsetY = speedvec.y / l * speed * 25.0f;
sheet->moveOffsetZ = speed * 3.0f;
sheet->startTime = CTimer::m_snTimeInMilliseconds;
sheet->moveTargetZ = CWorld::FindGroundZFor3DCoord(
sheet->vec1.x + sheet->moveOffsetX,
sheet->vec1.y + sheet->moveOffsetY,
sheet->vec1.z + 3.0f, NULL, NULL) + 0.1f;
sheet->RemoveFromList();
sheet->AddToList(&StartMoversList);
}
}
}
}
static uint8 rand8(void) { return rand(); }
WRAPPER int CCullZones__FindAttributesForCoors(float x, float y, float z) { EAXJMP(0x72D970); }
static float
FindGroundForRubbish(float x, float y, float z, bool* success)
{
float groundz = CWorld::FindGroundZFor3DCoord(x, y, z, success, NULL);
return groundz;
// get the water to work right :/
// if(CWaterLevel::GetWaterLevel(x, y, z, &waterz, false, NULL))
// ;
}
void
CRubbish::Update(void)
{
COneSheet* sheet;
if (bRubbishInvisible) {
RubbishVisibility -= 5;
if (RubbishVisibility < 0)
RubbishVisibility = 0;
}
else {
RubbishVisibility += 5;
if (RubbishVisibility > 255)
RubbishVisibility = 255;
}
CVector campos = TheCamera.GetCoords();
// Generate new sheets
sheet = StartEmptyList.next;
if (sheet != &EndEmptyList) {
float radius = rand8() / 255.0f + 23.0f;
float angle;
uint8 r = rand8();
if (r & 1)
angle = rand8() / 255.0f * M_PI * 2.0f;
else
angle = (r - 128) / 160.0f + TheCamera.Orientation;
sheet->vec1.x = sin(angle) * radius + campos.x;
sheet->vec1.y = cos(angle) * radius + campos.y;
bool foundGround;
sheet->vec1.z = FindGroundForRubbish(sheet->vec1.x, sheet->vec1.y, campos.z, &foundGround) + 0.1f;
if (foundGround) {
sheet->angle = rand8() / 255.0f * M_PI * 2.0f;
sheet->type = 1;
if (CCullZones__FindAttributesForCoors(sheet->vec1.x, sheet->vec1.y, sheet->vec1.z) & 8)
sheet->zoneVisible1 = 0;
else
sheet->zoneVisible1 = 1;
sheet->RemoveFromList();
sheet->AddToList(&StartStaticsList);
}
}
static float movement[3][34] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0.05, 0.12, 0.25, 0.42, 0.57, 0.68, 0.8, 0.86, 0.9, 0.93, 0.95, 0.96, 0.97, 0.98, 0.99, 1, // XY movemnt
0.15, 0.35, 0.6, 0.9, 1.2, 1.25, 1.3, 1.2, 1.1, 0.95, 0.8, 0.6, 0.45, 0.3, 0.2, 0.1, 0 }, // Z movement
{ 0, 0.05, 0.12, 0.25, 0.42, 0.57, 0.68, 0.8, 0.95, 1.1, 1.15, 1.18, 1.15, 1.1, 1.05, 1.03, 1,
0.15, 0.35, 0.6, 0.9, 1.2, 1.25, 1.3, 1.2, 1.1, 0.95, 0.8, 0.6, 0.45, 0.3, 0.2, 0.1, 0 }
};
// Update Movers
COneSheet* next;
for (sheet = StartMoversList.next; sheet != &EndMoversList; sheet = next) {
next = sheet->next;
int t = CTimer::m_snTimeInMilliseconds - sheet->startTime;
if (t < sheet->duration) {
int step = 16 * t / sheet->duration; // 16 steps
float stepInterp = (t - sheet->duration / 16.0f * step) / (sheet->duration / 16.0f); // interpolation along step
float interp = (float)t / sheet->duration; // interpolation along total animation
float moveMult = stepInterp * movement[sheet->movementType][step + 1] +
(1.0f - stepInterp) * movement[sheet->movementType][step];
float moveMultZ = stepInterp * movement[sheet->movementType][step + 1 + 17] +
(1.0f - stepInterp) * movement[sheet->movementType][step + 17];
sheet->vec2.x = sheet->vec1.x + sheet->moveOffsetX * moveMult;
sheet->vec2.y = sheet->vec1.y + sheet->moveOffsetY * moveMult;
sheet->vec2.z = interp * sheet->moveTargetZ + (1.0f - interp) * sheet->vec1.z +
sheet->moveOffsetZ * moveMultZ;
sheet->angle += CTimer::ms_fTimeStep / 25.0f;
if (sheet->angle > 2 * M_PI)
sheet->angle -= 2 * M_PI;
}
else {
// Move done, make static again
sheet->vec1.x += sheet->moveOffsetX;
sheet->vec1.y += sheet->moveOffsetY;
sheet->vec1.z = sheet->moveTargetZ;
sheet->type = 1;
sheet->zoneVisible1 = sheet->zoneVisible2;
sheet->RemoveFromList();
sheet->AddToList(&StartStaticsList);
}
}
int freq;
if (CWeather::Wind < 0.1f)
freq = 0x1F;
else if (CWeather::Wind < 0.4f)
freq = 7;
else if (CWeather::Wind < 0.7f)
freq = 1;
else
freq = 0;
// Turn Statics into Movers
if ((CTimer::m_FrameCounter & freq) == 0) {
int i = rand() & (NUMSHEETS - 1);
sheet = &aSheets[i];
if (sheet->type == 1) {
sheet->startTime = CTimer::m_snTimeInMilliseconds;
sheet->duration = CWeather::Wind * 1500.0f + 1000.0f;
sheet->moveOffsetZ = 0.2f;
sheet->moveOffsetX = CWeather::Wind * 3.0f;
sheet->moveOffsetY = CWeather::Wind * 3.0f;
bool foundGround;
sheet->moveTargetZ = FindGroundForRubbish(sheet->vec1.x + sheet->moveOffsetX, sheet->vec1.y + sheet->moveOffsetY, sheet->vec1.z, &foundGround) + 0.1f;
if (CCullZones__FindAttributesForCoors(sheet->vec1.x + sheet->moveOffsetX, sheet->vec1.y + sheet->moveOffsetY, sheet->moveTargetZ) & 8)
sheet->zoneVisible2 = 0;
else
sheet->zoneVisible2 = 1;
if (foundGround) {
sheet->type = 2;
sheet->movementType = 1;
sheet->RemoveFromList();
sheet->AddToList(&StartMoversList);
}
}
}
// Remove sheets that are too far away
// Actually only two per frame
int i;
for (i = 0; i < NUMSHEETS; i++) {
if (aSheets[i].type != 1)
continue;
if (aSheets[i].vec1.DistanceXY(campos) > 24.0f) {
aSheets[i].type = 0;
aSheets[i].RemoveFromList();
aSheets[i].AddToList(&StartEmptyList);
}
}
}
static int TempBufferIndicesStored;
static int TempBufferVerticesStored;
static RwIm3DVertex TempVertexBuffer[512];
static RwImVertexIndex TempBufferRenderIndexList[1024];
void
CRubbish::Render(void)
{
if (RubbishVisibility == 0 || CGame::currArea > 0)
return;
int alphafunc;
RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &alphafunc);
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, (void*)rwALPHATESTFUNCTIONALWAYS);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
int textype;
for (textype = 0; textype < 4; textype++) {
if (textype < 3)
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[textype]));
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
for (COneSheet* sheet = &aSheets[textype * (NUMSHEETS / 4)];
sheet < &aSheets[(textype + 1) * (NUMSHEETS / 4)];
sheet++) {
if (sheet->type == 0)
continue;
int alpha = 100;
CVector pos;
if (sheet->type == 1) {
pos = sheet->vec1;
if (!sheet->zoneVisible1)
alpha = 0;
}
else {
pos = sheet->vec2;
if (!sheet->zoneVisible1 || !sheet->zoneVisible2) {
float t = (float)(CTimer::m_snTimeInMilliseconds - sheet->startTime) / sheet->duration;
float f1 = sheet->zoneVisible1 ? 1.0f - t : 0.0f;
float f2 = sheet->zoneVisible2 ? t : 0.0f;
alpha = 100 * (f1 + f2);
}
}
float dist = pos.DistanceXY(TheCamera.GetCoords());
if (dist > 23.0f)
continue;
if (dist > 20.0f)
alpha -= alpha * (dist - 20.0f) / (23.0f - 20.0f);
float vx1, vx2;
float vy1, vy2;
static float sizes[4] = { 0.4, 0.8, 0.3, 0.3 }; // all square in VCS
vx1 = sin(sheet->angle) * sizes[textype];
vy1 = cos(sheet->angle) * sizes[textype];
vx2 = cos(sheet->angle) * sizes[textype];
vy2 = -sin(sheet->angle) * sizes[textype];
alpha = RubbishVisibility * alpha / 255;
int i = TempBufferVerticesStored;
RwIm3DVertexSetPos(&TempVertexBuffer[i + 0], pos.x + vx1 + vx2, pos.y + vy1 + vy2, pos.z);
RwIm3DVertexSetPos(&TempVertexBuffer[i + 1], pos.x + vx1 - vx2, pos.y + vy1 - vy2, pos.z);
RwIm3DVertexSetPos(&TempVertexBuffer[i + 2], pos.x - vx1 + vx2, pos.y - vy1 + vy2, pos.z);
RwIm3DVertexSetPos(&TempVertexBuffer[i + 3], pos.x - vx1 - vx2, pos.y - vy1 - vy2, pos.z);
RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 0], 255, 255, 255, alpha);
RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 1], 255, 255, 255, alpha);
RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 2], 255, 255, 255, alpha);
RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 3], 255, 255, 255, alpha);
RwIm3DVertexSetU(&TempVertexBuffer[i + 0], 0.0f);
RwIm3DVertexSetV(&TempVertexBuffer[i + 0], 0.0f);
RwIm3DVertexSetU(&TempVertexBuffer[i + 1], 1.0f);
RwIm3DVertexSetV(&TempVertexBuffer[i + 1], 0.0f);
RwIm3DVertexSetU(&TempVertexBuffer[i + 2], 0.0f);
RwIm3DVertexSetV(&TempVertexBuffer[i + 2], 1.0f);
RwIm3DVertexSetU(&TempVertexBuffer[i + 3], 1.0f);
RwIm3DVertexSetV(&TempVertexBuffer[i + 3], 1.0f);
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 0;
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 1;
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 2;
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 1;
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 3;
TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 2;
TempBufferVerticesStored += 4;
}
if (TempBufferIndicesStored) {
if (RwIm3DTransform(TempVertexBuffer, TempBufferVerticesStored, NULL, rwIM3D_VERTEXUV)) {
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
}
}
RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, (void*)alphafunc);
}
void
CRubbish::SetVisibility(bool v)
{
bRubbishInvisible = !v;
}
static StaticPatcher Patcher([]() {
Memory::InjectHook(0x7204C0, CRubbish::SetVisibility, PATCH_JUMP);
if (DebugMenuLoad()) {
DebugMenuAddVarBool8("Rendering", "Rubbish invisible", (int8*)&CRubbish::bRubbishInvisible, NULL);
}
});
rubbish.h
#ifndef __RUBBISH
#define __RUBBISH
struct COneSheet
{
CVector vec1;
CVector vec2;
float moveTargetZ;
int8 type;
int8 movementType;
int32 startTime;
int32 duration;
float moveOffsetZ;
float moveOffsetX;
float moveOffsetY;
float angle;
int8 zoneVisible1;
int8 zoneVisible2;
int8 unk72;
int8 unk73;
COneSheet *next;
COneSheet *prev;
void AddToList(COneSheet *list);
void RemoveFromList(void);
};
class CVehicle;
class CRubbish
{
public:
// MUST be a power of 2
enum { NUMSHEETS = 32 };
static int RubbishVisibility;
static bool bRubbishInvisible;
static COneSheet aSheets[NUMSHEETS];
static COneSheet StartEmptyList, EndEmptyList;
static COneSheet StartStaticsList, EndStaticsList;
static COneSheet StartMoversList, EndMoversList;
static RwTexture *gpRubbishTexture[4];
static void Init(void);
static void Update(void);
static void StirUp(CVehicle *vehicle);
static void Render(void);
static void SetVisibility(bool v);
};
#endif
Ошибки:
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DEnd.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwTextureRead.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DRenderIndexedPrimitive.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwEngineInstance.
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: __thiscall StaticPatcher::StaticPatcher(void (__cdecl*)(void))" (??0StaticPatcher@@QAE@P6AXXZ@Z).
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static class CBaseModelInfo * * CModelInfo::ms_modelInfoPtrs" (?ms_modelInfoPtrs@CModelInfo@@2QAPAVCBaseModelInfo@@A).
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DTransform.
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static int & CTimer::m_snTimeInMilliseconds" (?m_snTimeInMilliseconds@CTimer@@2AAHA).
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static double __cdecl CWorld::FindGroundZFor3DCoord(float,float,float,bool *,class CEntity * *)" (?FindGroundZFor3DCoord@CWorld@@SANMMMPA_NPAPAVCEntity@@@Z).
Rubbish.obj : error LNK2001: неразрешенный внешний символ _gDebugMenuAPI.
O:\GTA San Andreas\scripts\vcrubbish.SA.asi : fatal error LNK1120: неразрешенных внешних элементов: 10
Источник: Stack Overflow на русском