diff options
Diffstat (limited to 'src')
292 files changed, 17054 insertions, 7391 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..ad72eb56 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,121 @@ +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +file(GLOB_RECURSE ${PROJECT}_SOURCES "*.cpp" "*.h" "*.rc") + +function(header_directories RETURN_LIST) + file(GLOB_RECURSE ALL_SRCS *.h *.cpp *.c) + set(RELDIRS) + foreach(SRC ${ALL_SRCS}) + file(RELATIVE_PATH RELSRC "${CMAKE_CURRENT_SOURCE_DIR}" "${SRC}") + get_filename_component(RELDIR "${RELSRC}" DIRECTORY) + list(APPEND RELDIRS ${RELDIR}) + endforeach() + list(REMOVE_DUPLICATES RELDIRS) + set(${RETURN_LIST} ${RELDIRS} PARENT_SCOPE) +endfunction() + +header_directories(${PROJECT}_INCLUDES) + +add_executable(${EXECUTABLE} WIN32 + ${${PROJECT}_SOURCES} +) + +target_link_libraries(${EXECUTABLE} PRIVATE + librw::librw + Threads::Threads +) + +target_include_directories(${EXECUTABLE} + PRIVATE + $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> + $<BUILD_INTERFACE:${${PROJECT}_INCLUDES}> +) + +target_compile_definitions(${EXECUTABLE} + PRIVATE + $<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG> + LIBRW + CMAKE_NO_AUTOLINK +) + +if(LIBRW_PLATFORM_D3D9) + target_compile_definitions(${EXECUTABLE} + PUBLIC + USE_D3D9 + ) +endif() + +if(${PROJECT}_AUDIO STREQUAL "OAL") + find_package(OpenAL REQUIRED) + target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR}) + target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY}) + target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS}) + target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL) +elseif(${PROJECT}_AUDIO STREQUAL "MSS") + find_package(MilesSDK REQUIRED) + target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_MSS) + target_link_libraries(${EXECUTABLE} PRIVATE MilesSDK::MilesSDK) +endif() + +find_package(mpg123 REQUIRED) +target_link_libraries(${EXECUTABLE} PRIVATE + MPG123::libmpg123 +) +if(${PROJECT}_WITH_OPUS) + find_package(opusfile REQUIRED) + target_link_libraries(${EXECUTABLE} PRIVATE + opusfile::opusfile + ) + target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OPUS) +endif() +if(${PROJECT}_WITH_LIBSNDFILE) + find_package(SndFile REQUIRED) + target_link_libraries(${EXECUTABLE} PRIVATE + SndFile::SndFile + ) + target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL_USE_SNDFILE) +endif() + +target_compile_definitions(${EXECUTABLE} PRIVATE ) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + target_compile_options(${EXECUTABLE} + PRIVATE + "-Wall" + ) + if (NOT LIBRW_PLATFORM_PS2) + target_compile_options(${EXECUTABLE} + PRIVATE + -Wextra + -Wdouble-promotion + -Wpedantic + ) + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + target_compile_options(${EXECUTABLE} + PUBLIC + /Zc:sizedDealloc- + ) +endif() + +set_target_properties(${EXECUTABLE} + PROPERTIES + C_STANDARD 11 + C_EXTENSIONS OFF + C_STANDARD_REQUIRED ON + CXX_STANDARD 11 + CXX_EXTENSIONS OFF + CXX_STANDARD_REQUIRED ON +) + +if(${PROJECT}_INSTALL) + install( + TARGETS ${EXECUTABLE} + EXPORT ${EXECUTABLE}-targets + RUNTIME DESTINATION "." + ) + if(MSVC) + install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL) + endif() +endif() diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp index 83c1742a..ad6f54a9 100644 --- a/src/animation/AnimBlendAssocGroup.cpp +++ b/src/animation/AnimBlendAssocGroup.cpp @@ -15,8 +15,6 @@ #include "AnimBlendAssociation.h" #include "AnimBlendAssocGroup.h" -//--MIAMI: file done - CAnimBlendAssocGroup::CAnimBlendAssocGroup(void) { animBlock = nil; @@ -117,8 +115,8 @@ GetModelFromName(const char *name) char playername[32]; if(strncasecmp(name, "CSplay", 6) == 0 && - strncasecmp(CModelInfo::GetModelInfo(MI_PLAYER)->GetName(), "ig", 2) == 0){ - strcpy(playername, CModelInfo::GetModelInfo(MI_PLAYER)->GetName()); + strncasecmp(CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName(), "ig", 2) == 0){ + strcpy(playername, CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName()); playername[0] = 'C'; playername[1] = 'S'; name = playername; @@ -127,7 +125,7 @@ GetModelFromName(const char *name) for(i = 0; i < MODELINFOSIZE; i++){ mi = CModelInfo::GetModelInfo(i); if(mi && mi->GetRwObject() && RwObjectGetType(mi->GetRwObject()) == rpCLUMP && - strcmpIgnoringDigits(mi->GetName(), name)) + strcmpIgnoringDigits(mi->GetModelName(), name)) return mi; } return nil; @@ -149,7 +147,7 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name) CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(animBlock->firstIndex + i); CBaseModelInfo *model = GetModelFromName(anim->name); if(model){ - debug("Associated anim %s with model %s\n", anim->name, model->GetName()); + debug("Associated anim %s with model %s\n", anim->name, model->GetModelName()); RpClump *clump = (RpClump*)model->CreateInstance(); RpAnimBlendClumpInit(clump); assocList[i].Init(clump, anim); diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp index a6c679eb..bb4e7bf4 100644 --- a/src/animation/AnimBlendAssociation.cpp +++ b/src/animation/AnimBlendAssociation.cpp @@ -5,9 +5,7 @@ #include "RpAnimBlend.h" #include "AnimManager.h" #include "AnimBlendAssociation.h" -#include "RwHelper.h" - -//--MIAMI: file done +#include "MemoryMgr.h" CAnimBlendAssociation::CAnimBlendAssociation(void) { @@ -139,11 +137,15 @@ CAnimBlendAssociation::SetCurrentTime(float time) } CAnimManager::UncompressAnimation(hierarchy); - if(hierarchy->compressed2){ +#ifdef ANIM_COMPRESSION + // strangely PC has this but android doesn't + if(hierarchy->keepCompressed){ for(i = 0; i < numNodes; i++) if(nodes[i].sequence) nodes[i].SetupKeyFrameCompressed(); - }else{ + }else +#endif + { for(i = 0; i < numNodes; i++) if(nodes[i].sequence) nodes[i].FindKeyFrame(currentTime); diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp index 5f7491fe..b333a449 100644 --- a/src/animation/AnimBlendClumpData.cpp +++ b/src/animation/AnimBlendClumpData.cpp @@ -1,14 +1,12 @@ #include "common.h" #include "AnimBlendClumpData.h" -#include "RwHelper.h" - -//--MIAMI: file done +#include "MemoryMgr.h" CAnimBlendClumpData::CAnimBlendClumpData(void) { numFrames = 0; - velocity = nil; + velocity2d = nil; frames = nil; link.Init(); } diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h index af7e5df5..bb711b28 100644 --- a/src/animation/AnimBlendClumpData.h +++ b/src/animation/AnimBlendClumpData.h @@ -3,7 +3,6 @@ #include "AnimBlendList.h" -// TODO: put somewhere else struct AnimBlendFrameData { enum { @@ -12,24 +11,18 @@ struct AnimBlendFrameData VELOCITY_EXTRACTION = 8, VELOCITY_EXTRACTION_3D = 0x10, UPDATE_KEYFRAMES = 0x20, - UNK_COMPRESSED = 0x40, + COMPRESSED = 0x40 }; uint8 flag; RwV3d resetPos; -#ifdef PED_SKIN union { RwFrame *frame; RpHAnimStdInterpFrame *hanimFrame; }; int32 nodeID; -#else - RwFrame *frame; -#endif }; -#ifndef PED_SKIN -VALIDATE_SIZE(AnimBlendFrameData, 0x14); -#endif +VALIDATE_SIZE(AnimBlendFrameData, 0x18); class CAnimBlendClumpData @@ -37,15 +30,16 @@ class CAnimBlendClumpData public: CAnimBlendLink link; int32 numFrames; - CVector *velocity; + union { + CVector2D *velocity2d; + CVector *velocity3d; + }; // order of frames is determined by RW hierarchy AnimBlendFrameData *frames; CAnimBlendClumpData(void); ~CAnimBlendClumpData(void); void SetNumberOfFrames(int n); -#ifdef PED_SKIN void SetNumberOfBones(int n) { SetNumberOfFrames(n); } -#endif void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg); }; diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp index d3d6287a..bfa39ef9 100644 --- a/src/animation/AnimBlendHierarchy.cpp +++ b/src/animation/AnimBlendHierarchy.cpp @@ -4,8 +4,6 @@ #include "AnimBlendHierarchy.h" #include "AnimManager.h" -//--MIAMI: file done - CAnimBlendHierarchy::CAnimBlendHierarchy(void) { sequences = nil; @@ -65,10 +63,10 @@ CAnimBlendHierarchy::CalcTotalTimeCompressed(void) continue; #endif - totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->deltaTime/60.0f); + totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->GetDeltaTime()); for(j = sequences[i].numFrames-1; j >= 1; j--){ - KeyFrame *kf1 = sequences[i].GetKeyFrameCompressed(j); - KeyFrame *kf2 = sequences[i].GetKeyFrameCompressed(j-1); + KeyFrameCompressed *kf1 = sequences[i].GetKeyFrameCompressed(j); + KeyFrameCompressed *kf2 = sequences[i].GetKeyFrameCompressed(j-1); kf1->deltaTime -= kf2->deltaTime; } } @@ -94,6 +92,12 @@ CAnimBlendHierarchy::RemoveAnimSequences(void) void CAnimBlendHierarchy::Uncompress(void) { +#ifdef ANIM_COMPRESSION + int i; + assert(compressed); + for(i = 0; i < numSequences; i++) + sequences[i].Uncompress(); +#endif compressed = 0; if(totalLength == 0.0f){ RemoveQuaternionFlips(); @@ -104,6 +108,22 @@ CAnimBlendHierarchy::Uncompress(void) void CAnimBlendHierarchy::RemoveUncompressedData(void) { - // useless +#ifdef ANIM_COMPRESSION + int i; + assert(!compressed); + for(i = 0; i < numSequences; i++) + sequences[i].RemoveUncompressedData(); +#endif compressed = 1; } + +#ifdef USE_CUSTOM_ALLOCATOR +void +CAnimBlendHierarchy::MoveMemory(bool onlyone) +{ + int i; + for(i = 0; i < numSequences; i++) + if(sequences[i].MoveMemory() && onlyone) + return; +} +#endif diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h index b34ae210..4838c4f8 100644 --- a/src/animation/AnimBlendHierarchy.h +++ b/src/animation/AnimBlendHierarchy.h @@ -2,6 +2,10 @@ #include "templates.h" +#ifdef MoveMemory +#undef MoveMemory // windows shit +#endif + class CAnimBlendSequence; // A collection of sequences @@ -11,8 +15,8 @@ public: char name[24]; CAnimBlendSequence *sequences; int16 numSequences; - bool compressed; // not really used - bool compressed2; // not really used + bool compressed; + bool keepCompressed; float totalLength; CLink<CAnimBlendHierarchy*> *linkPtr; @@ -25,6 +29,7 @@ public: void RemoveAnimSequences(void); void Uncompress(void); void RemoveUncompressedData(void); + void MoveMemory(bool onlyone = false); bool IsCompressed() { return !!compressed; }; }; diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp index ac1328eb..6352c11b 100644 --- a/src/animation/AnimBlendNode.cpp +++ b/src/animation/AnimBlendNode.cpp @@ -3,8 +3,6 @@ #include "AnimBlendAssociation.h" #include "AnimBlendNode.h" -//--MIAMI: file done - void CAnimBlendNode::Init(void) { @@ -48,6 +46,44 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight) } bool +CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight) +{ + bool looped = false; + + trans = CVector(0.0f, 0.0f, 0.0f); + rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f); + + if(association->IsRunning()){ + remainingTime -= association->timeStep; + if(remainingTime <= 0.0f) + looped = NextKeyFrameCompressed(); + } + + float blend = association->GetBlendAmount(weight); + if(blend > 0.0f){ + KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA); + KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB); + float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime(); + if(sequence->type & CAnimBlendSequence::KF_TRANS){ + CVector transA, transB; + kfA->GetTranslation(&transA); + kfB->GetTranslation(&transB); + trans = transB + t*(transA - transB); + trans *= blend; + } + if(sequence->type & CAnimBlendSequence::KF_ROT){ + CQuaternion rotA, rotB; + kfA->GetRotation(&rotA); + kfB->GetRotation(&rotB); + rot.Slerp(rotB, rotA, theta, invSin, t); + rot *= blend; + } + } + + return looped; +} + +bool CAnimBlendNode::NextKeyFrame(void) { bool looped; @@ -84,6 +120,43 @@ CAnimBlendNode::NextKeyFrame(void) return looped; } +bool +CAnimBlendNode::NextKeyFrameCompressed(void) +{ + bool looped; + + if(sequence->numFrames <= 1) + return false; + + looped = false; + frameB = frameA; + + // Advance as long as we have to + while(remainingTime <= 0.0f){ + frameA++; + + if(frameA >= sequence->numFrames){ + // reached end of animation + if(!association->IsRepeating()){ + frameA--; + remainingTime = 0.0f; + return false; + } + looped = true; + frameA = 0; + } + + remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime(); + } + + frameB = frameA - 1; + if(frameB < 0) + frameB += sequence->numFrames; + + CalcDeltasCompressed(); + return looped; +} + // Set animation to time t bool CAnimBlendNode::FindKeyFrame(float t) @@ -132,7 +205,7 @@ CAnimBlendNode::SetupKeyFrameCompressed(void) frameA = 0; remainingTime = 0.0f; }else - remainingTime = sequence->GetKeyFrameCompressed(frameA)->deltaTime/60.0f; + remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime(); CalcDeltasCompressed(); return true; @@ -157,9 +230,17 @@ CAnimBlendNode::CalcDeltasCompressed(void) { if((sequence->type & CAnimBlendSequence::KF_ROT) == 0) return; - KeyFrame *kfA = sequence->GetKeyFrameCompressed(frameA); - KeyFrame *kfB = sequence->GetKeyFrameCompressed(frameB); - float cos = DotProduct(kfA->rotation, kfB->rotation); + KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA); + KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB); + CQuaternion rotA, rotB; + kfA->GetRotation(&rotA); + kfB->GetRotation(&rotB); + float cos = DotProduct(rotA, rotB); + if(cos < 0.0f){ + rotB *= -1.0f; + kfB->SetRotation(rotB); + } + cos = DotProduct(rotA, rotB); if(cos > 1.0f) cos = 1.0f; theta = Acos(cos); @@ -184,6 +265,26 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight) } void +CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight) +{ + trans = CVector(0.0f, 0.0f, 0.0f); + + float blend = association->GetBlendAmount(weight); + if(blend > 0.0f){ + KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA); + KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB); + float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime(); + if(sequence->type & CAnimBlendSequence::KF_TRANS){ + CVector transA, transB; + kfA->GetTranslation(&transA); + kfB->GetTranslation(&transB); + trans = transB + t*(transA - transB); + trans *= blend; + } + } +} + +void CAnimBlendNode::GetEndTranslation(CVector &trans, float weight) { trans = CVector(0.0f, 0.0f, 0.0f); @@ -195,3 +296,19 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight) trans = kf->translation * blend; } } + +void +CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight) +{ + trans = CVector(0.0f, 0.0f, 0.0f); + + float blend = association->GetBlendAmount(weight); + if(blend > 0.0f){ + KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1); + if(sequence->type & CAnimBlendSequence::KF_TRANS){ + CVector pos; + kf->GetTranslation(&pos); + trans = pos * blend; + } + } +} diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h index 9446e1ae..99a657ac 100644 --- a/src/animation/AnimBlendNode.h +++ b/src/animation/AnimBlendNode.h @@ -20,13 +20,17 @@ public: void Init(void); bool Update(CVector &trans, CQuaternion &rot, float weight); + bool UpdateCompressed(CVector &trans, CQuaternion &rot, float weight); bool NextKeyFrame(void); + bool NextKeyFrameCompressed(void); bool FindKeyFrame(float t); bool SetupKeyFrameCompressed(void); void CalcDeltas(void); void CalcDeltasCompressed(void); void GetCurrentTranslation(CVector &trans, float weight); + void GetCurrentTranslationCompressed(CVector &trans, float weight); void GetEndTranslation(CVector &trans, float weight); + void GetEndTranslationCompressed(CVector &trans, float weight); }; diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp index b04d6b41..36ac9495 100644 --- a/src/animation/AnimBlendSequence.cpp +++ b/src/animation/AnimBlendSequence.cpp @@ -1,8 +1,7 @@ #include "common.h" #include "AnimBlendSequence.h" - -//--MIAMI: file done +#include "MemoryHeap.h" CAnimBlendSequence::CAnimBlendSequence(void) { @@ -10,9 +9,7 @@ CAnimBlendSequence::CAnimBlendSequence(void) numFrames = 0; keyFrames = nil; keyFramesCompressed = nil; -#ifdef PED_SKIN boneTag = -1; -#endif } CAnimBlendSequence::~CAnimBlendSequence(void) @@ -67,3 +64,137 @@ CAnimBlendSequence::RemoveQuaternionFlips(void) last = frame->rotation; } } + +void +CAnimBlendSequence::Uncompress(void) +{ + int i; + + if(numFrames == 0) + return; + + PUSH_MEMID(MEMID_ANIMATION); + + float rotScale = 1.0f/4096.0f; + float timeScale = 1.0f/60.0f; + float transScale = 1.0f/1024.0f; + if(type & KF_TRANS){ + void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans)); + KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed; + KeyFrameTrans *kf = (KeyFrameTrans*)newKfs; + for(i = 0; i < numFrames; i++){ + kf->rotation.x = ckf->rot[0]*rotScale; + kf->rotation.y = ckf->rot[1]*rotScale; + kf->rotation.z = ckf->rot[2]*rotScale; + kf->rotation.w = ckf->rot[3]*rotScale; + kf->deltaTime = ckf->deltaTime*timeScale; + kf->translation.x = ckf->trans[0]*transScale; + kf->translation.y = ckf->trans[1]*transScale; + kf->translation.z = ckf->trans[2]*transScale; + kf++; + ckf++; + } + keyFrames = newKfs; + }else{ + void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame)); + KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed; + KeyFrame *kf = (KeyFrame*)newKfs; + for(i = 0; i < numFrames; i++){ + kf->rotation.x = ckf->rot[0]*rotScale; + kf->rotation.y = ckf->rot[1]*rotScale; + kf->rotation.z = ckf->rot[2]*rotScale; + kf->rotation.w = ckf->rot[3]*rotScale; + kf->deltaTime = ckf->deltaTime*timeScale; + kf++; + ckf++; + } + keyFrames = newKfs; + } + REGISTER_MEMPTR(&keyFrames); + + RwFree(keyFramesCompressed); + keyFramesCompressed = nil; + + POP_MEMID(); +} + +void +CAnimBlendSequence::CompressKeyframes(void) +{ + int i; + + if(numFrames == 0) + return; + + PUSH_MEMID(MEMID_ANIMATION); + + float rotScale = 4096.0f; + float timeScale = 60.0f; + float transScale = 1024.0f; + if(type & KF_TRANS){ + void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed)); + KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs; + KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames; + for(i = 0; i < numFrames; i++){ + ckf->rot[0] = kf->rotation.x*rotScale; + ckf->rot[1] = kf->rotation.y*rotScale; + ckf->rot[2] = kf->rotation.z*rotScale; + ckf->rot[3] = kf->rotation.w*rotScale; + ckf->deltaTime = kf->deltaTime*timeScale + 0.5f; + ckf->trans[0] = kf->translation.x*transScale; + ckf->trans[1] = kf->translation.y*transScale; + ckf->trans[2] = kf->translation.z*transScale; + kf++; + ckf++; + } + keyFramesCompressed = newKfs; + }else{ + void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed)); + KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs; + KeyFrame *kf = (KeyFrame*)keyFrames; + for(i = 0; i < numFrames; i++){ + ckf->rot[0] = kf->rotation.x*rotScale; + ckf->rot[1] = kf->rotation.y*rotScale; + ckf->rot[2] = kf->rotation.z*rotScale; + ckf->rot[3] = kf->rotation.w*rotScale; + ckf->deltaTime = kf->deltaTime*timeScale + 0.5f; + kf++; + ckf++; + } + keyFramesCompressed = newKfs; + } + REGISTER_MEMPTR(&keyFramesCompressed); + + POP_MEMID(); +} + +void +CAnimBlendSequence::RemoveUncompressedData(void) +{ + if(numFrames == 0) + return; + CompressKeyframes(); + RwFree(keyFrames); + keyFrames = nil; +} + +#ifdef USE_CUSTOM_ALLOCATOR +bool +CAnimBlendSequence::MoveMemory(void) +{ + if(keyFrames){ + void *newaddr = gMainHeap.MoveMemory(keyFrames); + if(newaddr != keyFrames){ + keyFrames = newaddr; + return true; + } + }else if(keyFramesCompressed){ + void *newaddr = gMainHeap.MoveMemory(keyFramesCompressed); + if(newaddr != keyFramesCompressed){ + keyFramesCompressed = newaddr; + return true; + } + } + return false; +} +#endif diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h index 759a12ea..67118b2f 100644 --- a/src/animation/AnimBlendSequence.h +++ b/src/animation/AnimBlendSequence.h @@ -2,6 +2,10 @@ #include "Quaternion.h" +#ifdef MoveMemory +#undef MoveMemory // windows shit +#endif + // TODO: put them somewhere else? struct KeyFrame { CQuaternion rotation; @@ -12,6 +16,43 @@ struct KeyFrameTrans : KeyFrame { CVector translation; }; +struct KeyFrameCompressed { + int16 rot[4]; // 4096 + int16 deltaTime; // 60 + + void GetRotation(CQuaternion *quat){ + float scale = 1.0f/4096.0f; + quat->x = rot[0]*scale; + quat->y = rot[1]*scale; + quat->z = rot[2]*scale; + quat->w = rot[3]*scale; + } + void SetRotation(const CQuaternion &quat){ + rot[0] = quat.x * 4096.0f; + rot[1] = quat.y * 4096.0f; + rot[2] = quat.z * 4096.0f; + rot[3] = quat.w * 4096.0f; + } + float GetDeltaTime(void) { return deltaTime/60.0f; } + void SetTime(float t) { deltaTime = t*60.0f + 0.5f; } +}; + +struct KeyFrameTransCompressed : KeyFrameCompressed { + int16 trans[3]; // 1024 + + void GetTranslation(CVector *vec) { + float scale = 1.0f/1024.0f; + vec->x = trans[0]*scale; + vec->y = trans[1]*scale; + vec->z = trans[2]*scale; + } + void SetTranslation(const CVector &vec){ + trans[0] = vec.x*1024.0f; + trans[1] = vec.y*1024.0f; + trans[2] = vec.z*1024.0f; + } +}; + // The sequence of key frames of one animated node class CAnimBlendSequence @@ -38,21 +79,17 @@ public: &((KeyFrameTrans*)keyFrames)[n] : &((KeyFrame*)keyFrames)[n]; } - KeyFrame *GetKeyFrameCompressed(int n) { + KeyFrameCompressed *GetKeyFrameCompressed(int n) { return type & KF_TRANS ? - &((KeyFrameTrans*)keyFramesCompressed)[n] : - &((KeyFrame*)keyFramesCompressed)[n]; + &((KeyFrameTransCompressed*)keyFramesCompressed)[n] : + &((KeyFrameCompressed*)keyFramesCompressed)[n]; } bool HasTranslation(void) { return !!(type & KF_TRANS); } - // TODO? these are unused -// void Uncompress(void); -// void CompressKeyframes(void); -// void RemoveUncompressedData(void); + void Uncompress(void); + void CompressKeyframes(void); + void RemoveUncompressedData(void); + bool MoveMemory(void); -#ifdef PED_SKIN void SetBoneTag(int tag) { boneTag = tag; } -#endif }; -#ifndef PED_SKIN -VALIDATE_SIZE(CAnimBlendSequence, 0x2C); -#endif +VALIDATE_SIZE(CAnimBlendSequence, 0x30); diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index a85149e6..284a567d 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -12,8 +12,6 @@ #include "AnimManager.h" #include "Streaming.h" -//--MIAMI: file done - CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS]; CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS]; int32 CAnimManager::ms_numAnimBlocks; @@ -153,8 +151,8 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_CAR_GETOUT_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_CAR_CLOSE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_CAR_HOOKERTALK, ASSOC_REPEAT | ASSOC_PARTIAL }, - { ANIM_IDLE_STANCE2, ASSOC_PARTIAL }, - { ANIM_IDLE_STANCE3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, + { ANIM_TRAIN_GETIN, ASSOC_PARTIAL }, + { ANIM_TRAIN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_CAR_CRAWLOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_CAR_CRAWLOUT_RHS2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_CAR_ROLLOUT_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION }, @@ -287,6 +285,7 @@ AnimAssocDesc aStripAnimDescs[] = { { ANIM_STRIP_F, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_STRIP_G, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, }; +#ifdef PC_PLAYER_CONTROLS AnimAssocDesc aStdAnimDescsSide[] = { { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK }, { ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK }, @@ -294,7 +293,7 @@ AnimAssocDesc aStdAnimDescsSide[] = { { ANIM_IDLE_STANCE, ASSOC_REPEAT }, { ANIM_WALK_START, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION }, }; - +#endif char const* aStdAnimations[] = { "walk_civi", "run_civi", @@ -834,6 +833,7 @@ char const* aSkateAnimations[] = { "skate_sprint", "skate_idle", }; +#ifdef PC_PLAYER_CONTROLS char const* aPlayerStrafeBackAnimations[] = { "walk_back", "run_back", @@ -897,7 +897,7 @@ char const* aChainsawStrafeRightAnimations[] = { "idle_csaw", "walkst_csaw_right", }; - +#endif #define awc(a) ARRAY_SIZE(a), a const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = { @@ -953,6 +953,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_ { "jogwoman", "ped", MI_COP, awc(aJoggerWomanAnimations), aStdAnimDescs }, { "panicchunky", "ped", MI_COP, awc(aPanicChunkyAnimations), aStdAnimDescs }, { "skate", "skate", MI_COP, awc(aSkateAnimations), aStdAnimDescs }, +#ifdef PC_PLAYER_CONTROLS { "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs }, { "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide }, { "playerright", "ped", MI_COP, awc(aPlayerStrafeRightAnimations), aStdAnimDescsSide }, @@ -962,6 +963,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_ { "csawback", "ped", MI_COP, awc(aChainsawStrafeBackAnimations), aStdAnimDescs }, { "csawleft", "ped", MI_COP, awc(aChainsawStrafeLeftAnimations), aStdAnimDescsSide }, { "csawright", "ped", MI_COP, awc(aChainsawStrafeRightAnimations), aStdAnimDescsSide }, +#endif }; #undef awc @@ -992,7 +994,7 @@ CAnimManager::Shutdown(void) void CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier) { - if(hier->compressed2){ + if(hier->keepCompressed){ if(hier->totalLength == 0.0f) hier->CalcTotalTimeCompressed(); }else{ @@ -1255,13 +1257,10 @@ CAnimManager::CreateAnimAssocGroups(void) group->firstAnimId = def->animDescs[0].animId; group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims); for(j = 0; j < group->numAssociations; j++) - // GetAnimation(i) in III (but it's in LoadAnimFiles), GetAnimation(group->animDesc[j].animId) in VC group->GetAnimation(def->animDescs[j].animId)->flags |= def->animDescs[j].flags; -#ifdef PED_SKIN if(IsClumpSkinned(clump)) RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil); -#endif RpClumpDestroy(clump); } } @@ -1276,9 +1275,8 @@ CAnimManager::LoadAnimFile(const char *filename) RwStreamClose(stream, nil); } -//--MIAMI: done void -CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]) +CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32]) { #define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3) struct IfpHeader { @@ -1323,16 +1321,22 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] RwStreamRead(stream, buf, name.size); hier->SetName(buf); - // Unimplemented uncompressed anim thing - if (somename) { - for (int i = 0; somename[i][0]; i++) { - if (!CGeneral::faststricmp(somename[i], hier->name)) +#ifdef ANIM_COMPRESSION + bool compressHier = compress; +#else + bool compressHier = false; +#endif + if (uncompressedAnims) { + for (int i = 0; uncompressedAnims[i][0]; i++) { + if (!CGeneral::faststricmp(uncompressedAnims[i], hier->name)){ debug("Loading %s uncompressed\n", hier->name); + compressHier = false; + } } } - hier->compressed = false; - hier->compressed2 = false; + hier->compressed = compressHier; + hier->keepCompressed = false; // DG info has number of nodes/sequences RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader)); @@ -1352,69 +1356,86 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] ROUNDSIZE(anim.size); RwStreamRead(stream, buf, anim.size); int numFrames = *(int*)(buf+28); -#ifdef PED_SKIN + seq->SetName(buf); if(anim.size == 44) seq->SetBoneTag(*(int*)(buf+40)); -#endif - seq->SetName(buf); if(numFrames == 0) continue; + bool hasScale = false; + bool hasTranslation = false; RwStreamRead(stream, &info, sizeof(info)); - if(strncmp(info.ident, "KR00", 4) == 0){ - seq->SetNumFrames(numFrames, false, false); - KeyFrame *kf = seq->GetKeyFrame(0); - if (strstr(seq->name, "L Toe")) - debug("anim %s has toe keyframes\n", hier->name); // , seq->name); - - for(l = 0; l < numFrames; l++, kf++){ - RwStreamRead(stream, buf, 0x14); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->deltaTime = fbuf[4]; // absolute time here - } + if(strncmp(info.ident, "KRTS", 4) == 0){ + hasScale = true; + seq->SetNumFrames(numFrames, true, compressHier); }else if(strncmp(info.ident, "KRT0", 4) == 0){ - seq->SetNumFrames(numFrames, true, false); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - if (strstr(seq->name, "L Toe")) - debug("anim %s has toe keyframes\n", hier->name); // , seq->name); + hasTranslation = true; + seq->SetNumFrames(numFrames, true, compressHier); + }else if(strncmp(info.ident, "KR00", 4) == 0){ + seq->SetNumFrames(numFrames, false, compressHier); + } + if(strstr(seq->name, "L Toe")) + debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name + + for(l = 0; l < numFrames; l++){ + if(hasScale){ + RwStreamRead(stream, buf, 0x2C); + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + CVector trans(fbuf[4], fbuf[5], fbuf[6]); - for(l = 0; l < numFrames; l++, kf++){ + if(compressHier){ + KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); + kf->SetRotation(rot); + kf->SetTranslation(trans); + // scaling ignored + kf->SetTime(fbuf[10]); // absolute time here + }else{ + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->translation = trans; + // scaling ignored + kf->deltaTime = fbuf[10]; // absolute time here + } + }else if(hasTranslation){ RwStreamRead(stream, buf, 0x20); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; - kf->deltaTime = fbuf[7]; // absolute time here - } - }else if(strncmp(info.ident, "KRTS", 4) == 0){ - seq->SetNumFrames(numFrames, true, false); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - if (strstr(seq->name, "L Toe")) - debug("anim %s has toe keyframes\n", hier->name); // , seq->name); + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + CVector trans(fbuf[4], fbuf[5], fbuf[6]); - for(l = 0; l < numFrames; l++, kf++){ - RwStreamRead(stream, buf, 0x2C); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; - // scaling ignored - kf->deltaTime = fbuf[10]; // absolute time here + if(compressHier){ + KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); + kf->SetRotation(rot); + kf->SetTranslation(trans); + kf->SetTime(fbuf[7]); // absolute time here + }else{ + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->translation = trans; + kf->deltaTime = fbuf[7]; // absolute time here + } + }else{ + RwStreamRead(stream, buf, 0x14); + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + + if(compressHier){ + KeyFrameCompressed *kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l); + kf->SetRotation(rot); + kf->SetTime(fbuf[4]); // absolute time here + }else{ + KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->deltaTime = fbuf[4]; // absolute time here + } } } } - hier->RemoveQuaternionFlips(); - hier->CalcTotalTime(); + if(!compressHier){ + hier->RemoveQuaternionFlips(); + hier->CalcTotalTime(); + } } if(animIndex > ms_numAnimations) ms_numAnimations = animIndex; diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h index a55577b1..213326b6 100644 --- a/src/animation/AnimManager.h +++ b/src/animation/AnimManager.h @@ -57,6 +57,7 @@ enum AssocGroupId ASSOCGRP_JOGWOMAN, ASSOCGRP_PANICCHUNKY, ASSOCGRP_SKATE, +#ifdef PC_PLAYER_CONTROLS ASSOCGRP_PLAYERBACK, ASSOCGRP_PLAYERLEFT, ASSOCGRP_PLAYERRIGHT, @@ -66,6 +67,7 @@ enum AssocGroupId ASSOCGRP_CHAINSAWBACK, ASSOCGRP_CHAINSAWLEFT, ASSOCGRP_CHAINSAWRIGHT, +#endif NUM_ANIM_ASSOC_GROUPS }; @@ -136,7 +138,7 @@ public: static CAnimBlendAssociation *BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId animId, float delta); static void LoadAnimFiles(void); static void LoadAnimFile(const char *filename); - static void LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] = nil); + static void LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32] = nil); static void CreateAnimAssocGroups(void); static void RemoveLastAnimFile(void); static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; } diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h index f2ef3dfd..cf8b9fe0 100644 --- a/src/animation/AnimationId.h +++ b/src/animation/AnimationId.h @@ -140,8 +140,8 @@ enum AnimationId ANIM_CAR_CLOSE_RHS, ANIM_CAR_HOOKERTALK, - ANIM_IDLE_STANCE2, - ANIM_IDLE_STANCE3, + ANIM_TRAIN_GETIN, + ANIM_TRAIN_GETOUT, ANIM_CAR_CRAWLOUT_RHS, ANIM_CAR_CRAWLOUT_RHS2, diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index 64951a87..633618b1 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -23,8 +23,6 @@ #include "Radar.h" #include "Pools.h" -//--MIAMI: file done - const struct { const char *szTrackName; int iTrackId; @@ -291,12 +289,15 @@ CCutsceneMgr::SetupCutsceneToStart(void) if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) { pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION); } else { - KeyFrameTrans* keyFrames; - if (pAnimBlendAssoc->hierarchy->IsCompressed()) - keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0)); - else - keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0)); - ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation); + if (pAnimBlendAssoc->hierarchy->IsCompressed()){ + KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0)); + CVector trans; + keyFrames->GetTranslation(&trans); + ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans); + }else{ + KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0)); + ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation); + } } pAnimBlendAssoc->SetRun(); } else { @@ -331,7 +332,7 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) } if (pNewAnim->hierarchy->IsCompressed()) - pNewAnim->hierarchy->compressed2 = true; + pNewAnim->hierarchy->keepCompressed = true; CStreaming::ImGonnaUseStreamingMemory(); pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName); @@ -344,8 +345,8 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject); pAnimBlendClumpData->link.Prepend(&pNewAnim->link); - if (pNewAnim->hierarchy->compressed2) - pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED; + if (pNewAnim->hierarchy->keepCompressed) + pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED; } void @@ -380,7 +381,7 @@ CCutsceneMgr::CreateCutsceneObject(int modelId) CCutsceneObject *pCutsceneObject; CStreaming::ImGonnaUseStreamingMemory(); - debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetName()); + debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetModelName()); if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) { pModelInfo = CModelInfo::GetModelInfo(modelId); pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01]; @@ -566,7 +567,7 @@ CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo) ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil; ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump()); - debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); + debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName()); } void @@ -575,9 +576,9 @@ CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const ch ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil; ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame; debug("Attach %s to component %s of %s\n", - CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), + CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(), frame, - CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); + CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName()); if (RwObjectGetType(pObject->m_rwObject) == rpCLUMP) { RpClump *clump = (RpClump*)pObject->m_rwObject; if (IsClumpSkinned(clump)) @@ -594,8 +595,8 @@ CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone) ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo; ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id]; debug("Attach %s to %s\n", - CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), - CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); + CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(), + CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName()); } void @@ -630,8 +631,8 @@ CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver() CStreaming::RemoveCurrentZonesModels(); CStreaming::SetModelIsDeletable(MI_MALE01); CStreaming::SetModelTxdIsDeletable(MI_MALE01); - CStreaming::SetModelIsDeletable(MI_HMOCA); - CStreaming::SetModelTxdIsDeletable(MI_HMOCA); + CStreaming::SetModelIsDeletable(MI_TAXI_D); + CStreaming::SetModelTxdIsDeletable(MI_TAXI_D); CStreaming::SetModelIsDeletable(MI_NIGHTSTICK); CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK); CStreaming::SetModelIsDeletable(MI_MISSILE); diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp index faeea709..d3094bb0 100644 --- a/src/animation/FrameUpdate.cpp +++ b/src/animation/FrameUpdate.cpp @@ -6,8 +6,6 @@ #include "AnimBlendAssociation.h" #include "RpAnimBlend.h" -//--MIAMI: file done - CAnimBlendClumpData *gpAnimBlendClump; // PS2 names without "NonSkinned" @@ -19,6 +17,9 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg); +void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg); +void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg); + void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg) { @@ -30,7 +31,7 @@ FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg) AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && - gpAnimBlendClump->velocity){ + gpAnimBlendClump->velocity2d){ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D) FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(frame, arg); else @@ -139,11 +140,11 @@ FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, v } if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - gpAnimBlendClump->velocity->x = transx - curx; - gpAnimBlendClump->velocity->y = transy - cury; + gpAnimBlendClump->velocity2d->x = transx - curx; + gpAnimBlendClump->velocity2d->y = transy - cury; if(looped){ - gpAnimBlendClump->velocity->x += endx; - gpAnimBlendClump->velocity->y += endy; + gpAnimBlendClump->velocity2d->x += endx; + gpAnimBlendClump->velocity2d->y += endy; } mat->pos.x = pos.x - transx; mat->pos.y = pos.y - transy; @@ -219,9 +220,9 @@ FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, } if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - *gpAnimBlendClump->velocity = trans - cur; + *gpAnimBlendClump->velocity3d = trans - cur; if(looped) - *gpAnimBlendClump->velocity += end; + *gpAnimBlendClump->velocity3d += end; mat->pos.x = (pos - trans).x + frame->resetPos.x; mat->pos.y = (pos - trans).y + frame->resetPos.y; mat->pos.z = (pos - trans).z + frame->resetPos.z; @@ -241,7 +242,7 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg) AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && - gpAnimBlendClump->velocity){ + gpAnimBlendClump->velocity2d){ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D) FrameUpdateCallBackWith3dVelocityExtractionSkinned(frame, arg); else @@ -351,11 +352,11 @@ FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void } if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - gpAnimBlendClump->velocity->x = transx - curx; - gpAnimBlendClump->velocity->y = transy - cury; + gpAnimBlendClump->velocity2d->x = transx - curx; + gpAnimBlendClump->velocity2d->y = transy - cury; if(looped){ - gpAnimBlendClump->velocity->x += endx; - gpAnimBlendClump->velocity->y += endy; + gpAnimBlendClump->velocity2d->x += endx; + gpAnimBlendClump->velocity2d->y += endy; } xform->t.x = pos.x - transx; xform->t.y = pos.y - transy; @@ -431,9 +432,9 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo } if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - *gpAnimBlendClump->velocity = trans - cur; + *gpAnimBlendClump->velocity3d = trans - cur; if(looped) - *gpAnimBlendClump->velocity += end; + *gpAnimBlendClump->velocity3d += end; xform->t.x = (pos - trans).x + frame->resetPos.x; xform->t.y = (pos - trans).y + frame->resetPos.y; xform->t.z = (pos - trans).z + frame->resetPos.z; @@ -443,6 +444,225 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg) { - if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity) + if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity2d) FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg); } + + +void +FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg) +{ + CVector vec, pos(0.0f, 0.0f, 0.0f); + CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); + float totalBlendAmount = 0.0f; + CVector trans(0.0f, 0.0f, 0.0f); + CVector cur(0.0f, 0.0f, 0.0f); + CVector end(0.0f, 0.0f, 0.0f); + bool looped = false; + RwMatrix *mat = RwFrameGetMatrix(frame->frame); + CAnimBlendNode **node; + AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; + + if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && + gpAnimBlendClump->velocity2d){ + if(updateData->foobar) + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->association->IsPartial()) + totalBlendAmount += (*node)->association->blendAmount; + + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->sequence->HasTranslation()){ + if((*node)->association->HasTranslation()){ + (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount); + cur += vec; + } + } + + for(node = updateData->nodes; *node; node++){ + if((*node)->sequence){ + bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); +#ifdef FIX_BUGS + if(DotProduct(rot, q) < 0.0f) + rot -= q; + else +#endif + rot += q; + if((*node)->sequence->HasTranslation()){ + pos += vec; + if((*node)->association->HasTranslation()){ + trans += vec; + looped |= nodelooped; + if(nodelooped){ + (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount); + end += vec; + } + } + } + } + ++*node; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ + RwMatrixSetIdentity(mat); + rot.Normalise(); + rot.Get(mat); + } + + if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ + *gpAnimBlendClump->velocity3d = trans - cur; + if(looped) + *gpAnimBlendClump->velocity3d += end; + mat->pos.x = (pos - trans).x + frame->resetPos.x; + mat->pos.y = (pos - trans).y + frame->resetPos.y; + mat->pos.z = (pos - trans).z + frame->resetPos.z; + } + RwMatrixUpdate(mat); + }else{ + if(updateData->foobar) + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->association->IsPartial()) + totalBlendAmount += (*node)->association->blendAmount; + + for(node = updateData->nodes; *node; node++){ + if((*node)->sequence){ + (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); + if((*node)->sequence->HasTranslation()) + pos += vec; +#ifdef FIX_BUGS + if(DotProduct(rot, q) < 0.0f) + rot -= q; + else +#endif + rot += q; + } + ++*node; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ + RwMatrixSetIdentity(mat); + rot.Normalise(); + rot.Get(mat); + } + + if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ + mat->pos.x = pos.x; + mat->pos.y = pos.y; + mat->pos.z = pos.z; + mat->pos.x += frame->resetPos.x; + mat->pos.y += frame->resetPos.y; + mat->pos.z += frame->resetPos.z; + } + RwMatrixUpdate(mat); + } +} + +void +FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg) +{ + CVector vec, pos(0.0f, 0.0f, 0.0f); + CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); + float totalBlendAmount = 0.0f; + CVector trans(0.0f, 0.0f, 0.0f); + CVector cur(0.0f, 0.0f, 0.0f); + CVector end(0.0f, 0.0f, 0.0f); + bool looped = false; + RpHAnimStdInterpFrame *xform = frame->hanimFrame; + CAnimBlendNode **node; + AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; + + if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && + gpAnimBlendClump->velocity2d){ + if(updateData->foobar) + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->association->IsPartial()) + totalBlendAmount += (*node)->association->blendAmount; + + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->sequence->HasTranslation()){ + if((*node)->association->HasTranslation()){ + (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount); + cur += vec; + } + } + + for(node = updateData->nodes; *node; node++){ + if((*node)->sequence){ + bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); +#ifdef FIX_BUGS + if(DotProduct(rot, q) < 0.0f) + rot -= q; + else +#endif + rot += q; + if((*node)->sequence->HasTranslation()){ + pos += vec; + if((*node)->association->HasTranslation()){ + trans += vec; + looped |= nodelooped; + if(nodelooped){ + (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount); + end += vec; + } + } + } + } + ++*node; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ + rot.Normalise(); + xform->q.imag.x = rot.x; + xform->q.imag.y = rot.y; + xform->q.imag.z = rot.z; + xform->q.real = rot.w; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ + *gpAnimBlendClump->velocity3d = trans - cur; + if(looped) + *gpAnimBlendClump->velocity3d += end; + xform->t.x = (pos - trans).x + frame->resetPos.x; + xform->t.y = (pos - trans).y + frame->resetPos.y; + xform->t.z = (pos - trans).z + frame->resetPos.z; + } + }else{ + float transBlendAmount = 0.0f; + + if(updateData->foobar) + for(node = updateData->nodes; *node; node++) + if((*node)->sequence && (*node)->association->IsPartial()) + totalBlendAmount += (*node)->association->blendAmount; + + for(node = updateData->nodes; *node; node++){ + if((*node)->sequence){ + (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); + if((*node)->sequence->HasTranslation()){ + pos += vec; + transBlendAmount += (*node)->association->blendAmount; + } + if(DotProduct(rot, q) < 0.0f) + rot -= q; + else + rot += q; + } + ++*node; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ + rot.Normalise(); + xform->q.imag.x = rot.x; + xform->q.imag.y = rot.y; + xform->q.imag.z = rot.z; + xform->q.real = rot.w; + } + + if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ + xform->t.x = transBlendAmount*pos.x; + xform->t.y = transBlendAmount*pos.y; + xform->t.z = transBlendAmount*pos.z; + xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x; + xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y; + xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z; + } + } +} diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp index e93615b7..9a11d8bb 100644 --- a/src/animation/RpAnimBlend.cpp +++ b/src/animation/RpAnimBlend.cpp @@ -8,11 +8,10 @@ #include "AnimBlendClumpData.h" #include "AnimBlendHierarchy.h" #include "AnimBlendAssociation.h" +#include "AnimManager.h" #include "RpAnimBlend.h" #include "PedModelInfo.h" -//--MIAMI: file done - RwInt32 ClumpOffset; enum @@ -436,13 +435,16 @@ RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateD CAnimBlendAssociation *a = (*node)->association; for(i = 0; i < numNodes; i++) if((frames[i].flag & AnimBlendFrameData::VELOCITY_EXTRACTION) == 0 || - gpAnimBlendClump->velocity == nil){ + gpAnimBlendClump->velocity2d == nil){ if((*node)[i].sequence) (*node)[i].FindKeyFrame(a->currentTime - a->timeStep); } } } +// TODO: +// CAnimBlendClumpData::LoadFramesIntoSPR +// CAnimBlendClumpData::ForAllFramesInSPR void RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender) { @@ -466,7 +468,7 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender) assoc = CAnimBlendAssociation::FromLink(link); if(assoc->UpdateBlend(timeDelta)){ if(assoc->hierarchy->sequences){ - //CAnimManager::UncompressAnimation(v6->hierarchy) + CAnimManager::UncompressAnimation(assoc->hierarchy); if(i < 11) updateData.nodes[i++] = assoc->GetNode(0); if(assoc->flags & ASSOC_MOVEMENT){ @@ -486,6 +488,14 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender) updateData.nodes[i] = nil; +#ifdef ANIM_COMPRESSION + if(clumpData->frames[0].flag & AnimBlendFrameData::COMPRESSED){ + if(IsClumpSkinned(clump)) + clumpData->ForAllFrames(FrameUpdateCallBackSkinnedCompressed, &updateData); + else + clumpData->ForAllFrames(FrameUpdateCallBackNonSkinnedCompressed, &updateData); + }else +#endif if(doRender){ if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES) RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames); diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h index d0f7a114..6e9e0f0f 100644 --- a/src/animation/RpAnimBlend.h +++ b/src/animation/RpAnimBlend.h @@ -43,3 +43,6 @@ extern CAnimBlendClumpData *gpAnimBlendClump; void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg); + +void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg); +void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg); diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp index 6ce7bbac..250cd18e 100644 --- a/src/audio/AudioCollision.cpp +++ b/src/audio/AudioCollision.cpp @@ -71,31 +71,33 @@ cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const case SURFACE_TARMAC: case SURFACE_PAVEMENT: case SURFACE_STEEP_CLIFF: - case SURFACE_TRANSPARENT_STONE: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break; + case SURFACE_TRANSPARENT_STONE: + case SURFACE_CONCRETE_BEACH: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break; case SURFACE_GRASS: + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; - case SURFACE_GRAVEL: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; - case SURFACE_MUD_DRY: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break; - case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; + case SURFACE_GLASS: + case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; case SURFACE_TRANSPARENT_CLOTH: case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break; case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break; case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break; case SURFACE_SCAFFOLD_POLE: - case SURFACE_METAL_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; + case SURFACE_METAL_GATE: case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break; case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break; - case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break; - case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; - case SURFACE_WATER: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; + case SURFACE_SAND: + case SURFACE_WATER: + case SURFACE_RUBBER: + case SURFACE_WHEELBASE: + case SURFACE_SAND_BEACH: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break; case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break; case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break; - case SURFACE_RUBBER: - case SURFACE_WHEELBASE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break; case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break; case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break; @@ -135,8 +137,8 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000; vol = 30.f * ratio; - } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || - surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) { + } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || surface2 == SURFACE_MUD_DRY || + surface1 == SURFACE_SAND || surface2 == SURFACE_SAND || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) { ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000; @@ -156,12 +158,12 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio void cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter) { + bool distCalculated = false; if(col.m_fIntensity2 > 0.0016f) { uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col); if(emittingVol) { - m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance); - m_sQueueSample.m_nVolume = - ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance); + CalculateDistance(distCalculated, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance); if(m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = counter; m_sQueueSample.m_vecPos = col.m_vecPosition; @@ -217,7 +219,9 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1, SFX_TYRE_BUMP, SFX_COL_CARDBOARD_1, SFX_COL_TARMAC_1, - SFX_COL_GATE}; + SFX_COL_GATE, + SFX_COL_SAND_1, + SFX_COL_TARMAC_1 }; void cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) @@ -266,7 +270,7 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4; break; case SFX_COL_PED_1: - m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5; + m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 2; break; case SFX_COL_WOOD_CRATES_1: m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4; diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 3f1f568a..c58daaaf 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -41,14 +41,14 @@ #include "WindModifiers.h" #include "Fluff.h" #include "Script.h" - +#include "Wanted.h" const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; const int allChannels = channels + 2; -enum PLAY_STATUS : uint8 { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; -enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; +enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; +enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; void cAudioManager::PreInitialiseGameSpecificSetup() const @@ -123,39 +123,39 @@ cAudioManager::PostInitialiseGameSpecificSetup() { m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager); if (m_nFireAudioEntity >= 0) - SetEntityStatus(m_nFireAudioEntity, 1); + SetEntityStatus(m_nFireAudioEntity, true); m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1); if (m_nCollisionEntity >= 0) - SetEntityStatus(m_nCollisionEntity, 1); + SetEntityStatus(m_nCollisionEntity, true); m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1); if (m_nFrontEndEntity >= 0) - SetEntityStatus(m_nFrontEndEntity, 1); + SetEntityStatus(m_nFrontEndEntity, true); m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1); if (m_nProjectileEntity >= 0) - SetEntityStatus(m_nProjectileEntity, 1); + SetEntityStatus(m_nProjectileEntity, true); m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1); if (m_nWaterCannonEntity >= 0) - SetEntityStatus(m_nWaterCannonEntity, 1); + SetEntityStatus(m_nWaterCannonEntity, true); m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1); if (m_nPoliceChannelEntity >= 0) - SetEntityStatus(m_nPoliceChannelEntity, 1); + SetEntityStatus(m_nPoliceChannelEntity, true); #ifdef GTA_BRIDGE m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1); if (m_nBridgeEntity >= 0) - SetEntityStatus(m_nBridgeEntity, 1); + SetEntityStatus(m_nBridgeEntity, true); #endif // GTA_BRIDGE m_nEscalatorEntity = CreateEntity(AUDIOTYPE_ESCALATOR, (void*)1); if (m_nEscalatorEntity >= 0) - SetEntityStatus(m_nEscalatorEntity, 1); + SetEntityStatus(m_nEscalatorEntity, true); m_nExtraSoundsEntity = CreateEntity(AUDIOTYPE_EXTRA_SOUNDS, (void*)1); if (m_nExtraSoundsEntity >= 0) - SetEntityStatus(m_nExtraSoundsEntity, 1); + SetEntityStatus(m_nExtraSoundsEntity, true); m_sMissionAudio.m_nSampleIndex[0] = NO_SAMPLE; @@ -261,7 +261,7 @@ cAudioManager::ProcessReverb() const if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) { for (uint32 i = 0; i < numChannels; i++) { if (m_asActiveSamples[i].m_bReverbFlag) - SampleManager.SetChannelReverbFlag(i, 1); + SampleManager.SetChannelReverbFlag(i, true); } } } @@ -277,10 +277,7 @@ void cAudioManager::CalculateDistance(bool &distCalculated, float dist) { if (!distCalculated) { - if (dist > 0.0f) - m_sQueueSample.m_fDistance = Sqrt(dist); - else - m_sQueueSample.m_fDistance = 0.0f; + m_sQueueSample.m_fDistance = Sqrt(dist); distCalculated = true; } } @@ -308,16 +305,15 @@ cAudioManager::ProcessPlayerMood() playerPed = FindPlayerPed(); if (playerPed != nil) { - if (playerPed->m_pWanted->m_nWantedLevel > 3) { + if (playerPed->m_pWanted->GetWantedLevel() > 3) { m_nPlayerMood = PLAYER_MOOD_ANGRY; return; } - if (playerPed->m_pWanted->m_nWantedLevel > 1) { + if (playerPed->m_pWanted->GetWantedLevel() > 1) { m_nPlayerMood = PLAYER_MOOD_PISSED_OFF; return; } - //lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime(); if (lastMissionPassedTime != -1) { if (curTime < lastMissionPassedTime) { lastMissionPassedTime = curTime; @@ -350,7 +346,7 @@ cAudioManager::ProcessSpecial() if (playerPed != nil) { if (playerPed->m_audioEntityId >= 0 && m_asAudioEntities[playerPed->m_audioEntityId].m_bIsUsed) { if (playerPed->EnteringCar()) { - if(!playerPed->bInVehicle&& CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == nil) + if(!playerPed->bInVehicle && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == nil) SampleManager.StopChannel(m_nActiveSamples); } } @@ -361,7 +357,7 @@ cAudioManager::ProcessSpecial() void cAudioManager::ProcessEntity(int32 id) { - if (m_asAudioEntities[id].m_nStatus != STATUS_PLAYER) { + if (m_asAudioEntities[id].m_bStatus) { m_sQueueSample.m_nEntityIndex = id; switch (m_asAudioEntities[id].m_nType) { case AUDIOTYPE_PHYSICAL: @@ -1403,7 +1399,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params) } else if (params.m_fVelocityChange == 0.0f) { traction = 0.9f; } - if (transmission->fMaxVelocity <= 0.0) { + if (transmission->fMaxVelocity <= 0.0f) { relativeChange = 0.0f; modificator = 0.0f; } else { @@ -1421,7 +1417,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params) } modificator = relativeChange; } else { - modificator = Min(1.0, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f)); + modificator = Min(1.0f, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f)); } } } else { @@ -1506,14 +1502,10 @@ cAudioManager::UpdateGasPedalAudio(CVehicle* veh, int vehType) float gasPedal = Abs(veh->m_fGasPedal); float* gasPealAudioPtr; - switch (vehType) { - case VEHICLE_TYPE_CAR: - gasPealAudioPtr = &((CAutomobile*)veh)->m_fGasPedalAudio; - case VEHICLE_TYPE_BIKE: - gasPealAudioPtr = &((CBike*)veh)->m_fGasPedalAudio; - default: - return; - break; + switch(vehType) { + case VEHICLE_TYPE_CAR: gasPealAudioPtr = &((CAutomobile *)veh)->m_fGasPedalAudio; break; + case VEHICLE_TYPE_BIKE: gasPealAudioPtr = &((CBike *)veh)->m_fGasPedalAudio; break; + default: return; } if (*gasPealAudioPtr < gasPedal) *gasPealAudioPtr = Min(*gasPealAudioPtr + 0.09f, gasPedal); @@ -1568,29 +1560,12 @@ cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sampl } void -cAudioManager::ProcessCesna(cVehicleParams& params) +cAudioManager::ProcessCesna(cVehicleParams ¶ms) { - static uint8 nAccel = 0; - - //((CAutomobile *)params.m_pVehicle)->Damage.GetEngineStatus(); - - if (FindPlayerVehicle() == params.m_pVehicle) { - if (params.m_nIndex == DODO) { - if (Pads[0].GetAccelerate() <= 0) { - if (nAccel != 0) - --nAccel; - } else if (nAccel < 60) { - ++nAccel; - } - AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_IDLE, SFX_BANK_0, 52, true); - AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, SFX_BANK_0, 2, true); - } - } else if (params.m_nIndex == DODO) { - AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, SFX_BANK_0, 52, true); - } else if (params.m_fDistance < SQR(200)) { + if(params.m_fDistance < SQR(200)) { CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); m_sQueueSample.m_nVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { + if(m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 52; m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE; m_sQueueSample.m_nBankIndex = SFX_BANK_0; @@ -1602,28 +1577,28 @@ cAudioManager::ProcessCesna(cVehicleParams& params) m_sQueueSample.m_nEmittingVolume = 80; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 8.0f; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; m_sQueueSample.m_fSoundIntensity = 200.0f; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bRequireReflection = false; AddSampleToRequestedQueue(); } - if (params.m_fDistance < SQR(90)) { + if(params.m_fDistance < SQR(90)) { m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { + if(m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 2; m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_nFrequency = 25000; m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_nEmittingVolume = 80; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 8.0f; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; m_sQueueSample.m_fSoundIntensity = 90.0f; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_bReverbFlag = true; @@ -2002,27 +1977,11 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh } } else { nCruising = 1; - params.m_pVehicle->bAudioChangingGear = true; - bAccelSampleStopped = true; - SampleManager.StopChannel(m_nActiveSamples); - if (isMoped || accelerateState >= 150 && wheelsOnGround && brakeState <= 0 && !params.m_pVehicle->bIsHandbrakeOn - && !lostTraction && currentGear >= params.m_pTransmission->nNumberOfGears - 1) { - if (accelerateState >= 220 && params.m_fVelocityChange + 0.001f >= velocityChangeForAudio) { - if (nCruising < 800) - ++nCruising; - } else if (nCruising > 3) { - --nCruising; - } - freq = 27 * nCruising + freqModifier + 22050; - if (engineSoundType == SFX_BANK_TRUCK) - freq /= 2; - AudioManager.AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true); - } else { - nCruising = 0; - } + goto PlayCruising; } } } else { +PlayCruising: bAccelSampleStopped = true; SampleManager.StopChannel(m_nActiveSamples); if (isMoped || accelerateState >= 150 && wheelsOnGround && brakeState <= 0 && !params.m_pVehicle->bIsHandbrakeOn @@ -2036,7 +1995,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh freq = 27 * nCruising + freqModifier + 22050; if (engineSoundType == SFX_BANK_TRUCK) freq /= 2; - AudioManager.AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true); + AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true); } else { nCruising = 0; } @@ -2232,7 +2191,6 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams& params) if (veh->m_modelIndex == MI_MRWHOOP) return true; - veh->m_nAlarmState; if (veh->IsAlarmOn()) return true; @@ -2614,12 +2572,8 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) bool noReflections; bool isHeli; float maxDist; - cPedParams pedParams; static uint8 GunIndex = 53; - pedParams.m_pPed = nil; - pedParams.m_bDistanceCalculated = false; - pedParams.m_fDistance = 0.0f; for (int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { noReflections = false; isHeli = false; @@ -3010,21 +2964,58 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) isHeli = true; break; default: + { maxDist = SQR(SOUND_INTENSITY); +#ifdef FIX_BUGS + int32 sampleIndex; + int32 frequency; + CPed *pPed = params.m_pVehicle->pDriver; + if(!pPed->HasWeaponSlot(WEAPONSLOT_SUBMACHINEGUN)) { + sampleIndex = SFX_UZI_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + } else + switch(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) { + case WEAPONTYPE_TEC9: + sampleIndex = SFX_TEC_LEFT; + frequency = RandomDisplacement(500) + 17000; + break; + case WEAPONTYPE_SILENCED_INGRAM: + sampleIndex = SFX_TEC_LEFT; + frequency = RandomDisplacement(1000) + 34000; + break; + case WEAPONTYPE_MP5: + sampleIndex = SFX_MP5_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + break; + default: + sampleIndex = SFX_UZI_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + break; + } + m_sQueueSample.m_nSampleIndex = sampleIndex; +#else m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; +#endif m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = GunIndex++; emittingVol = m_anRandomTable[2] % 15 + 65; - if (GunIndex > 58) - GunIndex = 53; + if(GunIndex > 58) GunIndex = 53; +#ifdef FIX_BUGS + m_sQueueSample.m_nFrequency = frequency; +#else m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); +#endif m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bRequireReflection = true; break; } + } break; } case SOUND_WEAPON_HIT_VEHICLE: { @@ -3059,6 +3050,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) break; } case SOUND_PED_HELI_PLAYER_FOUND: { + cPedParams pedParams; pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; pedParams.m_fDistance = params.m_fDistance; SetupPedComments(pedParams, SOUND_PED_HELI_PLAYER_FOUND); @@ -3073,9 +3065,11 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT); continue; */ case SOUND_PED_VCPA_PLAYER_FOUND: { + cPedParams pedParams; pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; pedParams.m_fDistance = params.m_fDistance; SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND); + continue; } case SOUND_WATER_FALL: { const float SOUND_INTENSITY = 40.0f; @@ -3161,7 +3155,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) m_sQueueSample.m_nCounter = GunIndex++; if (GunIndex > 58) GunIndex = 53; - m_sQueueSample.m_bRequireReflection = 0; + m_sQueueSample.m_bRequireReflection = false; AddSampleToRequestedQueue(); continue; #endif @@ -3193,7 +3187,7 @@ AddSample: #ifdef GTA_TRAIN bool -cAudioManager::ProcessTrainNoise(cVehicleParams *params) +cAudioManager::ProcessTrainNoise(cVehicleParams& params) { const float SOUND_INTENSITY = 300.0f; @@ -3201,12 +3195,12 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) uint8 emittingVol; float speedMultipler; - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) return false; - if (params->m_fVelocityChange > 0.0f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - train = (CTrain *)params->m_pVehicle; + if (params.m_fVelocityChange > 0.0f) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + train = (CTrain *)params.m_pVehicle; speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f); emittingVol = (75.f * speedMultipler); if (train->m_fWagonPosition == 0.0f) { @@ -3232,7 +3226,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) } } const float SOUND_INTENSITY = 70.0f; - if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + if (params.m_fDistance < SQR(SOUND_INTENSITY)) { m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 33; @@ -3263,25 +3257,128 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params) { CBoat *boat; float padRelativeAccerate; - float gasPedal; - int32 padAccelerate; - uint8 emittingVol; - float oneShotVol; - static uint16 LastAccel = 0; - static uint8 LastVol = 0; + bool isV12 = false; + static int32 LastFreq = 2000; + static int8 LastVol = 0; - static const int intensity = 50; + static const float intensity = 90.0f; if (params.m_fDistance < SQR(intensity)) { boat = (CBoat *)params.m_pVehicle; - if (params.m_nIndex == REEFER) { + if(boat->GetStatus() == STATUS_WRECKED) + return true; + + float freqModificator; + float volModificator; + int BaseVol; + int BaseFreq; + + switch(boat->GetModelIndex()) { + case MI_RIO: + freqModificator = 490.0f; + volModificator = 60.0f; + BaseVol = 20; + BaseFreq = 1888; + break; + case MI_PREDATOR: + case MI_SQUALO: + case MI_SPEEDER: + case MI_COASTG: + case MI_DINGHY: + case MI_JETMAX: + freqModificator = 6000.0f; + volModificator = 60.0f; + isV12 = true; + BaseFreq = 9000; + BaseVol = 20; + break; + case MI_REEFER: + freqModificator = 715.0f; + volModificator = 80.0f; + BaseVol = 0; + BaseFreq = 3775; + break; + case MI_TROPIC: + case MI_MARQUIS: + freqModificator = 463.0f; + volModificator = 60.0f; + BaseVol = 20; + BaseFreq = 1782; + break; + default: + return true; + } + + bool bIsPlayerVeh; + + if(FindPlayerVehicle() == params.m_pVehicle) { + float padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake()); + padRelativeAccerate = padAccelerate / 255.0f; + bIsPlayerVeh = true; + } else { + padRelativeAccerate = Max(params.m_pVehicle->m_fGasPedal, params.m_pVehicle->m_fBrakePedal); + bIsPlayerVeh = false; + } + + int Freq = BaseFreq + (padRelativeAccerate * freqModificator); + int Vol = BaseVol + (padRelativeAccerate * volModificator); + + if(!boat->bPropellerInWater) + Freq = (9 * Freq) / 8; + + if(bIsPlayerVeh) { + if(Freq > LastFreq) { + if(isV12) + Freq = Min(Freq, LastFreq + 100); + else + Freq = Min(Freq, LastFreq + 15); + } else { + if(isV12) + Freq = Max(Freq, LastFreq - 100); + else + Freq = Max(Freq, LastFreq - 15); + } + if(Vol > LastVol) + Vol = Min(Vol, LastVol + 3); + else + Vol = Max(Vol, LastVol - 3); + } + + if (Vol > 0) { CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(Vol, intensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nFrequency = Freq; + m_sQueueSample.m_nCounter = 40; + if (isV12) + m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP; + else + m_sQueueSample.m_nSampleIndex = SFX_BOAT_CRUISER_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = Vol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + if(boat->GetModelIndex() == MI_REEFER) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, intensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nFrequency = 6000; m_sQueueSample.m_nCounter = 39; m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - m_sQueueSample.m_nFrequency = 10386; m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_bIs2D = false; @@ -3298,102 +3395,11 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params) m_sQueueSample.m_bRequireReflection = false; AddSampleToRequestedQueue(); } - if (FindPlayerVehicle() == params.m_pVehicle) { - padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake()); - padRelativeAccerate = padAccelerate / 255; - emittingVol = (100.f * padRelativeAccerate) + 15; - m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - } else { - gasPedal = Abs(boat->m_fGasPedal); - if (gasPedal > 0.0f) { - m_sQueueSample.m_nFrequency = 6000; - emittingVol = 15; - } else { - emittingVol = (100.f * gasPedal) + 15; - m_sQueueSample.m_nFrequency = (3000.f * gasPedal) + 6000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - } - } - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); - if (!m_sQueueSample.m_nVolume) - return true; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - } else { - if (FindPlayerVehicle() == params.m_pVehicle) { - padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake()); - if (padAccelerate <= 20) { - emittingVol = 45 - 45 * padAccelerate / 40; - m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025; - m_sQueueSample.m_nCounter = 39; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - if (LastAccel > 20) { - oneShotVol = LastVol; - PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_BOAT_SLOWDOWN, oneShotVol); - } - } else { - emittingVol = 105 * padAccelerate / 255 + 15; - m_sQueueSample.m_nFrequency = 4000 * padAccelerate / 255 + 8000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - } - LastVol = emittingVol; - LastAccel = padAccelerate; - } else { - gasPedal = Abs(boat->m_fGasPedal); - if (gasPedal > 0.0f) { - m_sQueueSample.m_nFrequency = 11025; - emittingVol = 45; - m_sQueueSample.m_nCounter = 39; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - } else { - emittingVol = (105.f * gasPedal) + 15; - m_sQueueSample.m_nFrequency = (4000.f * gasPedal) + 8000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - } - } - CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); - if (!m_sQueueSample.m_nVolume) - return true; - m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; } - AddSampleToRequestedQueue(); + if(bIsPlayerVeh) { + LastFreq = Freq; + LastVol = Vol; + } return true; } return false; @@ -3432,7 +3438,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params) m_sQueueSample.m_fSpeedMultiplier = 2.0f; m_sQueueSample.m_fSoundIntensity = 50.0f; m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 6; m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bRequireReflection = false; AddSampleToRequestedQueue(); @@ -3630,7 +3636,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params) //after accel rotor sound emittingVol = ((cameraAngle + 1.0f) * volumeModifier * 127.0f) / 2.0f; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 1; if (hunterBool) { @@ -3677,7 +3683,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params) if (automobile->bEngineOn) { if (propellerSpeed < 1.0f) { emittingVol = (1.0f - propellerSpeed / 2.0f) * 70.0f; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.0, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.0f, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { if (hunterBool) { m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_4; @@ -3718,7 +3724,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params) m_sQueueSample.m_nFrequency = 18000 + Min(1.0f, (Max(accelerateState, brakeState) / 255.0f) * freqModifier) * 2204; else m_sQueueSample.m_nFrequency = 14287 + Min(1.0f, freqModifier) * 3713; - if (propellerSpeed < 1.0) + if (propellerSpeed < 1.0f) m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2.0f); m_sQueueSample.m_nFrequency = clamp2(m_sQueueSample.m_nFrequency, freqSkimmerPrev, 197); freqSkimmerPrev = m_sQueueSample.m_nFrequency; @@ -3761,7 +3767,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params) m_sQueueSample.m_nCounter = 2; m_sQueueSample.m_nSampleIndex = hunterBool ? SFX_HELI_APACHE_3 : SFX_CAR_HELI_REA; m_sQueueSample.m_nBankIndex = 0; - m_sQueueSample.m_bIs2D = 0; + m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_nReleasingVolumeModificator = 1; m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000; m_sQueueSample.m_nLoopCount = 0; @@ -3880,8 +3886,8 @@ cAudioManager::ProcessJumbo(cVehicleParams& params) CPlane *plane; float position; - //if (params.m_fDistance >= SQR(440)) - // return; + if (params.m_fDistance >= SQR(440)) + return; CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); plane = (CPlane*)params.m_pVehicle; @@ -4083,27 +4089,27 @@ bool cAudioManager::SetupJumboFlySound(uint8 emittingVol) { const float SOUND_INTENSITY = 440.0f; - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; + if(m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); m_sQueueSample.m_nVolume = vol; - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; + if(m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_nReleasingVolumeDivider = 5; - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; // todo port fix to re3 AddSampleToRequestedQueue(); } return true; @@ -4149,7 +4155,7 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) int32 cAudioManager::GetJumboTaxiFreq() const { - return (60.833f * m_sQueueSample.m_fDistance) + 22050; + return (1.f / 180 * 10950 * m_sQueueSample.m_fDistance) + 22050; // todo port fix to re3 } #pragma endregion Some jumbo crap @@ -4162,13 +4168,9 @@ cAudioManager::ProcessPed(CPhysical *ped) { cPedParams params; - params.m_pPed = nil; - params.m_bDistanceCalculated = false; - params.m_fDistance = 0.0f; - m_sQueueSample.m_vecPos = ped->GetPosition(); - //params.m_bDistanceCalculated = false; + params.m_bDistanceCalculated = false; params.m_pPed = (CPed *)ped; params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); ProcessPedOneShots(params); @@ -4200,109 +4202,109 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) switch (sound) { case SOUND_STEP_START: case SOUND_STEP_END: - if (!params.m_pPed->bIsLooking) { - emittingVol = m_anRandomTable[3] % 15 + 45; - if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) - emittingVol /= 2; - maxDist = 400.f; - switch (params.m_pPed->m_nSurfaceTouched) { - case SURFACE_GRASS: - sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; - break; - case SURFACE_GRAVEL: - case SURFACE_MUD_DRY: - sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; - break; - case SURFACE_CAR: - case SURFACE_GARAGE_DOOR: - case SURFACE_CAR_PANEL: - case SURFACE_THICK_METAL_PLATE: - case SURFACE_SCAFFOLD_POLE: - case SURFACE_LAMP_POST: - case SURFACE_FIRE_HYDRANT: - case SURFACE_GIRDER: - case SURFACE_METAL_CHAIN_FENCE: - case SURFACE_CONTAINER: - case SURFACE_NEWS_VENDOR: - sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; - break; - case SURFACE_SAND: - sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; - break; - case SURFACE_WATER: - sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - break; - case SURFACE_WOOD_CRATES: - case SURFACE_WOOD_BENCH: - case SURFACE_WOOD_SOLID: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; - break; - case SURFACE_HEDGE: - sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; - break; - default: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; - break; - } - m_sQueueSample.m_nSampleIndex = sampleIndex; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 32; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - switch (params.m_pPed->m_nMoveState) { - case PEDMOVE_WALK: - emittingVol /= 4; - m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_RUN: - emittingVol /= 2; - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_SPRINT: - m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; - break; - default: - break; - } - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; + if (params.m_pPed->bIsInTheAir) + continue; + emittingVol = m_anRandomTable[3] % 15 + 45; + if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) + emittingVol /= 2; + maxDist = 400.f; + switch (params.m_pPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; + break; + case SURFACE_CAR: + case SURFACE_GARAGE_DOOR: + case SURFACE_CAR_PANEL: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_SCAFFOLD_POLE: + case SURFACE_LAMP_POST: + case SURFACE_FIRE_HYDRANT: + case SURFACE_GIRDER: + case SURFACE_METAL_CHAIN_FENCE: + case SURFACE_CONTAINER: + case SURFACE_NEWS_VENDOR: + sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; + break; + case SURFACE_SAND: + sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; + break; + case SURFACE_WATER: + sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + break; + case SURFACE_WOOD_CRATES: + case SURFACE_WOOD_BENCH: + case SURFACE_WOOD_SOLID: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; + break; + case SURFACE_HEDGE: + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; + break; + default: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; + break; } + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - SOUND_STEP_START + 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + switch (params.m_pPed->m_nMoveState) { + case PEDMOVE_WALK: + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_RUN: + emittingVol /= 2; + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_SPRINT: + m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; + break; + default: + break; + } + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; break; case SOUND_FALL_LAND: case SOUND_FALL_COLLAPSE: - if (!ped->bIsLooking) { - maxDist = SQR(30); - emittingVol = m_anRandomTable[3] % 20 + 80; - if (ped->m_nSurfaceTouched == SURFACE_WATER) { - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - } else if (sound == SOUND_FALL_LAND) { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; - } else { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; - } - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; + if (ped->bIsInTheAir) + continue; + maxDist = SQR(30); + emittingVol = m_anRandomTable[3] % 20 + 80; + if (ped->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + } else if (sound == SOUND_FALL_LAND) { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; + } else { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; break; case SOUND_FIGHT_37: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; @@ -4341,6 +4343,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nFrequency = 20000; goto AddFightSound; case SOUND_FIGHT_46: + case SOUND_187: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; m_sQueueSample.m_nFrequency = 18000; goto AddFightSound; @@ -4353,7 +4356,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nFrequency = 20000; AddFightSound: { - uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float uint8 damagerType = soundParams & 0xFF; uint32 weaponType = soundParams >> 8; @@ -4401,7 +4404,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) case SOUND_WEAPON_BAT_ATTACK: case SOUND_WEAPON_KNIFE_ATTACK: { - uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float uint8 damagerType = soundParams & 0xFF; uint32 weaponType = soundParams >> 8; if (damagerType == ENTITY_TYPE_PED) { @@ -4455,14 +4458,12 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_bRequireReflection = true; break; } - // TODO: breaks the game right now, probably needs AudioManager.cpp to be done first - /* case SOUND_WEAPON_CHAINSAW_ATTACK: if (FindVehicleOfPlayer()) continue; m_sQueueSample.m_nSampleIndex = SFX_CAR_ACCEL_13; m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW - m_sQueueSample.m_nCounter = 64; + m_sQueueSample.m_nCounter = 70; m_sQueueSample.m_nFrequency = 27000; m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 3.0f; @@ -4474,7 +4475,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_ACCEL_13); m_sQueueSample.m_nEmittingVolume = 100; m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 5; break; case SOUND_WEAPON_CHAINSAW_IDLE: @@ -4491,7 +4492,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nLoopCount = 0; emittingVol = 100; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_AFTER_ACCEL_13); m_sQueueSample.m_nEmittingVolume = 100; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = false; @@ -4513,13 +4514,12 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nLoopCount = 0; emittingVol = 100; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_AFTER_ACCEL_13); m_sQueueSample.m_nEmittingVolume = 100; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 5; break; - */ case SOUND_WEAPON_SHOT_FIRED: weapon = ped->GetWeapon(); if (!weapon) @@ -5042,7 +5042,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) uint8 param1 = soundParams & 0xFF; uint32 param2 = soundParams >> 8; m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 1) + SFX_SKATE_1; - m_sQueueSample.m_nBankIndex = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound; stereo = true; ++iSound; @@ -5118,7 +5118,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_bRequireReflection = true; break; case SOUND_SHIRT_WIND_FLAP: - if (params.m_pPed->IsPlayer()) { + if (params.m_pPed->IsPlayer() && params.m_pPed->m_pMyVehicle) { if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 0.0f) { if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 1.0f) m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1.0f; @@ -5161,7 +5161,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nReleasingVolumeDivider = 3; } } - break; + continue; default: SetupPedComments(params, sound); continue; @@ -5449,7 +5449,7 @@ cAudioManager::GetPlayerTalkSfx(CPed *ped, int16 sound) { uint32 sfx; - if(this->m_bIsPlayerShutUp) return NO_SAMPLE; + if(m_bIsPlayerShutUp) return NO_SAMPLE; switch(sound) { case SOUND_PED_DEATH: return 9796; case SOUND_PED_DAMAGE: @@ -5678,7 +5678,7 @@ cAudioManager::GetCopTalkSfx(CPed *ped, int16 sound) case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8494, 4); break; case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8491, 3); break; case SOUND_PED_PED_COLLISION: - if(FindPlayerPed()->m_pWanted->m_nWantedLevel <= 0) return NO_SAMPLE; + if(FindPlayerPed()->m_pWanted->GetWantedLevel() <= 0) return NO_SAMPLE; GetPhrase(sfx, ped->m_lastComment, 8476, 5); break; default: return GetGenericMaleTalkSfx(ped, sound); @@ -7960,7 +7960,7 @@ cAudioManager::ProcessExplosions(int32 explosion) m_sQueueSample.m_vecPos = *CExplosion::GetExplosionPosition(i); distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared); + m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = i; @@ -8025,7 +8025,7 @@ cAudioManager::ProcessFires(int32) m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos; distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = distSquared < 0.0f ? 0.0f : Sqrt(distSquared); + m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = i; @@ -8081,7 +8081,7 @@ cAudioManager::ProcessWaterCannon(int32) m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distSquared < SQR(SOUND_INTENSITY)) { - m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared); + m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; @@ -8122,10 +8122,7 @@ cAudioManager::ProcessExtraSounds() m_sQueueSample.m_vecPos = aVecExtraSoundPosition[i]; distance = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distance < SQR(SOUND_INTENSITY)) { - if (distance > 0.0f) - m_sQueueSample.m_fDistance = Sqrt(distance); - else - m_sQueueSample.m_fDistance = 0.0f; + m_sQueueSample.m_fDistance = Sqrt(distance); m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = i; @@ -8164,10 +8161,7 @@ cAudioManager::ProcessEscalators() m_sQueueSample.m_vecPos = CEscalators::GetEscalator(i).GetPosition(); distance = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distance < SQR(SOUND_INTENSITY)) { - if (distance > 0.0f) - m_sQueueSample.m_fDistance = Sqrt(distance); - else - m_sQueueSample.m_fDistance = 0.0f; + m_sQueueSample.m_fDistance = Sqrt(distance); m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP; @@ -8218,41 +8212,34 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) uint8 emittingVolume; float distSquared; - cPedParams male; - cPedParams female; - static uint8 iSound = 0; switch (sound) { - /*case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S: - case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L: - male.m_pPed = nil; - male.m_bDistanceCalculated = false; - male.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - SetupPedComments(&male, SOUND_INJURED_PED_MALE_OUCH); - return; - case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S: - case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L: - female.m_pPed = nil; - female.m_bDistanceCalculated = false; - female.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - SetupPedComments(&female, SOUND_INJURED_PED_FEMALE); - return; - case SCRIPT_SOUND_GATE_START_CLUNK: - case SCRIPT_SOUND_GATE_STOP_CLUNK: + case SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK: m_sQueueSample.m_fSoundIntensity = 40.0f; m_sQueueSample.m_nSampleIndex = SFX_COL_GATE; m_sQueueSample.m_nBankIndex = SFX_BANK_0; - if (sound == SCRIPT_SOUND_GATE_START_CLUNK) - m_sQueueSample.m_nFrequency = 10600; - else - m_sQueueSample.m_nFrequency = 9000; - m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = 10600; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + emittingVolume = 60; m_sQueueSample.m_fSpeedMultiplier = 0.0f; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bRequireReflection = true; - emittingVolume = RandomDisplacement(10) + 50; - break;*/ + break; + case SCRIPT_SOUND_GARAGE_DOOR_CLUNK: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; // huh? + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 22000; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 4; + emittingVolume = 60; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + break; + case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT: case SCRIPT_SOUND_BULLET_HIT_GROUND_1: case SCRIPT_SOUND_BULLET_HIT_GROUND_2: case SCRIPT_SOUND_BULLET_HIT_GROUND_3: @@ -8266,20 +8253,42 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) m_sQueueSample.m_bIs2D = false; emittingVolume = m_anRandomTable[2] % 20 + 90; break; - /* - case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1: - case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2: - if (!SampleManager.IsSampleBankLoaded(SAMPLEBANK_TRAIN)) - return; - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_TRAIN; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE); - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + case SCRIPT_SOUND_WILLIE_CARD_SWIPE: + emittingVolume = 70; + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 20159; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 1.0f; m_sQueueSample.m_bIs2D = false; - break;*/ + m_sQueueSample.m_bRequireReflection = false; + break; + case SCRIPT_SOUND_MALE_AMBULANCE_OUCH: + { + cPedParams pedParams; + pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(pedParams, SOUND_INJURED_PED_MALE_OUCH); + return; + } + case SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH: + { + cPedParams pedParams; + pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(pedParams, SOUND_INJURED_PED_FEMALE); + return; + } + case SCRIPT_SOUND_SEAPLANE_LOW_FUEL: + m_sQueueSample.m_fSoundIntensity = 1000.0f; + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_LOW; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 100; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_HORN_JEEP); // BUG? + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_bRequireReflection = false; + break; case SCRIPT_SOUND_PAYPHONE_RINGING: m_sQueueSample.m_fSoundIntensity = 80.0f; m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING; @@ -8378,6 +8387,18 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) m_sQueueSample.m_bRequireReflection = true; emittingVolume = m_anRandomTable[2] % 30 + 60; break; + case SCRIPT_SOUND_HIT_BALL: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_HIT_BALL; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 60; + break; case SCRIPT_SOUND_GUNSHELL_DROP: playerPed = FindPlayerPed(); if (playerPed) { @@ -8390,39 +8411,24 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) case SURFACE_SAND: case SURFACE_RUBBER: case SURFACE_HEDGE: + case SURFACE_SAND_BEACH: m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; - m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; + m_sQueueSample.m_nFrequency = RandomDisplacement(600) + 10600; m_sQueueSample.m_nReleasingVolumeModificator = 18; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = m_anRandomTable[2] % 20 + 30; - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = iSound++; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - AddSampleToRequestedQueue(); - } - } - return; + break; case SURFACE_WATER: return; default: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000; + m_sQueueSample.m_nReleasingVolumeModificator = 15; break; } + } else { + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000; + m_sQueueSample.m_nReleasingVolumeModificator = 15; } - m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; - m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000; - m_sQueueSample.m_nReleasingVolumeModificator = 15; m_sQueueSample.m_fSoundIntensity = 20.0f; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_fSpeedMultiplier = 0.0f; @@ -8466,116 +8472,204 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound) uint8 emittingVolume; float distSquared; - switch (sound) { - /*case SCRIPT_SOUND_PARTY_1_LOOP_S: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; + switch(sound) { + case SCRIPT_SOUND_BANK_ALARM_LOOP: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_BUILDINGS_BANK_ALARM; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDINGS_BANK_ALARM); + m_sQueueSample.m_nReleasingVolumeModificator = 2; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_1_LOOP_L: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); + case SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP: + case SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GARAGE_DOOR_LOOP); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_2_LOOP_S: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_2; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; + case SCRIPT_SOUND_SNORING_LOOP: + m_sQueueSample.m_fSoundIntensity = 6.0f; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_SNORE; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SNORING; + emittingVolume = 25; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDING_SNORE); + m_sQueueSample.m_nReleasingVolumeModificator = 6; m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_2_LOOP_L: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_2; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; + case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP: + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 60; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TANK_TURRET); + m_sQueueSample.m_nReleasingVolumeModificator = 4; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_3_LOOP_S: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_3; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); + case SCRIPT_SOUND_NEW_BUILDING_BAR_1: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_1; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_3_LOOP_L: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_3; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); + case SCRIPT_SOUND_NEW_BUILDING_BAR_2: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_2; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_4_LOOP_S: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_4; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); + case SCRIPT_SOUND_NEW_BUILDING_BAR_3: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_3; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_4_LOOP_L: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_4; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); + case SCRIPT_SOUND_NEW_BUILDING_BAR_4: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_4; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_4; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PARTY_1_LOOP: - m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1; - emittingVolume = MAX_VOLUME; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_1; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_1); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; break; - case SCRIPT_SOUND_PRETEND_FIRE_LOOP: - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_2; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_2); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_3; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_3); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_1: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_1; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_1); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_2: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_2; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_2); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_3: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_3; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_3); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_CHURCH: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_CHURCH; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CHURCH; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_WATERFALL: + emittingVolume = 30; + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; m_sQueueSample.m_nBankIndex = SFX_BANK_0; - emittingVolume = 80; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); - m_sQueueSample.m_nReleasingVolumeModificator = 8; - m_sQueueSample.m_nReleasingVolumeDivider = 10; + m_sQueueSample.m_nFrequency = 20812; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nReleasingVolumeDivider = 9; m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break;*/ - default: - return; + m_sQueueSample.m_bIs2D = false; + break; + default: return; } distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { + if(m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 0; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_nLoopCount = 0; @@ -8657,7 +8751,7 @@ cAudioManager::ProcessWeather(int32 id) modifier = Max(Abs(x), Abs(y)) * 10.0f; modifier = Min(1.0f, modifier); wind = Max(CWeather::Wind, modifier); - if (wind > 0.0f && CObject::fDistToNearestTree < 75.0) { + if (wind > 0.0f && CObject::fDistToNearestTree < 75.0f) { m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PALM_TREE_LO); m_sQueueSample.m_nVolume = (m_anRandomTable[1] % 10 + 45.0f) * (75.0f - CObject::fDistToNearestTree) * (4.0f / 300.0f) * wind; @@ -8728,6 +8822,8 @@ cAudioManager::ProcessFrontEnd() case SOUND_GARAGE_BOMB1_SET: case SOUND_GARAGE_BOMB2_SET: case SOUND_GARAGE_BOMB3_SET: + case SOUND_PICKUP_WEAPON_BOUGHT: + case SOUND_PICKUP_WEAPON: center = true; processedPickup = true; m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT; @@ -8995,7 +9091,7 @@ cAudioManager::ProcessProjectiles() m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition(); distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared); + m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = i; @@ -9020,7 +9116,7 @@ cAudioManager::ProcessGarages() const float SOUND_INTENSITY = 80.0f; CEntity *entity; - eGarageState state; + uint8 state; uint32 sampleIndex; uint8 j; float distSquared; @@ -9144,7 +9240,7 @@ cAudioManager::ProcessFireHydrant() const float SOUND_INTENSITY = 35; float distSquared; - bool distCalculated = 0; + bool distCalculated = false; m_sQueueSample.m_vecPos = ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition(); distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); @@ -9828,7 +9924,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) nCheckPlayingDelay[slot] = 0; nFramesUntilFailedLoad[slot] = 0; } else if (!m_nUserPause) { - if (++nFramesForPretendPlaying[slot] < 120) { + if (++nFramesForPretendPlaying[slot] < 90) { m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING; } else { m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED; @@ -9844,7 +9940,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) } else { if (m_nUserPause) SampleManager.PauseStream(1, slot + 1); - if (m_sMissionAudio.m_bPredefinedProperties) { + if (m_sMissionAudio.m_bPredefinedProperties[slot]) { if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL) SampleManager.SetStreamedVolumeAndPan(80, 0, 1, slot + 1); else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAR) @@ -9898,7 +9994,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) else { SampleManager.PauseStream(0, slot + 1); - if (!m_sMissionAudio.m_bPredefinedProperties) { + if (!m_sMissionAudio.m_bPredefinedProperties[slot]) { distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]); if (distSquared >= SQR(80.0f)) { emittingVol = 0; @@ -9941,7 +10037,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) } break; case LOADING_STATUS_FAILED: - if (++nFramesUntilFailedLoad[slot] >= 90) { + if (++nFramesUntilFailedLoad[slot] >= 120) { nFramesForPretendPlaying[slot] = 0; g_bMissionAudioLoadFailed[slot] = true; nFramesUntilFailedLoad[slot] = 0; diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index fbfdb855..721a7acc 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -10,6 +10,7 @@ #include "sampman.h" #include "Camera.h" #include "World.h" +#include "ZoneCull.h" cAudioManager AudioManager; @@ -17,12 +18,16 @@ const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; const int allChannels = channels + 2; +#define SPEED_OF_SOUND 343.f +#define TIME_SPENT 40 + cAudioManager::cAudioManager() { m_bIsInitialised = false; - field_1 = 1; - m_fSpeedOfSound = 6.86f; - m_nTimeSpent = 50; + m_bReverb = true; + field_6 = 0; + m_fSpeedOfSound = SPEED_OF_SOUND / TIME_SPENT; + m_nTimeSpent = TIME_SPENT; m_nActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS; m_nActiveSampleQueue = 1; ClearRequestedQueue(); @@ -128,7 +133,7 @@ cAudioManager::CreateEntity(eAudioType type, void *entity) for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { if (!m_asAudioEntities[i].m_bIsUsed) { m_asAudioEntities[i].m_bIsUsed = true; - m_asAudioEntities[i].m_nStatus = 0; + m_asAudioEntities[i].m_bStatus = false; m_asAudioEntities[i].m_nType = type; m_asAudioEntities[i].m_pEntity = entity; m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_NO_SOUND; @@ -163,7 +168,7 @@ void cAudioManager::SetEntityStatus(int32 id, uint8 status) { if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) - m_asAudioEntities[id].m_nStatus = status; + m_asAudioEntities[id].m_bStatus = status; } void @@ -426,7 +431,8 @@ cAudioManager::CheckForAnAudioFileOnCD() const uint8 cAudioManager::GetCDAudioDriveLetter() const { - return SampleManager.GetCDAudioDriveLetter(); + if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter(); + return 0; } bool @@ -456,7 +462,7 @@ cAudioManager::ServiceSoundEffects() ClearActiveSamples(); } m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1; - ProcessReverb(); + if(m_bReverb) ProcessReverb(); ProcessSpecial(); ClearRequestedQueue(); InterrogateAudioEntities(); @@ -584,7 +590,7 @@ cAudioManager::AddSampleToRequestedQueue() } m_sQueueSample.m_nCalculatedVolume = calculatedVolume; m_sQueueSample.m_bLoopEnded = false; - if (m_sQueueSample.m_bIs2D) { + if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) { m_sQueueSample.m_bRequireReflection = false; m_sQueueSample.m_nLoopsRemaining = 0; } @@ -596,6 +602,9 @@ cAudioManager::AddSampleToRequestedQueue() } m_sQueueSample.m_bRequireReflection = false; + if ( m_bReverb && m_sQueueSample.m_bIs2D ) + m_sQueueSample.field_4C = 30; + if (!m_bDynamicAcousticModelingStatus) m_sQueueSample.m_bReverbFlag = false; @@ -642,9 +651,9 @@ cAudioManager::AddReflectionsToRequestedQueue() emittingVolume = m_sQueueSample.m_nVolume; oldFreq = m_sQueueSample.m_nFrequency; } else { - emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 16); + emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16; } - m_sQueueSample.m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity / 2.f; + m_sQueueSample.m_fSoundIntensity /= 2.f; int halfOldFreq = oldFreq >> 1; @@ -802,7 +811,7 @@ cAudioManager::AddReleasingSounds() if (sample.m_nReleasingVolumeModificator < 20) ++sample.m_nReleasingVolumeModificator; } - sample.m_bReleasingSoundFlag = 0; + sample.m_bReleasingSoundFlag = false; } memcpy(&m_sQueueSample, &sample, sizeof(tSound)); AddSampleToRequestedQueue(); diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 2e0af437..376a7f60 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -49,7 +49,7 @@ public: eAudioType m_nType; void *m_pEntity; bool m_bIsUsed; - uint8 m_nStatus; + uint8 m_bStatus; int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS]; float m_afVolume[NUM_AUDIOENTITY_EVENTS]; uint8 m_AudioEvents; @@ -144,21 +144,39 @@ public: bool m_bDistanceCalculated; float m_fDistance; CPed *m_pPed; + + cPedParams() + { + m_bDistanceCalculated = false; + m_fDistance = 0.0f; + m_pPed = nil; + } }; class cVehicleParams { public: - eVehicleType m_VehicleType; + int32 m_VehicleType; bool m_bDistanceCalculated; float m_fDistance; CVehicle *m_pVehicle; cTransmission *m_pTransmission; int32 m_nIndex; float m_fVelocityChange; + + cVehicleParams() + { + m_VehicleType = -1; + m_bDistanceCalculated = false; + m_fDistance = 0.0f; + m_pVehicle = nil; + m_pTransmission = nil; + m_nIndex = 0; + m_fVelocityChange = 0.0f; + } }; -VALIDATE_SIZE(cVehicleParams, 0x18); +VALIDATE_SIZE(cVehicleParams, 0x1C); enum { REFLECTION_NORTH = 0, @@ -176,7 +194,7 @@ class cAudioManager { public: bool m_bIsInitialised; - uint8 field_1; // unused + uint8 m_bReverb; // unused bool m_bFifthFrameFlag; uint8 m_nActiveSamples; uint8 field_4; // unused @@ -256,8 +274,8 @@ public: uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; // done int32 CreateEntity(eAudioType type, void *entity); // done - void DestroyAllGameCreatedEntities(); // done ? I don't seed pEntity = nil; - void DestroyEntity(int32 id); // done (inlined in vc) ? I not seen id checks + void DestroyAllGameCreatedEntities(); // done + void DestroyEntity(int32 id); // done (inlined in vc) void DoPoliceRadioCrackle(); // done // functions returning talk sfx, @@ -359,38 +377,39 @@ public: uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc) // end of functions returning talk sfx - void GenerateIntegerRandomNumberTable(); // done - char *Get3DProviderName(uint8 id) const; - uint8 GetCDAudioDriveLetter() const; - int8 GetCurrent3DProviderIndex() const; - int8 AutoDetect3DProviders() const; // done - float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used - float GetCollisionOneShotRatio(int32 a, float b) const; - float GetCollisionRatio(float a, float b, float c, float d) const; - float GetDistanceSquared(const CVector &v) const; // done (inlined in vc) - int32 GetJumboTaxiFreq() const; - uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done - int8 GetMissionScriptPoliceAudioPlayingStatus() const; - uint8 GetNum3DProvidersAvailable() const; // done - uint32 GetPedCommentSfx(CPed *ped, int32 sound); - void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; - float GetVehicleDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, float gasPedalAudio, cTransmission* transmission, float velocityChange); // done - float GetVehicleNonDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, cTransmission* transmission, float velocityChange); // done + void GenerateIntegerRandomNumberTable(); // done + char *Get3DProviderName(uint8 id) const; // done + uint8 GetCDAudioDriveLetter() const; // done + int8 GetCurrent3DProviderIndex() const; // done + int8 AutoDetect3DProviders() const; // done + float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used + float GetCollisionOneShotRatio(int32 a, float b) const; // done + float GetCollisionRatio(float a, float b, float c, float d) const; // done (inlined in vc) + float GetDistanceSquared(const CVector &v) const; // done (inlined in vc) + int32 GetJumboTaxiFreq() const; // done (inlined in vc) + uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done + int8 GetMissionScriptPoliceAudioPlayingStatus() const; // done + uint8 GetNum3DProvidersAvailable() const; // done + uint32 GetPedCommentSfx(CPed *ped, int32 sound); // done + void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; // done + float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, + float velocityChange); // done + float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange); // done bool HasAirBrakes(int32 model) const; // done - void Initialise(); // done - void InitialisePoliceRadio(); //done - void InitialisePoliceRadioZones(); //done - void InterrogateAudioEntities(); // done - bool IsAudioInitialised() const; // done + void Initialise(); // done + void InitialisePoliceRadio(); // done + void InitialisePoliceRadioZones(); // done + void InterrogateAudioEntities(); // done (inlined) + bool IsAudioInitialised() const; // done bool IsMissionAudioSampleFinished(uint8 slot); // done - bool IsMP3RadioChannelAvailable() const; // done + bool IsMP3RadioChannelAvailable() const; // done bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done void PlayLoadedMissionAudio(uint8 slot); // done - void PlayOneShot(int32 index, uint16 sound, float vol); // done + void PlayOneShot(int32 index, uint16 sound, float vol); // done void PlaySuspectLastSeen(float x, float y, float z); // done void PlayerJustGotInCar() const; // done void PlayerJustLeftCar() const; // done @@ -403,7 +422,7 @@ public: void ProcessActiveQueues(); // done bool ProcessAirBrakes(cVehicleParams& params); // done bool ProcessBoatEngine(cVehicleParams& params); - bool ProcessBoatMovingOverWater(cVehicleParams& params); + bool ProcessBoatMovingOverWater(cVehicleParams& params); //done #ifdef GTA_BRIDGE void ProcessBridge(); // done(bcs not exists in VC) void ProcessBridgeMotor(); // done(bcs not exists in VC) @@ -412,7 +431,7 @@ public: #endif bool ProcessCarBombTick(cVehicleParams& params); // done void ProcessCarHeli(cVehicleParams& params); // done - void ProcessCesna(cVehicleParams& params); // + void ProcessCesna(cVehicleParams& params); // done //void ProcessCrane(); // done(bcs not exists in VC) bool ProcessEngineDamage(cVehicleParams& params); // done void ProcessEntity(int32 sound); // done @@ -420,7 +439,7 @@ public: void ProcessFireHydrant(); // done void ProcessFires(int32 entity); // done void ProcessFrontEnd(); // done - void ProcessGarages(); // + void ProcessGarages(); // done void ProcessJumbo(cVehicleParams& params); // done void ProcessJumboAccel(CPlane *plane); // done void ProcessJumboDecel(CPlane *plane); // done @@ -428,9 +447,9 @@ public: void ProcessJumboLanding(CPlane *plane); // done void ProcessJumboTakeOff(CPlane *plane); // done void ProcessJumboTaxi(); // done - void ProcessLoopingScriptObject(uint8 sound); // - void ProcessMissionAudio(); // - void ProcessMissionAudioSlot(uint8 slot); // + void ProcessLoopingScriptObject(uint8 sound); // done + void ProcessMissionAudio(); // done + void ProcessMissionAudioSlot(uint8 slot); // done void ProcessModelHeliVehicle(cVehicleParams& params); // done void ProcessModelVehicle(cVehicleParams& params); // done void ProcessOneShotScriptObject(uint8 sound); // @@ -450,15 +469,15 @@ public: bool ProcessTrainNoise(cVehicleParams *params); //done(bcs not exists in VC) #endif void ProcessVehicle(CVehicle *vehicle); // done - bool ProcessVehicleDoors(cVehicleParams& params); // done - void ProcessVehicleEngine(cVehicleParams& params); // done - void ProcessVehicleFlatTyre(cVehicleParams& params); // done - bool ProcessVehicleHorn(cVehicleParams& params); // done - void ProcessVehicleOneShots(cVehicleParams& params); // done - bool ProcessVehicleReverseWarning(cVehicleParams& params); // done - bool ProcessVehicleRoadNoise(cVehicleParams& params); // done - bool ProcessVehicleSirenOrAlarm(cVehicleParams& params); // done - bool ProcessVehicleSkidding(cVehicleParams& params); // done + bool ProcessVehicleDoors(cVehicleParams ¶ms); // done + void ProcessVehicleEngine(cVehicleParams ¶ms); // done + void ProcessVehicleFlatTyre(cVehicleParams ¶ms); // done + bool ProcessVehicleHorn(cVehicleParams ¶ms); // done + void ProcessVehicleOneShots(cVehicleParams ¶ms); // done + bool ProcessVehicleReverseWarning(cVehicleParams ¶ms); // done + bool ProcessVehicleRoadNoise(cVehicleParams ¶ms); // done + bool ProcessVehicleSirenOrAlarm(cVehicleParams ¶ms); // done + bool ProcessVehicleSkidding(cVehicleParams ¶ms); // done void ProcessWaterCannon(int32); // done void ProcessWeather(int32 id); // done bool ProcessWetRoadNoise(cVehicleParams& params); // done @@ -474,52 +493,54 @@ public: void ResetPoliceRadio(); // done void ResetTimers(uint32 time); // done - void Service(); //done - void ServiceCollisions(); //done - void ServicePoliceRadio(); - void ServicePoliceRadioChannel(uint8 wantedLevel); - void ServiceSoundEffects(); - int8 SetCurrent3DProvider(uint8 which); - void SetDynamicAcousticModelingStatus(uint8 status); - void SetEffectsFadeVol(uint8 volume) const; - void SetEffectsMasterVolume(uint8 volume) const; - void SetMP3BoostVolume(uint8 volume) const; - void SetEntityStatus(int32 id, uint8 status); //done - uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); - void SetMissionAudioLocation(uint8 slot, float x, float y, float z); - void SetMissionScriptPoliceAudio(int32 sfx) const; - void SetMonoMode(uint8 mono); - void SetMusicFadeVol(uint8 volume) const; - void SetMusicMasterVolume(uint8 volume) const; - void SetSpeakerConfig(int32 conf) const; - void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); - void SetUpOneShotCollisionSound(const cAudioCollision &col); - bool SetupCrimeReport(); - bool SetupJumboEngineSound(uint8 vol, uint32 freq); - bool SetupJumboFlySound(uint8 emittingVol); - bool SetupJumboRumbleSound(uint8 emittingVol); - bool SetupJumboTaxiSound(uint8 vol); - bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); - void SetupPedComments(cPedParams ¶ms, uint16 sound); // done + void Service(); // done + void ServiceCollisions(); // done + void ServicePoliceRadio(); // done + void ServicePoliceRadioChannel(uint8 wantedLevel); // done + void ServiceSoundEffects(); // done + int8 SetCurrent3DProvider(uint8 which); // done + void SetDynamicAcousticModelingStatus(uint8 status); // done + void SetEffectsFadeVol(uint8 volume) const; // done + void SetEffectsMasterVolume(uint8 volume) const; // done + void SetMP3BoostVolume(uint8 volume) const; // done + void SetEntityStatus(int32 id, uint8 status); // done + uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); // done + void SetMissionAudioLocation(uint8 slot, float x, float y, float z); // done + void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized + void SetMonoMode(uint8 mono); // done + void SetMusicFadeVol(uint8 volume) const; // done + void SetMusicMasterVolume(uint8 volume) const; // done + void SetSpeakerConfig(int32 conf) const; // done + void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); // done + void SetUpOneShotCollisionSound(const cAudioCollision &col); // done + bool SetupCrimeReport(); // done + bool SetupJumboEngineSound(uint8 vol, uint32 freq); // done + bool SetupJumboFlySound(uint8 emittingVol); // done + bool SetupJumboRumbleSound(uint8 emittingVol); // done + bool SetupJumboTaxiSound(uint8 vol); // done + bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); // done + void SetupPedComments(cPedParams ¶ms, uint16 sound); // done void SetupSuspectLastSeenReport(); - void Terminate(); //done - void TranslateEntity(Const CVector *v1, CVector *v2) const; //done + void Terminate(); // done + void TranslateEntity(Const CVector *v1, CVector *v2) const; // done + + void UpdateGasPedalAudio(CVehicle *veh, int vehType); // done + void UpdateReflections(); // done + bool UsesReverseWarning(int32 model) const; // done + bool UsesSiren(cVehicleParams ¶ms) const; // done + bool UsesSirenSwitching(cVehicleParams ¶ms) const; // done - void UpdateGasPedalAudio(CVehicle* veh, int vehType); // done - void UpdateReflections(); //done - bool UsesReverseWarning(int32 model) const; //done - bool UsesSiren(cVehicleParams& params) const; //done - bool UsesSirenSwitching(cVehicleParams& params) const; //done + CVehicle *FindVehicleOfPlayer(); // done + void SetPedTalkingStatus(CPed *ped, uint8 status); // done + void SetPlayersMood(uint8 mood, uint32 time); // done - CVehicle *FindVehicleOfPlayer(); //done - void SetPedTalkingStatus(CPed *ped, uint8 status); - void SetPlayersMood(uint8 mood, uint32 time); + float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); } #ifdef GTA_PC // only used in pc - void AdjustSamplesVolume(); - uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); + void AdjustSamplesVolume(); // done (inlined) + uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // done (inlined) #endif }; diff --git a/src/audio/AudioSamples.h b/src/audio/AudioSamples.h index 703431a5..a68cf768 100644 --- a/src/audio/AudioSamples.h +++ b/src/audio/AudioSamples.h @@ -2,7 +2,8 @@ #include "common.h" -enum eSfxSample : uint32 { +enum eSfxSample +{ SFX_CAR_HORN_JEEP = 0, SFX_CAR_HORN_BMW328, SFX_CAR_HORN_BUS, diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 8aedf306..acfe09c3 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -25,7 +25,7 @@ cMusicManager MusicManager; int32 gNumRetunePresses; int32 gRetuneCounter; bool g_bAnnouncementReadPosAlready; -uint8 RadioStaticCounter; +uint8 RadioStaticCounter = 5; uint32 RadioStaticTimer; CVector vecRiotPosition(300.7f, -322.0f, 12.0f); @@ -223,8 +223,8 @@ void cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos) { if (m_bIsInitialised) { - if (station == USERTRACK) - station = RADIO_OFF; + if (station == STREAMED_SOUND_RADIO_MP3_PLAYER) + station = STREAMED_SOUND_CITY_AMBIENT; if (station <= STREAMED_SOUND_RADIO_POLICE) { m_bRadioSetByScript = true; m_nRadioStation = station; @@ -435,7 +435,7 @@ cMusicManager::ServiceFrontEndMode() else { if (m_nCurrentVolume < m_nMaxVolume) m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); - SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63u, 0, 0); + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); } } else { if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER) @@ -512,7 +512,7 @@ cMusicManager::ServiceGameMode() gRetuneCounter = 0; field_2 = false; } else if (ped) { - if (ped->m_objective != OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN && ped->m_objective != OBJ_55) { + if(!ped->DyingOrDead()) { #ifdef GTA_PC if (SampleManager.IsMP3RadioChannelAvailable() && vehicle->m_nRadioStation < USERTRACK @@ -564,8 +564,8 @@ cMusicManager::ServiceGameMode() gRetuneCounter = 0; return; } - if (m_nAnnouncement == NO_TRACK) - { + if(m_nAnnouncement == NO_TRACK) { + m_nStreamedTrack = NO_TRACK; m_nFrontendTrack = GetCarTuning(); field_2 = false; gRetuneCounter = 0; @@ -991,6 +991,7 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped) } } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) { SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 0); + nFramesSinceCutsceneEnded = 0; } else { if (nFramesSinceCutsceneEnded == -1) volume = m_nCurrentVolume; diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp index 781040d6..e174e587 100644 --- a/src/audio/PoliceRadio.cpp +++ b/src/audio/PoliceRadio.cpp @@ -13,6 +13,7 @@ #include "World.h" #include "Zones.h" #include "sampman.h" +#include "Wanted.h" const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; @@ -67,7 +68,7 @@ cAudioManager::InitialisePoliceRadio() for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE; - SampleManager.SetChannelReverbFlag(policeChannel, 0); + SampleManager.SetChannelReverbFlag(policeChannel, false); gSpecialSuspectLastSeenReport = false; for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++) gMinTimeToNextReport[i] = m_FrameCounter; @@ -136,7 +137,7 @@ cAudioManager::ServicePoliceRadio() #endif CPlayerPed *playerPed = FindPlayerPed(); if (playerPed) { - wantedLevel = playerPed->m_pWanted->m_nWantedLevel; + wantedLevel = playerPed->m_pWanted->GetWantedLevel(); if (!crimeReport) { if (wantedLevel != 0) { if (nLastSeen != 0) @@ -653,7 +654,7 @@ void cAudioManager::ReportCrime(eCrimeType type, const CVector &pos) { int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes); - if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && + if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && (type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) { for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) { if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) { diff --git a/src/audio/PoliceRadio.h b/src/audio/PoliceRadio.h index e9a0fde0..d7c928e2 100644 --- a/src/audio/PoliceRadio.h +++ b/src/audio/PoliceRadio.h @@ -1,6 +1,6 @@ #pragma once -#include "Wanted.h" +#include "Crime.h" struct cAMCrime { int32 type; diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h index 65094555..91fcec49 100644 --- a/src/audio/audio_enums.h +++ b/src/audio/audio_enums.h @@ -1274,7 +1274,7 @@ enum AudioEntityHandle { AEHANDLE_ERROR_BADAUDIOTYPE = -1, }; -enum eAudioType : int32 +enum eAudioType { AUDIOTYPE_PHYSICAL = 0, AUDIOTYPE_EXPLOSION, diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp index e16de572..e4cb0b77 100644 --- a/src/audio/oal/oal_utils.cpp +++ b/src/audio/oal/oal_utils.cpp @@ -3,6 +3,14 @@ #ifdef AUDIO_OAL +/* + * When linking to a static openal-soft library, + * the extension function inside the openal library conflict with the variables here. + * Therefore declare these re3 owned symbols in a private namespace. + */ + +namespace re3_openal { + LPALGENEFFECTS alGenEffects; LPALDELETEEFFECTS alDeleteEffects; LPALISEFFECT alIsEffect; @@ -37,6 +45,9 @@ LPALGETFILTERIV alGetFilteriv; LPALGETFILTERF alGetFilterf; LPALGETFILTERFV alGetFilterfv; +} + +using namespace re3_openal; void EFXInit() { diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h index b89ccf36..f0fa090a 100644 --- a/src/audio/oal/oal_utils.h +++ b/src/audio/oal/oal_utils.h @@ -11,6 +11,8 @@ void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); void EAX3_SetReverbMix(ALuint filter, float mix); void SetEffectsLevel(ALuint uiFilter, float level); +namespace re3_openal { + extern LPALGENEFFECTS alGenEffects; extern LPALDELETEEFFECTS alDeleteEffects; extern LPALISEFFECT alIsEffect; @@ -44,4 +46,9 @@ extern LPALGETFILTERI alGetFilteri; extern LPALGETFILTERIV alGetFilteriv; extern LPALGETFILTERF alGetFilterf; extern LPALGETFILTERFV alGetFilterfv; + +} + +using namespace re3_openal; + #endif diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index 06a38c29..19fa4ec4 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -4,20 +4,395 @@ #include "stream.h" #include "sampman.h" -#ifdef AUDIO_OPUS -#include <opusfile.h> -#else -#ifdef _WIN32 +#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK +#ifdef AUDIO_OAL_USE_SNDFILE #pragma comment( lib, "libsndfile-1.lib" ) +#endif +#ifdef AUDIO_OAL_USE_MPG123 #pragma comment( lib, "libmpg123-0.lib" ) -#else -#include "crossplatform.h" #endif +#endif +#ifdef AUDIO_OAL_USE_SNDFILE #include <sndfile.h> +#endif +#ifdef AUDIO_OAL_USE_MPG123 #include <mpg123.h> #endif +#ifdef AUDIO_OAL_USE_OPUS +#include <opusfile.h> +#endif + +#ifndef _WIN32 +#include "crossplatform.h" +#endif + +/* +As we ran onto an issue of having different volume levels for mono streams +and stereo streams we are now handling all the stereo panning ourselves. +Each stream now has two sources - one panned to the left and one to the right, +and uses two separate buffers to store data for each individual channel. +For that we also have to reshuffle all decoded PCM stereo data from LRLRLRLR to +LLLLRRRR (handled by CSortStereoBuffer). +*/ + +class CSortStereoBuffer +{ + uint16* PcmBuf; + size_t BufSize; +public: + CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {} + ~CSortStereoBuffer() + { + if (PcmBuf) + free(PcmBuf); + } + + uint16* GetBuffer(size_t size) + { + if (size == 0) return nil; + if (!PcmBuf) + { + BufSize = size; + PcmBuf = (uint16*)malloc(BufSize); + } + else if (BufSize < size) + { + BufSize = size; + PcmBuf = (uint16*)realloc(PcmBuf, size); + } + return PcmBuf; + } + + void SortStereo(void* buf, size_t size) + { + uint16* InBuf = (uint16*)buf; + uint16* OutBuf = GetBuffer(size); + + if (!OutBuf) return; + + size_t rightStart = size / 4; + for (size_t i = 0; i < size / 4; i++) + { + OutBuf[i] = InBuf[i*2]; + OutBuf[i+rightStart] = InBuf[i*2+1]; + } + + memcpy(InBuf, OutBuf, size); + } + +}; + +CSortStereoBuffer SortStereoBuffer; + +class CImaADPCMDecoder +{ + const uint16 StepTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 + }; + + int16 Sample, StepIndex; + +public: + CImaADPCMDecoder() + { + Init(0, 0); + } + + void Init(int16 _Sample, int16 _StepIndex) + { + Sample = _Sample; + StepIndex = _StepIndex; + } + + void Decode(uint8 *inbuf, int16 *_outbuf, size_t size) + { + int16* outbuf = _outbuf; + for (size_t i = 0; i < size; i++) + { + *(outbuf++) = DecodeSample(inbuf[i] & 0xF); + *(outbuf++) = DecodeSample(inbuf[i] >> 4); + } + } + + int16 DecodeSample(uint8 adpcm) + { + uint16 step = StepTable[StepIndex]; + + if (adpcm & 4) + StepIndex += ((adpcm & 3) + 1) * 2; + else + StepIndex--; + + StepIndex = clamp(StepIndex, 0, 88); + + int delta = step >> 3; + if (adpcm & 1) delta += step >> 2; + if (adpcm & 2) delta += step >> 1; + if (adpcm & 4) delta += step; + if (adpcm & 8) delta = -delta; + + int newSample = Sample + delta; + Sample = clamp(newSample, -32768, 32767); + return Sample; + } +}; + +class CWavFile : public IDecoder +{ + enum + { + WAVEFMT_PCM = 1, + WAVEFMT_IMA_ADPCM = 0x11, + WAVEFMT_XBOX_ADPCM = 0x69, + }; + + struct tDataHeader + { + uint32 ID; + uint32 Size; + }; + + struct tFormatHeader + { + uint16 AudioFormat; + uint16 NumChannels; + uint32 SampleRate; + uint32 ByteRate; + uint16 BlockAlign; + uint16 BitsPerSample; + uint16 extra[2]; // adpcm only + + tFormatHeader() { memset(this, 0, sizeof(*this)); } + }; + + FILE *m_pFile; + bool m_bIsOpen; + + tFormatHeader m_FormatHeader; + + uint32 m_DataStartOffset; // TODO: 64 bit? + uint32 m_nSampleCount; + uint32 m_nSamplesPerBlock; + + // ADPCM things + uint8 *m_pAdpcmBuffer; + int16 **m_ppPcmBuffers; + CImaADPCMDecoder *m_pAdpcmDecoders; -#ifndef AUDIO_OPUS + void Close() + { + if (m_pFile) { + fclose(m_pFile); + m_pFile = nil; + } + delete[] m_pAdpcmBuffer; + delete[] m_ppPcmBuffers; + delete[] m_pAdpcmDecoders; + } + + uint32 GetCurrentSample() const + { + // TODO: 64 bit? + uint32 FilePos = ftell(m_pFile); + if (FilePos <= m_DataStartOffset) + return 0; + return (FilePos - m_DataStartOffset) / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + } + +public: + CWavFile(const char* path) : m_bIsOpen(false), m_DataStartOffset(0), m_nSampleCount(0), m_nSamplesPerBlock(0), m_pAdpcmBuffer(nil), m_ppPcmBuffers(nil), m_pAdpcmDecoders(nil) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + +#define CLOSE_ON_ERROR(op)\ + if (op) { \ + Close(); \ + return; \ + } + + tDataHeader DataHeader; + + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != 'FFIR'); + + // TODO? validate filesizes + + int WAVE; + CLOSE_ON_ERROR(fread(&WAVE, 4, 1, m_pFile) == 0); + CLOSE_ON_ERROR(WAVE != 'EVAW') + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != ' tmf'); + + CLOSE_ON_ERROR(fread(&m_FormatHeader, Min(DataHeader.Size, sizeof(tFormatHeader)), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.Size > sizeof(tFormatHeader)); + + switch (m_FormatHeader.AudioFormat) + { + case WAVEFMT_XBOX_ADPCM: + m_FormatHeader.AudioFormat = WAVEFMT_IMA_ADPCM; + case WAVEFMT_IMA_ADPCM: + m_nSamplesPerBlock = (m_FormatHeader.BlockAlign / m_FormatHeader.NumChannels - 4) * 2 + 1; + m_pAdpcmBuffer = new uint8[m_FormatHeader.BlockAlign]; + m_ppPcmBuffers = new int16*[m_FormatHeader.NumChannels]; + m_pAdpcmDecoders = new CImaADPCMDecoder[m_FormatHeader.NumChannels]; + break; + case WAVEFMT_PCM: + m_nSamplesPerBlock = 1; + if (m_FormatHeader.BitsPerSample != 16) + { + debug("Unsupported PCM (%d bits), only signed 16-bit is supported (%s)\n", m_FormatHeader.BitsPerSample, path); + Close(); + return; + } + break; + default: + debug("Unsupported wav format 0x%x (%s)\n", m_FormatHeader.AudioFormat, path); + Close(); + return; + } + + while (true) { + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + if (DataHeader.ID == 'atad') + break; + fseek(m_pFile, DataHeader.Size, SEEK_CUR); + // TODO? validate data size + // maybe check if there no extreme custom headers that might break this + } + + m_DataStartOffset = ftell(m_pFile); + m_nSampleCount = DataHeader.Size / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + + m_bIsOpen = true; +#undef CLOSE_ON_ERROR + } + + ~CWavFile() + { + Close(); + } + + bool IsOpened() + { + return m_bIsOpen; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + return m_nSampleCount; + } + + uint32 GetSampleRate() + { + return m_FormatHeader.SampleRate; + } + + uint32 GetChannels() + { + return m_FormatHeader.NumChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + fseek(m_pFile, m_DataStartOffset + ms2samples(milliseconds) / m_nSamplesPerBlock * m_FormatHeader.BlockAlign, SEEK_SET); + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + return samples2ms(GetCurrentSample()); + } + +#define SAMPLES_IN_LINE (8) + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_FormatHeader.AudioFormat == WAVEFMT_PCM) + { + // just read the file and sort the samples + uint32 size = fread(buffer, 1, GetBufferSize(), m_pFile); + if (m_FormatHeader.NumChannels == 2) + SortStereoBuffer.SortStereo(buffer, size); + return size; + } + else if (m_FormatHeader.AudioFormat == WAVEFMT_IMA_ADPCM) + { + // trim the buffer size if we're at the end of our file + uint32 nMaxSamples = GetBufferSamples() / m_FormatHeader.NumChannels; + uint32 nSamplesLeft = m_nSampleCount - GetCurrentSample(); + nMaxSamples = Min(nMaxSamples, nSamplesLeft); + + // align sample count to our block + nMaxSamples = nMaxSamples / m_nSamplesPerBlock * m_nSamplesPerBlock; + + // count the size of output buffer + uint32 OutBufSizePerChannel = nMaxSamples * GetSampleSize(); + uint32 OutBufSize = OutBufSizePerChannel * m_FormatHeader.NumChannels; + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + OutBufSizePerChannel * i); + + uint32 samplesRead = 0; + while (samplesRead < nMaxSamples) + { + // read the file + uint8 *pAdpcmBuf = m_pAdpcmBuffer; + if (fread(m_pAdpcmBuffer, 1, m_FormatHeader.BlockAlign, m_pFile) == 0) + return 0; + + // get the first sample in adpcm block and initialise the decoder(s) + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + int16 Sample = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + int16 Step = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + m_pAdpcmDecoders[i].Init(Sample, Step); + *(m_ppPcmBuffers[i]) = Sample; + m_ppPcmBuffers[i]++; + } + samplesRead++; + + // decode the rest of the block + for (uint32 s = 1; s < m_nSamplesPerBlock; s += SAMPLES_IN_LINE) + { + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + m_pAdpcmDecoders[i].Decode(pAdpcmBuf, m_ppPcmBuffers[i], SAMPLES_IN_LINE / 2); + pAdpcmBuf += SAMPLES_IN_LINE / 2; + m_ppPcmBuffers[i] += SAMPLES_IN_LINE; + } + samplesRead += SAMPLES_IN_LINE; + } + } + return OutBufSize; + } + return 0; + } +}; + +#ifdef AUDIO_OAL_USE_SNDFILE class CSndFile : public IDecoder { SNDFILE *m_pfSound; @@ -79,9 +454,18 @@ public: uint32 Decode(void *buffer) { if ( !IsOpened() ) return 0; - return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize(); + + size_t size = sf_read_short(m_pfSound, (short*)buffer, GetBufferSamples()) * GetSampleSize(); + if (GetChannels()==2) + SortStereoBuffer.SortStereo(buffer, size); + return size; } }; +#endif + +#ifdef AUDIO_OAL_USE_MPG123 +// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though) +#define MP3_USE_FUZZY_SEEK class CMP3File : public IDecoder { @@ -106,6 +490,9 @@ public: m_pMH = mpg123_new(nil, nil); if ( m_pMH ) { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0); +#endif long rate = 0; int channels = 0; int encoding = 0; @@ -181,10 +568,299 @@ public: assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX)); #endif if (err != MPG123_OK && err != MPG123_DONE) return 0; + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size); return (uint32)size; } }; -#else + +class CADFFile : public CMP3File +{ + static ssize_t r_read(void* fh, void* buf, size_t size) + { + size_t bytesRead = fread(buf, 1, size, (FILE*)fh); + uint8* _buf = (uint8*)buf; + for (size_t i = 0; i < size; i++) + _buf[i] ^= 0x22; + return bytesRead; + } + static off_t r_seek(void* fh, off_t pos, int seekType) + { + fseek((FILE*)fh, pos, seekType); + return ftell((FILE*)fh); + } + static void r_close(void* fh) + { + fclose((FILE*)fh); + } +public: + CADFFile(const char* path) + { + m_pMH = mpg123_new(nil, nil); + if (m_pMH) + { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0); +#endif + long rate = 0; + int channels = 0; + int encoding = 0; + + FILE* f = fopen(path, "rb"); + + m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK + && mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; + m_nRate = rate; + m_nChannels = channels; + + if (IsOpened()) + { + mpg123_format_none(m_pMH); + mpg123_format(m_pMH, rate, channels, encoding); + } + } + } +}; + +#endif +#define VAG_LINE_SIZE (0x10) +#define VAG_SAMPLES_IN_LINE (28) + +class CVagDecoder +{ + const double f[5][2] = { { 0.0, 0.0 }, + { 60.0 / 64.0, 0.0 }, + { 115.0 / 64.0, -52.0 / 64.0 }, + { 98.0 / 64.0, -55.0 / 64.0 }, + { 122.0 / 64.0, -60.0 / 64.0 } }; + + double s_1; + double s_2; +public: + CVagDecoder() + { + ResetState(); + } + + void ResetState() + { + s_1 = s_2 = 0.0; + } + + static short quantize(double sample) + { + int a = int(sample + 0.5); + return short(clamp(a, -32768, 32767)); + } + + void Decode(void* _inbuf, int16* _outbuf, size_t size) + { + uint8* inbuf = (uint8*)_inbuf; + int16* outbuf = _outbuf; + size &= ~(VAG_LINE_SIZE - 1); + + while (size > 0) { + double samples[VAG_SAMPLES_IN_LINE]; + + int predict_nr, shift_factor, flags; + predict_nr = *(inbuf++); + shift_factor = predict_nr & 0xf; + predict_nr >>= 4; + flags = *(inbuf++); + if (flags == 7) // TODO: ignore? + break; + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i += 2) { + int d = *(inbuf++); + int16 s = int16((d & 0xf) << 12); + samples[i] = (double)(s >> shift_factor); + s = int16((d & 0xf0) << 8); + samples[i + 1] = (double)(s >> shift_factor); + } + + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i++) { + samples[i] = samples[i] + s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1]; + s_2 = s_1; + s_1 = samples[i]; + *(outbuf++) = quantize(samples[i] + 0.5); + } + size -= VAG_LINE_SIZE; + } + } +}; + +#define VB_BLOCK_SIZE (0x2000) +#define NUM_VAG_LINES_IN_BLOCK (VB_BLOCK_SIZE / VAG_LINE_SIZE) +#define NUM_VAG_SAMPLES_IN_BLOCK (NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE) + +class CVbFile : public IDecoder +{ + FILE *m_pFile; + CVagDecoder *m_pVagDecoders; + + size_t m_FileSize; + size_t m_nNumberOfBlocks; + + uint32 m_nSampleRate; + uint8 m_nChannels; + bool m_bBlockRead; + uint16 m_LineInBlock; + size_t m_CurrentBlock; + + uint8 **m_ppVagBuffers; // buffers that cache actual ADPCM file data + int16 **m_ppPcmBuffers; + + void ReadBlock(int32 block = -1) + { + // just read next block if -1 + if (block != -1) + fseek(m_pFile, block * m_nChannels * VB_BLOCK_SIZE, SEEK_SET); + + for (int i = 0; i < m_nChannels; i++) + fread(m_ppVagBuffers[i], VB_BLOCK_SIZE, 1, m_pFile); + m_bBlockRead = true; + } + +public: + CVbFile(const char* path, uint32 nSampleRate = 32000, uint8 nChannels = 2) : m_nSampleRate(nSampleRate), m_nChannels(nChannels), m_pVagDecoders(nil), m_ppVagBuffers(nil), m_ppPcmBuffers(nil), + m_FileSize(0), m_nNumberOfBlocks(0), m_bBlockRead(false), m_LineInBlock(0), m_CurrentBlock(0) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + + fseek(m_pFile, 0, SEEK_END); + m_FileSize = ftell(m_pFile); + fseek(m_pFile, 0, SEEK_SET); + + m_nNumberOfBlocks = m_FileSize / (nChannels * VB_BLOCK_SIZE); + m_pVagDecoders = new CVagDecoder[nChannels]; + m_ppVagBuffers = new uint8*[nChannels]; + m_ppPcmBuffers = new int16*[nChannels]; + for (uint8 i = 0; i < nChannels; i++) + m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE]; + } + + ~CVbFile() + { + if (m_pFile) + { + fclose(m_pFile); + + delete[] m_pVagDecoders; + for (int i = 0; i < m_nChannels; i++) + delete[] m_ppVagBuffers[i]; + delete[] m_ppVagBuffers; + delete[] m_ppPcmBuffers; + } + } + + bool IsOpened() + { + return m_pFile != nil; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if (!IsOpened()) return 0; + return m_nNumberOfBlocks * NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE; + } + + uint32 GetSampleRate() + { + return m_nSampleRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + uint32 samples = ms2samples(milliseconds); + + // find the block of our sample + uint32 block = samples / NUM_VAG_SAMPLES_IN_BLOCK; + if (block > m_nNumberOfBlocks) + { + samples = 0; + block = 0; + } + if (block != m_CurrentBlock) + m_bBlockRead = false; + + // find a line of our sample within our block + uint32 remainingSamples = samples - block * NUM_VAG_SAMPLES_IN_BLOCK; + uint32 newLine = remainingSamples / VAG_SAMPLES_IN_LINE / VAG_LINE_SIZE; + + if (m_CurrentBlock != block || m_LineInBlock != newLine) + { + m_CurrentBlock = block; + m_LineInBlock = newLine; + for (uint32 i = 0; i < GetChannels(); i++) + m_pVagDecoders[i].ResetState(); + } + + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + uint32 pos = (m_CurrentBlock * NUM_VAG_LINES_IN_BLOCK + m_LineInBlock) * VAG_SAMPLES_IN_LINE; + return samples2ms(pos); + } + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_CurrentBlock >= m_nNumberOfBlocks) return 0; + + // cache current ADPCM block + if (!m_bBlockRead) + ReadBlock(m_CurrentBlock); + + // trim the buffer size if we're at the end of our file + int numberOfRequiredLines = GetBufferSamples() / m_nChannels / VAG_SAMPLES_IN_LINE; + int numberOfRemainingLines = (m_nNumberOfBlocks - m_CurrentBlock) * NUM_VAG_LINES_IN_BLOCK - m_LineInBlock; + int bufSizePerChannel = Min(numberOfRequiredLines, numberOfRemainingLines) * VAG_SAMPLES_IN_LINE * GetSampleSize(); + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_nChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + bufSizePerChannel * i); + + int size = 0; + while (size < bufSizePerChannel) + { + // decode the VAG lines + for (uint32 i = 0; i < m_nChannels; i++) + { + m_pVagDecoders[i].Decode(m_ppVagBuffers[i] + m_LineInBlock * VAG_LINE_SIZE, m_ppPcmBuffers[i], VAG_LINE_SIZE); + m_ppPcmBuffers[i] += VAG_SAMPLES_IN_LINE; + } + size += VAG_SAMPLES_IN_LINE * GetSampleSize(); + m_LineInBlock++; + + // block is over, read the next block + if (m_LineInBlock >= NUM_VAG_LINES_IN_BLOCK) + { + m_CurrentBlock++; + if (m_CurrentBlock >= m_nNumberOfBlocks) // end of file + break; + m_LineInBlock = 0; + ReadBlock(); + } + } + + return bufSizePerChannel * m_nChannels; + } +}; +#ifdef AUDIO_OAL_USE_OPUS class COpusFile : public IDecoder { OggOpusFile *m_FileH; @@ -272,72 +948,30 @@ public: if (size < 0) return 0; + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size * m_nChannels * GetSampleSize()); + return size * m_nChannels * GetSampleSize(); } }; #endif -class CADFFile : public CMP3File -{ - static ssize_t r_read(void* fh, void* buf, size_t size) - { - size_t bytesRead = fread(buf, 1, size, (FILE*)fh); - uint8* _buf = (uint8*)buf; - for (int i = 0; i < size; i++) - _buf[i] ^= 0x22; - return bytesRead; - } - static off_t r_seek(void* fh, off_t pos, int seekType) - { - fseek((FILE*)fh, pos, seekType); - return ftell((FILE*)fh); - } - static void r_close(void* fh) - { - fclose((FILE*)fh); - } -public: - CADFFile(const char* path) - { - m_pMH = mpg123_new(nil, nil); - if (m_pMH) - { - long rate = 0; - int channels = 0; - int encoding = 0; - - FILE* f = fopen(path, "rb"); - - m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK - && mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; - m_nRate = rate; - m_nChannels = channels; - - if (IsOpened()) - { - mpg123_format_none(m_pMH); - mpg123_format(m_pMH, rate, channels, encoding); - } - } - } -}; - void CStream::Initialise() { -#ifndef AUDIO_OPUS +#ifdef AUDIO_OAL_USE_MPG123 mpg123_init(); #endif } void CStream::Terminate() { -#ifndef AUDIO_OPUS +#ifdef AUDIO_OAL_USE_MPG123 mpg123_exit(); #endif } -CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) : - m_alSource(source), +CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate) : + m_pAlSources(sources), m_alBuffers(buffers), m_pBuffer(nil), m_bPaused(false), @@ -364,15 +998,22 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF DEV("Stream %s\n", m_aFilename); -#ifndef AUDIO_OPUS - if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) - m_pSoundFile = new CMP3File(m_aFilename); - else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) + if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) +#ifdef AUDIO_OAL_USE_SNDFILE m_pSoundFile = new CSndFile(m_aFilename); +#else + m_pSoundFile = new CWavFile(m_aFilename); +#endif +#ifdef AUDIO_OAL_USE_MPG123 + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) + m_pSoundFile = new CMP3File(m_aFilename); else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf")) m_pSoundFile = new CADFFile(m_aFilename); -#else - if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) +#endif + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB")) + m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate); +#ifdef AUDIO_OAL_USE_OPUS + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) m_pSoundFile = new COpusFile(m_aFilename); #endif else @@ -420,7 +1061,7 @@ void CStream::Delete() bool CStream::HasSource() { - return m_alSource != AL_NONE; + return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE); } bool CStream::IsOpened() @@ -434,9 +1075,10 @@ bool CStream::IsPlaying() if ( !m_bPaused ) { - ALint sourceState; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - if ( m_bActive || sourceState == AL_PLAYING ) + ALint sourceState[2]; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); + if ( m_bActive || sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING) return true; } @@ -447,9 +1089,12 @@ void CStream::Pause() { if ( !HasSource() ) return; ALint sourceState = AL_PAUSED; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - if (sourceState != AL_PAUSED ) - alSourcePause(m_alSource); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[1]); } void CStream::SetPause(bool bPause) @@ -471,19 +1116,21 @@ void CStream::SetPause(bool bPause) void CStream::SetPitch(float pitch) { if ( !HasSource() ) return; - alSourcef(m_alSource, AL_PITCH, pitch); + alSourcef(m_pAlSources[0], AL_PITCH, pitch); + alSourcef(m_pAlSources[1], AL_PITCH, pitch); } void CStream::SetGain(float gain) { if ( !HasSource() ) return; - alSourcef(m_alSource, AL_GAIN, gain); + alSourcef(m_pAlSources[0], AL_GAIN, gain); + alSourcef(m_pAlSources[1], AL_GAIN, gain); } -void CStream::SetPosition(float x, float y, float z) +void CStream::SetPosition(int i, float x, float y, float z) { if ( !HasSource() ) return; - alSource3f(m_alSource, AL_POSITION, x, y, z); + alSource3f(m_pAlSources[i], AL_POSITION, x, y, z); } void CStream::SetVolume(uint32 nVol) @@ -494,8 +1141,13 @@ void CStream::SetVolume(uint32 nVol) void CStream::SetPan(uint8 nPan) { + m_nPan = clamp((int8)nPan - 63, 0, 63); + SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + + m_nPan = clamp((int8)nPan + 64, 64, 127); + SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + m_nPan = nPan; - SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f))); } void CStream::SetPosMS(uint32 nPos) @@ -512,10 +1164,10 @@ uint32 CStream::GetPosMS() ALint offset; //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); - alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset); + alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset); return m_pSoundFile->Tell() - - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1)) / m_pSoundFile->GetChannels() + - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels() + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels(); } @@ -525,33 +1177,41 @@ uint32 CStream::GetLengthMS() return m_pSoundFile->GetLength(); } -bool CStream::FillBuffer(ALuint alBuffer) +bool CStream::FillBuffer(ALuint *alBuffer) { if ( !HasSource() ) return false; if ( !IsOpened() ) return false; - if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) ) + if ( !(alBuffer[0] != AL_NONE && alIsBuffer(alBuffer[0])) ) + return false; + if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) ) return false; uint32 size = m_pSoundFile->Decode(m_pBuffer); if( size == 0 ) return false; - alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, - m_pBuffer, size, m_pSoundFile->GetSampleRate()); - + uint32 channelSize = size / m_pSoundFile->GetChannels(); + + alBufferData(alBuffer[0], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + // TODO: use just one buffer if we play mono + if (m_pSoundFile->GetChannels() == 1) + alBufferData(alBuffer[1], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + else + alBufferData(alBuffer[1], AL_FORMAT_MONO16, (uint8*)m_pBuffer + channelSize, channelSize, m_pSoundFile->GetSampleRate()); return true; } int32 CStream::FillBuffers() { int32 i = 0; - for ( i = 0; i < NUM_STREAMBUFFERS; i++ ) + for ( i = 0; i < NUM_STREAMBUFFERS/2; i++ ) { - if ( !FillBuffer(m_alBuffers[i]) ) + if ( !FillBuffer(&m_alBuffers[i*2]) ) break; - alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]); + alSourceQueueBuffers(m_pAlSources[0], 1, &m_alBuffers[i*2]); + alSourceQueueBuffers(m_pAlSources[1], 1, &m_alBuffers[i*2+1]); } return i; @@ -561,12 +1221,15 @@ void CStream::ClearBuffers() { if ( !HasSource() ) return; - ALint buffersQueued; - alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued); + ALint buffersQueued[2]; + alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &buffersQueued[0]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &buffersQueued[1]); ALuint value; - while (buffersQueued--) - alSourceUnqueueBuffers(m_alSource, 1, &value); + while (buffersQueued[0]--) + alSourceUnqueueBuffers(m_pAlSources[0], 1, &value); + while (buffersQueued[1]--) + alSourceUnqueueBuffers(m_pAlSources[1], 1, &value); } bool CStream::Setup() @@ -574,7 +1237,6 @@ bool CStream::Setup() if ( IsOpened() ) { m_pSoundFile->Seek(0); - alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE); //SetPosition(0.0f, 0.0f, 0.0f); SetPitch(1.0f); //SetPan(m_nPan); @@ -590,17 +1252,29 @@ void CStream::SetPlay(bool state) if ( state ) { ALint sourceState = AL_PLAYING; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); if (sourceState != AL_PLAYING ) - alSourcePlay(m_alSource); + alSourcePlay(m_pAlSources[0]); + + sourceState = AL_PLAYING; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PLAYING) + alSourcePlay(m_pAlSources[1]); + m_bActive = true; } else { ALint sourceState = AL_STOPPED; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); if (sourceState != AL_STOPPED ) - alSourceStop(m_alSource); + alSourceStop(m_pAlSources[0]); + + sourceState = AL_STOPPED; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED) + alSourceStop(m_pAlSources[1]); + m_bActive = false; } } @@ -631,35 +1305,51 @@ void CStream::Update() if ( !m_bPaused ) { - ALint sourceState; - ALint buffersProcessed = 0; + ALint sourceState[2]; + ALint buffersProcessed[2] = { 0, 0 }; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); + // Relying a lot on left buffer states in here + + do + { + //alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); + //alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]); + } while (buffersProcessed[0] != buffersProcessed[1]); ALint looping = AL_FALSE; - alGetSourcei(m_alSource, AL_LOOPING, &looping); + alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping); if ( looping == AL_TRUE ) { TRACE("stream set looping"); - alSourcei(m_alSource, AL_LOOPING, AL_TRUE); + alSourcei(m_pAlSources[0], AL_LOOPING, AL_TRUE); + alSourcei(m_pAlSources[1], AL_LOOPING, AL_TRUE); } - while( buffersProcessed-- ) + assert(buffersProcessed[0] == buffersProcessed[1]); + + while( buffersProcessed[0]-- ) { - ALuint buffer; + ALuint buffer[2]; - alSourceUnqueueBuffers(m_alSource, 1, &buffer); + alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]); - if ( m_bActive && FillBuffer(buffer) ) - alSourceQueueBuffers(m_alSource, 1, &buffer); + if (m_bActive && FillBuffer(buffer)) + { + alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]); + } } - if ( sourceState != AL_PLAYING ) + if ( sourceState[0] != AL_PLAYING ) { - alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); - SetPlay(buffersProcessed!=0); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); + SetPlay(buffersProcessed[0]!=0); } } } diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h index 2476abcc..bcbc5e54 100644 --- a/src/audio/oal/stream.h +++ b/src/audio/oal/stream.h @@ -3,7 +3,7 @@ #ifdef AUDIO_OAL #include <AL/al.h> -#define NUM_STREAMBUFFERS 4 +#define NUM_STREAMBUFFERS 8 class IDecoder { @@ -57,7 +57,7 @@ public: class CStream { char m_aFilename[128]; - ALuint &m_alSource; + ALuint *m_pAlSources; ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; bool m_bPaused; @@ -73,20 +73,20 @@ class CStream IDecoder *m_pSoundFile; bool HasSource(); - void SetPosition(float x, float y, float z); + void SetPosition(int i, float x, float y, float z); void SetPitch(float pitch); void SetGain(float gain); void Pause(); void SetPlay(bool state); - bool FillBuffer(ALuint alBuffer); + bool FillBuffer(ALuint *alBuffer); int32 FillBuffers(); void ClearBuffers(); public: static void Initialise(); static void Terminate(); - CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]); + CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate = 32000); ~CStream(); void Delete(); diff --git a/src/audio/sampman.h b/src/audio/sampman.h index d3e4415f..5d7d39af 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -1,5 +1,4 @@ #pragma once -#include "common.h" #include "AudioSamples.h" #define MAX_VOLUME 127 @@ -240,7 +239,7 @@ public: extern cSampleManager SampleManager; extern uint32 BankStartOffset[MAX_SFX_BANKS]; -#ifdef AUDIO_OPUS +#if defined(OPUS_AUDIO_PATHS) static char StreamedNameTable[][25] = { "AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS", "AUDIO\\MSX.OPUS", "AUDIO\\FLASH.OPUS", "AUDIO\\CHAT.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\POLICE.OPUS", "AUDIO\\CITY.OPUS", @@ -275,8 +274,7 @@ static char StreamedNameTable[][25] = { "AUDIO\\h5_b.OPUS", "AUDIO\\h5_c.OPUS", "AUDIO\\ammu_a.OPUS", "AUDIO\\ammu_b.OPUS", "AUDIO\\ammu_c.OPUS", "AUDIO\\door_1.OPUS", "AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS", "AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"}; -#else -#ifdef PS2_AUDIO +#elif defined(PS2_AUDIO_PATHS) static char StreamedNameTable[][40] = { "AUDIO\\MUSIC\\WILD.VB", @@ -1610,5 +1608,4 @@ static char StreamedNameTable[][25] = "AUDIO\\BUST_26.WAV", "AUDIO\\BUST_27.WAV", "AUDIO\\BUST_28.WAV", -}; -#endif
\ No newline at end of file +};
\ No newline at end of file diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp index f7c4d7a6..2d6a655e 100644 --- a/src/audio/sampman_miles.cpp +++ b/src/audio/sampman_miles.cpp @@ -1,8 +1,5 @@ -#include "common.h" - #ifdef AUDIO_MSS -#include <windows.h> -#include <shobjidl.h> +#include <shlobj.h> #include <shlguid.h> #include <time.h> @@ -11,6 +8,7 @@ #include "eax-util.h" #include "mss.h" +#include "common.h" #include "sampman.h" #include "AudioManager.h" #include "MusicManager.h" @@ -20,8 +18,6 @@ #pragma comment( lib, "mss32.lib" ) -// --MIAMI: file done - cSampleManager SampleManager; uint32 BankStartOffset[MAX_SFX_BANKS]; /////////////////////////////////////////////////////////////// @@ -1380,7 +1376,7 @@ cSampleManager::Terminate(void) bool cSampleManager::CheckForAnAudioFileOnCD(void) { -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) +#if !defined(NO_CDCHECK) // TODO: check steam, probably GTAVC_STEAM_PATCH needs to be added char filepath[MAX_PATH]; strcpy(filepath, m_MiscomPath); @@ -1406,7 +1402,7 @@ cSampleManager::CheckForAnAudioFileOnCD(void) #else return true; -#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) +#endif // #if !defined(NO_CDCHECK) } char diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 80f19e50..0d06098d 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -1,17 +1,11 @@ //#define JUICY_OAL #ifdef AUDIO_OAL -#include "sampman.h" - #include <time.h> #include "eax.h" #include "eax-util.h" -#define WITHWINDOWS -#include "common.h" -#include "crossplatform.h" - #ifdef _WIN32 #include <io.h> #include <AL/al.h> @@ -19,8 +13,24 @@ #include <AL/alext.h> #include <AL/efx.h> #include <AL/efx-presets.h> + +// for user MP3s +#include <direct.h> +#include <shlobj.h> +#include <shlguid.h> +#else +#define _getcwd getcwd +#endif + +#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK +#pragma comment( lib, "OpenAL32.lib" ) #endif +#include "common.h" +#include "crossplatform.h" + +#include "sampman.h" + #include "oal/oal_utils.h" #include "oal/aldlist.h" #include "oal/channel.h" @@ -30,7 +40,7 @@ #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" -#ifdef AUDIO_OPUS +#ifdef AUDIO_OAL_USE_OPUS #include <opusfile.h> #endif @@ -38,19 +48,6 @@ //TODO: max channels //TODO: loop count -#ifdef _WIN32 -#pragma comment( lib, "OpenAL32.lib" ) -#endif - -// for user MP3s -#ifdef _WIN32 -#include <direct.h> -#include <shobjidl.h> -#include <shlguid.h> -#else -#define _getcwd getcwd -#endif - cSampleManager SampleManager; bool _bSampmanInitialised = false; @@ -83,7 +80,7 @@ char SampleBankDescFilename[] = "audio/sfx.SDT"; char SampleBankDataFilename[] = "audio/sfx.RAW"; FILE *fpSampleDescHandle; -#ifdef AUDIO_OPUS +#ifdef OPUS_SFX OggOpusFile *fpSampleDataHandle; #else FILE *fpSampleDataHandle; @@ -102,7 +99,7 @@ CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS]; uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; -ALuint ALStreamSources[MAX_STREAMS]; +ALuint ALStreamSources[MAX_STREAMS][2]; ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS]; struct tMP3Entry @@ -245,9 +242,9 @@ release_existing() if (stream) stream->ProviderTerm(); - alDeleteSources(1, &ALStreamSources[i]); alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); } + alDeleteSources(MAX_STREAMS*2, ALStreamSources[0]); CChannel::DestroyChannels(); @@ -287,7 +284,10 @@ set_new_provider(int index) //TODO: _maxSamples = MAXCHANNELS; - ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; + ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ, + ALC_MONO_SOURCES, MAX_STREAMS * 2 + MAXCHANNELS, + 0, + }; ALDevice = alcOpenDevice(providers[index].id); ASSERT(ALDevice != NULL); @@ -319,11 +319,17 @@ set_new_provider(int index) alGenAuxiliaryEffectSlots(1, &ALEffectSlot); alGenEffects(1, &ALEffect); } - + + alGenSources(MAX_STREAMS*2, ALStreamSources[0]); for ( int32 i = 0; i < MAX_STREAMS; i++ ) { - alGenSources(1, &ALStreamSources[i]); alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f); + alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f); CStream *stream = aStream[i]; if (stream) @@ -384,6 +390,12 @@ set_new_provider(int index) return false; } +static bool +IsThisTrackAt16KHz(uint32 track) +{ + return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_RADIO_POLICE; +} + cSampleManager::cSampleManager(void) { ; @@ -981,15 +993,17 @@ cSampleManager::Initialise(void) #ifdef AUDIO_CACHE FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); if (cacheFile) { + debug("Loadind audio cache (If game crashes around here, then your cache is corrupted, remove audio/sound.cache)\n"); fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); fclose(cacheFile); } else -#endif { - + debug("Cannot load audio cache\n"); +#endif + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) { - aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0], IsThisTrackAt16KHz(i) ? 16000 : 32000); if ( aStream[0] && aStream[0]->IsOpened() ) { @@ -1004,10 +1018,15 @@ cSampleManager::Initialise(void) } #ifdef AUDIO_CACHE cacheFile = fcaseopen("audio\\sound.cache", "wb"); - fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); -#endif + if(cacheFile) { + debug("Saving audio cache\n"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } else { + debug("Cannot save audio cache\n"); + } } +#endif { if ( !InitialiseSampleBanks() ) @@ -1230,7 +1249,7 @@ cSampleManager::LoadSampleBank(uint8 nBank) return false; } -#ifdef AUDIO_OPUS +#ifdef OPUS_SFX int samplesRead = 0; int samplesSize = nSampleBankSize[nBank] / 2; op_pcm_seek(fpSampleDataHandle, 0); @@ -1335,7 +1354,7 @@ cSampleManager::LoadPedComment(uint32 nComment) } } -#ifdef AUDIO_OPUS +#ifdef OPUS_SFX int samplesRead = 0; int samplesSize = m_aSamples[nComment].nSize / 2; op_pcm_seek(fpSampleDataHandle, m_aSamples[nComment].nOffset / 2); @@ -1542,10 +1561,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] = vol / 4; + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } // no idea, does this one looks like a bug or it's SetChannelVolume ? @@ -1671,7 +1691,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) strcpy(filename, StreamedNameTable[nFile]); - CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1746,7 +1766,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) nFile = 0; strcat(filename, StreamedNameTable[nFile]); - CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1770,12 +1790,12 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) } if (mp3->pLinkPath != NULL) - aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, mp3->aFilename); - aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); } if (aStream[nStream]->IsOpened()) { @@ -1802,7 +1822,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) { nFile = 0; strcat(filename, StreamedNameTable[nFile]); - CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1826,7 +1846,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) } if (e->pLinkPath != NULL) - aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, e->aFilename); @@ -1859,7 +1879,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) strcpy(filename, StreamedNameTable[nFile]); - CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1991,7 +2011,7 @@ cSampleManager::InitialiseSampleBanks(void) fpSampleDescHandle = fcaseopen(SampleBankDescFilename, "rb"); if ( fpSampleDescHandle == NULL ) return false; -#ifndef AUDIO_OPUS +#ifndef OPUS_SFX fpSampleDataHandle = fcaseopen(SampleBankDataFilename, "rb"); if ( fpSampleDataHandle == NULL ) { @@ -2009,7 +2029,7 @@ cSampleManager::InitialiseSampleBanks(void) fpSampleDataHandle = op_open_file(SampleBankDataFilename, &e); #endif fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); -#ifdef AUDIO_OPUS +#ifdef OPUS_SFX int32 _nSampleDataEndOffset = m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nOffset + m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nSize; #endif fclose(fpSampleDescHandle); diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index 0a1689bc..98982f61 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -1,6 +1,6 @@ #pragma once -enum eSound : uint16 +enum eSound { SOUND_CAR_DOOR_CLOSE_BONNET = 0, SOUND_CAR_DOOR_CLOSE_BUMPER, @@ -208,7 +208,7 @@ enum eSound : uint16 }; -enum eScriptSounds : uint16 { +enum eScriptSounds { SCRIPT_SOUND_BANK_ALARM_LOOP = 0, SCRIPT_SOUND_PART_MISSION_COMPLETE, SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP, diff --git a/src/entities/Building.cpp b/src/buildings/Building.cpp index 921055ce..8035cf25 100644 --- a/src/entities/Building.cpp +++ b/src/buildings/Building.cpp @@ -27,14 +27,14 @@ IsBuildingPointerValid(CBuilding* pBuilding) if (!pBuilding) return false; if (pBuilding->GetIsATreadable()) { - int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding); + int index = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pBuilding); #ifdef FIX_BUGS return index >= 0 && index < CPools::GetTreadablePool()->GetSize(); #else return index >= 0 && index <= CPools::GetTreadablePool()->GetSize(); #endif } else { - int index = CPools::GetBuildingPool()->GetJustIndex(pBuilding); + int index = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding); #ifdef FIX_BUGS return index >= 0 && index < CPools::GetBuildingPool()->GetSize(); #else diff --git a/src/entities/Building.h b/src/buildings/Building.h index 2c2dfb1f..2c2dfb1f 100644 --- a/src/entities/Building.h +++ b/src/buildings/Building.h diff --git a/src/entities/Solid.h b/src/buildings/Solid.h index 4ca800c2..4ca800c2 100644 --- a/src/entities/Solid.h +++ b/src/buildings/Solid.h diff --git a/src/entities/Treadable.cpp b/src/buildings/Treadable.cpp index 00abbe13..00abbe13 100644 --- a/src/entities/Treadable.cpp +++ b/src/buildings/Treadable.cpp diff --git a/src/entities/Treadable.h b/src/buildings/Treadable.h index c3ab755e..c3ab755e 100644 --- a/src/entities/Treadable.h +++ b/src/buildings/Treadable.h diff --git a/src/collision/ColModel.cpp b/src/collision/ColModel.cpp index ba33c134..49847dbd 100644 --- a/src/collision/ColModel.cpp +++ b/src/collision/ColModel.cpp @@ -2,6 +2,7 @@ #include "ColModel.h" #include "Collision.h" #include "Game.h" +#include "MemoryHeap.h" #include "Pools.h" CColModel::CColModel(void) @@ -23,7 +24,6 @@ CColModel::CColModel(void) CColModel::~CColModel(void) { RemoveCollisionVolumes(); - RemoveTrianglePlanes(); } void* @@ -65,10 +65,15 @@ CColModel::RemoveCollisionVolumes(void) void CColModel::CalculateTrianglePlanes(void) { + PUSH_MEMID(MEMID_COLLISION); + // HACK: allocate space for one more element to stuff the link pointer into trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1)); + REGISTER_MEMPTR(&trianglePlanes); for(int i = 0; i < numTriangles; i++) trianglePlanes[i].Set(vertices, triangles[i]); + + POP_MEMID(); } void @@ -198,4 +203,4 @@ CColModel::operator=(const CColModel &other) vertices = nil; } return *this; -}
\ No newline at end of file +} diff --git a/src/collision/ColStore.cpp b/src/collision/ColStore.cpp index bca1e9b7..f1e695fe 100644 --- a/src/collision/ColStore.cpp +++ b/src/collision/ColStore.cpp @@ -11,8 +11,13 @@ #include "Frontend.h" #include "Physical.h" #include "ColStore.h" +#include "VarConsole.h" +#include "Pools.h" CPool<ColDef,ColDef> *CColStore::ms_pColPool; +#ifndef MASTER +bool bDispColInMem; +#endif void CColStore::Initialise(void) @@ -20,6 +25,9 @@ CColStore::Initialise(void) if(ms_pColPool == nil) ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles"); AddColSlot("generic"); // slot 0. not streamed +#ifndef MASTER + VarConsole.Add("Display collision in memory", &bDispColInMem, true); +#endif } void @@ -173,11 +181,22 @@ CColStore::LoadCollision(const CVector2D &pos) if(GetBoundingBox(i).IsPointInside(pos) || bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) || - CGeneral::faststrcmp(GetColName(i), "yacht") == 0){ + strcmp(GetColName(i), "yacht") == 0){ wantThisOne = true; }else{ for (int j = 0; j < MAX_CLEANUP; j++) { - CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); + CPhysical* pEntity = nil; + cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[i]; + if (pCleanup->type == CLEANUP_CAR) { + pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id); + if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED) + continue; + } + else if (pCleanup->type == CLEANUP_CHAR) { + pEntity = CPools::GetPedPool()->GetAt(pCleanup->id); + if (!pEntity || ((CPed*)pEntity)->DyingOrDead()) + continue; + } if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) { if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) wantThisOne = true; diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp index 20778345..45a15628 100644 --- a/src/collision/Collision.cpp +++ b/src/collision/Collision.cpp @@ -24,8 +24,6 @@ #include "Camera.h" #include "ColStore.h" -//--MIAMI: file done - #ifdef VU_COLLISION #include "VuCollision.h" @@ -93,7 +91,7 @@ CCollision::Update(void) { } -//--MIAMI: unused +// unused eLevelName GetCollisionInSectorList(CPtrList &list) { @@ -110,7 +108,7 @@ GetCollisionInSectorList(CPtrList &list) return LEVEL_GENERIC; } -//--MIAMI: unused +// unused // Get a level this sector is in based on collision models eLevelName GetCollisionInSector(CSector §) @@ -499,7 +497,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); // If we don't intersect with the bounding box, no chance on the rest if(!TestLineBox(*(CColLine*)newline, model.boundingBox)) @@ -507,12 +505,14 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod for(i = 0; i < model.numSpheres; i++){ if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue; if(TestLineSphere(*(CColLine*)newline, model.spheres[i])) return true; } for(i = 0; i < model.numBoxes; i++){ if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue; if(TestLineBox(*(CColLine*)newline, model.boxes[i])) return true; } @@ -522,6 +522,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod VuTriangle vutri; for(i = 0; i < model.numTriangles; i++){ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -539,6 +540,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod #endif for(; i < model.numTriangles; i++){ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -876,7 +878,7 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC return true; } -//--MIAMI: unused +// unused bool CCollision::ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, @@ -1321,7 +1323,7 @@ CCollision::ProcessLineOfSight(const CColLine &line, // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); if(mindist < 1.0f) newline[1] = newline[0] + (newline[1] - newline[0])*mindist; @@ -1333,6 +1335,7 @@ CCollision::ProcessLineOfSight(const CColLine &line, float coldist = 1.0f; for(i = 0; i < model.numSpheres; i++){ if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue; if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist)) point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece); } @@ -1348,6 +1351,7 @@ CCollision::ProcessLineOfSight(const CColLine &line, CColTriangle *lasttri = nil; for(i = 0; i < model.numTriangles; i++){ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -1367,6 +1371,7 @@ CCollision::ProcessLineOfSight(const CColLine &line, float dist; for(; i < model.numTriangles; i++){ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -1456,7 +1461,7 @@ CCollision::ProcessVerticalLine(const CColLine &line, // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); if(mindist < 1.0f) newline[1] = newline[0] + (newline[1] - newline[0])*mindist; @@ -1466,13 +1471,13 @@ CCollision::ProcessVerticalLine(const CColLine &line, float coldist = 1.0f; for(i = 0; i < model.numSpheres; i++){ - if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue; + if(ignoreSeeThrough && IsSeeThroughVertical(model.spheres[i].surface)) continue; if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist)) point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece); } for(i = 0; i < model.numBoxes; i++){ - if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue; + if(ignoreSeeThrough && IsSeeThroughVertical(model.boxes[i].surface)) continue; if(ProcessLineBox(*(CColLine*)newline, model.boxes[i], point, coldist)) point.Set(0, 0, model.boxes[i].surface, model.boxes[i].piece); } @@ -1484,7 +1489,7 @@ CCollision::ProcessVerticalLine(const CColLine &line, CColTriangle *lasttri = nil; VuTriangle vutri; for(i = 0; i < model.numTriangles; i++){ - if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -1503,7 +1508,7 @@ CCollision::ProcessVerticalLine(const CColLine &line, CVuVector pnt, normal; float dist; for(; i < model.numTriangles; i++){ - if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue; + if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue; CColTriangle *tri = &model.triangles[i]; model.vertices[tri->a].Unpack(vutri.v0); @@ -1655,16 +1660,16 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, matAB *= matrixA; CVuVector bsphereAB; // bounding sphere of A in B space - TransformPoint(bsphereAB, matAB, *(RwV3d*)modelA.boundingSphere.center); // inlined + TransformPoint(bsphereAB, matAB, modelA.boundingSphere.center); // inlined bsphereAB.w = modelA.boundingSphere.radius; if(!TestSphereBox(*(CColSphere*)&bsphereAB, modelB.boundingBox)) return 0; // transform modelA's spheres and lines to B space - TransformPoints(aSpheresA, modelA.numSpheres, matAB, (RwV3d*)&modelA.spheres->center, sizeof(CColSphere)); + TransformPoints(aSpheresA, modelA.numSpheres, matAB, &modelA.spheres->center, sizeof(CColSphere)); for(i = 0; i < modelA.numSpheres; i++) aSpheresA[i].w = modelA.spheres[i].radius; - TransformPoints(aLinesA, modelA.numLines*2, matAB, (RwV3d*)&modelA.lines->p0, sizeof(CColLine)/2); + TransformPoints(aLinesA, modelA.numLines*2, matAB, &modelA.lines->p0, sizeof(CColLine)/2); // Test them against model B's bounding volumes int numSpheresA = 0; @@ -1681,7 +1686,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, matBA *= matrixB; // transform modelB's spheres to A space - TransformPoints(aSpheresB, modelB.numSpheres, matBA, (RwV3d*)&modelB.spheres->center, sizeof(CColSphere)); + TransformPoints(aSpheresB, modelB.numSpheres, matBA, &modelB.spheres->center, sizeof(CColSphere)); for(i = 0; i < modelB.numSpheres; i++) aSpheresB[i].w = modelB.spheres[i].radius; diff --git a/src/collision/TempColModels.cpp b/src/collision/TempColModels.cpp index e7ba54f1..0c0d4376 100644 --- a/src/collision/TempColModels.cpp +++ b/src/collision/TempColModels.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "TempColModels.h" +#include "Game.h" CColModel CTempColModels::ms_colModelPed1; CColModel CTempColModels::ms_colModelPed2; @@ -41,7 +42,7 @@ CTempColModels::Initialise(void) colmodel.numSpheres = ARRAY_SIZE(sphrs);\ colmodel.spheres = sphrs;\ colmodel.level = LEVEL_GENERIC;\ - colmodel.ownsCollisionVolumes = false;\ + colmodel.ownsCollisionVolumes = false; int i; diff --git a/src/collision/TempColModels.h b/src/collision/TempColModels.h index 0c936d6f..1a888723 100644 --- a/src/collision/TempColModels.h +++ b/src/collision/TempColModels.h @@ -1,6 +1,6 @@ #pragma once -#include "Collision.h" +#include "ColModel.h" class CTempColModels { diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp index 1b14e3d7..c956a6f1 100644 --- a/src/control/AutoPilot.cpp +++ b/src/control/AutoPilot.cpp @@ -6,8 +6,6 @@ #include "Curves.h" #include "PathFind.h" -//--MIAMI: file done - void CAutoPilot::ModifySpeed(float speed) { m_fMaxTrafficSpeed = Max(0.01f, speed); @@ -109,9 +107,9 @@ void CAutoPilot::Load(uint8*& buf) m_nNextDirection = ReadSaveBuf<int8>(buf); m_nCurrentLane = ReadSaveBuf<int8>(buf); m_nNextLane = ReadSaveBuf<int8>(buf); - m_nDrivingStyle = (eCarDrivingStyle)ReadSaveBuf<uint8>(buf); - m_nCarMission = (eCarMission)ReadSaveBuf<uint8>(buf); - m_nTempAction = (eCarTempAction)ReadSaveBuf<uint8>(buf); + m_nDrivingStyle = ReadSaveBuf<uint8>(buf); + m_nCarMission = ReadSaveBuf<uint8>(buf); + m_nTempAction = ReadSaveBuf<uint8>(buf); m_nTimeTempAction = ReadSaveBuf<uint32>(buf); m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf); m_nCruiseSpeed = ReadSaveBuf<uint8>(buf); diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index 25feb72d..aa14ccdd 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -4,7 +4,7 @@ class CVehicle; struct CPathNode; -enum eCarMission : uint8 +enum eCarMission { MISSION_NONE, MISSION_CRUISE, @@ -35,7 +35,7 @@ enum eCarMission : uint8 MISSION_BLOCKPLAYER_FORWARDANDBACK }; -enum eCarTempAction : uint8 +enum eCarTempAction { TEMPACT_NONE, TEMPACT_WAIT, @@ -50,7 +50,7 @@ enum eCarTempAction : uint8 TEMPACT_SWERVERIGHT }; -enum eCarDrivingStyle : uint8 +enum eCarDrivingStyle { DRIVINGSTYLE_STOP_FOR_CARS, DRIVINGSTYLE_SLOW_DOWN_FOR_CARS, @@ -76,9 +76,9 @@ public: int8 m_nNextDirection; int8 m_nCurrentLane; int8 m_nNextLane; - eCarDrivingStyle m_nDrivingStyle; - eCarMission m_nCarMission; - eCarTempAction m_nTempAction; + uint8 m_nDrivingStyle; + uint8 m_nCarMission; + uint8 m_nTempAction; uint32 m_nTimeTempAction; float m_fMaxTrafficSpeed; uint8 m_nCruiseSpeed; diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp index 1a1c03bd..1e63cf30 100644 --- a/src/control/Bridge.cpp +++ b/src/control/Bridge.cpp @@ -6,8 +6,6 @@ #include "PathFind.h" #include "Stats.h" -//--MIAMI: file done - CEntity *CBridge::pLiftRoad; CEntity *CBridge::pLiftPart; CEntity *CBridge::pWeight; diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp index a3fcbf9a..8e79fee1 100644 --- a/src/control/CarAI.cpp +++ b/src/control/CarAI.cpp @@ -22,8 +22,6 @@ #define DISTANCE_TO_SWITCH_DISTANCE_GOTO 20.0f -//--MIAMI: file done - float CCarAI::FindSwitchDistanceClose(CVehicle* pVehicle) { return pVehicle->AutoPilot.m_nSwitchDistance; @@ -44,7 +42,7 @@ float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle) void CCarAI::BackToCruisingIfNoWantedLevel(CVehicle* pVehicle) { if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer && - (FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) { + (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) { CCarCtrl::JoinCarWithRoadSystem(pVehicle); pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE; pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; @@ -118,7 +116,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) TellOccupantsToLeaveCar(pVehicle); pVehicle->AutoPilot.m_nCruiseSpeed = 0; pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; - if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() <= 1) pVehicle->m_bSirenOrAlarm = false; } } @@ -160,7 +158,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) TellOccupantsToLeaveCar(pVehicle); pVehicle->AutoPilot.m_nCruiseSpeed = 0; pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; - if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() <= 1) pVehicle->m_bSirenOrAlarm = false; } } @@ -333,7 +331,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER; } if (distance > 70.0f || FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || - (FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) { + (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) { TellOccupantsToLeaveCar(pVehicle); pVehicle->AutoPilot.m_nCruiseSpeed = 0; pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER; @@ -350,7 +348,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) break; } default: - if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && !CCullZones::NoPolice()){ + if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && !CCullZones::NoPolice()){ if (ABS(FindPlayerCoors().x - pVehicle->GetPosition().x) > 10.0f || ABS(FindPlayerCoors().y - pVehicle->GetPosition().y) > 10.0f){ pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle); @@ -364,7 +362,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) TellOccupantsToLeaveCar(pVehicle); pVehicle->AutoPilot.m_nCruiseSpeed = 0; pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; - if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() <= 1) pVehicle->m_bSirenOrAlarm = false; } } @@ -377,7 +375,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) pVehicle->AutoPilot.m_nCruiseSpeed = 0; break; } - if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel >= 1 && CCullZones::PoliceAbandonCars()) { + if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->GetWantedLevel() >= 1 && CCullZones::PoliceAbandonCars()) { TellOccupantsToLeaveCar(pVehicle); pVehicle->AutoPilot.m_nCruiseSpeed = 0; pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; @@ -485,7 +483,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) else pVehicle->AutoPilot.m_fCruiseSpeedMultiplier += change; - if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0) { + if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0) { if (!FindPlayerVehicle() || FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR || FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) { @@ -550,7 +548,7 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle) case MI_RHINO: case MI_BARRACKS: pVehicle->SetUpDriver(); - if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 1) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() > 1) pVehicle->SetupPassenger(0); return; case MI_PREDATOR: @@ -634,9 +632,9 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget) pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed); } -eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() +uint8 CCarAI::FindPoliceCarMissionForWantedLevel() { - switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel){ + switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()){ case 0: case 1: return MISSION_BLOCKPLAYER_FARAWAY; case 2: return (CGeneral::GetRandomNumber() & 3) >= 3 ? MISSION_RAMPLAYER_FARAWAY : MISSION_BLOCKPLAYER_FARAWAY; @@ -648,9 +646,9 @@ eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() } } -eCarMission CCarAI::FindPoliceBoatMissionForWantedLevel() +uint8 CCarAI::FindPoliceBoatMissionForWantedLevel() { - switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { + switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) { case 0: case 1: return MISSION_BLOCKPLAYER_FARAWAY; case 2: @@ -664,7 +662,7 @@ eCarMission CCarAI::FindPoliceBoatMissionForWantedLevel() int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle) { - switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { + switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) { case 0: return CGeneral::GetRandomNumberInRange(12, 16); case 1: return 25; case 2: return 34; @@ -678,7 +676,7 @@ int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle) void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle) { - if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel == 1){ + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel() == 1){ float distanceToPlayer = (pVehicle->GetPosition() - FindPlayerCoors()).Magnitude(); if (FindPlayerVehicle()){ if (distanceToPlayer < 10.0f) @@ -695,7 +693,7 @@ void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle) else pVehicle->AutoPilot.m_nCruiseSpeed = 25; } - }else if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel == 2){ + }else if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel() == 2){ float distanceToPlayer = (pVehicle->GetPosition() - FindPlayerCoors()).Magnitude(); if (FindPlayerVehicle()) { if (distanceToPlayer < 10.0f) @@ -722,7 +720,7 @@ void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle) void CCarAI::MellowOutChaseSpeedBoat(CVehicle* pVehicle) { - switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { + switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) { case 0: pVehicle->AutoPilot.m_nCruiseSpeed = 8; break; case 1: pVehicle->AutoPilot.m_nCruiseSpeed = 10; break; case 2: pVehicle->AutoPilot.m_nCruiseSpeed = 15; break; diff --git a/src/control/CarAI.h b/src/control/CarAI.h index d4af1806..dcd76d78 100644 --- a/src/control/CarAI.h +++ b/src/control/CarAI.h @@ -22,8 +22,8 @@ public: static void TellOccupantsToFleeCar(CVehicle*); static void TellCarToRamOtherCar(CVehicle*, CVehicle*); static void TellCarToBlockOtherCar(CVehicle*, CVehicle*); - static eCarMission FindPoliceCarMissionForWantedLevel(); - static eCarMission FindPoliceBoatMissionForWantedLevel(); + static uint8 FindPoliceCarMissionForWantedLevel(); + static uint8 FindPoliceBoatMissionForWantedLevel(); static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*); static void MellowOutChaseSpeed(CVehicle*); static void MellowOutChaseSpeedBoat(CVehicle*); diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 19f2c628..c6d78882 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -35,6 +35,7 @@ #include "WaterLevel.h" #include "World.h" #include "Zones.h" +#include "Pickups.h" #define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS (51.0f) #define DISTANCE_TO_SCAN_FOR_DANGER (14.0f) @@ -82,8 +83,6 @@ #define OFFSCREEN_DESPAWN_RANGE (40.0f) #define EXTENDED_RANGE_DESPAWN_MULTIPLIER (1.5f) -//--MIAMI: file done - bool CCarCtrl::bMadDriversCheat; int CCarCtrl::NumLawEnforcerCars; int CCarCtrl::NumAmbulancesOnDuty; @@ -110,8 +109,6 @@ int32 CCarCtrl::LoadedCarsArray[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY]; CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP]; uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP]; -//--MIAMI: done except heli/plane functions - void CCarCtrl::GenerateRandomCars() { @@ -151,18 +148,18 @@ CCarCtrl::GenerateOneRandomCar() CWanted* pWanted = pPlayer->m_pPed->m_pWanted; int carClass; int carModel; - if (pWanted->m_nWantedLevel > 1 && NumLawEnforcerCars < pWanted->m_MaximumLawEnforcerVehicles && + if (pWanted->GetWantedLevel() > 1 && NumLawEnforcerCars < pWanted->m_MaximumLawEnforcerVehicles && pWanted->m_CurrentCops < pWanted->m_MaxCops && !CGame::IsInInterior() && ( - pWanted->m_nWantedLevel > 3 || - pWanted->m_nWantedLevel > 2 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 5000 || - pWanted->m_nWantedLevel > 1 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 8000)) { - /* Last pWanted->m_nWantedLevel > 1 is unnecessary but I added it for better readability. */ + pWanted->GetWantedLevel() > 3 || + pWanted->GetWantedLevel() > 2 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 5000 || + pWanted->GetWantedLevel() > 1 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 8000)) { + /* Last pWanted->GetWantedLevel() > 1 is unnecessary but I added it for better readability. */ /* Wouldn't be surprised it was there originally but was optimized out. */ carClass = COPS; carModel = ChoosePoliceCarModel(); }else{ carModel = ChooseModel(&zone, &carClass); - if (carModel == -1 || (carClass == COPS && pWanted->m_nWantedLevel >= 1)) + if (carModel == -1 || (carClass == COPS && pWanted->GetWantedLevel() >= 1)) /* All cop spawns with wanted level are handled by condition above. */ /* In particular it means that cop cars never spawn if player has wanted level of 1. */ return; @@ -295,7 +292,7 @@ CCarCtrl::GenerateOneRandomCar() } if (!ThePaths.GenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, preferredDistance, angleLimit, invertAngleLimitTest, &spawnPosition, &curNodeId, &nextNodeId, - &positionBetweenNodes, carClass == COPS && pWanted->m_nWantedLevel >= 1)) + &positionBetweenNodes, carClass == COPS && pWanted->GetWantedLevel() >= 1)) return; CPathNode* pCurNode = &ThePaths.m_pathNodes[curNodeId]; CPathNode* pNextNode = &ThePaths.m_pathNodes[nextNodeId]; @@ -359,7 +356,7 @@ CCarCtrl::GenerateOneRandomCar() switch (carClass) { case COPS: pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; - if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel != 0){ + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel() != 0){ pVehicle->AutoPilot.m_nCruiseSpeed = CCarAI::FindPoliceCarSpeedForWantedLevel(pVehicle); pVehicle->AutoPilot.m_fMaxTrafficSpeed = pVehicle->AutoPilot.m_nCruiseSpeed / 2; pVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel(); @@ -442,6 +439,11 @@ CCarCtrl::GenerateOneRandomCar() pVehicle->GetRight() = CVector(forwardY, -forwardX, 0.0f); pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f); + float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); + float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); + float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); + float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); + #ifdef FIX_BUGS CCarPathLink* pCurrentLink; CCarPathLink* pNextLink; @@ -452,11 +454,6 @@ CCarCtrl::GenerateOneRandomCar() float directionNextLinkX; float directionNextLinkY; if (positionBetweenNodes < 0.5f) { - float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); - float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); - float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); - float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); - pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; positionOnCurrentLinkIncludingLane = CVector( @@ -486,11 +483,6 @@ CCarCtrl::GenerateOneRandomCar() pVehicle->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - (uint32)((positionBetweenNodes - 0.5f) * pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); - float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); - float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); - float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); - float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); - pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; positionOnCurrentLinkIncludingLane = CVector( @@ -1907,7 +1899,6 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle) } if (pVehicle->AutoPilot.m_bStayInFastLane) pVehicle->AutoPilot.m_nNextLane = 0; -#ifdef FIX_BUGS CVector positionOnCurrentLinkIncludingLane( pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) #ifdef FIX_BUGS @@ -1922,16 +1913,6 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle) #endif ,pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX, 0.0f); -#else - CVector positionOnCurrentLinkIncludingLane( - pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH), - pCurLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX, - 0.0f); - CVector positionOnNextLinkIncludingLane( - pNextLink->GetX() + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY, - pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX, - 0.0f); -#endif float directionCurrentLinkX = pCurLink->GetDirX() * pVehicle->AutoPilot.m_nCurrentDirection; float directionCurrentLinkY = pCurLink->GetDirY() * pVehicle->AutoPilot.m_nCurrentDirection; float directionNextLinkX = pNextLink->GetDirX() * pVehicle->AutoPilot.m_nNextDirection; @@ -2867,7 +2848,13 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv case DRIVINGSTYLE_STOP_FOR_CARS: case DRIVINGSTYLE_SLOW_DOWN_FOR_CARS: case DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS: - speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle) / pVehicle->AutoPilot.m_nCruiseSpeed; + speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle); +#ifdef FIX_BUGS + if (pVehicle->AutoPilot.GetCruiseSpeed() != 0) + speedStyleMultiplier /= pVehicle->AutoPilot.GetCruiseSpeed(); +#else + speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed; +#endif break; default: speedStyleMultiplier = 1.0f; @@ -2940,7 +2927,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic *pHandbrake = true; float maxAngle = FindMaxSteerAngle(pVehicle); steerAngle = Min(maxAngle, Max(-maxAngle, steerAngle)); - float speedMultiplier = FindSpeedMultiplier(angleToTarget - angleForward, + float speedMultiplier = FindSpeedMultiplier(CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y) - angleForward, MIN_ANGLE_FOR_SPEED_LIMITING, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT); float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier; float currentSpeed = pVehicle->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_CARAI_SPEED; @@ -3175,7 +3162,7 @@ void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle) void CCarCtrl::GenerateEmergencyServicesCar(void) { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 3) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() > 3) return; if (CGame::IsInInterior()) return; @@ -3194,8 +3181,9 @@ void CCarCtrl::GenerateEmergencyServicesCar(void) CStreaming::RequestModel(MI_AMBULAN, STREAMFLAGS_DEPENDENCY); CStreaming::RequestModel(MI_MEDIC, STREAMFLAGS_DONT_REMOVE); if (CStreaming::HasModelLoaded(MI_AMBULAN) && CStreaming::HasModelLoaded(MI_MEDIC)){ - if (GenerateOneEmergencyServicesCar(MI_AMBULAN, pNearestAccident->m_pVictim->GetPosition())) + if (GenerateOneEmergencyServicesCar(MI_AMBULAN, pNearestAccident->m_pVictim->GetPosition())){ LastTimeAmbulanceCreated = CTimer::GetTimeInMilliseconds(); + } } } } @@ -3209,12 +3197,19 @@ void CCarCtrl::GenerateEmergencyServicesCar(void) float distance = 30.0f; CFire* pNearestFire = gFireManager.FindNearestFire(FindPlayerCoors(), &distance); if (pNearestFire) { - if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 30000){ + if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 35000){ CStreaming::RequestModel(MI_FIRETRUCK, STREAMFLAGS_DEPENDENCY); CStreaming::RequestModel(MI_FIREMAN, STREAMFLAGS_DONT_REMOVE); if (CStreaming::HasModelLoaded(MI_FIRETRUCK) && CStreaming::HasModelLoaded(MI_FIREMAN)){ - if (GenerateOneEmergencyServicesCar(MI_FIRETRUCK, pNearestFire->m_vecPos)) + if (GenerateOneEmergencyServicesCar(MI_FIRETRUCK, pNearestFire->m_vecPos)){ LastTimeFireTruckCreated = CTimer::GetTimeInMilliseconds(); +#ifdef SECUROM + if ((myrand() & 7) == 5){ + // if pirated game + CPickups::Init(); + } +#endif + } } } } diff --git a/src/control/Curves.cpp b/src/control/Curves.cpp index 29471608..31a2767a 100644 --- a/src/control/Curves.cpp +++ b/src/control/Curves.cpp @@ -2,8 +2,6 @@ #include "Curves.h" -//--MIAMI: file done - float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y) { CVector2D dir1(dir1X, dir1Y); diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 0f68a989..a6aca57e 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -16,8 +16,6 @@ #include "Vehicle.h" #include "GameLogic.h" -//--MIAMI: file done - #define FRENZY_ANY_PED -1 #define FRENZY_ANY_CAR -2 @@ -73,13 +71,21 @@ CDarkel::DrawMessages() { CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(610.0f)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 30)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 30); +#endif CFont::SetCentreOn(); CFont::SetPropOn(); uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; if (bStandardSoundAndMessages) { if (timePassedSinceStart >= 3000 && timePassedSinceStart < 11000) { +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); +#else + CFont::SetScale(1.3f, 1.3f); +#endif CFont::SetJustifyOff(); CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 3000, 11000))); CFont::SetFontStyle(FONT_STANDARD); @@ -89,7 +95,11 @@ CDarkel::DrawMessages() } } else { if (timePassedSinceStart < 8000) { +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); +#else + CFont::SetScale(1.3f, 1.3f); +#endif CFont::SetJustifyOff(); CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 0, 8000))); CFont::SetFontStyle(FONT_STANDARD); @@ -98,7 +108,11 @@ CDarkel::DrawMessages() } } } +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(0.75f), SCREEN_SCALE_Y(1.5f)); +#else + CFont::SetScale(0.75f, 1.5f); +#endif CFont::SetCentreOff(); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); @@ -127,13 +141,25 @@ CDarkel::DrawMessages() uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; if (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart < 5000) { CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(620.0f)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 20); +#endif CFont::SetCentreOn(); +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); +#else + CFont::SetScale(1.5f, 1.5f); +#endif CFont::SetJustifyOff(); CFont::SetColor(CRGBA(128, 255, 128, CalcFade(timePassedSinceStart, 0, 5000))); CFont::SetFontStyle(FONT_STANDARD); +#ifdef FIX_BUGS int y = SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(25.0f - timePassedSinceStart * 0.01f); +#else + int y = (SCREEN_HEIGHT / 2 + 25) - (timePassedSinceStart * 0.01f); +#endif CFont::PrintString(SCREEN_WIDTH / 2, y, TheText.Get("KF_3")); } } @@ -295,11 +321,16 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode CPlayerPed *player = FindPlayerPed(); if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { InterruptedWeaponSelected = player->GetWeapon()->m_eWeaponType; +#if (defined FIX_BUGS || !defined GTA_PS2) player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); +#endif InterruptedWeaponType = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_eWeaponType; AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal; if (InterruptedWeaponType) CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->AddRef(); +#if (!defined FIX_BUGS && defined GTA_PS2) + player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); +#endif player->GiveWeapon(fixedWeapon, 30000); player->SetCurrentWeapon(fixedWeapon); player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot); diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp index e7f7d525..33c40c91 100644 --- a/src/control/GameLogic.cpp +++ b/src/control/GameLogic.cpp @@ -46,8 +46,6 @@ CVector CGameLogic::ShortCutDropOffForMission; float CGameLogic::ShortCutDropOffOrientationForMission; bool CGameLogic::MissionDropOffReadyToBeUsed; -//--MIAMI: file done - #define SHORTCUT_TAXI_COST (9) #define TOTAL_BUSTED_AUDIO (28) @@ -222,7 +220,7 @@ CGameLogic::Update() pPlayerInfo.m_WBState = WBSTATE_PLAYING; int takeMoney; - switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) { + switch (pPlayerInfo.m_pPed->m_pWanted->GetWantedLevel()) { case 0: case 1: takeMoney = 100; diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index b27b3c20..e3b5aa8c 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -4,9 +4,7 @@ #include "main.h" #include "Bike.h" -#ifdef FIX_BUGS #include "Boat.h" -#endif #include "DMAudio.h" #include "General.h" #include "Font.h" @@ -25,8 +23,7 @@ #include "Vehicle.h" #include "Wanted.h" #include "World.h" - -//--MIAMI: file done +#include "VarConsole.h" #define CRUSHER_GARAGE_X1 (1135.5f) #define CRUSHER_GARAGE_Y1 (57.0f) @@ -47,7 +44,7 @@ // Distances #define DISTANCE_TO_CALL_OFF_CHASE (10.0f) -#define DISTANCE_FOR_MRWHOOP_HACK (4.0f) +#define DISTANCE_FOR_MRWHOOP_HACK (0.5f) #define DISTANCE_TO_ACTIVATE_GARAGE (8.0f) #define DISTANCE_TO_ACTIVATE_KEEPCAR_GARAGE (17.0f) #define DISTANCE_TO_CLOSE_MISSION_GARAGE (30.0f) @@ -109,7 +106,7 @@ const int32 gaCarsToCollectInCraigsGarages[TOTAL_COLLECTCARS_GARAGES][TOTAL_COLL { MI_VOODOO, MI_CUBAN, MI_CADDY, MI_BAGGAGE, MI_MRWHOOP, MI_PIZZABOY } }; -const int32 gaCarsToCollectIn60Seconds[] = { MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO }; // what is this? +const int32 gaCarsToCollectIn60Seconds[] = { MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO }; int32 CGarages::BankVansCollected; bool CGarages::BombsAreFree; @@ -126,13 +123,20 @@ uint32 CGarages::MessageEndTime; uint32 CGarages::NumGarages; bool CGarages::PlayerInGarage; int32 CGarages::PoliceCarsCollected; -CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][CGarages::MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; -int32 CGarages::AudioEntity = AEHANDLE_NONE; +CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; +int32 hGarages = AEHANDLE_NONE; CGarage CGarages::aGarages[NUM_GARAGES]; bool CGarages::bCamShouldBeOutisde; +#ifndef MASTER +bool bPrintNearestObject; +#endif + void CGarages::Init(void) { +#ifndef MASTER + VarConsole.Add("Print nearest object", &bPrintNearestObject, true); +#endif CrushedCarId = -1; NumGarages = 0; MessageEndTime = 0; @@ -148,41 +152,51 @@ void CGarages::Init(void) for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++) CarTypesCollected[i] = 0; LastTimeHelpMessage = 0; - for (int i = 0; i < TOTAL_HIDEOUT_GARAGES; i++) { - for (int j = 0; j < MAX_NUM_CARS_IN_HIDEOUT_GARAGE; j++) - aCarsInSafeHouses[i][j].Init(); + for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) { + for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) + aCarsInSafeHouses[j][i].Init(); } - AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); - if (AudioEntity >= 0) - DMAudio.SetEntityStatus(AudioEntity, 1); + hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); + if (hGarages >= 0) + DMAudio.SetEntityStatus(hGarages, true); } void CGarages::Shutdown(void) { NumGarages = 0; - if (AudioEntity < 0) + if (hGarages < 0) return; - DMAudio.DestroyEntity(AudioEntity); - AudioEntity = AEHANDLE_NONE; + DMAudio.DestroyEntity(hGarages); + hGarages = AEHANDLE_NONE; } void CGarages::Update(void) { - static int GarageToBeTidied = 0; -#ifndef PS2 + static uint32 GarageToBeTidied = 0; if (CReplay::IsPlayingBack()) return; +#ifdef SECUROM + extern uint8 gameProcessPirateCheck; + if (gameProcessPirateCheck == 2) return; #endif bCamShouldBeOutisde = false; TheCamera.pToGarageWeAreIn = nil; TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = nil; +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (aGarages[i].IsUsed()) aGarages[i].Update(); } if ((CTimer::GetFrameCounter() & 0xF) != 0xC) return; +#ifdef FIX_BUGS + if (++GarageToBeTidied >= NumGarages) +#else if (++GarageToBeTidied >= NUM_GARAGES) +#endif GarageToBeTidied = 0; if (!aGarages[GarageToBeTidied].IsUsed()) return; @@ -192,7 +206,7 @@ void CGarages::Update(void) aGarages[GarageToBeTidied].TidyUpGarage(); } -int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, eGarageType type, int32 targetId) +int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, uint8 type, int32 targetId) { if (NumGarages >= NUM_GARAGES) { assert(0); @@ -293,7 +307,7 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X return NumGarages++; } -void CGarages::ChangeGarageType(int16 garage, eGarageType type, int32 mi) +void CGarages::ChangeGarageType(int16 garage, uint8 type, int32 mi) { CGarage* pGarage = &aGarages[garage]; pGarage->m_eGarageType = type; @@ -339,6 +353,43 @@ void CGarage::Update() } if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED) return; + if (m_bRotatedDoor) { +#ifdef GTA_PS2 + if (m_eGarageState == GS_OPENING) { + if (m_pDoor1) { + if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1) + m_pDoor1->bUsesCollision = false; + } + if (m_pDoor2) { + if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2) + m_pDoor2->bUsesCollision = false; + } + } + else if (m_eGarageState == GS_OPENED) { + if (m_pDoor1) + m_pDoor1->bUsesCollision = true; + if (m_pDoor2) + m_pDoor2->bUsesCollision = true; + } +#else + if (m_eGarageState == GS_OPENING || m_eGarageState == GS_OPENED) { + if (m_pDoor1) { + if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding) + m_pDoor1->bUsesCollision = false; + } + if (m_pDoor2) { + if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding) + m_pDoor2->bUsesCollision = false; + } + } + else { + if (m_pDoor1) + m_pDoor1->bUsesCollision = true; + if (m_pDoor2) + m_pDoor2->bUsesCollision = true; + } +#endif + } switch (m_eGarageType) { case GARAGE_RESPRAY: switch (m_eGarageState) { @@ -378,7 +429,7 @@ void CGarage::Update() if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); CStats::CheckPointReachedSuccessfully(); } UpdateDoorsHeight(); @@ -399,7 +450,7 @@ void CGarage::Update() m_eGarageState = GS_OPENING; DMAudio.PlayFrontEndSound(SOUND_GARAGE_OPENING, 1); bool bTakeMoney = false; - if (FindPlayerPed()->m_pWanted->m_nWantedLevel != 0) { + if (FindPlayerPed()->m_pWanted->GetWantedLevel() != 0) { bTakeMoney = true; FindPlayerPed()->m_pWanted->Suspend(); } @@ -482,7 +533,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENEDCONTAINSCAR; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -526,7 +577,7 @@ void CGarage::Update() if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } UpdateDoorsHeight(); if (m_eGarageType == GARAGE_BOMBSHOP3) @@ -539,14 +590,18 @@ void CGarage::Update() case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_SET, 1); break; case GARAGE_BOMBSHOP2: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB2_SET, 1); break; case GARAGE_BOMBSHOP3: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB3_SET, 1); break; - default: break; } m_eGarageState = GS_OPENING; if (!CGarages::BombsAreFree) CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE); if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) { +#if (!defined GTA_PS2 || defined FIX_BUGS) FindPlayerVehicle()->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType); FindPlayerVehicle()->m_pBombRigger = FindPlayerPed(); +#else // PS2 version contained a bug: CBike was casted to CAutomobile, but due to coincidence it didn't corrupt memory + ((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType); + ((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed(); +#endif if (m_eGarageType == GARAGE_BOMBSHOP3) CGarages::GivePlayerDetonator(); CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB; @@ -584,7 +639,6 @@ void CGarage::Update() case GARAGE_BOMBSHOP3: CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb. break; - default: break; } CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE); FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false; @@ -598,7 +652,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENEDCONTAINSCAR; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -616,13 +670,17 @@ void CGarage::Update() switch (m_eGarageState) { case GS_OPENED: if (((CVector2D)FindPlayerCoors() - CVector2D(GetGarageCenterX(), GetGarageCenterY())).MagnitudeSqr() > SQR(DISTANCE_TO_CLOSE_MISSION_GARAGE)) { - if ((CTimer::GetFrameCounter() & 0x1F) == 0 && !IsAnyOtherCarTouchingGarage(nil)) { + if ((CTimer::GetFrameCounter() & 0x1F) == 0 +#ifndef GTA_PS2 + && (!m_pTarget || IsEntityTouching3D(m_pTarget)) +#endif + ) { m_eGarageState = GS_CLOSING; m_bClosingWithoutTargetCar = true; } } else if (!FindPlayerVehicle() && m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) && - !IsAnyOtherCarTouchingGarage(m_pTarget) && IsEntityEntirelyOutside(FindPlayerPed(), 2.0f)) { + IsEntityEntirelyOutside(FindPlayerVehicle() ? (CEntity*)FindPlayerVehicle() : (CEntity*)FindPlayerPed(), 2.0f)) { CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE); FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true; m_eGarageState = GS_CLOSING; @@ -634,7 +692,7 @@ void CGarage::Update() ThrowCarsNearDoorOutOfGarage(m_pTarget); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); if (m_bClosingWithoutTargetCar) m_eGarageState = GS_FULLYCLOSED; else { @@ -664,7 +722,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -717,7 +775,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); if (m_pTarget) { MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex()); DestroyVehicleAndDriverAndPassengers(m_pTarget); @@ -757,7 +815,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -778,7 +836,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } if (!IsGarageEmpty()) m_eGarageState = GS_OPENING; @@ -789,7 +847,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -823,7 +881,7 @@ void CGarage::Update() ThrowCarsNearDoorOutOfGarage(m_pTarget); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); if (m_bClosingWithoutTargetCar) m_eGarageState = GS_FULLYCLOSED; else { @@ -852,7 +910,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -872,7 +930,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -892,7 +950,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } UpdateDoorsHeight(); break; @@ -900,7 +958,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -932,8 +990,8 @@ void CGarage::Update() // Close car doors either if player is far, or if he is in vehicle and garage is full, // or if player is very very far so that we can remove whatever is blocking garage door without him noticing if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) || - !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT) && - !IsAnyCarBlockingDoor())) + !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT)) && + !IsAnyCarBlockingDoor()) m_eGarageState = GS_CLOSING; else if (FindPlayerVehicle() && CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >= @@ -951,7 +1009,7 @@ void CGarage::Update() if (!IsPlayerOutsideGarage()) m_eGarageState = GS_OPENING; else if (m_fDoorPos == 0.0f) { - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); m_eGarageState = GS_FULLYCLOSED; StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS); } @@ -982,7 +1040,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1009,7 +1067,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } UpdateDoorsHeight(); break; @@ -1025,7 +1083,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1036,8 +1094,8 @@ void CGarage::Update() break; } break; - //case GARAGE_COLLECTORSITEMS: - //case GARAGE_60SECONDS: + //case GARAGE_COLLECTORSITEMS: + //case GARAGE_60SECONDS: case GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR: switch (m_eGarageState) { case GS_OPENED: @@ -1046,20 +1104,23 @@ void CGarage::Update() m_eGarageState = GS_CLOSING; m_bClosingWithoutTargetCar = false; } + break; case GS_CLOSING: m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f); CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE); } + UpdateDoorsHeight(); + break; case GS_FULLYCLOSED: break; case GS_OPENING: m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1074,28 +1135,6 @@ void CGarage::Update() } } -void CGarage::ThrowCarsNearDoorOutOfGarage(CVehicle* pException) -{ - uint32 i = CPools::GetVehiclePool()->GetSize(); - while (i--) { - CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); - if (!pVehicle || pVehicle == pException) - continue; - if (!IsEntityTouching3D(pVehicle)) - continue; - CColModel* pColModel = pVehicle->GetColModel(); - for (int i = 0; i < pColModel->numSpheres; i++) { - CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center; - float radius = pColModel->spheres[i].radius; - if (!IsPointInsideGarage(pos, 0.0f)) { - CVector vecDirectionAway(pVehicle->GetPosition().x - GetGarageCenterX(), pVehicle->GetPosition().y - GetGarageCenterY(), 0.0f); - vecDirectionAway.Normalise(); - pVehicle->AddToMoveSpeed(vecDirectionAway * CTimer::GetTimeStepInSeconds()); - } - } - } -} - bool CGarage::IsStaticPlayerCarEntirelyInside() { if (!FindPlayerVehicle()) @@ -1160,7 +1199,7 @@ bool CGarage::IsPointInsideGarage(CVector pos, float m_fMargin) return true; } -bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin) +bool CGarage::IsEntityEntirelyInside3D(CEntity* pEntity, float fMargin) { if (pEntity->GetPosition().x < m_fInfX - fMargin || pEntity->GetPosition().x > m_fSupX + fMargin || pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin || @@ -1212,12 +1251,12 @@ bool CGarage::IsPlayerOutsideGarage() return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f); } -bool CGarage::IsEntityTouching3D(CEntity * pEntity) +bool CGarage::IsEntityTouching3D(CEntity* pEntity) { float radius = pEntity->GetBoundRadius(); - if (pEntity->GetPosition().x - radius < m_fInfX || pEntity->GetPosition().x + radius > m_fSupX || - pEntity->GetPosition().y - radius < m_fInfY || pEntity->GetPosition().y + radius > m_fSupY || - pEntity->GetPosition().z - radius < m_fInfZ || pEntity->GetPosition().z + radius > m_fSupZ) + if (m_fInfX - radius > pEntity->GetPosition().x || m_fSupX + radius < pEntity->GetPosition().x || + m_fInfY - radius > pEntity->GetPosition().y || m_fSupY + radius < pEntity->GetPosition().y || + m_fInfZ - radius > pEntity->GetPosition().z || m_fSupZ + radius < pEntity->GetPosition().z) return false; CColModel* pColModel = pEntity->GetColModel(); for (int i = 0; i < pColModel->numSpheres; i++) { @@ -1261,6 +1300,28 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException) return false; } +void CGarage::ThrowCarsNearDoorOutOfGarage(CVehicle* pException) +{ + uint32 i = CPools::GetVehiclePool()->GetSize(); + while (i--) { + CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); + if (!pVehicle || pVehicle == pException) + continue; + if (!IsEntityTouching3D(pVehicle)) + continue; + CColModel* pColModel = pVehicle->GetColModel(); + for (int i = 0; i < pColModel->numSpheres; i++) { + CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center; + float radius = pColModel->spheres[i].radius; + if (!IsPointInsideGarage(pos, 0.0f)) { + CVector vecDirectionAway(pVehicle->GetPosition().x - GetGarageCenterX(), pVehicle->GetPosition().y - GetGarageCenterY(), 0.0f); + vecDirectionAway.Normalise(); + pVehicle->AddToMoveSpeed(vecDirectionAway * CTimer::GetTimeStepInSeconds()); + } + } + } +} + bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException) { uint32 i = CPools::GetPedPool()->GetSize(); @@ -1328,7 +1389,9 @@ void CGarage::RemoveCarsBlockingDoorNotInside() if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) { CWorld::Remove(pVehicle); delete pVehicle; - return; // WHY? +#ifndef FIX_BUGS + return; +#endif } } } @@ -1337,43 +1400,34 @@ void CGarage::RemoveCarsBlockingDoorNotInside() void CGarages::PrintMessages() { if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) { - CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f)); // BUG: game doesn't use macro here. + CFont::DrawFonts(); + CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f)); CFont::SetPropOn(); CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(590.0f)); - CFont::SetCentreOn(); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); - CFont::SetColor(CRGBA(0, 0, 0, 255)); - -#if defined(PS2) || defined (FIX_BUGS) - float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 50)); #else - float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements + CFont::SetCentreSize(SCREEN_WIDTH - 50); #endif + CFont::SetCentreOn(); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetColor(CRGBA(27, 89, 130, 255)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); - if (MessageNumberInString2 < 0) { - if (MessageNumberInString < 0) { - CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString)); - - CFont::SetColor(CRGBA(27, 89, 130, 255)); - CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString)); - } - else { - CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString); - - CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString); + float y_offset = SCREEN_SCALE_Y(140.0f); - CFont::SetColor(CRGBA(27, 89, 130, 255)); - CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString); - } + if (MessageNumberInString2 >= 0) { + CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString); + CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString); + } + else if (MessageNumberInString >= 0) { + CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString); + CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString); } else { - CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString); - CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString); - - CFont::SetColor(CRGBA(27, 89, 130, 255)); - CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString); + CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString)); } } } @@ -1390,7 +1444,9 @@ bool CGarages::IsCarSprayable(CVehicle * pVehicle) case MI_BARRACKS: case MI_DODO: case MI_COACH: +#ifndef GTA_PS2 case MI_FBIRANCH: +#endif return false; default: break; @@ -1462,41 +1518,54 @@ void CGarage::UpdateCrusherShake(float X, float Y) m_pDoor2->GetMatrix().GetPosition().y -= Y; } -// This is dumb but there is no way to avoid goto. What was there originally even? -static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, uint8 nIndex) +void CGarage::RefreshDoorPointers(bool bCreate) { - bool bNeedToFindDoorEntities = false; - if (pDoor) { - if (bIsDummy) { - if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex((CDummy*)pDoor))) - return true; - if (nIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)pDoor) & 0x7F)) + bool bNeedToFindDoorEntities = bCreate || m_bRecreateDoorOnNextRefresh; + m_bRecreateDoorOnNextRefresh = false; + if (m_pDoor1) { + if (m_bDoor1IsDummy) { + if (CPools::GetDummyPool()->GetIsFree(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor1))) bNeedToFindDoorEntities = true; - if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex())) - return true; + else { + if (m_bDoor1PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor1) & 0x7F)) + bNeedToFindDoorEntities = true; + if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex())) + bNeedToFindDoorEntities = true; + } } else { - if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex((CObject*)pDoor))) - return true; - if (nIndex != (CPools::GetObjectPool()->GetIndex((CObject*)pDoor) & 0x7F)) + if (CPools::GetObjectPool()->GetIsFree(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor1))) bNeedToFindDoorEntities = true; - if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex())) - return true; + else { + if (m_bDoor1PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor1) & 0x7F)) + bNeedToFindDoorEntities = true; + if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex())) + bNeedToFindDoorEntities = true; + } + } + } + if (m_pDoor2) { + if (m_bDoor2IsDummy) { + if (CPools::GetDummyPool()->GetIsFree(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor2))) + bNeedToFindDoorEntities = true; + else { + if (m_bDoor2PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor2) & 0x7F)) + bNeedToFindDoorEntities = true; + if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex())) + bNeedToFindDoorEntities = true; + } + } + else { + if (CPools::GetObjectPool()->GetIsFree(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor2))) + bNeedToFindDoorEntities = true; + else { + if (m_bDoor2PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor2) & 0x7F)) + bNeedToFindDoorEntities = true; + if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex())) + bNeedToFindDoorEntities = true; + } } } - return bNeedToFindDoorEntities; -} - -void CGarage::RefreshDoorPointers(bool bCreate) -{ - bool bNeedToFindDoorEntities = true; - if (!bCreate && !m_bRecreateDoorOnNextRefresh) - bNeedToFindDoorEntities = false; - m_bRecreateDoorOnNextRefresh = false; - if (DoINeedToRefreshPointer(m_pDoor1, m_bDoor1IsDummy, m_bDoor1PoolIndex)) - bNeedToFindDoorEntities = true; - if (DoINeedToRefreshPointer(m_pDoor2, m_bDoor2IsDummy, m_bDoor2PoolIndex)) - bNeedToFindDoorEntities = true; if (bNeedToFindDoorEntities) FindDoorsEntities(); } @@ -1520,7 +1589,7 @@ void CGarages::TriggerMessage(const char* text, int16 num1, uint16 time, int16 n MessageNumberInString2 = num2; } -void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle * pVehicle) +void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle* pVehicle) { assert(garage >= 0 && garage < NUM_GARAGES); if (pVehicle) { @@ -1663,10 +1732,10 @@ void CGarage::FindDoorsEntities() { m_pDoor1 = nil; m_pDoor2 = nil; - int xstart = Max(0, CWorld::GetSectorIndexX(m_fInfX)); - int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fSupX)); - int ystart = Max(0, CWorld::GetSectorIndexY(m_fInfY)); - int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY)); + int xstart = Max(0, CWorld::GetSectorIndexX(GetGarageCenterX() - 100.0f)); + int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(GetGarageCenterX() + 100.0f)); + int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY() - 100.0f)); + int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(GetGarageCenterY() + 100.0f)); assert(xstart <= xend); assert(ystart <= yend); @@ -1779,8 +1848,8 @@ void CStoredCar::StoreCar(CVehicle* pVehicle) m_bExplosionproof = pVehicle->bExplosionProof; m_bCollisionproof = pVehicle->bCollisionProof; m_bMeleeproof = pVehicle->bMeleeProof; - if (pVehicle->IsCar()) - m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; + if (pVehicle->IsCar() || pVehicle->IsBike()) + m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour } CVehicle* CStoredCar::RestoreCar() @@ -1817,9 +1886,7 @@ CVehicle* CStoredCar::RestoreCar() pVehicle->m_currentColour2 = m_nSecondaryColor; pVehicle->m_nRadioStation = m_nRadioStation; pVehicle->bFreebies = false; -#ifdef FIX_BUGS if (pVehicle->IsCar()) -#endif { ((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType; #ifdef FIX_BUGS @@ -1882,7 +1949,11 @@ bool CGarage::RestoreCarsForThisHideout(CStoredCar* aCars) bool CGarages::IsPointInAGarageCameraZone(CVector point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: break; @@ -1909,8 +1980,13 @@ bool CGarages::CameraShouldBeOutside() void CGarages::GivePlayerDetonator() { - FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR, 1); - FindPlayerPed()->GetWeapon(FindPlayerPed()->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY; + CPlayerPed* pPed = FindPlayerPed(); + int slot = CWeaponInfo::GetWeaponInfo(WEAPONTYPE_DETONATOR)->m_nWeaponSlot; + pPed->GiveWeapon(WEAPONTYPE_DETONATOR, 1); + pPed->GetWeapon(pPed->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY; + pPed->m_nSelectedWepSlot = slot; + if (pPed->m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) + pPed->m_storedWeapon = WEAPONTYPE_DETONATOR; } float CGarages::FindDoorHeightForMI(int32 mi) @@ -1923,12 +1999,12 @@ void CGarage::TidyUpGarage() uint32 i = CPools::GetVehiclePool()->GetSize(); while (i--) { CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); - if (!pVehicle || !pVehicle->IsCar()) - continue; - if (IsPointInsideGarage(pVehicle->GetPosition())) { - if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) { - CWorld::Remove(pVehicle); - delete pVehicle; + if (pVehicle && (pVehicle->IsCar() || pVehicle->IsBike())) { + if (IsPointInsideGarage(pVehicle->GetPosition())) { + if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) { + CWorld::Remove(pVehicle); + delete pVehicle; + } } } } @@ -1939,9 +2015,9 @@ void CGarage::TidyUpGarageClose() uint32 i = CPools::GetVehiclePool()->GetSize(); while (i--) { CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); - if (!pVehicle || !pVehicle->IsCar()) + if (!pVehicle) continue; - if (!pVehicle->IsCar() || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle)) + if ((!pVehicle->IsCar() && !pVehicle->IsBike()) || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle)) continue; bool bRemove = false; if (m_eGarageState != GS_FULLYCLOSED) { @@ -1966,7 +2042,11 @@ void CGarage::TidyUpGarageClose() void CGarages::PlayerArrestedOrDied() { static int GarageToBeTidied = 0; // lol +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (aGarages[i].m_eGarageType != GARAGE_NONE) aGarages[i].PlayerArrestedOrDied(); } @@ -2061,20 +2141,24 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle) void CGarages::CloseHideOutGaragesBeforeSave() { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (!IsThisGarageTypeSafehouse(aGarages[i].m_eGarageType)) continue; if (aGarages[i].m_eGarageState != GS_FULLYCLOSED) { aGarages[i].m_eGarageState = GS_FULLYCLOSED; aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouses[FindSafeHouseIndexForGarageType(aGarages[i].m_eGarageType)], NUM_GARAGE_STORED_CARS); aGarages[i].RemoveCarsBlockingDoorNotInside(); + aGarages[i].m_fDoorPos = 0.0f; + aGarages[i].UpdateDoorsHeight(); } - aGarages[i].m_fDoorPos = 0.0f; - aGarages[i].UpdateDoorsHeight(); } } -int32 CGarages::CountCarsInHideoutGarage(eGarageType type) +int32 CGarages::CountCarsInHideoutGarage(uint8 type) { int32 total = 0; for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) { @@ -2085,11 +2169,24 @@ int32 CGarages::CountCarsInHideoutGarage(eGarageType type) bool CGarages::IsPointWithinHideOutGarage(Const CVector& point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_HIDEOUT_ONE: case GARAGE_HIDEOUT_TWO: case GARAGE_HIDEOUT_THREE: + case GARAGE_HIDEOUT_FOUR: + case GARAGE_HIDEOUT_FIVE: + case GARAGE_HIDEOUT_SIX: + case GARAGE_HIDEOUT_SEVEN: + case GARAGE_HIDEOUT_EIGHT: + case GARAGE_HIDEOUT_NINE: + case GARAGE_HIDEOUT_TEN: + case GARAGE_HIDEOUT_ELEVEN: + case GARAGE_HIDEOUT_TWELVE: if (aGarages[i].IsPointInsideGarage(point)) return true; default: break; @@ -2100,7 +2197,11 @@ bool CGarages::IsPointWithinHideOutGarage(Const CVector& point) bool CGarages::IsPointWithinAnyGarage(Const CVector& point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: continue; @@ -2114,7 +2215,11 @@ bool CGarages::IsPointWithinAnyGarage(Const CVector& point) void CGarages::SetAllDoorsBackToOriginalHeight() { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: continue; @@ -2252,3 +2357,41 @@ CGarages::IsModelIndexADoor(uint32 id) id == MI_GARAGEDOOR25 || id == MI_GARAGEDOOR26; } + +void CGarages::StopCarFromBlowingUp(CAutomobile* pCar) +{ + pCar->m_fFireBlowUpTimer = 0.0f; + pCar->m_fHealth = Max(pCar->m_fHealth, 300.0f); + pCar->Damage.SetEngineStatus(Max(pCar->Damage.GetEngineStatus(), 275)); +} + +bool CGarage::Does60SecondsNeedThisCarAtAll(int mi) +{ + for (int i = 0; i < ARRAY_SIZE(gaCarsToCollectIn60Seconds); i++) { + if (gaCarsToCollectIn60Seconds[i] == mi) + return true; + } + return false; +} + +bool CGarage::Does60SecondsNeedThisCar(int mi) +{ + for (int i = 0; i < ARRAY_SIZE(gaCarsToCollectIn60Seconds); i++) { + if (gaCarsToCollectIn60Seconds[i] == mi) + return m_bCollectedCarsState & BIT(i); + } + return false; +} + +void CGarage::MarkThisCarAsCollectedFor60Seconds(int mi) +{ + for (int i = 0; i < ARRAY_SIZE(gaCarsToCollectIn60Seconds); i++) { + if (gaCarsToCollectIn60Seconds[i] == mi) + m_bCollectedCarsState |= BIT(i); + } +} + +bool CGarage::IsPlayerEntirelyInsideGarage() +{ + return IsEntityEntirelyInside3D(FindPlayerVehicle() ? (CEntity*)FindPlayerVehicle() : (CEntity*)FindPlayerPed(), 0.0f); +} diff --git a/src/control/Garages.h b/src/control/Garages.h index 04c01719..07d5f712 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -1,13 +1,12 @@ #pragma once -#include "Automobile.h" #include "audio_enums.h" #include "Camera.h" #include "config.h" +#include "Lists.h" class CVehicle; -class CCamera; -enum eGarageState : int8 +enum eGarageState { GS_FULLYCLOSED, GS_OPENED, @@ -18,7 +17,7 @@ enum eGarageState : int8 GS_AFTERDROPOFF, }; -enum eGarageType : int8 +enum eGarageType { GARAGE_NONE, GARAGE_MISSION, @@ -93,8 +92,9 @@ VALIDATE_SIZE(CStoredCar, 0x28); class CGarage { - eGarageType m_eGarageType; - eGarageState m_eGarageState; +public: + uint8 m_eGarageType; + uint8 m_eGarageState; uint8 m_nMaxStoredCars; bool field_2; // unused bool m_bClosingWithoutTargetCar; @@ -148,8 +148,8 @@ class CGarage return Abs(TheCamera.GetPosition().x - GetGarageCenterX()) > SWITCH_GARAGE_DISTANCE_CLOSE || Abs(TheCamera.GetPosition().y - GetGarageCenterY()) > SWITCH_GARAGE_DISTANCE_CLOSE; #else - return Abs(TheCamera.GetPosition().x - m_fX1) > SWITCH_GARAGE_DISTANCE_CLOSE || - Abs(TheCamera.GetPosition().y - m_fY1) > SWITCH_GARAGE_DISTANCE_CLOSE; + return Abs(TheCamera.GetPosition().x - m_fInfX) > SWITCH_GARAGE_DISTANCE_CLOSE || + Abs(TheCamera.GetPosition().y - m_fInfY) > SWITCH_GARAGE_DISTANCE_CLOSE; #endif } void TidyUpGarageClose(); @@ -182,24 +182,25 @@ class CGarage void FindDoorsEntities(); void FindDoorsEntitiesSectorList(CPtrList&, bool); void PlayerArrestedOrDied(); + bool Does60SecondsNeedThisCarAtAll(int mi); + bool Does60SecondsNeedThisCar(int mi); + void MarkThisCarAsCollectedFor60Seconds(int mi); + bool IsPlayerEntirelyInsideGarage(); bool IsPointInsideGarage(CVector); bool IsPointInsideGarage(CVector, float); void ThrowCarsNearDoorOutOfGarage(CVehicle*); - int32 FindMaxNumStoredCarsForGarage() { return Max(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); } + int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); } - friend class CGarages; - friend class cAudioManager; - friend class CCamera; }; class CGarages { enum { MESSAGE_LENGTH = 8, - MAX_NUM_CARS_IN_HIDEOUT_GARAGE = 4 }; +public: static int32 BankVansCollected; static bool BombsAreFree; static bool RespraysAreFree; @@ -216,19 +217,17 @@ class CGarages static bool PlayerInGarage; static int32 PoliceCarsCollected; static CGarage aGarages[NUM_GARAGES]; - static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; - static int32 AudioEntity; + static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; static bool bCamShouldBeOutisde; -public: static void Init(void); #ifndef PS2 static void Shutdown(void); #endif static void Update(void); - static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, eGarageType type, int32 targetId); - static void ChangeGarageType(int16, eGarageType, int32); + static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, uint8 type, int32 targetId); + static void ChangeGarageType(int16, uint8, int32); static void PrintMessages(void); static void TriggerMessage(const char* text, int16, uint16 time, int16); static void SetTargetCarForMissonGarage(int16, CVehicle*); @@ -259,15 +258,15 @@ public: static bool IsModelIndexADoor(uint32 id); static void SetFreeBombs(bool bValue) { BombsAreFree = bValue; } static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; } + static void StopCarFromBlowingUp(CAutomobile*); static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; } -private: static bool IsCarSprayable(CVehicle*); static float FindDoorHeightForMI(int32); static void CloseHideOutGaragesBeforeSave(void); - static int32 CountCarsInHideoutGarage(eGarageType); - static int32 GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; } - static int32 GetCarsCollectedIndexForGarageType(eGarageType type) + static int32 CountCarsInHideoutGarage(uint8); + static int32 GetBombTypeForGarageType(uint8 type) { return type - GARAGE_BOMBSHOP1 + 1; } + static int32 GetCarsCollectedIndexForGarageType(uint8 type) { switch (type) { case GARAGE_COLLECTCARS_1: return 0; @@ -278,7 +277,7 @@ private: } return 0; } - static int32 FindSafeHouseIndexForGarageType(eGarageType type) + static int32 FindSafeHouseIndexForGarageType(uint8 type) { switch (type) { case GARAGE_HIDEOUT_ONE: return 0; @@ -296,9 +295,6 @@ private: } return -1; } - static bool IsThisGarageTypeSafehouse(eGarageType type) { return FindSafeHouseIndexForGarageType(type) >= 0; } + static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; } - friend class cAudioManager; - friend class CReplay; - friend class CGarage; }; diff --git a/src/control/NameGrid.cpp b/src/control/NameGrid.cpp new file mode 100644 index 00000000..204e8b9c --- /dev/null +++ b/src/control/NameGrid.cpp @@ -0,0 +1,87 @@ +#include "common.h" +#include "NameGrid.h" + +// TODO: reverse mobile code + +CPlayerName::CPlayerName() +{ + // TODO +} + +void +CPlayerName::DisplayName(int) +{ + // TODO +} + +CRow::CRow() +{ + // TODO +} + +void +CRow::SetLetter(int, wchar *) +{ + // TODO +} + +CGrid::CGrid() +{ + // TODO +} + +void +CGrid::ProcessAnyLeftJustDown() +{ + unk_int2--; +} + +void +CGrid::ProcessAnyRightJustDown() +{ + unk_int2++; +} + +void +CGrid::ProcessAnyUpJustDown() +{ + unk_int1--; +} + +void +CGrid::ProcessAnyDownJustDown() +{ + unk_int1++; +} + +void +CGrid::AllDoneMakePlayerName() +{ + // TODO +} + +void +CGrid::ProcessDPadCrossJustDown() +{ + // TODO +} + +void +CGrid::DisplayGrid() +{ + // TODO +} + +void +CGrid::ProcessControllerInput() +{ + // TODO +} + +void +CGrid::Process() +{ + ProcessControllerInput(); + DisplayGrid(); + playerName.DisplayName(2 * playerName.unk_4c); +}
\ No newline at end of file diff --git a/src/control/NameGrid.h b/src/control/NameGrid.h new file mode 100644 index 00000000..d52cec73 --- /dev/null +++ b/src/control/NameGrid.h @@ -0,0 +1,53 @@ +#pragma once + +// TODO: reverse mobile code + +class CPlayerName +{ + friend class CGrid; + + float x; + float y; + wchar unk_8[34]; + int unk_4c; +public: + CPlayerName(); + void DisplayName(int); +}; + +class CRow +{ + friend class CGrid; + + int unk_0; + int unk_4; + wchar unk_8[20]; + int unk_30; +public: + CRow(); + void SetLetter(int, wchar *); +}; + +class CGrid +{ + CRow rows[5]; + int unk_int1; + int unk_int2; + int unk_int3; + float unk_float1; + float unk_float2; + CPlayerName playerName; + char unk2[4]; + char unk3[4]; +public: + CGrid(); + void ProcessAnyLeftJustDown(); + void ProcessAnyRightJustDown(); + void ProcessAnyUpJustDown(); + void ProcessAnyDownJustDown(); + void AllDoneMakePlayerName(); + void ProcessDPadCrossJustDown(); + void DisplayGrid(); + void ProcessControllerInput(); + void Process(); +};
\ No newline at end of file diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp index 52d00f43..08e6fa3f 100644 --- a/src/control/OnscreenTimer.cpp +++ b/src/control/OnscreenTimer.cpp @@ -9,8 +9,6 @@ #include "OnscreenTimer.h" #include "Camera.h" -// --MIAMI: file done - void COnscreenTimer::Init() { m_bDisabled = false; for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) { diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index e10693eb..2d3972f6 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -8,8 +8,6 @@ #include "Lines.h" // for debug #include "PathFind.h" -//--MIAMI: file done except mobile unused function - bool gbShowPedPaths; bool gbShowCarPaths; bool gbShowCarPathsLinks; @@ -286,6 +284,8 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) DetachedInfoForTilePeds = new CPathInfoForObject[12*NUMDETACHED_PEDS]; memset(DetachedInfoForTilePeds, 0, 12*NUMDETACHED_PEDS*sizeof(CPathInfoForObject)); + delete[] TempExternalNodes; + TempExternalNodes = nil; TempExternalNodes = new CTempNodeExternal[NUMTEMPEXTERNALNODES]; memset(TempExternalNodes, 0, NUMTEMPEXTERNALNODES*sizeof(CTempNodeExternal)); NumTempExternalNodes = 0; @@ -338,17 +338,17 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, InfoForTileCars[i].x = x/16.0f; InfoForTileCars[i].y = y/16.0f; InfoForTileCars[i].z = z/16.0f; - InfoForTilePeds[i].width = 8.0f*Min(width, 15.0f); + InfoForTileCars[i].width = 8.0f*Min(width, 15.0f); InfoForTileCars[i].numLeftLanes = numLeft; InfoForTileCars[i].numRightLanes = numRight; - InfoForTilePeds[i].crossing = false; - InfoForTilePeds[i].speedLimit = 0; - InfoForTilePeds[i].roadBlock = false; - InfoForTilePeds[i].disabled = false; - InfoForTilePeds[i].waterPath = false; - InfoForTilePeds[i].onlySmallBoats = false; - InfoForTilePeds[i].betweenLevels = false; - InfoForTilePeds[i].spawnRate = Min(spawnRate, 15); + InfoForTileCars[i].crossing = false; + InfoForTileCars[i].speedLimit = 0; + InfoForTileCars[i].roadBlock = false; + InfoForTileCars[i].disabled = false; + InfoForTileCars[i].waterPath = false; + InfoForTileCars[i].onlySmallBoats = false; + InfoForTileCars[i].betweenLevels = false; + InfoForTileCars[i].spawnRate = Min(spawnRate, 15); if(node == 11) InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound(); @@ -1818,6 +1818,12 @@ CPathFind::Load(uint8 *buf, uint32 size) m_pathNodes[i].bBetweenLevels = true; else m_pathNodes[i].bBetweenLevels = false; + +#ifdef SECUROM + // if pirated game + for(i = 0; i < m_numPathNodes; i++) + m_pathNodes[i].bDisabled = true; +#endif } void diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index 7f8677ec..411dc8c3 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -17,8 +17,6 @@ #include "Replay.h" #endif -// --MIAMI: file done - CPhoneInfo gPhoneInfo; bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up @@ -58,7 +56,7 @@ CPhoneInfo::Update(void) } else { CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PHONE); if (player->m_nPedState == PED_MAKE_CALL) - player->m_nPedState = PED_IDLE; + player->SetPedState(PED_IDLE); } } bool notInCar; @@ -105,7 +103,7 @@ CPhoneInfo::Update(void) player->m_fRotationCur = angleToFace; player->m_fRotationDest = angleToFace; player->SetHeading(angleToFace); - player->m_nPedState = PED_MAKE_CALL; + player->SetPedState(PED_MAKE_CALL); CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PHONE); TheCamera.SetWideScreenOn(); playerInfo->MakePlayerSafe(true); @@ -286,6 +284,7 @@ CPhoneInfo::Initialise(void) CBuilding *building = pool->GetSlot(i); if (building) { if (building->GetModelIndex() == MI_PHONEBOOTH1) { + assert(m_nMax < ARRAY_SIZE(m_aPhones) && "NUMPHONES should be increased"); CPhone *maxPhone = &m_aPhones[m_nMax]; maxPhone->m_nState = PHONE_STATE_FREE; maxPhone->m_vecPos = building->GetPosition(); @@ -308,7 +307,7 @@ INITSAVEBUF // Convert entity pointer to building pool index while saving if (phone->m_pEntity) { - phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1); + phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1); } } VALIDATESAVEBUF(*size) @@ -333,7 +332,7 @@ PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) ped->bUpdateAnimHeading = true; if (ped->m_nPedState == PED_MAKE_CALL) - ped->m_nPedState = PED_IDLE; + ped->SetPedState(PED_IDLE); } void diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 1ff4f8f6..67e658c6 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -34,8 +34,6 @@ #include "Messages.h" #include "Streaming.h" -// --MIAMI: file done - CPickup CPickups::aPickUps[NUMPICKUPS]; int16 CPickups::NumMessages; int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS]; @@ -278,7 +276,7 @@ CPickup::CanBePickedUp(CPlayerPed *player, int playerId) bool cannotBePickedUp = (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > CWorld::Players[playerId].m_nMaxArmour - 0.5f) || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > CWorld::Players[playerId].m_nMaxHealth - 0.5f) - || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0) + || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->GetWantedLevel() == 0) || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame)); return !cannotBePickedUp; } @@ -596,7 +594,10 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) bool explode = false; if (CTimer::GetTimeInMilliseconds() > m_nTimer) explode = true; - else {// added else here since vehicle lookup is useless +#ifdef FIX_BUGS + else// added else here since vehicle lookup is useless +#endif + { for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) { CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i); if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) { @@ -781,7 +782,7 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); return true; } else if (modelIndex == MI_PICKUP_BRIBE) { - int32 level = Max(FindPlayerPed()->m_pWanted->m_nWantedLevel - 1, 0); + int32 level = Max(FindPlayerPed()->m_pWanted->GetWantedLevel() - 1, 0); player->SetWantedLevel(level); DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); return true; @@ -852,7 +853,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan if (slot >= NUMPICKUPS) return -1; - aPickUps[slot].m_eType = (ePickupType)type; + aPickUps[slot].m_eType = type; aPickUps[slot].m_bRemoved = false; aPickUps[slot].m_nQuantity = quantity; aPickUps[slot].m_nMoneySpeed = rate; @@ -1183,7 +1184,9 @@ CPickups::DoPickUpEffects(CEntity *entity) CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, - 0.0f); + 0.0f, + false, + -0.5f); } } @@ -1250,7 +1253,7 @@ CPickups::DoCollectableEffects(CEntity *entity) int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f; CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0, color, color, color, 4.0f, 1.0f, 40.0f, false, 0.0f); - CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_HEX, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); } entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000)); @@ -1333,7 +1336,7 @@ CPickups::RenderPickUpText() #ifdef FIX_BUGS const float MAX_SCALE = SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH; #else - const float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH; + float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH; #endif float fScaleY = aMessages[i].m_dist.y / 30.0f; @@ -1342,7 +1345,7 @@ CPickups::RenderPickUpText() float fScaleX = aMessages[i].m_dist.x / 30.0f; if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; - CFont::SetScale(fScaleX, fScaleY); + CFont::SetScale(fScaleX, fScaleY); // this shouldn't be scaled CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetJustifyOff(); @@ -1458,9 +1461,9 @@ INITSAVEBUF CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]); if (buf_pickup->m_eType != PICKUP_NONE) { if (buf_pickup->m_pObject != nil) - buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1); + buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1); if (buf_pickup->m_pExtraObject != nil) - buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pExtraObject) + 1); + buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1); } } @@ -1573,7 +1576,6 @@ CPacManPickups::ResetPowerPillsCarriedByPlayer() { } -// --MIAMI: Done void CPed::CreateDeadPedMoney(void) { @@ -1594,7 +1596,6 @@ CPed::CreateDeadPedMoney(void) m_nPedMoney = 0; } -// --MIAMI: Done void CPed::CreateDeadPedWeaponPickups(void) { @@ -1620,7 +1621,6 @@ CPed::CreateDeadPedWeaponPickups(void) ClearWeapons(); } -// --MIAMI: Done void CPed::CreateDeadPedPickupCoors(float *x, float *y, float *z) { diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 36179f66..af9503e0 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -1,7 +1,7 @@ #pragma once #include "Weapon.h" -enum ePickupType : uint8 +enum ePickupType { PICKUP_NONE = 0, PICKUP_IN_SHOP, @@ -43,7 +43,7 @@ public: int16 m_eModelIndex; uint16 m_nIndex; char m_sTextKey[8]; - ePickupType m_eType; + uint8 m_eType; bool m_bRemoved; uint8 m_bWasAmmoCollected:1; uint8 m_bWasControlMessageShown:1; diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 9b4a21fc..5e6c7cdb 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -10,8 +10,6 @@ #include "VehicleModelInfo.h" #include "World.h" -//--MIAMI: file done - uint16 CRecordDataForGame::RecordingState; void CRecordDataForGame::Init(void) diff --git a/src/control/Record.h b/src/control/Record.h index 8b55b1f4..6a94c408 100644 --- a/src/control/Record.h +++ b/src/control/Record.h @@ -57,9 +57,7 @@ public: static void RestoreInfoForMatrix(CMatrix&, CCarStateEachFrame*); static void RestoreInfoForCar(CAutomobile*, CCarStateEachFrame*, bool); static void ProcessControlCars(void); -#if (defined(GTA_PS2) || defined(FIX_BUGS)) static bool ShouldThisPadBeLeftAlone(uint8 pad); -#endif static void GiveUsACar(int32, CVector, float, CAutomobile**, uint8, uint8); static void StartChaseScene(float); static void CleanUpChaseScene(void); diff --git a/src/control/Remote.cpp b/src/control/Remote.cpp index 164a2f4c..047b19f3 100644 --- a/src/control/Remote.cpp +++ b/src/control/Remote.cpp @@ -9,8 +9,6 @@ #include "PlayerInfo.h" #include "Vehicle.h" -//--MIAMI: file done - void CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uint16 model) { diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 0c70d2f6..dbb2612d 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -53,8 +53,6 @@ #include "Fluff.h" #include "WaterCreatures.h" -//--MIAMI: file done - uint8 CReplay::Mode; CAddressInReplayBuffer CReplay::Record; CAddressInReplayBuffer CReplay::Playback; @@ -336,7 +334,7 @@ void CReplay::RecordThisFrame(void) GoToNextBlock(); tGeneralPacket* general = (tGeneralPacket*)&Record.m_pBase[Record.m_nOffset]; general->type = REPLAYPACKET_GENERAL; - general->camera_pos.CopyOnlyMatrix(&TheCamera.GetMatrix()); + general->camera_pos.CopyOnlyMatrix(TheCamera.GetMatrix()); general->player_pos = FindPlayerCoors(); general->in_rcvehicle = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle ? true : false; Record.m_nOffset += sizeof(*general); @@ -794,10 +792,19 @@ void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id) vp->matrix.CompressFromFullMatrix(vehicle->GetMatrix()); vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */ vp->acceleration = vehicle->m_fGasPedal * 100.0f; +#ifdef FIX_BUGS // originally it's undefined behaviour - different fields are copied on PC and mobile + for (int i = 0; i < 2; i++) + vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i]; + for (int i = 0; i < 2; i++) + vp->wheel_rotation[i + 2] = 128.0f / PI * bike->m_aWheelSpeed[i]; + for (int i = 0; i < 4; i++) + vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i]; +#else for (int i = 0; i < 4; i++) { vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i]; vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i]; } +#endif vp->velocityX = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */ vp->velocityY = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().y)); vp->velocityZ = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().z)); @@ -902,12 +909,19 @@ void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddress vehicle->m_vecMoveSpeed = CVector(vp->velocityX / 8000.0f, vp->velocityY / 8000.0f, vp->velocityZ / 8000.0f); vehicle->m_fSteerAngle = vp->wheel_state / 50.0f; vehicle->bEngineOn = true; +#ifdef FIX_BUGS + for (int i = 0; i < 2; i++) + bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI); + for (int i = 0; i < 2; i++) + bike->m_aWheelSpeed[i] = vp->wheel_rotation[i + 2] / (128.0f / PI); + for (int i = 0; i < 4; i++) + bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f; +#else for (int i = 0; i < 4; i++) { bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f; bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI); - // NB: technically last assignment overflows - there are 2 wheels of bike - // however it saves two useful fields; this looks like unrolled loop, not sequential assignments } +#endif bike->m_fLeanLRAngle = vp->lean_angle / 50.0f; bike->m_fWheelAngle = vp->wheel_angle / 50.0f; bike->bLeanMatrixClean = false; @@ -1218,10 +1232,10 @@ void CReplay::ProcessReplayCamera(void) TheCamera.GetUp() = CVector(0.0f, 1.0f, 0.0f); TheCamera.GetRight() = CVector(1.0f, 0.0f, 0.0f); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetRight(); + pm->pos = TheCamera.GetPosition(); + pm->at = TheCamera.GetForward(); + pm->up = TheCamera.GetUp(); + pm->right = TheCamera.GetRight(); break; } case REPLAYCAMMODE_FIXED: @@ -1237,10 +1251,10 @@ void CReplay::ProcessReplayCamera(void) TheCamera.GetMatrix().GetUp() = up; TheCamera.GetMatrix().GetRight() = right; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); + pm->pos = TheCamera.GetMatrix().GetPosition(); + pm->at = TheCamera.GetMatrix().GetForward(); + pm->up = TheCamera.GetMatrix().GetUp(); + pm->right = TheCamera.GetMatrix().GetRight(); break; } default: @@ -1447,7 +1461,7 @@ void CReplay::RestoreStuffFromMem(void) ped->m_rwObject = nil; ped->m_modelIndex = -1; ped->SetModelIndex(mi); - ped->m_pVehicleAnim = 0; + ped->m_pVehicleAnim = nil; ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped); DMAudio.SetEntityStatus(ped->m_audioEntityId, true); CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false); @@ -1492,12 +1506,12 @@ void CReplay::RestoreStuffFromMem(void) tmp1.UpdateRW(); } else if (mi == MI_HUNTER) { - RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0); - RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0); } else if (vehicle->IsRealHeli()) { + RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0); + RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0); } @@ -1713,7 +1727,7 @@ void CReplay::SaveReplayToHD(void) CFileMgr::SetDir(""); } -void PlayReplayFromHD(void) +void CReplay::PlayReplayFromHD(void) { CFileMgr::SetDirMyDocuments(); int fr = CFileMgr::OpenFile("replay.rep", "rb"); @@ -1732,17 +1746,17 @@ void PlayReplayFromHD(void) return; } int slot; - for (slot = 0; CFileMgr::Read(fr, (char*)CReplay::Buffers[slot], sizeof(CReplay::Buffers[slot])); slot++) - CReplay::BufferStatus[slot] = CReplay::REPLAYBUFFER_PLAYBACK; - CReplay::BufferStatus[slot - 1] = CReplay::REPLAYBUFFER_RECORD; - while (slot < CReplay::NUM_REPLAYBUFFERS) - CReplay::BufferStatus[slot++] = CReplay::REPLAYBUFFER_UNUSED; + for (slot = 0; CFileMgr::Read(fr, (char*)Buffers[slot], sizeof(Buffers[slot])); slot++) + BufferStatus[slot] = REPLAYBUFFER_PLAYBACK; + BufferStatus[slot - 1] = REPLAYBUFFER_RECORD; + while (slot < NUM_REPLAYBUFFERS) + BufferStatus[slot++] = REPLAYBUFFER_UNUSED; CFileMgr::CloseFile(fr); CFileMgr::SetDir(""); - CReplay::TriggerPlayback(CReplay::REPLAYCAMMODE_ASSTORED, 0.0f, 0.0f, 0.0f, false); - CReplay::bPlayingBackFromFile = true; - CReplay::bAllowLookAroundCam = true; - CReplay::StreamAllNecessaryCarsAndPeds(); + TriggerPlayback(REPLAYCAMMODE_ASSTORED, 0.0f, 0.0f, 0.0f, false); + bPlayingBackFromFile = true; + bAllowLookAroundCam = true; + StreamAllNecessaryCarsAndPeds(); } void CReplay::StreamAllNecessaryCarsAndPeds(void) @@ -1840,10 +1854,10 @@ void CReplay::ProcessLookAroundCam(void) TheCamera.GetRight() = right; TheCamera.SetPosition(camera_pt); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetRight(); + pm->pos = TheCamera.GetPosition(); + pm->at = TheCamera.GetForward(); + pm->up = TheCamera.GetUp(); + pm->right = TheCamera.GetRight(); TheCamera.CalculateDerivedValues(); RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); @@ -1878,13 +1892,20 @@ void CReplay::Display() TimeCount = (TimeCount + 1) % UINT16_MAX; if ((TimeCount & 0x20) == 0) return; - CFont::SetPropOn(); - CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); - CFont::SetAlignment(ALIGN_LEFT); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH-20); +#endif + CFont::SetCentreOff(); + CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); CFont::SetFontStyle(FONT_STANDARD); if (Mode == MODE_PLAYBACK) - CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY")); + CFont::PrintString(SCREEN_WIDTH/15, SCREEN_HEIGHT/10, TheText.Get("REPLAY")); } #endif diff --git a/src/control/Replay.h b/src/control/Replay.h index 84a6bef0..5dd8b651 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -64,8 +64,6 @@ struct CStoredDetailedAnimationState uint8 aGroupId2[NUM_PARTIAL_ANIMS_IN_REPLAY]; }; -void PlayReplayFromHD(void); - #ifdef GTA_REPLAY #define REPLAY_STUB #else @@ -410,12 +408,10 @@ private: static void EmptyAllPools(void); static void MarkEverythingAsNew(void); static void SaveReplayToHD(void); + static void PlayReplayFromHD(void); // out of class in III PC and later because of SecuROM static void FindFirstFocusCoordinate(CVector *coord); static void ProcessLookAroundCam(void); static size_t FindSizeOfPacket(uint8); static void GoToNextBlock(void); - - /* Absolute nonsense, but how could this function end up being outside of class? */ - friend void PlayReplayFromHD(void); #endif }; diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp index f63d2c07..e1950a29 100644 --- a/src/control/Restart.cpp +++ b/src/control/Restart.cpp @@ -4,8 +4,6 @@ #include "Zones.h" #include "PathFind.h" -//--MIAMI: file done - uint8 CRestart::OverrideHospitalLevel; uint8 CRestart::OverridePoliceStationLevel; bool CRestart::bFadeInAfterNextArrest; diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index 260978b3..f75b4f50 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -16,8 +16,6 @@ #include "General.h" #include "Object.h" -//--MIAMI: file done - #define ROADBLOCKDIST (90.0f) #define ROADBLOCK_OBJECT_WIDTH (4.0f) @@ -26,6 +24,10 @@ int16 CRoadBlocks::RoadBlockNodes[NUMROADBLOCKS]; bool CRoadBlocks::InOrOut[NUMROADBLOCKS]; CScriptRoadblock CRoadBlocks::aScriptRoadBlocks[NUM_SCRIPT_ROADBLOCKS]; +#ifdef SECUROM +uint8 roadBlocksPirateCheck = 0; +#endif + void CRoadBlocks::Init(void) { @@ -189,6 +191,13 @@ CRoadBlocks::RegisterScriptRoadBlock(CVector vInf, CVector vSup) void CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2) { +#ifdef SECUROM + if (roadBlocksPirateCheck == 0) + // if not pirated game + // roadBlocksPirateCheck = 1; + // else + roadBlocksPirateCheck = 2; +#endif CMatrix tmp; CVector forward = (point2 - point1); float distBetween = forward.Magnitude(); diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp index 21512290..74d81327 100644 --- a/src/control/SceneEdit.cpp +++ b/src/control/SceneEdit.cpp @@ -1,7 +1,7 @@ #include "common.h" #include "SceneEdit.h" - +#ifdef GTA_SCENE_EDIT #include "Automobile.h" #include "Camera.h" #include "CarCtrl.h" @@ -20,8 +20,6 @@ #include "WeaponInfo.h" #include "World.h" -//--MIAMI: file done - bool CSceneEdit::m_bEditOn; int32 CSceneEdit::m_bCameraFollowActor; bool CSceneEdit::m_bRecording; @@ -281,24 +279,44 @@ void CSceneEdit::Draw(void) #endif sprintf(str, "Action"); AsciiToUnicode(str, wstr); - CFont::SetColor(CRGBA(0, 0, 0, 0)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(ACTION_MESSAGE_Y + SHADOW_OFFSET), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-ACTION_MESSAGE_X_RIGHT) + SHADOW_OFFSET, SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-ACTION_MESSAGE_Y) + SHADOW_OFFSET, wstr); +#endif CFont::SetColor(CRGBA(193, 164, 120, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(ACTION_MESSAGE_Y), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-ACTION_MESSAGE_X_RIGHT), SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-ACTION_MESSAGE_Y), wstr); +#endif sprintf(str, "Selected"); AsciiToUnicode(str, wstr); - CFont::SetColor(CRGBA(0, 0, 0, 0)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y + SHADOW_OFFSET), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-SELECTED_MESSAGE_X_RIGHT) + SHADOW_OFFSET, SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-SELECTED_MESSAGE_Y) + SHADOW_OFFSET, wstr); +#endif CFont::SetColor(CRGBA(193, 164, 120, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-SELECTED_MESSAGE_X_RIGHT), SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-SELECTED_MESSAGE_Y), wstr); +#endif CFont::SetCentreOff(); +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.7f)); +#else + CFont::SetScale(0.7f, 0.7f); +#endif #ifdef FIX_BUGS CFont::SetFontStyle(FONT_STANDARD); #else CFont::SetFontStyle(FONT_HEADING); #endif - CFont::SetColor(CRGBA(0, 0, 0, 0)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); for (int i = 0; i < NUM_COMMANDS_TO_DRAW; i++) { int16 nCommandDrawn = m_nCurrentCommand + i - NUM_COMMANDS_TO_DRAW / 2; if (nCommandDrawn >= MOVIE_TOTAL_COMMANDS) @@ -307,13 +325,21 @@ void CSceneEdit::Draw(void) nCommandDrawn += (MOVIE_TOTAL_COMMANDS - 1); sprintf(str, "%s", pCommandStrings[nCommandDrawn]); AsciiToUnicode(str, wstr); - CFont::SetColor(CRGBA(0, 0, 0, 0)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(COMMAND_NAME_Y + SHADOW_OFFSET + i * COMMAND_NAME_HEIGHT), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-COMMAND_NAME_X_RIGHT) + SHADOW_OFFSET, SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-COMMAND_NAME_Y) + SHADOW_OFFSET + i * COMMAND_NAME_HEIGHT, wstr); +#endif if (nCommandDrawn == m_nCurrentCommand) CFont::SetColor(CRGBA(156, 91, 40, 255)); else CFont::SetColor(CRGBA(193, 164, 120, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT), SCREEN_SCALE_Y(COMMAND_NAME_Y + i * COMMAND_NAME_HEIGHT), wstr); +#else + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH-COMMAND_NAME_X_RIGHT), SCREEN_SCALE_FROM_BOTTOM(DEFAULT_SCREEN_HEIGHT-COMMAND_NAME_Y) + i * COMMAND_NAME_HEIGHT, wstr); +#endif } } @@ -1098,3 +1124,4 @@ bool CSceneEdit::SelectWeapon(void) } return false; } +#endif diff --git a/src/control/SceneEdit.h b/src/control/SceneEdit.h index 6dcefa31..7c8fb98a 100644 --- a/src/control/SceneEdit.h +++ b/src/control/SceneEdit.h @@ -1,5 +1,5 @@ #pragma once - +#ifdef GTA_SCENE_EDIT class CPed; class CVehicle; @@ -93,3 +93,4 @@ public: static void SelectVehicle(void); static bool SelectWeapon(void); }; +#endif diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 6c4e21d5..642ad65b 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -17,6 +17,9 @@ #include "FileMgr.h" #include "Frontend.h" #include "General.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif #include "HandlingMgr.h" #include "Heli.h" #include "Hud.h" @@ -50,8 +53,6 @@ #include <stdarg.h> #endif -//--MIAMI: file done - uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE]; CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS]; intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; @@ -69,7 +70,7 @@ int32 CTheScripts::StoreVehicleIndex; bool CTheScripts::StoreVehicleWasRandom; CRunningScript *CTheScripts::pIdleScripts; CRunningScript *CTheScripts::pActiveScripts; -uint32 CTheScripts::NextFreeCollectiveIndex; +int32 CTheScripts::NextFreeCollectiveIndex; int32 CTheScripts::LastRandomPedId; uint16 CTheScripts::NumberOfUsedObjects; bool CTheScripts::bAlreadyRunningAMissionScript; @@ -82,7 +83,7 @@ uint16 CTheScripts::NumScriptDebugLines; uint16 CTheScripts::NumberOfIntroRectanglesThisFrame; uint16 CTheScripts::NumberOfIntroTextLinesThisFrame; uint8 CTheScripts::UseTextCommands; -CMissionCleanup CTheScripts::MissionCleanup; +CMissionCleanup CTheScripts::MissionCleanUp; CUpsideDownCarCheck CTheScripts::UpsideDownCars; CStuckCarCheck CTheScripts::StuckCars; uint16 CTheScripts::CommandsExecuted; @@ -93,6 +94,10 @@ uint32 CTheScripts::LastMissionPassedTime; uint16 CTheScripts::NumberOfExclusiveMissionScripts; bool CTheScripts::bPlayerHasMetDebbieHarry; bool CTheScripts::bPlayerIsInTheStatium; +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +int16 CTheScripts::CardStack[CARDS_IN_DECK * MAX_DECKS]; +int16 CTheScripts::CardStackPosition; +#endif #ifdef MISSION_REPLAY @@ -123,6 +128,9 @@ float oldTargetX; float oldTargetY; int missionRetryScriptIndex; bool doingMissionRetry; +bool gbTryingPorn4Again; +int IsInAmmunation; +int MissionSkipLevel; #endif @@ -215,7 +223,7 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_GOSUB, INPUT_ARGUMENTS(ARGTYPE_LABEL,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_RETURN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_LINE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""), - REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""), REGISTER_COMMAND(COMMAND_GET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""), REGISTER_COMMAND(COMMAND_SET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_BOOL,), OUTPUT_ARGUMENTS(), true, -1, ""), @@ -252,12 +260,12 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="), REGISTER_COMMAND(COMMAND_DIV_INT_LVAR_BY_INT_VAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " /="), REGISTER_COMMAND(COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="), - REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), @@ -274,16 +282,16 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_SET_LVAR_INT_TO_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ="), REGISTER_COMMAND(COMMAND_CSET_VAR_INT_TO_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), REGISTER_COMMAND(COMMAND_CSET_VAR_FLOAT_TO_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), - REGISTER_COMMAND(COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), - REGISTER_COMMAND(COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), + REGISTER_COMMAND(COMMAND_CSET_LVAR_INT_TO_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, 0, " =#"), + REGISTER_COMMAND(COMMAND_CSET_LVAR_FLOAT_TO_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, 0, " =#"), REGISTER_COMMAND(COMMAND_CSET_VAR_INT_TO_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), REGISTER_COMMAND(COMMAND_CSET_VAR_FLOAT_TO_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), - REGISTER_COMMAND(COMMAND_CSET_LVAR_INT_TO_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), - REGISTER_COMMAND(COMMAND_CSET_LVAR_FLOAT_TO_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"), - REGISTER_COMMAND(COMMAND_ABS_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), - REGISTER_COMMAND(COMMAND_ABS_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), - REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), - REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), + REGISTER_COMMAND(COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, 0, " =#"), + REGISTER_COMMAND(COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, 0, " =#"), + REGISTER_COMMAND(COMMAND_ABS_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), + REGISTER_COMMAND(COMMAND_ABS_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), + REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), + REGISTER_COMMAND(COMMAND_ABS_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"), REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_FLOAT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""), REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_INT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""), REGISTER_COMMAND(COMMAND_CREATE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_PED_HANDLE,), false, -1, ""), @@ -912,8 +920,8 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), - REGISTER_COMMAND(COMMAND_PLAYER_MADE_PROGRESS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), - REGISTER_COMMAND(COMMAND_SET_PROGRESS_TOTAL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_PLAYER_MADE_PROGRESS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_SET_PROGRESS_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_REGISTER_JUMP_DISTANCE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_REGISTER_JUMP_HEIGHT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_REGISTER_JUMP_FLIPS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), @@ -1568,6 +1576,39 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_REGISTER_FIRE_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_IS_AUSTRALIAN_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), REGISTER_COMMAND(COMMAND_DISARM_CAR_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + REGISTER_COMMAND(COMMAND_IS_JAPANESE_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), +#elif (!defined GTA_PS2) + REGISTER_COMMAND(COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + REGISTER_COMMAND(COMMAND_SHUFFLE_CARD_DECKS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_FETCH_NEXT_CARD, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_DEBUG_CAMERA_ON, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_SET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_OBJECT_STATIC, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_DO_2D_RECTANGLES_COLLIDE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""), +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT) + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), +#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + REGISTER_COMMAND(COMMAND_IS_MISSION_SKIP, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_SET_IN_AMMUNATION, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_DO_SAVE_GAME, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_RETRY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_DUMMY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), +#endif }; #undef REGISTER_COMMAND #undef INPUT_ARGUMENTS @@ -1630,7 +1671,7 @@ void CMissionCleanup::Init() } } -CMissionCleanupEntity* CMissionCleanup::FindFree() +cleanup_entity_struct* CMissionCleanup::FindFree() { for (int i = 0; i < MAX_CLEANUP; i++){ if (m_sEntities[i].type == CLEANUP_UNUSED) @@ -1642,7 +1683,7 @@ CMissionCleanupEntity* CMissionCleanup::FindFree() void CMissionCleanup::AddEntityToList(int32 id, uint8 type) { - CMissionCleanupEntity* pNew = FindFree(); + cleanup_entity_struct* pNew = FindFree(); if (!pNew) return; pNew->id = id; @@ -1650,17 +1691,6 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type) m_nCount++; } -static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false) -{ - if (!pEntity->bIsStaticWaitingForCollision) - return; - if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) { - pEntity->bIsStaticWaitingForCollision = false; - if (!pEntity->GetIsStatic()) - pEntity->AddToMovingList(); - } -} - void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) { for (int i = 0; i < MAX_CLEANUP; i++){ @@ -1668,23 +1698,38 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) switch (m_sEntities[i].type) { case CLEANUP_CAR: { - CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); - if (v) - PossiblyWakeThisEntity(v); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); + if (pVehicle) { + if (pVehicle->bIsStaticWaitingForCollision) { + pVehicle->bIsStaticWaitingForCollision = false; + if (!pVehicle->GetIsStatic()) + pVehicle->AddToMovingList(); + } + } break; } case CLEANUP_CHAR: { - CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (p) - PossiblyWakeThisEntity(p); + CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); + if (pPed) { + if (pPed->bIsStaticWaitingForCollision) { + pPed->bIsStaticWaitingForCollision = false; + if (!pPed->GetIsStatic()) + pPed->AddToMovingList(); + } + } break; } case CLEANUP_OBJECT: { - CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); - if (o) - PossiblyWakeThisEntity(o); + CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); + if (pObject) { + if (pObject->bIsStaticWaitingForCollision) { + pObject->bIsStaticWaitingForCollision = false; + if (!pObject->GetIsStatic()) + pObject->AddToMovingList(); + } + } break; } default: @@ -1703,23 +1748,44 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects() switch (m_sEntities[i].type) { case CLEANUP_CAR: { - CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); - if (v) - PossiblyWakeThisEntity(v, true); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); + if (pVehicle) { + if (pVehicle->bIsStaticWaitingForCollision) { + if (CColStore::HasCollisionLoaded(pVehicle->GetPosition())) { + pVehicle->bIsStaticWaitingForCollision = false; + if (!pVehicle->GetIsStatic()) + pVehicle->AddToMovingList(); + } + } + } break; } case CLEANUP_CHAR: { - CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (p) - PossiblyWakeThisEntity(p, true); + CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); + if (pPed) { + if (pPed->bIsStaticWaitingForCollision) { + if (CColStore::HasCollisionLoaded(pPed->GetPosition())) { + pPed->bIsStaticWaitingForCollision = false; + if (!pPed->GetIsStatic()) + pPed->AddToMovingList(); + } + } + } break; } case CLEANUP_OBJECT: { - CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); - if (o) - PossiblyWakeThisEntity(o, true); + CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); + if (pObject) { + if (pObject->bIsStaticWaitingForCollision) { + if (CColStore::HasCollisionLoaded(pObject->GetPosition())) { + pObject->bIsStaticWaitingForCollision = false; + if (!pObject->GetIsStatic()) + pObject->AddToMovingList(); + } + } + } break; } default: @@ -1728,21 +1794,6 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects() } } -CPhysical* CMissionCleanup::DoesThisEntityWaitForCollision(int i) -{ - if (m_sEntities[i].type == CLEANUP_CAR) { - CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); - if (pVehicle && pVehicle->GetStatus() != STATUS_WRECKED) - return pVehicle; - } - else if (m_sEntities[i].type == CLEANUP_CHAR) { - CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (pPed && !pPed->DyingOrDead()) - return pPed; - } - return nil; -} - void CMissionCleanup::Process() { CPopulation::m_AllRandomPedsThisType = -1; @@ -1819,6 +1870,12 @@ void CMissionCleanup::Process() m_sEntities[i].type = CLEANUP_UNUSED; m_nCount--; } +#ifdef SECUROM + if ((myrand() & 3) == 2){ + // if pirated game + CWeather::ForceHurricaneWeather(); + } +#endif } /* NB: CUpsideDownCarCheck is not used by actual script at all @@ -1835,10 +1892,16 @@ void CUpsideDownCarCheck::Init() bool CUpsideDownCarCheck::IsCarUpsideDown(int32 id) { - CVehicle* v = CPools::GetVehiclePool()->GetAt(id); - return v->GetUp().z <= -0.97f && - v->GetMoveSpeed().Magnitude() < 0.01f && - v->GetTurnSpeed().Magnitude() < 0.02f; + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(id); + return IsCarUpsideDown(pVehicle); +} + +bool CUpsideDownCarCheck::IsCarUpsideDown(CVehicle* pVehicle) +{ + assert(pVehicle); + return pVehicle->GetUp().z <= UPSIDEDOWN_UP_THRESHOLD && + pVehicle->GetMoveSpeed().Magnitude() < UPSIDEDOWN_MOVE_SPEED_THRESHOLD && + pVehicle->GetTurnSpeed().Magnitude() < UPSIDEDOWN_TURN_SPEED_THRESHOLD; } void CUpsideDownCarCheck::UpdateTimers() @@ -1861,7 +1924,7 @@ void CUpsideDownCarCheck::UpdateTimers() bool CUpsideDownCarCheck::AreAnyCarsUpsideDown() { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ - if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > 1000) + if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD) return true; } return false; @@ -1872,8 +1935,10 @@ void CUpsideDownCarCheck::AddCarToCheck(int32 id) uint16 index = 0; while (index < MAX_UPSIDEDOWN_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) index++; +#ifdef FIX_BUGS if (index >= MAX_UPSIDEDOWN_CAR_CHECKS) return; +#endif m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_nUpsideDownTimer = 0; } @@ -1892,7 +1957,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id) { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ if (m_sCars[i].m_nVehicleIndex == id) - return m_sCars[i].m_nUpsideDownTimer > 1000; + return m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD; } return false; } @@ -1942,7 +2007,10 @@ void CStuckCarCheck::AddCarToCheck(int32 id, float radius, uint32 time) int index = 0; while (index < MAX_STUCK_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) index++; - /* Would be nice to return if index >= MAX_STUCK_CAR_CHECKS... */ +#ifdef FIX_BUGS + if (index >= MAX_STUCK_CAR_CHECKS) + return; +#endif m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_vecPos = pv->GetPosition(); m_sCars[index].m_nLastCheck = CTimer::GetTimeInMilliseconds(); @@ -2174,7 +2242,7 @@ void CTheScripts::Init() ScriptsArray[i].Init(); ScriptsArray[i].AddScriptToList(&pIdleScripts); } - MissionCleanup.Init(); + MissionCleanUp.Init(); UpsideDownCars.Init(); StuckCars.Init(); CFileMgr::SetDir("data"); @@ -2289,6 +2357,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip) pNew->Init(); pNew->SetIP(ip); pNew->AddScriptToList(&pActiveScripts); + pNew->m_bIsActive = true; return pNew; } @@ -2301,7 +2370,7 @@ void CTheScripts::Process() float timeStep = CTimer::GetTimeStepInMilliseconds(); UpsideDownCars.UpdateTimers(); StuckCars.Process(); - MissionCleanup.CheckIfCollisionHasLoadedForMissionObjects(); + MissionCleanUp.CheckIfCollisionHasLoadedForMissionObjects(); DrawScriptSpheres(); if (FailCurrentMission) --FailCurrentMission; @@ -2373,6 +2442,8 @@ void CTheScripts::Process() script->UpdateTimers(timeStep); script->Process(); script = next; + if (script && !script->m_bIsActive) + script = nil; } DbgFlag = false; #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT @@ -3025,8 +3096,10 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) #ifdef MISSION_REPLAY if (m_bMissionFlag) { CPlayerInfo* pPlayerInfo = &CWorld::Players[CWorld::PlayerInFocus]; +#if 0 // makeing autosave is pointless and is a bit buggy if (pPlayerInfo->m_pPed->GetPedState() != PED_DEAD && pPlayerInfo->m_WBState == WBSTATE_PLAYING && !m_bDeatharrestExecuted) SaveGameForPause(1); +#endif oldTargetX = oldTargetY = 0.0f; if (AllowMissionReplay == 1) AllowMissionReplay = 2; @@ -3039,7 +3112,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) CollectParameters(&m_nIp, 1); script_assert(ScriptParams[0] >= 0); CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]); - m_bIsActive = true; + pNew->m_bIsActive = true; int8 type = CTheScripts::Read1ByteFromScript(&m_nIp); float tmp; for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) { @@ -3621,7 +3694,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_DELETE_CHAR: @@ -3630,7 +3703,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); CTheScripts::RemoveThisPed(ped); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_CHAR_WANDER_DIR: @@ -3851,7 +3924,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); return 0; } case COMMAND_DELETE_CAR: @@ -3864,7 +3937,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) delete car; } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_CAR_GOTO_COORDINATES: @@ -3984,9 +4057,9 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) car->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1]; if (missionRetryScriptIndex == 40 && car->GetModelIndex() == MI_CHEETAH) // Turismo car->AutoPilot.m_nCruiseSpeed = 8 * car->AutoPilot.m_nCruiseSpeed / 10; - car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); + car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity); #else - car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); + car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity); #endif return 0; } @@ -3995,7 +4068,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(car); - car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1]; + car->AutoPilot.m_nDrivingStyle = (uint8)ScriptParams[1]; return 0; } case COMMAND_SET_CAR_MISSION: @@ -4003,7 +4076,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(car); - car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1]; + car->AutoPilot.m_nCarMission = (uint8)ScriptParams[1]; car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); car->bEngineOn = true; return 0; @@ -4179,7 +4252,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) { if (!m_bIsMissionScript) return 0; - CTheScripts::MissionCleanup.Process(); + CTheScripts::MissionCleanUp.Process(); return 0; } case COMMAND_STORE_CAR_CHAR_IS_IN: @@ -4202,7 +4275,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pOld->bIsLocked = false; CCarCtrl::NumRandomCars++; CCarCtrl::NumMissionCars--; - CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); } } @@ -4213,14 +4286,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CCarCtrl::NumMissionCars++; CCarCtrl::NumRandomCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case PARKED_VEHICLE: pCurrent->VehicleCreatedBy = MISSION_VEHICLE; CCarCtrl::NumMissionCars++; CCarCtrl::NumParkedCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case MISSION_VEHICLE: case PERMANENT_VEHICLE: @@ -4253,7 +4326,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pOld->bIsLocked = false; CCarCtrl::NumRandomCars++; CCarCtrl::NumMissionCars--; - CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); } } @@ -4264,14 +4337,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CCarCtrl::NumMissionCars++; CCarCtrl::NumRandomCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case PARKED_VEHICLE: pCurrent->VehicleCreatedBy = MISSION_VEHICLE; CCarCtrl::NumMissionCars++; CCarCtrl::NumParkedCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case MISSION_VEHICLE: case PERMANENT_VEHICLE: @@ -4420,7 +4493,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_DELETE_OBJECT: @@ -4433,7 +4506,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) delete pObj; } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_ADD_SCORE: @@ -4470,7 +4543,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) return 0; case COMMAND_IS_WANTED_LEVEL_GREATER: CollectParameters(&m_nIp, 2); - UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_pPed->m_pWanted->m_nWantedLevel > ScriptParams[1]); + UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_pPed->m_pWanted->GetWantedLevel() > ScriptParams[1]); return 0; case COMMAND_CLEAR_WANTED_LEVEL: CollectParameters(&m_nIp, 1); @@ -4649,7 +4722,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD: @@ -4699,81 +4772,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) return -1; } - -void CRunningScript::Save(uint8*& buf) -{ -#ifdef COMPATIBLE_SAVES - SkipSaveBuf(buf, 8); - for (int i = 0; i < 8; i++) - WriteSaveBuf<char>(buf, m_abScriptName[i]); - WriteSaveBuf<uint32>(buf, m_nIp); -#ifdef CHECK_STRUCT_SIZES - static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); -#endif - for (int i = 0; i < MAX_STACK_DEPTH; i++) - WriteSaveBuf<uint32>(buf, m_anStack[i]); - WriteSaveBuf<uint16>(buf, m_nStackPointer); - SkipSaveBuf(buf, 2); -#ifdef CHECK_STRUCT_SIZES - static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); -#endif - for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) - WriteSaveBuf<int32>(buf, m_anLocalVariables[i]); - WriteSaveBuf<bool>(buf, m_bCondResult); - WriteSaveBuf<bool>(buf, m_bIsMissionScript); - WriteSaveBuf<bool>(buf, m_bSkipWakeTime); - SkipSaveBuf(buf, 1); - WriteSaveBuf<uint32>(buf, m_nWakeTime); - WriteSaveBuf<uint16>(buf, m_nAndOrState); - WriteSaveBuf<bool>(buf, m_bNotFlag); - WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled); - WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted); - WriteSaveBuf<bool>(buf, m_bMissionFlag); - SkipSaveBuf(buf, 2); -#else - WriteSaveBuf(buf, *this); -#endif -} - -void CRunningScript::Load(uint8*& buf) -{ -#ifdef COMPATIBLE_SAVES - SkipSaveBuf(buf, 8); - for (int i = 0; i < 8; i++) - m_abScriptName[i] = ReadSaveBuf<char>(buf); - m_nIp = ReadSaveBuf<uint32>(buf); -#ifdef CHECK_STRUCT_SIZES - static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); -#endif - for (int i = 0; i < MAX_STACK_DEPTH; i++) - m_anStack[i] = ReadSaveBuf<uint32>(buf); - m_nStackPointer = ReadSaveBuf<uint16>(buf); - SkipSaveBuf(buf, 2); -#ifdef CHECK_STRUCT_SIZES - static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); -#endif - for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) - m_anLocalVariables[i] = ReadSaveBuf<int32>(buf); - m_bCondResult = ReadSaveBuf<bool>(buf); - m_bIsMissionScript = ReadSaveBuf<bool>(buf); - m_bSkipWakeTime = ReadSaveBuf<bool>(buf); - SkipSaveBuf(buf, 1); - m_nWakeTime = ReadSaveBuf<uint32>(buf); - m_nAndOrState = ReadSaveBuf<uint16>(buf); - m_bNotFlag = ReadSaveBuf<bool>(buf); - m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf); - m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf); - m_bMissionFlag = ReadSaveBuf<bool>(buf); - SkipSaveBuf(buf, 2); -#else - CRunningScript* n = next; - CRunningScript* p = prev; - *this = ReadSaveBuf<CRunningScript>(buf); - next = n; - prev = p; -#endif -} - #ifdef MISSION_REPLAY bool CRunningScript::CanAllowMissionReplay() @@ -4802,13 +4800,13 @@ void RetryMission(int type, int unk) { if (type == 0) { doingMissionRetry = true; - FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY; + FrontEndMenuManager.m_nCurrScreen = 57; // MENUPAGE_MISSION_RETRY FrontEndMenuManager.RequestFrontEndStartUp(); } else if (type == 2) { doingMissionRetry = false; AllowMissionReplay = 6; - CTheScripts::MissionCleanup.Process(); + CTheScripts::MissionCleanUp.Process(); } } diff --git a/src/control/Script.h b/src/control/Script.h index f7613d18..a45e11cf 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,5 +1,5 @@ #pragma once -#include "common.h" +#include "Font.h" #include "PedType.h" #include "Text.h" #include "Sprite2d.h" @@ -19,26 +19,35 @@ extern int32 ScriptParams[32]; void FlushLog(); #define script_assert(_Expression) FlushLog(); assert(_Expression); -#define PICKUP_PLACEMENT_OFFSET 0.5f -#define PED_FIND_Z_OFFSET 5.0f -#define COP_PED_FIND_Z_OFFSET 10.0f +#define PICKUP_PLACEMENT_OFFSET (0.5f) +#define PED_FIND_Z_OFFSET (5.0f) +#define COP_PED_FIND_Z_OFFSET (10.0f) -#define SPHERE_MARKER_R 252 -#define SPHERE_MARKER_G 138 -#define SPHERE_MARKER_B 242 -#define SPHERE_MARKER_A 228 +#define UPSIDEDOWN_UP_THRESHOLD (-0.97f) +#define UPSIDEDOWN_MOVE_SPEED_THRESHOLD (0.01f) +#define UPSIDEDOWN_TURN_SPEED_THRESHOLD (0.02f) +#define UPSIDEDOWN_TIMER_THRESHOLD (1000) + +#define SPHERE_MARKER_R (252) +#define SPHERE_MARKER_G (138) +#define SPHERE_MARKER_B (242) +#define SPHERE_MARKER_A (228) #define SPHERE_MARKER_PULSE_PERIOD 2048 #define SPHERE_MARKER_PULSE_FRACTION 0.1f #ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define METERS_IN_FOOT 0.3048f -#define FEET_IN_METER 3.28084f +#define MILES_IN_METER (0.000621371192f) +#define METERS_IN_FOOT (0.3048f) +#define FEET_IN_METER (3.28084f) #else -#define METERS_IN_FOOT 0.3f -#define FEET_IN_METER 3.33f +#define MILES_IN_METER (1 / 1670.f) +#define METERS_IN_FOOT (0.3f) +#define FEET_IN_METER (3.33f) #endif -#define KEY_LENGTH_IN_SCRIPT 8 +#define KEY_LENGTH_IN_SCRIPT (8) + +//#define GTA_SCRIPT_COLLECTIVE struct intro_script_rectangle { @@ -91,12 +100,12 @@ struct intro_text_line m_bCentered = false; m_bBackground = false; m_bBackgroundOnly = false; - m_fWrapX = 182.0f; /* TODO: scaling as bugfix */ - m_fCenterSize = 640.0f; /* --||-- */ + m_fWrapX = 182.0f; + m_fCenterSize = DEFAULT_SCREEN_WIDTH; m_sBackgroundColor = CRGBA(128, 128, 128, 128); m_bTextProportional = true; m_bTextBeforeFade = false; - m_nFont = 2; /* enum? */ + m_nFont = FONT_STANDARD; m_fAtX = 0.0f; m_fAtY = 0.0f; memset(&m_Text, 0, sizeof(m_Text)); @@ -131,7 +140,7 @@ enum { CLEANUP_OBJECT }; -struct CMissionCleanupEntity +struct cleanup_entity_struct { uint8 type; int32 id; @@ -145,22 +154,21 @@ enum { class CMissionCleanup { - CMissionCleanupEntity m_sEntities[MAX_CLEANUP]; +public: + cleanup_entity_struct m_sEntities[MAX_CLEANUP]; uint8 m_nCount; -public: CMissionCleanup(); void Init(); - CMissionCleanupEntity* FindFree(); + cleanup_entity_struct* FindFree(); void AddEntityToList(int32, uint8); void RemoveEntityFromList(int32, uint8); void Process(); void CheckIfCollisionHasLoadedForMissionObjects(); - CPhysical* DoesThisEntityWaitForCollision(int i); }; -struct CUpsideDownCarCheckEntry +struct upsidedown_car_data { int32 m_nVehicleIndex; uint32 m_nUpsideDownTimer; @@ -168,11 +176,12 @@ struct CUpsideDownCarCheckEntry class CUpsideDownCarCheck { - CUpsideDownCarCheckEntry m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS]; + upsidedown_car_data m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS]; public: void Init(); bool IsCarUpsideDown(int32); + bool IsCarUpsideDown(CVehicle*); void UpdateTimers(); bool AreAnyCarsUpsideDown(); void AddCarToCheck(int32); @@ -190,7 +199,7 @@ struct stuck_car_data bool m_bStuck; stuck_car_data() { } - inline void Reset(); + void Reset(); }; class CStuckCarCheck @@ -217,8 +226,8 @@ enum { struct tCollectiveData { - int32 index; - uint32 unk_data; + int32 colIndex; + int32 pedIndex; }; enum { @@ -256,7 +265,7 @@ enum { enum { MAX_NUM_SCRIPTS = 128, - MAX_NUM_INTRO_TEXT_LINES = 2, + MAX_NUM_INTRO_TEXT_LINES = 48, MAX_NUM_INTRO_RECTANGLES = 16, MAX_NUM_SCRIPT_SRPITES = 16, MAX_NUM_SCRIPT_SPHERES = 16, @@ -269,6 +278,7 @@ enum { class CTheScripts { +public: static uint8 ScriptSpace[SIZE_SCRIPT_SPACE]; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; @@ -282,14 +292,14 @@ class CTheScripts static CStoredLine aStoredLines[MAX_NUM_STORED_LINES]; static bool DbgFlag; static uint32 OnAMissionFlag; - static CMissionCleanup MissionCleanup; + static CMissionCleanup MissionCleanUp; static CStuckCarCheck StuckCars; static CUpsideDownCarCheck UpsideDownCars; static int32 StoreVehicleIndex; static bool StoreVehicleWasRandom; static CRunningScript *pIdleScripts; static CRunningScript *pActiveScripts; - static uint32 NextFreeCollectiveIndex; + static int32 NextFreeCollectiveIndex; static int32 LastRandomPedId; static uint16 NumberOfUsedObjects; static bool bAlreadyRunningAMissionScript; @@ -306,11 +316,19 @@ class CTheScripts static uint16 ScriptsUpdated; static uint32 LastMissionPassedTime; static uint16 NumberOfExclusiveMissionScripts; -public: +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +#define CARDS_IN_SUIT (13) +#define NUM_SUITS (4) +#define MAX_DECKS (6) +#define CARDS_IN_DECK (CARDS_IN_SUIT * NUM_SUITS) +#define CARDS_IN_STACK (CARDS_IN_DECK * MAX_DECKS) + static int16 CardStack[CARDS_IN_STACK]; + static int16 CardStackPosition; +#endif static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; -public: + static void Init(); static void Process(); @@ -364,8 +382,6 @@ public: return Read4BytesFromScript(&tmp); } -private: - static CRunningScript* StartNewScript(uint32); static void CleanUpThisVehicle(CVehicle*); @@ -404,18 +420,30 @@ public: static void SwitchToMission(int32 mission); #endif - friend class CRunningScript; - friend class CHud; - friend void CMissionCleanup::Process(); - friend class CColStore; -#ifdef FIX_BUGS - friend void RetryMission(int, int); +#ifdef GTA_SCRIPT_COLLECTIVE + static void AdvanceCollectiveIndex() + { + if (NextFreeCollectiveIndex == INT32_MAX) + NextFreeCollectiveIndex = 0; + else + NextFreeCollectiveIndex++; + } + + static int AddPedsInVehicleToCollective(int); + static int AddPedsInAreaToCollective(float, float, float, float); + static int FindFreeSlotInCollectiveArray(); + static void SetObjectiveForAllPedsInCollective(int, eObjective, int16, int16); + static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector, float); + static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector); + static void SetObjectiveForAllPedsInCollective(int, eObjective, void*); + static void SetObjectiveForAllPedsInCollective(int, eObjective); #endif + }; enum { - MAX_STACK_DEPTH = 6, // 4 PS2 + MAX_STACK_DEPTH = 6, NUM_LOCAL_VARS = 16, NUM_TIMERS = 2 }; @@ -442,6 +470,7 @@ class CRunningScript ORS_8 }; +public: CRunningScript* next; CRunningScript* prev; char m_abScriptName[8]; @@ -480,7 +509,6 @@ public: static const uint32 nSaveStructSize; -private: void CollectParameters(uint32*, int16); int32 CollectNextParameterWithoutIncreasingPC(uint32); int32* GetPointerToScriptVariable(uint32*, int16); @@ -523,6 +551,14 @@ private: void LocateObjectCommand(int32, uint32*); void ObjectInAreaCheckCommand(int32, uint32*); +#ifdef GTA_SCRIPT_COLLECTIVE + void LocateCollectiveCommand(int32, uint32*); + void LocateCollectiveCharCommand(int32, uint32*); + void LocateCollectiveCarCommand(int32, uint32*); + void LocateCollectivePlayerCommand(int32, uint32*); + void CollectiveInAreaCheckCommand(int32, uint32*); +#endif + #ifdef MISSION_REPLAY bool CanAllowMissionReplay(); #endif @@ -534,25 +570,27 @@ private: float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; } + bool ThisIsAValidRandomCop(uint32 mi, int cop, int swat, int fbi, int army, int miami); bool ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal); bool CheckDamagedWeaponType(int32 actual, int32 type); - static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); - - friend class CTheScripts; }; #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; #endif #ifdef MISSION_REPLAY +static_assert(false, "Mission replay is not supported"); extern int AllowMissionReplay; extern uint32 WaitForMissionActivate; extern uint32 WaitForSave; extern uint32 MissionStartTime; extern int missionRetryScriptIndex; extern bool doingMissionRetry; +extern bool gbTryingPorn4Again; +extern int IsInAmmunation; +extern int MissionSkipLevel; uint32 AddExtraDeathDelay(); void RetryMission(int, int); diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp index 93098dac..656973ca 100644 --- a/src/control/Script2.cpp +++ b/src/control/Script2.cpp @@ -1030,7 +1030,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; script_assert(pPed); - ScriptParams[0] = pPed->m_pWanted->m_nWantedLevel; + ScriptParams[0] = pPed->m_pWanted->GetWantedLevel(); StoreParameters(&m_nIp, 1); return 0; } @@ -1048,7 +1048,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisPed(pPed); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED: @@ -1057,7 +1057,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisVehicle(pVehicle); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED: @@ -1066,7 +1066,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisObject(pObject); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_DONT_REMOVE_CHAR: @@ -1074,7 +1074,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_DONT_REMOVE_CAR: @@ -1082,7 +1082,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_DONT_REMOVE_OBJECT: @@ -1090,7 +1090,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); script_assert(pObject); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_CREATE_CHAR_AS_PASSENGER: @@ -1142,6 +1142,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetPosition(pVehicle->GetPosition()); pPed->SetOrientation(0.0f, 0.0f, 0.0f); CPopulation::ms_nTotalMissionPeds++; + CWorld::Add(pPed); if (ScriptParams[3] >= 0) pVehicle->AddPassenger(pPed, ScriptParams[3]); else @@ -1149,16 +1150,14 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->m_pMyVehicle = pVehicle; pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); pPed->bInVehicle = true; - pVehicle->SetStatus(STATUS_PHYSICS); pPed->SetPedState(PED_DRIVING); pPed->bUsesCollision = false; pPed->AddInCarAnims(pVehicle, false); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition()); - CWorld::Add(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT: @@ -1300,9 +1299,9 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 2); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]); pPed->bScriptObjectiveCompleted = false; - pPed->SetObjective(OBJECTIVE_DESTROY_OBJECT, pVehicle); + pPed->SetObjective(OBJECTIVE_DESTROY_OBJECT, pObject); return 0; } case COMMAND_SET_CHAR_OBJ_DESTROY_CAR: diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp index 2bc29eb7..1ac18fa8 100644 --- a/src/control/Script3.cpp +++ b/src/control/Script3.cpp @@ -34,6 +34,7 @@ #include "Zones.h" #include "GameLogic.h" #include "Bike.h" +#include "Wanted.h" int8 CRunningScript::ProcessCommands500To599(int32 command) { @@ -286,7 +287,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) float supX = *(float*)&ScriptParams[5]; float supY = *(float*)&ScriptParams[6]; float supZ = *(float*)&ScriptParams[7]; - ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, (eGarageType)ScriptParams[8], 0); + ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, ScriptParams[8], 0); StoreParameters(&m_nIp, 1); return 0; } @@ -302,7 +303,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) float supX = *(float*)&ScriptParams[5]; float supY = *(float*)&ScriptParams[6]; float supZ = *(float*)&ScriptParams[7]; - ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, (eGarageType)ScriptParams[8], ScriptParams[9]); + ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, ScriptParams[8], ScriptParams[9]); StoreParameters(&m_nIp, 1); return 0; } @@ -325,11 +326,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 1); UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0])); return 0; +/* case COMMAND_SET_FREE_BOMBS: CollectParameters(&m_nIp, 1); CGarages::SetFreeBombs(ScriptParams[0] != 0); return 0; -#ifdef GTA_PS2 case COMMAND_SET_POWERPOINT: { CollectParameters(&m_nIp, 7); @@ -363,8 +364,6 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) return 0; } -#endif // GTA_PS2 - /* case COMMAND_SET_ALL_TAXI_LIGHTS: CollectParameters(&m_nIp, 1); CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0); @@ -818,7 +817,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], - 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); + 255, pos, *(float*)&ScriptParams[3], 450.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); return 0; } case COMMAND_DRAW_LIGHT: @@ -858,7 +857,12 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_PLAYING); return 0; } - //case COMMAND_SET_COLL_OBJ_NO_OBJ: +#ifdef GTA_SCRIPT_COLLECTIVE + case COMMAND_SET_COLL_OBJ_NO_OBJ: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_NONE); + return 0; +#endif default: script_assert(0); } @@ -868,65 +872,314 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) int8 CRunningScript::ProcessCommands600To699(int32 command) { switch (command){ - /* Collective commands are not implemented until LCS. +#ifdef GTA_SCRIPT_COLLECTIVE case COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_WAIT_ON_FOOT); + return 0; case COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE); + return 0; case COMMAND_SET_COLL_OBJ_GUARD_SPOT: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GUARD_AREA, pos); + return 0; + } case COMMAND_SET_COLL_OBJ_GUARD_AREA: + { + CollectParameters(&m_nIp, 5); + float infX = *(float*)&ScriptParams[1]; + float supX = *(float*)&ScriptParams[3]; + if (infX > supX) { + infX = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[1]; + } + float infY = *(float*)&ScriptParams[2]; + float supY = *(float*)&ScriptParams[4]; + if (infY > supY) { + infY = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[2]; + } + CVector pos; + pos.x = (infX + supX) / 2; + pos.y = (infY + supY) / 2; + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = Max(pos.x - infX, pos.y - infY); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GUARD_AREA, pos, radius); + return 0; + } case COMMAND_SET_COLL_OBJ_WAIT_IN_CAR: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_WAIT_IN_CAR); + return 0; case COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ON_FOOT, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed; + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ON_FOOT, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ANY_MEANS, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed; + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ANY_MEANS, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed; + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed; + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_CHAR_ON_FOOT, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed; + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_CHAR_ON_FOOT, pPed); + return 0; + } case COMMAND_SET_COLL_OBJ_LEAVE_CAR: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_LEAVE_CAR); + return 0; case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_ENTER_CAR_AS_PASSENGER, pVehicle); + return 0; + } case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle); + return 0; + } + /* case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR: case COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE: case COMMAND_SET_COLL_OBJ_DESTROY_OBJECT: + */ case COMMAND_SET_COLL_OBJ_DESTROY_CAR: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_DESTROY_CAR, pVehicle); + return 0; + } case COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT: + { + CollectParameters(&m_nIp, 5); + float infX = *(float*)&ScriptParams[1]; + float supX = *(float*)&ScriptParams[3]; + if (infX > supX) { + infX = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[1]; + } + float infY = *(float*)&ScriptParams[2]; + float supY = *(float*)&ScriptParams[4]; + if (infY > supY) { + infY = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[2]; + } + CVector pos; + pos.x = (infX + supX) / 2; + pos.y = (infY + supY) / 2; + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = Max(pos.x - infX, pos.y - infY); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius); + return 0; + } + /* case COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR: case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET: case COMMAND_SET_COLL_OBJ_GUARD_ATTACK: + */ case COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE: + CollectParameters(&m_nIp, 3); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FOLLOW_ROUTE, ScriptParams[1], ScriptParams[2]); + return 0; case COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT: - case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR: + { + CollectParameters(&m_nIp, 3); + CVector pos(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], CWorld::FindGroundZForCoord(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2])); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ON_FOOT, pos); + return 0; + } + //case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR: case COMMAND_SET_COLL_OBJ_RUN_TO_AREA: + { + CollectParameters(&m_nIp, 5); + float infX = *(float*)&ScriptParams[1]; + float supX = *(float*)&ScriptParams[3]; + if (infX > supX) { + infX = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[1]; + } + float infY = *(float*)&ScriptParams[2]; + float supY = *(float*)&ScriptParams[4]; + if (infY > supY) { + infY = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[2]; + } + CVector pos; + pos.x = (infX + supX) / 2; + pos.y = (infY + supY) / 2; + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = Max(pos.x - infX, pos.y - infY); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_RUN_TO_AREA, pos, radius); + return 0; + } case COMMAND_SET_COLL_OBJ_RUN_TO_COORD: + { + CollectParameters(&m_nIp, 3); + CVector pos(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], CWorld::FindGroundZForCoord(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2])); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_RUN_TO_AREA, pos); + return 0; + } case COMMAND_ADD_PEDS_IN_AREA_TO_COLL: + { + CollectParameters(&m_nIp, 3); + float X = *(float*)&ScriptParams[0]; + float Y = *(float*)&ScriptParams[1]; + float Z = CWorld::FindGroundZForCoord(X, Y); + float radius = *(float*)&ScriptParams[2]; + ScriptParams[0] = CTheScripts::AddPedsInAreaToCollective(X, Y, Z, radius); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL: + CollectParameters(&m_nIp, 1); + ScriptParams[0] = CTheScripts::AddPedsInVehicleToCollective(ScriptParams[0]); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_CLEAR_COLL: + CollectParameters(&m_nIp, 1); + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CTheScripts::CollectiveArray[i].colIndex == ScriptParams[0]) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + } + } + return 0; case COMMAND_IS_COLL_IN_CARS: + { + CollectParameters(&m_nIp, 1); + bool result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + } + else { + result = false; + break; + } + } + UpdateCompareFlag(result); + return 0; + } case COMMAND_LOCATE_COLL_ANY_MEANS_2D: case COMMAND_LOCATE_COLL_ON_FOOT_2D: case COMMAND_LOCATE_COLL_IN_CAR_2D: case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D: case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D: case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D: + LocateCollectiveCommand(command, &m_nIp); + return 0; case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D: case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D: case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D: + LocateCollectiveCharCommand(command, &m_nIp); + return 0; case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D: case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D: case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D: + LocateCollectiveCarCommand(command, &m_nIp); + return 0; case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D: case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D: case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D: + LocateCollectivePlayerCommand(command, &m_nIp); + return 0; case COMMAND_IS_COLL_IN_AREA_2D: case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D: case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D: case COMMAND_IS_COLL_STOPPED_IN_AREA_2D: case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D: case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D: + CollectiveInAreaCheckCommand(command, &m_nIp); + return 0; case COMMAND_GET_NUMBER_OF_PEDS_IN_COLL: - */ + { + CollectParameters(&m_nIp, 1); + int total = 0; + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + } + else { + total++; + } + } + ScriptParams[0] = total; + StoreParameters(&m_nIp, 1); + return 0; + } +#endif case COMMAND_SET_CHAR_HEED_THREATS: { CollectParameters(&m_nIp, 2); @@ -1025,7 +1278,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); return 0; } /* @@ -1064,7 +1317,31 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) return 0; } */ - //case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS: +#ifdef GTA_SCRIPT_COLLECTIVE + case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS: + { + CollectParameters(&m_nIp, 5); + float infX = *(float*)&ScriptParams[1]; + float supX = *(float*)&ScriptParams[3]; + if (infX > supX) { + infX = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[1]; + } + float infY = *(float*)&ScriptParams[2]; + float supY = *(float*)&ScriptParams[4]; + if (infY > supY) { + infY = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[2]; + } + CVector pos; + pos.x = (infX + supX) / 2; + pos.y = (infY + supY) / 2; + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = Max(pos.x - infX, pos.y - infY); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius); + return 0; + } +#endif case COMMAND_IS_PLAYER_STOPPED: { CollectParameters(&m_nIp, 1); @@ -1556,7 +1833,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1611,7 +1888,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1848,7 +2125,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) } case COMMAND_CHANGE_GARAGE_TYPE: CollectParameters(&m_nIp, 2); - CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], 0); + CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], 0); return 0; /* case COMMAND_ACTIVATE_CRUSHER_CRANE: @@ -2124,7 +2401,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[1]); script_assert(pPed); script_assert(pLeader); - UpdateCompareFlag(pPed->m_leader == pLeader); + UpdateCompareFlag(pPed->m_leader == pLeader && !pPed->bWaitForLeaderToComeCloser); return 0; } default: diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index b2e2aaa5..9830f0dc 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -39,6 +39,7 @@ #include "World.h" #include "Zones.h" #include "Bike.h" +#include "Wanted.h" #ifdef FIX_BUGS static bool IsSlideObjectUsedWrongByScript(const CVector& posTarget, const CVector& slideBy) @@ -68,7 +69,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed; script_assert(pPed); script_assert(pLeader); - UpdateCompareFlag(pPed->m_leader == pLeader); + UpdateCompareFlag(pPed->m_leader == pLeader && !pPed->bWaitForLeaderToComeCloser); return 0; } case COMMAND_EXPLODE_CHAR_HEAD: @@ -92,7 +93,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 2); CBoat* pBoat = (CBoat*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pBoat && pBoat->m_vehType == VEHICLE_TYPE_BOAT); - pBoat->m_bIsAnchored = (ScriptParams[1] == 0); + pBoat->m_bIsAnchored = (ScriptParams[1] != 0); return 0; } case COMMAND_SET_ZONE_GROUP: @@ -106,7 +107,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) printf("Couldn't find zone - %s\n", zone); return 0; } - CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]); + while (zone_id >= 0) { + CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]); + zone_id = CTheZones::FindNextZoneByLabelAndReturnIndex(zone, ZONE_INFO); + } return 0; } case COMMAND_START_CAR_FIRE: @@ -155,7 +159,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ++CCarCtrl::NumMissionCars; --CCarCtrl::NumRandomCars; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); } ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); @@ -188,7 +192,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ++CCarCtrl::NumMissionCars; --CCarCtrl::NumRandomCars; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); } ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); @@ -255,7 +259,12 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) return 0; } */ - //case COMMAND_SET_COLL_OBJ_CATCH_TRAIN: +#ifdef GTA_SCRIPT_COLLECTIVE + case COMMAND_SET_COLL_OBJ_CATCH_TRAIN: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_CATCH_TRAIN); + return 0; +#endif case COMMAND_SET_PLAYER_NEVER_GETS_TIRED: { CollectParameters(&m_nIp, 2); @@ -604,7 +613,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE: @@ -784,20 +793,20 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) }else{ pPed->m_pMyVehicle->RemovePassenger(pPed); } - if (pPed->m_vehEnterType) { + if (pPed->m_vehDoor) { if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) { uint8 flags = 0; if (pPed->m_pMyVehicle->IsBike()) { - if (pPed->m_vehEnterType == CAR_DOOR_LF || - pPed->m_vehEnterType == CAR_DOOR_RF || - pPed->m_vehEnterType == CAR_WINDSCREEN) + if (pPed->m_vehDoor == CAR_DOOR_LF || + pPed->m_vehDoor == CAR_DOOR_RF || + pPed->m_vehDoor == CAR_WINDSCREEN) flags = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF; - else if (pPed->m_vehEnterType == CAR_DOOR_LR || - pPed->m_vehEnterType == CAR_DOOR_RR) + else if (pPed->m_vehDoor == CAR_DOOR_LR || + pPed->m_vehDoor == CAR_DOOR_RR) flags = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR; } else { - switch (pPed->m_vehEnterType) { + switch (pPed->m_vehDoor) { case CAR_DOOR_LF: flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_LF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR; break; @@ -813,7 +822,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } } pPed->m_pMyVehicle->m_nGettingOutFlags &= ~flags; - pPed->m_pMyVehicle->ProcessOpenDoor(pPed->m_vehEnterType, NUM_STD_ANIMS, 0.0f); + pPed->m_pMyVehicle->ProcessOpenDoor(pPed->m_vehDoor, NUM_STD_ANIMS, 0.0f); } } } @@ -1051,7 +1060,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR: @@ -1148,7 +1157,12 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CGarages::GivePlayerDetonator(); return 0; */ - //case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR: +#ifdef GTA_SCRIPT_COLLECTIVE + case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR: + CollectParameters(&m_nIp, 1); + CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_STEAL_ANY_CAR); + return 0; +#endif case COMMAND_SET_OBJECT_VELOCITY: { CollectParameters(&m_nIp, 4); @@ -1482,7 +1496,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); const CVector& pos = pVehicle->GetPosition(); - float heading = CGeneral::GetATanOfXY(pos.y - *(float*)&ScriptParams[2], pos.x - *(float*)&ScriptParams[1]) + HALFPI; + float heading = CGeneral::GetATanOfXY(pos.x - *(float*)&ScriptParams[1], pos.y - *(float*)&ScriptParams[2]) + HALFPI; if (heading > TWOPI) heading -= TWOPI; pVehicle->SetHeading(heading); @@ -1513,7 +1527,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - pVehicle->SetStatus((eEntityStatus)ScriptParams[1]); + pVehicle->SetStatus(ScriptParams[1]); return 0; } case COMMAND_IS_CHAR_MALE: @@ -1537,7 +1551,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL: { CollectParameters(&m_nIp, 3); - CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], ScriptParams[2]); + CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], ScriptParams[2]); return 0; } case COMMAND_FIND_DRUG_PLANE_COORDINATES: @@ -1798,8 +1812,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) return 0; int attempts; int model = -1; - int index = CGeneral::GetRandomNumberInRange(0, 50); - for (attempts = 0; attempts < 50; attempts++) { + int index = CGeneral::GetRandomNumberInRange(0, MAXVEHICLESLOADED); + for (attempts = 0; attempts < MAXVEHICLESLOADED; attempts++) { if (model != -1) break; model = CStreaming::ms_vehiclesLoaded[index]; @@ -2169,10 +2183,10 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_PRINT_HELP: { if (CCamera::m_bUseMouse3rdPerson && ( - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15", 7) == 0 || - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A", 7) == 0 || - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C", 7) == 0 || - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D", 7) == 0)) { + strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15") == 0 || + strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A") == 0 || + strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C") == 0 || + strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D") == 0)) { m_nIp += KEY_LENGTH_IN_SCRIPT; return 0; } @@ -2192,3 +2206,143 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } return -1; } + +int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) +{ + if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) + ScriptSphereArray[index].m_Index = 1; + else + ScriptSphereArray[index].m_Index++; + return (uint16)index | ScriptSphereArray[index].m_Index << 16; +} + +int32 CTheScripts::GetActualScriptSphereIndex(int32 index) +{ + if (index == -1) + return -1; + uint16 check = (uint32)index >> 16; + uint16 array_idx = index & (0xFFFF); + script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray)); + if (check != ScriptSphereArray[array_idx].m_Index) + return -1; + return array_idx; +} + +void CTheScripts::DrawScriptSpheres() +{ + for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { + if (ScriptSphereArray[i].m_bInUse) + C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius, + SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); + } +} + +int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius) +{ + int16 i = 0; + for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { + if (!ScriptSphereArray[i].m_bInUse) + break; + } +#ifdef FIX_BUGS + if (i == MAX_NUM_SCRIPT_SPHERES) + return -1; +#endif + ScriptSphereArray[i].m_bInUse = true; + ScriptSphereArray[i].m_Id = id; + ScriptSphereArray[i].m_vecCenter = pos; + ScriptSphereArray[i].m_fRadius = radius; + return GetNewUniqueScriptSphereIndex(i); +} + +void CTheScripts::RemoveScriptSphere(int32 index) +{ + index = GetActualScriptSphereIndex(index); + if (index == -1) + return; + ScriptSphereArray[index].m_bInUse = false; + ScriptSphereArray[index].m_Id = 0; +} + +void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model) +{ + int i = 0; + bool found = false; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == pBuilding) + found = true; + else + i++; + } + if (found) { + if (BuildingSwapArray[i].m_nOldModel == new_model) { + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; + } + else { + BuildingSwapArray[i].m_nNewModel = new_model; + } + } + else { + i = 0; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == nil) + found = true; + else + i++; + } + if (found) { + BuildingSwapArray[i].m_pBuilding = pBuilding; + BuildingSwapArray[i].m_nNewModel = new_model; + BuildingSwapArray[i].m_nOldModel = old_model; + } + } +} + +void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove) +{ + int i = 0; + bool found = false; + while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { + if (InvisibilitySettingArray[i] == pEntity) + found = true; + else + i++; + } + if (found) { + if (remove) + InvisibilitySettingArray[i] = nil; + } + else if (!remove) { + i = 0; + while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { + if (InvisibilitySettingArray[i] == nil) + found = true; + else + i++; + } + if (found) + InvisibilitySettingArray[i] = pEntity; + } +} + +void CTheScripts::UndoBuildingSwaps() +{ + for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { + if (BuildingSwapArray[i].m_pBuilding) { + BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel); + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; + } + } +} + +void CTheScripts::UndoEntityInvisibilitySettings() +{ + for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) { + if (InvisibilitySettingArray[i]) { + InvisibilitySettingArray[i]->bIsVisible = true; + InvisibilitySettingArray[i] = nil; + } + } +} diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index 7efebb73..b03ff49d 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -17,146 +17,6 @@ #include "World.h" #include "main.h" -int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) -{ - if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) - ScriptSphereArray[index].m_Index = 1; - else - ScriptSphereArray[index].m_Index++; - return (uint16)index | ScriptSphereArray[index].m_Index << 16; -} - -int32 CTheScripts::GetActualScriptSphereIndex(int32 index) -{ - if (index == -1) - return -1; - uint16 check = (uint32)index >> 16; - uint16 array_idx = index & (0xFFFF); - script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray)); - if (check != ScriptSphereArray[array_idx].m_Index) - return -1; - return array_idx; -} - -void CTheScripts::DrawScriptSpheres() -{ - for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { - if (ScriptSphereArray[i].m_bInUse) - C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius, - SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); - } -} - -int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius) -{ - int16 i = 0; - for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { - if (!ScriptSphereArray[i].m_bInUse) - break; - } -#ifdef FIX_BUGS - if (i == MAX_NUM_SCRIPT_SPHERES) - return -1; -#endif - ScriptSphereArray[i].m_bInUse = true; - ScriptSphereArray[i].m_Id = id; - ScriptSphereArray[i].m_vecCenter = pos; - ScriptSphereArray[i].m_fRadius = radius; - return GetNewUniqueScriptSphereIndex(i); -} - -void CTheScripts::RemoveScriptSphere(int32 index) -{ - index = GetActualScriptSphereIndex(index); - if (index == -1) - return; - ScriptSphereArray[index].m_bInUse = false; - ScriptSphereArray[index].m_Id = 0; -} - -void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model) -{ - int i = 0; - bool found = false; - while (i < MAX_NUM_BUILDING_SWAPS && !found) { - if (BuildingSwapArray[i].m_pBuilding == pBuilding) - found = true; - else - i++; - } - if (found) { - if (BuildingSwapArray[i].m_nOldModel == new_model) { - BuildingSwapArray[i].m_pBuilding = nil; - BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; - } - else { - BuildingSwapArray[i].m_nNewModel = new_model; - } - } - else { - i = 0; - while (i < MAX_NUM_BUILDING_SWAPS && !found) { - if (BuildingSwapArray[i].m_pBuilding == nil) - found = true; - else - i++; - } - if (found) { - BuildingSwapArray[i].m_pBuilding = pBuilding; - BuildingSwapArray[i].m_nNewModel = new_model; - BuildingSwapArray[i].m_nOldModel = old_model; - } - } -} - -void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove) -{ - int i = 0; - bool found = false; - while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { - if (InvisibilitySettingArray[i] == pEntity) - found = true; - else - i++; - } - if (found) { - if (remove) - InvisibilitySettingArray[i] = nil; - } - else if (!remove) { - i = 0; - while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { - if (InvisibilitySettingArray[i] == nil) - found = true; - else - i++; - } - if (found) - InvisibilitySettingArray[i] = pEntity; - } -} - -void CTheScripts::UndoBuildingSwaps() -{ - for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { - if (BuildingSwapArray[i].m_pBuilding) { - BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel); - BuildingSwapArray[i].m_pBuilding = nil; - BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; - } - } -} - -void CTheScripts::UndoEntityInvisibilitySettings() -{ - for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) { - if (InvisibilitySettingArray[i]) { - InvisibilitySettingArray[i]->bIsVisible = true; - InvisibilitySettingArray[i] = nil; - } - } -} - void CRunningScript::UpdateCompareFlag(bool flag) { if (m_bNotFlag) @@ -1562,6 +1422,488 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button) return 0; } +#ifdef GTA_SCRIPT_COLLECTIVE +void CRunningScript::LocateCollectiveCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug, decided = false; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_2D: + case COMMAND_LOCATE_COLL_ON_FOOT_2D: + case COMMAND_LOCATE_COLL_IN_CAR_2D: + case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D: + case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D: + case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D: + b3D = false; + break; + default: + b3D = true; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + X = *(float*)&ScriptParams[1]; + Y = *(float*)&ScriptParams[2]; + if (b3D) { + Z = *(float*)&ScriptParams[3]; + dX = *(float*)&ScriptParams[4]; + dY = *(float*)&ScriptParams[5]; + dZ = *(float*)&ScriptParams[6]; + debug = ScriptParams[7]; + } + else { + dX = *(float*)&ScriptParams[3]; + dY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) { + if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex) + continue; + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + continue; + } + CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + switch (command) { + case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D: + case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D: + case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D: + if (!CTheScripts::IsPedStopped(pPed)) { + result = false; + decided = true; + } + break; + default: + break; + } + if (!decided) { + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = false; + if (in_area) { + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_2D: + case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D: + result = true; + break; + case COMMAND_LOCATE_COLL_ON_FOOT_2D: + case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D: + result = !pPed->bInVehicle; + break; + case COMMAND_LOCATE_COLL_IN_CAR_2D: + case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D: + result = pPed->bInVehicle; + break; + default: + script_assert(false); + break; + } + } + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + +void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D: + case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D: + case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D: + b3D = false; + break; + default: + b3D = true; + break; + } + CollectParameters(pIp, b3D ? 6 : 5); + CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]); + script_assert(pTarget); + if (pTarget->bInVehicle) { + X = pTarget->m_pMyVehicle->GetPosition().x; + Y = pTarget->m_pMyVehicle->GetPosition().y; + Z = pTarget->m_pMyVehicle->GetPosition().z; + } + else { + X = pTarget->GetPosition().x; + Y = pTarget->GetPosition().y; + Z = pTarget->GetPosition().z; + } + dX = *(float*)&ScriptParams[2]; + dY = *(float*)&ScriptParams[3]; + if (b3D) { + dZ = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + else { + debug = ScriptParams[4]; + } + result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) { + if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex) + continue; + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + continue; + } + CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = false; + if (in_area) { + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D: + result = true; + break; + case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D: + result = !pPed->bInVehicle; + break; + case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D: + result = pPed->bInVehicle; + break; + default: + script_assert(false); + break; + } + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + +void CRunningScript::LocateCollectiveCarCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D: + case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D: + case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D: + b3D = false; + break; + default: + b3D = true; + break; + } + CollectParameters(pIp, b3D ? 6 : 5); + CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + script_assert(pTarget); + X = pTarget->GetPosition().x; + Y = pTarget->GetPosition().y; + Z = pTarget->GetPosition().z; + dX = *(float*)&ScriptParams[2]; + dY = *(float*)&ScriptParams[3]; + if (b3D) { + dZ = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + else { + debug = ScriptParams[4]; + } + result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) { + if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex) + continue; + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + continue; + } + CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = false; + if (in_area) { + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D: + result = true; + break; + case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D: + result = !pPed->bInVehicle; + break; + case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D: + result = pPed->bInVehicle; + break; + default: + script_assert(false); + break; + } + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + +void CRunningScript::LocateCollectivePlayerCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D: + case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D: + case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D: + b3D = false; + break; + default: + b3D = true; + break; + } + CollectParameters(pIp, b3D ? 6 : 5); + CVector pos = CWorld::Players[ScriptParams[1]].GetPos(); + X = pos.x; + Y = pos.y; + Z = pos.z; + dX = *(float*)&ScriptParams[2]; + dY = *(float*)&ScriptParams[3]; + if (b3D) { + dZ = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + else { + debug = ScriptParams[4]; + } + result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) { + if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex) + continue; + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + continue; + } + CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = false; + if (in_area) { + switch (command) { + case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D: + result = true; + break; + case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D: + result = !pPed->bInVehicle; + break; + case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D: + result = pPed->bInVehicle; + break; + default: + script_assert(false); + break; + } + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + +void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug, decided = false; + float infX, infY, infZ, supX, supY, supZ; + switch (command) { + case COMMAND_IS_COLL_IN_AREA_2D: + case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D: + case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D: + b3D = false; + break; + default: + b3D = true; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + infX = *(float*)&ScriptParams[1]; + infY = *(float*)&ScriptParams[2]; + if (b3D) { + infZ = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[5]; + supZ = *(float*)&ScriptParams[6]; + if (infZ > supZ) { + infZ = *(float*)&ScriptParams[6]; + supZ = *(float*)&ScriptParams[3]; + } + debug = ScriptParams[7]; + } + else { + supX = *(float*)&ScriptParams[3]; + supY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + if (infX > supX) { + float tmp = infX; + infX = supX; + supX = tmp; + } + if (infY > supY) { + float tmp = infY; + infY = supY; + supY = tmp; + } + result = true; + for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) { + if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex) + continue; + CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex); + if (!pPed) { + CTheScripts::CollectiveArray[i].colIndex = -1; + CTheScripts::CollectiveArray[i].pedIndex = 0; + continue; + } + CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + switch (command) { + case COMMAND_IS_COLL_STOPPED_IN_AREA_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D: + if (!CTheScripts::IsPedStopped(pPed)) { + result = false; + decided = true; + } + break; + default: + break; + } + if (!decided) { + bool in_area; + if (b3D) { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y && + infZ <= pos.z && + supZ >= pos.z; + } + else { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y; + } + result = false; + if (in_area) { + switch (command) { + case COMMAND_IS_COLL_IN_AREA_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_2D: + result = true; + break; + case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D: + result = !pPed->bInVehicle; + break; + case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D: + case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D: + result = pPed->bInVehicle; + break; + default: + script_assert(false); + break; + } + } + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); + else + CTheScripts::DrawDebugSquare(infX, infY, supX, supY); + } +} +#endif + bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type) { if (actual == -1) @@ -1579,54 +1921,54 @@ bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type) return false; switch (actual) { - case WEAPONTYPE_UNARMED: - case WEAPONTYPE_BRASSKNUCKLE: - case WEAPONTYPE_SCREWDRIVER: - case WEAPONTYPE_GOLFCLUB: - case WEAPONTYPE_NIGHTSTICK: - case WEAPONTYPE_KNIFE: - case WEAPONTYPE_BASEBALLBAT: - case WEAPONTYPE_HAMMER: - case WEAPONTYPE_CLEAVER: - case WEAPONTYPE_MACHETE: - case WEAPONTYPE_KATANA: - case WEAPONTYPE_CHAINSAW: - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_DETONATOR_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_COLT45: - case WEAPONTYPE_PYTHON: - case WEAPONTYPE_SHOTGUN: - case WEAPONTYPE_SPAS12_SHOTGUN: - case WEAPONTYPE_STUBBY_SHOTGUN: - case WEAPONTYPE_TEC9: - case WEAPONTYPE_UZI: - case WEAPONTYPE_SILENCED_INGRAM: - case WEAPONTYPE_MP5: - case WEAPONTYPE_M4: - case WEAPONTYPE_RUGER: - case WEAPONTYPE_SNIPERRIFLE: - case WEAPONTYPE_LASERSCOPE: - case WEAPONTYPE_ROCKETLAUNCHER: - case WEAPONTYPE_FLAMETHROWER: - case WEAPONTYPE_M60: - case WEAPONTYPE_MINIGUN: - case WEAPONTYPE_DETONATOR: - case WEAPONTYPE_HELICANNON: - case WEAPONTYPE_CAMERA: - case WEAPONTYPE_EXPLOSION: - case WEAPONTYPE_UZI_DRIVEBY: - return true; - case WEAPONTYPE_HEALTH: - case WEAPONTYPE_ARMOUR: - case WEAPONTYPE_RAMMEDBYCAR: - case WEAPONTYPE_RUNOVERBYCAR: - case WEAPONTYPE_DROWNING: - case WEAPONTYPE_FALL: - case WEAPONTYPE_UNIDENTIFIED: - return false; + case WEAPONTYPE_UNARMED: + case WEAPONTYPE_BRASSKNUCKLE: + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_BASEBALLBAT: + case WEAPONTYPE_HAMMER: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + case WEAPONTYPE_CHAINSAW: + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_DETONATOR_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_ROCKETLAUNCHER: + case WEAPONTYPE_FLAMETHROWER: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_DETONATOR: + case WEAPONTYPE_HELICANNON: + case WEAPONTYPE_CAMERA: + case WEAPONTYPE_EXPLOSION: + case WEAPONTYPE_UZI_DRIVEBY: + return true; + case WEAPONTYPE_HEALTH: + case WEAPONTYPE_ARMOUR: + case WEAPONTYPE_RAMMEDBYCAR: + case WEAPONTYPE_RUNOVERBYCAR: + case WEAPONTYPE_DROWNING: + case WEAPONTYPE_FALL: + case WEAPONTYPE_UNIDENTIFIED: + return false; } return false; @@ -1784,10 +2126,10 @@ INITSAVEBUF handle = 0; } else if (pBuilding->GetIsATreadable()) { type = 1; - handle = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding) + 1; + handle = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pBuilding) + 1; } else { type = 2; - handle = CPools::GetBuildingPool()->GetJustIndex(pBuilding) + 1; + handle = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding) + 1; } WriteSaveBuf(buf, type); WriteSaveBuf(buf, handle); @@ -1805,19 +2147,19 @@ INITSAVEBUF case ENTITY_TYPE_BUILDING: if (((CBuilding*)pEntity)->GetIsATreadable()) { type = 1; - handle = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pEntity) + 1; + handle = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pEntity) + 1; } else { type = 2; - handle = CPools::GetBuildingPool()->GetJustIndex((CBuilding*)pEntity) + 1; + handle = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)pEntity) + 1; } break; case ENTITY_TYPE_OBJECT: type = 3; - handle = CPools::GetObjectPool()->GetJustIndex((CObject*)pEntity) + 1; + handle = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)pEntity) + 1; break; case ENTITY_TYPE_DUMMY: type = 4; - handle = CPools::GetDummyPool()->GetJustIndex((CDummy*)pEntity) + 1; + handle = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)pEntity) + 1; default: break; } } @@ -1909,6 +2251,80 @@ VALIDATESAVEBUF(size) #undef SCRIPT_DATA_SIZE +void CRunningScript::Save(uint8*& buf) +{ +#ifdef COMPATIBLE_SAVES + SkipSaveBuf(buf, 8); + for (int i = 0; i < 8; i++) + WriteSaveBuf<char>(buf, m_abScriptName[i]); + WriteSaveBuf<uint32>(buf, m_nIp); +#ifdef CHECK_STRUCT_SIZES + static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); +#endif + for (int i = 0; i < MAX_STACK_DEPTH; i++) + WriteSaveBuf<uint32>(buf, m_anStack[i]); + WriteSaveBuf<uint16>(buf, m_nStackPointer); + SkipSaveBuf(buf, 2); +#ifdef CHECK_STRUCT_SIZES + static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); +#endif + for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + WriteSaveBuf<int32>(buf, m_anLocalVariables[i]); + WriteSaveBuf<bool>(buf, m_bIsActive); + WriteSaveBuf<bool>(buf, m_bCondResult); + WriteSaveBuf<bool>(buf, m_bIsMissionScript); + WriteSaveBuf<bool>(buf, m_bSkipWakeTime); + WriteSaveBuf<uint32>(buf, m_nWakeTime); + WriteSaveBuf<uint16>(buf, m_nAndOrState); + WriteSaveBuf<bool>(buf, m_bNotFlag); + WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled); + WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted); + WriteSaveBuf<bool>(buf, m_bMissionFlag); + SkipSaveBuf(buf, 2); +#else + WriteSaveBuf(buf, *this); +#endif +} + +void CRunningScript::Load(uint8*& buf) +{ +#ifdef COMPATIBLE_SAVES + SkipSaveBuf(buf, 8); + for (int i = 0; i < 8; i++) + m_abScriptName[i] = ReadSaveBuf<char>(buf); + m_nIp = ReadSaveBuf<uint32>(buf); +#ifdef CHECK_STRUCT_SIZES + static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); +#endif + for (int i = 0; i < MAX_STACK_DEPTH; i++) + m_anStack[i] = ReadSaveBuf<uint32>(buf); + m_nStackPointer = ReadSaveBuf<uint16>(buf); + SkipSaveBuf(buf, 2); +#ifdef CHECK_STRUCT_SIZES + static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); +#endif + for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + m_anLocalVariables[i] = ReadSaveBuf<int32>(buf); + m_bIsActive = ReadSaveBuf<bool>(buf); + m_bCondResult = ReadSaveBuf<bool>(buf); + m_bIsMissionScript = ReadSaveBuf<bool>(buf); + m_bSkipWakeTime = ReadSaveBuf<bool>(buf); + m_nWakeTime = ReadSaveBuf<uint32>(buf); + m_nAndOrState = ReadSaveBuf<uint16>(buf); + m_bNotFlag = ReadSaveBuf<bool>(buf); + m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf); + m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf); + m_bMissionFlag = ReadSaveBuf<bool>(buf); + SkipSaveBuf(buf, 2); +#else + CRunningScript* n = next; + CRunningScript* p = prev; + *this = ReadSaveBuf<CRunningScript>(buf); + next = n; + prev = p; +#endif +} + void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity) { static CColPoint aTempColPoints[MAX_COLLISION_POINTS]; @@ -2032,6 +2448,172 @@ void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, fl CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, ¢er, supX - center.x, 0.0f, 0.0f, center.y - supY, 0); } +#ifdef GTA_SCRIPT_COLLECTIVE +int CTheScripts::AddPedsInVehicleToCollective(int index) +{ + int colIndex = NextFreeCollectiveIndex; + AdvanceCollectiveIndex(); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(index); + script_assert(pVehicle); + CPed* pDriver = pVehicle->pDriver; + if (pDriver && !pDriver->IsPlayer() && pDriver->CharCreatedBy != MISSION_CHAR && pDriver->m_nPedType != PEDTYPE_COP) { + int index = FindFreeSlotInCollectiveArray(); + if (index > -1) { + CollectiveArray[index].colIndex = colIndex; + CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pDriver); + } + } + for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) { + CPed* pPassenger = pVehicle->pPassengers[i]; + if (pPassenger && !pPassenger->IsPlayer() && pPassenger->CharCreatedBy != MISSION_CHAR && pPassenger->m_nPedType != PEDTYPE_COP) { + int index = FindFreeSlotInCollectiveArray(); + if (index > -1) { + CollectiveArray[index].colIndex = colIndex; + CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPassenger); + } + } + } + return colIndex; +} + +int CTheScripts::AddPedsInAreaToCollective(float x, float y, float z, float radius) +{ + int16 numFound; + CEntity* pEntities[64]; + int colIndex = NextFreeCollectiveIndex; + AdvanceCollectiveIndex(); + CWorld::FindObjectsInRange(CVector(x, y, z), radius, true, &numFound, 64, pEntities, false, true, true, false, false); + for (int16 i = 0; i < numFound; i++) { + if (pEntities[i]->GetType() == ENTITY_TYPE_PED) { + CPed* pPed = (CPed*)pEntities[i]; + if (pPed && !pPed->IsPlayer() && pPed->CharCreatedBy != MISSION_CHAR && pPed->m_nPedType != PEDTYPE_COP) { + int index = FindFreeSlotInCollectiveArray(); + if (index > -1) { + CollectiveArray[index].colIndex = colIndex; + CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPed); + } + } + } + else if (pEntities[i]->GetType() == ENTITY_TYPE_VEHICLE) { + CVehicle* pVehicle = (CVehicle*)pEntities[i]; + CPed* pDriver = pVehicle->pDriver; + if (pDriver && !pDriver->IsPlayer() && pDriver->CharCreatedBy != MISSION_CHAR && pDriver->m_nPedType != PEDTYPE_COP) { + int index = FindFreeSlotInCollectiveArray(); + if (index > -1) { + CollectiveArray[index].colIndex = colIndex; + CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pDriver); + } + } + for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) { + CPed* pPassenger = pVehicle->pPassengers[i]; + if (pPassenger && !pPassenger->IsPlayer() && pPassenger->CharCreatedBy != MISSION_CHAR && pPassenger->m_nPedType != PEDTYPE_COP) { + int index = FindFreeSlotInCollectiveArray(); + if (index > -1) { + CollectiveArray[index].colIndex = colIndex; + CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPassenger); + } + } + } + } + } + return colIndex; +} + +int CTheScripts::FindFreeSlotInCollectiveArray() +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == -1) + return i; + } + return -1; +} + +void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, int16 p1, int16 p2) +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == colIndex) { + CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex); + if (pPed == nil) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + else { + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(objective, p1, p2); + } + } + } +} + +void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, CVector p1, float p2) +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == colIndex) { + CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex); + if (pPed == nil) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + else { + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(objective, p1, p2); + } + } + } +} + +void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, CVector p1) +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == colIndex) { + CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex); + if (pPed == nil) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + else { + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(objective, p1); + } + } + } +} + +void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, void* p1) +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == colIndex) { + CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex); + if (pPed == nil) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + else { + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(objective, p1); + } + } + } +} + +void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective) +{ + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + if (CollectiveArray[i].colIndex == colIndex) { + CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex); + if (pPed == nil) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + else { + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(objective); + } + } + } +} +#endif //GTA_SCRIPT_COLLECTIVE + bool CTheScripts::IsPedStopped(CPed* pPed) { if (pPed->InVehicle()) @@ -2122,10 +2704,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) if (pPed->IsPedInControl()) pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7); if (flees) { - if (pPed->m_nPedState == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH) - pPed->ClearFollowPath(); - - pPed->m_nPedState = state; + pPed->SetPedState(state); pPed->SetMoveState(ms); } --CPopulation::ms_nTotalMissionPeds; @@ -2180,7 +2759,7 @@ void CTheScripts::UpdateObjectIndices() CBaseModelInfo* pModel = CModelInfo::GetModelInfo(j); if (!pModel) continue; - strcpy(name, pModel->GetName()); + strcpy(name, pModel->GetModelName()); #ifdef FIX_BUGS for (int k = 0; k < USED_OBJECT_NAME_LENGTH && name[k]; k++) #else diff --git a/src/control/Script6.cpp b/src/control/Script6.cpp index 53464804..4d7121f2 100644 --- a/src/control/Script6.cpp +++ b/src/control/Script6.cpp @@ -3,6 +3,7 @@ #include "Script.h" #include "ScriptCommands.h" +#include "Bike.h" #include "CarCtrl.h" #include "Cranes.h" #include "Credits.h" @@ -31,7 +32,6 @@ #include "Weather.h" #include "Zones.h" #include "main.h" -#include "Bike.h" #include "GameLogic.h" #include "Sprite.h" #include "CarAI.h" @@ -42,6 +42,19 @@ extern const char* scriptfile; #endif +bool CRunningScript::ThisIsAValidRandomCop(uint32 mi, int cop, int swat, int fbi, int army, int miami) +{ + switch (mi) + { + case MI_COP: if (cop) return true; break; + case MI_SWAT: if (swat) return true; break; + case MI_FBI: if (fbi) return true; break; + case MI_ARMY: if (army) return true; break; + default: if (mi >= MI_VICE1 && mi <= MI_VICE8 && miami) return true; break; + } + return false; +} + bool CRunningScript::ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal) { switch (pedtype) { @@ -66,19 +79,6 @@ bool CRunningScript::ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, in } } -bool CRunningScript::ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami) -{ - switch (mi) - { - case MI_COP: if (cop) return true; - case MI_SWAT: if (swat) return true; - case MI_FBI: if (fbi) return true; - case MI_ARMY: if (army) return true; - default: - return miami && (mi >= MI_VICE1 && mi <= MI_VICE8); - } -} - int8 CRunningScript::ProcessCommands1000To1099(int32 command) { switch (command) { @@ -703,7 +703,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_START_BOAT_FOAM_ANIMATION: @@ -999,7 +999,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CVector vTestedPos(pTestedPed->GetPosition().x, pTestedPed->GetPosition().y, pTestedPed->GetPosition().z + 0.4); CVector vScreenPos; float w, h; - if (CSprite::CalcScreenCoors(vTestedPos, vScreenPos, &w, &h, false)) { + if (CSprite::CalcScreenCoors(vTestedPos, &vScreenPos, &w, &h, false)) { CVector2D vCrosshairPosition(CCamera::m_f3rdPersonCHairMultX * RsGlobal.maximumWidth, CCamera::m_f3rdPersonCHairMultY * RsGlobal.maximumHeight); float fScreenDistance = ((CVector2D)vScreenPos - vCrosshairPosition).Magnitude(); if (SCREEN_STRETCH_X(0.45f) > fScreenDistance / w) { @@ -1191,7 +1191,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 8); CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); - pPed->AttachPedToEntity(pVehicle, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(ScriptParams[6]), (eWeaponType)ScriptParams[7]); + pPed->AttachPedToEntity(pVehicle, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(*(float*)&ScriptParams[6]), (eWeaponType)ScriptParams[7]); return 0; } case COMMAND_DETACH_CHAR_FROM_CAR: @@ -1272,7 +1272,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1320,7 +1320,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1409,7 +1409,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 3); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - pVehicle->AutoPilot.m_nTempAction = (eCarTempAction)ScriptParams[1]; + pVehicle->AutoPilot.m_nTempAction = (uint8)ScriptParams[1]; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[2]; return 0; } diff --git a/src/control/Script7.cpp b/src/control/Script7.cpp index 1bad3407..34a364a7 100644 --- a/src/control/Script7.cpp +++ b/src/control/Script7.cpp @@ -95,8 +95,8 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) CollectParameters(&m_nIp, 2); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - ScriptParams[0] = pPed->GetWeapon(ScriptParams[1]).m_eWeaponType; - ScriptParams[1] = pPed->GetWeapon(ScriptParams[1]).m_nAmmoTotal; + ScriptParams[0] = pPed->GetWeapon(ScriptParams[1] - 1).m_eWeaponType; + ScriptParams[1] = pPed->GetWeapon(ScriptParams[1] - 1).m_nAmmoTotal; ScriptParams[2] = CPickups::ModelForWeapon((eWeaponType)ScriptParams[0]); StoreParameters(&m_nIp, 3); return 0; @@ -576,11 +576,11 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) CollectParameters(&m_nIp, 1); CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels; - ScriptParams[1] = *(int*)&pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels; + *(float*)&ScriptParams[1] = pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels; ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie; - ScriptParams[3] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnWheelie; + *(float*)&ScriptParams[3] = pPlayerInfo->m_nLastDistanceTravelledOnWheelie; ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie; - ScriptParams[5] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnStoppie; + *(float*)&ScriptParams[5] = pPlayerInfo->m_nLastDistanceTravelledOnStoppie; StoreParameters(&m_nIp, 6); pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0; pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f; @@ -625,7 +625,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) key[i] = tolower(key[i]); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; script_assert(pPed); - UpdateCompareFlag(strcmp(key, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName()) == 0); + UpdateCompareFlag(strcmp(key, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetModelName()) == 0); return 0; } case COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY: @@ -793,6 +793,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); pVehicle->bIsFrozen = ScriptParams[1]; + pVehicle->bInfiniteMass = ScriptParams[1]; return 0; } case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CHAR: @@ -1104,6 +1105,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); script_assert(pObject); pObject->bIsFrozen = ScriptParams[1]; + pObject->bInfiniteMass = ScriptParams[1]; return 0; } case COMMAND_SET_PLAYER_HAS_MET_DEBBIE_HARRY: @@ -1201,7 +1203,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER: @@ -1231,7 +1233,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: diff --git a/src/control/Script8.cpp b/src/control/Script8.cpp index 7af0ac8e..9a8e536e 100644 --- a/src/control/Script8.cpp +++ b/src/control/Script8.cpp @@ -4,8 +4,18 @@ #include "ScriptCommands.h" #include "DMAudio.h" +#if ((defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) && defined MORE_LANGUAGES) +#include "Frontend.h" +#endif #include "GameLogic.h" #include "Garages.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +#include "General.h" +#include "maths.h" +#endif #include "Hud.h" #include "Pad.h" #include "PedAttractor.h" @@ -53,11 +63,11 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) case COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE: CollectParameters(&m_nIp, 2); CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]); - break; + return 0; case COMMAND_WANTED_STARS_ARE_FLASHING: { - CWanted *pWanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted; - UpdateCompareFlag(pWanted->m_nMinWantedLevel - pWanted->m_nWantedLevel > 0); + CWanted* pWanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted; + UpdateCompareFlag(pWanted->m_nMinWantedLevel - pWanted->GetWantedLevel() > 0); return 0; } case COMMAND_SET_ALLOW_HURRICANES: @@ -122,11 +132,12 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) CollectParameters(&m_nIp, 1); CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; char key[KEY_LENGTH_IN_SCRIPT]; + memset(key, 0, KEY_LENGTH_IN_SCRIPT); CTheScripts::ReadTextLabelFromScript(&m_nIp, key); m_nIp += KEY_LENGTH_IN_SCRIPT; CVector pos = pPlayerInfo->GetPos(); - CZone *infoZone = CTheZones::FindInformationZoneForPosition(&pos); - UpdateCompareFlag(strncmp(key, infoZone->name, 8) == 0); + CZone* infoZone = CTheZones::FindInformationZoneForPosition(&pos); + UpdateCompareFlag(strncmp(key, infoZone->name, 8) == 0); // original code doesn't seem to be using strncmp in here and compare 2 ints instead return 0; } case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE: @@ -272,7 +283,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -341,7 +352,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) case COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI: { CollectParameters(&m_nIp, 3); - CObject *pHeli = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CObject* pHeli = CPools::GetObjectPool()->GetAt(ScriptParams[0]); bool found = false; float waterLevel = -1000.0f; CVector pos = pHeli->GetPosition(); @@ -373,6 +384,230 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) } return 0; } +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + case COMMAND_IS_JAPANESE_GAME: +#ifdef MORE_LANGUAGES + UpdateCompareFlag(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_JAPANESE); +#elif (defined GTAVC_JP_PATCH) + UpdateCompareFlag(true); +#else + UpdateCompareFlag(false); +#endif + return 0; +#elif (!defined GTA_PS2) + case COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED: + { + script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 1); + //CUserDisplay::OnscnTimer.SetCounterFlashWhenFirstDisplayed(var, ScriptParams[0]); + return 0; + } +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + case COMMAND_SHUFFLE_CARD_DECKS: + { + CollectParameters(&m_nIp, 1); + script_assert(ScriptParams[0] >= 0 && ScriptParams[0] <= 6); + for (int i = 0; i < CARDS_IN_STACK; i++) + CTheScripts::CardStack[i] = 0; + int16 seq[CARDS_IN_STACK]; + for (int i = 0; i < MAX_DECKS * CARDS_IN_DECK; i++) + seq[i] = i; + int cards_left = CARDS_IN_DECK * ScriptParams[0]; + for (int k = 1; k < CARDS_IN_DECK + 1; k++) { + for (int deck = 0; deck < ScriptParams[0]; deck++) { + int index = CGeneral::GetRandomNumberInRange(0, cards_left); + CTheScripts::CardStack[seq[index]] = k; + for (int l = index; l < cards_left; l++) { + if (l + 1 < CARDS_IN_STACK) + seq[l] = seq[l + 1]; + else + seq[l] = 0; + } + --cards_left; + } + } + CTheScripts::CardStackPosition = 0; + return 0; + } + case COMMAND_FETCH_NEXT_CARD: + { + if (CTheScripts::CardStack[CTheScripts::CardStackPosition] == 0) + CTheScripts::CardStackPosition = 0; + ScriptParams[0] = CTheScripts::CardStack[CTheScripts::CardStackPosition++]; + if (CTheScripts::CardStackPosition == CARDS_IN_DECK * MAX_DECKS) + CTheScripts::CardStackPosition = 0; + StoreParameters(&m_nIp, 1); + return 0; + } + case COMMAND_GET_OBJECT_VELOCITY: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(CVector*)&ScriptParams[0] = GAME_SPEED_TO_METERS_PER_SECOND * pObject->GetMoveSpeed(); + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_IS_DEBUG_CAMERA_ON: + UpdateCompareFlag(TheCamera.WorldViewerBeingUsed); + return 0; + case COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector newSpeed = pObject->GetTurnSpeed() + *(CVector*)&ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z); + return 0; + } + case COMMAND_SET_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector newSpeed = *(CVector*)&ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z); + return 0; + } + case COMMAND_IS_OBJECT_STATIC: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(pObject->GetIsStatic()); + return 0; + } + case COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS: + { + CollectParameters(&m_nIp, 4); + CVector2D v1 = *(CVector2D*)&ScriptParams[0]; + CVector2D v2 = *(CVector2D*)&ScriptParams[2]; + float c = DotProduct2D(v1, v2) / (v1.Magnitude() * v2.Magnitude()); +#ifdef FIX_BUGS // command is a SA leftover where it was fixed to this + *(float*)&ScriptParams[0] = RADTODEG(Acos(c)); +#else + *(float*)&ScriptParams[0] = Acos(c); +#endif + return 0; + } + case COMMAND_DO_2D_RECTANGLES_COLLIDE: + { + CollectParameters(&m_nIp, 8); + float infX1 = *(float*)&ScriptParams[0] - *(float*)&ScriptParams[2] * 0.5; // NB: not float + float supX1 = *(float*)&ScriptParams[0] + *(float*)&ScriptParams[2] * 0.5; + float infX2 = *(float*)&ScriptParams[4] - *(float*)&ScriptParams[6] * 0.5; + float supX2 = *(float*)&ScriptParams[4] + *(float*)&ScriptParams[6] * 0.5; + float infY1 = *(float*)&ScriptParams[1] - *(float*)&ScriptParams[3] * 0.5; + float supY1 = *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3] * 0.5; + float infY2 = *(float*)&ScriptParams[5] - *(float*)&ScriptParams[7] * 0.5; + float supY2 = *(float*)&ScriptParams[5] + *(float*)&ScriptParams[7] * 0.5; + bool collide = true; + if (infY2 > supY1) + collide = false; + if (infY1 > supY2) + collide = false; + if (infX2 > supX1) + collide = false; + if (infX1 > supX2) + collide = false; + UpdateCompareFlag(collide); + return 0; + } + case COMMAND_GET_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(CVector*)&ScriptParams[0] = pObject->GetTurnSpeed() * GAME_SPEED_TO_METERS_PER_SECOND; + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector vecAddition = *(CVector*)&ScriptParams[1] * CTimer::GetTimeStep() / GAME_SPEED_TO_METERS_PER_SECOND; + if (!pObject->bIsStatic) { + CVector vecCurrSpeed = pObject->GetSpeed(); + vecCurrSpeed.Normalise(); + if (vecCurrSpeed.z != 1.0) { // NB: not float! + CVector vx = CrossProduct(vecCurrSpeed, CVector(0.0f, 0.0f, 1.0f)); + vx.Normalise(); + CVector vz = CrossProduct(vx, vecCurrSpeed); + vz.Normalise(); + CVector vecNewSpeed = pObject->GetSpeed() + vecAddition.x * vx + vecAddition.y * vecCurrSpeed + vecAddition.z * vecCurrSpeed; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetMoveSpeed(vecNewSpeed); + } + } + return 0; + } + case COMMAND_GET_OBJECT_SPEED: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(float*)&ScriptParams[0] = pObject->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND; + StoreParameters(&m_nIp, 1); + return 0; + } +#endif +#if (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + case COMMAND_IS_MISSION_SKIP: +#ifdef MISSION_REPLAY + ScriptParams[0] = MissionSkipLevel; +#else + ScriptParams[0] = 0; +#endif + StoreParameters(&m_nIp, 1); + return 0; + case COMMAND_SET_IN_AMMUNATION: + CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + IsInAmmunation = ScriptParams[0]; +#endif + return 0; + case COMMAND_DO_SAVE_GAME: + CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + SaveGameForPause(ScriptParams[0]); +#endif + return 0; + case COMMAND_IS_RETRY: +#ifdef MISSION_REPLAY + if (strcmp(m_abScriptName, "porno4") != 0) + ScriptParams[0] = AllowMissionReplay; +#ifdef FIX_BUGS + else + ScriptParams[0] = gbTryingPorn4Again; +#else + else if (gbTryingPorn4Again) + ScriptParams[0] = 1; +#endif +#else + ScriptParams[0] = 0; +#endif + StoreParameters(&m_nIp, 1); + return 0; + case COMMAND_DUMMY: + return 0; +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + // it is unknown what these commands do but they don't take parameters + case COMMAND_MARK_CUTSCENE_START: + return 0; + case COMMAND_MARK_CUTSCENE_END: + return 0; + case COMMAND_CUTSCENE_SCROLL: + return 0; +#endif default: script_assert(0); } diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h index 18fc9575..9863e852 100644 --- a/src/control/ScriptCommands.h +++ b/src/control/ScriptCommands.h @@ -1437,6 +1437,39 @@ enum { COMMAND_REGISTER_FIRE_LEVEL, COMMAND_IS_AUSTRALIAN_GAME, COMMAND_DISARM_CAR_BOMB, +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + COMMAND_IS_JAPANESE_GAME, +#elif (!defined GTA_PS2) + COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED, +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + COMMAND_SHUFFLE_CARD_DECKS, + COMMAND_FETCH_NEXT_CARD, + COMMAND_GET_OBJECT_VELOCITY, + COMMAND_IS_DEBUG_CAMERA_ON, + COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY, + COMMAND_SET_OBJECT_ROTATION_VELOCITY, + COMMAND_IS_OBJECT_STATIC, + COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS, + COMMAND_DO_2D_RECTANGLES_COLLIDE, + COMMAND_GET_OBJECT_ROTATION_VELOCITY, + COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY, + COMMAND_GET_OBJECT_SPEED, +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT) + COMMAND_MARK_CUTSCENE_START, + COMMAND_MARK_CUTSCENE_END, + COMMAND_CUTSCENE_SCROLL, +#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + COMMAND_IS_MISSION_SKIP, + COMMAND_SET_IN_AMMUNATION, + COMMAND_DO_SAVE_GAME, + COMMAND_IS_RETRY, + COMMAND_DUMMY, + COMMAND_MARK_CUTSCENE_START, + COMMAND_MARK_CUTSCENE_END, + COMMAND_CUTSCENE_SCROLL, +#endif #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT LAST_SCRIPT_COMMAND #endif diff --git a/src/control/SetPieces.cpp b/src/control/SetPieces.cpp index 9b4e0075..143115b8 100644 --- a/src/control/SetPieces.cpp +++ b/src/control/SetPieces.cpp @@ -10,11 +10,10 @@ #include "Vehicle.h" #include "Wanted.h" #include "World.h" +#include "VarConsole.h" #define TIME_BETWEEN_SETPIECE_SPAWNS 20000 -//--MIAMI: file done - bool CSetPieces::bDebug; uint32 CSetPieces::NumSetPieces; CSetPiece CSetPieces::aSetPieces[NUM_SETPIECES]; @@ -23,13 +22,16 @@ void CSetPieces::Init(void) { bDebug = false; NumSetPieces = 0; +#ifndef MASTER + VarConsole.Add("Show set pieces", &bDebug, true); +#endif } void CSetPieces::AddOne(uint8 type, CVector2D vTriggerInf, CVector2D vTriggerSup, CVector2D vSpawn1, CVector2D vTarget1, CVector2D vSpawn2, CVector2D vTarget2) { if (NumSetPieces >= NUM_SETPIECES) return; - aSetPieces[NumSetPieces].m_nType = (eSetPieceType)type; + aSetPieces[NumSetPieces].m_nType = type; aSetPieces[NumSetPieces].m_vTriggerInf.x = Min(vTriggerInf.x, vTriggerSup.x); aSetPieces[NumSetPieces].m_vTriggerInf.y = Min(vTriggerInf.y, vTriggerSup.y); aSetPieces[NumSetPieces].m_vTriggerSup.x = Max(vTriggerInf.x, vTriggerSup.x); @@ -47,6 +49,9 @@ void CSetPieces::Update(void) int nLast = NumSetPieces * (CTimer::GetFrameCounter() % 8 + 1) / 8; for (int i = nFirst; i < nLast; i++) aSetPieces[i].Update(); +#ifndef MASTER + // TODO: debug code from mobile +#endif // !MASTER } void CSetPieces::Save(uint8* buf, uint32* size) @@ -79,7 +84,7 @@ void CSetPiece::Update(void) switch (m_nType) { case SETPIECE_TWOCOPCARSINALLEY: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 1 || FindPlayerVehicle()) return; CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); if (!pVehicle1) @@ -113,7 +118,7 @@ void CSetPiece::Update(void) } case SETPIECE_CARBLOCKINGPLAYERFROMSIDE: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 2) return; if (!FindPlayerVehicle()) return; @@ -136,7 +141,7 @@ void CSetPiece::Update(void) } case SETPIECE_CARRAMMINGPLAYERFROMSIDE: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 2) return; if (!FindPlayerVehicle()) return; @@ -159,7 +164,7 @@ void CSetPiece::Update(void) } case SETPIECE_CREATECOPPERONFOOT: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 1 || FindPlayerVehicle()) return; CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1); if (!pCop) @@ -173,7 +178,7 @@ void CSetPiece::Update(void) } case SETPIECE_CREATETWOCOPPERSONFOOT: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 1 || FindPlayerVehicle()) return; CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1); if (!pCop) @@ -197,7 +202,7 @@ void CSetPiece::Update(void) } case SETPIECE_TWOCARSBLOCKINGPLAYERFROMSIDE: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 2) return; if (!FindPlayerVehicle()) return; @@ -235,7 +240,7 @@ void CSetPiece::Update(void) } case SETPIECE_TWOCARSRAMMINGPLAYERFROMSIDE: { - if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + if (FindPlayerPed()->m_pWanted->GetWantedLevel() < 2) return; if (!FindPlayerVehicle()) return; diff --git a/src/control/SetPieces.h b/src/control/SetPieces.h index 5776d35a..5c228d4c 100644 --- a/src/control/SetPieces.h +++ b/src/control/SetPieces.h @@ -5,7 +5,7 @@ class CVehicle; class CCopPed; -enum eSetPieceType : uint8 +enum eSetPieceType { SETPIECE_NONE = 0, SETPIECE_TWOCOPCARSINALLEY, @@ -20,7 +20,7 @@ enum eSetPieceType : uint8 class CSetPiece { public: - eSetPieceType m_nType; + uint8 m_nType; uint32 m_nLastTimeCreated; CVector2D m_vTriggerInf; CVector2D m_vTriggerSup; diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp index ecfc7207..df0761ab 100644 --- a/src/control/TrafficLights.cpp +++ b/src/control/TrafficLights.cpp @@ -15,8 +15,6 @@ #include "Weather.h" #include "World.h" -//--MIAMI: file done - bool CTrafficLights::bGreenLightsCheat; void diff --git a/src/core/Accident.cpp b/src/core/Accident.cpp index cb46e181..c8611323 100644 --- a/src/core/Accident.cpp +++ b/src/core/Accident.cpp @@ -6,8 +6,6 @@ #include "Pools.h" #include "World.h" -// --MIAMI: File done - CAccidentManager gAccidentManager; CAccident* diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index 8b798268..854ec7d4 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -47,7 +47,6 @@ CEntity *CAnimViewer::pTarget = nil; void CAnimViewer::Render(void) { if (pTarget) { -// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); if (pTarget) { #ifdef FIX_BUGS if(pTarget->IsPed()) @@ -113,7 +112,7 @@ CAnimViewer::Initialise(void) { CTimeCycle::Initialise(); CCarCtrl::Init(); CPlayerPed *player = new CPlayerPed(); - player->SetPosition(0.0f, 0.0f, 0.0f); + player->SetPosition(1000.0f, 1000.0f, 1000.0f); CWorld::Players[0].m_pPed = player; CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index bc01b58e..26232100 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -30,8 +30,6 @@ #include "Bike.h" #include "Pickups.h" -//--MIAMI: file done - bool PrintDebugCode = false; int16 DebugCamMode; @@ -180,9 +178,11 @@ CCam::Process(void) Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_FOLLOWPED: +#ifdef PC_PLAYER_CONTROLS if(CCamera::m_bUseMouse3rdPerson) Process_FollowPedWithMouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); else +#endif #ifdef FREE_CAM if(CCamera::bFreeCam) Process_FollowPed_Rotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); @@ -287,9 +287,11 @@ CCam::Process(void) case MODE_FIGHT_CAM_RUNABOUT: Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#ifdef GTA_SCENE_EDIT case MODE_EDITOR: Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#endif default: Source = CVector(0.0f, 0.0f, 0.0f); Front = CVector(0.0f, 1.0f, 0.0f); @@ -2366,8 +2368,10 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } - while(Beta >= PI) Beta -= 2*PI; - while(Beta < -PI) Beta += 2*PI; + if (!isAttached) { + while(Beta >= TWOPI) Beta -= TWOPI; + while(Beta < 0) Beta += TWOPI; + } if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); @@ -2410,13 +2414,14 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) } } }else{ - while(Beta < -PI) Beta += 2*PI; - while(Beta >= PI) Beta -= 2*PI; + while(Beta < -PI) Beta += TWOPI; + while(Beta >= PI) Beta -= TWOPI; } mat = TargetPed->m_attachedTo->GetMatrix(); rot.SetRotateX(Alpha); switch(TargetPed->m_attachType){ + case 0: rot.RotateZ(Beta); break; case 1: rot.RotateZ(Beta + HALFPI); break; case 2: rot.RotateZ(Beta + PI); break; case 3: rot.RotateZ(Beta - HALFPI); break; @@ -2703,7 +2708,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(CamTargetEntity->GetClump()); int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD)); RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); - RwV3dTransformPoints((RwV3d*)&HeadPos, (RwV3d*)&HeadPos, 1, &mats[idx]); + RwV3dTransformPoints(&HeadPos, &HeadPos, 1, &mats[idx]); RwV3d scl = { 0.0f, 0.0f, 0.0f }; RwMatrixScale(&mats[idx], &scl, rwCOMBINEPRECONCAT); @@ -2744,7 +2749,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, Source = HeadPos; // unused: - // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID); + // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID); // Source - MidPos; // Look around @@ -2920,8 +2925,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float UseMouse = false; int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN); int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT); - // TODO: enum? this should be mouse wheel up and down - if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){ + if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){ if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){ if(CPad::GetPad(0)->SniperZoomIn()){ TargetFOV = FOV - 10.0f; @@ -3734,6 +3738,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) } } +#ifdef PC_PLAYER_CONTROLS if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ @@ -3744,6 +3749,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) TheCamera.pTargetEntity->GetMatrix().UpdateRW(); } } +#endif } void @@ -3939,11 +3945,11 @@ CCam::Process_Debug(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 75.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 75.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -4010,11 +4016,11 @@ CCam::Process_Debug(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 75.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 75.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -4034,6 +4040,7 @@ CCam::Process_Debug(const CVector&, float, float, float) } #endif +#ifdef GTA_SCENE_EDIT void CCam::Process_Editor(const CVector&, float, float, float) { @@ -4090,11 +4097,11 @@ CCam::Process_Editor(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 75.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 75.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -4112,6 +4119,7 @@ CCam::Process_Editor(const CVector&, float, float, float) sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z); } } +#endif void CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) @@ -4336,7 +4344,7 @@ CCam::ProcessArrestCamOne(void) ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetPos, PED_MID); if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop) cop = FindPlayerPed()->m_pArrestingCop; - if(cop && CGeneral::GetRandomNumberInRange(0.0f, 0.1f) > 0.5f){ + if(cop && CGeneral::GetRandomNumberInRange(0.0f, 1.0f) > 0.5f){ ArrestModes[0] = ARRESTCAM_OVERSHOULDER; ArrestModes[1] = ARRESTCAM_ALONGGROUND; ArrestModes[2] = ARRESTCAM_OVERSHOULDER; @@ -4358,7 +4366,7 @@ CCam::ProcessArrestCamOne(void) if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop) cop = FindPlayerPed()->m_pArrestingCop; - if(cop && CGeneral::GetRandomNumberInRange(0.0f, 0.1f) > 0.65f){ + if(cop && CGeneral::GetRandomNumberInRange(0.0f, 1.0f) > 0.65f){ ArrestModes[0] = ARRESTCAM_OVERSHOULDER; ArrestModes[1] = ARRESTCAM_LAMPPOST; ArrestModes[2] = ARRESTCAM_ALONGGROUND; @@ -4428,6 +4436,7 @@ CCam::ProcessArrestCamOne(void) pStoredCopPed = nil; } + Source = CamSource; CVector OrigSource = Source; TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV); Front = TargetPos - Source; @@ -4454,8 +4463,9 @@ CCam::ProcessArrestCamOne(void) if(nUsingWhichCamera == ARRESTCAM_OVERSHOULDER && pStoredCopPed){ foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, pStoredCopPed, TargetPos, CamSource); - if(CamSource.z > Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep()) - CamSource.z = Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep(); + float newZ = Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep(); + if(CamSource.z > newZ) + CamSource.z = newZ; }else if(nUsingWhichCamera >= ARRESTCAM_ALONGGROUND_RIGHT && nUsingWhichCamera <= ARRESTCAM_ALONGGROUND_LEFT_UP){ CamSource = Source; Front = TargetPos - CamSource; @@ -4909,13 +4919,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (FOV > DefaultFOV) // 0.98f: CAR_FOV_FADE_MULT - FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; + FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; - if (FOV <= DefaultFOV + 30.0f) { - if (FOV < DefaultFOV) - FOV = DefaultFOV; - } else - FOV = DefaultFOV + 30.0f; + FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f); } // WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta) @@ -5042,7 +5048,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, targetAlpha = maxAlphaAllowed; } float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6]; - float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); + float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); if (targetAlphaBlendAmount <= maxAlphaBlendAmount) { if (targetAlphaBlendAmount < -maxAlphaBlendAmount) targetAlphaBlendAmount = -maxAlphaBlendAmount; @@ -5052,11 +5058,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // Using GetCarGun(LR/UD) will give us same unprocessed RightStick value as SA float stickX = -(pad->GetCarGunLeftRight()); - float stickY = pad->GetCarGunUpDown(); + float stickY = -pad->GetCarGunUpDown(); - // In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used. - if (CCamera::m_bUseMouse3rdPerson) + // In SA this checks for m_bUseMouse3rdPerson so num2 / num8 do not move camera + // when Keyboard & Mouse controls are used. To make it work better with III/VC, check for actual pad state instead + if (!CPad::IsAffectedByController && !isCar) stickY = 0.0f; + else if (CPad::bInvertLook4Pad) + stickY = -stickY; float xMovement = Abs(stickX) * (FOV / 80.0f * 5.f / 70.f) * stickX * 0.007f * 0.007f; float yMovement = Abs(stickY) * (FOV / 80.0f * 3.f / 70.f) * stickY * 0.007f * 0.007f; @@ -5134,7 +5143,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12]; float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9]; - float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); + float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f); if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount) @@ -5246,69 +5255,78 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // SA calls SetColVarsVehicle in here if (nextDirectionIsForward) { - // This is new in LCS! + // LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so. + + // This is only in LCS! float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); - // Move cam if on collision - CColPoint foundCol; - CEntity* foundEnt; + // Our addition +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex())) + + // Clip Source and fix near clip + CColPoint colPoint; + CEntity* entity; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - float obstacleCamDist = newDistance - obstacleTargetDist; - if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); - } - } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float lessClip = obstacleCamDist - 0.35f; - if (lessClip <= DEFAULT_NEAR) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - } else { - obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - float lessClip = obstacleTargetDist - 0.3f; - if (lessClip >= 0.05f) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } + if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){ + float PedColDist = (TargetCoors - colPoint.point).Magnitude(); + float ColCamDist = newDistance - PedColDist; + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ + // Ped in the way but not clipping through + if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){ + PedColDist = (TargetCoors - colPoint.point).Magnitude(); + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); + }else{ + RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR)); } + }else{ + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); } } + CWorld::pIgnoreEntity = nil; - float nearClip = RwCameraGetNearClipPlane(Scene.camera); - float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. - for (int i = 0; - i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false); - i++) { - - CVector surfaceCamDist = gaTempSphereColPoints->point - Source; - CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; - float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; - - if (newNearClip > nearClip) - newNearClip = nearClip; - if (newNearClip < 0.1f) - newNearClip = 0.1f; - if (nearClip > newNearClip) - RwCameraSetNearClipPlane(Scene.camera, newNearClip); - - if (newNearClip == 0.1f) - Source += (TargetCoors - Source) * 0.3f; - - nearClip = RwCameraGetNearClipPlane(Scene.camera); - radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; + + float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); + float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fTweakFOV; + float Near = RwCameraGetNearClipPlane(Scene.camera); + float radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + int i = 0; + while(entity){ + + if (IS_TRAFFIC_LIGHT(entity)) + break; + + CVector CamToCol = gaTempSphereColPoints[0].point - Source; + float frontDist = DotProduct(CamToCol, Front); + float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; + + // Try to decrease near clip + dist = Max(Min(Near, dist), 0.1f); + if(dist < Near) + RwCameraSetNearClipPlane(Scene.camera, dist); + + // Move forward a bit + if(dist == 0.1f) + Source += (TargetCoors - Source)*0.3f; + + // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + + i++; + if(i > 5) + entity = nil; } +#undef IS_TRAFFIC_LIGHT } TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index a6cf71f1..25d2e5c3 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -69,7 +69,11 @@ enum // NB: removed explicit TheCamera from all functions CCamera TheCamera; +#ifdef PC_PLAYER_CONTROLS bool CCamera::m_bUseMouse3rdPerson = true; +#else +bool CCamera::m_bUseMouse3rdPerson = false; +#endif bool bDidWeProcessAnyCinemaCam; static bool bSwitchedToObbeCam; float CCamera::m_fMouseAccelHorzntl; @@ -1133,27 +1137,31 @@ CCamera::CamControl(void) }else{ whichDoor = 1; garageDoorPos1 = Cams[ActiveCam].Source; - garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2.0f, (stairsZone->miny+stairsZone->maxy)/2.0f, 0.0f); - if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f && - pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f && - pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){ -// if((garageCenter-garageDoorPos1).Magnitude() > 15.0f){ - bool bClearViewOutside = true; - CVector dirOutside = pTargetEntity->GetPosition() - garageCenter; - dirOutside.z = 0.0f; - dirOutside.Normalise(); - float zoneDim = stairsZone->maxx - stairsZone->minx; - if(zoneDim < stairsZone->maxy - stairsZone->miny) - zoneDim = stairsZone->maxy - stairsZone->miny; - zoneDim *= 2.0f; - CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside; - if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){ - posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside; - if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)) - bClearViewOutside = false; + + if(stairsZone){ // always true + garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2, (stairsZone->miny+stairsZone->maxy)/2, 0.0f); + if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f && + pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f && + pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){ + garageDoorPos1 = CVector(382.6f, -489.6f, 13.1f); + }else{ + bool bClearViewOutside = true; + CVector dirOutside = pTargetEntity->GetPosition() - garageCenter; + dirOutside.z = 0.0f; + dirOutside.Normalise(); + float zoneDim = stairsZone->maxx - stairsZone->minx; + if(zoneDim < stairsZone->maxy - stairsZone->miny) + zoneDim = stairsZone->maxy - stairsZone->miny; + zoneDim *= 2.0f; + CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside; + if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){ + posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside; + if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)) + bClearViewOutside = false; + } + if(bClearViewOutside) + garageDoorPos1 = posOutside; } - if(bClearViewOutside) - garageDoorPos1 = posOutside; } } @@ -1163,7 +1171,7 @@ CCamera::CamControl(void) garageCenter.z = 0.0f; }else{ garageDoorPos1.z = 0.0f; - if(stairs == nil) // how can this be true? + if(!stairs) // how can this be true? garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f); } if(whichDoor == 1) @@ -1602,8 +1610,10 @@ CCamera::CamControl(void) switchByJumpCut = true; } } +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) ReqMode = CCam::MODE_EDITOR; +#endif if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){ if(switchByJumpCut){ @@ -2343,7 +2353,7 @@ CCamera::StartTransition(int16 newMode) while(deltaBeta < -PI) deltaBeta += 2*PI; deltaBeta = Abs(deltaBeta); - door = FindPlayerPed()->m_vehEnterType; + door = FindPlayerPed()->m_vehDoor; if(deltaBeta > HALFPI){ if(((CPed*)pTargetEntity)->m_carInObjective){ if(((CPed*)pTargetEntity)->m_carInObjective->IsUpsideDown()){ @@ -2944,7 +2954,7 @@ CCamera::TryToStartNewCamMode(int obbeMode) if (CReplay::IsPlayingBack()) return false; #endif - if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) + if(FindPlayerPed()->m_pWanted->GetWantedLevel() < 1) return false; if(FindPlayerVehicle() == nil) return false; @@ -2972,7 +2982,7 @@ CCamera::TryToStartNewCamMode(int obbeMode) if (CReplay::IsPlayingBack()) return false; #endif - if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) + if(FindPlayerPed()->m_pWanted->GetWantedLevel() < 1) return false; if(FindPlayerVehicle() == nil) return false; @@ -3389,12 +3399,12 @@ CCamera::LoadTrainCamNodes(char const *name) char token[16] = { 0 }; char filename[16] = { 0 }; uint8 *buf; - size_t bufpos = 0; + ssize_t bufpos = 0; int field = 0; int tokpos = 0; char c; int i; - size_t len; + ssize_t len; strcpy(filename, name); len = (int)strlen(filename); @@ -3621,6 +3631,8 @@ CCamera::LoadPathSplines(int file) m_arrPathArray[i].m_arr_PathData[j] = atof(token); i++; j = 0; + if (i == MAX_NUM_OF_SPLINETYPES) + reading = false; memset(token, 0, 32); n = 0; } @@ -4043,9 +4055,17 @@ CCamera::CalculateDerivedValues(void) bool CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat) { - RwV3d c; - c = center; - RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix); +#ifdef GTA_PS2 + CVuVector c; + TransformPoint(c, *mat, center); +#else + CVector c = center; + #ifdef FIX_BUGS + c = *mat * center; + #else + RwV3dTransformPoints(&c, &c, 1, (RwMatrix*)mat); + #endif +#endif if(c.y < CDraw::GetNearClipZ()) return false; if(c.y > CDraw::GetFarClipZ()) return false; if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > 0.0f) return false; @@ -4058,9 +4078,17 @@ CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat) bool CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat) { - RwV3d c; - c = center; - RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix); +#ifdef GTA_PS2 + CVuVector c; + TransformPoint(c, *mat, center); +#else + CVector c = center; + #ifdef FIX_BUGS + c = *mat * center; + #else + RwV3dTransformPoints(&c, &c, 1, (RwMatrix*)mat); + #endif +#endif if(c.y + radius < CDraw::GetNearClipZ()) return false; if(c.y - radius > CDraw::GetFarClipZ()) return false; if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > radius) return false; @@ -4078,11 +4106,24 @@ CCamera::IsSphereVisible(const CVector ¢er, float radius) } bool -CCamera::IsBoxVisible(RwV3d *box, const CMatrix *mat) +#ifdef GTA_PS2 +CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat) +#else +CCamera::IsBoxVisible(CVector *box, const CMatrix *mat) +#endif { int i; int frustumTests[6] = { 0 }; - RwV3dTransformPoints(box, box, 8, &mat->m_matrix); +#ifdef GTA_PS2 + TransformPoints(box, 8, *mat, box); +#else + #ifdef FIX_BUGS + for (i = 0; i < 8; i++) + box[i] = *mat * box[i]; + #else + RwV3dTransformPoints(box, box, 8, (RwMatrix*)mat); + #endif +#endif for(i = 0; i < 8; i++){ if(box[i].y < CDraw::GetNearClipZ()) frustumTests[0]++; diff --git a/src/core/Camera.h b/src/core/Camera.h index ff74931c..538ff067 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -209,7 +209,9 @@ public: void PrintMode(void); void Process_Debug(const CVector&, float, float, float); +#ifdef GTA_SCENE_EDIT void Process_Editor(const CVector&, float, float, float); +#endif void Process_ModelView(const CVector &CameraTarget, float, float, float); void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float); @@ -631,7 +633,11 @@ public: bool IsPointVisible(const CVector ¢er, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, float radius); - bool IsBoxVisible(RwV3d *box, const CMatrix *mat); +#ifdef GTA_PS2 + bool IsBoxVisible(CVuVector *box, const CMatrix *mat); +#else + bool IsBoxVisible(CVector *box, const CMatrix *mat); +#endif }; VALIDATE_SIZE(CCamera, 0xE9D8); diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp index c11fb72a..4bb31ea4 100644 --- a/src/core/CdStream.cpp +++ b/src/core/CdStream.cpp @@ -5,6 +5,7 @@ #include "CdStream.h" #include "rwcore.h" #include "RwHelper.h" +#include "MemoryMgr.h" #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) @@ -72,7 +73,11 @@ CdStreamInitThread(void) gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); +#ifdef FIX_BUGS + gCdStreamSema = CreateSemaphore(nil, 0, 5, nil); +#else gCdStreamSema = CreateSemaphore(nil, 0, 5, "CdStream"); +#endif if ( gCdStreamSema == nil ) { @@ -242,8 +247,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) else return STREAM_SUCCESS; } - + +#ifdef BIG_IMG + LARGE_INTEGER liDistanceToMove; + liDistanceToMove.QuadPart = _GET_OFFSET(offset); + liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE; + SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN); +#else SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN); +#endif DWORD NumberOfBytesRead; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 5c8d1b16..0854d850 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -16,7 +16,7 @@ #include "CdStream.h" #include "rwcore.h" -#include "RwHelper.h" +#include "MemoryMgr.h" #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) @@ -429,7 +429,7 @@ void *CdStreamThread(void *param) ASSERT(pChannel->hFile >= 0); ASSERT(pChannel->pBuffer != nil ); - lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET); + lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET); if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { // pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel // STREAM_WAITING is a little hack to make CStreaming not process this data diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp index 6c54ac63..a3298343 100644 --- a/src/core/Clock.cpp +++ b/src/core/Clock.cpp @@ -4,8 +4,7 @@ #include "Pad.h" #include "Clock.h" #include "Stats.h" - -// --MIAMI: File done +#include "VarConsole.h" _TODO("gbFastTime"); bool gbFastTime; @@ -20,6 +19,10 @@ uint32 CClock::ms_nMillisecondsPerGameMinute; uint32 CClock::ms_nLastClockTick; bool CClock::ms_bClockHasBeenStored; +#ifndef MASTER +bool gbFreezeTime; +#endif + void CClock::Initialise(uint32 scale) { @@ -31,6 +34,10 @@ CClock::Initialise(uint32 scale) ms_nLastClockTick = CTimer::GetTimeInMilliseconds(); ms_bClockHasBeenStored = false; debug("CClock ready\n"); +#ifndef MASTER + VarConsole.Add("Time (hour of day)", &ms_nGameClockHours, 1, 0, 23, true); + VarConsole.Add("Freeze time", &gbFreezeTime, true); +#endif } void @@ -50,6 +57,10 @@ CClock::Update(void) } } +#ifndef MASTER + else if (gbFreezeTime) + ms_nLastClockTick = CTimer::GetTimeInMilliseconds(); +#endif else if(CTimer::GetTimeInMilliseconds() - ms_nLastClockTick > ms_nMillisecondsPerGameMinute || gbFastTime) { ms_nGameClockMinutes++; diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 51e942d0..fcc4503a 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -1,11 +1,7 @@ -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif - +#define WITHDINPUT #include "common.h" #include "platform.h" -#include "crossplatform.h" // for Windows version +#include "crossplatform.h" #include "ControllerConfig.h" #include "Pad.h" #include "FileMgr.h" @@ -21,8 +17,6 @@ #include "Camera.h" #include "GenericGameStorage.h" -// --MIAMI: file done - CControllerConfigManager ControlsManager; CControllerConfigManager::CControllerConfigManager() @@ -37,6 +31,9 @@ CControllerConfigManager::CControllerConfigManager() void CControllerConfigManager::MakeControllerActionsBlank() { +#ifdef LOAD_INI_SETTINGS + ms_padButtonsInited = 0; +#endif for (int32 i = 0; i < MAX_CONTROLLERTYPES; i++) { for (int32 j = 0; j < MAX_CONTROLLERACTIONS; j++) @@ -323,6 +320,10 @@ void CControllerConfigManager::InitDefaultControlConfigMouse(CMouseControllerSta } } +#ifdef LOAD_INI_SETTINGS +uint32 CControllerConfigManager::ms_padButtonsInited = 0; +#endif + void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) { m_bFirstCapture = true; @@ -331,6 +332,22 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) if (buttons > 16) btn = 16; +#ifdef LOAD_INI_SETTINGS + uint32 buttonMin = ms_padButtonsInited; + if (buttonMin >= btn) + return; + + ms_padButtonsInited = btn; + + #define IF_BTN_IN_RANGE(n) \ + case n: \ + if (n <= buttonMin) \ + return; +#else + #define IF_BTN_IN_RANGE(n) \ + case n: +#endif + // Now we use SDL Game Controller DB #if defined RW_D3D9 || defined RWLIBS if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427 @@ -343,50 +360,50 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) switch (btn) { - case 16: + IF_BTN_IN_RANGE(16) SetControllerKeyAssociatedWithAction(GO_LEFT, 16, JOYSTICK); - case 15: + IF_BTN_IN_RANGE(15) SetControllerKeyAssociatedWithAction(GO_BACK, 15, JOYSTICK); - case 14: + IF_BTN_IN_RANGE(14) SetControllerKeyAssociatedWithAction(GO_RIGHT, 14, JOYSTICK); - case 13: + IF_BTN_IN_RANGE(13) SetControllerKeyAssociatedWithAction(GO_FORWARD, 13, JOYSTICK); - case 12: - case 11: + IF_BTN_IN_RANGE(12) + IF_BTN_IN_RANGE(11) SetControllerKeyAssociatedWithAction(PED_LOOKBEHIND, 11, JOYSTICK); SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); - case 10: + IF_BTN_IN_RANGE(10) SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); - case 9: + IF_BTN_IN_RANGE(9) SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); - case 8: + IF_BTN_IN_RANGE(8) SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); - case 7: + IF_BTN_IN_RANGE(7) SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); - case 6: + IF_BTN_IN_RANGE(6) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKRIGHT, 6, JOYSTICK); - case 5: + IF_BTN_IN_RANGE(5) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, 5, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKLEFT, 5, JOYSTICK); /*******************************************************************************************/ - case 4: + IF_BTN_IN_RANGE(4) SetControllerKeyAssociatedWithAction(VEHICLE_BRAKE, 4, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_JUMPING, 4, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_IN, 4, JOYSTICK); - case 3: + IF_BTN_IN_RANGE(3) SetControllerKeyAssociatedWithAction(VEHICLE_ACCELERATE, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SPRINT, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 3, JOYSTICK); - case 2: + IF_BTN_IN_RANGE(2) SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 2, JOYSTICK); #ifdef BIND_VEHICLE_FIREWEAPON SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 2, JOYSTICK); #endif - case 1: + IF_BTN_IN_RANGE(1) SetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, 1, JOYSTICK); /*******************************************************************************************/ } @@ -395,47 +412,47 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) { switch (btn) { - case 16: + IF_BTN_IN_RANGE(16) SetControllerKeyAssociatedWithAction(GO_LEFT, 16, JOYSTICK); - case 15: + IF_BTN_IN_RANGE(15) SetControllerKeyAssociatedWithAction(GO_BACK, 15, JOYSTICK); - case 14: + IF_BTN_IN_RANGE(14) SetControllerKeyAssociatedWithAction(GO_RIGHT, 14, JOYSTICK); - case 13: + IF_BTN_IN_RANGE(13) SetControllerKeyAssociatedWithAction(GO_FORWARD, 13, JOYSTICK); - case 12: - case 11: + IF_BTN_IN_RANGE(12) + IF_BTN_IN_RANGE(11) SetControllerKeyAssociatedWithAction(PED_LOOKBEHIND, 11, JOYSTICK); SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); - case 10: + IF_BTN_IN_RANGE(10) SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); - case 9: + IF_BTN_IN_RANGE(9) SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); - case 8: + IF_BTN_IN_RANGE(8) SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); - case 7: + IF_BTN_IN_RANGE(7) SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); - case 6: + IF_BTN_IN_RANGE(6) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKRIGHT, 6, JOYSTICK); - case 5: + IF_BTN_IN_RANGE(5) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, 5, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKLEFT, 5, JOYSTICK); /*******************************************************************************************/ - case 4: + IF_BTN_IN_RANGE(4) SetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, 4, JOYSTICK); - case 3: + IF_BTN_IN_RANGE(3) SetControllerKeyAssociatedWithAction(VEHICLE_BRAKE, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_JUMPING, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_IN, 3, JOYSTICK); - case 2: + IF_BTN_IN_RANGE(2) SetControllerKeyAssociatedWithAction(VEHICLE_ACCELERATE, 2, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SPRINT, 2, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 2, JOYSTICK); - case 1: + IF_BTN_IN_RANGE(1) SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 1, JOYSTICK); #ifdef BIND_VEHICLE_FIREWEAPON SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 1, JOYSTICK); @@ -2348,8 +2365,280 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act return num; } +#ifdef BIND_VEHICLE_FIREWEAPON +#define VFB(b) b, +#else +#define VFB(b) +#endif + +#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT, RSL, RSR) \ + {{ \ + O, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + L1, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L3, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + R1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + O, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + SELECT, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L1, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + R1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + X, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ + T, /* PED_SNIPER_ZOOM_IN */ \ + Q, /* PED_SNIPER_ZOOM_OUT */ \ + L1, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + O, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + L3, /* VEHICLE_CHANGE_RADIO_STATION */ \ + R1, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + T, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + R1, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ + VFB(R1) /* VEHICLE_FIREWEAPON */ \ + nil, /* VEHICLE_ACCELERATE */ \ + nil, /* VEHICLE_BRAKE */ \ + O, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L3, /* VEHICLE_HORN */ \ + Q, /* TOGGLE_SUBMISSIONS */ \ + L1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + L1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }} + +#ifdef BUTTON_ICONS +#define UP "~U~" +#define DOWN "~D~" +#define LEFT "~<~" +#define RIGHT "~>~" +#else +#define UP "UP" +#define DOWN "DOWN" +#define LEFT "LEFT" +#define RIGHT "RIGHT" +#endif + +const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK", "right stick left", "right stick right"); + +#ifdef BUTTON_ICONS +const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK", "~(~", "~)~"); +#endif + + +#if 0 // set 1 for ps2 fonts +#define PS2_TRIANGLE "\"" +#define PS2_CIRCLE "|" +#define PS2_CROSS "/" +#define PS2_SQUARE "^" +#elif defined(BUTTON_ICONS) +#define PS2_TRIANGLE "~T~" +#define PS2_CIRCLE "~O~" +#define PS2_CROSS "~X~" +#define PS2_SQUARE "~Q~" +#else +#define PS2_TRIANGLE "TRIANGLE" +#define PS2_CIRCLE "CIRCLE" +#define PS2_CROSS "CROSS" +#define PS2_SQUARE "SQUARE" +#endif + +const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] = + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT", "right stick left", "right stick right"); + +#ifdef BUTTON_ICONS +const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT", "~(~", "~)~"); +#endif + +#undef PS2_TRIANGLE +#undef PS2_CIRCLE +#undef PS2_CROSS +#undef PS2_SQUARE + +#undef UP +#undef DOWN +#undef LEFT +#undef RIGHT + +#undef CONTROLLER_BUTTONS +#undef VFB + void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight) { +#ifdef DETECT_PAD_INPUT_SWITCH + if (CPad::GetPad(0)->IsAffectedByController) { + wchar wstr[16]; + + // TODO: INI and/or menu setting for Xbox/PS switch +#ifdef BUTTON_ICONS + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; +#else + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons; +#endif + + assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these + AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr); + + CMessages::WideStringCopy(text, wstr, leight); + return; + } +#endif + int32 nums = GetNumOfSettingsForAction((e_ControllerAction)action); int32 sets = 0; @@ -2502,7 +2791,7 @@ void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action) for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++) { int32 setorder = m_aSettings[action][k].m_ContSetOrder; - if (setorder > i && setorder != KEYBOARD) + if (setorder > i && setorder != 0) { if (init) { diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index eb66937a..604fb5cc 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -144,6 +144,10 @@ public: tControllerConfigBind m_aSettings[MAX_CONTROLLERACTIONS][MAX_CONTROLLERTYPES]; bool m_aSimCheckers[MAX_SIMS][MAX_CONTROLLERTYPES]; bool m_bMouseAssociated; + +#ifdef LOAD_INI_SETTINGS + static uint32 ms_padButtonsInited; +#endif CControllerConfigManager(); diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index b22ddcb2..b7f139b4 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -10,8 +10,6 @@ #include "main.h" #include "Accident.h" -// --MIAMI: file done - int32 CEventList::ms_nFirstFreeSlotIndex; CEvent gaEvent[NUMEVENTS]; @@ -59,7 +57,6 @@ CEventList::Update(void) } } -// ok void CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout) { @@ -121,7 +118,7 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent } if(criminal == FindPlayerPed()) - ReportCrimeForEvent(type, (uintptr)ent, copsDontCare); + ReportCrimeForEvent(type, (intptr)ent, copsDontCare); } void @@ -199,7 +196,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event) } void -CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare) +CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare) { eCrimeType crime; switch(type){ @@ -221,7 +218,7 @@ CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCa default: crime = CRIME_NONE; break; } - if (crime == CRIME_HIT_PED && IsPedPointerValid((CPed*)crimeId) && FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 && ((CPed*)crimeId)->bBeingChasedByPolice) { + if (crime == CRIME_HIT_PED && IsPedPointerValid((CPed*)crimeId) && FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 && ((CPed*)crimeId)->bBeingChasedByPolice) { if (!((CPed*)crimeId)->DyingOrDead()) { CMessages::AddBigMessage(TheText.Get("GOODBOY"), 5000, 0); CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 50; diff --git a/src/core/EventList.h b/src/core/EventList.h index dcca1270..3e9d8fd4 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -62,7 +62,7 @@ public: static bool GetEvent(eEventType type, int32 *event); static void ClearEvent(int32 event); static bool FindClosestEvent(eEventType type, CVector posn, int32 *event); - static void ReportCrimeForEvent(eEventType type, size_t, bool); + static void ReportCrimeForEvent(eEventType type, intptr, bool); }; extern CEvent gaEvent[NUMEVENTS];
\ No newline at end of file diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 7dd662e2..4d1cd921 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -2,6 +2,7 @@ #include <ctype.h> #include "main.h" +#include "General.h" #include "Quaternion.h" #include "ModelInfo.h" #include "ModelIndices.h" @@ -24,12 +25,11 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#include "MemoryHeap.h" #include "Streaming.h" #include "ColStore.h" #include "Occlusion.h" -//--MIAMI: file done - char CFileLoader::ms_line[256]; const char* @@ -68,17 +68,19 @@ CFileLoader::LoadLevel(const char *filename) if(*line == '#') continue; - if(strncmp(line, "EXIT", 9) == 0) // BUG: 9? + if(strncmp(line, "EXIT", 4) == 0) break; if(strncmp(line, "IMAGEPATH", 9) == 0){ RwImageSetPath(line + 10); }else if(strncmp(line, "TEXDICTION", 10) == 0){ + PUSH_MEMID(MEMID_TEXTURES); strcpy(txdname, line+11); LoadingScreenLoadingFile(txdname); RwTexDictionary *txd = LoadTexDictionary(txdname); AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); + POP_MEMID(); }else if(strncmp(line, "COLFILE", 7) == 0){ LoadingScreenLoadingFile(line+10); LoadCollisionFile(line+10, 0); @@ -94,22 +96,30 @@ CFileLoader::LoadLevel(const char *filename) }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ LoadingScreenLoadingFile("Collision"); + PUSH_MEMID(MEMID_WORLD); CObjectData::Initialise("DATA\\OBJECT.DAT"); CStreaming::Init(); + POP_MEMID(); + PUSH_MEMID(MEMID_COLLISION); CColStore::LoadAllCollision(); + POP_MEMID(); for(int i = 0; i < MODELINFOSIZE; i++) if(CModelInfo::GetModelInfo(i)) CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex(); objectsLoaded = true; } + PUSH_MEMID(MEMID_WORLD); LoadingScreenLoadingFile(line + 4); LoadScene(line + 4); + POP_MEMID(); }else if(strncmp(line, "SPLASH", 6) == 0){ #ifndef DISABLE_LOADING_SCREEN LoadSplash(GetRandomSplashScreen()); #endif +#ifndef GTA_PS2 }else if(strncmp(line, "CDIMAGE", 7) == 0){ CdStreamAddImage(line + 8); +#endif } } @@ -160,7 +170,7 @@ CFileLoader::LoadTexDictionary(const char *filename) struct ColHeader { - char ident[4]; + uint32 ident; uint32 size; }; @@ -172,12 +182,14 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) CBaseModelInfo *mi; ColHeader header; + PUSH_MEMID(MEMID_COLLISION); + debug("Loading collision file %s\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); assert(fd > 0); while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){ - assert(strncmp(header.ident, "COLL", 4) == 0); + assert(header.ident == 'LLOC'); CFileMgr::Read(fd, (char*)work_buff, header.size); memcpy(modelname, work_buff, 24); @@ -197,6 +209,8 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) } CFileMgr::CloseFile(fd); + + POP_MEMID(); } @@ -212,7 +226,7 @@ CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlo while(size > 8){ header = (ColHeader*)buffer; modelsize = header->size; - if(strncmp(header->ident, "COLL", 4) != 0) + if(header->ident != 'LLOC') return size-8 < CDSTREAM_SECTOR_SIZE; memcpy(modelname, buffer+8, 24); memcpy(work_buff, buffer+32, modelsize-24); @@ -246,7 +260,7 @@ CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot) while(size > 8){ header = (ColHeader*)buffer; modelsize = header->size; - if(strncmp(header->ident, "COLL", 4) != 0) + if(header->ident != 'LLOC') return size-8 < CDSTREAM_SECTOR_SIZE; memcpy(modelname, buffer+8, 24); memcpy(work_buff, buffer+32, modelsize-24); @@ -291,6 +305,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 44; if(model.numSpheres > 0){ model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere)); + REGISTER_MEMPTR(&model.spheres); for(i = 0; i < model.numSpheres; i++){ model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]); buf += 20; @@ -315,6 +330,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numBoxes > 0){ model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox)); + REGISTER_MEMPTR(&model.boxes); for(i = 0; i < model.numBoxes; i++){ model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]); buf += 28; @@ -326,6 +342,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(numVertices > 0){ model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector)); + REGISTER_MEMPTR(&model.vertices); for(i = 0; i < numVertices; i++){ model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8)); #if 0 @@ -343,6 +360,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numTriangles > 0){ model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle)); + REGISTER_MEMPTR(&model.triangles); for(i = 0; i < model.numTriangles; i++){ model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]); buf += 16; @@ -472,7 +490,7 @@ bool CFileLoader::StartLoadClumpFile(RwStream *stream, uint32 id) { if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){ - printf("Start loading %s\n", CModelInfo::GetModelInfo(id)->GetName()); + printf("Start loading %s\n", CModelInfo::GetModelInfo(id)->GetModelName()); return RpClumpGtaStreamRead1(stream); }else{ printf("FAILED\n"); @@ -486,7 +504,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id) RpClump *clump; CClumpModelInfo *mi; - printf("Finish loading %s\n", CModelInfo::GetModelInfo(id)->GetName()); + printf("Finish loading %s\n", CModelInfo::GetModelInfo(id)->GetModelName()); clump = RpClumpGtaStreamRead2(stream); if(clump){ @@ -566,6 +584,9 @@ CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src) RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst); } +#define isLine3(l, a, b, c) ((l[0] == a) && (l[1] == b) && (l[2] == c)) +#define isLine4(l, a, b, c, d) ((l[0] == a) && (l[1] == b) && (l[2] == c) && (l[3] == d)) + void CFileLoader::LoadObjectTypes(const char *filename) { @@ -601,15 +622,15 @@ CFileLoader::LoadObjectTypes(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "objs", 4) == 0) section = OBJS; - else if(strncmp(line, "tobj", 4) == 0) section = TOBJ; - else if(strncmp(line, "weap", 4) == 0) section = WEAP; - else if(strncmp(line, "hier", 4) == 0) section = HIER; - else if(strncmp(line, "cars", 4) == 0) section = CARS; - else if(strncmp(line, "peds", 4) == 0) section = PEDS; - else if(strncmp(line, "path", 4) == 0) section = PATH; - else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX; - }else if(strncmp(line, "end", 3) == 0){ + if(isLine4(line, 'o','b','j','s')) section = OBJS; + else if(isLine4(line, 't','o','b','j')) section = TOBJ; + else if(isLine4(line, 'w','e','a','p')) section = WEAP; + else if(isLine4(line, 'h','i','e','r')) section = HIER; + else if(isLine4(line, 'c','a','r','s')) section = CARS; + else if(isLine4(line, 'p','e','d','s')) section = PEDS; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + else if(isLine4(line, '2','d','f','x')) section = TWODFX; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case OBJS: @@ -716,7 +737,7 @@ CFileLoader::LoadObject(const char *line) } mi = CModelInfo::AddSimpleModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetNumAtomics(numObjs); mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); @@ -764,7 +785,7 @@ CFileLoader::LoadTimeObject(const char *line) } mi = CModelInfo::AddTimeModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetNumAtomics(numObjs); mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); @@ -790,7 +811,7 @@ CFileLoader::LoadWeaponObject(const char *line) sscanf(line, "%d %s %s %s %d %f", &id, model, txd, animFile, &numObjs, &dist); mi = CModelInfo::AddWeaponModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetNumAtomics(1); mi->m_lodDistances[0] = dist; mi->SetTexDictionary(txd); @@ -809,7 +830,7 @@ CFileLoader::LoadClumpObject(const char *line) if(sscanf(line, "%d %s %s", &id, model, txd) == 3){ mi = CModelInfo::AddClumpModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); mi->SetColModel(&CTempColModels::ms_colModelBBox); } @@ -833,7 +854,7 @@ CFileLoader::LoadVehicleObject(const char *line) &frequency, &level, &comprules, &misc, &wheelScale); mi = CModelInfo::AddVehicleModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); mi->SetAnimFile(animFile); for(p = gamename; *p; p++) @@ -842,21 +863,21 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_level = level; mi->m_compRules = comprules; - if(strncmp(type, "car", 4) == 0){ + if(strcmp(type, "car") == 0){ mi->m_wheelId = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_CAR; - }else if(strncmp(type, "boat", 5) == 0){ + }else if(strcmp(type, "boat") == 0){ mi->m_vehicleType = VEHICLE_TYPE_BOAT; - }else if(strncmp(type, "train", 6) == 0){ + }else if(strcmp(type, "train") == 0){ mi->m_vehicleType = VEHICLE_TYPE_TRAIN; - }else if(strncmp(type, "heli", 5) == 0){ + }else if(strcmp(type, "heli") == 0){ mi->m_vehicleType = VEHICLE_TYPE_HELI; - }else if(strncmp(type, "plane", 6) == 0){ + }else if(strcmp(type, "plane") == 0){ mi->m_planeLodId = misc; mi->m_wheelScale = 1.0f; mi->m_vehicleType = VEHICLE_TYPE_PLANE; - }else if(strncmp(type, "bike", 5) == 0){ + }else if(strcmp(type, "bike") == 0){ mi->m_bikeSteerAngle = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_BIKE; @@ -865,29 +886,29 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId); - if(strncmp(vehclass, "normal", 7) == 0) + if(strcmp(vehclass, "normal") == 0) mi->m_vehicleClass = CCarCtrl::NORMAL; - else if(strncmp(vehclass, "poorfamily", 11) == 0) + else if(strcmp(vehclass, "poorfamily") == 0) mi->m_vehicleClass = CCarCtrl::POOR; - else if(strncmp(vehclass, "richfamily", 11) == 0) + else if(strcmp(vehclass, "richfamily") == 0) mi->m_vehicleClass = CCarCtrl::RICH; - else if(strncmp(vehclass, "executive", 10) == 0) + else if(strcmp(vehclass, "executive") == 0) mi->m_vehicleClass = CCarCtrl::EXEC; - else if(strncmp(vehclass, "worker", 7) == 0) + else if(strcmp(vehclass, "worker") == 0) mi->m_vehicleClass = CCarCtrl::WORKER; - else if(strncmp(vehclass, "big", 4) == 0) + else if(strcmp(vehclass, "big") == 0) mi->m_vehicleClass = CCarCtrl::BIG; - else if(strncmp(vehclass, "taxi", 5) == 0) + else if(strcmp(vehclass, "taxi") == 0) mi->m_vehicleClass = CCarCtrl::TAXI; - else if(strncmp(vehclass, "moped", 6) == 0) + else if(strcmp(vehclass, "moped") == 0) mi->m_vehicleClass = CCarCtrl::MOPED; - else if(strncmp(vehclass, "motorbike", 10) == 0) + else if(strcmp(vehclass, "motorbike") == 0) mi->m_vehicleClass = CCarCtrl::MOTORBIKE; - else if(strncmp(vehclass, "leisureboat", 12) == 0) + else if(strcmp(vehclass, "leisureboat") == 0) mi->m_vehicleClass = CCarCtrl::LEISUREBOAT; - else if(strncmp(vehclass, "workerboat", 11) == 0) + else if(strcmp(vehclass, "workerboat") == 0) mi->m_vehicleClass = CCarCtrl::WORKERBOAT; - else if(strncmp(vehclass, "ignore", 11) == 0){ + else if(strcmp(vehclass, "ignore") == 0) { mi->m_vehicleClass = -1; return; } @@ -912,7 +933,7 @@ CFileLoader::LoadPedObject(const char *line) animFile, &radio1, &radio2); mi = CModelInfo::AddPedModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); mi->SetAnimFile(animFile); mi->SetColModel(&CTempColModels::ms_colModelPed1); @@ -994,7 +1015,7 @@ CFileLoader::Load2dEffect(const char *line) CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); mi = CModelInfo::GetModelInfo(id); - effect = CModelInfo::Get2dEffectStore().alloc(); + effect = CModelInfo::Get2dEffectStore().Alloc(); mi->Add2dEffect(effect); effect->pos = CVector(x, y, z); effect->col = CRGBA(r, g, b, a); @@ -1102,13 +1123,13 @@ CFileLoader::LoadScene(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "inst", 4) == 0) section = INST; - else if(strncmp(line, "zone", 4) == 0) section = ZONE; - else if(strncmp(line, "cull", 4) == 0) section = CULL; - else if(strncmp(line, "pick", 4) == 0) section = PICK; - else if(strncmp(line, "path", 4) == 0) section = PATH; - else if(strncmp(line, "occl", 4) == 0) section = OCCL; - }else if(strncmp(line, "end", 3) == 0){ + if(isLine4(line, 'i','n','s','t')) section = INST; + else if(isLine4(line, 'z','o','n','e')) section = ZONE; + else if(isLine4(line, 'c','u','l','l')) section = CULL; + else if(isLine4(line, 'p','i','c','k')) section = PICK; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + else if(isLine4(line, 'o','c','c','l')) section = OCCL; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case INST: @@ -1182,7 +1203,7 @@ CFileLoader::LoadObjectInstance(const char *line) assert(mi->IsSimple()); if(!CStreaming::IsObjectInCdImage(id)) - debug("Not in cdimage %s\n", mi->GetName()); + debug("Not in cdimage %s\n", mi->GetModelName()); angle = -RADTODEG(2.0f * acosf(angle)); xform = RwMatrixCreate(); @@ -1286,7 +1307,7 @@ CFileLoader::LoadOcclusionVolume(const char *line) } -//--MIAMI: unused +// unused void CFileLoader::ReloadPaths(const char *filename) { @@ -1306,11 +1327,11 @@ CFileLoader::ReloadPaths(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "path", 4) == 0) { + if (isLine4(line, 'p','a','t','h')) { section = PATH; ThePaths.AllocatePathFindInfoMem(4500); } - } else if (strncmp(line, "end", 3) == 0) { + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { @@ -1361,10 +1382,10 @@ CFileLoader::ReloadObjectTypes(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "objs", 4) == 0) section = OBJS; - else if (strncmp(line, "tobj", 4) == 0) section = TOBJ; - else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX; - } else if (strncmp(line, "end", 3) == 0) { + if (isLine4(line, 'o','b','j','s')) section = OBJS; + else if (isLine4(line, 't','o','b','j')) section = TOBJ; + else if (isLine4(line, '2','d','f','x')) section = TWODFX; + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { @@ -1415,7 +1436,7 @@ CFileLoader::ReloadObject(const char *line) #ifdef FIX_BUGS mi && #endif - mi->GetModelType() == MITYPE_SIMPLE && !strcmp(mi->GetName(), model) && mi->m_numAtomics == numObjs) { + mi->GetModelType() == MITYPE_SIMPLE && !strcmp(mi->GetModelName(), model) && mi->m_numAtomics == numObjs) { mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); } else { @@ -1437,7 +1458,7 @@ CFileLoader::ReLoadScene(const char *filename) if (*line == '#') continue; - if (strncmp(line, "EXIT", 9) == 0) // BUG: 9? + if (strncmp(line, "EXIT", 4) == 0) break; if (strncmp(line, "IDE", 3) == 0) { diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index d3695cb4..32aa4041 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -240,21 +240,24 @@ CFileMgr::SetDirMyDocuments(void) mychdir(_psGetUserFilesFolder()); } -size_t -CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode) +ssize_t +CFileMgr::LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode) { int fd; - size_t n, len; + ssize_t n, len; fd = myfopen(file, mode); if(fd == 0) - return 0; + return -1; len = 0; do{ n = myfread(buf + len, 1, 0x4000, fd); - if(n < 0) +#ifndef FIX_BUGS + if (n < 0) return -1; +#endif len += n; + assert(len < maxlen); }while(n == 0x4000); buf[len] = 0; myfclose(fd); @@ -274,13 +277,13 @@ CFileMgr::OpenFileForWriting(const char *file) } size_t -CFileMgr::Read(int fd, const char *buf, size_t len) +CFileMgr::Read(int fd, const char *buf, ssize_t len) { return myfread((void*)buf, 1, len, fd); } size_t -CFileMgr::Write(int fd, const char *buf, size_t len) +CFileMgr::Write(int fd, const char *buf, ssize_t len) { return myfwrite((void*)buf, 1, len, fd); } diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h index 8278953b..f70451b7 100644 --- a/src/core/FileMgr.h +++ b/src/core/FileMgr.h @@ -9,12 +9,12 @@ public: static void ChangeDir(const char *dir); static void SetDir(const char *dir); static void SetDirMyDocuments(void); - static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode); + static ssize_t LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode); static int OpenFile(const char *file, const char *mode); static int OpenFile(const char *file) { return OpenFile(file, "rb"); } static int OpenFileForWriting(const char *file); - static size_t Read(int fd, const char *buf, size_t len); - static size_t Write(int fd, const char *buf, size_t len); + static size_t Read(int fd, const char *buf, ssize_t len); + static size_t Write(int fd, const char *buf, ssize_t len); static bool Seek(int fd, int offset, int whence); static bool ReadLine(int fd, char *buf, int len); static int CloseFile(int fd); diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index a47ca3cf..8a6db0da 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -18,8 +18,6 @@ #include "GameLogic.h" #include "CarAI.h" -// --MIAMI: file done - CFireManager gFireManager; CFire::CFire() @@ -46,7 +44,7 @@ CFire::ProcessFire(void) float fDamagePlayer; float fDamagePeds; float fDamageVehicle; - int8 nRandNumber; + int16 nRandNumber; float fGreen; float fRed; CVector lightpos; @@ -107,7 +105,11 @@ CFire::ProcessFire(void) } } } - if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) + if (!FindPlayerVehicle() && +#ifdef FIX_BUGS + FindPlayerPed() && +#endif + !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) && ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) { FindPlayerPed()->DoStuffToGoOnFire(); gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1); @@ -148,11 +150,10 @@ CFire::ProcessFire(void) CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, 7.0f, 0.0f, 0.0f, -7.0f, 0, nRandNumber / 2, nRandNumber / 2, 0, 10.0f, 1.0f, 40.0f, 0, 0.0f); } - fGreen = nRandNumber / 128; - fRed = nRandNumber / 128; + fGreen = nRandNumber / 128.f; + fRed = nRandNumber / 128.f; - CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f), - 12.0f, fRed, fGreen, 0, 0, 0); + CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0.0f, 0, 0); } else { Extinguish(); } @@ -391,19 +392,16 @@ CFireManager::ExtinguishPoint(CVector point, float range) bool CFireManager::ExtinguishPointWithWater(CVector point, float range) { - int fireI = 0; - for (int i = 0; i < NUM_FIRES; i++) { - if (m_aFires[i].m_bIsOngoing) { - if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) { - fireI = i; - break; - } - } - } - if (fireI == NUM_FIRES) - return false; - - CFire *fireToExtinguish = &m_aFires[fireI]; + int i; + for (i = 0; i < NUM_FIRES;) { + if (m_aFires[i].m_bIsOngoing && (point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) { + break; + } + if (++i >= NUM_FIRES) + return false; + } + + CFire *fireToExtinguish = &m_aFires[i]; fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep(); CVector steamPos = fireToExtinguish->m_vecPos + CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, diff --git a/src/core/FrontEndControls.cpp b/src/core/FrontEndControls.cpp index 68992e16..18f6b3b2 100644 --- a/src/core/FrontEndControls.cpp +++ b/src/core/FrontEndControls.cpp @@ -7,7 +7,7 @@ #include "FrontEndControls.h" #define X SCREEN_SCALE_X -#define Y(x) SCREEN_SCALE_Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(DEFAULT_SCREEN_HEIGHT_PAL))) +#define Y(x) SCREEN_SCALE_Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(SCREEN_HEIGHT_PAL))) void CPlaceableShText::Draw(float x, float y) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 2b458828..0a9db5a4 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -1,9 +1,6 @@ -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif - +#define FORCE_PC_SCALING #define WITHWINDOWS +#define WITHDINPUT #include "common.h" #ifndef PS2_MENU #include "crossplatform.h" @@ -39,29 +36,59 @@ #include "User.h" #include "sampman.h" -#define MAP_MIN_SIZE 162.f -#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f - // Similar story to Hud.cpp: // Game has colors inlined in code. // For easier modification we collect them here: -CRGBA LABEL_COLOR(255, 150, 225, 255); -CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); -CRGBA MENUOPTION_COLOR(255, 150, 225, 255); -CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255); -CRGBA HEADER_COLOR(255, 150, 255, 255); -CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); -CRGBA SLIDERON_COLOR(97, 194, 247, 255); -CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); -CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130); -CRGBA RADIO_SELECTOR_COLOR(27, 89, 130, 255); -CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); +const CRGBA LABEL_COLOR(255, 150, 225, 255); +const CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); +const CRGBA MENUOPTION_COLOR = LABEL_COLOR; +const CRGBA SELECTEDMENUOPTION_COLOR = LABEL_COLOR; +const CRGBA HEADER_COLOR = LABEL_COLOR; +const CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); +const CRGBA SLIDERON_COLOR(97, 194, 247, 255); +const CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); +const CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130); +const CRGBA LIST_OPTION_COLOR(155, 155, 155, 255); +const CRGBA RADIO_SELECTOR_COLOR = SLIDEROFF_COLOR; +const CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); +const CRGBA SCROLLBAR_COLOR = LABEL_COLOR; + +#define MAP_MIN_SIZE 162.f +#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result +#define SCROLLABLE_PAGES -#ifdef MAP_ENHANCEMENTS -CVector2D mapCrosshair; +#define hasNativeList(screen) (screen == MENUPAGE_SKIN_SELECT || screen == MENUPAGE_KEYBOARD_CONTROLS) + +#ifdef SCROLLABLE_PAGES +#define MAX_VISIBLE_OPTION 12 +#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) +#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) + +int GetOptionCount(int screen) +{ + int i = 0; + for (; i < NUM_MENUROWS && aScreens[screen].m_aEntries[i].m_Action != MENUACTION_NOTHING; i++); + return i; +} + +#define SETUP_SCROLLING(screen) \ + if (!hasNativeList(screen)) { \ + m_nTotalListRow = GetOptionCount(screen); \ + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { \ + m_nSelectedListRow = 0; \ + m_nFirstVisibleRowOnList = 0; \ + m_nScrollbarTopMargin = 0; \ + } \ + } + +#define MINUS_SCROLL_OFFSET - scrollOffset +#else +#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW +#define SETUP_SCROLLING(screen) +#define MINUS_SCROLL_OFFSET #endif #ifdef TRIANGLE_BACK_BUTTON @@ -75,6 +102,10 @@ CVector2D mapCrosshair; #define GetBackJustDown GetSquareJustDown #endif +#ifdef MAP_ENHANCEMENTS +CVector2D mapCrosshair; +#endif + #ifdef CUTSCENE_BORDERS_SWITCH bool CMenuManager::m_PrefsCutsceneBorders = true; #endif @@ -94,7 +125,6 @@ bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x68C144 const char* FrontendFilenames[][2] = { {"background", ""}, {"vc_logo", "vc_logom"}, @@ -151,6 +181,11 @@ wchar* CMenuManager::m_pDialogText = nil; CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetDropShadowPosition(0); +#define SET_FONT_FOR_LIST_ITEM \ + CFont::SetRightJustifyOff(); \ + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + #define RESET_FONT_FOR_NEW_PAGE \ CFont::SetBackgroundOff(); \ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ @@ -159,11 +194,12 @@ wchar* CMenuManager::m_pDialogText = nil; CFont::SetJustifyOn(); \ CFont::SetRightJustifyOff(); \ CFont::SetBackGroundOnlyTextOn(); \ - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); \ - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); -#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ +#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ do { \ + float y = origY MINUS_SCROLL_OFFSET; \ lastActiveBarX = DisplaySlider(MENU_X_LEFT_ALIGNED(MENUSLIDER_X), MENU_Y(y), MENU_Y(MENUSLIDER_SMALLEST_BAR), MENU_Y(MENUSLIDER_BIGGEST_BAR), MENU_X(MENUSLIDER_UNK), value, MENU_X(3.0f)); \ if (i != m_nCurrOption || !itemsAreSelectable) \ break; \ @@ -203,8 +239,8 @@ CMenuManager::ScrollUpListByOne() inline void CMenuManager::ScrollDownListByOne() { - if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { m_nSelectedListRow++; m_nFirstVisibleRowOnList++; m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow; @@ -219,13 +255,13 @@ CMenuManager::ScrollDownListByOne() inline void CMenuManager::PageUpList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { if (m_nFirstVisibleRowOnList > 0) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); - m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); + m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN); + m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1); } else { m_nFirstVisibleRowOnList = 0; m_nSelectedListRow = 0; @@ -237,21 +273,100 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) inline void CMenuManager::PageDownList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); + m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN); m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList); } else { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; m_nSelectedListRow = m_nTotalListRow - 1; } m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; } } +#ifdef CUSTOM_FRONTEND_OPTIONS +#define PLUS_LINE_HEIGHT_ON_SCREEN + (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->lineHeight : MENU_DEFAULT_LINE_HEIGHT) +bool ScreenHasOption(int screen, const char* gxtKey) +{ + for (int i = 0; i < NUM_MENUROWS; i++) { + if (strcmp(gxtKey, aScreens[screen].m_aEntries[i].m_EntryName) == 0) + return true; + } + return false; +} + +inline void +CMenuManager::ThingsToDoBeforeLeavingPage() +{ + if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { + CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); + + } else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); + + DMAudio.StopFrontEndTrack(); + OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); + + } else if (ScreenHasOption(m_nCurrScreen, "FED_RES")) { + m_nDisplayVideoMode = m_nPrefsVideoMode; + } + + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + CPlayerSkin::EndFrontendSkinEdit(); + } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif + + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + + if (option.m_Action == MENUACTION_CFO_DYNAMIC) + if(option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue) + option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue; + + if (aScreens[m_nCurrScreen].returnPrevPageFunc) { + aScreens[m_nCurrScreen].returnPrevPageFunc(); + } +} + +inline int8 +CMenuManager::GetPreviousPageOption() +{ + int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage : + (m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_OPTIONS || m_nCurrScreen == MENUPAGE_EXIT ? MENUPAGE_START_MENU : aScreens[m_nCurrScreen].m_PreviousPage); + + if (prevPage == -1) // Game also does same + return 0; + + prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; + + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[prevPage].m_aEntries[i].m_Action >= MENUACTION_NOTHING) { // CFO check + if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { + return i; + } + } + } + + // This shouldn't happen + return 0; +} + +#else +#define PLUS_LINE_HEIGHT_ON_SCREEN + MENU_DEFAULT_LINE_HEIGHT inline void CMenuManager::ThingsToDoBeforeLeavingPage() { @@ -265,9 +380,6 @@ CMenuManager::ThingsToDoBeforeLeavingPage() break; case MENUPAGE_DISPLAY_SETTINGS: m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef IMPROVED_VIDEOMODE - m_nSelectedScreenMode = m_nPrefsWindowed; -#endif break; case MENUPAGE_SKIN_SELECT: if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0) @@ -276,6 +388,14 @@ CMenuManager::ThingsToDoBeforeLeavingPage() CPlayerSkin::EndFrontendSkinEdit(); break; } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif } inline int8 @@ -284,13 +404,13 @@ CMenuManager::GetPreviousPageOption() return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry)))); } +#endif // ------ Functions not in the game/inlined ends bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); -// --MIAMI: Done void CMenuManager::SwitchToNewScreen(int8 screen) { @@ -320,8 +440,9 @@ CMenuManager::SwitchToNewScreen(int8 screen) m_nCurrOption = 0; m_nCurrScreen = screen; } - - if (m_nPrevScreen == MENUPAGE_SKIN_SELECT || m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS) + SETUP_SCROLLING(m_nCurrScreen) + + if (hasNativeList(m_nPrevScreen)) m_nTotalListRow = 0; if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) @@ -346,7 +467,11 @@ CMenuManager::CMenuManager() m_PrefsMP3BoostVolume = 0; m_PrefsShowSubtitles = 0; m_PrefsShowLegends = 1; +#ifdef ASPECT_RATIO_SCALE + m_PrefsUseWideScreen = AR_AUTO; +#else m_PrefsUseWideScreen = 0; +#endif m_PrefsVsync = 0; m_PrefsVsyncDisp = 1; m_PrefsFrameLimiter = 1; @@ -367,7 +492,11 @@ CMenuManager::CMenuManager() m_PrefsDMA = 1; OS_Language = LANG_ENGLISH; m_ControlMethod = CONTROL_STANDARD; +#ifdef PC_PLAYER_CONTROLS CCamera::m_bUseMouse3rdPerson = true; +#else + CCamera::m_bUseMouse3rdPerson = false; +#endif m_lastWorking3DAudioProvider = 0; m_nFirstVisibleRowOnList = 0; m_nScrollbarTopMargin = 0.0f; @@ -393,6 +522,10 @@ CMenuManager::CMenuManager() m_fMapCenterY = MENU_Y(225.0f); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + +#ifdef NO_ISLAND_LOADING + m_PrefsIslandLoading = ISLAND_LOADING_LOW; +#endif } void @@ -430,13 +563,21 @@ CMenuManager::Initialise(void) DMAudio.Service(); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); +#ifdef FIX_BUGS + static bool firstTime = true; + if (firstTime) { + DMAudio.SetRadioInCar(m_PrefsRadioStation); + firstTime = false; + } else +#endif m_PrefsRadioStation = DMAudio.GetRadioInCar(); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); if (DMAudio.IsMP3RadioChannelAvailable()) { if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; + m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1); } else if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > WAVE) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; + m_PrefsRadioStation = CGeneral::GetRandomNumber() % (WAVE + 1); CFileMgr::SetDir(""); //CFileMgr::SetDir(""); @@ -463,7 +604,6 @@ CMenuManager::CentreMousePointer() } } -// --MIAMI: Done void CMenuManager::CheckCodesForControls(int typeOfControl) { @@ -521,7 +661,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl) m_bWaitingForNewKeyBind = false; m_KeyPressedCode = -1; m_bStartWaitingForKeyBind = false; +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#else SaveSettings(); +#endif } } @@ -532,7 +676,6 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2) m_nMousePosY > y1 && m_nMousePosY < y2; } -// --MIAMI: Done void CMenuManager::CheckSliderMovement(int value) { @@ -575,6 +718,9 @@ CMenuManager::CheckSliderMovement(int value) case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#endif break; default: return; @@ -582,7 +728,6 @@ CMenuManager::CheckSliderMovement(int value) SaveSettings(); } -// --MIAMI: Done void CMenuManager::DisplayHelperText(char *text) { @@ -598,9 +743,10 @@ CMenuManager::DisplayHelperText(char *text) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetDropShadowPosition(0); + // We're using SCREEN_STRETCH_FROM_RIGHT, because we also stretch black borders if (text) { CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get(text)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get(text)); return; } @@ -620,19 +766,19 @@ CMenuManager::DisplayHelperText(char *text) // TODO: name this cases? switch (m_nHelperTextMsgId) { case 1: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_APP")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP")); break; case 2: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_HRD")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD")); break; case 3: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSO")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO")); break; case 4: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_STS")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_STS")); break; case 5: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSC")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC")); break; default: if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO) @@ -641,7 +787,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MUSICVOLUME || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SFXVOLUME) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -650,7 +796,7 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_bGameNotLoaded ? TheText.Get("FET_MIG") : TheText.Get("FEH_NA")); return; } @@ -658,7 +804,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_AUDIOHW || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SPEAKERCONF) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -667,19 +813,18 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nCurrScreen != MENUPAGE_STATS ? TheText.Get("FET_MIG") : TheText.Get("FEH_SSA")); break; } } -// --MIAMI: Done int CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing) { @@ -731,7 +876,6 @@ CMenuManager::DoSettingsBeforeStartingAGame() DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } -// --MIAMI: Done void CMenuManager::DrawStandardMenus(bool activeScreen) { @@ -743,8 +887,14 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); +#ifdef CUSTOM_FRONTEND_OPTIONS + const int xMargin = aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->xMargin != 0 ? aScreens[m_nCurrScreen].layout->xMargin : MENU_X_MARGIN; +#else + const int xMargin = MENU_X_MARGIN; +#endif + + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); #ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); #else @@ -790,7 +940,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetScale(MENU_X(BIGTEXT2_X_SCALE), MENU_Y(BIGTEXT2_Y_SCALE)); CFont::SetRightJustifyOff(); - CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); @@ -825,8 +974,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } CFont::PrintString(MENU_X_LEFT_ALIGNED(100.0f), MENU_Y(97.0f), str); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -836,7 +985,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT); } - bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -844,8 +992,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) uint8 section = 0; // 0: highlight trapezoid 1: texts while (section < 2) { +#endif +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { +#else for (int i = 0; i < NUM_MENUROWS; ++i) { +#endif wchar* rightText = nil; wchar* leftText; if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) { @@ -870,16 +1025,26 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetRightJustifyOff(); CFont::SetCentreOn(); } - if (!aScreens[m_nCurrScreen].m_aEntries[i].m_X && !aScreens[m_nCurrScreen].m_aEntries[i].m_Y) { + if (aScreens[m_nCurrScreen].m_aEntries[i].m_X == 0 && aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { if (i == 0 || (i == 1 && weHaveLabel)) { +#ifdef CUSTOM_FRONTEND_OPTIONS + aScreens[m_nCurrScreen].m_aEntries[i].m_X = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startX : MENU_DEFAULT_CONTENT_X); + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startY : MENU_DEFAULT_CONTENT_Y); +#else aScreens[m_nCurrScreen].m_aEntries[i].m_X = MENU_DEFAULT_CONTENT_X; aScreens[m_nCurrScreen].m_aEntries[i].m_Y = MENU_DEFAULT_CONTENT_Y; +#endif } else { aScreens[m_nCurrScreen].m_aEntries[i].m_X = aScreens[m_nCurrScreen].m_aEntries[i-1].m_X; - aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y + MENU_DEFAULT_LINE_HEIGHT; + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; } } +#ifdef CUSTOM_FRONTEND_OPTIONS + else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; + } +#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { @@ -901,7 +1066,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) { - if (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 0) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD") == 0) { CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1055,17 +1220,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode == 0) - sprintf(asciiTemp, "FULLSCREEN"); - else - sprintf(asciiTemp, "WINDOWED"); - - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); @@ -1128,6 +1282,33 @@ CMenuManager::DrawStandardMenus(bool activeScreen) rightText = TheText.Get("FEA_NM3"); } break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_DYNAMIC: + case MENUACTION_CFO_SELECT: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + + // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) + if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; + + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + + rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->drawFunc) { + bool isOptionDisabled = false; + rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i); + if (isOptionDisabled) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } + } + break; +#endif } // Highlight trapezoid @@ -1135,7 +1316,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) int leftXMax, rightXMin; - // FIX: Let's don't scale those so GetStringWidth will give unscaled width, which will be handy to other calculations below that's done without scaling in mind. + // FIX: Let's don't scale those so GetStringWidth can give us unscaled width, which will be handy to other calculations below that's done without scaling in mind, + // and scaling will be done eventually. // CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); CFont::SetScale(BIGTEXT_X_SCALE, BIGTEXT_Y_SCALE); @@ -1165,9 +1347,9 @@ CMenuManager::DrawStandardMenus(bool activeScreen) leftXMax = 40; } - int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y; + int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y MINUS_SCROLL_OFFSET; int topYMax = y; - uint32 bottomYMin = y + 22; + uint32 bottomYMin = y + MENU_DEFAULT_LINE_HEIGHT - 7; // Decreasing is not recommended. Because this actually is dependent to font scale, not line height. // Actually bottomRight and bottomLeft should be exchanged here(although this is original code). // So this shows us either R* didn't use same struct for menu BG and highlight, or they just kept fields as x1,y1 etc. Yikes. @@ -1228,7 +1410,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (section == 1) { if (leftText) { - CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), leftText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), leftText); } if (rightText) { @@ -1241,7 +1423,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); } - CFont::PrintString(MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), rightText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(DEFAULT_SCREEN_WIDTH - RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin)), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), rightText); } if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) { @@ -1262,7 +1444,12 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 - && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FEA_3DH") +#else + && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS +#endif + && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); SetHelperText(3); @@ -1270,19 +1457,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nDisplayVideoMode != m_nPrefsVideoMode) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FED_RES")) { +#else && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif m_nDisplayVideoMode = m_nPrefsVideoMode; SetHelperText(3); } } -#ifdef IMPROVED_VIDEOMODE - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_POS") != 0 - && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { - m_nSelectedScreenMode = m_nPrefsWindowed; - } - } -#endif // Sliders int lastActiveBarX; @@ -1324,6 +1507,35 @@ CMenuManager::DrawStandardMenus(bool activeScreen) section++; } +#ifdef SCROLLABLE_PAGES + #define SCROLLBAR_BOTTOM_Y 105.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_RIGHT_X 26.0f + #define SCROLLBAR_WIDTH 9.5f + #define SCROLLBAR_TOP_Y 84 + + if (activeScreen && SCREEN_HAS_AUTO_SCROLLBAR) { + // Scrollbar background + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(30, 30, 30, FadeIn(150))); + + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); + float scrollbarBottom, scrollbarTop; + + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 6 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + 2 + m_nScrollbarTopMargin); + // Scrollbar shadow + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), + CRGBA(50, 50, 50, FadeIn(255))); + + // Scrollbar + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); + + } +#endif + switch (m_nCurrScreen) { case MENUPAGE_STATS: case MENUPAGE_CONTROLLER_PC: @@ -1336,6 +1548,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) DisplayHelperText("FEA_NAH"); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + default: + if (aScreens[m_nCurrScreen].layout) { + if (aScreens[m_nCurrScreen].layout->showLeftRightHelper) { + DisplayHelperText(nil); + } + } + break; +#endif } if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) { @@ -1348,7 +1569,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) #endif } -// --MIAMI: Done int CMenuManager::GetNumOptionsCntrlConfigScreens(void) { @@ -1376,7 +1596,6 @@ CMenuManager::GetNumOptionsCntrlConfigScreens(void) return number; } -// --MIAMI: Done void CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 column) { @@ -1607,7 +1826,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // Print bindings, including seperator (-) between them - CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(0.25f), MENU_Y(LISTITEM_Y_SCALE)); for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { @@ -1680,31 +1899,24 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 else DisplayHelperText("FET_RIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = true; } else { DisplayHelperText("FET_CIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { DisplayHelperText("FET_EIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM } } } } -// --MIAMI: Done void CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight) { @@ -1761,7 +1973,6 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig } } -// --MIAMI: Done void CMenuManager::DrawControllerSetupScreen() { @@ -1860,9 +2071,7 @@ CMenuManager::DrawControllerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); CFont::SetDropShadowPosition(0); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM int yStart; if (m_ControlMethod == CONTROL_CLASSIC) @@ -1921,9 +2130,9 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetRightJustifyOff(); if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21 || i == 22 || i == 23)) - CFont::SetScale(MENU_X(0.32f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(0.32f), MENU_Y(LISTITEM_Y_SCALE)); else - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -1954,11 +2163,9 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); - CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f), TheText.Get("FEDS_TB")); } -// --MIAMI: Done void CMenuManager::DrawFrontEnd() { @@ -1974,6 +2181,7 @@ CMenuManager::DrawFrontEnd() } else { m_nCurrScreen = MENUPAGE_PAUSE_MENU; } + SETUP_SCROLLING(m_nCurrScreen) } if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) @@ -1985,7 +2193,6 @@ CMenuManager::DrawFrontEnd() DrawBackground(false); } -// --MIAMI: Done void CMenuManager::DrawBackground(bool transitionCall) { @@ -2097,6 +2304,20 @@ CMenuManager::DrawBackground(bool transitionCall) menuBg.bottomRight_y = 398.0f; break; default: +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->noInvasiveBorders) { + // Taken from the case above + menuBg.topLeft_x = 26.0f; + menuBg.topLeft_y = 59.0f; + menuBg.topRight_x = 629.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 398.0f; + break; + } +#endif menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65; menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21; menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568; @@ -2209,7 +2430,6 @@ CMenuManager::DrawBackground(bool transitionCall) } } -// --MIAMI: Done void CMenuManager::DrawPlayerSetupScreen(bool activeScreen) { @@ -2232,7 +2452,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) SYSTEMTIME SystemTime; HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData); for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) { - if (strncmp(FindFileData.cFileName, DEFAULT_SKIN_NAME, 5) != 0) { + if (strcmp(FindFileData.cFileName, DEFAULT_SKIN_NAME) != 0) { m_pSelectedSkin->nextSkin = new tSkinInfo; m_pSelectedSkin = m_pSelectedSkin->nextSkin; m_pSelectedSkin->skinId = nextSkinId; @@ -2279,7 +2499,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1); if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1); - if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "�", 1)) + if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1); } @@ -2332,9 +2552,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); // Skin list - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM if (m_nSkinsTotal > 0) { for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList; m_pSelectedSkin = m_pSelectedSkin->nextSkin); @@ -2381,7 +2599,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) } else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) { CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255))); } else { - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); } wchar unicodeTemp[80]; AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp); @@ -2403,18 +2621,17 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) ++rowIdx; m_pSelectedSkin = m_pSelectedSkin->nextSkin; } - // Scrollbar background + // Scrollbar background - it's unchanged since III and still yellowish... CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205))); - // Scrollbar - float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal * (float) MAX_VISIBLE_LIST_ROW; + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nSkinsTotal / (float) MAX_VISIBLE_LIST_ROW); float scrollbarBottom, scrollbarTop; if (m_nSkinsTotal <= MAX_VISIBLE_LIST_ROW) { scrollbarBottom = SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 4.0f); scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP); - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } else { @@ -2425,15 +2642,16 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 4 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal); scrollbarTop = MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin); #endif - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } + // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(255, 150, 225, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); // FIX: Scroll button dimensions are buggy, because: // 1 - stretches the original image @@ -2601,14 +2819,12 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); } -// --MIAMI: Done int CMenuManager::FadeIn(int alpha) { return Min(m_nMenuFadeAlpha, alpha); } -// --MIAMI: Done int CMenuManager::GetStartOptionsCntrlConfigScreens() { @@ -2743,7 +2959,6 @@ CMenuManager::LoadAllTextures() CTimer::Update(); } -// --MIAMI: Done void CMenuManager::LoadSettings() { @@ -2792,12 +3007,7 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, gString, 20); CFileMgr::Read(fileHandle, gString, 4); CFileMgr::Read(fileHandle, gString, 4); -#ifdef FREE_CAM - CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Read(fileHandle, gString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -2828,16 +3038,28 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } } CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); +#ifdef LOAD_INI_SETTINGS + if (LoadINISettings()) { + LoadINIControllerSettings(); + } else { + // no re3.ini, create it + SaveINISettings(); + SaveINIControllerSettings(); + } +#endif + +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#endif +#ifdef PC_PLAYER_CONTROLS CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#endif #ifdef LEGACY_MENU_OPTIONS m_PrefsVsync = m_PrefsVsyncDisp; #endif @@ -2879,10 +3101,10 @@ CMenuManager::LoadSettings() } } -// --MIAMI: Done void CMenuManager::SaveSettings() { +#ifndef LOAD_INI_SETTINGS static char RubbishString[48] = "stuffmorestuffevenmorestuff etc"; static int SomeVersion = 3; @@ -2904,12 +3126,7 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, RubbishString, 20); CFileMgr::Write(fileHandle, RubbishString, 4); CFileMgr::Write(fileHandle, RubbishString, 4); -#ifdef FREE_CAM - CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Write(fileHandle, RubbishString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -2940,14 +3157,16 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); + +#else + m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; + SaveINISettings(); +#endif } void @@ -2972,7 +3191,6 @@ CMenuManager::MessageScreen(const char *text, bool blackBg) DoRWStuffEndOfFrame(); } -// --MIAMI: Done void CMenuManager::SmallMessageScreen(const char* text) { @@ -2999,7 +3217,6 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text)); } -// --MIAMI: Done void CMenuManager::PrintBriefs() { @@ -3031,11 +3248,12 @@ CMenuManager::PrintBriefs() } } -// --MIAMI: Done void CMenuManager::PrintStats() { - static uint8 pirateCheck = 0; +#ifdef SECUROM + static uint8 statsPirateCheck = 0; +#endif static float scrollY = 0; int rowNum = CStats::ConstructStatLine(99999); @@ -3048,11 +3266,13 @@ CMenuManager::PrintStats() CFont::SetPropOn(); CFont::SetDropShadowPosition(0); - if (pirateCheck == 0) +#ifdef SECUROM + if (statsPirateCheck == 0) // if not pirated game - pirateCheck = 46; + // statsPirateCheck = 46; // else - // pirateCheck = 45; + statsPirateCheck = 45; +#endif if (m_PrefsLanguage == LANGUAGE_AMERICAN) CFont::SetScale(MENU_X(0.43f), MENU_Y(0.75f)); @@ -3072,8 +3292,10 @@ CMenuManager::PrintStats() lastCheck = CTimer::GetTimeInMillisecondsPauseMode(); } - if (pirateCheck == 45) +#ifdef SECUROM + if (statsPirateCheck == 45) return; +#endif float nextYChange, y, alpha; @@ -3137,14 +3359,17 @@ CMenuManager::PrintStats() UnicodeStrcat(gUString2, gUString); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); +#ifndef FIX_BUGS CFont::SetScale(MENU_X(0.5f), MENU_Y(0.9f)); +#else + CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE)); +#endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetDropShadowPosition(0); CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X) - CFont::GetStringWidth(gUString2, true) / 2.f, MENU_Y(STATS_RATING_Y_2), gUString2); } -// --MIAMI: Done void CMenuManager::Process(void) { @@ -3435,7 +3660,7 @@ CMenuManager::ExportStats() char *statValue = UnicodeToAscii(gUString2); for (int j = 0; statValue[j] != '\0'; ++j) { if (statValue[j] == '_') - statValue[j] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation + statValue[j] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation } if (statValue) fprintf(txtFile, "%s\n\n", statValue); @@ -3497,7 +3722,7 @@ CMenuManager::ExportStats() char *statValue = UnicodeToAscii(gUString2); for (int l = 0; statValue[l] != '\0'; ++l) { if (statValue[l] == '_') - statValue[l] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation + statValue[l] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation } if (statValue) fprintf(htmlFile, "%s", statValue); @@ -3683,10 +3908,10 @@ CMenuManager::PrintRadioSelector(void) CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255))); // Arrows and their shadows - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(333.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(321.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(307.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(321.f), CRGBA(0, 0, 0, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(330.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(318.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(304.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(318.f), CRGBA(97, 194, 247, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(333.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(321.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(307.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(321.f), CRGBA(0, 0, 0, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(330.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(318.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(304.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(318.f), CRGBA(97, 194, 247, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); if (radioChangeRequested) { if (CTimer::GetTimeInMillisecondsPauseMode() - lastRadioChange > 50) { DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -3837,7 +4062,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { m_nFirstVisibleRowOnList = 0; } m_nSelectedListRow = 0; @@ -3847,8 +4072,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; } m_nSelectedListRow = m_nTotalListRow - 1; m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; @@ -3946,13 +4171,22 @@ CMenuManager::UserInput(void) static int oldOption = -99; oldOption = m_nCurrOption; +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int rowToCheck = firstOption; rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#else for (int rowToCheck = 0; rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#endif if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING || aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_LABEL) continue; - if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y) && - m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y + MENU_DEFAULT_LINE_HEIGHT)) { + // unused: CFont::GetStringWidth(TheText.Get(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName), true); + // So they also wanted the compare X, but they abandoned the idea later on + + if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET) && + m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET PLUS_LINE_HEIGHT_ON_SCREEN)) { static int oldScreen = m_nCurrScreen; m_nOptionMouseHovering = rowToCheck; @@ -3996,7 +4230,7 @@ CMenuManager::UserInput(void) if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT; changeValueBy = 0; - if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS || m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + if (hasNativeList(m_nCurrScreen)) { ProcessList(optionSelected, goBack); } else { AdditionalOptionInput(goBack); @@ -4007,8 +4241,7 @@ CMenuManager::UserInput(void) goDown = true; m_nOptionHighlightTransitionBlend = 0; - } - else if (m_AllowNavigation && + } else if (m_AllowNavigation && (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) { m_bShowMouse = false; goUp = true; @@ -4020,8 +4253,7 @@ CMenuManager::UserInput(void) m_bShowMouse = false; optionSelected = true; } - } - else { + } else { if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { m_bShowMouse = false; optionSelected = true; @@ -4058,6 +4290,27 @@ CMenuManager::UserInput(void) } } +#ifdef SCROLLABLE_PAGES + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { + bool temp = false; + + m_nSelectedListRow = m_nCurrOption; + + // ignore detected back/select states, it's our screen's job + ProcessList(temp, temp); + + // and ignore our screen's goUp/Down, now it's ProcessList's job + goUp = false; + goDown = false; + m_nCurrOption = m_nSelectedListRow; + + if (oldOption != m_nCurrOption) + m_nOptionHighlightTransitionBlend = 0; + } + + // Prevent sound on scroll. Mouse wheel is now belongs to us! + if (!(m_nTotalListRow > MAX_VISIBLE_OPTION && (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()))) +#endif if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp() || CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp() || CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp() @@ -4067,7 +4320,7 @@ CMenuManager::UserInput(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); else if (option == MENUACTION_SFXVOLUME) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0); - else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESTEER) + else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESENS) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); } @@ -4111,10 +4364,15 @@ CMenuManager::UserInput(void) } } - if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { - changeValueBy = 1; - } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { - changeValueBy = -1; +#ifdef SCROLLABLE_PAGES + if (!SCREEN_HAS_AUTO_SCROLLBAR) +#endif + { + if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { + changeValueBy = 1; + } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { + changeValueBy = -1; + } } if (m_AllowNavigation) { @@ -4147,9 +4405,30 @@ CMenuManager::UserInput(void) } } ProcessUserInput(goDown, goUp, optionSelected, goBack, changeValueBy); +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].m_aEntries[oldOption].m_Action < MENUACTION_NOTHING) { // CFO check + CMenuScreenCustom::CMenuEntry &oldEntry = aScreens[m_nCurrScreen].m_aEntries[oldOption]; + if (m_nCurrOption != oldOption) { + if (oldEntry.m_Action == MENUACTION_CFO_DYNAMIC) + if(oldEntry.m_CFODynamic->buttonPressFunc) + oldEntry.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != oldEntry.m_CFOSelect->lastSavedValue) + SetHelperText(3); // Restored original value + + oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *oldEntry.m_CFO->value; + } + } else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != *oldEntry.m_CFO->value) + SetHelperText(1); // Enter to apply + else if (m_nHelperTextMsgId == 1) + ResetHelperText(); // Applied + } + } +#endif } -// --MIAMI: Done except TODOs void CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount) { @@ -4165,19 +4444,19 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u MouseButtonJustClicked = false; if (CPad::GetPad(0)->GetLeftMouseJustDown()) - MouseButtonJustClicked = 1; + MouseButtonJustClicked = rsMOUSELEFTBUTTON; else if (CPad::GetPad(0)->GetRightMouseJustUp()) - MouseButtonJustClicked = 3; + MouseButtonJustClicked = rsMOUSERIGHTBUTTON; else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) - MouseButtonJustClicked = 2; + MouseButtonJustClicked = rsMOUSMIDDLEBUTTON; else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) - MouseButtonJustClicked = 4; + MouseButtonJustClicked = rsMOUSEWHEELUPBUTTON; else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) - MouseButtonJustClicked = 5; + MouseButtonJustClicked = rsMOUSEWHEELDOWNBUTTON; else if (CPad::GetPad(0)->GetMouseX1JustUp()) - MouseButtonJustClicked = 6; + MouseButtonJustClicked = rsMOUSEX1BUTTON; else if (CPad::GetPad(0)->GetMouseX2JustUp()) - MouseButtonJustClicked = 7; + MouseButtonJustClicked = rsMOUSEX2BUTTON; JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); @@ -4260,7 +4539,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (optionSelected && m_nMenuFadeAlpha == 255) { if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) { DoSettingsBeforeStartingAGame(); - } else if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) || (m_nCurrScreen == MENUPAGE_SKIN_SELECT)) { + } else if (hasNativeList(m_nCurrScreen)) { switch (m_nCurrExLayer) { case HOVEROPTION_LIST: if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -4297,6 +4576,10 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; +#ifdef FIX_BUGS + int currScreen = m_nCurrScreen; + int currOption = m_nCurrOption; +#endif switch (option) { case MENUACTION_CHANGEMENU: case MENUACTION_YES: @@ -4340,8 +4623,8 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u { int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; - if (saveSlot >= 2 && saveSlot <= 9) { - m_nCurrSaveSlot = saveSlot - 2; + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) { + m_nCurrSaveSlot = saveSlot - SAVESLOT_1; if (Slots[m_nCurrSaveSlot] != SLOT_EMPTY && Slots[m_nCurrSaveSlot] != SLOT_CORRUPTED) { if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) { SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM); @@ -4428,15 +4711,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u SaveSettings(); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - m_nPrefsWindowed = m_nSelectedScreenMode; - _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution - SaveSettings(); - } - break; -#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4490,7 +4764,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u #endif CRenderer::ms_lodDistScale = m_PrefsLOD; m_PrefsShowSubtitles = false; +#ifdef ASPECT_RATIO_SCALE + m_PrefsUseWideScreen = AR_AUTO; +#else m_PrefsUseWideScreen = false; +#endif m_PrefsShowLegends = true; m_PrefsVsyncDisp = true; m_PrefsFrameLimiter = true; @@ -4498,6 +4776,13 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u m_PrefsShowHud = true; m_nDisplayVideoMode = m_nPrefsVideoMode; CMBlur::BlurOn = false; +#ifdef CUSTOM_FRONTEND_OPTIONS + extern void RestoreDefGraphics(int8); + extern void RestoreDefDisplay(int8); + + RestoreDefGraphics(FEOPTION_ACTION_SELECT); + RestoreDefDisplay(FEOPTION_ACTION_SELECT); +#endif SaveSettings(); } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) { ControlsManager.MakeControllerActionsBlank(); @@ -4519,11 +4804,21 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u #endif MousePointerStateHelper.bInvertVertically = true; TheCamera.m_bHeadBob = false; +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = 0.003f; +#endif TheCamera.m_fMouseAccelHorzntl = 0.0025f; CVehicle::m_bDisableMouseSteering = true; m_ControlMethod = CONTROL_STANDARD; +#ifdef PC_PLAYER_CONTROLS TheCamera.m_bUseMouse3rdPerson = true; +#else + TheCamera.m_bUseMouse3rdPerson = false; +#endif SaveSettings(); +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#endif } SetHelperText(2); break; @@ -4537,12 +4832,47 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + + if (!option.m_CFOSelect->onlyApplyOnEnter) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + } + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO + // if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT); + } + + break; +#endif } ProcessOnOffMenuOptions(); if (!goBack) { +#ifdef FIX_BUGS + int saveSlot = aScreens[currScreen].m_aEntries[currOption].m_SaveSlot; + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[currOption] != SLOT_OK) +#else int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; - - if (saveSlot >= 2 && saveSlot <= 9 && Slots[m_nCurrOption] != SLOT_OK) + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[m_nCurrOption] != SLOT_OK) +#endif DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); else DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); @@ -4553,7 +4883,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (m_NoEmptyBinding) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0); SwitchToNewScreen(-2); - if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { + if (hasNativeList(m_nCurrScreen)) { m_nTotalListRow = 0; } } else { @@ -4608,11 +4938,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - m_nSelectedScreenMode = !m_nSelectedScreenMode; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeAmount; @@ -4659,6 +4984,40 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u CCamera::m_bUseMouse3rdPerson = !m_ControlMethod; SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + + if (changeAmount > 0) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts) + option.m_CFOSelect->displayedValue = 0; + } else { + option.m_CFOSelect->displayedValue--; + if (option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1; + } + if (!option.m_CFOSelect->onlyApplyOnEnter) { + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO + // if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + } + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC && option.m_CFODynamic->buttonPressFunc) { + option.m_CFODynamic->buttonPressFunc(changeAmount > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); + } + break; +#endif } CheckSliderMovement(changeAmount); ProcessOnOffMenuOptions(); @@ -4672,7 +5031,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } -// --MIAMI: Done void CMenuManager::ProcessOnOffMenuOptions() { @@ -5029,7 +5387,6 @@ CMenuManager::ProcessFileActions() } } -// --MIAMI: Done void CMenuManager::SwitchMenuOnAndOff() { @@ -5038,7 +5395,11 @@ CMenuManager::SwitchMenuOnAndOff() // Reminder: You need REGISTER_START_BUTTON defined to make it work. if ((CPad::GetPad(0)->GetStartJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) && (!m_bMenuActive || m_nCurrScreen == MENUPAGE_PAUSE_MENU || m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE_CHEAT_WARNING) - || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { + || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested +#ifdef REGISTER_START_BUTTON + || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded +#endif + ) { if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS #ifdef XBOX_MESSAGE_SCREEN @@ -5066,6 +5427,10 @@ CMenuManager::SwitchMenuOnAndOff() Initialise(); LoadAllTextures(); } else { +#ifdef EXTENDED_COLOURFILTER + // we always expect CPostFX to be open + CMBlur::BlurOn = true; +#endif if (CMBlur::BlurOn) CMBlur::MotionBlurOpen(Scene.camera); else @@ -5080,7 +5445,13 @@ CMenuManager::SwitchMenuOnAndOff() } m_StatsScrollSpeed = 150.0f; +#ifdef FIX_BUGS + ThingsToDoBeforeLeavingPage(); +#endif SaveSettings(); +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#endif pControlEdit = nil; pEditString = nil; DisplayComboButtonErrMsg = false; @@ -5169,7 +5540,6 @@ CMenuManager::UnloadTextures() CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown(); } -// --MIAMI: Done void CMenuManager::WaitForUserCD() { @@ -5352,8 +5722,8 @@ CMenuManager::PrintMap(void) #endif m_bMenuMapActive = false; - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); DisplayHelperText("FEH_MPH"); } @@ -5404,5 +5774,3 @@ uint8 CMenuManager::GetNumberOfMenuOptions() #undef GetBackJustUp #undef GetBackJustDown - -#endif diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 01eb1c2e..c1c3983e 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -11,7 +11,7 @@ #define MENUHEADER_HEIGHT 2.0f #define MENUHEADER_WIDTH 1.0f -#define MENU_UNK_X_MARGIN 10.0f +#define MENU_X_MARGIN 10.0f #define MENUACTION_SCALE_MULT 0.9f @@ -23,6 +23,8 @@ #define MENU_DEFAULT_CONTENT_Y 100 #define MENU_DEFAULT_LINE_HEIGHT 29 +#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f) + #define MENURADIO_ICON_FIRST_X 238.f #define MENURADIO_ICON_Y 288.0f #define MENURADIO_ICON_SIZE 60.0f @@ -34,17 +36,23 @@ #define MENUSLIDER_SMALLEST_BAR 8.0f #define MENUSLIDER_BIGGEST_BAR 25.0f -#define BIGTEXT2_X_SCALE 0.6f +#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD #define BIGTEXT2_Y_SCALE 1.2f -#define BIGTEXT_X_SCALE 0.6f +#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING #define BIGTEXT_Y_SCALE 1.0f -#define MEDIUMTEXT_X_SCALE 0.48f +#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD #define MEDIUMTEXT_Y_SCALE 1.0f -#define SMALLTEXT_X_SCALE 0.42f +#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD #define SMALLTEXT_Y_SCALE 0.9f -#define SMALLESTTEXT_X_SCALE 0.3f +#define SMALLESTTEXT_X_SCALE 0.3f // For FONT_STANDARD #define SMALLESTTEXT_Y_SCALE 0.7f +#define LISTITEM_X_SCALE 0.4f // Only unproportional and commonly used scale for FONT_STANDARD +#define LISTITEM_Y_SCALE 0.6f + +#define HELPER_TEXT_RIGHT_MARGIN MENU_X_MARGIN +#define HELPER_TEXT_BOTTOM_MARGIN 18.f + #define PLAYERSETUP_LIST_TOP 58.0f #define PLAYERSETUP_LIST_BOTTOM 95.0f #define PLAYERSETUP_LIST_LEFT 200.0f @@ -56,8 +64,6 @@ #endif #define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f #define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64 -#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f -#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f #define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f #define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f #define PLAYERSETUP_LIST_BODY_TOP 77 @@ -186,7 +192,6 @@ enum eMenuScreen MENUPAGE_MOUSE_CONTROLS = 31, MENUPAGE_PAUSE_MENU = 32, MENUPAGE_NONE = 33, // Then chooses main menu or pause menu - MENUPAGE_OUTRO = 34, #ifdef LEGACY_MENU_OPTIONS MENUPAGE_CONTROLLER_SETTINGS, MENUPAGE_DEBUG_MENU, @@ -196,14 +201,26 @@ enum eMenuScreen MENUPAGE_CONTROLLER_PC_OLD4, MENUPAGE_CONTROLLER_DEBUG, #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, #endif +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUPAGE_DETECT_JOYSTICK, +#endif + +#endif + MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages MENUPAGES }; enum eMenuAction { +#ifdef CUSTOM_FRONTEND_OPTIONS + MENUACTION_CFO_SELECT = -2, + MENUACTION_CFO_DYNAMIC = -1, +#endif MENUACTION_NOTHING, MENUACTION_LABEL, MENUACTION_YES, @@ -258,29 +275,10 @@ enum eMenuAction MENUACTION_DRAWDIST, MENUACTION_MOUSESENS, MENUACTION_MP3VOLUMEBOOST, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT, -#endif #ifdef LEGACY_MENU_OPTIONS MENUACTION_CTRLVIBRATION, MENUACTION_CTRLCONFIG, #endif -#ifdef ANISOTROPIC_FILTERING - MENUACTION_MIPMAPS, - MENUACTION_TEXTURE_FILTERING, -#endif -#ifdef MULTISAMPLING - MENUACTION_MULTISAMPLING, -#endif -#ifdef NO_ISLAND_LOADING - MENUACTION_ISLANDLOADING, -#endif -#ifdef PS2_ALPHA_TEST - MENUACTION_PS2_ALPHA_TEST, -#endif -#ifdef CUTSCENE_BORDERS_SWITCH - MENUACTION_CUTSCENEBORDERS, -#endif }; enum eCheckHover @@ -326,8 +324,8 @@ enum eCheckHover enum { -#ifdef LEGACY_MENU_OPTIONS - NUM_MENUROWS = 14, +#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS + NUM_MENUROWS = 18, #else NUM_MENUROWS = 12, #endif @@ -361,6 +359,7 @@ struct BottomBarOption int32 screenId; }; +#ifndef CUSTOM_FRONTEND_OPTIONS struct CMenuScreen { char m_ScreenName[8]; @@ -378,6 +377,93 @@ struct CMenuScreen uint8 m_Align; } m_aEntries[NUM_MENUROWS]; }; +extern CMenuScreen aScreens[MENUPAGES]; +#else +#include "frontendoption.h" +struct CCustomScreenLayout { + int startX; // not used at all if first entry has X and Y values + int startY; // not used at all if first entry has X and Y values + int lineHeight; // used to determine next entry's Y coordinate, if it has 0-0 as coordinates + bool showLeftRightHelper; + bool noInvasiveBorders; // not needed on pages already handled by game + int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN +}; + +struct CCFO +{ + int8 *value; + const char *saveCat; + const char *save; +}; + +struct CCFOSelect : CCFO +{ + char** rightTexts; + int8 numRightTexts; + bool onlyApplyOnEnter; + int8 displayedValue; // only if onlyApplyOnEnter enabled for now + int8 lastSavedValue; // only if onlyApplyOnEnter enabled + ChangeFunc changeFunc; + bool disableIfGameLoaded; + + CCFOSelect() {}; + CCFOSelect(int8* value, const char* saveCat, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){ + this->value = value; + if (value) + this->lastSavedValue = this->displayedValue = *value; + + this->saveCat = saveCat; + this->save = save; + this->rightTexts = (char**)rightTexts; + this->numRightTexts = numRightTexts; + this->onlyApplyOnEnter = onlyApplyOnEnter; + this->changeFunc = changeFunc; + this->disableIfGameLoaded = disableIfGameLoaded; + } +}; + +struct CCFODynamic : CCFO +{ + DrawFunc drawFunc; + ButtonPressFunc buttonPressFunc; + + CCFODynamic() {}; + CCFODynamic(int8* value, const char* saveCat, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){ + this->value = value; + this->saveCat = saveCat; + this->save = save; + this->drawFunc = drawFunc; + this->buttonPressFunc = buttonPressFunc; + } +}; + +struct CMenuScreenCustom +{ + char m_ScreenName[8]; + int32 m_PreviousPage; // eMenuScreen + CCustomScreenLayout *layout; + ReturnPrevPageFunc returnPrevPageFunc; + + struct CMenuEntry + { + int32 m_Action; // eMenuAction - below zero is CFO + char m_EntryName[8]; + struct { + union { + CCFO *m_CFO; // for initializing + CCFOSelect *m_CFOSelect; + CCFODynamic *m_CFODynamic; + }; + int32 m_SaveSlot; // eSaveSlot + int32 m_TargetMenu; // eMenuScreen + }; + uint16 m_X; + uint16 m_Y; + uint8 m_Align; + } m_aEntries[NUM_MENUROWS]; +}; +extern CMenuScreenCustom aScreens[MENUPAGES]; +#endif struct MenuTrapezoid { @@ -497,8 +583,8 @@ public: int32 field_54; int8 m_bLanguageLoaded; uint8 m_PrefsAllowNastyGame; - uint8 m_PrefsMP3BoostVolume; - uint8 m_ControlMethod; + int8 m_PrefsMP3BoostVolume; + int8 m_ControlMethod; int32 m_nPrefsVideoMode; int32 m_nDisplayVideoMode; int32 m_nMouseTempPosX; @@ -578,8 +664,8 @@ public: int32 m_nSelectedScreenMode; #endif #ifdef MULTISAMPLING - static int8 m_nPrefsMSAALevel; - static int8 m_nDisplayMSAALevel; + int8 m_nPrefsMSAALevel; + int8 m_nDisplayMSAALevel; #endif enum LANGUAGE @@ -617,11 +703,10 @@ public: ISLAND_LOADING_HIGH }; - static int8 m_DisplayIslandLoading; - static int8 m_PrefsIslandLoading; + int8 m_PrefsIslandLoading; - #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) - #define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p) + #define ISLAND_LOADING_IS(p) if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) + #define ISLAND_LOADING_ISNT(p) if (FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p) #else #define ISLAND_LOADING_IS(p) #define ISLAND_LOADING_ISNT(p) @@ -710,6 +795,5 @@ VALIDATE_SIZE(CMenuManager, 0x688); #endif extern CMenuManager FrontEndMenuManager; -extern CMenuScreen aScreens[]; #endif diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp index c9264f7d..c0fcc652 100644 --- a/src/core/Frontend_PS2.cpp +++ b/src/core/Frontend_PS2.cpp @@ -22,7 +22,7 @@ #include "Game.h" #include "World.h" #include "PlayerInfo.h" -#include "FrontendControls.h" +#include "FrontEndControls.h" #include "MemoryCard.h" #define CRect_SZ(x, y, w, h) CRect(x, y, x+w, y+h) @@ -43,7 +43,7 @@ void DoRWStuffEndOfFrame(void); #define X SCREEN_SCALE_X #define Y SCREEN_SCALE_Y -#define YF(x) Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(DEFAULT_SCREEN_HEIGHT_PAL))) +#define YF(x) Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(SCREEN_HEIGHT_PAL))) //#define X(x) ((x)/640.0f*SCRW) //#define Y(y) ((y)/448.0f*SCRH) @@ -3017,4 +3017,4 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *string, CRGBA &color) *dst = '\0'; } -#endif
\ No newline at end of file +#endif diff --git a/src/core/Game.cpp b/src/core/Game.cpp index f31ffa27..83d30bb4 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -1,6 +1,3 @@ -#pragma warning( push ) -#pragma warning( disable : 4005) -#pragma warning( pop ) #include "common.h" #include "platform.h" @@ -10,7 +7,6 @@ #include "Accident.h" #include "Antennas.h" #include "Bridge.h" -#include "Camera.h" #include "CarCtrl.h" #include "CarGen.h" #include "CdStream.h" @@ -32,6 +28,7 @@ #include "Fluff.h" #include "Font.h" #include "Frontend.h" +#include "frontendoption.h" #include "GameLogic.h" #include "Garages.h" #include "GenericGameStorage.h" @@ -44,6 +41,7 @@ #include "MBlur.h" #include "Messages.h" #include "MemoryCard.h" +#include "MemoryHeap.h" #include "Pad.h" #include "Particle.h" #include "ParticleObject.h" @@ -67,7 +65,6 @@ #include "Skidmarks.h" #include "SetPieces.h" #include "SpecialFX.h" -#include "Sprite2d.h" #include "Stats.h" #include "Streaming.h" #include "SurfaceTable.h" @@ -94,6 +91,7 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" +#include "VarConsole.h" #ifdef USE_TEXTURE_POOL #include "TexturePools.h" #endif @@ -111,10 +109,16 @@ char CGame::aDatFile[32]; bool CGame::russianGame = false; bool CGame::japaneseGame = false; #endif +#ifndef MASTER +CVector CGame::PlayerCoords; +bool8 CGame::VarUpdatePlayerCoords; +#endif int gameTxdSlot; -// --MIAMI: File done +#ifdef SECUROM +uint8 gameProcessPirateCheck = 0; +#endif bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); @@ -167,6 +171,11 @@ CGame::InitialiseOnceBeforeRW(void) #ifdef EXTENDED_COLOURFILTER CPostFX::InitOnce(); #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + // Not needed here but may be needed in future + // if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) + CustomFrontendOptionsPopulate(); +#endif return true; } @@ -186,12 +195,22 @@ CGame::InitialiseRenderWare(void) #ifdef USE_TEXTURE_POOL _TexturePoolsInitialise(); #endif - + CTxdStore::Initialise(); CVisibilityPlugins::Initialise(); - + +#ifdef GTA_PS2 + RpSkySelectTrueTSClipper(TRUE); + RpSkySelectTrueTLClipper(TRUE); + + // PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights + // directly without going through RpWorld and all that + SetupPS2ManagerDefaultLightingCallback(); + PreAllocateRwObjects(); +#endif + /* Create camera */ - Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE); + Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE); ASSERT(Scene.camera != nil); if (!Scene.camera) { @@ -221,7 +240,7 @@ CGame::InitialiseRenderWare(void) /* Add the camera to the world */ RpWorldAddCamera(Scene.world, Scene.camera); LightsCreate(Scene.world); - + CreateDebugFont(); #ifdef LIBRW @@ -238,23 +257,39 @@ CGame::InitialiseRenderWare(void) ReplaceAtomicPipeCallback(); #endif // PS2_ALPHA_TEST #endif // LIBRW - + + PUSH_MEMID(MEMID_TEXTURES); CFont::Initialise(); CHud::Initialise(); CPlayerSkin::Initialise(); - + POP_MEMID(); + +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeInit(); // need Scene.world for this +#endif +#ifdef SCREEN_DROPLETS + ScreenDroplets::InitDraw(); +#endif + return (true); } void CGame::ShutdownRenderWare(void) { +#ifdef SCREEN_DROPLETS + ScreenDroplets::Shutdown(); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeShutdown(); +#endif + DestroySplashScreen(); CHud::Shutdown(); CFont::Shutdown(); for ( int32 i = 0; i < NUMPLAYERS; i++ ) CWorld::Players[i].DeletePlayerSkin(); - + CPlayerSkin::Shutdown(); DestroyDebugFont(); @@ -286,7 +321,12 @@ bool CGame::InitialiseOnceAfterRW(void) CSurfaceTable::Initialise("DATA\\SURFACE.DAT"); CPedStats::Initialise(); CTimeCycle::Initialise(); +#ifdef GTA_PS2 + LoadingScreen("Loading the Game", "Initialising audio", GetRandomSplashScreen()); +#endif DMAudio.Initialise(); + +#ifndef GTA_PS2 if ( DMAudio.GetNum3DProvidersAvailable() == 0 ) FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER; @@ -303,6 +343,7 @@ bool CGame::InitialiseOnceAfterRW(void) DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); +#endif return true; } @@ -318,23 +359,40 @@ bool CGame::Initialise(const char* datFile) { ResetLoadingScreenBar(); strcpy(aDatFile, datFile); + +#ifdef GTA_PS2 + // TODO: upload VU0 collision code here +#endif + CPools::Initialise(); + +#ifndef GTA_PS2 CIniFile::LoadIniFile(); +#endif #ifdef USE_TEXTURE_POOL _TexturePoolsUnknown(false); #endif currLevel = LEVEL_BEACH; currArea = AREA_MAIN_MAP; + + PUSH_MEMID(MEMID_TEXTURES); LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); gameTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(gameTxdSlot); CTxdStore::AddRef(gameTxdSlot); + LoadingScreen("Loading the Game", "Loading particles", nil); int particleTxdSlot = CTxdStore::AddTxdSlot("particle"); CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD"); CTxdStore::AddRef(particleTxdSlot); CTxdStore::SetCurrentTxd(gameTxdSlot); LoadingScreen("Loading the Game", "Setup game variables", nil); + POP_MEMID(); + +#ifdef GTA_PS2 + CDma::SyncChannel(0, true); +#endif + CGameLogic::InitAtStartOfGame(); CReferences::Init(); TheCamera.Init(); @@ -354,21 +412,32 @@ bool CGame::Initialise(const char* datFile) CMessages::ClearAllMessagesDisplayedByGame(); CRecordDataForGame::Init(); CRestart::Initialise(); + + PUSH_MEMID(MEMID_WORLD); CWorld::Initialise(); + POP_MEMID(); + + PUSH_MEMID(MEMID_TEXTURES); CParticle::Initialise(); -#ifdef PS2 - gStartX = -180.0f; - gStartY = 180.0f; - gStartZ = 14.0f; -#endif + POP_MEMID(); + + PUSH_MEMID(MEMID_ANIMATION); CAnimManager::Initialise(); CCutsceneMgr::Initialise(); + POP_MEMID(); + + PUSH_MEMID(MEMID_CARS); CCarCtrl::Init(); + POP_MEMID(); + + PUSH_MEMID(MEMID_DEF_MODELS); InitModelIndices(); CModelInfo::Initialise(); CPickups::Init(); CTheCarGenerators::Init(); + CdStreamAddImage("MODELS\\GTA3.IMG"); + CFileLoader::LoadLevel("DATA\\DEFAULT.DAT"); CFileLoader::LoadLevel(datFile); #ifdef EXTENDED_PIPELINES @@ -380,17 +449,21 @@ bool CGame::Initialise(const char* datFile) CVehicleModelInfo::LoadVehicleColours(); CVehicleModelInfo::LoadEnvironmentMaps(); CTheZones::PostZoneCreation(); + POP_MEMID(); + LoadingScreen("Loading the Game", "Setup paths", nil); ThePaths.PreparePathData(); for (int i = 0; i < NUMPLAYERS; i++) CWorld::Players[i].Clear(); CWorld::Players[0].LoadPlayerSkin(); TestModelIndices(); + LoadingScreen("Loading the Game", "Setup water", nil); - WaterLevelInitialise("DATA\\WATER.DAT"); + CWaterLevel::Initialise("DATA\\WATER.DAT"); TheConsole.Init(); CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; + LoadingScreen("Loading the Game", "Setup streaming", nil); CStreaming::LoadInitialVehicles(); CStreaming::LoadInitialPeds(); @@ -398,8 +471,12 @@ bool CGame::Initialise(const char* datFile) CStreaming::LoadAllRequestedModels(false); CStreaming::RemoveIslandsNotUsed(currLevel); printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d + LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); + PUSH_MEMID(MEMID_ANIMATION); CAnimManager::LoadAnimFiles(); + POP_MEMID(); + CStreaming::LoadInitialWeapons(); CStreaming::LoadAllRequestedModels(0); CPed::Initialise(); @@ -410,13 +487,16 @@ bool CGame::Initialise(const char* datFile) #endif LoadingScreen("Loading the Game", "Find big buildings", nil); CRenderer::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CRadar::Initialise(); CRadar::LoadTextures(); CWeapon::InitialiseWeapons(); + LoadingScreen("Loading the Game", "Setup traffic lights", nil); CTrafficLights::ScanForLightsOnMap(); CRoadBlocks::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CPopulation::Initialise(); CWorld::PlayerInFocus = 0; @@ -427,10 +507,16 @@ bool CGame::Initialise(const char* datFile) CAntennas::Init(); CGlass::Init(); gPhoneInfo.Initialise(); +#ifdef GTA_SCENE_EDIT CSceneEdit::Initialise(); +#endif + LoadingScreen("Loading the Game", "Load scripts", nil); + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Init(); CGangs::Initialise(); + POP_MEMID(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CClock::Initialise(1000); CHeli::InitHelis(); @@ -446,24 +532,26 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); + LoadingScreen("Loading the Game", "Position dynamic objects", nil); LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); + CTrain::InitTrains(); CPlane::InitPlanes(); CCredits::Init(); CRecordDataForChase::Init(); CReplay::Init(); + + LoadingScreen("Loading the Game", "Start script", nil); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - LoadingScreen("Loading the Game", "Start script", nil); - CTheScripts::StartTestScript(); - CTheScripts::Process(); - TheCamera.Process(); -#ifdef PS2_MENU + { + CTheScripts::StartTestScript(); + CTheScripts::Process(); + TheCamera.Process(); } -#endif + LoadingScreen("Loading the Game", "Load scene", nil); CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) @@ -471,6 +559,16 @@ bool CGame::Initialise(const char* datFile) #ifdef USE_TEXTURE_POOL _TexturePoolsUnknown(true); #endif + +#ifndef MASTER + PlayerCoords = FindPlayerCoors(); + VarConsole.Add("X PLAYER COORD", &PlayerCoords.x, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("Y PLAYER COORD", &PlayerCoords.y, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("Z PLAYER COORD", &PlayerCoords.z, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("UPDATE PLAYER COORD", &VarUpdatePlayerCoords, true); +#endif + + DMAudio.SetStartingTrackPositions(true); DMAudio.ChangeMusicMode(MUSICMODE_GAME); return true; @@ -488,9 +586,7 @@ bool CGame::ShutDown(void) CScriptPaths::Shutdown(); CWaterCreatures::RemoveAll(); CSpecialFX::Shutdown(); -#ifndef PS2 CGarages::Shutdown(); -#endif CMovingThings::Shutdown(); gPhoneInfo.Shutdown(); CWeapon::ShutdownWeapons(); @@ -544,13 +640,11 @@ void CGame::ReInitGameObjectVariables(void) CGameLogic::InitAtStartOfGame(); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - TheCamera.Init(); - TheCamera.SetRwCamera(Scene.camera); -#ifdef PS2_MENU + { + TheCamera.Init(); + TheCamera.SetRwCamera(Scene.camera); } -#endif CDebug::DebugInitTextBuffer(); CWeather::Init(); CUserDisplay::Init(); @@ -559,11 +653,6 @@ void CGame::ReInitGameObjectVariables(void) CWorld::bDoingCarCollisions = false; CHud::ReInitialise(); CRadar::Initialise(); -#ifdef PS2 - gStartX = -180.0f; - gStartY = 180.0f; - gStartZ = 14.0f; -#endif CCarCtrl::ReInit(); CTimeCycle::Initialise(); CDraw::SetFOV(120.0f); @@ -585,15 +674,15 @@ void CGame::ReInitGameObjectVariables(void) CWorld::Players[i].Clear(); CWorld::PlayerInFocus = 0; -#ifdef PS2 - CWeaponEffects::Init(); - CSkidmarks::Init(); -#endif CAntennas::Init(); CGlass::Init(); gPhoneInfo.Initialise(); + + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Init(); CGangs::Initialise(); + POP_MEMID(); + CTimer::Initialise(); CClock::Initialise(1000); CTheCarGenerators::Init(); @@ -604,10 +693,6 @@ void CGame::ReInitGameObjectVariables(void) CPickups::Init(); CPacManPickups::Init(); CGarages::Init(); -#ifdef PS2 - CClouds::Init(); - CRemote::Init(); -#endif CSpecialFX::Init(); CRopes::Init(); CWaterCannons::Init(); @@ -705,8 +790,7 @@ void CGame::InitialiseWhenRestarting(void) if ( FrontEndMenuManager.m_bWantToLoad == true ) { FrontEndMenuManager.m_bWantToLoad = false; - // TODO(Miami) - //InitRadioStationPositionList(); + InitRadioStationPositionList(); if ( GenericLoad() == true ) { DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); @@ -746,23 +830,38 @@ void CGame::InitialiseWhenRestarting(void) void CGame::Process(void) { CPad::UpdatePads(); -#ifdef GTA_PS2 +#ifdef USE_CUSTOM_ALLOCATOR ProcessTidyUpMemory(); #endif #ifdef DEBUGMENU DebugMenuProcess(); #endif CCutsceneMgr::Update(); + if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused()) FrontEndMenuManager.Process(); + CTheZones::Update(); - // DRM call in here +#ifdef SECUROM + if (CTimer::GetTimeInMilliseconds() >= (35 * 60 * 1000) && gameProcessPirateCheck == 0){ + // if game not pirated + // gameProcessPirateCheck = 1; + // else + gameProcessPirateCheck = 2; + } +#endif uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); CStreaming::Update(); uint32 processTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond() - startTime; CWindModifiers::Number = 0; if (!CTimer::GetIsPaused()) { +#ifndef MASTER + if (VarUpdatePlayerCoords) { + FindPlayerPed()->Teleport(PlayerCoords); + VarUpdatePlayerCoords = false; + } +#endif CSprite2d::SetRecipNearClip(); CSprite2d::InitPerFrame(); CFont::InitPerFrame(); @@ -771,7 +870,11 @@ void CGame::Process(void) CPad::DoCheats(); CClock::Update(); CWeather::Update(); + + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Process(); + POP_MEMID(); + CCollision::Update(); CScriptPaths::Update(); CTrain::UpdateTrains(); @@ -781,7 +884,9 @@ void CGame::Process(void) CSkidmarks::Update(); CAntennas::Update(); CGlass::Update(); +#ifdef GTA_SCENE_EDIT CSceneEdit::Update(); +#endif CSetPieces::Update(); CEventList::Update(); CParticle::Update(); @@ -803,7 +908,11 @@ void CGame::Process(void) CWaterCannons::Update(); CUserDisplay::Process(); CReplay::Update(); + + PUSH_MEMID(MEMID_WORLD); CWorld::Process(); + POP_MEMID(); + gAccidentManager.Update(); CPacManPickups::Update(); CPickups::Update(); @@ -825,62 +934,399 @@ void CGame::Process(void) gPhoneInfo.Update(); if (!CReplay::IsPlayingBack()) { + PUSH_MEMID(MEMID_CARS); if (processTime < 2) CCarCtrl::GenerateRandomCars(); CRoadBlocks::GenerateRoadBlocks(); CCarCtrl::RemoveDistantCars(); CCarCtrl::RemoveCarsIfThePoolGetsFull(); + POP_MEMID(); } } +#ifdef GTA_PS2 + CMemCheck::DoTest(); +#endif } -void -CGame::InitAfterFocusLoss() +#ifdef USE_CUSTOM_ALLOCATOR + +// TODO(MIAMI) + +int32 gNumMemMoved; + +bool +MoveMem(void** ptr) { - FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider; - DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider); + if (*ptr) { + gNumMemMoved++; + void* newPtr = gMainHeap.MoveMemory(*ptr); + if (*ptr != newPtr) { + *ptr = newPtr; + return true; + } + } + return false; +} - if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive) - FrontEndMenuManager.m_bStartUpFrontEndRequested = true; +// Some convenience structs +struct SkyDataPrefix +{ + uint32 pktSize1; + uint32 data; // pointer to data as read from TXD + uint32 pktSize2; + uint32 unused; +}; + +struct DMAGIFUpload +{ + uint32 tag1_qwc, tag1_addr; // dmaref + uint32 nop1, vif_direct1; + + uint32 giftag[4]; + uint32 gs_bitbltbuf[4]; + + uint32 tag2_qwc, tag2_addr; // dmaref + uint32 nop2, vif_direct2; +}; + +// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot +RwTexture* +MoveTextureMemoryCB(RwTexture* texture, void* pData) +{ +#ifdef GTA_PS2 + bool* pRet = (bool*)pData; + RwRaster* raster = RwTextureGetRaster(texture); + _SkyRasterExt* rasterExt = RASTEREXTFROMRASTER(raster); + if (raster->originalPixels == nil || // the raw data + raster->cpPixels == raster->originalPixels || // old format, can't handle it + rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0) + return texture; + + // this is the allocated pointer we will move + SkyDataPrefix* prefix = (SkyDataPrefix*)raster->originalPixels; + DMAGIFUpload* uploads = (DMAGIFUpload*)(prefix + 1); + + // We have 4qw for each upload, + // i.e. for each buffer width of mip levels, + // and the palette if there is one. + // NB: this code does NOT support mipmaps! + // so we assume two uploads (pixels and palette) + // + // each upload looks like this: + // (DMAcnt; NOP; VIF DIRECT(2)) + // giftag (1, A+D) + // GS_BITBLTBUF + // (DMAref->pixel data; NOP; VIF DIRECT(5)) + // the DMArefs are what we have to adjust + uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff; + dataDiff = prefix->data - (uintptr)raster->originalPixels; + upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels; + if (raster->palette) + upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels; + pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels; + if (raster->palette) + paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels; + uint8* newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels); + if (newptr != raster->originalPixels) { + // adjust everything + prefix->data = (uintptr)newptr + dataDiff; + uploads[0].tag2_addr = (uintptr)newptr + upload1Diff; + if (raster->palette) + uploads[1].tag2_addr = (uintptr)newptr + upload2Diff; + raster->originalPixels = newptr; + raster->cpPixels = newptr + pixelDiff; + if (raster->palette) + raster->palette = newptr + paletteDiff; + + if (pRet) { + *pRet = true; + return nil; + } + } +#else + // nothing to do here really, everything should be in videomemory +#endif + return texture; } bool -CGame::CanSeeWaterFromCurrArea(void) +MoveAtomicMemory(RpAtomic* atomic, bool onlyOne) { - return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION - || currArea == AREA_HOTEL; + RpGeometry* geo = RpAtomicGetGeometry(atomic); + +#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31 + if (MoveMem((void**)&geo->triangles) && onlyOne) + return true; + if (MoveMem((void**)&geo->matList.materials) && onlyOne) + return true; + if (MoveMem((void**)&geo->preLitLum) && onlyOne) + return true; + if (MoveMem((void**)&geo->texCoords[0]) && onlyOne) + return true; + if (MoveMem((void**)&geo->texCoords[1]) && onlyOne) + return true; + + // verts and normals of morph target are allocated together + int vertDiff; + if (geo->morphTarget->normals) + vertDiff = geo->morphTarget->normals - geo->morphTarget->verts; + if (MoveMem((void**)&geo->morphTarget->verts)) { + if (geo->morphTarget->normals) + geo->morphTarget->normals = geo->morphTarget->verts + vertDiff; + if (onlyOne) + return true; + } + + RpMeshHeader* oldmesh = geo->mesh; + if (MoveMem((void**)&geo->mesh)) { + // index pointers are allocated together with meshes, + // have to relocate those too + RpMesh* mesh = (RpMesh*)(geo->mesh + 1); + uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh; + for (int i = 0; i < geo->mesh->numMeshes; i++) + mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc); + if (onlyOne) + return true; + } +#else + // we could do something in librw here +#endif + return false; } bool -CGame::CanSeeOutSideFromCurrArea(void) +MoveColModelMemory(CColModel& colModel, bool onlyOne) { - return currArea == AREA_MAIN_MAP || currArea == AREA_MALL || - currArea == AREA_MANSION || currArea == AREA_HOTEL; +#if GTA_VERSION >= GTA3_PS2_160 + // hm...should probably only do this if ownsCollisionVolumes + // but it doesn't exist on PS2... + if (!colModel.ownsCollisionVolumes) + return false; +#endif + + if (MoveMem((void**)&colModel.spheres) && onlyOne) + return true; + if (MoveMem((void**)&colModel.lines) && onlyOne) + return true; + if (MoveMem((void**)&colModel.boxes) && onlyOne) + return true; + if (MoveMem((void**)&colModel.vertices) && onlyOne) + return true; + if (MoveMem((void**)&colModel.triangles) && onlyOne) + return true; + if (MoveMem((void**)&colModel.trianglePlanes) && onlyOne) + return true; + return false; } -void CGame::DrasticTidyUpMemory(bool) +RpAtomic* +MoveAtomicMemoryCB(RpAtomic* atomic, void* pData) { -#ifdef USE_TEXTURE_POOL - // TODO + bool* pRet = (bool*)pData; + if (pRet == nil) + MoveAtomicMemory(atomic, false); + else if (MoveAtomicMemory(atomic, true)) { + *pRet = true; + return nil; + } + return atomic; +} + +bool +TidyUpModelInfo(CBaseModelInfo* modelInfo, bool onlyone) +{ + if (modelInfo->GetColModel() && modelInfo->DoesOwnColModel()) + if (MoveColModelMemory(*modelInfo->GetColModel(), onlyone)) + return true; + + RwObject* rwobj = modelInfo->GetRwObject(); + if (RwObjectGetType(rwobj) == rpATOMIC) + if (MoveAtomicMemory((RpAtomic*)rwobj, onlyone)) + return true; + if (RwObjectGetType(rwobj) == rpCLUMP) { + bool ret = false; + if (onlyone) + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret); + else + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil); + if (ret) + return true; + } + + if (modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel) + if (MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone)) + return true; + + return false; +} #endif -#ifdef PS2 - // meow + + +void CGame::DrasticTidyUpMemory(bool flushDraw) +{ +#ifdef USE_CUSTOM_ALLOCATOR + bool removedCol = false; + + TidyUpMemory(true, flushDraw); + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC); + TidyUpMemory(true, flushDraw); + removedCol = true; + } + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); + CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); + CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if (removedCol) { + // different on PS2 + CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory); + } + + if (!playingIntro) + CStreaming::RequestBigBuildings(currLevel); + + CStreaming::LoadAllRequestedModels(true); #endif } -void CGame::TidyUpMemory(bool unk1, bool unk2) +void CGame::TidyUpMemory(bool moveTextures, bool flushDraw) { -#ifdef PS2 - // meow +#ifdef USE_CUSTOM_ALLOCATOR + printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock()); + + if (moveTextures) { + if (flushDraw) { +#ifdef GTA_PS2 + for (int i = 0; i < sweMaxFlips + 1; i++) { +#else + for (int i = 0; i < 5; i++) { // probably more than needed +#endif + RwCameraBeginUpdate(Scene.camera); + RwCameraEndUpdate(Scene.camera); + RwCameraShowRaster(Scene.camera, nil, 0); + } + } + int fontSlot = CTxdStore::FindTxdSlot("fonts"); + + for (int i = 0; i < TXDSTORESIZE; i++) { + if (i == fontSlot || + CTxdStore::GetSlot(i) == nil) + continue; + RwTexDictionary* txd = CTxdStore::GetSlot(i)->texDict; + if (txd) + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil); + } + } + + // animations + for (int i = 0; i < NUMANIMATIONS; i++) { + CAnimBlendHierarchy* anim = CAnimManager::GetAnimation(i); + if (anim == nil) + continue; // cannot happen + anim->MoveMemory(); + } + + // model info + for (int i = 0; i < MODELINFOSIZE; i++) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(i); + if (mi == nil) + continue; + TidyUpModelInfo(mi, false); + } + + printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock()); #endif - if (unk2) { - DrasticTidyUpMemory(true); // parameter is unknown too } -} void CGame::ProcessTidyUpMemory(void) { -#ifdef PS2 - // meow +#ifdef USE_CUSTOM_ALLOCATOR + static int32 modelIndex = 0; + static int32 animIndex = 0; + static int32 txdIndex = 0; + bool txdReturn = false; + RwTexDictionary* txd = nil; + gNumMemMoved = 0; + + // model infos + for (int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++) { + CBaseModelInfo* mi; + do { + mi = CModelInfo::GetModelInfo(modelIndex); + modelIndex++; + if (modelIndex >= MODELINFOSIZE) + modelIndex = 0; + } while (mi == nil); + + if (TidyUpModelInfo(mi, true)) + return; + } + + // tex dicts + for (int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++) { + if (gNumMemMoved > 80) + break; + + do { +#ifdef FIX_BUGS + txd = nil; #endif + if (CTxdStore::GetSlot(txdIndex)) + txd = CTxdStore::GetSlot(txdIndex)->texDict; + txdIndex++; + if (txdIndex >= TXDSTORESIZE) + txdIndex = 0; + } while (txd == nil); + + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn); + if (txdReturn) + return; + } + + // animations + CAnimBlendHierarchy* anim; + do { + anim = CAnimManager::GetAnimation(animIndex); + animIndex++; + if (animIndex >= NUMANIMATIONS) + animIndex = 0; + } while (anim == nil); // always != nil + anim->MoveMemory(true); +#endif +} + +void +CGame::InitAfterFocusLoss() +{ + FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider; + DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider); + + if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive) + FrontEndMenuManager.m_bStartUpFrontEndRequested = true; +} + +bool +CGame::CanSeeWaterFromCurrArea(void) +{ + return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION + || currArea == AREA_HOTEL; +} + +bool +CGame::CanSeeOutSideFromCurrArea(void) +{ + return currArea == AREA_MAIN_MAP || currArea == AREA_MALL || + currArea == AREA_MANSION || currArea == AREA_HOTEL; } diff --git a/src/core/Game.h b/src/core/Game.h index ee9ca943..4052eb00 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -48,6 +48,11 @@ public: static bool playingIntro; static char aDatFile[32]; +#ifndef MASTER + static CVector PlayerCoords; + static bool8 VarUpdatePlayerCoords; +#endif + static bool InitialiseOnceBeforeRW(void); static bool InitialiseRenderWare(void); static void ShutdownRenderWare(void); diff --git a/src/core/General.h b/src/core/General.h index 7e06b96e..1ea7f2bd 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -2,8 +2,6 @@ #include <ctype.h> -// --MIAMI: file done - class CGeneral { public: @@ -123,6 +121,15 @@ public: return *str2 != '\0'; } + static bool faststrncmp(const char *str1, const char *str2, uint32 count) + { + for(uint32 i = 0; *str1 && i < count; str1++, str2++, i++) { + if (*str1 != *str2) + return true; + } + return false; + } + static bool faststricmp(const char *str1, const char *str2) { for (; *str1; str1++, str2++) { diff --git a/src/core/IniFile.cpp b/src/core/IniFile.cpp index f7e2bfdd..b9033530 100644 --- a/src/core/IniFile.cpp +++ b/src/core/IniFile.cpp @@ -7,8 +7,6 @@ #include "main.h" #include "Population.h" -// --MIAMI: file done - float CIniFile::PedNumberMultiplier = 0.6f; float CIniFile::CarNumberMultiplier = 0.6f; diff --git a/src/core/Lists.h b/src/core/Lists.h index ecf24740..7572e882 100644 --- a/src/core/Lists.h +++ b/src/core/Lists.h @@ -1,7 +1,5 @@ #pragma once -#include "common.h" - class CPtrNode { public: diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 11cd3078..72e19c49 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -2,44 +2,10 @@ #include "Frontend.h" #ifdef PC_MENU -#ifdef CUTSCENE_BORDERS_SWITCH -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, -#else -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) -#endif - -#ifdef IMPROVED_VIDEOMODE -#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen, -#else -#define MENU_IMPROVED_VIDEOMODE(screen) -#endif - -#ifdef ANISOTROPIC_FILTERING -#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen, -#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen, -#else -#define MENU_MIPMAPS(screen) -#define MENU_TEXTURE_FILTERING(screen) -#endif - -#ifdef MULTISAMPLING -#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen, -#else -#define MENU_MULTISAMPLING(screen) -#endif - -#ifdef NO_ISLAND_LOADING -#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen, -#else -#define MENU_ISLAND_LOADING(screen) -#endif - -#ifdef PS2_ALPHA_TEST -#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen, -#else -#define MENU_PS2_ALPHA_TEST(screen) -#endif +// Please don't touch this file, except for bug fixing or ports. +// Check MenuScreensCustom.cpp +#ifndef CUSTOM_FRONTEND_OPTIONS CMenuScreen aScreens[] = { // MENUPAGE_STATS = 0 { "FEH_STA", MENUPAGE_NONE, 3, @@ -72,7 +38,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER, }, - // MENUPAGE_GRAPHICS_SETTINGS = 4 + // MENUPAGE_DISPLAY_SETTINGS = 4 #ifdef LEGACY_MENU_OPTIONS #define Y_OFFSET 50 #else @@ -95,14 +61,8 @@ CMenuScreen aScreens[] = { MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER, -#else - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, -#endif }, #undef Y_OFFSET @@ -255,8 +215,12 @@ CMenuScreen aScreens[] = { // MENUPAGE_CONTROLLER_PC = 26 { "FET_CTL", MENUPAGE_OPTIONS, 0, +#ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER, MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 0, 0, MENUALIGN_CENTER, +#else + MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 320, 150, MENUALIGN_CENTER, +#endif MENUACTION_CHANGEMENU, "FEC_MOU", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_CENTER, MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, MENUALIGN_CENTER, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER, @@ -286,10 +250,8 @@ CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER, }, - // TODO(Miami) // MENUPAGE_KEYBOARD_CONTROLS = 30 { "FET_STI", MENUPAGE_CONTROLLER_PC, 1, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, 0, }, // MENUPAGE_MOUSE_CONTROLS = 31 @@ -314,18 +276,15 @@ CMenuScreen aScreens[] = { // MENUPAGE_NONE = 33 { "", 0, 0, }, - // MENUPAGE_OUTRO = 34 - { "", 0, 0, }, - #ifdef LEGACY_MENU_OPTIONS - // MENUPAGE_CONTROLLER_SETTINGS = 4 + // MENUPAGE_CONTROLLER_SETTINGS { "FET_CON", MENUPAGE_OPTIONS, 0, MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_DEBUG_MENU = 18 + // MENUPAGE_DEBUG_MENU { "FED_DBG", MENUPAGE_NONE, 0, MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, @@ -334,7 +293,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + // MENUPAGE_CONTROLLER_PC_OLD1 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 0, MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, @@ -348,12 +307,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + // MENUPAGE_CONTROLLER_PC_OLD2 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1, }, - // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + // MENUPAGE_CONTROLLER_PC_OLD3 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 2, MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, @@ -362,12 +321,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + // MENUPAGE_CONTROLLER_PC_OLD4 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3, }, - // MENUPAGE_CONTROLLER_DEBUG = 40 + // MENUPAGE_CONTROLLER_DEBUG { "FEC_DBG", MENUPAGE_CONTROLLER_PC, 3, MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, @@ -376,6 +335,10 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, #endif + + // MENUPAGE_OUTRO - Originally 34 + { "", 0, 0, }, }; #endif +#endif diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp new file mode 100644 index 00000000..770e8ec1 --- /dev/null +++ b/src/core/MenuScreensCustom.cpp @@ -0,0 +1,732 @@ +#include "common.h" +#include "platform.h" +#include "crossplatform.h" +#include "Renderer.h" +#include "Frontend.h" +#include "Font.h" +#include "Camera.h" +#include "main.h" +#include "MBlur.h" +#include "postfx.h" +#include "custompipes.h" +#include "RwHelper.h" +#include "Text.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Collision.h" +#include "ModelInfo.h" +#include "Pad.h" +#include "ControllerConfig.h" + +// Menu screens array is at the bottom of the file. + +#ifdef PC_MENU + +#ifdef CUSTOM_FRONTEND_OPTIONS + +#ifdef IMPROVED_VIDEOMODE + #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT, +#else + #define VIDEOMODE_SELECTOR +#endif + +#ifdef MULTISAMPLING + #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT, +#else + #define MULTISAMPLING_SELECTOR +#endif + +#ifdef CUTSCENE_BORDERS_SWITCH + #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, +#else + #define CUTSCENE_BORDERS_TOGGLE +#endif + +#ifdef FREE_CAM + #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, +#else + #define FREE_CAM_TOGGLE +#endif + +#ifdef PS2_ALPHA_TEST + #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, +#else + #define DUALPASS_SELECTOR +#endif + +#ifdef NO_ISLAND_LOADING + #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT, +#else + #define ISLAND_LOADING_SELECTOR +#endif + +#ifdef EXTENDED_COLOURFILTER + #define POSTFX_SELECTORS \ + MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, +#else + #define POSTFX_SELECTORS +#endif + +#ifdef INVERT_LOOK_FOR_PAD + #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) }, 150, 0, MENUALIGN_LEFT, +#else + #define INVERT_PAD_SELECTOR +#endif + +const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" }; +const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + +void RestoreDefGraphics(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef PS2_ALPHA_TEST + gPS2alphaTest = false; + #endif + #ifdef MULTISAMPLING + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0; + #endif + #ifdef NO_ISLAND_LOADING + if (!FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + } else + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsFrameLimiter = true; + FrontEndMenuManager.m_PrefsVsyncDisp = true; + #ifdef LEGACY_MENU_OPTIONS + FrontEndMenuManager.m_PrefsVsync = true; + #endif + FrontEndMenuManager.m_PrefsUseWideScreen = false; + FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode; + CMBlur::BlurOn = false; + FrontEndMenuManager.SaveSettings(); + #endif +} + +void RestoreDefDisplay(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef CUTSCENE_BORDERS_SWITCH + FrontEndMenuManager.m_PrefsCutsceneBorders = true; + #endif + #ifdef FREE_CAM + TheCamera.bFreeCam = false; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsBrightness = 256; + FrontEndMenuManager.m_PrefsLOD = 1.2f; + CRenderer::ms_lodDistScale = 1.2f; + FrontEndMenuManager.m_PrefsShowSubtitles = false; + FrontEndMenuManager.m_PrefsShowLegends = true; + FrontEndMenuManager.m_PrefsRadarMode = 0; + FrontEndMenuManager.m_PrefsShowHud = true; + FrontEndMenuManager.SaveSettings(); + #endif +} + +#ifdef NO_ISLAND_LOADING +const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" }; +void IslandLoadingAfterChange(int8 before, int8 after) { + if (!FrontEndMenuManager.m_bGameNotLoaded) { + if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug: + + if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH); + CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND); + } + if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestBigBuildings(CGame::currLevel); + + } else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestIslands(CGame::currLevel); + } else + FrontEndMenuManager.m_PrefsIslandLoading = after; + + } else { // low + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } + + FrontEndMenuManager.SetHelperText(0); +} +#endif + +#ifdef MORE_LANGUAGES +void LangPolSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangRusSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangJapSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +#ifndef MULTISAMPLING +void GraphicsGoBack() { +} +#else +void GraphicsGoBack() { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; +} + +void MultiSamplingButtonPress(int8 action) { + if (action == FEOPTION_ACTION_SELECT) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel; + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); + FrontEndMenuManager.SetHelperText(0); + FrontEndMenuManager.SaveSettings(); + } + } else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) { + if (FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1); + + int i = 0; + int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels(); + while (maxAA != 1) { + i++; + maxAA >>= 1; + } + + if (FrontEndMenuManager.m_nDisplayMSAALevel < 0) + FrontEndMenuManager.m_nDisplayMSAALevel = i; + else if (FrontEndMenuManager.m_nDisplayMSAALevel > i) + FrontEndMenuManager.m_nDisplayMSAALevel = 0; + } + } else if (action == FEOPTION_ACTION_FOCUSLOSS) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + FrontEndMenuManager.SetHelperText(3); + } + } +} + +wchar* MultiSamplingDraw(bool *disabled, bool userHovering) { + static wchar unicodeTemp[64]; + if (userHovering) { + if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) { + if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply + FrontEndMenuManager.ResetHelperText(); + } else { + FrontEndMenuManager.SetHelperText(1); + } + } else { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + } + } + + if (!FrontEndMenuManager.m_bGameNotLoaded) + *disabled = true; + + switch (FrontEndMenuManager.m_nDisplayMSAALevel) { + case 0: + return TheText.Get("FEM_OFF"); + default: + sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel)); + AsciiToUnicode(gString, unicodeTemp); + return unicodeTemp; + } +} +#endif + +#ifdef IMPROVED_VIDEOMODE +const char* screenModes[] = { "FED_FLS", "FED_WND" }; +void ScreenModeAfterChange(int8 before, int8 after) +{ + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution + FrontEndMenuManager.SetHelperText(0); +} + +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +wchar selectedJoystickUnicode[128]; +int cachedButtonNum = -1; + +wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { + int numButtons; + int found = -1; + const char *joyname; + if (userHovering) { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if ((joyname = glfwGetJoystickName(i))) { + const uint8* buttons = glfwGetJoystickButtons(i, &numButtons); + for (int j = 0; j < numButtons; j++) { + if (buttons[j]) { + found = i; + break; + } + } + if (found != -1) + break; + } + } + + if (found != -1 && PSGLOBAL(joy1id) != found) { + if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found) + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + else + PSGLOBAL(joy2id) = -1; + + strcpy(gSelectedJoystickName, joyname); + PSGLOBAL(joy1id) = found; + cachedButtonNum = numButtons; + } + } + if (PSGLOBAL(joy1id) == -1) + AsciiToUnicode("Not found", selectedJoystickUnicode); + else + AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); + + return selectedJoystickUnicode; +} + +void DetectJoystickGoBack() { + if (cachedButtonNum != -1) { +#ifdef LOAD_INI_SETTINGS + ControlsManager.InitDefaultControlConfigJoyPad(cachedButtonNum); + SaveINIControllerSettings(); +#else + // Otherwise no way to save gSelectedJoystickName or ms_padButtonsInited anyway :shrug: Why do you even use this config.?? +#endif + cachedButtonNum = -1; + } +} +#endif + +CMenuScreenCustom aScreens[] = { + // MENUPAGE_STATS = 0 + { "FEH_STA", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_NEW_GAME = 1 + { "FEP_STG", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_BRIEFS = 2 + { "FEH_BRI", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_SOUND_SETTINGS = 3 + { "FEH_AUD", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT, + MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_DISPLAY_SETTINGS = 4 +#ifndef GRAPHICS_MENU_OPTIONS + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER + MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR + MULTISAMPLING_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + POSTFX_SELECTORS + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#else + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_LANGUAGE_SETTINGS = 5 + { "FEH_LAN", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_LANG_ENG, "FEL_ENG", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LANG_FRE, "FEL_FRE", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef MORE_LANGUAGES + MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER, + MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER + MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_MAP = 6 + { "FEH_MAP", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER, + }, + + // MENUPAGE_NEW_GAME_RELOAD = 7 + { "FES_NGA", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER, + MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_LOAD_SLOT = 8 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_DELETE_SLOT = 9 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOAD_SLOT_CONFIRM = 10 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_DELETE_SLOT_CONFIRM = 11 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QD", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOADING_IN_PROGRESS = 12 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + }, + + // MENUPAGE_DELETING_IN_PROGRESS = 13 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + }, + + // MENUPAGE_DELETE_SUCCESSFUL = 14 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_SAVE_SLOT = 15 + { "FET_SG", MENUPAGE_DISABLED, nil, nil, + MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QZ", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVING_IN_PROGRESS = 17 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + }, + + // MENUPAGE_SAVE_SUCCESSFUL = 18 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CUSTOM_WARNING = 19 + { "FET_SG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CHEAT_WARNING = 20 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SKIN_SELECT = 21 + { "FET_PS", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_UNUSED = 22 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED = 23 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED_2 = 24 + { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + }, + + // MENUPAGE_LOAD_FAILED = 25 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC = 26 + { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil, +#ifdef PC_PLAYER_CONTROLS + MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER, + MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER, +#else + MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 320, 150, MENUALIGN_CENTER, +#endif +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER, + INVERT_PAD_SELECTOR + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_OPTIONS = 27 + { "FET_OPT", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef GRAPHICS_MENU_OPTIONS + MENUACTION_CHANGEMENU, "FET_GRA", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_EXIT = 28 + { "FET_QG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER, + MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_START_MENU = 29 + { "FEM_MM", MENUPAGE_DISABLED, nil, nil, + MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_KEYBOARD_CONTROLS = 30 + { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil, + }, + + // MENUPAGE_MOUSE_CONTROLS = 31 + { "FEC_MOU", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_MOUSESENS, "FEC_MSH", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 40, 170, MENUALIGN_LEFT, + MENUACTION_INVVERT, "FEC_IVV", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER, + }, + + // MENUPAGE_PAUSE_MENU = 32 + { "FET_PAU", MENUPAGE_DISABLED, nil, nil, + MENUACTION_RESUME, "FEP_RES", {nil, SAVESLOT_NONE, 0}, 320, 120, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_SGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_MAP", {nil, SAVESLOT_NONE, MENUPAGE_MAP}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_STA", {nil, SAVESLOT_NONE, MENUPAGE_STATS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_BRI", {nil, SAVESLOT_NONE, MENUPAGE_BRIEFS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FET_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_NONE = 33 + { "", 0, nil, nil, }, + + +#ifdef LEGACY_MENU_OPTIONS + // MENUPAGE_CONTROLLER_SETTINGS = 4 + { "FET_CON", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_CTRLCONFIG, "FEC_CCF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_CTRLVIBRATION, "FEC_VIB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_DEBUG_MENU = 18 + { "FED_DBG", MENUPAGE_NONE, nil, nil, + MENUACTION_RELOADIDE, "FED_RID", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SETDBGFLAG, "FED_DFL", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_COLLISIONPOLYS, "FED_SCP", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_PLB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWR", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LKT", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PJP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PSP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TLF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TRG", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CCM", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_LUP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LDN", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_SHOWHEADBOB, "FEC_GSL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_DEBUG = 40 + { "FEC_DBG", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_TGD", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TDO", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TSS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, +#endif + +#ifdef GRAPHICS_MENU_OPTIONS + // MENUPAGE_GRAPHICS_SETTINGS + { "FET_GRA", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack, + + MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MULTISAMPLING_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR +#ifdef EXTENDED_COLOURFILTER + POSTFX_SELECTORS +#elif defined LEGACY_MENU_OPTIONS + MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, +#endif + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + // MENUPAGE_DETECT_JOYSTICK + { "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), DetectJoystickGoBack, + MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0, + MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_OUTRO = 34 + { "", 0, nil, nil, }, +}; + +#endif +#endif diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 91e2d704..5c79c0d3 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -1,11 +1,4 @@ -#pragma warning( push ) -#pragma warning( disable : 4005) -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif -#pragma warning( pop ) - +#define WITHDINPUT #include "common.h" #include "crossplatform.h" #include "platform.h" @@ -54,8 +47,6 @@ #include "libpad.h" #endif -// --MIAMI: file done except Mobile(see TODOs) and PS2 stuff - CPad Pads[MAX_PADS]; #ifdef GTA_PS2 u_long128 pad_dma_buf[scePadDmaBufferMax] __attribute__((aligned(64))); @@ -151,7 +142,7 @@ void PickUpChicksCheat() if ( FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike()) ) { CVehicle *vehicle = FindPlayerVehicle(); - if ( FindPlayerVehicle()->m_vehType == 5 ) + if ( FindPlayerVehicle()->IsBike() ) { if ( vehicle->pPassengers[0] ) vehicle->pPassengers[0]->SetObjective(OBJECTIVE_LEAVE_CAR, vehicle); @@ -457,7 +448,7 @@ void ArmourCheat() void WantedLevelUpCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT5"), true); - FindPlayerPed()->m_pWanted->CheatWantedLevel(Min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6)); + FindPlayerPed()->m_pWanted->CheatWantedLevel(Min(FindPlayerPed()->m_pWanted->GetWantedLevel() + 2, 6)); } void WantedLevelDownCheat() @@ -1213,14 +1204,46 @@ void CPad::AddToCheatString(char c) int Cheat_strncmp(char* sourceStr, char* origCheatStr) { - char cheatCodeVals[] = { 3,5,7,1,13,27,3,7,1,11,13,8,7,32,13,6,28,19,10,3,3,5,7,1,13,27,3,7 }; - - for (uint32 i = 0; i < strlen(origCheatStr); i++) { - if ((sourceStr[i] != origCheatStr[i] - cheatCodeVals[i]) || i >= ARRAY_SIZE(cheatCodeVals)) { - return 1; - } +#define ccmp(n) if((uint8)sourceStr[i] != (uint8)origCheatStr[i] - n) return 1; + int i = 0; + while(origCheatStr[i]) + { + switch(i) + { + case 0: ccmp(3); break; + case 1: ccmp(5); break; + case 2: ccmp(7); break; + case 3: ccmp(1); break; + case 4: ccmp(13); break; + case 5: ccmp(27); break; + case 6: ccmp(3); break; + case 7: ccmp(7); break; + case 8: ccmp(1); break; + case 9: ccmp(11); break; + case 10: ccmp(13); break; + case 11: ccmp(8); break; + case 12: ccmp(7); break; + case 13: ccmp(32); break; + case 14: ccmp(13); break; + case 15: ccmp(6); break; + case 16: ccmp(28); break; + case 17: ccmp(19); break; + case 18: ccmp(10); break; + case 19: ccmp(3); break; + case 20: ccmp(3); break; + case 21: ccmp(5); break; + case 22: ccmp(7); break; + case 23: ccmp(1); break; + case 24: ccmp(13); break; + case 25: ccmp(27); break; + case 26: ccmp(3); break; + case 27: ccmp(7); break; + default: return 1; + } + i++; } return 0; +#undef ccmp } // TODO(Miami): Mobile has changed some of the cheats to include debugging things @@ -1660,12 +1683,11 @@ void CPad::UpdatePads(void) bUpdate = false; if ( bUpdate ) - { GetPad(0)->Update(0); - // GetPad(1)->Update(0); // not in VC - } -#if defined(MASTER) && !defined(XINPUT) +#ifndef MASTER + GetPad(1)->Update(1); +#else GetPad(1)->NewState.Clear(); GetPad(1)->OldState.Clear(); #endif @@ -3299,10 +3321,18 @@ void CPad::PrintErrorMessage(void) if ( bDisplayNoControllerMessage && !CGame::playingIntro && !FrontEndMenuManager.m_bMenuActive ) { CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_FROM_BOTTOM(130.0f), SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(140.0f)), CRGBA(50, 50, 50, 210)); +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f)); +#else + CFont::SetScale(0.85f, 1.0f); +#endif CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(590.0f)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 20); +#endif CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); @@ -3317,10 +3347,18 @@ void CPad::PrintErrorMessage(void) else if ( bObsoleteControllerMessage ) { CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_FROM_BOTTOM(130.0f), SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(140.0f)), CRGBA(50, 50, 50, 210)); +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f)); +#else + CFont::SetScale(0.85f, 1.0f); +#endif CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(590.0f)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 20); +#endif CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 61e2f67a..a64d4cca 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -3,6 +3,7 @@ #include "Automobile.h" #include "Bridge.h" #include "Camera.h" +#include "CarCtrl.h" #include "Cranes.h" #include "Darkel.h" #include "Explosion.h" @@ -36,91 +37,6 @@ CVector lastPlayerPos; -// --MIAMI: Done -void -CPlayerInfo::SetPlayerSkin(char *skin) -{ - strncpy(m_aSkinName, skin, 32); - LoadPlayerSkin(); -} - -// --MIAMI: Done -const CVector & -CPlayerInfo::GetPos() -{ -#ifdef FIX_BUGS - if (!m_pPed) - return TheCamera.GetPosition(); -#endif - if (m_pPed->InVehicle()) - return m_pPed->m_pMyVehicle->GetPosition(); - return m_pPed->GetPosition(); -} - -// --MIAMI: Done -void -CPlayerInfo::LoadPlayerSkin() -{ - DeletePlayerSkin(); - - m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); -} - -// --MIAMI: Done -void -CPlayerInfo::DeletePlayerSkin() -{ - if (m_pSkinTexture) { - RwTextureDestroy(m_pSkinTexture); - m_pSkinTexture = nil; - } -} - -// --MIAMI: Done -void -CPlayerInfo::KillPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_WASTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); - CStats::TimesDied++; -} - -// --MIAMI: Done -void -CPlayerInfo::ArrestPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_BUSTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - m_nBustedAudioStatus = BUSTEDAUDIO_NONE; - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); - CStats::TimesArrested++; -} - -// --MIAMI: Done -bool -CPlayerInfo::IsPlayerInRemoteMode() -{ - return m_pRemoteVehicle || m_bInRemoteMode; -} - -void -CPlayerInfo::PlayerFailedCriticalMission() -{ - if (m_WBState != WBSTATE_PLAYING) - return; - m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); -} - -// --MIAMI: Done void CPlayerInfo::Clear(void) { @@ -181,192 +97,6 @@ CPlayerInfo::Clear(void) m_nBustedAudioStatus = BUSTEDAUDIO_NONE; } -// --MIAMI: Done -void -CPlayerInfo::BlowUpRCBuggy(bool actually) -{ - if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) - return; - - CRemote::TakeRemoteControlledCarFromPlayer(actually); - if (actually) - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); -} - -// --MIAMI: Done -void -CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) -{ - if (!car || car == m_pPed->m_pMyVehicle) { - if (m_pPed->EnteringCar()) - m_pPed->QuitEnteringCar(); - } - if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) - m_pPed->ClearObjective(); -} - -// --MIAMI: Done -void -CPlayerInfo::MakePlayerSafe(bool toggle) -{ - if (toggle) { - m_pPed->m_pWanted->m_bIgnoredByEveryone = true; - CWorld::StopAllLawEnforcersInTheirTracks(); - CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); - CPad::StopPadsShaking(); - m_pPed->bBulletProof = true; - m_pPed->bFireProof = true; - m_pPed->bCollisionProof = true; - m_pPed->bMeleeProof = true; - m_pPed->bOnlyDamagedByPlayer = true; - m_pPed->bExplosionProof = true; - m_pPed->m_bCanBeDamaged = false; - ((CPlayerPed*)m_pPed)->ClearAdrenaline(); - CancelPlayerEnteringCars(nil); - gFireManager.ExtinguishPoint(GetPos(), 4000.0f); - CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); - CProjectileInfo::RemoveAllProjectiles(); - CWorld::SetAllCarsCanBeDamaged(false); - CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); - CReplay::DisableReplays(); - - } else { - m_pPed->m_pWanted->m_bIgnoredByEveryone = false; - CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); - m_pPed->bBulletProof = false; - m_pPed->bFireProof = false; - m_pPed->bCollisionProof = false; - m_pPed->bMeleeProof = false; - m_pPed->bOnlyDamagedByPlayer = false; - m_pPed->bExplosionProof = false; - m_pPed->m_bCanBeDamaged = true; - CWorld::SetAllCarsCanBeDamaged(true); - CReplay::EnableReplays(); - } -} - -// --MIAMI: Done -bool -CPlayerInfo::IsRestartingAfterDeath() -{ - return m_WBState == WBSTATE_WASTED; -} - -// --MIAMI: Done -bool -CPlayerInfo::IsRestartingAfterArrest() -{ - return m_WBState == WBSTATE_BUSTED; -} - -// --MIAMI: Done -// lastCloseness is passed to other calls of this function -void -CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) -{ - // This dist used for determining the angle to face - CVector2D dist(carToTest->GetPosition() - player->GetPosition()); - float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); - while (neededTurn >= PI) { - neededTurn -= 2 * PI; - } - - while (neededTurn < -PI) { - neededTurn += 2 * PI; - } - - // This dist used for evaluating cars' distances, weird... - // Accounts inverted needed turn (or needed turn in long way) and car dist. - float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); - if (closeness > *lastCloseness) { - *lastCloseness = closeness; - *closestCarOutput = (CVehicle*)carToTest; - } -} - -// --MIAMI: Done -void -CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) -{ - // Interesting - *size = sizeof(CPlayerInfo); - -#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio); -#undef CopyToBuf -} - -// --MIAMI: Done -void -CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) -{ -#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio) -#undef CopyFromBuf -} - -// --MIAMI: Done -void -CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) -{ - for (CPtrNode* node = carList.first; node; node = node->next) { - CVehicle *car = (CVehicle*)node->item; - if(car->m_scanCode != CWorld::GetCurrentScanCode()) { - if (!car->bUsesCollision || !car->IsVehicle()) - continue; - - car->m_scanCode = CWorld::GetCurrentScanCode(); - if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING - && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { - CVector carCentre = car->GetBoundCentre(); - - if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) { - float dist = (ped->GetPosition() - carCentre).Magnitude2D(); - if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { - EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); - } - } - } - } - } -} - void CPlayerInfo::Process(void) { @@ -400,7 +130,7 @@ CPlayerInfo::Process(void) CAutomobile *car = (CAutomobile*)m_pPed->m_pMyVehicle; if (car->m_nWheelsOnGround < 3) - m_nTimeNotFullyOnGround += CTimer::GetTimeInMilliseconds(); + m_nTimeNotFullyOnGround += CTimer::GetTimeStepInMilliseconds(); else m_nTimeNotFullyOnGround = 0; @@ -658,8 +388,8 @@ CPlayerInfo::Process(void) m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow); } else if (carBelow->IsBoat()) { if (!carBelow->pDriver) { - m_pPed->m_vehEnterType = 0; - m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType); + m_pPed->m_vehDoor = 0; + m_pPed->SetEnterCar(carBelow, m_pPed->m_vehDoor); } } else { m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow); @@ -673,13 +403,13 @@ CPlayerInfo::Process(void) uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar; if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) { TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 0); + TheCamera.Fade(1.0f, FADE_OUT); } if (timeWithoutRemoteCar > 2000) { if (m_WBState == WBSTATE_PLAYING && field_D6) { TheCamera.RestoreWithJumpCut(); TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 1); + TheCamera.Fade(1.0f, FADE_IN); TheCamera.Process(); CTimer::Stop(); CCullZones::ForceCullZoneCoors(TheCamera.GetPosition()); @@ -749,7 +479,7 @@ CPlayerInfo::Process(void) CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled; } - if (m_pPed->m_pWanted->m_nWantedLevel && !CTheScripts::IsPlayerOnAMission()) { + if (m_pPed->m_pWanted->GetWantedLevel() && !CTheScripts::IsPlayerOnAMission()) { float maxDelta = 0.0f; static bool movedSignificantly = true; static bool thereIsACarPathNear = true; @@ -761,7 +491,7 @@ CPlayerInfo::Process(void) lastPlayerPos = FindPlayerCoors(); thereIsACarPathNear = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 60.0f, true, false, false, false) != 0; } - switch (m_pPed->m_pWanted->m_nWantedLevel) { + switch (m_pPed->m_pWanted->GetWantedLevel()) { case 1: maxDelta = 31.f; break; @@ -796,3 +526,355 @@ CPlayerInfo::Process(void) m_nMoney = Min(999999999, m_nMoney); m_nVisibleMoney = Min(999999999, m_nVisibleMoney); } + +bool +CPlayerInfo::IsPlayerInRemoteMode() +{ + return m_pRemoteVehicle || m_bInRemoteMode; +} + +void +CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) +{ + // Interesting + *size = sizeof(CPlayerInfo); + +#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio); +#undef CopyToBuf +} + +void +CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) +{ +#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio) +#undef CopyFromBuf +} + +void +CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) +{ + for (CPtrNode* node = carList.first; node; node = node->next) { + CVehicle *car = (CVehicle*)node->item; + if(car->m_scanCode != CWorld::GetCurrentScanCode()) { + if (!car->bUsesCollision || !car->IsVehicle()) + continue; + + car->m_scanCode = CWorld::GetCurrentScanCode(); + if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING + && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { + CVector carCentre = car->GetBoundCentre(); + + if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) { + float dist = (ped->GetPosition() - carCentre).Magnitude2D(); + if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { + EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); + } + } + } + } + } +} + +// lastCloseness is passed to other calls of this function +void +CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) +{ + // This dist used for determining the angle to face + CVector2D dist(carToTest->GetPosition() - player->GetPosition()); + float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); + while (neededTurn >= PI) { + neededTurn -= 2 * PI; + } + + while (neededTurn < -PI) { + neededTurn += 2 * PI; + } + + // This dist used for evaluating cars' distances, weird... + // Accounts inverted needed turn (or needed turn in long way) and car dist. + float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); + if (closeness > *lastCloseness) { + *lastCloseness = closeness; + *closestCarOutput = (CVehicle*)carToTest; + } +} + +const CVector & +CPlayerInfo::GetPos() +{ +#ifdef FIX_BUGS + if (!m_pPed) + return TheCamera.GetPosition(); +#endif + if (m_pPed->InVehicle()) + return m_pPed->m_pMyVehicle->GetPosition(); + return m_pPed->GetPosition(); +} + +CVector +FindPlayerCoors(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) + return TheCamera.GetPosition(); +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->GetPosition(); + else + return ped->GetPosition(); +} + +const CVector & +FindPlayerSpeed(void) +{ +#ifdef FIX_BUGS + static CVector vecTmpVector(0.0f, 0.0f, 0.0f); + if (CReplay::IsPlayingBack()) + return vecTmpVector; +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->m_vecMoveSpeed; + else + return ped->m_vecMoveSpeed; +} + +CVehicle * +FindPlayerVehicle(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped && ped->InVehicle()) return ped->m_pMyVehicle; + return nil; +} + +CEntity * +FindPlayerEntity(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle; + else + return ped; +} + +CVehicle * +FindPlayerTrain(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) + return FindPlayerVehicle(); + else + return nil; +} + +CPlayerPed * +FindPlayerPed(void) +{ + return CWorld::Players[CWorld::PlayerInFocus].m_pPed; +} + +const CVector & +FindPlayerCentreOfWorld(int32 player) +{ +#ifdef FIX_BUGS + if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return CWorld::Players[player].m_pPed->GetPosition(); +} + +const CVector & +FindPlayerCentreOfWorld_NoSniperShift(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return FindPlayerPed()->GetPosition(); +} + +float +FindPlayerHeading(void) +{ + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); + return FindPlayerPed()->GetForward().Heading(); +} + +bool +CPlayerInfo::IsRestartingAfterDeath() +{ + return m_WBState == WBSTATE_WASTED; +} + +bool +CPlayerInfo::IsRestartingAfterArrest() +{ + return m_WBState == WBSTATE_BUSTED; +} + +void +CPlayerInfo::KillPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_WASTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); + CStats::TimesDied++; +} + +void +CPlayerInfo::ArrestPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_BUSTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + m_nBustedAudioStatus = BUSTEDAUDIO_NONE; + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); + CStats::TimesArrested++; +} + +void +CPlayerInfo::PlayerFailedCriticalMission() +{ + if (m_WBState != WBSTATE_PLAYING) + return; + m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); +} + +void +CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) +{ + if (!car || car == m_pPed->m_pMyVehicle) { + if (m_pPed->EnteringCar()) + m_pPed->QuitEnteringCar(); + } + if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) + m_pPed->ClearObjective(); +} + +void +CPlayerInfo::MakePlayerSafe(bool toggle) +{ + if (toggle) { + m_pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); + CPad::StopPadsShaking(); + m_pPed->bBulletProof = true; + m_pPed->bFireProof = true; + m_pPed->bCollisionProof = true; + m_pPed->bMeleeProof = true; + m_pPed->bOnlyDamagedByPlayer = true; + m_pPed->bExplosionProof = true; + m_pPed->m_bCanBeDamaged = false; + ((CPlayerPed*)m_pPed)->ClearAdrenaline(); + CancelPlayerEnteringCars(nil); + gFireManager.ExtinguishPoint(GetPos(), 4000.0f); + CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); + CProjectileInfo::RemoveAllProjectiles(); + CWorld::SetAllCarsCanBeDamaged(false); + CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); + CReplay::DisableReplays(); + + } else { + m_pPed->m_pWanted->m_bIgnoredByEveryone = false; + CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); + m_pPed->bBulletProof = false; + m_pPed->bFireProof = false; + m_pPed->bCollisionProof = false; + m_pPed->bMeleeProof = false; + m_pPed->bOnlyDamagedByPlayer = false; + m_pPed->bExplosionProof = false; + m_pPed->m_bCanBeDamaged = true; + CWorld::SetAllCarsCanBeDamaged(true); + CReplay::EnableReplays(); + } +} + +void +CPlayerInfo::BlowUpRCBuggy(bool actually) +{ + if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) + return; + + CRemote::TakeRemoteControlledCarFromPlayer(actually); + if (actually) + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); +} + +#ifdef GTA_PC +void +CPlayerInfo::SetPlayerSkin(const char *skin) +{ + strncpy(m_aSkinName, skin, 32); + LoadPlayerSkin(); +} + +void +CPlayerInfo::LoadPlayerSkin() +{ + DeletePlayerSkin(); + + m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); +} + +void +CPlayerInfo::DeletePlayerSkin() +{ + if (m_pSkinTexture) { + RwTextureDestroy(m_pSkinTexture); + m_pSkinTexture = nil; + } +} +#endif diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 7d99a4e0..a24185f0 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -1,6 +1,6 @@ #pragma once -#include "Collision.h" +#include "ColModel.h" enum eWastedBustedState { @@ -10,7 +10,7 @@ enum eWastedBustedState WBSTATE_FAILED_CRITICAL_MISSION, }; -enum eBustedAudioState : uint8 +enum eBustedAudioState { BUSTEDAUDIO_NONE, BUSTEDAUDIO_LOADING, @@ -82,15 +82,14 @@ public: bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; bool m_bDriveByAllowed; - eBustedAudioState m_nBustedAudioStatus; + uint8 m_nBustedAudioStatus; int16 m_nCurrentBustedAudio; +#ifdef GTA_PC char m_aSkinName[32]; RwTexture *m_pSkinTexture; +#endif void MakePlayerSafe(bool); - void LoadPlayerSkin(); - void DeletePlayerSkin(); - void SetPlayerSkin(char* skin); const CVector &GetPos(); void Process(void); void KillPlayer(void); @@ -107,5 +106,19 @@ public: void SavePlayerInfo(uint8 *buf, uint32* size); void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**); - ~CPlayerInfo() { }; +#ifdef GTA_PC + void LoadPlayerSkin(); + void SetPlayerSkin(const char *skin); + void DeletePlayerSkin(); +#endif }; + +CPlayerPed *FindPlayerPed(void); +CVehicle *FindPlayerVehicle(void); +CVehicle *FindPlayerTrain(void); +CEntity *FindPlayerEntity(void); +CVector FindPlayerCoors(void); +const CVector &FindPlayerSpeed(void); +const CVector &FindPlayerCentreOfWorld(int32 player); +const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); +float FindPlayerHeading(void);
\ No newline at end of file diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index cbc57902..bf35f8ef 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -13,8 +13,7 @@ #include "Streaming.h" #include "Wanted.h" #include "World.h" - -//--MIAMI: file done +#include "MemoryHeap.h" CCPtrNodePool *CPools::ms_pPtrNodePool; CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool; @@ -27,19 +26,39 @@ CDummyPool *CPools::ms_pDummyPool; CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool; CColModelPool *CPools::ms_pColModelPool; +#if defined GTA_PS2 && !defined MASTER // or USE_CUSTOM_ALLOCATOR +// not in VC. perhaps ifdef'ed away +#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg) +#else +#define CHECKMEM(msg) +#endif + void CPools::Initialise(void) { + PUSH_MEMID(MEMID_POOLS); + CHECKMEM("before pools"); ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode"); + CHECKMEM("after CPtrNodePool"); ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode"); + CHECKMEM("after CEntryInfoNodePool"); ms_pPedPool = new CPedPool(NUMPEDS, "Peds"); + CHECKMEM("after CPedPool"); ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles"); + CHECKMEM("after CVehiclePool"); ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings"); + CHECKMEM("after CBuildingPool"); ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables"); + CHECKMEM("after CTreadablePool"); ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects"); + CHECKMEM("after CObjectPool"); ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys"); + CHECKMEM("after CDummyPool"); ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj"); + CHECKMEM("after cAudioScriptObjectPool"); ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel"); + CHECKMEM("after pools"); + POP_MEMID(); } void @@ -90,7 +109,7 @@ CPools::CheckPoolsEmpty() void CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot) { - if (ms_pObjectPool->IsFreeSlot(slot)) return; + if (ms_pObjectPool->GetIsFree(slot)) return; CObject *object = ms_pObjectPool->GetSlot(slot); if (object->ObjectCreatedBy == TEMP_OBJECT) { @@ -515,7 +534,7 @@ INITSAVEBUF #endif CopyToBuf(buf, CWanted::MaximumWantedLevel); CopyToBuf(buf, CWanted::nMaximumWantedLevel); - memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME); + memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetModelName(), MAX_MODEL_NAME); SkipSaveBuf(buf, MAX_MODEL_NAME); } } diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 8fe900ae..36fb156d 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -17,8 +17,6 @@ #include "SpecialFX.h" #include "Font.h" -// --MIAMI: file done - float CRadar::m_radarRange; sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; CVector2D vec2DRadarOrigin; @@ -476,6 +474,10 @@ void CRadar::Draw3dMarkers() void CRadar::DrawBlips() { if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) { +#ifdef SECUROM + extern uint8 roadBlocksPirateCheck; + if (roadBlocksPirateCheck == 2) return; +#endif RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); @@ -675,7 +677,7 @@ void CRadar::DrawRadarMask() CVector2D(-1.0, -1.0f) }; - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)nil); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); diff --git a/src/core/Radar.h b/src/core/Radar.h index 8f2e7069..0829dda6 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -156,8 +156,28 @@ struct sRadarTraceSave // Values for screen space #define RADAR_LEFT (40.0f) #define RADAR_BOTTOM (40.0f) + +#ifdef FIX_RADAR +/* + The values are from an early screenshot taken before R* broke radar + #define RADAR_WIDTH (82.0f) + #define RADAR_HEIGHT (82.0f) +*/ +#define RADAR_WIDTH ((CDraw::ms_bFixRadar) ? (82.0f) : (94.0f)) +#define RADAR_HEIGHT ((CDraw::ms_bFixRadar) ? (82.0f) : (76.0f)) +#else +/* + broken since forever, someone tried to fix size for 640x512(PAL) + http://aap.rockstarvision.com/pics/gta3/ps2screens/gta3_interface.jpg + but failed: + http://aap.rockstarvision.com/pics/gta3/artwork/gta3_artwork_16.jpg + most likely the guy used something like this: + int y = 82 * (640.0/512.0)/(640.0/480.0); + int x = y * (640.0/512.0); +*/ #define RADAR_WIDTH (94.0f) #define RADAR_HEIGHT (76.0f) +#endif class CRadar { diff --git a/src/core/References.cpp b/src/core/References.cpp index 52abbc3e..dc83d96d 100644 --- a/src/core/References.cpp +++ b/src/core/References.cpp @@ -22,6 +22,83 @@ CReferences::Init(void) } void +CEntity::RegisterReference(CEntity **pent) +{ + if(IsBuilding()) + return; + CReference *ref; + // check if already registered + for(ref = m_pFirstReference; ref; ref = ref->next) + if(ref->pentity == pent) + return; + // have to allocate new reference + ref = CReferences::pEmptyList; + if(ref){ + CReferences::pEmptyList = ref->next; + + ref->pentity = pent; + ref->next = m_pFirstReference; + m_pFirstReference = ref; + return; + } + return; +} + +// Clean up the reference from *pent -> 'this' +void +CEntity::CleanUpOldReference(CEntity **pent) +{ + CReference* ref, ** lastnextp; + lastnextp = &m_pFirstReference; + for (ref = m_pFirstReference; ref; ref = ref->next) { + if (ref->pentity == pent) { + *lastnextp = ref->next; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = ref; + break; + } + lastnextp = &ref->next; + } +} + +// Clear all references to this entity +void +CEntity::ResolveReferences(void) +{ + CReference *ref; + // clear pointers to this entity + for(ref = m_pFirstReference; ref; ref = ref->next) + if(*ref->pentity == this) + *ref->pentity = nil; + // free list + if(m_pFirstReference){ + for(ref = m_pFirstReference; ref->next; ref = ref->next) + ; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = m_pFirstReference; + m_pFirstReference = nil; + } +} + +// Free all references that no longer point to this entity +void +CEntity::PruneReferences(void) +{ + CReference *ref, *next, **lastnextp; + lastnextp = &m_pFirstReference; + for(ref = m_pFirstReference; ref; ref = next){ + next = ref->next; + if(*ref->pentity == this) + lastnextp = &ref->next; + else{ + *lastnextp = ref->next; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = ref; + } + } +} + +void CReferences::RemoveReferencesToPlayer(void) { if(FindPlayerVehicle()) diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index bd2351de..7ada0da9 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -115,8 +115,6 @@ float CStats::LongestWheelieDist; float CStats::LongestStoppieDist; float CStats::Longest2WheelDist; -// --MIAMI: functions below are done, but there are some to be moved from Frontend - void CStats::Init() { PeopleKilledByOthers = 0; @@ -1007,7 +1005,7 @@ CStats::ConstructStatLine(int rowIdx) // What a random stat... if (lastProcessedDay != DaysPassed) { lastProcessedDay = DaysPassed; - lastPoliceSpending = (CTimer::GetTimeInMilliseconds() + 80) * 255.44f; + lastPoliceSpending = (CTimer::GetTimeInMilliseconds() & 255 + 80) * 255.44f; } STAT_LINE_1(float, "DAYPLC", lastPoliceSpending, 3); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 40d4acee..6f0e3153 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -32,8 +32,11 @@ #include "ColStore.h" #include "DMAudio.h" #include "Script.h" - -//--MIAMI: file done (possibly bugs) +#include "MemoryMgr.h" +#include "MemoryHeap.h" +#include "Font.h" +#include "Frontend.h" +#include "VarConsole.h" bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -78,6 +81,12 @@ CEntity *pIslandLODbeachEntity; int32 islandLODmainland; int32 islandLODbeach; +#ifndef MASTER +bool gbPrintStats; +bool gbPrintVehiclesInMemory; // TODO +bool gbPrintStreamingBuffer; // TODO +#endif + bool CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) { @@ -233,8 +242,14 @@ CStreaming::Init2(void) pIslandLODbeachEntity = nil; islandLODmainland = -1; islandLODbeach = -1; - CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); - CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); + CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); + CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); + +#ifndef MASTER + VarConsole.Add("Streaming Debug", &gbPrintStats, true); + VarConsole.Add("Streaming Vehicle Debug", &gbPrintVehiclesInMemory, true); + VarConsole.Add("Printf Streaming Buffer contents", &gbPrintStreamingBuffer, true); +#endif } void @@ -289,12 +304,22 @@ CStreaming::Shutdown(void) } } +#ifndef MASTER +uint64 timeProcessingTXD; +uint64 timeProcessingDFF; +#endif + void CStreaming::Update(void) { CStreamingInfo *si, *prev; bool requestedSubway = false; +#ifndef MASTER + timeProcessingTXD = 0; + timeProcessingDFF = 0; +#endif + UpdateMemoryUsed(); if(ms_channelError != -1){ @@ -332,6 +357,10 @@ CStreaming::Update(void) CColStore::EnsureCollisionIsInMemory(FindPlayerCoors()); } + // TODO: PrintRequestList + //if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2()) + // PrintRequestList(); + for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0) @@ -451,7 +480,7 @@ GetObjectName(int streamId) { static char objname[32]; if(streamId < STREAM_OFFSET_TXD) - sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName()); + sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetModelName()); else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL) sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD)); else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM) @@ -463,6 +492,14 @@ GetObjectName(int streamId) return objname; } +#ifdef USE_CUSTOM_ALLOCATOR +RpAtomic* +RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data) +{ + // empty because we expect models to be pre-instanced + return atomic; +} +#endif bool CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) @@ -487,7 +524,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Txd and anim have to be loaded int animId = mi->GetAnimFileIndex(); +#ifdef FIX_BUGS + if(!HasTxdLoaded(mi->GetTxdSlot()) || +#else + // texDict will exist even if only first part has loaded if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil || +#endif animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){ RemoveModel(streamId); ReRequestModel(streamId); @@ -497,10 +539,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Set Txd and anims to use CTxdStore::AddRef(mi->GetTxdSlot()); +#if GTA_VERSION > GTAVC_PS2 if(animId != -1) CAnimManager::AddAnimBlockRef(animId); - CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); +#endif + PUSH_MEMID(MEMID_STREAM_MODELS); + CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); if(mi->IsSimple()){ success = CFileLoader::LoadAtomicFile(stream, streamId); // TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that @@ -512,18 +557,25 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; }else{ success = CFileLoader::LoadClumpFile(stream, streamId); +#ifdef USE_CUSTOM_ALLOCATOR + if(success) + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif } + POP_MEMID(); UpdateMemoryUsed(); // Txd and anims no longer needed unless we only read part of the file if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); +#if GTA_VERSION > GTAVC_PS2 if(animId != -1) CAnimManager::RemoveAnimBlockRefWithoutDelete(animId); +#endif } if(!success){ - debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName()); + debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetModelName()); RemoveModel(streamId); ReRequestModel(streamId); RwStreamClose(stream, &mem); @@ -538,12 +590,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) return false; } + PUSH_MEMID(MEMID_STREAM_TEXUTRES); if(ms_bLoadingBigModel || cdsize > 200){ success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream); if(success) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; }else success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream); + POP_MEMID(); UpdateMemoryUsed(); if(!success){ @@ -554,7 +608,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) return false; } }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){ - if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){ + PUSH_MEMID(MEMID_STREAM_COLLISION); + bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length); + POP_MEMID(); + if(!success){ debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL)); RemoveModel(streamId); ReRequestModel(streamId); @@ -569,8 +626,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } + PUSH_MEMID(MEMID_STREAM_ANIMATION); CAnimManager::LoadAnimFile(stream, true, nil); CAnimManager::CreateAnimAssocGroups(); + POP_MEMID(); } RwStreamClose(stream, &mem); @@ -603,7 +662,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Mark objects as loaded if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; +#ifndef USE_CUSTOM_ALLOCATOR ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; +#endif } endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); @@ -638,26 +699,39 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) if(streamId < STREAM_OFFSET_TXD){ // Model mi = CModelInfo::GetModelInfo(streamId); + PUSH_MEMID(MEMID_STREAM_MODELS); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); success = CFileLoader::FinishLoadClumpFile(stream, streamId); - if(success) + if(success){ +#ifdef USE_CUSTOM_ALLOCATOR + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif success = AddToLoadedVehiclesList(streamId); + } + POP_MEMID(); mi->RemoveRef(); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); +#if GTA_VERSION > GTAVC_PS2 if(mi->GetAnimFileIndex() != -1) CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex()); +#endif }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); + PUSH_MEMID(MEMID_STREAM_TEXUTRES); success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); + POP_MEMID(); CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); }else{ assert(0 && "invalid streamId"); } RwStreamClose(stream, &mem); + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; +#ifndef USE_CUSTOM_ALLOCATOR ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; +#endif if(!success){ RemoveModel(streamId); @@ -740,7 +814,15 @@ CStreaming::RequestBigBuildings(eLevelName level) n = CPools::GetBuildingPool()->GetSize()-1; for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); - if(b && b->bIsBIGBuilding && b->m_level == level) + if(b && b->bIsBIGBuilding +#ifdef NO_ISLAND_LOADING + && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && + (b != pIslandLODbeachEntity)) || + (b->m_level == level)) +#else + && b->m_level == level +#endif + ) if(!b->bStreamBIGBuilding) RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } @@ -757,8 +839,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding -#ifndef NO_ISLAND_LOADING - && b->m_level == level +#ifdef NO_ISLAND_LOADING + && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity) + ) || (b->m_level == level)) +#else + && b->m_level == level #endif ) if(b->bStreamBIGBuilding){ @@ -828,7 +913,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos) void CStreaming::RequestIslands(eLevelName level) { -#ifndef NO_ISLAND_LOADING + ISLAND_LOADING_ISNT(HIGH) switch(level){ case LEVEL_MAINLAND: if(islandLODbeach != -1) @@ -840,7 +925,6 @@ CStreaming::RequestIslands(eLevelName level) break; default: break; } -#endif } static char *IGnames[] = { @@ -904,7 +988,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag mi = CModelInfo::GetModelInfo(modelId); if(strncasecmp("CSPlay", modelName, 6) == 0){ - char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetName(); + char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName(); for(int i = 0; CSnames[i][0]; i++){ if(strcasecmp(curname, IGnames[i]) == 0){ modelName = CSnames[i]; @@ -912,7 +996,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag } } } - if(!CGeneral::faststrcmp(mi->GetName(), modelName)){ + if(!CGeneral::faststrcmp(mi->GetModelName(), modelName)){ // Already have the correct name, just request it RequestModel(modelId, flags); return; @@ -937,8 +1021,8 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag } } - strcpy(oldName, mi->GetName()); - mi->SetName(modelName); + strcpy(oldName, mi->GetModelName()); + mi->SetModelName(modelName); // What exactly is going on here? if(CModelInfo::GetModelInfo(oldName, nil)){ @@ -1170,12 +1254,13 @@ CStreaming::RemoveBuildingsNotInArea(int32 area) void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { -#ifndef NO_ISLAND_LOADING + ISLAND_LOADING_IS(LOW) + { if(level != LEVEL_BEACH) RemoveBigBuildings(LEVEL_BEACH); if(level != LEVEL_MAINLAND) RemoveBigBuildings(LEVEL_MAINLAND); -#endif + } RemoveIslandsNotUsed(level); } @@ -1195,7 +1280,6 @@ DeleteIsland(CEntity *island) void CStreaming::RemoveIslandsNotUsed(eLevelName level) { -#ifndef NO_ISLAND_LOADING int i; if(pIslandLODmainlandEntity == nil) for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ @@ -1207,7 +1291,12 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) if(building->GetModelIndex() == islandLODbeach) pIslandLODbeachEntity = building; } - +#ifdef NO_ISLAND_LOADING + if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + DeleteIsland(pIslandLODmainlandEntity); + DeleteIsland(pIslandLODbeachEntity); + } else +#endif switch(level){ case LEVEL_MAINLAND: DeleteIsland(pIslandLODmainlandEntity); @@ -1217,7 +1306,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) break; } -#endif // !NO_ISLAND_LOADING } void @@ -1705,11 +1793,11 @@ CStreaming::StreamZoneModels(const CVector &pos) int newMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j]; if(newMI != oldMI){ RequestModel(newMI, STREAMFLAGS_DEPENDENCY); - debug("Request Ped %s\n", CModelInfo::GetModelInfo(newMI)->GetName()); + debug("Request Ped %s\n", CModelInfo::GetModelInfo(newMI)->GetModelName()); if(ms_numPedsLoaded == MAXZONEPEDSLOADED){ SetModelIsDeletable(oldMI); SetModelTxdIsDeletable(oldMI); - debug("Remove Ped %s\n", CModelInfo::GetModelInfo(oldMI)->GetName()); + debug("Remove Ped %s\n", CModelInfo::GetModelInfo(oldMI)->GetModelName()); }else ms_numPedsLoaded++; timeBeforeNextLoad = 300; @@ -1818,26 +1906,38 @@ CStreaming::LoadBigBuildingsWhenNeeded(void) CTimer::Suspend(); CGame::currLevel = CTheZones::m_CurrLevel; - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - CCollision::LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); - - RemoveUnusedBigBuildings(CGame::currLevel); - RemoveUnusedBuildings(CGame::currLevel); - RemoveUnusedModelsInLoadedList(); - CGame::TidyUpMemory(true, true); - + ISLAND_LOADING_IS(LOW) + { + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + + RemoveUnusedBigBuildings(CGame::currLevel); + RemoveUnusedBuildings(CGame::currLevel); + RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + } CReplay::EmptyReplayBuffer(); if(CGame::currLevel != LEVEL_GENERIC) LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + ISLAND_LOADING_IS(LOW) + CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); +#ifdef NO_ISLAND_LOADING + else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) { + RemoveIslandsNotUsed(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } +#endif + CStreaming::LoadAllRequestedModels(false); CGame::TidyUpMemory(true, true); CTimer::Resume(); - DMAudio.SetEffectsFadeVol(127); + + ISLAND_LOADING_IS(LOW) + DMAudio.SetEffectsFadeVol(127); } @@ -2415,19 +2515,27 @@ CStreaming::FlushRequestList(void) void CStreaming::ImGonnaUseStreamingMemory(void) { - // empty + PUSH_MEMID(MEMID_STREAM); } void CStreaming::IHaveUsedStreamingMemory(void) { + POP_MEMID(); UpdateMemoryUsed(); } void CStreaming::UpdateMemoryUsed(void) { - // empty +#ifdef USE_CUSTOM_ALLOCATOR + ms_memoryUsed = + gMainHeap.GetMemoryUsed(MEMID_STREAM) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION); +#endif } #define STREAM_DIST 80.0f @@ -3041,3 +3149,71 @@ CStreaming::UpdateForAnimViewer(void) CStreaming::RetryLoadFile(CStreaming::ms_channelError); } } + + +void +CStreaming::PrintStreamingBufferState() +{ + char str[128]; + wchar wstr[128]; + uint32 offset, size; + + CTimer::Stop(); + int i = 0; + while (i < NUMSTREAMINFO) { + while (true) { + int j = 0; + DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255); + CPad::UpdatePads(); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + DefinedState(); + + CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight); + CRGBA unusedColor(255, 255, 255, 255); + CFont::SetFontStyle(FONT_BANK); + CFont::SetBackgroundOff(); + CFont::SetWrapx(DEFAULT_SCREEN_WIDTH); + CFont::SetScale(0.5f, 0.75f); + CFont::SetCentreOff(); + CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(200, 200, 200, 200)); + CFont::SetBackGroundOnlyTextOff(); + int modelIndex = i; + if (modelIndex < NUMSTREAMINFO) { + int y = 24; + for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) { + CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex]; + CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex); + if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size)) + continue; + + if (modelIndex >= STREAM_OFFSET_TXD) + sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD), + CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags); + else + sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetModelName(), modelInfo->GetNumRefs(), 2 * size, + streamingInfo->m_flags); + AsciiToUnicode(str, wstr); + CFont::PrintString(24.0f, y, wstr); + y += 12; + j++; + } + } + + if (CPad::GetPad(1)->GetCrossJustDown()) + i = modelIndex; + + if (!CPad::GetPad(1)->GetTriangleJustDown()) + break; + + i = 0; + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); + } + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); + } + CTimer::Update(); +}
\ No newline at end of file diff --git a/src/core/Streaming.h b/src/core/Streaming.h index dd85ce97..a67384f6 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -197,11 +197,11 @@ public: static void DeleteFarAwayRwObjects(const CVector &pos); static void DeleteAllRwObjects(void); static void DeleteRwObjectsAfterDeath(const CVector &pos); - static void DeleteRwObjectsBehindCamera(size_t mem); + static void DeleteRwObjectsBehindCamera(size_t mem); // originally signed static void DeleteRwObjectsInSectorList(CPtrList &list); static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y); - static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); - static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); + static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); // originally signed + static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed static void LoadScene(const CVector &pos); static void LoadSceneCollision(const CVector &pos); @@ -210,4 +210,6 @@ public: static void MemoryCardLoad(uint8 *buffer, uint32 length); static void UpdateForAnimViewer(void); + + static void PrintStreamingBufferState(); }; diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp index 56cea203..c4b184bf 100644 --- a/src/core/SurfaceTable.cpp +++ b/src/core/SurfaceTable.cpp @@ -6,8 +6,6 @@ #include "Collision.h" #include "SurfaceTable.h" -//--MIAMI: file done - float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS]; void @@ -138,7 +136,7 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType) case SURFACE_SAND: case SURFACE_SAND_BEACH: - return 1.0f - CWeather::WetRoads*0.5f; + return 1.0f + CWeather::WetRoads*0.5f; default: return 1.0f; diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h index cd08c843..8ff43106 100644 --- a/src/core/SurfaceTable.h +++ b/src/core/SurfaceTable.h @@ -81,6 +81,7 @@ inline bool IsShootThrough(uint8 surfType) { switch(surfType) + case SURFACE_TRANSPARENT_CLOTH: case SURFACE_METAL_CHAIN_FENCE: case SURFACE_TRANSPARENT_STONE: case SURFACE_SCAFFOLD_POLE: diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index bdef6187..5ebe3f53 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -7,8 +7,6 @@ #include "Timer.h" #include "SpecialFX.h" -// --MIAMI: file done - uint32 CTimer::m_snTimeInMilliseconds; PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; diff --git a/src/core/User.cpp b/src/core/User.cpp index 8d584b74..53196d03 100644 --- a/src/core/User.cpp +++ b/src/core/User.cpp @@ -10,8 +10,6 @@ #include "World.h" #include "Zones.h" -// --MIAMI: file done - CPlaceName CUserDisplay::PlaceName; COnscreenTimer CUserDisplay::OnscnTimer; CPager CUserDisplay::Pager; diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index f5ea6e53..65bc84d8 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -15,8 +15,6 @@ int32 CWanted::MaximumWantedLevel = 6; int32 CWanted::nMaximumWantedLevel = 9600; -// --MIAMI: File done except stats - void CWanted::Initialise() { diff --git a/src/core/Wanted.h b/src/core/Wanted.h index 057b5407..f2da23e3 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -41,6 +41,7 @@ public: int32 NumOfHelisRequired(); void SetWantedLevel(int32); void SetWantedLevelNoDrop(int32 level); + int32 GetWantedLevel() { return m_nWantedLevel; } void CheatWantedLevel(int32 level); void RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare); void RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare); diff --git a/src/core/World.cpp b/src/core/World.cpp index bc104fe9..bc698c83 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -4,7 +4,6 @@ #include "CopPed.h" #include "CutsceneMgr.h" #include "DMAudio.h" -#include "Entity.h" #include "EventList.h" #include "Explosion.h" #include "Fire.h" @@ -12,11 +11,8 @@ #include "Glass.h" #include "Messages.h" #include "ModelIndices.h" -#include "Object.h" #include "ParticleObject.h" -#include "Ped.h" #include "Pickups.h" -#include "PlayerPed.h" #include "Population.h" #include "ProjectileInfo.h" #include "Record.h" @@ -25,17 +21,14 @@ #include "RpAnimBlend.h" #include "Shadows.h" #include "TempColModels.h" -#include "Vehicle.h" #include "WaterLevel.h" #include "World.h" -// --MIAMI: file done - #define OBJECT_REPOSITION_OFFSET_Z 2.0f CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -CPtrList CWorld::ms_bigBuildingsList[4]; +CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS]; CPtrList CWorld::ms_listMovingEntityPtrs; CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; uint16 CWorld::ms_nCurrentScanCode; @@ -147,13 +140,13 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } CObject::DeleteAllTempObjectsInArea(pos, radius); gFireManager.ExtinguishPoint(pos, radius); - CWorld::ExtinguishAllCarFiresInArea(pos, radius); + ExtinguishAllCarFiresInArea(pos, radius); CExplosion::RemoveAllExplosionsInArea(pos, radius); if(bRemoveProjectilesAndTidyUpShadows) { CProjectileInfo::RemoveAllProjectiles(); @@ -796,7 +789,7 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); @@ -813,42 +806,42 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -1070,7 +1063,7 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nCollidingEntities = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); @@ -1087,42 +1080,42 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, + FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } @@ -1156,7 +1149,7 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); @@ -1164,49 +1157,49 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X - 1); const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y - 1); #else - const int32 nEndX = Min(GetSectorIndexX(vecSectorPos.x), NUMSECTORS_X); - const int32 nEndY = Min(GetSectorIndexY(vecSectorPos.y), NUMSECTORS_Y); + const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X); + const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y); #endif for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } @@ -1242,7 +1235,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; const int32 nStartX = Max(GetSectorIndexX(fStartX), 0); const int32 nStartY = Max(GetSectorIndexY(fStartY), 0); @@ -1257,42 +1250,42 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -1327,7 +1320,7 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds, bool bObjects) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); @@ -1342,26 +1335,26 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bVehicles) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); } if(bPeds) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); } if(bObjects) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); } @@ -1399,102 +1392,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec } } -CPlayerPed * -FindPlayerPed(void) -{ - return CWorld::Players[CWorld::PlayerInFocus].m_pPed; -} - -CVehicle * -FindPlayerVehicle(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped && ped->InVehicle()) return ped->m_pMyVehicle; - return nil; -} - -CVehicle * -FindPlayerTrain(void) -{ - if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) - return FindPlayerVehicle(); - else - return nil; -} - -CEntity * -FindPlayerEntity(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle; - else - return ped; -} - -CVector -FindPlayerCoors(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) - return TheCamera.GetPosition(); -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->GetPosition(); - else - return ped->GetPosition(); -} - -CVector & -FindPlayerSpeed(void) -{ -#ifdef FIX_BUGS - static CVector vecTmpVector(0.0f, 0.0f, 0.0f); - if (CReplay::IsPlayingBack()) - return vecTmpVector; -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->m_vecMoveSpeed; - else - return ped->m_vecMoveSpeed; -} - -const CVector & -FindPlayerCentreOfWorld(int32 player) -{ -#ifdef FIX_BUGS - if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return CWorld::Players[player].m_pPed->GetPosition(); -} - -const CVector & -FindPlayerCentreOfWorld_NoSniperShift(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return FindPlayerPed()->GetPosition(); -} - -float -FindPlayerHeading(void) -{ - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); - return FindPlayerPed()->GetForward().Heading(); -} - void CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2) { @@ -1517,7 +1414,7 @@ CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, floa } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } @@ -1543,7 +1440,7 @@ CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, floa void CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); float fStartX = x1 - 10.0f; float fStartY = y1 - 10.0f; float fEndX = x2 + 10.0f; @@ -1560,12 +1457,12 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2) for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, y2); } } @@ -1580,7 +1477,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1 if(pVehicle->m_scanCode != GetCurrentScanCode()) { pVehicle->m_scanCode = GetCurrentScanCode(); const CVector &vehiclePos = pVehicle->GetPosition(); - eCarMission carMission = pVehicle->AutoPilot.m_nCarMission; + uint8 carMission = pVehicle->AutoPilot.m_nCarMission; if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX && vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer && (carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE || @@ -1739,14 +1636,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range) } } +inline void +AddSteamsFromGround(CPtrList& list) +{ + CPtrNode* pNode = list.first; + while (pNode) { + ((CEntity*)pNode->item)->AddSteamsFromGround(nil); + pNode = pNode->next; + } +} + void CWorld::AddParticles(void) { for(int32 y = 0; y < NUMSECTORS_Y; y++) { for(int32 x = 0; x < NUMSECTORS_X; x++) { CSector *pSector = GetSector(x, y); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); } } } @@ -1758,44 +1665,52 @@ CWorld::ShutDown(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } +#ifndef FIX_BUGS pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif } - for(int32 i = 0; i < 4; i++) { - for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) { + for(int32 i = 0; i < NUM_LEVELS; i++) { + for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; // Maybe remove from world here? delete pEntity; } - GetBigBuildingList((eLevelName)i).Flush(); + ms_bigBuildingsList[i].Flush(); } for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) { CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); +#ifdef FIX_BUGS + pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); + pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) { sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y); pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -1840,19 +1755,19 @@ CWorld::ClearForRestart(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) { CVehicle *pVehicle = (CVehicle *)pNode->item; if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) { - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } } @@ -1885,7 +1800,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) float fBoundingBoxMinZ = pColModel->boundingBox.min.z; float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; if (fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z; - position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, + position.z = FindGroundZFor3DCoord(position.x, position.y, position.z + fHeight, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); @@ -1918,7 +1833,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) if(modelId == MI_BUOY) { bool bFound = true; const CVector &position = pEntity->GetPosition(); - float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y, + float fGroundZ = FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound); CColModel *pColModel = pEntity->GetColModel(); float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; @@ -1983,17 +1898,17 @@ CWorld::RemoveStaticObjects() CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -2015,10 +1930,11 @@ CWorld::Process(void) if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) { if (csObj->IsObject()) - RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped()); + RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepNonClippedInSeconds()); else { - csObj->bOffscreen = !csObj->GetIsOnScreen(); - RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen); + if (!csObj->bOffscreen) + csObj->bOffscreen = !csObj->GetIsOnScreen(); + RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepInSeconds(), !csObj->bOffscreen); } } csObj->ProcessControl(); @@ -2032,18 +1948,14 @@ CWorld::Process(void) } else { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { CEntity *movingEnt = (CEntity *)node->item; -#ifdef SQUEEZE_PERFORMANCE - if (movingEnt->bRemoveFromWorld) { - RemoveEntityInsteadOfProcessingIt(movingEnt); - } else -#endif - if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && + if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { if (movingEnt->IsObject()) - RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped()); + RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepNonClippedInSeconds()); else { - movingEnt->bOffscreen = !movingEnt->GetIsOnScreen(); - RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen); + if (!movingEnt->bOffscreen) + movingEnt->bOffscreen = !movingEnt->GetIsOnScreen(); + RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepInSeconds(), !movingEnt->bOffscreen); } } } @@ -2200,11 +2112,11 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); } } @@ -2262,7 +2174,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa if(!pEntity->GetIsStatic()) { float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f); CVector vecForceDir = - vecDistance * (fPower * pEntity->m_fMass / 14000.0f * fDamageMultiplier / + vecDistance * (fPower * pEntity->m_fMass / 1400.0f * fDamageMultiplier / Max(fMagnitude, 0.01f)); vecForceDir.z = Max(vecForceDir.z, 0.0f); if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f); diff --git a/src/core/World.h b/src/core/World.h index be32db20..81eb5d4c 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -3,6 +3,7 @@ #include "Game.h" #include "Lists.h" #include "PlayerInfo.h" +#include "Collision.h" /* Sectors span from -2400 to 1600 in x and -2000 to 2000 y. * With 80x80 sectors, each is 50x50 units. */ @@ -48,14 +49,9 @@ public: VALIDATE_SIZE(CSector, 0x28); -class CEntity; -struct CColPoint; -struct CColLine; -struct CStoredCollPoly; - class CWorld { - static CPtrList ms_bigBuildingsList[4]; + static CPtrList ms_bigBuildingsList[NUM_LEVELS]; static CPtrList ms_listMovingEntityPtrs; static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; static uint16 ms_nCurrentScanCode; @@ -178,15 +174,3 @@ public: }; extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; - -class CPlayerPed; -class CVehicle; -CPlayerPed *FindPlayerPed(void); -CVehicle *FindPlayerVehicle(void); -CVehicle *FindPlayerTrain(void); -CEntity *FindPlayerEntity(void); -CVector FindPlayerCoors(void); -CVector &FindPlayerSpeed(void); -const CVector &FindPlayerCentreOfWorld(int32 player); -const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); -float FindPlayerHeading(void); diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp index 69c7a796..db3577ad 100644 --- a/src/core/ZoneCull.cpp +++ b/src/core/ZoneCull.cpp @@ -11,8 +11,6 @@ #include "ZoneCull.h" #include "Zones.h" -//--MIAMI: done - int32 CCullZones::NumAttributeZones; CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES]; diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h index 8200b09a..d7780caf 100644 --- a/src/core/ZoneCull.h +++ b/src/core/ZoneCull.h @@ -17,12 +17,12 @@ enum eZoneAttribs struct CAttributeZone { - float minx; - float maxx; - float miny; - float maxy; - float minz; - float maxz; + int16 minx; + int16 maxx; + int16 miny; + int16 maxy; + int16 minz; + int16 maxz; int16 attributes; int16 wantedLevel; }; diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 8abe0f1e..85564f03 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -9,8 +9,6 @@ #include "World.h" #include "Timer.h" -//--MIAMI: file done - eLevelName CTheZones::m_CurrLevel; int16 CTheZones::FindIndex; @@ -209,6 +207,9 @@ CTheZones::PostZoneCreation(void) for(i = 1; i < TotalNumberOfNavigationZones; i++) InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]); InitialiseAudioZoneArray(); +#ifndef MASTER + CheckZonesForOverlap(); +#endif } void @@ -222,8 +223,7 @@ CTheZones::CheckZonesForOverlap(void) for(j = 1; j < TotalNumberOfInfoZones; j++) if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j])) - sprintf(str, "Info zone %s contains %s\n", - &InfoZoneArray[j].name, &InfoZoneArray[i].name); + sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name); } } @@ -542,7 +542,7 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, info->gangPedThreshold[8] += info->gangPedThreshold[7]; } -//--MIAMI: unused +// unused void CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity) { @@ -551,7 +551,7 @@ CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity) ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; } -//--MIAMI: unused +// unused void CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity) { diff --git a/src/core/Zones.h b/src/core/Zones.h index 5306d9f1..b987f009 100644 --- a/src/core/Zones.h +++ b/src/core/Zones.h @@ -103,8 +103,8 @@ public: static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity); static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup); static int16 FindAudioZone(CVector *pos); - static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &NavigationZoneArray[i]; } - static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; } + static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; } + static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; } static void AddZoneToAudioZoneArray(CZone *zone); static void InitialiseAudioZoneArray(void); static void SaveAllZones(uint8 *buffer, uint32 *length); diff --git a/src/core/common.h b/src/core/common.h index 9c81cf3b..7fdbdf69 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -11,17 +11,34 @@ #include <string.h> #include <math.h> -#if defined _WIN32 && defined WITHWINDOWS -#include <windows.h> +#if !defined RW_D3D9 && defined LIBRW +#undef WITHD3D +#undef WITHDINPUT +#endif + +#if (defined WITHD3D && !defined LIBRW) +#define WITHWINDOWS #endif -#if defined _WIN32 && defined WITHD3D +#if defined _WIN32 && defined WITHWINDOWS && !defined _INC_WINDOWS #include <windows.h> -#ifndef USE_D3D9 -#include <d3d8types.h> -#else -#include <d3d9types.h> #endif + +#ifdef WITHD3D + #ifdef LIBRW + #define WITH_D3D // librw includes d3d9 itself via this right now + #else + #ifndef USE_D3D9 + #include <d3d8types.h> + #else + #include <d3d9types.h> + #endif + #endif +#endif + +#ifdef WITHDINPUT +#define DIRECTINPUT_VERSION 0x0800 +#include <dinput.h> #endif #include <rwcore.h> @@ -52,14 +69,6 @@ #define rwVENDORID_ROCKSTAR 0x0253F2 -// Get rid of bullshit windows definitions, we're not running on an 8086 -#ifdef far -#undef far -#endif -#ifdef near -#undef near -#endif - #define Max(a,b) ((a) > (b) ? (a) : (b)) #define Min(a,b) ((a) < (b) ? (a) : (b)) @@ -73,21 +82,28 @@ typedef int16_t int16; typedef uint32_t uint32; typedef int32_t int32; typedef uintptr_t uintptr; +typedef intptr_t intptr; typedef uint64_t uint64; typedef int64_t int64; // hardcode ucs-2 typedef uint16_t wchar; +typedef uint8 bool8; +typedef uint16 bool16; +typedef uint32 bool32; + +#if defined(_MSC_VER) +typedef ptrdiff_t ssize_t; +#endif + #ifndef nil #define nil NULL #endif #include "config.h" -#ifdef PED_SKIN #include <rphanim.h> #include <rpskin.h> -#endif #ifdef __GNUC__ #define TYPEALIGN(n) __attribute__ ((aligned (n))) @@ -116,17 +132,43 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w) #include "skeleton.h" #include "Draw.h" -#define DEFAULT_SCREEN_WIDTH (640) -#define DEFAULT_SCREEN_HEIGHT (448) -#define DEFAULT_SCREEN_HEIGHT_PAL (512) -#define DEFAULT_SCREEN_HEIGHT_NTSC (448) +#if defined(PROPER_SCALING) + #ifdef FORCE_PC_SCALING + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (448) + #else + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (480) + #endif +#elif defined(GTA_PS2) + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (480) +#else //elif defined(GTA_PC) + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (448) +#endif + #define DEFAULT_ASPECT_RATIO (4.0f/3.0f) #define DEFAULT_VIEWWINDOW (0.7f) // game uses maximumWidth/Height, but this probably won't work // with RW windowed mode -#define SCREEN_WIDTH ((float)RsGlobal.width) +#ifdef GTA_PS2 + #ifdef GTA_PAL + #define SCREEN_WIDTH ((float)640) + #define SCREEN_HEIGHT ((float)512) + #else + #define SCREEN_WIDTH ((float)640) + #define SCREEN_HEIGHT ((float)448) + #endif +#else +#define SCREEN_WIDTH ((float)RsGlobal.width) #define SCREEN_HEIGHT ((float)RsGlobal.height) +#endif + +#define SCREEN_HEIGHT_PAL ((float)512) +#define SCREEN_HEIGHT_NTSC ((float)448) + #define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio()) #define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetScaledFOV() * 0.5f))) @@ -144,8 +186,13 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w) #ifdef ASPECT_RATIO_SCALE #define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) -extern float ScaleAndCenterX(float x); -#define SCALE_AND_CENTER_X(x) ScaleAndCenterX(x) +#define SCALE_AND_CENTER_X(x) ((SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH) ? (x) : (SCREEN_WIDTH - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)) / 2 + SCREEN_SCALE_X((x))) +#ifdef PROPER_SCALING + #ifndef FORCE_PC_SCALING + #undef SCREEN_SCALE_Y + #define SCREEN_SCALE_Y(a) CDraw::ScaleY(SCREEN_STRETCH_Y(a)) + #endif +#endif #else #define SCREEN_SCALE_AR(a) (a) #define SCALE_AND_CENTER_X(x) SCREEN_STRETCH_X(x) @@ -251,8 +298,14 @@ void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); -#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) +// Switch to enable development messages. +#if 1 +#define DEV(f, ...) +#else #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) +#endif + +#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) #define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) #define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) diff --git a/src/core/config.h b/src/core/config.h index e591a560..ef282b25 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -7,7 +7,7 @@ enum Config { MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, - MODELINFOSIZE = 6500, + MODELINFOSIZE = 6500, // 4900 on PS2 TXDSTORESIZE = 1385, COLSTORESIZE = 31, EXTRADIRSIZE = 256, @@ -36,7 +36,7 @@ enum Config { NUMDUMMIES = 2340, NUMAUDIOSCRIPTOBJECTS = 192, NUMCOLMODELS = 4400, - NUMCUTSCENEOBJECTS = 50, // does not exist in VC + NUMCUTSCENEOBJECTS = 50, // not a pool in VC NUMANIMBLOCKS = 35, NUMANIMATIONS = 450, @@ -146,10 +146,6 @@ enum Config { NUM_SHORTCUT_START_POINTS = 16 }; -// We'll use this once we're ready to become independent of the game -// Use it to mark bugs in the code that will prevent the game from working then -//#define STANDALONE - // We don't expect to compile for PS2 or Xbox // but it might be interesting for documentation purposes #define GTA_PC @@ -176,6 +172,19 @@ enum Config { #define FINAL #endif +// Version defines +#define GTAVC_PS2 400 +#define GTAVC_PC_10 410 +#define GTAVC_PC_11 411 +#define GTAVC_PC_JAP 412 +// TODO? maybe something for xbox or android? + +#define GTA_VERSION GTAVC_PC_11 + +// TODO(MIAMI): someone ought to find and check out uses of these defines: +//#define GTA3_STEAM_PATCH +//#define GTAVC_JP_PATCH + // quality of life fixes that should also be in FINAL #define NASTY_GAME // nasty game for all languages #define NO_CDCHECK @@ -183,24 +192,30 @@ enum Config { // those infamous texts #define DRAW_GAME_VERSION_TEXT +// Memory allocation and compression +// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet +//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices +//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed + #if defined GTA_PS2 # define GTA_PS2_STUFF # define RANDOMSPLASH +//# define USE_CUSTOM_ALLOCATOR # define VU_COLLISION #elif defined GTA_PC -//# define GTA3_STEAM_PATCH -//# define GTAVC_JP_PATCH # ifdef GTA_PS2_STUFF # define USE_PS2_RAND # define RANDOMSPLASH // use random splash as on PS2 # define PS2_MATFX # endif +# define PC_PLAYER_CONTROLS // mouse player/cam mode # define GTA_REPLAY +# define GTA_SCENE_EDIT #elif defined GTA_XBOX #endif #ifdef VU_COLLISION -#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code +#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code #endif #ifdef MASTER @@ -223,11 +238,16 @@ enum Config { # define TIMEBARS // print debug timers #endif -#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more +#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds. //#define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible +#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS #define FIX_HIGH_FPS_BUGS_ON_FRONTEND +#if defined(__LP64__) || defined(_WIN64) +#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build +#endif + // Just debug menu entries #ifdef DEBUGMENU #define RELOADABLES // some debug menu options to reload TXD files @@ -236,38 +256,29 @@ enum Config { // Rendering/display #define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios +#define PROPER_SCALING // use original DEFAULT_SCREEN_WIDTH/DEFAULT_SCREEN_HEIGHT from PS2 instead of PC(R* changed HEIGHT here to make radar look better, but broke other hud elements aspect ratio). #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time #define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync -//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +#define ANISOTROPIC_FILTERING // set all textures to max anisotropic filtering //#define USE_TEXTURE_POOL -//#define CUTSCENE_BORDERS_SWITCH #ifdef LIBRW -//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) -//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) -//#define SCREEN_DROPLETS // neo water droplets -//#define NEW_RENDERER // leeds-like world rendering, needs librw +#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) +#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) +#define SCREEN_DROPLETS // neo water droplets +#define NEW_RENDERER // leeds-like world rendering, needs librw #endif -//#define MULTISAMPLING // adds MSAA option TODO -#ifndef EXTENDED_COLOURFILTER -#undef SCREEN_DROPLETS // we need the front- (or back-)buffer for this effect -#endif -#ifndef EXTENDED_PIPELINES -#undef SCREEN_DROPLETS // we need neo.txd -#endif +#define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc) -#ifdef LIBRW -// these are not supported with librw yet -# undef MULTISAMPLING +#ifndef EXTENDED_COLOURFILTER +#undef SCREEN_DROPLETS // we need the backbuffer for this effect #endif // Water & Particle -#define PC_PARTICLE -//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 // #define PC_WATER #define WATER_CHEATS @@ -288,11 +299,13 @@ enum Config { #define WALLCLIMB_CHEAT #define REGISTER_START_BUTTON //#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls +#define BUTTON_ICONS // use textures to show controller buttons // Hud, frontend and radar -//#define BETA_SLIDING_TEXT #define PC_MENU +#define FIX_RADAR // use radar size from early version before R* broke it + #ifndef PC_MENU # define PS2_MENU //# define PS2_MENU_USEALLPAGEICONS @@ -300,26 +313,46 @@ enum Config { # define MAP_ENHANCEMENTS // Adding waypoint and better mouse support # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON -//#define CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS -#define LEGACY_MENU_OPTIONS +#define LEGACY_MENU_OPTIONS // i.e. frame sync(vsync) #define MUCH_SHORTER_OUTRO_SCREEN // #define XBOX_MESSAGE_SCREEN // Blue background, no "saved successfully press OK" screen etc. +# define CUSTOM_FRONTEND_OPTIONS + +# ifdef CUSTOM_FRONTEND_OPTIONS +# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable +# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +# define CUTSCENE_BORDERS_SWITCH +# define MULTISAMPLING // adds MSAA option +# define INVERT_LOOK_FOR_PAD // enable the hidden option +# endif +#endif // Script #define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#define SUPPORT_JAPANESE_SCRIPT +//#define SUPPORT_XBOX_SCRIPT +//#define SUPPORT_MOBILE_SCRIPT +#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT) +static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive"); +#endif +#ifdef PC_MENU //#define MISSION_REPLAY // mobile feature #endif //#define SIMPLIER_MISSIONS // apply simplifications from mobile #define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT -#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log +#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log #ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #define USE_BASIC_SCRIPT_DEBUG_OUTPUT #endif +#ifdef MASTER +#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT +#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT +#endif + // Replay //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) @@ -333,9 +366,6 @@ enum Config { #define CAMERA_PICKUP // Peds -#define PED_SKIN // support for skinned geometry on peds -#define ANIMATE_PED_COL_MODEL -#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle #define CANCELLABLE_CAR_ENTER // Camera @@ -344,13 +374,30 @@ enum Config { // Audio #define AUDIO_CACHE // cache sound lengths to speed up the cold boot -//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS +//#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds) +//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder +#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files + +#ifdef AUDIO_OPUS +#define AUDIO_OAL_USE_OPUS // enable support of opus files +//#define OPUS_AUDIO_PATHS // (not supported on VC yet) changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled) +//#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled) + +#ifndef AUDIO_OAL_USE_OPUS +#undef OPUS_AUDIO_PATHS +#undef OPUS_SFX +#endif + +#endif +#ifdef LIBRW +// these are not supported with librw yet +#endif +// IMG +#define BIG_IMG // allows to read larger img files //#define SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE #undef PS2_ALPHA_TEST #undef NO_ISLAND_LOADING - #define PC_PARTICLE - #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial #endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 7fb07fff..1798a60f 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -3,7 +3,7 @@ #include "rphanim.h" #include "rpskin.h" #include "rtbmp.h" -#ifndef LIBRW +#ifdef ANISOTROPIC_FILTERING #include "rpanisot.h" #endif @@ -63,6 +63,7 @@ #include "timebars.h" #include "GenericGameStorage.h" #include "MemoryCard.h" +#include "MemoryHeap.h" #include "SceneEdit.h" #include "debugmenu.h" #include "Clock.h" @@ -71,6 +72,7 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" +#include "VarConsole.h" GlobalScene Scene; @@ -88,7 +90,7 @@ bool gbModelViewer; bool gbShowTimebars; #endif -int32 frameCount; +volatile int32 frameCount; RwRGBA gColourTop; @@ -109,13 +111,32 @@ void TheGame(void); void DebugMenuPopulate(void); #endif +#ifndef FINAL +bool gbPrintMemoryUsage; +#endif + +#ifdef GTA_PS2 +#define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad +#define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad +#else +#define WANT_TO_LOAD FrontEndMenuManager.m_bWantToLoad +#define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad +#endif + #ifdef NEW_RENDERER bool gbNewRenderer; +#endif +#ifdef FIX_BUGS +// need to clear stencil for mblur fx. no idea why it works in the original game +// also for clearing out water rects in new renderer #define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL) #else #define CLEARMODE (rwCAMERACLEARZ) #endif +bool bDisplayNumOfAtomicsRendered = false; +bool bDisplayPosn = false; + void ValidateVersion() { @@ -381,7 +402,7 @@ PluginAttach(void) return FALSE; } -#ifndef LIBRW +#ifdef ANISOTROPIC_FILTERING RpAnisotPluginAttach(); #endif #ifdef EXTENDED_PIPELINES @@ -391,24 +412,87 @@ PluginAttach(void) return TRUE; } +#ifdef GTA_PS2 +#define NUM_PREALLOC_ATOMICS 1800 +#define NUM_PREALLOC_CLUMPS 80 +#define NUM_PREALLOC_FRAMES 2600 +#define NUM_PREALLOC_GEOMETRIES 850 +#define NUM_PREALLOC_TEXDICTS 121 +#define NUM_PREALLOC_TEXTURES 1700 +#define NUM_PREALLOC_MATERIALS 2600 +bool preAlloc; + +void +PreAllocateRwObjects(void) +{ + int i; + + PUSH_MEMID(MEMID_PRE_ALLOC); + void **tmp = new void*[0x8000]; + preAlloc = true; + + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + tmp[i] = RpAtomicCreate(); + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + RpAtomicDestroy((RpAtomic*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + tmp[i] = RpClumpCreate(); + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + RpClumpDestroy((RpClump*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + tmp[i] = RwFrameCreate(); + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + RwFrameDestroy((RwFrame*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + tmp[i] = RpGeometryCreate(0, 0, 0); + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + RpGeometryDestroy((RpGeometry*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + tmp[i] = RwTexDictionaryCreate(); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTexDictionaryDestroy((RwTexDictionary*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXTURES; i++) + tmp[i] = RwTextureCreate(RwRasterCreate(0, 0, 0, 0)); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTextureDestroy((RwTexture*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + tmp[i] = RpMaterialCreate(); + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + RpMaterialDestroy((RpMaterial*)tmp[i]); + + delete[] tmp; + preAlloc = false; + POP_MEMID(); +} +#endif + static RwBool Initialise3D(void *param) { + PUSH_MEMID(MEMID_RENDER); + +#ifndef MASTER + VarConsole.Add("Display number of atomics rendered", &bDisplayNumOfAtomicsRendered, true); + VarConsole.Add("Display posn and framerate", &bDisplayPosn, true); +#endif + if (RsRwInitialize(param)) { + POP_MEMID(); + #ifdef DEBUGMENU DebugMenuInit(); DebugMenuPopulate(); #endif // !DEBUGMENU - bool ret = CGame::InitialiseRenderWare(); -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeInit(); // need Scene.world for this -#endif -#ifdef SCREEN_DROPLETS - ScreenDroplets::InitDraw(); -#endif - return ret; + return CGame::InitialiseRenderWare(); } + POP_MEMID(); return (FALSE); } @@ -416,12 +500,6 @@ Initialise3D(void *param) static void Terminate3D(void) { -#ifdef SCREEN_DROPLETS - ScreenDroplets::Shutdown(); -#endif -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeShutdown(); -#endif CGame::ShutdownRenderWare(); #ifdef DEBUGMENU DebugMenuShutdown(); @@ -435,7 +513,6 @@ Terminate3D(void) CSprite2d splash; int splashTxdId = -1; -//--MIAMI: done CSprite2d* LoadSplash(const char *name) { @@ -481,7 +558,6 @@ DestroySplashScreen(void) splashTxdId = -1; } -//--MIAMI: done Const char* GetRandomSplashScreen(void) { @@ -524,7 +600,6 @@ ResetLoadingScreenBar() NumberOfChunksLoaded = 0.0f; } -//--MIAMI: done void LoadingScreen(const char *str1, const char *str2, const char *splashscreen) { @@ -611,7 +686,6 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) } } -//--MIAMI: done void LoadingIslandScreen(const char *levelName) { @@ -757,10 +831,188 @@ tZonePrint ZonePrint[] = }; #ifndef MASTER + +void +PrintMemoryUsage(void) +{ +// little hack +if(CPools::GetPtrNodePool() == nil) +return; + + // Style taken from LCS, modified for III +// CFont::SetFontStyle(FONT_PAGER); + CFont::SetFontStyle(FONT_BANK); + CFont::SetBackgroundOff(); + CFont::SetWrapx(640.0f); +// CFont::SetScale(0.5f, 0.75f); + CFont::SetScale(0.4f, 0.75f); + CFont::SetCentreOff(); + CFont::SetCentreSize(640.0f); + CFont::SetJustifyOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(200, 200, 200, 200)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetDropShadowPosition(0); + + float y; + +#ifdef USE_CUSTOM_ALLOCATOR + y = 24.0f; + sprintf(gString, "Total: %d blocks, %d bytes", gMainHeap.m_totalBlocksUsed, gMainHeap.m_totalMemUsed); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Game: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME), gMainHeap.GetMemoryUsed(MEMID_GAME)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "World: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_WORLD), gMainHeap.GetMemoryUsed(MEMID_WORLD)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Render: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDER), gMainHeap.GetMemoryUsed(MEMID_RENDER)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "PreAlloc: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PRE_ALLOC), gMainHeap.GetMemoryUsed(MEMID_PRE_ALLOC)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Default Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_DEF_MODELS), gMainHeap.GetMemoryUsed(MEMID_DEF_MODELS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_TEXTURES), gMainHeap.GetMemoryUsed(MEMID_TEXTURES)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streaming: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM), gMainHeap.GetMemoryUsed(MEMID_STREAM)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_MODELS), gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed LODs: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_LODS), gMainHeap.GetMemoryUsed(MEMID_STREAM_LODS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_TEXUTRES), gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_COLLISION), gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Ped Attr: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PED_ATTR), gMainHeap.GetMemoryUsed(MEMID_PED_ATTR)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_ANIMATION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Pools: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_POOLS), gMainHeap.GetMemoryUsed(MEMID_POOLS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_COLLISION), gMainHeap.GetMemoryUsed(MEMID_COLLISION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Game Process: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME_PROCESS), gMainHeap.GetMemoryUsed(MEMID_GAME_PROCESS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Script: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_SCRIPT), gMainHeap.GetMemoryUsed(MEMID_SCRIPT)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Cars: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_CARS), gMainHeap.GetMemoryUsed(MEMID_CARS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; +#endif + + y = 132.0f; + AsciiToUnicode("Pools usage:", gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "PtrNode: %d/%d", CPools::GetPtrNodePool()->GetNoOfUsedSpaces(), CPools::GetPtrNodePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "EntryInfoNode: %d/%d", CPools::GetEntryInfoNodePool()->GetNoOfUsedSpaces(), CPools::GetEntryInfoNodePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Ped: %d/%d", CPools::GetPedPool()->GetNoOfUsedSpaces(), CPools::GetPedPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Vehicle: %d/%d", CPools::GetVehiclePool()->GetNoOfUsedSpaces(), CPools::GetVehiclePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Building: %d/%d", CPools::GetBuildingPool()->GetNoOfUsedSpaces(), CPools::GetBuildingPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Treadable: %d/%d", CPools::GetTreadablePool()->GetNoOfUsedSpaces(), CPools::GetTreadablePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Object: %d/%d", CPools::GetObjectPool()->GetNoOfUsedSpaces(), CPools::GetObjectPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Dummy: %d/%d", CPools::GetDummyPool()->GetNoOfUsedSpaces(), CPools::GetDummyPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "AudioScriptObjects: %d/%d", CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces(), CPools::GetAudioScriptObjectPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; +} + void DisplayGameDebugText() { - static bool bDisplayPosn = false; static bool bDisplayCheatStr = false; // custom #ifndef FINAL @@ -769,8 +1021,10 @@ DisplayGameDebugText() TWEAKBOOL(bDisplayPosn); TWEAKBOOL(bDisplayCheatStr); } -#endif + if(gbPrintMemoryUsage) + PrintMemoryUsage(); +#endif char str[200]; wchar ustr[200]; @@ -882,18 +1136,19 @@ void MattRenderScene(void) { // this calls CMattRenderer::Render - CWorld::AdvanceCurrentScanCode(); + /// CWorld::AdvanceCurrentScanCode(); // CMattRenderer::ResetRenderStates - CRenderer::ClearForFrame(); + /// CRenderer::ClearForFrame(); // before ConstructRenderList // CClock::CalcEnvMapTimeMultiplicator + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater // CClock::ms_EnvMapTimeMultiplicator = 1.0f; // cWorldStream::ClearDynamics - CRenderer::ConstructRenderList(); + /// CRenderer::ConstructRenderList(); // before PreRender if(gbRenderWorld0) CRenderer::RenderWorld(0); // roads // CMattRenderer::ResetRenderStates - CRenderer::PreRender(); + /// CRenderer::PreRender(); // has to be called before BeginUpdate because of cutscene shadows CCoronas::RenderReflections(); if(gbRenderWorld1) CRenderer::RenderWorld(1); // opaque @@ -907,12 +1162,13 @@ if(gbRenderBoats) CRenderer::RenderBoats(); if(gbRenderFadingInUnderwaterEntities) CRenderer::RenderFadingInUnderwaterEntities(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); if(gbRenderWater) CRenderer::RenderTransparentWater(); if(gbRenderEverythingBarRoads) CRenderer::RenderEverythingBarRoads(); - // get env map here? + // seam fixer // moved this: // CRenderer::RenderFadingInEntities(); } @@ -930,8 +1186,7 @@ RenderScene_new(void) } // TODO -bool FredIsInFirstPersonCam(void) { return true; } // this seems to give the best result in all cases - +bool FredIsInFirstPersonCam(void) { return false; } void RenderEffects_new(void) { @@ -951,10 +1206,11 @@ if(gbRenderWorld2) if(gbRenderVehicles) CRenderer::RenderVehicles(); }else{ -if(gbRenderVehicles) - CRenderer::RenderVehicles(); + // flipped these two, seems to give the best result if(gbRenderWorld2) CRenderer::RenderWorld(2); // transparent +if(gbRenderVehicles) + CRenderer::RenderVehicles(); } // better render these after transparent world if(gbRenderFadingInEntities) @@ -1100,9 +1356,11 @@ Render2dStuff(void) MusicManager.DisplayRadioStationName(); TheConsole.Display(); +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) CSceneEdit::Draw(); else +#endif CHud::Draw(); CSpecialFX::Render2DFXs(); @@ -1126,14 +1384,12 @@ RenderMenus(void) { if (FrontEndMenuManager.m_bMenuActive) { -#ifdef PS2 - gMainHeap.PushMemId(_TODOCONST(17)); -#endif FrontEndMenuManager.DrawFrontEnd(); -#ifdef PS2 - gMainHeap.PopMemId(); -#endif } +#ifndef MASTER + else + VarConsole.Check(); +#endif } void @@ -1161,32 +1417,25 @@ Idle(void *arg) CSprite2d::InitPerFrame(); CFont::InitPerFrame(); + PUSH_MEMID(MEMID_GAME_PROCESS); CPointLights::InitPerFrame(); tbStartTimer(0, "CGame::Process"); CGame::Process(); tbEndTimer("CGame::Process"); + POP_MEMID(); tbStartTimer(0, "DMAudio.Service"); DMAudio.Service(); tbEndTimer("DMAudio.Service"); if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ -#ifdef PS2_MENU - TheMemoryCard.m_bWantToLoad = false; + WANT_TO_LOAD = false; FrontEndMenuManager.m_bWantToRestart = true; -#else - FrontEndMenuManager.m_bWantToRestart = true; - FrontEndMenuManager.m_bWantToLoad = false; -#endif return; } -#ifdef PS2_MENU - if ( FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad ) -#else - if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) { return; } @@ -1196,6 +1445,8 @@ Idle(void *arg) if(arg == nil) return; + PUSH_MEMID(MEMID_RENDER); + if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2) { // This is from SA, but it's nice for windowed mode @@ -1205,21 +1456,23 @@ Idle(void *arg) pos.y = SCREEN_HEIGHT / 2.0f; RsMouseSetPos(&pos); #endif -#ifdef NEW_RENDERER - if(!gbNewRenderer) -#endif -{ + tbStartTimer(0, "CnstrRenderList"); #ifdef PC_WATER CWaterLevel::PreCalcWaterGeometry(); #endif +#ifdef NEW_RENDERER + if(gbNewRenderer){ + CWorld::AdvanceCurrentScanCode(); // don't think this is even necessary + CRenderer::ClearForFrame(); + } +#endif CRenderer::ConstructRenderList(); tbEndTimer("CnstrRenderList"); tbStartTimer(0, "PreRender"); CRenderer::PreRender(); tbEndTimer("PreRender"); -} #ifdef FIX_BUGS RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); // TODO: temp? this fixes OpenGL render but there should be a better place for this @@ -1230,12 +1483,12 @@ Idle(void *arg) if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255)) - return; + goto popret; }else{ if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255)) - return; + goto popret; } DefinedState(); @@ -1283,7 +1536,7 @@ Idle(void *arg) CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) - return; + goto popret; } tbStartTimer(0, "RenderMenus"); @@ -1292,7 +1545,7 @@ Idle(void *arg) #ifdef PS2_MENU if ( TheMemoryCard.m_bWantToLoad ) - return; + goto popret; #endif tbStartTimer(0, "DoFade"); @@ -1312,8 +1565,13 @@ Idle(void *arg) DoRWStuffEndOfFrame(); + POP_MEMID(); // MEMID_RENDER + if(g_SlowMode) ProcessSlowMode(); + return; + +popret: POP_MEMID(); // MEMID_RENDER } void @@ -1466,28 +1724,24 @@ TheModelViewer(void) } #endif -#ifdef PS2 + +#ifdef GTA_PS2 void TheGame(void) { printf("Into TheGame!!!\n"); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(1)); -#endif + PUSH_MEMID(MEMID_GAME); // NB: not popped CTimer::Initialise(); -#ifdef GTA_PS2 - CGame::Initialise(); -#else CGame::Initialise("DATA\\GTA3.DAT"); -#endif Const char *splash = GetRandomSplashScreen(); // inlined here LoadingScreen("Starting Game", NULL, splash); #ifdef GTA_PS2 + // TODO(MIAMI): not checked yet if ( TheMemoryCard.CheckCardInserted(CARD_ONE) == CMemoryCard::NO_ERR_SUCCESS && TheMemoryCard.ChangeDirectory(CARD_ONE, TheMemoryCard.Cards[CARD_ONE].dir) && TheMemoryCard.FindMostRecentFileName(CARD_ONE, TheMemoryCard.MostRecentFile) == true @@ -1511,77 +1765,53 @@ void TheGame(void) while (true) { -#ifdef PS2 - if (TheMemoryCard.m_bWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToLoad) -#endif + if (FOUND_GAME_TO_LOAD) { Const char *splash1 = GetLevelSplashScreen(CGame::currLevel); LoadSplash(splash1); } -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = false; -#else - FrontEndMenuManager.m_bWantToLoad = false; -#endif + WANT_TO_LOAD = false; CTimer::Update(); -#ifdef PS2 - while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)) -#else - while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)) -#endif + while (!(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)) { CSprite2d::InitPerFrame(); CFont::InitPerFrame(); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(12)); -#endif - CPointLights::NumLights = 0; + PUSH_MEMID(MEMID_GAME_PROCESS) + CPointLights::InitPerFrame(); CGame::Process(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(); DMAudio.Service(); if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()) { -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = false; -#else - FrontEndMenuManager.m_bWantToLoad = false; -#endif + WANT_TO_LOAD = false; FrontEndMenuManager.m_bWantToRestart = true; break; } -#ifdef PS2 - if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) break; SetLightsWithTimeOfDayColour(Scene.world); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(15)); -#endif - // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. - if (!FrontEndMenuManager.m_bMenuActive || /*FrontEndMenuManager.m_bRenderGameInMenu == true && */TheCamera.GetScreenFadeStatus() != FADE_2 ) + PUSH_MEMID(MEMID_RENDER); + + CRenderer::ConstructRenderList(); + + if ((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true) && TheCamera.GetScreenFadeStatus() != FADE_2 ) { -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(11)); -#endif - CRenderer::ConstructRenderList(); CRenderer::PreRender(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); + // TODO(MIAMI): something ps2all specific + +#ifdef FIX_BUGS + // This has to be done BEFORE RwCameraBeginUpdate + RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); + RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); #endif if (CWeather::LightningFlash && !CCullZones::CamNoRain()) @@ -1590,8 +1820,10 @@ void TheGame(void) DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); DefinedState(); +#ifndef FIX_BUGS RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); +#endif RenderScene(); RenderDebugShit(); @@ -1608,21 +1840,14 @@ void TheGame(void) CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); - if (!RsCameraBeginUpdate(Scene.camera)) - break; + RsCameraBeginUpdate(Scene.camera); } RenderMenus(); -#ifdef PS2 - if (TheMemoryCard.m_bWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToLoad) -#endif + if (WANT_TO_LOAD) { -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(); // MEMID_RENDER break; } @@ -1639,9 +1864,7 @@ void TheGame(void) CTimer::Update(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(): // MEMID_RENDER if (g_SlowMode) ProcessSlowMode(); @@ -1653,24 +1876,12 @@ void TheGame(void) CGame::ShutDownForRestart(); CTimer::Stop(); -#ifdef PS2 - if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) { -#ifdef PS2 - if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (b_FoundRecentSavedGameWantToLoad) -#endif + if (FOUND_GAME_TO_LOAD) { FrontEndMenuManager.m_bWantToRestart = true; -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = true; -#else - FrontEndMenuManager.m_bWantToLoad = true; -#endif + WANT_TO_LOAD = true; } CGame::InitialiseWhenRestarting(); @@ -1689,11 +1900,7 @@ void TheGame(void) void SystemInit() { -#ifdef __MWERKS__ - mwInit(); -#endif - -#ifdef GTA_PS2 +#ifdef USE_CUSTOM_ALLOCATOR InitMemoryMgr(); #endif @@ -1702,7 +1909,7 @@ void SystemInit() char path[256]; - sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG"); + sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP241.IMG"); sceSifInitRpc(0); @@ -1716,14 +1923,10 @@ void SystemInit() CFileMgr::InitCdSystem(); sceFsReset(); -#endif - CFileMgr::Initialise(); - -#ifdef GTA_PS2 CFileMgr::InitCd(); - Char modulepath[256]; + char modulepath[256]; strcpy(modulepath, "cdrom0:\\"); strcat(modulepath, "SYSTEM\\"); @@ -1754,6 +1957,16 @@ void SystemInit() strcat(modulepath, "SYSTEM\\"); strcat(modulepath, "MCSERV.IRX"); LoadModule(modulepath); + + strcpy(modulepath, "cdrom0:\\"); + strcat(modulepath, "SYSTEM\\"); + strcat(modulepath, "CDSTREAM.IRX"); + LoadModule(modulepath); + + strcpy(modulepath, "cdrom0:\\"); + strcat(modulepath, "SYSTEM\\"); + strcat(modulepath, "SAMPMAN2.IRX"); + LoadModule(modulepath); #endif @@ -1783,6 +1996,7 @@ void SystemInit() FrontEndMenuManager.m_PrefsAllowNastyGame = true; #ifdef GTA_PS2 + // TODO(MIAMI): this code probably went elsewhere? int32 lang = sceScfGetLanguage(); if ( lang == SCE_ITALIAN_LANGUAGE ) FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; @@ -1810,59 +2024,160 @@ void SystemInit() // #endif -#ifdef PS2 +#ifdef GTA_PS2 TheMemoryCard.Init(); #endif } -void GameInit() +int VBlankCounter(int ca) { - if ( !gameAlreadyInitialised ) + frameCount++; + ExitHandler(); + return 0; +} + +// linked against by RW! +extern "C" void WaitVBlank(void) +{ + int32 startFrame = frameCount; + while(startFrame == frameCount); +} + +void GameInit(bool onlyRW) +{ + if(onlyRW) { #ifdef GTA_PS2 - char path[256]; - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "CDSTREAM.IRX"); - LoadModule(path); - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "SAMPMAN.IRX"); - LoadModule(path); - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "MUSICSTR.IRX"); - LoadModule(path); + Initialise3D(nil); +#else + Initialise3D(nil); //TODO: window parameter #endif - CdStreamInit(MAX_CDCHANNELS); - -#ifdef PS2 - Initialise3D(); //no params + gameAlreadyInitialised = true; + } + else + { + if ( !gameAlreadyInitialised ) +#ifdef GTA_PS2 + Initialise3D(nil); #else - //TODO + Initialise3D(nil); //TODO: window parameter #endif - + } + #ifdef GTA_PS2 char *files[] = { "\\ANIM\\CUTS.IMG;1", "\\ANIM\\CUTS.DIR;1", "\\ANIM\\PED.IFP;1", - "\\MODELS\\FRONTEND.TXD;1", + "\\MODELS\\FRONTEN1.TXD;1", + "\\MODELS\\FRONTEN2.TXD;1", "\\MODELS\\FONTS.TXD;1", "\\MODELS\\HUD.TXD;1", "\\MODELS\\PARTICLE.TXD;1", "\\MODELS\\MISC.TXD;1", "\\MODELS\\GENERIC.TXD;1", "\\MODELS\\GTA3.DIR;1", + // TODO: japanese? +#ifdef GTA_PAL "\\TEXT\\ENGLISH.GXT;1", "\\TEXT\\FRENCH.GXT;1", "\\TEXT\\GERMAN.GXT;1", "\\TEXT\\ITALIAN.GXT;1", "\\TEXT\\SPANISH.GXT;1", +#else + "\\TEXT\\AMERICAN.GXT;1", +#endif + "\\MODELS\\COLL\\GENERIC.COL;1", + "\\MODELS\\COLL\\VEHICLES.COL;1", + "\\MODELS\\COLL\\PEDS.COL;1", + "\\MODELS\\COLL\\WEAPONS.COL;1", + "\\MODELS\\GENERIC\\AIR_VLO.DFF;1", + "\\MODELS\\GENERIC\\WHEELS.DFF;1", + "\\MODELS\\GENERIC\\ARROW.DFF;1", + "\\MODELS\\GENERIC\\ZONECYLB.DFF;1", + "\\DATA\\HANDLING.CFG;1", + "\\DATA\\SURFACE.DAT;1", + "\\DATA\\PEDSTATS.DAT;1", + "\\DATA\\TIMECYC.DAT;1", + "\\DATA\\PARTICLE.CFG;1", + "\\DATA\\DEFAULT.DAT;1", + "\\DATA\\DEFAULT.IDE;1", + "\\DATA\\GTA_VC.DAT;1", + "\\DATA\\OBJECT.DAT;1", + "\\DATA\\MAP.ZON;1", + "\\DATA\\NAVIG.ZON;1", + "\\DATA\\INFO.ZON;1", + "\\DATA\\WATERPRO.DAT;1", + "\\DATA\\MAIN.SCM;1", + "\\DATA\\CARCOLS.DAT;1", + "\\DATA\\PED.DAT;1", + "\\DATA\\FISTFITE.DAT;1", + "\\DATA\\WEAPON.DAT;1", + "\\DATA\\PEDGRP.DAT;1", + "\\DATA\\PATHS\\FLIGHT.DAT;1", + "\\DATA\\PATHS\\FLIGHT2.DAT;1", + "\\DATA\\PATHS\\FLIGHT3.DAT;1", + "\\DATA\\PATHS\\SPATH0.DAT;1", + "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IDE;1", + "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IDE;1", + "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IDE;1", + "\\DATA\\MAPS\\DOCKS\\DOCKS.IDE;1", + "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IDE;1", + "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IDE;1", + "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IDE;1", + "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IDE;1", + "\\DATA\\MAPS\\GOLF\\GOLF.IDE;1", + "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IDE;1", + "\\DATA\\MAPS\\STARISL\\STARISL.IDE;1", + "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IDE;1", + "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IDE;1", + "\\DATA\\MAPS\\NBEACH\\NBEACH.IDE;1", + "\\DATA\\MAPS\\BANK\\BANK.IDE;1", + "\\DATA\\MAPS\\MALL\\MALL.IDE;1", + "\\DATA\\MAPS\\YACHT\\YACHT.IDE;1", + "\\DATA\\MAPS\\CISLAND\\CISLAND.IDE;1", + "\\DATA\\MAPS\\CLUB\\CLUB.IDE;1", + "\\DATA\\MAPS\\HOTEL\\HOTEL.IDE;1", + "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IDE;1", + "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IDE;1", + "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IDE;1", + "\\DATA\\MAPS\\HAITI\\HAITI.IDE;1", + "\\DATA\\MAPS\\HAITIN\\HAITIN.IDE;1", + "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IDE;1", + "\\DATA\\MAPS\\MANSION\\MANSION.IDE;1", + "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IDE;1", + "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IPL;1", + "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IPL;1", + "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IPL;1", + "\\DATA\\MAPS\\DOCKS\\DOCKS.IPL;1", + "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IPL;1", + "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IPL;1", + "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IPL;1", + "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IPL;1", + "\\DATA\\MAPS\\GOLF\\GOLF.IPL;1", + "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IPL;1", + "\\DATA\\MAPS\\STARISL\\STARISL.IPL;1", + "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IPL;1", + "\\DATA\\MAPS\\NBEACH\\NBEACH.IPL;1", + "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IPL;1", + "\\DATA\\MAPS\\CISLAND\\CISLAND.IPL;1", + "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IPL;1", + "\\DATA\\MAPS\\HAITI\\HAITI.IPL;1", + "\\DATA\\MAPS\\HAITIN\\HAITIN.IPL;1", + "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IPL;1", + "\\DATA\\MAPS\\BANK\\BANK.IPL;1", + "\\DATA\\MAPS\\MALL\\MALL.IPL;1", + "\\DATA\\MAPS\\YACHT\\YACHT.IPL;1", + "\\DATA\\MAPS\\CLUB\\CLUB.IPL;1", + "\\DATA\\MAPS\\HOTEL\\HOTEL.IPL;1", + "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IPL;1", + "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IPL;1", + "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IPL;1", + "\\DATA\\MAPS\\MANSION\\MANSION.IPL;1", + "\\DATA\\MAPS\\GENERIC.IDE;1", + "\\DATA\\OCCLU.IPL;1", + "\\DATA\\MAPS\\PATHS.IPL;1", "\\TXD\\LOADSC0.TXD;1", "\\TXD\\LOADSC1.TXD;1", "\\TXD\\LOADSC2.TXD;1", @@ -1877,92 +2192,16 @@ void GameInit() "\\TXD\\LOADSC11.TXD;1", "\\TXD\\LOADSC12.TXD;1", "\\TXD\\LOADSC13.TXD;1", - "\\TXD\\LOADSC14.TXD;1", - "\\TXD\\LOADSC15.TXD;1", - "\\TXD\\LOADSC16.TXD;1", - "\\TXD\\LOADSC17.TXD;1", - "\\TXD\\LOADSC18.TXD;1", - "\\TXD\\LOADSC19.TXD;1", - "\\TXD\\LOADSC20.TXD;1", - "\\TXD\\LOADSC21.TXD;1", - "\\TXD\\LOADSC22.TXD;1", - "\\TXD\\LOADSC23.TXD;1", - "\\TXD\\LOADSC24.TXD;1", - "\\TXD\\LOADSC25.TXD;1", - "\\TXD\\NEWS.TXD;1", - "\\MODELS\\COLL\\GENERIC.COL;1", - "\\MODELS\\COLL\\INDUST.COL;1", - "\\MODELS\\COLL\\COMMER.COL;1", - "\\MODELS\\COLL\\SUBURB.COL;1", - "\\MODELS\\COLL\\WEAPONS.COL;1", - "\\MODELS\\COLL\\VEHICLES.COL;1", - "\\MODELS\\COLL\\PEDS.COL;1", - "\\MODELS\\GENERIC\\AIR_VLO.DFF;1", - "\\MODELS\\GENERIC\\WEAPONS.DFF;1", - "\\MODELS\\GENERIC\\WHEELS.DFF;1", - "\\MODELS\\GENERIC\\LOPLYGUY.DFF;1", - "\\MODELS\\GENERIC\\ARROW.DFF;1", - "\\MODELS\\GENERIC\\ZONECYLB.DFF;1", - "\\DATA\\MAPS\\COMNTOP.IPL;1", - "\\DATA\\MAPS\\COMNBTM.IPL;1", - "\\DATA\\MAPS\\COMSE.IPL;1", - "\\DATA\\MAPS\\COMSW.IPL;1", - "\\DATA\\MAPS\\CULL.IPL;1", - "\\DATA\\MAPS\\INDUSTNE.IPL;1", - "\\DATA\\MAPS\\INDUSTNW.IPL;1", - "\\DATA\\MAPS\\INDUSTSE.IPL;1", - "\\DATA\\MAPS\\INDUSTSW.IPL;1", - "\\DATA\\MAPS\\SUBURBNE.IPL;1", - "\\DATA\\MAPS\\SUBURBSW.IPL;1", - "\\DATA\\MAPS\\OVERVIEW.IPL;1", - "\\DATA\\MAPS\\PROPS.IPL;1", - "\\DATA\\MAPS\\GTA3.IDE;1", - "\\DATA\\PATHS\\FLIGHT.DAT;1", - "\\DATA\\PATHS\\FLIGHT2.DAT;1", - "\\DATA\\PATHS\\FLIGHT3.DAT;1", - "\\DATA\\PATHS\\FLIGHT4.DAT;1", - "\\DATA\\PATHS\\TRACKS.DAT;1", - "\\DATA\\PATHS\\TRACKS2.DAT;1", - "\\DATA\\PATHS\\CHASE0.DAT;1", - "\\DATA\\PATHS\\CHASE1.DAT;1", - "\\DATA\\PATHS\\CHASE2.DAT;1", - "\\DATA\\PATHS\\CHASE3.DAT;1", - "\\DATA\\PATHS\\CHASE4.DAT;1", - "\\DATA\\PATHS\\CHASE5.DAT;1", - "\\DATA\\PATHS\\CHASE6.DAT;1", - "\\DATA\\PATHS\\CHASE7.DAT;1", - "\\DATA\\PATHS\\CHASE10.DAT;1", - "\\DATA\\PATHS\\CHASE11.DAT;1", - "\\DATA\\PATHS\\CHASE14.DAT;1", - "\\DATA\\PATHS\\CHASE16.DAT;1", - "\\DATA\\PATHS\\CHASE18.DAT;1", - "\\DATA\\PATHS\\CHASE19.DAT;1" + "\\TXD\\SPLASH1.TXD;1" }; for ( int32 i = 0; i < ARRAY_SIZE(files); i++ ) SkyRegisterFileOnCd([i]); #endif - CreateDebugFont(); - -#ifdef GTA_PS2 - AddIntcHandler(_TODOCONST(2), VBlankCounter, 0); -#endif - - CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO); - - CSprite2d::SetRecipNearClip(); - CTxdStore::Initialise(); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(9)); -#endif - CFont::Initialise(); - CHud::Initialise(); #ifdef GTA_PS2 - gMainHeap.PopMemId(); + AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0); #endif - - ValidateVersion(); #ifdef GTA_PS2 sceCdCLOCK rtc; @@ -1975,8 +2214,57 @@ void GameInit() //TODO: mysrand(); #endif - gameAlreadyInitialised = true; + // gameAlreadyInitialised = true; // why is this gone? + } +} + +int32 SkipAllMPEGs; +int32 gMemoryStickLoadOK; + +void PlayIntroMPEGs() +{ +#ifdef GTA_PS2 + if (gameAlreadyInitialised) + RpSkySuspend(); + + InitMPEGPlayer(); + + float skipTime; // wrong type, should be int +#ifdef GTA_PAL + if(gMemoryStickLoadOK) + skipTime = 2500000; + else + skipTime = 5300000; + + if(!SkipAllMPEGs) + PlayMPEG("cdrom0:\\MOVIES\\VCPAL.PSS;1", false, unk); + + if(!SkipAllMPEGs){ + SkipAllMPEGs = true; + PlayMPEG("cdrom0:\\MOVIES\\VICEPAL.PSS;1", true, 0); + } +#else + if(gMemoryStickLoadOK) + skipTime = 2750000; + else + skipTime = 5500000; + + if(!SkipAllMPEGs) + PlayMPEG("cdrom0:\\MOVIES\\VCNTSC.PSS;1", false, unk); + + if(!SkipAllMPEGs){ + SkipAllMPEGs = true; + PlayMPEG("cdrom0:\\MOVIES\\VICE.PSS;1", true, 0); } +#endif + + ShutdownMPEGPlayer(); + + if ( gameAlreadyInitialised ) + RpSkyResume(); +#else + //TODO +#endif } int @@ -1987,14 +2275,16 @@ main(int argc, char *argv[]) #endif SystemInit(); - -#ifdef PS2 + + if(RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR) + return 0; + +#ifdef GTA_PS2 int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE); - if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT - && r != CMemoryCard::ERR_OPENNOENTRY && r != CMemoryCard::ERR_NONE ) + if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT ) { - GameInit(); + GameInit(true); TheText.Unload(); TheText.Load(); @@ -2002,43 +2292,24 @@ main(int argc, char *argv[]) CFont::Initialise(); FrontEndMenuManager.DrawMemoryCardStartUpMenus(); - } + }else if(r == CMemoryCard::ERR_OPENNOENTRY) + gMemoryStickLoadOK = false; + else if(r == CMemoryCard::ERR_NONE) + gMemoryStickLoadOK = true; #endif - -#ifdef GTA_PS2 - { - if (gameAlreadyInitialised) - RpSkySuspend(); - - InitMPEGPlayer(); - - PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false); - if (CGame::frenchGame || CGame::germanGame) - PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true); - else - PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true); + PlayIntroMPEGs(); - ShutdownMPEGPlayer(); + GameInit(false); - if ( gameAlreadyInitialised ) - RpSkyResume(); - } -#else - //TODO -#endif + frameCount = 0; + while(frameCount < 100); - GameInit(); + CGame::InitialiseOnceAfterRW(); - if ( CGame::frenchGame || CGame::germanGame ) - LoadingScreen(NULL, version_name, "loadsc24"); - else - LoadingScreen(NULL, version_name, "loadsc0"); - - DMAudio.Initialise(); - TheGame(); - + +#if 0 // maybe ifndef FINAL or MASTER? CGame::ShutDown(); RwEngineStop(); @@ -2048,7 +2319,7 @@ main(int argc, char *argv[]) #ifdef __MWERKS__ mwExit(); // metrowerks shutdown #endif - +#endif return 0; } #endif diff --git a/src/core/main.h b/src/core/main.h index f428224e..9f181101 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -20,11 +20,16 @@ extern bool gbShowTimebars; #define gbShowTimebars false #endif +#ifndef FINAL +extern bool gbPrintMemoryUsage; +#endif + class CSprite2d; bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); +void PreAllocateRwObjects(void); void InitialiseGame(void); void LoadingScreen(const char *str1, const char *str2, const char *splashscreen); void LoadingIslandScreen(const char *levelName); @@ -39,6 +44,13 @@ void ResetLoadingScreenBar(void); void TheModelViewer(void); #endif +#ifdef LOAD_INI_SETTINGS +bool LoadINISettings(); +void SaveINISettings(); +void LoadINIControllerSettings(); +void SaveINIControllerSettings(); +#endif + #ifdef NEW_RENDERER extern bool gbNewRenderer; bool FredIsInFirstPersonCam(void); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index ebfa8de5..19697c37 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -1,7 +1,6 @@ #include <csignal> #define WITHWINDOWS #include "common.h" -#include "crossplatform.h" #include "Renderer.h" #include "Occlusion.h" #include "Credits.h" @@ -13,13 +12,10 @@ #include "Vehicle.h" #include "ModelIndices.h" #include "Streaming.h" -#include "PathFind.h" #include "Boat.h" #include "Heli.h" #include "Automobile.h" #include "Bike.h" -#include "Ped.h" -#include "Particle.h" #include "Console.h" #include "Debug.h" #include "Hud.h" @@ -29,13 +25,21 @@ #include "Radar.h" #include "debugmenu.h" #include "Frontend.h" -#include "Text.h" #include "WaterLevel.h" #include "main.h" #include "Script.h" #include "MBlur.h" #include "postfx.h" #include "custompipes.h" +#include "MemoryHeap.h" +#include "FileMgr.h" +#include "Camera.h" +#include "MBlur.h" +#include "ControllerConfig.h" + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +#include "crossplatform.h" +#endif #ifndef _WIN32 #include "assert.h" @@ -75,6 +79,452 @@ mysrand(unsigned int seed) myrand_seed = seed; } +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "frontendoption.h" + +void +CustomFrontendOptionsPopulate(void) +{ + // Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h + + // These work only if we have neo folder, so they're dynamically added +#ifdef EXTENDED_PIPELINES + const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; + const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + int fd = CFileMgr::OpenFile("neo/neo.txd","r"); + if (fd) { +#ifdef GRAPHICS_MENU_OPTIONS + FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); +#else + FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); +#endif + CFileMgr::CloseFile(fd); + } +#endif + +} +#endif + +#ifdef LOAD_INI_SETTINGS +#include "ini_parser.hpp" + +linb::ini cfg; +bool ReadIniIfExists(const char *cat, const char *key, uint32 *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtoul(value, &endPtr, 0); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, bool *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtoul(value, &endPtr, 0); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, int32 *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtol(value, &endPtr, 0); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, int8 *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtol(value, &endPtr, 0); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, float *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + if (value && value[0] != '\xBA') { + *out = atof(value); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, char *out, int size) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + if (value && value[0] != '\xBA') { + strncpy(out, value, size); + return true; + } + return false; +} + +void StoreIni(const char *cat, const char *key, uint32 val) +{ + char temp[10]; +sprintf(temp, "%u", val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, uint8 val) +{ + char temp[10]; + sprintf(temp, "%u", (uint32)val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, int32 val) +{ + char temp[10]; + sprintf(temp, "%d", val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, int8 val) +{ + char temp[10]; + sprintf(temp, "%d", (int32)val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, float val) +{ + char temp[10]; + sprintf(temp, "%f", val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, char *val, int size) +{ + cfg.set(cat, key, val); +} + +const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN", + "PED_SNIPER_ZOOM_OUT", "VEHICLE_ENTER_EXIT", "CAMERA_CHANGE_VIEW_ALL_SITUATIONS", "PED_JUMPING", "PED_SPRINT", "PED_LOOKBEHIND", "PED_DUCK", "PED_ANSWER_PHONE", +#ifdef BIND_VEHICLE_FIREWEAPON + "VEHICLE_FIREWEAPON", +#endif + "VEHICLE_ACCELERATE", "VEHICLE_BRAKE", "VEHICLE_CHANGE_RADIO_STATION", "VEHICLE_HORN", "TOGGLE_SUBMISSIONS", "VEHICLE_HANDBRAKE", "PED_1RST_PERSON_LOOK_LEFT", + "PED_1RST_PERSON_LOOK_RIGHT", "VEHICLE_LOOKLEFT", "VEHICLE_LOOKRIGHT", "VEHICLE_LOOKBEHIND", "VEHICLE_TURRETLEFT", "VEHICLE_TURRETRIGHT", "VEHICLE_TURRETUP", "VEHICLE_TURRETDOWN", + "PED_CYCLE_TARGET_LEFT", "PED_CYCLE_TARGET_RIGHT", "PED_CENTER_CAMERA_BEHIND_PLAYER", "PED_LOCK_TARGET", "NETWORK_TALK", "PED_1RST_PERSON_LOOK_UP", "PED_1RST_PERSON_LOOK_DOWN", + "_CONTROLLERACTION_36", "TOGGLE_DPAD", "SWITCH_DEBUG_CAM_ON", "TAKE_SCREEN_SHOT", "SHOW_MOUSE_POINTER_TOGGLE", "UNKNOWN_ACTION" }; + +const char *iniControllerTypes[] = { "kbd:", "2ndKbd:", "mouse:", "joy:" }; + +const char *iniMouseButtons[] = {"LEFT","MIDDLE","RIGHT","WHLUP","WHLDOWN","X1","X2"}; + +const char *iniKeyboardButtons[] = {"ESC","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12", + "INS","DEL","HOME","END","PGUP","PGDN","UP","DOWN","LEFT","RIGHT","DIVIDE","TIMES","PLUS","MINUS","PADDEL", + "PADEND","PADDOWN","PADPGDN","PADLEFT","PAD5","NUMLOCK","PADRIGHT","PADHOME","PADUP","PADPGUP","PADINS", + "PADENTER", "SCROLL","PAUSE","BACKSP","TAB","CAPSLK","ENTER","LSHIFT","RSHIFT","SHIFT","LCTRL","RCTRL","LALT", + "RALT", "LWIN", "RWIN", "APPS", "NULL"}; + +void LoadINIControllerSettings() +{ +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + ReadIniIfExists("Controller", "JoystickName", gSelectedJoystickName, 128); +#endif + // force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that + if (!ReadIniIfExists("Controller", "PadButtonsInited", &ControlsManager.ms_padButtonsInited)) { + ControlsManager.ms_padButtonsInited = cfg.category_size("Bindings") != 0 ? 16 : 0; + } + + for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) { + char value[128]; + if (ReadIniIfExists("Bindings", iniControllerActions[i], value, 128)) { + for (int32 j = 0; j < MAX_CONTROLLERTYPES; j++){ + ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)i, (eControllerType)j); + } + + for (char *binding = strtok(value,", "); binding != nil; binding = strtok(nil, ", ")) { + int contType = -1; + for (int32 k = 0; k < ARRAY_SIZE(iniControllerTypes); k++) { + int len = strlen(iniControllerTypes[k]); + if (strncmp(binding, iniControllerTypes[k], len) == 0) { + contType = k; + binding += len; + break; + } + } + if (contType == -1) + continue; + + int contKey; + if (contType == JOYSTICK) { + char *temp; + contKey = strtol(binding, &temp, 0); + + } else if (contType == KEYBOARD || contType == OPTIONAL_EXTRA) { + if (strlen(binding) == 1) { + contKey = binding[0]; + } else if(strcmp(binding, "SPC") == 0) { + contKey = ' '; + } else { + for (int32 k = 0; k < ARRAY_SIZE(iniKeyboardButtons); k++) { + if(strcmp(binding, iniKeyboardButtons[k]) == 0) { + contKey = 1000 + k; + break; + } + } + } + } else if (contType == MOUSE) { + for (int32 k = 0; k < ARRAY_SIZE(iniMouseButtons); k++) { + if(strcmp(binding, iniMouseButtons[k]) == 0) { + contKey = 1 + k; + break; + } + } + } + + ControlsManager.SetControllerKeyAssociatedWithAction((e_ControllerAction)i, contKey, (eControllerType)contType); + } + } + } +} + +void SaveINIControllerSettings() +{ + for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) { + char value[128] = { '\0' }; + + // upper limit should've been GetNumOfSettingsForAction(i), but sadly even R* doesn't use it's own system correctly, and there are gaps between orders. + for (int32 j = SETORDER_1; j < MAX_SETORDERS; j++){ + + // We respect the m_ContSetOrder, and join/implode/order the bindings according to that; using comma as seperator. + for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++){ + if (ControlsManager.m_aSettings[i][k].m_ContSetOrder == j) { + char next[32]; + if (k == JOYSTICK) { + snprintf(next, 32, "%s%d,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key); + + } else if (k == KEYBOARD || k == OPTIONAL_EXTRA) { + if (ControlsManager.m_aSettings[i][k].m_Key == ' ') + snprintf(next, 32, "%sSPC,", iniControllerTypes[k]); + else if (ControlsManager.m_aSettings[i][k].m_Key < 256) + snprintf(next, 32, "%s%c,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key); + else + snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniKeyboardButtons[ControlsManager.m_aSettings[i][k].m_Key - 1000]); + + } else if (k == MOUSE) { + snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniMouseButtons[ControlsManager.m_aSettings[i][k].m_Key - 1]); + } + strcat(value, next); + break; + } + } + } + int len = strlen(value); + if (len > 0) + value[len - 1] = '\0'; // to remove comma + + StoreIni("Bindings", iniControllerActions[i], value, 128); + } + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + StoreIni("Controller", "JoystickName", gSelectedJoystickName, 128); +#endif + StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited); + cfg.write_file("reVC.ini"); +} + +bool LoadINISettings() +{ + if (!cfg.load_file("reVC.ini")) + return false; + +#ifdef IMPROVED_VIDEOMODE + ReadIniIfExists("VideoMode", "Width", &FrontEndMenuManager.m_nPrefsWidth); + ReadIniIfExists("VideoMode", "Height", &FrontEndMenuManager.m_nPrefsHeight); + ReadIniIfExists("VideoMode", "Depth", &FrontEndMenuManager.m_nPrefsDepth); + ReadIniIfExists("VideoMode", "Subsystem", &FrontEndMenuManager.m_nPrefsSubsystem); + // Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section +#else + ReadIniIfExists("Graphics", "VideoMode", &FrontEndMenuManager.m_nDisplayVideoMode); +#endif + ReadIniIfExists("Controller", "HeadBob1stPerson", &TheCamera.m_bHeadBob); + ReadIniIfExists("Controller", "HorizantalMouseSens", &TheCamera.m_fMouseAccelHorzntl); + ReadIniIfExists("Controller", "InvertMouseVertically", &MousePointerStateHelper.bInvertVertically); + ReadIniIfExists("Controller", "DisableMouseSteering", &CVehicle::m_bDisableMouseSteering); + ReadIniIfExists("Audio", "SfxVolume", &FrontEndMenuManager.m_PrefsSfxVolume); + ReadIniIfExists("Audio", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume); + ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume); + ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation); + ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers); + ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); + ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA); + ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness); + ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD); + ReadIniIfExists("Display", "Subtitles", &FrontEndMenuManager.m_PrefsShowSubtitles); + ReadIniIfExists("Graphics", "AspectRatio", &FrontEndMenuManager.m_PrefsUseWideScreen); + ReadIniIfExists("Graphics", "FrameLimiter", &FrontEndMenuManager.m_PrefsFrameLimiter); +#ifdef LEGACY_MENU_OPTIONS + ReadIniIfExists("Graphics", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp); + ReadIniIfExists("Graphics", "Trails", &CMBlur::BlurOn); +#endif + ReadIniIfExists("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256); + ReadIniIfExists("Controller", "Method", &FrontEndMenuManager.m_ControlMethod); + ReadIniIfExists("General", "Language", &FrontEndMenuManager.m_PrefsLanguage); + ReadIniIfExists("Display", "ShowHud", &FrontEndMenuManager.m_PrefsShowHud); + ReadIniIfExists("Display", "RadarMode", &FrontEndMenuManager.m_PrefsRadarMode); + ReadIniIfExists("Display", "ShowLegends", &FrontEndMenuManager.m_PrefsShowLegends); + +#ifdef EXTENDED_COLOURFILTER + ReadIniIfExists("CustomPipesValues", "PostFXIntensity", &CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + ReadIniIfExists("CustomPipesValues", "NeoVehicleShininess", &CustomPipes::VehicleShininess); + ReadIniIfExists("CustomPipesValues", "NeoVehicleSpecularity", &CustomPipes::VehicleSpecularity); + ReadIniIfExists("CustomPipesValues", "RimlightMult", &CustomPipes::RimlightMult); + ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult); + ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult); +#endif + +#ifdef PROPER_SCALING + ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling); +#endif +#ifdef FIX_RADAR + ReadIniIfExists("Draw", "FixRadar", &CDraw::ms_bFixRadar); +#endif +#ifdef FIX_SPRITES + ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites); +#endif + +#ifdef CUSTOM_FRONTEND_OPTIONS + bool migrate = cfg.category_size("FrontendOptions") != 0; + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + // CFO check + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // CFO only supports saving uint8 right now + + // Migrate from old .ini to new .ini + if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value)) + cfg.remove("FrontendOptions", option.m_CFO->save); + else + ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value); + + if (option.m_Action == MENUACTION_CFO_SELECT) { + option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value; + } + } + } + } +#endif + + return true; +} + +void SaveINISettings() +{ +#ifdef IMPROVED_VIDEOMODE + StoreIni("VideoMode", "Width", FrontEndMenuManager.m_nPrefsWidth); + StoreIni("VideoMode", "Height", FrontEndMenuManager.m_nPrefsHeight); + StoreIni("VideoMode", "Depth", FrontEndMenuManager.m_nPrefsDepth); + StoreIni("VideoMode", "Subsystem", FrontEndMenuManager.m_nPrefsSubsystem); + // Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section +#else + StoreIni("Graphics", "VideoMode", FrontEndMenuManager.m_nDisplayVideoMode); +#endif + StoreIni("Controller", "HeadBob1stPerson", TheCamera.m_bHeadBob); + StoreIni("Controller", "HorizantalMouseSens", TheCamera.m_fMouseAccelHorzntl); + StoreIni("Controller", "InvertMouseVertically", MousePointerStateHelper.bInvertVertically); + StoreIni("Controller", "DisableMouseSteering", CVehicle::m_bDisableMouseSteering); + StoreIni("Audio", "SfxVolume", FrontEndMenuManager.m_PrefsSfxVolume); + StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume); + StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume); + StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation); + StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers); + StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); + StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA); + StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness); + StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD); + StoreIni("Display", "Subtitles", FrontEndMenuManager.m_PrefsShowSubtitles); + StoreIni("Graphics", "AspectRatio", FrontEndMenuManager.m_PrefsUseWideScreen); +#ifdef LEGACY_MENU_OPTIONS + StoreIni("Graphics", "VSync", FrontEndMenuManager.m_PrefsVsyncDisp); + StoreIni("Graphics", "Trails", CMBlur::BlurOn); +#endif + StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter); + StoreIni("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256); + StoreIni("Controller", "Method", FrontEndMenuManager.m_ControlMethod); + StoreIni("General", "Language", FrontEndMenuManager.m_PrefsLanguage); + StoreIni("Display", "ShowHud", FrontEndMenuManager.m_PrefsShowHud); + StoreIni("Display", "RadarMode", FrontEndMenuManager.m_PrefsRadarMode); + StoreIni("Display", "ShowLegends", FrontEndMenuManager.m_PrefsShowLegends); + +#ifdef EXTENDED_COLOURFILTER + StoreIni("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + StoreIni("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess); + StoreIni("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity); + StoreIni("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult); + StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); + StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); +#endif + StoreIni("Rendering", "BackfaceCulling", gBackfaceCulling); + +#ifdef PROPER_SCALING + StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling); +#endif +#ifdef FIX_RADAR + StoreIni("Draw", "FixRadar", CDraw::ms_bFixRadar); +#endif +#ifdef FIX_SPRITES + StoreIni("Draw", "FixSprites", CDraw::ms_bFixSprites); +#endif +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // Beware: CFO only supports saving uint8 right now + StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value); + } + } + } +#endif + + cfg.write_file("reVC.ini"); +} + +#endif + #ifdef DEBUGMENU void WeaponCheat1(); void WeaponCheat2(); @@ -256,7 +706,7 @@ void CTweakVars::Add(CTweakVar *var) TweakVarsListSize = 0; } if(TweakVarsListSize > 63) - TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var)); + TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(*var)); TweakVarsList[TweakVarsListSize++] = var; // TweakVarsList.push_back(var); @@ -456,7 +906,7 @@ extern bool gbRenderWorld2; #endif DebugMenuAddVar("Render", "Drunkness", &CMBlur::Drunkness, nil, 0.05f, 0, 1.0f); #ifndef MASTER - DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil); + DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil); #endif #ifdef EXTENDED_PIPELINES static const char *vehpipenames[] = { "MatFX", "Neo" }; @@ -483,9 +933,28 @@ extern bool gbRenderWorld2; DebugMenuAddVarBool8("Render", "Don't render Vehicles", &gbDontRenderVehicles, nil); DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil); + +#ifdef PROPER_SCALING + DebugMenuAddVarBool8("Draw", "Proper Scaling", &CDraw::ms_bProperScaling, nil); +#endif +#ifdef FIX_RADAR + DebugMenuAddVarBool8("Draw", "Fix Radar", &CDraw::ms_bFixRadar, nil); +#endif +#ifdef FIX_SPRITES + DebugMenuAddVarBool8("Draw", "Fix Sprites", &CDraw::ms_bFixSprites, nil); +#endif + +#ifndef FINAL + DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil); +#ifdef USE_CUSTOM_ALLOCATOR + DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap); +#endif +#endif DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil); +#ifdef GTA_SCENE_EDIT DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); +#endif #ifdef MAP_ENHANCEMENTS DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint); #endif diff --git a/src/core/templates.h b/src/core/templates.h index 9f5bd5ea..7bc85ee6 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -1,75 +1,93 @@ #pragma once -template<typename T, int n> +template<typename T, int32 n> class CStore { public: - int allocPtr; + int32 allocPtr; T store[n]; - T *alloc(void){ - if(this->allocPtr >= n){ + T *Alloc(void){ + if(allocPtr >= n){ printf("Size of this thing:%d needs increasing\n", n); assert(0); } - return &this->store[this->allocPtr++]; + return &store[allocPtr++]; } - void clear(void){ - this->allocPtr = 0; + void Clear(void){ + allocPtr = 0; } - int getIndex(T *item){ - assert(item >= &this->store[0]); - assert(item < &this->store[n]); - return item - this->store; + int32 GetIndex(T *item){ + assert(item >= &store[0]); + assert(item < &store[n]); + return item - store; } - T *getItem(int index){ + T *GetItem(int32 index){ assert(index >= 0); assert(index < n); - return &this->store[index]; + return &store[index]; } }; +#define POOLFLAG_ID 0x7f +#define POOLFLAG_ISFREE 0x80 + template<typename T, typename U = T> class CPool { U *m_entries; - union Flags { - struct { - uint8 id : 7; - uint8 free : 1; - }; - uint8 u; - } *m_flags; - int m_size; - int m_allocPtr; + uint8 *m_flags; + int32 m_size; + int32 m_allocPtr; public: - // TODO(MIAMI): remove ctor without name argument - CPool(int size, const char *name){ - // TODO: use new here - m_entries = (U*)malloc(sizeof(U)*size); - m_flags = (Flags*)malloc(sizeof(Flags)*size); + CPool(int32 size, const char *name){ + m_entries = (U*)new uint8[sizeof(U)*size]; + m_flags = new uint8[size]; m_size = size; m_allocPtr = -1; for(int i = 0; i < size; i++){ - m_flags[i].id = 0; - m_flags[i].free = 1; + SetId(i, 0); + SetIsFree(i, true); } } + + int GetId(int i) const + { + return m_flags[i] & POOLFLAG_ID; + } + + bool GetIsFree(int i) const + { + return !!(m_flags[i] & POOLFLAG_ISFREE); + } + + void SetId(int i, int id) + { + m_flags[i] = (m_flags[i] & POOLFLAG_ISFREE) | (id & POOLFLAG_ID); + } + + void SetIsFree(int i, bool isFree) + { + if (isFree) + m_flags[i] |= POOLFLAG_ISFREE; + else + m_flags[i] &= ~POOLFLAG_ISFREE; + } ~CPool() { Flush(); } void Flush() { if (m_size > 0) { - free(m_entries); - free(m_flags); + delete[] (uint8*)m_entries; + delete[] m_flags; m_entries = nil; m_flags = nil; m_size = 0; m_allocPtr = 0; } } - int GetSize(void) const { return m_size; } + int32 GetSize(void) const { return m_size; } T *New(void){ bool wrapped = false; do @@ -88,61 +106,67 @@ public: m_allocPtr = 0; } #endif - while(!m_flags[m_allocPtr].free); - m_flags[m_allocPtr].free = 0; - m_flags[m_allocPtr].id++; + while(!GetIsFree(m_allocPtr)); + SetIsFree(m_allocPtr, false); + SetId(m_allocPtr, GetId(m_allocPtr)+1); return (T*)&m_entries[m_allocPtr]; } - T *New(int handle){ + T *New(int32 handle){ T *entry = (T*)&m_entries[handle>>8]; SetNotFreeAt(handle); return entry; } - void SetNotFreeAt(int handle){ + void SetNotFreeAt(int32 handle){ int idx = handle>>8; - m_flags[idx].free = 0; - m_flags[idx].id = handle & 0x7F; + SetIsFree(idx, false); + SetId(idx, handle & POOLFLAG_ID); for(m_allocPtr = 0; m_allocPtr < m_size; m_allocPtr++) - if(m_flags[m_allocPtr].free) + if(GetIsFree(m_allocPtr)) return; } void Delete(T *entry){ int i = GetJustIndex(entry); - m_flags[i].free = 1; + SetIsFree(i, true); if(i < m_allocPtr) m_allocPtr = i; } T *GetSlot(int i){ - return m_flags[i].free ? nil : (T*)&m_entries[i]; + return GetIsFree(i) ? nil : (T*)&m_entries[i]; } T *GetAt(int handle){ #ifdef FIX_BUGS if (handle == -1) return nil; #endif - return m_flags[handle>>8].u == (handle & 0xFF) ? + return m_flags[handle>>8] == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } - int GetIndex(T *entry){ - int i = GetJustIndex(entry); - return m_flags[i].u + (i<<8); + int32 GetIndex(T* entry) { + int i = GetJustIndex_NoFreeAssert(entry); + return m_flags[i] + (i<<8); + } + int32 GetJustIndex(T* entry) { + int index = GetJustIndex_NoFreeAssert(entry); + assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required + assert(!GetIsFree(index)); + return index; } - int GetJustIndex(T *entry){ - // TODO: the cast is unsafe - return (int)((U*)entry - m_entries); + int32 GetJustIndex_NoFreeAssert(T* entry) { + int index = ((U*)entry - m_entries); + // Please don't add unsafe assert here, because at least one func. use this to check if entity is ped or vehicle. + return index; } - int GetNoOfUsedSpaces(void) const { + int32 GetNoOfUsedSpaces(void) const { int i; int n = 0; for(i = 0; i < m_size; i++) - if(!m_flags[i].free) + if(!GetIsFree(i)) n++; return n; } - bool IsFreeSlot(int i) { return !!m_flags[i].free; } void ClearStorage(uint8 *&flags, U *&entries){ - free(flags); - free(entries); + delete[] flags; + delete[] (uint8*)entries; flags = nil; entries = nil; } @@ -150,14 +174,14 @@ public: void CopyBack(uint8 *&flags, U *&entries){ memcpy(m_flags, flags, sizeof(uint8)*m_size); memcpy(m_entries, entries, sizeof(U)*m_size); - debug("Size copied:%d (%d)\n", sizeof(U)*m_size, sizeof(Flags)*m_size); + debug("Size copied:%d (%d)\n", sizeof(U)*m_size, m_size); m_allocPtr = 0; ClearStorage(flags, entries); debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } void Store(uint8 *&flags, U *&entries){ - flags = (uint8*)malloc(sizeof(uint8)*m_size); - entries = (U*)malloc(sizeof(U)*m_size); + flags = (uint8*)new uint8[sizeof(uint8)*m_size]; + entries = (U*)new uint8[sizeof(U)*m_size]; memcpy(flags, m_flags, sizeof(uint8)*m_size); memcpy(entries, m_entries, sizeof(U)*m_size); debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ @@ -236,7 +260,7 @@ public: link->Remove(); // remove from list freeHead.Insert(link); // insert into free list } - int Count(void){ + int32 Count(void){ int n = 0; CLink<T> *lnk; for(lnk = head.next; lnk != &tail; lnk = lnk->next) diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp index 544e24a6..9878b595 100644 --- a/src/entities/Dummy.cpp +++ b/src/entities/Dummy.cpp @@ -4,8 +4,6 @@ #include "World.h" #include "Dummy.h" -// --MIAMI: file done - void *CDummy::operator new(size_t sz) { return CPools::GetDummyPool()->New(); } void CDummy::operator delete(void *p, size_t sz) { CPools::GetDummyPool()->Delete((CDummy*)p); } @@ -58,7 +56,7 @@ IsDummyPointerValid(CDummy* pDummy) { if (!pDummy) return false; - int index = CPools::GetDummyPool()->GetJustIndex(pDummy); + int index = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert(pDummy); #ifdef FIX_BUGS if (index < 0 || index >= CPools::GetDummyPool()->GetSize()) #else diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 2285c93f..6204b748 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -4,36 +4,27 @@ #include "RwHelper.h" #include "ModelIndices.h" #include "Timer.h" -#include "Placeable.h" #include "Entity.h" #include "Object.h" -#include "ParticleObject.h" -#include "Lights.h" #include "World.h" #include "Camera.h" #include "Glass.h" -#include "Clock.h" #include "Weather.h" #include "Timecycle.h" -#include "Bridge.h" #include "TrafficLights.h" #include "Coronas.h" #include "PointLights.h" #include "Shadows.h" #include "Pickups.h" #include "SpecialFX.h" -#include "References.h" #include "TxdStore.h" #include "Zones.h" +#include "MemoryHeap.h" #include "Bones.h" #include "Debug.h" -#include "Renderer.h" #include "Ped.h" #include "Dummy.h" #include "WindModifiers.h" -#include "Occlusion.h" - -//--MIAMI: file done int gBuildings; @@ -101,186 +92,6 @@ CEntity::~CEntity(void) } void -CEntity::GetBoundCentre(CVector &out) -{ - out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center; -}; - -bool -CEntity::GetIsTouching(CVector const ¢er, float radius) -{ - return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr(); -} - -bool -CEntity::GetIsOnScreen(void) -{ - return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(), - &TheCamera.GetCameraMatrix()); -} - -bool -CEntity::GetIsOnScreenComplex(void) -{ - RwV3d boundBox[8]; - - if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix())) - return true; - - CRect rect = GetBoundRect(); - CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); - float z = GetPosition().z; - float minz = z + colmodel->boundingBox.min.z; - float maxz = z + colmodel->boundingBox.max.z; - boundBox[0].x = rect.left; - boundBox[0].y = rect.bottom; - boundBox[0].z = minz; - boundBox[1].x = rect.left; - boundBox[1].y = rect.top; - boundBox[1].z = minz; - boundBox[2].x = rect.right; - boundBox[2].y = rect.bottom; - boundBox[2].z = minz; - boundBox[3].x = rect.right; - boundBox[3].y = rect.top; - boundBox[3].z = minz; - boundBox[4].x = rect.left; - boundBox[4].y = rect.bottom; - boundBox[4].z = maxz; - boundBox[5].x = rect.left; - boundBox[5].y = rect.top; - boundBox[5].z = maxz; - boundBox[6].x = rect.right; - boundBox[6].y = rect.bottom; - boundBox[6].z = maxz; - boundBox[7].x = rect.right; - boundBox[7].y = rect.top; - boundBox[7].z = maxz; - - return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix()); -} - -void -CEntity::Add(void) -{ - int x, xstart, xmid, xend; - int y, ystart, ymid, yend; - CSector *s; - CPtrList *list; - - CRect bounds = GetBoundRect(); - xstart = CWorld::GetSectorIndexX(bounds.left); - xend = CWorld::GetSectorIndexX(bounds.right); - xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); - ystart = CWorld::GetSectorIndexY(bounds.top); - yend = CWorld::GetSectorIndexY(bounds.bottom); - ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); - assert(xstart >= 0); - assert(xend < NUMSECTORS_X); - assert(ystart >= 0); - assert(yend < NUMSECTORS_Y); - - for(y = ystart; y <= yend; y++) - for(x = xstart; x <= xend; x++){ - s = CWorld::GetSector(x, y); - if(x == xmid && y == ymid) switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES]; - break; - }else switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; - break; - } - list->InsertItem(this); - } -} - -void -CEntity::Remove(void) -{ - int x, xstart, xmid, xend; - int y, ystart, ymid, yend; - CSector *s; - CPtrList *list; - - CRect bounds = GetBoundRect(); - xstart = CWorld::GetSectorIndexX(bounds.left); - xend = CWorld::GetSectorIndexX(bounds.right); - xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); - ystart = CWorld::GetSectorIndexY(bounds.top); - yend = CWorld::GetSectorIndexY(bounds.bottom); - ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); - assert(xstart >= 0); - assert(xend < NUMSECTORS_X); - assert(ystart >= 0); - assert(yend < NUMSECTORS_Y); - - for(y = ystart; y <= yend; y++) - for(x = xstart; x <= xend; x++){ - s = CWorld::GetSector(x, y); - if(x == xmid && y == ymid) switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES]; - break; - }else switch(m_type){ - case ENTITY_TYPE_BUILDING: - list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; - break; - case ENTITY_TYPE_VEHICLE: - list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; - break; - case ENTITY_TYPE_PED: - list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; - break; - case ENTITY_TYPE_OBJECT: - list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; - break; - case ENTITY_TYPE_DUMMY: - list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; - break; - } - list->RemoveItem(this); - } -} - -void CEntity::SetModelIndex(uint32 id) { m_modelIndex = id; @@ -301,7 +112,11 @@ CEntity::CreateRwObject(void) CBaseModelInfo *mi; mi = CModelInfo::GetModelInfo(m_modelIndex); + + PUSH_MEMID(MEMID_WORLD); m_rwObject = mi->CreateInstance(); + POP_MEMID(); + if(m_rwObject){ if(IsBuilding()) gBuildings++; @@ -309,11 +124,55 @@ CEntity::CreateRwObject(void) m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); else if(RwObjectGetType(m_rwObject) == rpCLUMP) m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); + mi->AddRef(); } } void +CEntity::AttachToRwObject(RwObject *obj) +{ + m_rwObject = obj; + if(m_rwObject){ + if(RwObjectGetType(m_rwObject) == rpATOMIC) + m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); + else if(RwObjectGetType(m_rwObject) == rpCLUMP) + m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); + + CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); + } +} + +void +CEntity::DetachFromRwObject(void) +{ + if(m_rwObject) + CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef(); + m_rwObject = nil; + m_matrix.Detach(); +} + +RpAtomic* +AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data) +{ + if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){ + RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic); +#ifdef LIBRW + if(hier && hier->interpolator->currentAnim){ + RpHAnimAnimationDestroy(hier->interpolator->currentAnim); + hier->interpolator->currentAnim = nil; + } +#else + if(hier && hier->currentAnim){ + RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim); + hier->currentAnim = nil; + } +#endif + } + return atomic; +} + +void CEntity::DeleteRwObject(void) { RwFrame *f; @@ -336,35 +195,6 @@ CEntity::DeleteRwObject(void) } } -void -CEntity::UpdateRwFrame(void) -{ - if(m_rwObject){ - if(RwObjectGetType(m_rwObject) == rpATOMIC) - RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject)); - else if(RwObjectGetType(m_rwObject) == rpCLUMP) - RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject)); - } -} - -void -CEntity::SetupBigBuilding(void) -{ - CSimpleModelInfo *mi; - - mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); - bIsBIGBuilding = true; - bStreamingDontDelete = true; - bUsesCollision = false; - m_level = CTheZones::GetLevelFromPosition(&GetPosition()); - if(mi->m_lodDistances[0] <= 2000.0f) - bStreamBIGBuilding = true; - if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) - m_level = LEVEL_GENERIC; - else if(m_level == LEVEL_GENERIC) - printf("%s isn't in a level\n", mi->GetName()); -} - CRect CEntity::GetBoundRect(void) { @@ -386,6 +216,70 @@ CEntity::GetBoundRect(void) return rect; } +CVector +CEntity::GetBoundCentre(void) +{ + CVector v; + GetBoundCentre(v); + return v; +} + +void +CEntity::GetBoundCentre(CVector &out) +{ + out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center; +} + +float +CEntity::GetBoundRadius(void) +{ + return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; +} + +void +CEntity::UpdateRwFrame(void) +{ + if(m_rwObject) + RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject)); +} + +void +CEntity::UpdateRpHAnim(void) +{ + if(IsClumpSkinned(GetClump())){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + RpHAnimHierarchyUpdateMatrices(hier); +#if 0 + int i; + char buf[256]; + if(this == (CEntity*)FindPlayerPed()) + for(i = 0; i < hier->numNodes; i++){ + RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s", + kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real, + kf->t.x, kf->t.y, kf->t.z, + HIERNODEID(hier, i), + ConvertBoneTag2BoneName(HIERNODEID(hier, i))); + CDebug::PrintAt(buf, 10, 1+i*3); + + RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i]; + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.x, m->up.x, m->at.x, m->pos.x); + CDebug::PrintAt(buf, 80, 1+i*3+0); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.y, m->up.y, m->at.y, m->pos.y); + CDebug::PrintAt(buf, 80, 1+i*3+1); + sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", + m->right.z, m->up.z, m->at.z, m->pos.z); + CDebug::PrintAt(buf, 80, 1+i*3+2); + } + + void RenderSkeleton(RpHAnimHierarchy *hier); + RenderSkeleton(hier); +#endif + } +} + bool CEntity::HasPreRenderEffects(void) { @@ -511,15 +405,6 @@ CEntity::PreRender(void) } void -CEntity::PreRenderForGlassWindow(void) -{ - if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) - return; - CGlass::AskForObjectToBeRenderedInGlass(this); - bIsVisible = false; -} - -void CEntity::Render(void) { if(m_rwObject){ @@ -533,416 +418,217 @@ CEntity::Render(void) } bool -CEntity::SetupLighting(void) +CEntity::GetIsTouching(CVector const ¢er, float radius) { - return false; + return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr(); } -void -CEntity::AttachToRwObject(RwObject *obj) +bool +CEntity::IsVisible(void) { - m_rwObject = obj; - if(m_rwObject){ - if(RwObjectGetType(m_rwObject) == rpATOMIC) - m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); - else if(RwObjectGetType(m_rwObject) == rpCLUMP) - m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); - CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); - } + return m_rwObject && bIsVisible && GetIsOnScreen(); } -void -CEntity::DetachFromRwObject(void) +bool +CEntity::IsVisibleComplex(void) { - if(m_rwObject) - CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef(); - m_rwObject = nil; - m_matrix.Detach(); + return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } -void -CEntity::RegisterReference(CEntity **pent) +bool +CEntity::GetIsOnScreen(void) { - if(IsBuilding()) - return; - CReference *ref; - // check if already registered - for(ref = m_pFirstReference; ref; ref = ref->next) - if(ref->pentity == pent) - return; - // have to allocate new reference - ref = CReferences::pEmptyList; - if(ref){ - CReferences::pEmptyList = ref->next; - - ref->pentity = pent; - ref->next = m_pFirstReference; - m_pFirstReference = ref; - return; - } - return; + return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(), + &TheCamera.GetCameraMatrix()); } -// Clear all references to this entity -void -CEntity::ResolveReferences(void) +bool +CEntity::GetIsOnScreenComplex(void) { - CReference *ref; - // clear pointers to this entity - for(ref = m_pFirstReference; ref; ref = ref->next) - if(*ref->pentity == this) - *ref->pentity = nil; - // free list - if(m_pFirstReference){ - for(ref = m_pFirstReference; ref->next; ref = ref->next) - ; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = m_pFirstReference; - m_pFirstReference = nil; - } -} +#ifdef GTA_PS2 + CVuVector boundBox[8]; +#else + CVector boundBox[8]; +#endif -// Free all references that no longer point to this entity -void -CEntity::PruneReferences(void) -{ - CReference *ref, *next, **lastnextp; - lastnextp = &m_pFirstReference; - for(ref = m_pFirstReference; ref; ref = next){ - next = ref->next; - if(*ref->pentity == this) - lastnextp = &ref->next; - else{ - *lastnextp = ref->next; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = ref; - } - } -} + if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix())) + return true; -// Clean up the reference from *pent -> 'this' -void -CEntity::CleanUpOldReference(CEntity **pent) -{ - CReference* ref, ** lastnextp; - lastnextp = &m_pFirstReference; - for (ref = m_pFirstReference; ref; ref = ref->next) { - if (ref->pentity == pent) { - *lastnextp = ref->next; - ref->next = CReferences::pEmptyList; - CReferences::pEmptyList = ref; - break; - } - lastnextp = &ref->next; - } + CRect rect = GetBoundRect(); + CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); + float z = GetPosition().z; + float minz = z + colmodel->boundingBox.min.z; + float maxz = z + colmodel->boundingBox.max.z; + boundBox[0].x = rect.left; + boundBox[0].y = rect.bottom; + boundBox[0].z = minz; + boundBox[1].x = rect.left; + boundBox[1].y = rect.top; + boundBox[1].z = minz; + boundBox[2].x = rect.right; + boundBox[2].y = rect.bottom; + boundBox[2].z = minz; + boundBox[3].x = rect.right; + boundBox[3].y = rect.top; + boundBox[3].z = minz; + boundBox[4].x = rect.left; + boundBox[4].y = rect.bottom; + boundBox[4].z = maxz; + boundBox[5].x = rect.left; + boundBox[5].y = rect.top; + boundBox[5].z = maxz; + boundBox[6].x = rect.right; + boundBox[6].y = rect.bottom; + boundBox[6].z = maxz; + boundBox[7].x = rect.right; + boundBox[7].y = rect.top; + boundBox[7].z = maxz; + + return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix()); } void -CEntity::UpdateRpHAnim(void) +CEntity::Add(void) { - if(IsClumpSkinned(GetClump())){ - RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); - RpHAnimHierarchyUpdateMatrices(hier); -#if 0 - int i; - char buf[256]; - if(this == (CEntity*)FindPlayerPed()) - for(i = 0; i < hier->numNodes; i++){ - RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s", - kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real, - kf->t.x, kf->t.y, kf->t.z, - HIERNODEID(hier, i), - ConvertBoneTag2BoneName(HIERNODEID(hier, i))); - CDebug::PrintAt(buf, 10, 1+i*3); - - RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i]; - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.x, m->up.x, m->at.x, m->pos.x); - CDebug::PrintAt(buf, 80, 1+i*3+0); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.y, m->up.y, m->at.y, m->pos.y); - CDebug::PrintAt(buf, 80, 1+i*3+1); - sprintf(buf, "%6.3f %6.3f %6.3f %6.3f", - m->right.z, m->up.z, m->at.z, m->pos.z); - CDebug::PrintAt(buf, 80, 1+i*3+2); - } + int x, xstart, xmid, xend; + int y, ystart, ymid, yend; + CSector *s; + CPtrList *list; - void RenderSkeleton(RpHAnimHierarchy *hier); - RenderSkeleton(hier); -#endif - } -} + CRect bounds = GetBoundRect(); + xstart = CWorld::GetSectorIndexX(bounds.left); + xend = CWorld::GetSectorIndexX(bounds.right); + xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); + ystart = CWorld::GetSectorIndexY(bounds.top); + yend = CWorld::GetSectorIndexY(bounds.bottom); + ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); + assert(xstart >= 0); + assert(xend < NUMSECTORS_X); + assert(ystart >= 0); + assert(yend < NUMSECTORS_Y); -void -CEntity::AddSteamsFromGround(CVector *unused) -{ - int i, n; - C2dEffect *effect; - CVector pos; - - n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); - for(i = 0; i < n; i++){ - effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); - if(effect->type != EFFECT_PARTICLE) - continue; - - pos = GetMatrix() * effect->pos; - switch(effect->particle.particleType){ - case 0: - CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 1: - CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 2: - CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false); - break; - case 3: - CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 4: - CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 5: - CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false); - break; - case 6: - CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false); - break; + for(y = ystart; y <= yend; y++) + for(x = xstart; x <= xend; x++){ + s = CWorld::GetSector(x, y); + if(x == xmid && y == ymid) switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS]; + break; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES]; + break; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS]; + break; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS]; + break; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES]; + break; + }else switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; + break; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; + break; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; + break; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; + break; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; + break; + } + list->InsertItem(this); } - } } void -CEntity::ProcessLightsForEntity(void) +CEntity::Remove(void) { - int i, n; - C2dEffect *effect; - CVector pos; - bool lightOn, lightFlickering; - uint32 flashTimer1, flashTimer2, flashTimer3; - - if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f) - return; - - flashTimer1 = 0; - flashTimer2 = 0; - flashTimer3 = 0; - - n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); - for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){ - effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); + int x, xstart, xmid, xend; + int y, ystart, ymid, yend; + CSector *s; + CPtrList *list; - switch(effect->type){ - case EFFECT_LIGHT: - pos = GetMatrix() * effect->pos; + CRect bounds = GetBoundRect(); + xstart = CWorld::GetSectorIndexX(bounds.left); + xend = CWorld::GetSectorIndexX(bounds.right); + xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f); + ystart = CWorld::GetSectorIndexY(bounds.top); + yend = CWorld::GetSectorIndexY(bounds.bottom); + ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f); + assert(xstart >= 0); + assert(xend < NUMSECTORS_X); + assert(ystart >= 0); + assert(yend < NUMSECTORS_Y); - lightOn = false; - lightFlickering = false; - switch(effect->light.lightType){ - case LIGHT_ON: - lightOn = true; - break; - case LIGHT_ON_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - lightOn = true; - break; - case LIGHT_FLICKER: - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) - lightOn = true; - break; - case LIGHT_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) - lightOn = true; - } - break; - case LIGHT_FLASH1: - if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) - lightOn = true; + for(y = ystart; y <= yend; y++) + for(x = xstart; x <= xend; x++){ + s = CWorld::GetSector(x, y); + if(x == xmid && y == ymid) switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS]; break; - case LIGHT_FLASH1_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) - lightOn = true; + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES]; break; - case LIGHT_FLASH2: - if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) - lightOn = true; + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS]; break; - case LIGHT_FLASH2_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) - lightOn = true; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS]; break; - case LIGHT_FLASH3: - if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) - lightOn = true; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES]; break; - case LIGHT_FLASH3_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) - if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) - lightOn = true; + }else switch(m_type){ + case ENTITY_TYPE_BUILDING: + list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]; break; - case LIGHT_RANDOM_FLICKER: - if(m_randomSeed > 16) - lightOn = true; - else{ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) - lightOn = true; - } + case ENTITY_TYPE_VEHICLE: + list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP]; break; - case LIGHT_RANDOM_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ - if(m_randomSeed > 16) - lightOn = true; - else{ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) - lightOn = true; - } - } + case ENTITY_TYPE_PED: + list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP]; break; - case LIGHT_BRIDGE_FLASH1: - if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200) - lightOn = true; + case ENTITY_TYPE_OBJECT: + list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP]; break; - case LIGHT_BRIDGE_FLASH2: - if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60) - lightOn = true; + case ENTITY_TYPE_DUMMY: + list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP]; break; } + list->RemoveItem(this); + } +} - if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){ - if(lightOn) - bDoNotRender = false; - else - bDoNotRender = true; - return; - } - - // Corona - if(lightOn) - CCoronas::RegisterCorona((uintptr)this + i, - effect->col.r, effect->col.g, effect->col.b, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, - !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); - else if(lightFlickering) - CCoronas::RegisterCorona((uintptr)this + i, - 0, 0, 0, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, - !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); - - // Pointlight - bool alreadyProcessedFog; - alreadyProcessedFog = false; - if(effect->light.range != 0.0f && lightOn){ - if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - 0.0f, 0.0f, 0.0f, - CPointLights::FOG_NONE, true); - }else{ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f, - (effect->light.flags & LIGHTFLAG_FOG) >> 1, - true); - alreadyProcessedFog = true; - } - } - - if(!alreadyProcessedFog){ - if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS, - pos, CVector(0.0f, 0.0f, 0.0f), - 0.0f, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_ALWAYS, true); - }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY, - pos, CVector(0.0f, 0.0f, 0.0f), - 0.0f, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_NORMAL, true); - } - } +float +CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void) +{ + return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; +} - // Light shadow - if(effect->light.shadowSize != 0.0f){ - if(lightOn){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - effect->light.shadowSize, 0.0f, - 0.0f, -effect->light.shadowSize, - 128, - effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - 15.0f, 1.0f, 40.0f, false, 0.0f); - }else if(lightFlickering){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - effect->light.shadowSize, 0.0f, - 0.0f, -effect->light.shadowSize, - 0, 0.0f, 0.0f, 0.0f, - 15.0f, 1.0f, 40.0f, false, 0.0f); - } - } - break; +void +CEntity::SetupBigBuilding(void) +{ + CSimpleModelInfo *mi; - case EFFECT_SUNGLARE: - if(CWeather::SunGlare >= 0.0f){ - CVector pos = GetMatrix() * effect->pos; - CVector glareDir = pos - GetPosition(); - glareDir.Normalise(); - CVector camDir = TheCamera.GetPosition() - pos; - float dist = camDir.Magnitude(); - camDir *= 2.0f/dist; - glareDir += camDir; - glareDir.Normalise(); - float camAngle = -DotProduct(glareDir, CTimeCycle::GetSunDirection()); - if(camAngle > 0.0f){ - float intens = Sqrt(camAngle) * CWeather::SunGlare; - pos += camDir; - CCoronas::RegisterCorona((uintptr)this + 33 + i, - intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f, - intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f, - intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f, - 255, - pos, 0.5f*CWeather::SunGlare*Sqrt(dist), 120.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, - CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, - CCoronas::STREAK_OFF, 0.0f); - } - } - break; - } - } + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + bIsBIGBuilding = true; + bStreamingDontDelete = true; + bUsesCollision = false; + m_level = CTheZones::GetLevelFromPosition(&GetPosition()); + if(mi->m_lodDistances[0] <= 2000.0f) + bStreamBIGBuilding = true; + if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) + m_level = LEVEL_GENERIC; + else if(m_level == LEVEL_GENERIC) + printf("%s isn't in a level\n", mi->GetModelName()); } float WindTabel[] = { @@ -999,7 +685,7 @@ float BannerWindTabel[] = { 0.28f, 0.28f, 0.22f, 0.1f, 0.0f, -0.1f, -0.17f, -0.12f }; -//--MIAMI: unused +// unused void CEntity::ModifyMatrixForBannerInWind(void) { @@ -1036,14 +722,67 @@ CEntity::ModifyMatrixForBannerInWind(void) UpdateRwFrame(); } -void -CEntity::AddSteamsFromGround(CPtrList& list) +void +CEntity::PreRenderForGlassWindow(void) +{ + if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) + return; + CGlass::AskForObjectToBeRenderedInGlass(this); + bIsVisible = false; +} + +/* +0x487A10 - SetAtomicAlphaCB +0x4879E0 - SetClumpAlphaCB +*/ + +RpMaterial* +SetAtomicAlphaCB(RpMaterial *material, void *data) +{ + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; + return material; +} + +RpAtomic* +SetClumpAlphaCB(RpAtomic *atomic, void *data) +{ + RpGeometry *geometry = RpAtomicGetGeometry(atomic); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data); + return atomic; +} + +void +CEntity::SetRwObjectAlpha(int32 alpha) +{ + if (m_rwObject != nil) { + switch (RwObjectGetType(m_rwObject)) { + case rpATOMIC: { + RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha); + break; + } + case rpCLUMP: + RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha); + break; + } + } +} + +bool IsEntityPointerValid(CEntity* pEntity) { - CPtrNode *pNode = list.first; - while (pNode) { - ((CEntity*)pNode->item)->AddSteamsFromGround(nil); - pNode = pNode->next; + if (!pEntity) + return false; + switch (pEntity->GetType()) { + case ENTITY_TYPE_NOTHING: return false; + case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); + case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); + case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); + case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); + case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); } + return false; } #ifdef COMPATIBLE_SAVES @@ -1160,84 +899,3 @@ CEntity::LoadEntityFlags(uint8*& buf) } #endif - -bool IsEntityPointerValid(CEntity* pEntity) -{ - if (!pEntity) - return false; - switch (pEntity->GetType()) { - case ENTITY_TYPE_NOTHING: return false; - case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); - case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); - case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); - case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); - case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); - } - return false; -} - -bool CEntity::IsEntityOccluded(void) { - - CVector coors; - float width, height; - - if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height)) - return false; - - float area = Max(width, height) * GetBoundRadius() * 0.9f; - - for (int i = 0; i < COcclusion::NumActiveOccluders; i++) { - if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) { - if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) { - return true; - } - - if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) { - CVector min = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min; - CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.max; - - if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - if (CalcScreenCoors(CVector(max.x, min.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - if (CalcScreenCoors(CVector(min.x, max.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; - - return true; - } - } - } - - return false; -} - -/* -0x487A10 - SetAtomicAlphaCB -0x4879E0 - SetClumpAlphaCB -*/ - -RpMaterial* SetAtomicAlphaCB(RpMaterial *material, void *data) { - ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; - return material; -} - -RpAtomic* SetClumpAlphaCB(RpAtomic *atomic, void *data) { - RpGeometry *geometry = RpAtomicGetGeometry(atomic); - RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); - RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data); - return atomic; -} - -void CEntity::SetRwObjectAlpha(int32 alpha) { - if (m_rwObject != nil) { - switch (RwObjectGetType(m_rwObject)) { - case rpATOMIC: { - RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject); - RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); - RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha); - break; - } - case rpCLUMP: - RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha); - break; - } - } -}
\ No newline at end of file diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 08d1900a..2749e3f7 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -6,7 +6,7 @@ struct CReference; class CPtrList; -enum eEntityType : uint8 +enum eEntityType { ENTITY_TYPE_NOTHING = 0, ENTITY_TYPE_BUILDING, @@ -16,7 +16,7 @@ enum eEntityType : uint8 ENTITY_TYPE_DUMMY, }; -enum eEntityStatus : uint8 +enum eEntityStatus { STATUS_PLAYER, STATUS_PLAYER_PLAYBACKFROMBUFFER, @@ -99,10 +99,10 @@ public: CReference *m_pFirstReference; public: - eEntityType GetType() const { return (eEntityType)m_type; } - void SetType(eEntityType type) { m_type = type; } - eEntityStatus GetStatus() const { return (eEntityStatus)m_status; } - void SetStatus(eEntityStatus status) { m_status = status; } + uint8 GetType() const { return m_type; } + void SetType(uint8 type) { m_type = type; } + uint8 GetStatus() const { return m_status; } + void SetStatus(uint8 status) { m_status = status; } CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } bool GetIsStatic(void) const { return bIsStatic || bIsStaticWaitingForCollision; } void SetIsStatic(bool state) { bIsStatic = state; } @@ -130,7 +130,7 @@ public: virtual void PreRender(void); virtual void Render(void); virtual bool SetupLighting(void); - virtual void RemoveLighting(bool) {} + virtual void RemoveLighting(bool); virtual void FlagToDestroyWhenNextProcessed(void) {} bool IsBuilding(void) { return m_type == ENTITY_TYPE_BUILDING; } @@ -149,14 +149,14 @@ public: } void GetBoundCentre(CVector &out); - CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; } - float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; } - float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; } + CVector GetBoundCentre(void); + float GetBoundRadius(void); + float GetDistanceFromCentreOfMassToBaseOfModel(void); bool GetIsTouching(CVector const ¢er, float r); bool GetIsOnScreen(void); bool GetIsOnScreenComplex(void); - bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); } - bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } + bool IsVisible(void); + bool IsVisibleComplex(void); bool IsEntityOccluded(void); int16 GetModelIndex(void) const { return m_modelIndex; } void UpdateRwFrame(void); @@ -171,9 +171,7 @@ public: void PruneReferences(void); void CleanUpOldReference(CEntity **pent); -#ifdef PED_SKIN void UpdateRpHAnim(void); -#endif void PreRenderForGlassWindow(void); void AddSteamsFromGround(CVector *unused); @@ -181,8 +179,6 @@ public: void ModifyMatrixForBannerInWind(void); void ProcessLightsForEntity(void); void SetRwObjectAlpha(int32 alpha); - - static void AddSteamsFromGround(CPtrList& list); }; bool IsEntityPointerValid(CEntity*); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index acf9c702..73a6570a 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -21,8 +21,6 @@ #include "Pickups.h" #include "Physical.h" -//--MIAMI: file done - #ifdef WALLCLIMB_CHEAT bool gGravityCheat; #endif @@ -235,6 +233,7 @@ CPhysical::GetBoundRect(void) return CRect(center.x-radius, center.y-radius, center.x+radius, center.y+radius); } +// --MIAMI: Proof-read once void CPhysical::AddToMovingList(void) { @@ -242,6 +241,7 @@ CPhysical::AddToMovingList(void) m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this); } +// --MIAMI: Proof-read once void CPhysical::RemoveFromMovingList(void) { @@ -261,12 +261,14 @@ CPhysical::SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, C m_vecDamageNormal = dir; } +// --MIAMI: Proof-read once void CPhysical::AddCollisionRecord(CEntity *ent) { AddCollisionRecord_Treadable(ent); this->bHasCollided = true; ent->bHasCollided = true; + this->m_nLastTimeCollided = CTimer::GetTimeInMilliseconds(); if(IsVehicle() && ent->IsVehicle()){ if(((CVehicle*)this)->m_nAlarmState == -1) ((CVehicle*)this)->m_nAlarmState = 15000; @@ -280,10 +282,10 @@ CPhysical::AddCollisionRecord(CEntity *ent) return; if(m_nCollisionRecords < PHYSICAL_MAX_COLLISIONRECORDS) m_aCollisionRecords[m_nCollisionRecords++] = ent; - m_nLastTimeCollided = CTimer::GetTimeInMilliseconds(); } } +// --MIAMI: Proof-read once void CPhysical::AddCollisionRecord_Treadable(CEntity *ent) { @@ -291,6 +293,7 @@ CPhysical::AddCollisionRecord_Treadable(CEntity *ent) } } +// --MIAMI: Proof-read once bool CPhysical::GetHasCollidedWith(CEntity *ent) { @@ -302,20 +305,23 @@ CPhysical::GetHasCollidedWith(CEntity *ent) return false; } +// --MIAMI: Proof-read once void CPhysical::RemoveRefsToEntity(CEntity *ent) { - int i, j; + int i = 0, j; - for(i = 0; i < m_nCollisionRecords; i++){ + while (i < m_nCollisionRecords){ if(m_aCollisionRecords[i] == ent){ for(j = i; j < m_nCollisionRecords-1; j++) m_aCollisionRecords[j] = m_aCollisionRecords[j+1]; m_nCollisionRecords--; - } + } else + i++; } } +// --MIAMI: Proof-read once void CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phys, CVector localPos) { @@ -332,6 +338,7 @@ CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phy CWorld::Add(phys); } +// --MIAMI: Proof-read once int32 CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) { @@ -350,6 +357,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) return numSpheres; } +// --MIAMI: Proof-read once void CPhysical::ProcessControl(void) { @@ -417,6 +425,7 @@ CPhysical::GetSpeed(const CVector &r) return m_vecMoveSpeed + m_vecMoveFriction + CrossProduct(m_vecTurnFriction + m_vecTurnSpeed, r); } +// --MIAMI: Proof-read once void CPhysical::ApplyMoveSpeed(void) { @@ -426,7 +435,7 @@ CPhysical::ApplyMoveSpeed(void) GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep()); } - +// --MIAMI: Proof-read once void CPhysical::ApplyTurnSpeed(void) { @@ -442,12 +451,14 @@ CPhysical::ApplyTurnSpeed(void) } } +// --MIAMI: Proof-read once void CPhysical::ApplyMoveForce(float jx, float jy, float jz) { m_vecMoveSpeed += CVector(jx, jy, jz)*(1.0f/m_fMass); } +// --MIAMI: Proof-read once void CPhysical::ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz) { @@ -462,6 +473,7 @@ CPhysical::ApplyFrictionMoveForce(float jx, float jy, float jz) m_vecMoveFriction += CVector(jx, jy, jz)*(1.0f/m_fMass); } +// --MIAMI: Proof-read once void CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float py, float pz) { @@ -470,6 +482,7 @@ CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float m_vecTurnFriction += turnimpulse*(1.0f/m_fTurnMass); } +// --MIAMI: Proof-read once bool CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias) { @@ -483,6 +496,7 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector & return true; } +// --MIAMI: Proof-read once bool CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir) { @@ -500,6 +514,7 @@ CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVecto return true; } +// --MIAMI: Proof-read once // What exactly is speed? bool CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed) @@ -530,21 +545,21 @@ CPhysical::ApplyGravity(void) return; #ifdef WALLCLIMB_CHEAT if (gGravityCheat && this == FindPlayerVehicle()) { - static CVector v1(0.0f, 0.0f, 1.0f), v2(0.0f, 0.0f, 1.0f); - CVector prop = GetPosition() - (GetUp() + GetUp()); + static CVector gravityUp(0.0f, 0.0f, 1.0f), surfaceUp(0.0f, 0.0f, 1.0f); + CVector belowCar = GetPosition() - 2.0f*GetUp(); CColPoint point; CEntity* entity; - if (CWorld::ProcessLineOfSight(GetPosition(), prop, point, entity, true, false, false, false, false, false)) - v2 = point.normal; + if (CWorld::ProcessLineOfSight(GetPosition(), belowCar, point, entity, true, false, false, false, false, false)) + surfaceUp = point.normal; else - v2 = CVector(0.0f, 0.0f, 1.0f); - float coef = clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f); - v1 = v1 * (1.0f - coef) + v2 * coef; - if (v1.MagnitudeSqr() < 0.1f) - v1 = CVector(0.0f, 0.0f, 1.0f); + surfaceUp = CVector(0.0f, 0.0f, 1.0f); + float t = clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f); + gravityUp = gravityUp * (1.0f - t) + surfaceUp * t; + if (gravityUp.MagnitudeSqr() < 0.1f) + gravityUp = CVector(0.0f, 0.0f, 1.0f); else - v1.Normalise(); - m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * v1; + gravityUp.Normalise(); + m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * gravityUp; return; } #endif @@ -560,17 +575,16 @@ CPhysical::ApplyFriction(void) m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f); } +// --MIAMI: Proof-read once void CPhysical::ApplyAirResistance(void) { if(m_fAirResistance > 0.1f){ - if(GetStatus() != STATUS_GHOST){ - float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); - m_vecMoveSpeed *= f; - m_vecTurnSpeed *= f; - } - }else{ - float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep()); + float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); + m_vecMoveSpeed *= f; + m_vecTurnSpeed *= f; + }else if(GetStatus() != STATUS_GHOST){ + float f = Pow(1.0f/Abs(1.0f + m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr()), CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= 0.99f; } @@ -867,9 +881,13 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(B->GetStatus() == STATUS_PLAYER) pointposB *= 0.8f; if(CWorld::bNoMoreCollisionTorque){ - // BUG: the game actually uses A here, but this can't be right +#ifdef FIX_BUGS B->ApplyFrictionMoveForce(fB*-0.3f); B->ApplyFrictionTurnForce(fB*-0.3f, pointposB); +#else + A->ApplyFrictionMoveForce(fB*-0.3f); + A->ApplyFrictionTurnForce(fB*-0.3f, pointposB); +#endif } } if(!A->bInfiniteMass){ @@ -1015,6 +1033,7 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV return false; } +// --MIAMI: Proof-read once bool CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) { @@ -1037,14 +1056,24 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) fOtherSpeedA = vOtherSpeedA.Magnitude(); fOtherSpeedB = vOtherSpeedB.Magnitude(); +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeedA; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA); +#endif + speedSum = (B->m_fMass*fOtherSpeedB + A->m_fMass*fOtherSpeedA)/(B->m_fMass + A->m_fMass); if(fOtherSpeedA > speedSum){ impulseA = (speedSum - fOtherSpeedA) * A->m_fMass; impulseB = (speedSum - fOtherSpeedB) * B->m_fMass; impulseLimit = adhesiveLimit*CTimer::GetTimeStep(); if(impulseA < -impulseLimit) impulseA = -impulseLimit; - if(impulseB > impulseLimit) impulseB = impulseLimit; // BUG: game has A's clamp again here, but this can't be right +#ifdef FIX_BUGS + if(impulseB > impulseLimit) impulseB = impulseLimit; +#else + if(impulseA < -impulseLimit) impulseA = -impulseLimit; // duplicate +#endif A->ApplyFrictionMoveForce(frictionDir*impulseA); B->ApplyFrictionMoveForce(frictionDir*impulseB); return true; @@ -1063,7 +1092,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) fOtherSpeedA = vOtherSpeedA.Magnitude(); fOtherSpeedB = vOtherSpeedB.Magnitude(); +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeedA; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA); +#endif float massB = B->GetMass(pointposB, frictionDir); speedSum = (massB*fOtherSpeedB + A->m_fMass*fOtherSpeedA)/(massB + A->m_fMass); if(fOtherSpeedA > speedSum){ @@ -1091,7 +1125,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) fOtherSpeedA = vOtherSpeedA.Magnitude(); fOtherSpeedB = vOtherSpeedB.Magnitude(); +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeedA; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA); +#endif float massA = A->GetMass(pointposA, frictionDir); speedSum = (B->m_fMass*fOtherSpeedB + massA*fOtherSpeedA)/(B->m_fMass + massA); if(fOtherSpeedA > speedSum){ @@ -1119,7 +1158,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) fOtherSpeedA = vOtherSpeedA.Magnitude(); fOtherSpeedB = vOtherSpeedB.Magnitude(); +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeedA; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA); +#endif float massA = A->GetMass(pointposA, frictionDir); float massB = B->GetMass(pointposB, frictionDir); speedSum = (massB*fOtherSpeedB + massA*fOtherSpeedA)/(massB + massA); @@ -1139,6 +1183,7 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) return false; } +// --MIAMI: Proof-read once bool CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) { @@ -1156,7 +1201,12 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) fOtherSpeed = vOtherSpeed.Magnitude(); if(fOtherSpeed > 0.0f){ +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeed; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeed * (1.0f/fOtherSpeed); +#endif // not really impulse but speed // maybe use ApplyFrictionMoveForce instead? fImpulse = -fOtherSpeed; @@ -1174,9 +1224,14 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) fOtherSpeed = vOtherSpeed.Magnitude(); if(fOtherSpeed > 0.0f){ +#ifdef FIX_BUGS // division by 0 + frictionDir = vOtherSpeed; + frictionDir.Normalise(); +#else frictionDir = vOtherSpeed * (1.0f/fOtherSpeed); +#endif fImpulse = -fOtherSpeed * m_fMass; - impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5f; + impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5; if(fImpulse < -impulseLimit) fImpulse = -impulseLimit; ApplyFrictionMoveForce(frictionDir*fImpulse); ApplyFrictionTurnForce(frictionDir*fImpulse, pointpos); @@ -1194,6 +1249,7 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) return false; } +// --MIAMI: Proof-read once bool CPhysical::ProcessShiftSectorList(CPtrList *lists) { @@ -1267,7 +1323,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) skipShift = true; Aobj->m_pCollidingEntity = B; } - } + } else + skipShift = true; }else if(B->IsObject() && A->IsVehicle()){ CObject *Bobj = (CObject*)B; if(Bobj->ObjectCreatedBy != TEMP_OBJECT && @@ -1282,7 +1339,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) if(size.z < A->GetPosition().z || (Invert(A->GetMatrix(), inv) * size).z < 0.0f) skipShift = true; - } + } else + skipShift = true; }else if(IsBodyPart(A->GetModelIndex()) && B->IsPed()) skipShift = true; else if(A->IsPed() && IsBodyPart(B->GetModelIndex())) @@ -1354,6 +1412,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) return true; } +// --MIAMI: Proof-read once bool CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists) { @@ -1520,6 +1579,7 @@ collision: return true; } +// --MIAMI: Proof-read once bool CPhysical::ProcessCollisionSectorList(CPtrList *lists) { @@ -1656,8 +1716,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) return true; if(numCollisions == 0 && A == (CEntity*)FindPlayerPed() && Aped->m_pCollidingEntity == B) Aped->m_pCollidingEntity = nil; - }else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){ - + }else if(B->IsBuilding() || B->bIsStuck || B->m_phy_flagA08 || altcollision){ // This is the case where B doesn't move B->m_scanCode = CWorld::GetCurrentScanCode(); @@ -1925,18 +1984,22 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) CMatrix inv; CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = B->GetMatrix() * size; - if(size.z < B->GetPosition().z || + if(size.z < A->GetPosition().z || (Invert(A->GetMatrix(), inv) * size).z < 0.0f) Bobj->ObjectDamage(50.0f); } }else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){ if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f) Aobj->ObjectDamage(maxImpulseB); +#ifdef FIX_BUGS else if(Aobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ +#else + else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ +#endif CMatrix inv; CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = A->GetMatrix() * size; - if(size.z < A->GetPosition().z || + if(size.z < B->GetPosition().z || (Invert(B->GetMatrix(), inv) * size).z < 0.0f) Aobj->ObjectDamage(50.0f); } @@ -1987,6 +2050,7 @@ CPhysical::CheckCollision_SimpleCar(void) float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f; +// --MIAMI: Proof-read once void CPhysical::ProcessShift(void) { @@ -1997,8 +2061,8 @@ CPhysical::ProcessShift(void) RemoveAndAdd(); }else{ CPhysical *surf; - if(bHasHitWall && IsPed() && (surf = ((CPed*)this)->m_pCurrentPhysSurface, surf == nil || !surf->bInfiniteMass || surf->m_phy_flagA08) || - CWorld::bSecondShift){ + if(bHasHitWall && (IsPed() && (surf = ((CPed*)this)->m_pCurrentPhysSurface, surf == nil || !surf->bInfiniteMass || surf->m_phy_flagA08) || + CWorld::bSecondShift)){ m_vecMoveSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); m_vecTurnSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); } diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp index d6c8e065..a485138e 100644 --- a/src/extras/custompipes.cpp +++ b/src/extras/custompipes.cpp @@ -1,4 +1,4 @@ -#define WITH_D3D +#define WITHD3D #include "common.h" #ifdef EXTENDED_PIPELINES @@ -133,7 +133,11 @@ EnvMapRender(void) EnvMapCam->getFrame()->matrix.pos = camPos; EnvMapCam->getFrame()->transform(&EnvMapCam->getFrame()->matrix, rw::COMBINEREPLACE); - rw::RGBA skycol = { CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255 }; + rw::RGBA skycol; + skycol.red = CTimeCycle::GetSkyBottomRed(); + skycol.green = CTimeCycle::GetSkyBottomGreen(); + skycol.blue = CTimeCycle::GetSkyBottomBlue(); + skycol.alpha = 255; EnvMapCam->clear(&skycol, rwCAMERACLEARZ|rwCAMERACLEARIMAGE); RwCameraBeginUpdate(EnvMapCam); bRenderingEnvMap = true; @@ -337,7 +341,7 @@ ReadTweakValueTable(char *fp, InterpolatedValue &interp) * Neo Vehicle pipe */ -int32 VehiclePipeSwitch = VEHICLEPIPE_NEO; +int32 VehiclePipeSwitch = VEHICLEPIPE_MATFX; float VehicleShininess = 1.0f; float VehicleSpecularity = 1.0f; InterpolatedFloat Fresnel(0.4f); diff --git a/src/extras/custompipes.h b/src/extras/custompipes.h index ca3f0fb4..7ad239f0 100644 --- a/src/extras/custompipes.h +++ b/src/extras/custompipes.h @@ -1,7 +1,7 @@ #pragma once -#ifdef EXTENDED_PIPELINES #ifdef LIBRW +#ifdef EXTENDED_PIPELINES namespace CustomPipes { @@ -134,4 +134,12 @@ void AttachRimPipe(rw::Clump *clump); } #endif + +namespace WorldRender{ +extern int numBlendInsts[3]; +void AtomicFirstPass(RpAtomic *atomic, int pass); +void AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha); +void RenderBlendPass(int pass); +} + #endif diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp index 01de3f78..d7634e99 100644 --- a/src/extras/custompipes_d3d9.cpp +++ b/src/extras/custompipes_d3d9.cpp @@ -1,9 +1,7 @@ -#define WITH_D3D +#define WITHD3D #include "common.h" #ifdef RW_D3D9 -#ifdef EXTENDED_PIPELINES - #include "main.h" #include "RwHelper.h" #include "Lights.h" @@ -16,6 +14,8 @@ #include "World.h" #include "custompipes.h" +#ifdef EXTENDED_PIPELINES + #ifndef LIBRW #error "Need librw for EXTENDED_PIPELINES" #endif @@ -140,7 +140,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) void CreateVehiclePipe(void) { - if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/carTweakingTable.dat'\n"); else{ char *fp = (char*)work_buff; @@ -172,6 +172,9 @@ DestroyVehiclePipe(void) rw::d3d::destroyVertexShader(neoVehicle_VS); neoVehicle_VS = nil; + rw::d3d::destroyPixelShader(neoVehicle_PS); + neoVehicle_PS = nil; + ((rw::d3d9::ObjPipeline*)vehiclePipe)->destroy(); vehiclePipe = nil; } @@ -246,12 +249,13 @@ worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) drawInst(header, inst); inst++; } + d3d::setTexture(1, nil); } void CreateWorldPipe(void) { - if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n"); else ReadTweakValueTable((char*)work_buff, WorldLightmapBlend); @@ -362,6 +366,12 @@ CreateGlossPipe(void) void DestroyGlossPipe(void) { + rw::d3d::destroyVertexShader(neoGloss_VS); + neoGloss_VS = nil; + + rw::d3d::destroyPixelShader(neoGloss_PS); + neoGloss_PS = nil; + ((rw::d3d9::ObjPipeline*)glossPipe)->destroy(); glossPipe = nil; } @@ -491,7 +501,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) void CreateRimLightPipes(void) { - if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n"); else{ char *fp = (char*)work_buff; @@ -544,4 +554,168 @@ DestroyRimLightPipes(void) } #endif + +#ifdef NEW_RENDERER +#ifndef LIBRW +#error "Need librw for NEW_PIPELINES" +#endif + +namespace WorldRender +{ + +struct BuildingInst +{ + rw::RawMatrix combinedMat; + rw::d3d9::InstanceDataHeader *instHeader; + uint8 fadeAlpha; + bool lighting; +}; +BuildingInst blendInsts[3][2000]; +int numBlendInsts[3]; + +static RwRGBAReal black; + +static void +SetMatrix(BuildingInst *building, rw::Matrix *worldMat) +{ + using namespace rw; + RawMatrix world, worldview; + Camera *cam = engine->currentCamera; + convMatrix(&world, worldMat); + RawMatrix::mult(&worldview, &world, &cam->devView); + RawMatrix::mult(&building->combinedMat, &worldview, &cam->devProj); +} + +static bool +IsTextureTransparent(RwTexture *tex) +{ + if(tex == nil || tex->raster == nil) + return false; + return PLUGINOFFSET(rw::d3d::D3dRaster, tex->raster, rw::d3d::nativeRasterOffset)->hasAlpha; +} + +// Render all opaque meshes and put atomics that needs blending +// into the deferred list. +void +AtomicFirstPass(RpAtomic *atomic, int pass) +{ + using namespace rw; + using namespace rw::d3d; + using namespace rw::d3d9; + + BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; + + atomic->getPipeline()->instance(atomic); + building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; + assert(building->instHeader != nil); + assert(building->instHeader->platform == PLATFORM_D3D9); + building->fadeAlpha = 255; + building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); + + bool setupDone = false; + bool defer = false; + SetMatrix(building, atomic->getFrame()->getLTM()); + + InstanceData *inst = building->instHeader->inst; + for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ + Material *m = inst->material; + + if(inst->vertexAlpha || m->color.alpha != 255 || + IsTextureTransparent(m->texture)){ + defer = true; + continue; + } + + // alright we're rendering this atomic + if(!setupDone){ + setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); + setIndices(building->instHeader->indexBuffer); + setVertexDeclaration(building->instHeader->vertexDeclaration); + setVertexShader(default_amb_VS); + d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); + if(building->lighting) + setAmbient(pAmbient->color); + else + setAmbient(black); + setupDone = true; + } + + setMaterial(m->color, m->surfaceProps); + + if(m->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(default_tex_PS); + }else + setPixelShader(default_PS); + + drawInst(building->instHeader, inst); + } + if(defer) + numBlendInsts[pass]++; +} + +void +AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) +{ + using namespace rw; + using namespace rw::d3d; + using namespace rw::d3d9; + + BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; + + atomic->getPipeline()->instance(atomic); + building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; + assert(building->instHeader != nil); + assert(building->instHeader->platform == PLATFORM_D3D9); + building->fadeAlpha = fadeAlpha; + building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); + SetMatrix(building, atomic->getFrame()->getLTM()); + numBlendInsts[pass]++; +} + +void +RenderBlendPass(int pass) +{ + using namespace rw; + using namespace rw::d3d; + using namespace rw::d3d9; + + setVertexShader(default_amb_VS); + + int i; + for(i = 0; i < numBlendInsts[pass]; i++){ + BuildingInst *building = &blendInsts[pass][i]; + + setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); + setIndices(building->instHeader->indexBuffer); + setVertexDeclaration(building->instHeader->vertexDeclaration); + d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); + if(building->lighting) + setAmbient(pAmbient->color); + else + setAmbient(black); + + InstanceData *inst = building->instHeader->inst; + for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ + Material *m = inst->material; + if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) + continue; // already done this one + + rw::RGBA color = m->color; + color.alpha = (color.alpha * building->fadeAlpha)/255; + setMaterial(color, m->surfaceProps); + + if(m->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(default_tex_PS); + }else + setPixelShader(default_PS); + + drawInst(building->instHeader, inst); + } + } +} +} +#endif + #endif diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp index 4cd6607b..67be4afd 100644 --- a/src/extras/custompipes_gl.cpp +++ b/src/extras/custompipes_gl.cpp @@ -1,8 +1,6 @@ #include "common.h" #ifdef RW_OPENGL -#ifdef EXTENDED_PIPELINES - #include "main.h" #include "RwHelper.h" #include "Lights.h" @@ -15,6 +13,8 @@ #include "World.h" #include "custompipes.h" +#ifdef EXTENDED_PIPELINES + #ifndef LIBRW #error "Need librw for EXTENDED_PIPELINES" #endif @@ -148,7 +148,7 @@ CreateVehiclePipe(void) using namespace rw; using namespace rw::gl3; - if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/carTweakingTable.dat'\n"); else{ char *fp = (char*)work_buff; @@ -253,6 +253,7 @@ worldRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header) drawInst(header, inst); inst++; } + setTexture(1, nil); #ifndef RW_GL_USE_VAOS disableAttribPointers(header->attribDesc, header->numAttribs); #endif @@ -264,7 +265,7 @@ CreateWorldPipe(void) using namespace rw; using namespace rw::gl3; - if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n"); else ReadTweakValueTable((char*)work_buff, WorldLightmapBlend); @@ -533,7 +534,7 @@ CreateRimLightPipes(void) { using namespace rw::gl3; - if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0) + if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0) printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n"); else{ char *fp = (char*)work_buff; @@ -614,4 +615,171 @@ CustomPipeRegisterGL(void) } #endif + +#ifdef NEW_RENDERER +#ifndef LIBRW +#error "Need librw for NEW_PIPELINES" +#endif + +namespace WorldRender +{ + +struct BuildingInst +{ + rw::Matrix matrix; + rw::gl3::InstanceDataHeader *instHeader; + uint8 fadeAlpha; + bool lighting; +}; +BuildingInst blendInsts[3][2000]; +int numBlendInsts[3]; + +static RwRGBAReal black; + +static bool +IsTextureTransparent(RwTexture *tex) +{ + if(tex == nil || tex->raster == nil) + return false; + return PLUGINOFFSET(rw::gl3::Gl3Raster, tex->raster, rw::gl3::nativeRasterOffset)->hasAlpha; +} + +// Render all opaque meshes and put atomics that needs blending +// into the deferred list. +void +AtomicFirstPass(RpAtomic *atomic, int pass) +{ + using namespace rw; + using namespace rw::gl3; + + BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; + + atomic->getPipeline()->instance(atomic); + building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; + assert(building->instHeader != nil); + assert(building->instHeader->platform == PLATFORM_GL3); + building->fadeAlpha = 255; + building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); + + WorldLights lights; + lights.numAmbients = 1; + lights.numDirectionals = 0; + lights.numLocals = 0; + if(building->lighting) + lights.ambient = pAmbient->color; + else + lights.ambient = black; + + bool setupDone = false; + bool defer = false; + building->matrix = *atomic->getFrame()->getLTM(); + + InstanceData *inst = building->instHeader->inst; + for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ + Material *m = inst->material; + + if(inst->vertexAlpha || m->color.alpha != 255 || + IsTextureTransparent(m->texture)){ + defer = true; + continue; + } + + // alright we're rendering this atomic + if(!setupDone){ + defaultShader->use(); + setWorldMatrix(&building->matrix); +#ifdef RW_GL_USE_VAOS + glBindVertexArray(building->instHeader->vao); +#else + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); + glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); + setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); +#endif + setLights(&lights); + setupDone = true; + } + + setMaterial(m->color, m->surfaceProps); + + setTexture(0, m->texture); + + drawInst(building->instHeader, inst); + } +#ifndef RW_GL_USE_VAOS + disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); +#endif + if(defer) + numBlendInsts[pass]++; +} + +void +AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) +{ + using namespace rw; + using namespace rw::gl3; + + BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; + + atomic->getPipeline()->instance(atomic); + building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; + assert(building->instHeader != nil); + assert(building->instHeader->platform == PLATFORM_GL3); + building->fadeAlpha = fadeAlpha; + building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); + building->matrix = *atomic->getFrame()->getLTM(); + numBlendInsts[pass]++; +} + +void +RenderBlendPass(int pass) +{ + using namespace rw; + using namespace rw::gl3; + + defaultShader->use(); + WorldLights lights; + lights.numAmbients = 1; + lights.numDirectionals = 0; + lights.numLocals = 0; + + int i; + for(i = 0; i < numBlendInsts[pass]; i++){ + BuildingInst *building = &blendInsts[pass][i]; + +#ifdef RW_GL_USE_VAOS + glBindVertexArray(building->instHeader->vao); +#else + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); + glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); + setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); +#endif + setWorldMatrix(&building->matrix); + if(building->lighting) + lights.ambient = pAmbient->color; + else + lights.ambient = black; + setLights(&lights); + + InstanceData *inst = building->instHeader->inst; + for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ + Material *m = inst->material; + if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) + continue; // already done this one + + rw::RGBA color = m->color; + color.alpha = (color.alpha * building->fadeAlpha)/255; + setMaterial(color, m->surfaceProps); + + setTexture(0, m->texture); + + drawInst(building->instHeader, inst); + } +#ifndef RW_GL_USE_VAOS + disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); +#endif + } +} +} +#endif + #endif diff --git a/src/extras/debugmenu.cpp b/src/extras/debugmenu.cpp index 3a4c4175..533b97f5 100644 --- a/src/extras/debugmenu.cpp +++ b/src/extras/debugmenu.cpp @@ -5,7 +5,7 @@ #include "ControllerConfig.h" #include "Timer.h" #include "rtcharse.h" -#include "inttypes.h" +#include "re3_inttypes.h" #include "debugmenu.h" #include <new> diff --git a/src/extras/debugmenu.h b/src/extras/debugmenu.h index eb56c8f9..c2198aca 100644 --- a/src/extras/debugmenu.h +++ b/src/extras/debugmenu.h @@ -15,7 +15,7 @@ struct MenuEntry Menu *menu; MenuEntry(const char *name); - virtual ~MenuEntry(void) {} + virtual ~MenuEntry(void) { free((void*)name); } }; typedef MenuEntry DebugMenuEntry; diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp new file mode 100644 index 00000000..2660e75e --- /dev/null +++ b/src/extras/frontendoption.cpp @@ -0,0 +1,170 @@ +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "Frontend.h" +#include "Text.h" + +int lastOgScreen = MENUPAGES; // means no new pages + +int numCustomFrontendOptions = 0; +int numCustomFrontendScreens = 0; + +int optionCursor = -2; +int currentMenu; +bool optionOverwrite = false; + +void GoBack() +{ + FrontEndMenuManager.SwitchToNewScreen(-1); +} + +uint8 +GetNumberOfMenuOptions(int screen) +{ + uint8 Rows = 0; + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[screen].m_aEntries[i].m_Action == MENUACTION_NOTHING) + break; + + ++Rows; + } + return Rows; +} + +uint8 +GetLastMenuScreen() +{ + int8 page = -1; + for (int i = 0; i < MENUPAGES; i++) { + if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage == MENUPAGE_NONE) + break; + + ++page; + } + return page; +} + +int8 RegisterNewScreen(const char *name, int prevPage, ReturnPrevPageFunc returnPrevPageFunc) +{ + if (lastOgScreen == MENUPAGES) + lastOgScreen = GetLastMenuScreen(); + + numCustomFrontendScreens++; + int id = lastOgScreen + numCustomFrontendScreens; + assert(id < MENUPAGES && "No room for new custom frontend screens! Increase MENUPAGES"); + strncpy(aScreens[id].m_ScreenName, name, 8); + aScreens[id].m_PreviousPage = prevPage; + aScreens[id].returnPrevPageFunc = returnPrevPageFunc; + return id; +} + +int8 RegisterNewOption() +{ + numCustomFrontendOptions++; + uint8 numOptions = GetNumberOfMenuOptions(currentMenu); + uint8 curIdx; + if (optionCursor < 0) { + optionCursor = curIdx = numOptions + optionCursor + 1; + } else + curIdx = optionCursor; + + if (!optionOverwrite) { + if (aScreens[currentMenu].m_aEntries[curIdx].m_Action != MENUACTION_NOTHING) { + for (int i = numOptions - 1; i >= curIdx; i--) { + memcpy(&aScreens[currentMenu].m_aEntries[i + 1], &aScreens[currentMenu].m_aEntries[i], sizeof(CMenuScreenCustom::CMenuEntry)); + } + } + } + optionCursor++; + return curIdx; +} + +void FrontendOptionSetCursor(int screen, int8 option, bool overwrite) +{ + currentMenu = screen; + optionCursor = option; + optionOverwrite = overwrite; +} + +void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu, int saveSlot) { + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + + // We can't use custom text on those :shrug: + switch (action) { + case MENUACTION_SCREENRES: + strcpy(option.m_EntryName, "FED_RES"); + break; + case MENUACTION_AUDIOHW: + strcpy(option.m_EntryName, "FEA_3DH"); + break; + default: + strncpy(option.m_EntryName, gxtKey, 8); + break; + } + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + option.m_Action = action; + option.m_SaveSlot = saveSlot; + option.m_TargetMenu = targetMenu; +} + +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat, const char* saveName, bool disableIfGameLoaded) +{ + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + option.m_Action = MENUACTION_CFO_SELECT; + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + strncpy(option.m_EntryName, gxtKey, 8); + option.m_CFOSelect = new CCFOSelect(); + option.m_CFOSelect->rightTexts = (char**)malloc(numRightTexts * sizeof(char*)); + memcpy(option.m_CFOSelect->rightTexts, rightTexts, numRightTexts * sizeof(char*)); + option.m_CFOSelect->numRightTexts = numRightTexts; + option.m_CFOSelect->value = var; + if (var) { + option.m_CFOSelect->displayedValue = *var; + option.m_CFOSelect->lastSavedValue = *var; + } + option.m_CFOSelect->saveCat = saveCat; + option.m_CFOSelect->save = saveName; + option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter; + option.m_CFOSelect->changeFunc = changeFunc; + option.m_CFOSelect->disableIfGameLoaded = disableIfGameLoaded; +} + +void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat, const char* saveName) +{ + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + option.m_Action = MENUACTION_CFO_DYNAMIC; + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + strncpy(option.m_EntryName, gxtKey, 8); + option.m_CFODynamic = new CCFODynamic(); + option.m_CFODynamic->drawFunc = drawFunc; + option.m_CFODynamic->buttonPressFunc = buttonPressFunc; + option.m_CFODynamic->value = var; + option.m_CFODynamic->saveCat = saveCat; + option.m_CFODynamic->save = saveName; +} + +// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT +uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc) { + + uint8 screenOrder = RegisterNewScreen(gxtKey, prevPage, returnPrevPageFunc); + + CCustomScreenLayout *screen = new CCustomScreenLayout(); + aScreens[screenOrder].layout = screen; + screen->lineHeight = lineHeight; + screen->showLeftRightHelper = showLeftRightHelper; + + return screenOrder; +} +#endif diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h new file mode 100644 index 00000000..05cd5fa0 --- /dev/null +++ b/src/extras/frontendoption.h @@ -0,0 +1,86 @@ +#pragma once +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS + +// ! There are 2 ways to use CFO, +// 1st; by adding a new option to the array in MenuScreensCustom.cpp and passing attributes/CBs to it +// 2nd; by calling the functions listed at the bottom of this file. + +// -- Option types +// +// Static/select: You allocate the variable, pass it to function and game sets it from user input among the strings given to function, +// optionally you can add post-change event via ChangeFunc(only called on enter if onlyApplyOnEnter set, or set immediately) +// You can store the option in an INI file if you pass the key(as a char array) to corresponding parameter. +// +// Dynamic: Passing variable to function is only needed if you want to store it, otherwise you should do +// all the operations with ButtonPressFunc, this includes allocating the variable. +// Left-side text is passed while creating and static, but ofc right-side text is dynamic - +// you should return it in DrawFunc, which is called on every draw. +// +// Built-in action: As the name suggests, any action that game has built-in. But as an extra you can set the option text, + +// -- Returned via ButtonPressFunc() action param. +#define FEOPTION_ACTION_LEFT 0 +#define FEOPTION_ACTION_RIGHT 1 +#define FEOPTION_ACTION_SELECT 2 +#define FEOPTION_ACTION_FOCUSLOSS 3 + +// -- Callbacks + +// pretty much in everything I guess, and optional in all of them +typedef void (*ReturnPrevPageFunc)(); + +// for static options +typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value. + // only called on enter if onlyApplyOnEnter set, otherwise called on every value change + +// for dynamic options +typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text. + // you can also set *disabled if you want to gray it out. +typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above + +// -- Internal things +void CustomFrontendOptionsPopulate(); +extern int lastOgScreen; // for reloading +extern int numCustomFrontendOptions; +extern int numCustomFrontendScreens; + +// -- To be used in ButtonPressFunc / ChangeFunc(this one would be weird): +void GoBack(void); + +uint8 GetNumberOfMenuOptions(int screen); + +// !!! We're now moved to MenuScreensCustom.cpp, which houses an array that keeps all original+custom options. +// But you can still use the APIs below, and manipulate aScreens while in game. + +// Limits: +// The code relies on that you won't use more then NUM_MENUROWS(18) options on one page, and won't exceed the MENUPAGES of pages. +// Also congrats if you can make 18 options visible at once. + +// Texts: +// All text parameters accept char[8] GXT key. + +// Execute direction: +// All of the calls below eventually manipulate the aScreens array, so keep in mind to add/replace options in order, +// i.e. don't set cursor to 8 first and then 3. + + +// -- Placing the cursor to append/overwrite option +// +// Done via FrontendOptionSetCursor(screen, position, overwrite = false), parameters explained below: +// Screen: as the name suggests. Also accepts the screen IDs returned from FrontendScreenAdd. +// Option: if positive, next AddOption call will put the option to there and progress the cursor. +// if negative, cursor will be placed on bottom-(pos+1), so -1 means the very bottom, -2 means before the back button etc. +// Overwrite: Use to overwrite the options, not appending a new one. AddOption calls will still progress the cursor. + +void FrontendOptionSetCursor(int screen, int8 option, bool overwrite = false); + +// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveCat and saveKey param. obv), otherwise pass nil/0 +void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE); +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat = nil, const char* saveKey = nil, bool disableIfGameLoaded = false); +void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat = nil, const char* saveKey = nil); + +// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT +uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil); +#endif diff --git a/src/extras/ini_parser.hpp b/src/extras/ini_parser.hpp index 99acf1ee..7bea024c 100644 --- a/src/extras/ini_parser.hpp +++ b/src/extras/ini_parser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Denilson das Mercês Amorim <dma_2012@hotmail.com> + * Copyright (c) 2013-2015 Denilson das Mercês Amorim <dma_2012@hotmail.com> * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -158,6 +158,25 @@ namespace linb /* Too lazy to continue this container... If you need more methods, just add it */ + // re3 + void remove(const string_type& sect, const key_type& key) + { + auto it = this->find(sect); + if(it != this->end()) + { + it->second.erase(key); + } + } + + int category_size(const string_type& sect) + { + auto it = this->find(sect); + if(it != this->end()) + { + return it->second.size(); + } + return 0; + } #if 1 bool read_file(const char_type* filename) diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp index 2ea08141..03010267 100644 --- a/src/extras/postfx.cpp +++ b/src/extras/postfx.cpp @@ -1,5 +1,4 @@ -#define WITHWINDOWS -#define WITH_D3D +#define WITHD3D #include "common.h" #ifdef EXTENDED_COLOURFILTER diff --git a/src/extras/inttypes.h b/src/extras/re3_inttypes.h index bf0c53e2..bf0c53e2 100644 --- a/src/extras/inttypes.h +++ b/src/extras/re3_inttypes.h diff --git a/src/extras/screendroplets.cpp b/src/extras/screendroplets.cpp index 2d34cdcb..74c44da0 100644 --- a/src/extras/screendroplets.cpp +++ b/src/extras/screendroplets.cpp @@ -1,4 +1,4 @@ -#define WITH_D3D +#define WITHD3D #include "common.h" #ifdef SCREEN_DROPLETS @@ -8,11 +8,11 @@ #endif #include "General.h" -#include "Main.h" +#include "main.h" #include "RwHelper.h" -#include "Main.h" #include "Timer.h" #include "Camera.h" +#include "World.h" #include "ZoneCull.h" #include "Weather.h" #include "ParticleObject.h" @@ -76,11 +76,36 @@ ScreenDroplets::Initialise(void) ms_splashObject = nil; } +// Create white circle mask for rain drops +static RwTexture* +CreateDropMask(int32 size) +{ + RwImage *img = RwImageCreate(size, size, 32); + RwImageAllocatePixels(img); + + uint8 *pixels = RwImageGetPixels(img); + int32 stride = RwImageGetStride(img); + + for(int y = 0; y < size; y++){ + float yf = ((y + 0.5f)/size - 0.5f)*2.0f; + for(int x = 0; x < size; x++){ + float xf = ((x + 0.5f)/size - 0.5f)*2.0f; + memset(&pixels[y*stride + x*4], xf*xf + yf*yf < 1.0f ? 0xFF : 0x00, 4); + } + } + + int32 width, height, depth, format; + RwImageFindRasterFormat(img, rwRASTERTYPETEXTURE, &width, &height, &depth, &format); + RwRaster *ras = RwRasterCreate(width, height, depth, format); + RwRasterSetFromImage(ras, img); + RwImageDestroy(img); + return RwTextureCreate(ras); +} + void ScreenDroplets::InitDraw(void) { - if(CustomPipes::neoTxd) - ms_maskTex = CustomPipes::neoTxd->find("dropmask"); + ms_maskTex = CreateDropMask(64); ms_screenTex = RwTextureCreate(nil); RwTextureSetFilterMode(ms_screenTex, rwFILTERLINEAR); @@ -366,7 +391,7 @@ void ScreenDroplets::RegisterSplash(CParticleObject *pobj) { CVector dist = pobj->GetPosition() - ms_prevCamPos; - if(dist.MagnitudeSqr() < 20.0f){ + if(dist.MagnitudeSqr() < 50.0f){ // 20 originally ms_splashDuration = 14; ms_splashObject = pobj; } @@ -384,15 +409,16 @@ ScreenDroplets::ProcessCameraMovement(void) ms_prevCamUp = camUp; ms_prevCamPos = camPos; - ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, (RwV3d*)&ms_camMoveDelta); - ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, (RwV3d*)&ms_camMoveDelta); - ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, (RwV3d*)&ms_camMoveDelta); + ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, &ms_camMoveDelta); + ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, &ms_camMoveDelta); + ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, &ms_camMoveDelta); ms_screenMoveDelta *= 10.0f; ms_screenMoveDist = ms_screenMoveDelta.Magnitude2D(); uint16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; bool isTopDown = mode == CCam::MODE_TOPDOWN || mode == CCam::MODE_GTACLASSIC || mode == CCam::MODE_TOP_DOWN_PED; - bool isLookingInDirection = CPad::GetPad(0)->GetLookBehindForCar() || CPad::GetPad(0)->GetLookLeft() || CPad::GetPad(0)->GetLookRight(); + bool isLookingInDirection = FindPlayerVehicle() && mode == CCam::MODE_1STPERSON && + (CPad::GetPad(0)->GetLookBehindForCar() || CPad::GetPad(0)->GetLookLeft() || CPad::GetPad(0)->GetLookRight()); ms_enabled = !isTopDown && !isLookingInDirection; ms_movingEnabled = !isTopDown && !isLookingInDirection; diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index b04f7c7e..18a27ec1 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -1,5 +1,5 @@ #define _CRT_SECURE_NO_WARNINGS -#define WITH_D3D +#define WITH_D3D // not WITHD3D, so it's librw define #include <rwcore.h> #include <rpworld.h> #include <rpmatfx.h> @@ -14,11 +14,17 @@ using namespace rw; RwUInt8 RwObjectGetType(const RwObject *obj) { return obj->type; } +RwFrame* rwObjectGetParent(const RwObject *obj) { return (RwFrame*)obj->parent; } -void *RwMalloc(size_t size) { return malloc(size); } -void *RwCalloc(size_t numObj, size_t sizeObj) { return calloc(numObj, sizeObj); } -void RwFree(void *mem) { free(mem); } +void *RwMalloc(size_t size) { return engine->memfuncs.rwmalloc(size, 0); } +void *RwCalloc(size_t numObj, size_t sizeObj) { + void *mem = RwMalloc(numObj*sizeObj); + if(mem) + memset(mem, 0, numObj*sizeObj); + return mem; +} +void RwFree(void *mem) { engine->memfuncs.rwfree(mem); } //RwReal RwV3dNormalize(RwV3d * out, const RwV3d * in); @@ -166,8 +172,8 @@ RwFrame *RwCameraGetFrame(const RwCamera *camera) { return camera->getFrame( RwImage *RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth) { return Image::create(width, height, depth); } RwBool RwImageDestroy(RwImage * image) { image->destroy(); return true; } -RwImage *RwImageAllocatePixels(RwImage * image); -RwImage *RwImageFreePixels(RwImage * image); +RwImage *RwImageAllocatePixels(RwImage * image) { image->allocate(); return image; } +RwImage *RwImageFreePixels(RwImage * image) { image->free(); return image; } RwImage *RwImageCopy(RwImage * destImage, const RwImage * sourceImage); RwImage *RwImageResize(RwImage * image, RwInt32 width, RwInt32 height); RwImage *RwImageApplyMask(RwImage * image, const RwImage * mask); @@ -182,10 +188,10 @@ RwImage *RwImageSetPixels(RwImage * image, RwUInt8 * pixels) { image->pixels RwImage *RwImageSetPalette(RwImage * image, RwRGBA * palette) { image->palette = (uint8*)palette; return image; } RwInt32 RwImageGetWidth(const RwImage * image) { return image->width; } RwInt32 RwImageGetHeight(const RwImage * image) { return image->height; } -RwInt32 RwImageGetDepth(const RwImage * image); -RwInt32 RwImageGetStride(const RwImage * image); -RwUInt8 *RwImageGetPixels(const RwImage * image); -RwRGBA *RwImageGetPalette(const RwImage * image); +RwInt32 RwImageGetDepth(const RwImage * image) { return image->depth; } +RwInt32 RwImageGetStride(const RwImage * image) { return image->stride; } +RwUInt8 *RwImageGetPixels(const RwImage * image) { return image->pixels; } +RwRGBA *RwImageGetPalette(const RwImage * image) { return (RwRGBA*)image->palette; } RwUInt32 RwRGBAToPixel(RwRGBA * rgbIn, RwInt32 rasterFormat); RwRGBA *RwRGBASetFromPixel(RwRGBA * rgbOut, RwUInt32 pixelValue, RwInt32 rasterFormat); RwBool RwImageSetGamma(RwReal gammaValue); @@ -537,8 +543,27 @@ RwBool RwRenderStateSet(RwRenderState state, void *value) } } +static rw::MemoryFunctions gMemfuncs; +static void *(*real_malloc)(size_t size); +static void *(*real_realloc)(void *mem, size_t newSize); +static void *mallocWrap(size_t sz, uint32 hint) { if(sz == 0) return nil; return real_malloc(sz); } +static void *reallocWrap(void *p, size_t sz, uint32 hint) { return real_realloc(p, sz); } + + // WARNING: unused parameters -RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { Engine::init(); return true; } +RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { + if(memFuncs){ + real_malloc = memFuncs->rwmalloc; + real_realloc = memFuncs->rwrealloc; + gMemfuncs.rwmalloc = mallocWrap; + gMemfuncs.rwrealloc = reallocWrap; + gMemfuncs.rwfree = memFuncs->rwfree; + Engine::init(&gMemfuncs); + }else{ + Engine::init(nil); + } + return true; +} // TODO: this is platform dependent RwBool RwEngineOpen(RwEngineOpenParams *initParams) { static EngineOpenParams openParams; @@ -939,3 +964,12 @@ RtCharset *RtCharsetSetColors(RtCharset * charSet, const RwRGBA * foreGround, RtCharset *RtCharsetGetDesc(RtCharset * charset, RtCharsetDesc * desc) { *desc = charset->desc; return charset; } RtCharset *RtCharsetCreate(const RwRGBA * foreGround, const RwRGBA * backGround) { return Charset::create(foreGround, backGround); } RwBool RtCharsetDestroy(RtCharset * charSet) { charSet->destroy(); return true; } + + + +#include <rpanisot.h> + +RwInt8 RpAnisotGetMaxSupportedMaxAnisotropy(void) { return rw::getMaxSupportedMaxAnisotropy(); } +RwTexture *RpAnisotTextureSetMaxAnisotropy(RwTexture *tex, RwInt8 val) { tex->setMaxAnisotropy(val); return tex; } +RwInt8 RpAnisotTextureGetMaxAnisotropy(RwTexture *tex) { return tex->getMaxAnisotropy(); } +RwBool RpAnisotPluginAttach(void) { rw::registerAnisotropyPlugin(); return true; } diff --git a/src/fakerw/rpanisot.h b/src/fakerw/rpanisot.h new file mode 100644 index 00000000..a886512f --- /dev/null +++ b/src/fakerw/rpanisot.h @@ -0,0 +1,6 @@ +#pragma once + +RwInt8 RpAnisotGetMaxSupportedMaxAnisotropy(void); +RwTexture *RpAnisotTextureSetMaxAnisotropy(RwTexture *tex, RwInt8 val); +RwInt8 RpAnisotTextureGetMaxAnisotropy(RwTexture *tex); +RwBool RpAnisotPluginAttach(void); diff --git a/src/fakerw/rwplcore.h b/src/fakerw/rwplcore.h index 79c745b6..69c921cc 100644 --- a/src/fakerw/rwplcore.h +++ b/src/fakerw/rwplcore.h @@ -108,12 +108,12 @@ enum RwCorePluginID //struct RwObject; typedef rw::Object RwObject; +typedef rw::Frame RwFrame; typedef RwObject *(*RwObjectCallBack)(RwObject *object, void *data); RwUInt8 RwObjectGetType(const RwObject *obj); - - +RwFrame* rwObjectGetParent(const RwObject *obj); #define rwsprintf sprintf #define rwvsprintf vsprintf @@ -141,15 +141,15 @@ RwUInt8 RwObjectGetType(const RwObject *obj); *********************************************** */ -struct RwMemoryFunctions; -/* +struct RwMemoryFunctions { + // NB: from RW 3.6 on the allocating functions take + // a hint parameter! void *(*rwmalloc)(size_t size); void (*rwfree)(void *mem); void *(*rwrealloc)(void *mem, size_t newSize); void *(*rwcalloc)(size_t numObj, size_t sizeObj); }; -*/ void *RwMalloc(size_t size); void RwFree(void *mem); diff --git a/src/math/Matrix.cpp b/src/math/Matrix.cpp index 3ac3e2b9..c0d909cb 100644 --- a/src/math/Matrix.cpp +++ b/src/math/Matrix.cpp @@ -60,14 +60,20 @@ CMatrix::Detach(void) void CMatrix::Update(void) { - m_matrix = *m_attachment; + GetRight() = m_attachment->right; + GetForward() = m_attachment->up; + GetUp() = m_attachment->at; + GetPosition() = m_attachment->pos; } void CMatrix::UpdateRW(void) { if (m_attachment) { - *m_attachment = m_matrix; + m_attachment->right = GetRight(); + m_attachment->up = GetForward(); + m_attachment->at = GetUp(); + m_attachment->pos = GetPosition(); RwMatrixUpdate(m_attachment); } } @@ -75,104 +81,96 @@ CMatrix::UpdateRW(void) void CMatrix::operator=(CMatrix const &rhs) { - m_matrix = rhs.m_matrix; + memcpy(this, &rhs, sizeof(f)); if (m_attachment) UpdateRW(); } void -CMatrix::CopyOnlyMatrix(CMatrix *other) +CMatrix::CopyOnlyMatrix(const CMatrix &other) { - m_matrix = other->m_matrix; + memcpy(this, &other, sizeof(f)); } CMatrix & CMatrix::operator+=(CMatrix const &rhs) { - m_matrix.right.x += rhs.m_matrix.right.x; - m_matrix.up.x += rhs.m_matrix.up.x; - m_matrix.at.x += rhs.m_matrix.at.x; - m_matrix.right.y += rhs.m_matrix.right.y; - m_matrix.up.y += rhs.m_matrix.up.y; - m_matrix.at.y += rhs.m_matrix.at.y; - m_matrix.right.z += rhs.m_matrix.right.z; - m_matrix.up.z += rhs.m_matrix.up.z; - m_matrix.at.z += rhs.m_matrix.at.z; - m_matrix.pos.x += rhs.m_matrix.pos.x; - m_matrix.pos.y += rhs.m_matrix.pos.y; - m_matrix.pos.z += rhs.m_matrix.pos.z; + GetRight() += rhs.GetRight(); + GetForward() += rhs.GetForward(); + GetUp() += rhs.GetUp(); + GetPosition() += rhs.GetPosition(); return *this; } void CMatrix::SetUnity(void) { - m_matrix.right.x = 1.0f; - m_matrix.right.y = 0.0f; - m_matrix.right.z = 0.0f; - m_matrix.up.x = 0.0f; - m_matrix.up.y = 1.0f; - m_matrix.up.z = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = 1.0f; - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + rx = 1.0f; + ry = 0.0f; + rz = 0.0f; + fx = 0.0f; + fy = 1.0f; + fz = 0.0f; + ux = 0.0f; + uy = 0.0f; + uz = 1.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } void CMatrix::ResetOrientation(void) { - m_matrix.right.x = 1.0f; - m_matrix.right.y = 0.0f; - m_matrix.right.z = 0.0f; - m_matrix.up.x = 0.0f; - m_matrix.up.y = 1.0f; - m_matrix.up.z = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = 1.0f; + rx = 1.0f; + ry = 0.0f; + rz = 0.0f; + fx = 0.0f; + fy = 1.0f; + fz = 0.0f; + ux = 0.0f; + uy = 0.0f; + uz = 1.0f; } void CMatrix::SetScale(float s) { - m_matrix.right.x = s; - m_matrix.right.y = 0.0f; - m_matrix.right.z = 0.0f; + rx = s; + ry = 0.0f; + rz = 0.0f; - m_matrix.up.x = 0.0f; - m_matrix.up.y = s; - m_matrix.up.z = 0.0f; + fx = 0.0f; + fy = s; + fz = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = s; + ux = 0.0f; + uy = 0.0f; + uz = s; - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } void CMatrix::SetTranslate(float x, float y, float z) { - m_matrix.right.x = 1.0f; - m_matrix.right.y = 0.0f; - m_matrix.right.z = 0.0f; + rx = 1.0f; + ry = 0.0f; + rz = 0.0f; - m_matrix.up.x = 0.0f; - m_matrix.up.y = 1.0f; - m_matrix.up.z = 0.0f; + fx = 0.0f; + fy = 1.0f; + fz = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = 1.0f; + ux = 0.0f; + uy = 0.0f; + uz = 1.0f; - m_matrix.pos.x = x; - m_matrix.pos.y = y; - m_matrix.pos.z = z; + px = x; + py = y; + pz = z; } void @@ -181,17 +179,17 @@ CMatrix::SetRotateXOnly(float angle) float c = Cos(angle); float s = Sin(angle); - m_matrix.right.x = 1.0f; - m_matrix.right.y = 0.0f; - m_matrix.right.z = 0.0f; + rx = 1.0f; + ry = 0.0f; + rz = 0.0f; - m_matrix.up.x = 0.0f; - m_matrix.up.y = c; - m_matrix.up.z = s; + fx = 0.0f; + fy = c; + fz = s; - m_matrix.at.x = 0.0f; - m_matrix.at.y = -s; - m_matrix.at.z = c; + ux = 0.0f; + uy = -s; + uz = c; } void @@ -200,17 +198,17 @@ CMatrix::SetRotateYOnly(float angle) float c = Cos(angle); float s = Sin(angle); - m_matrix.right.x = c; - m_matrix.right.y = 0.0f; - m_matrix.right.z = -s; + rx = c; + ry = 0.0f; + rz = -s; - m_matrix.up.x = 0.0f; - m_matrix.up.y = 1.0f; - m_matrix.up.z = 0.0f; + fx = 0.0f; + fy = 1.0f; + fz = 0.0f; - m_matrix.at.x = s; - m_matrix.at.y = 0.0f; - m_matrix.at.z = c; + ux = s; + uy = 0.0f; + uz = c; } void @@ -219,26 +217,26 @@ CMatrix::SetRotateZOnly(float angle) float c = Cos(angle); float s = Sin(angle); - m_matrix.right.x = c; - m_matrix.right.y = s; - m_matrix.right.z = 0.0f; + rx = c; + ry = s; + rz = 0.0f; - m_matrix.up.x = -s; - m_matrix.up.y = c; - m_matrix.up.z = 0.0f; + fx = -s; + fy = c; + fz = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = 1.0f; + ux = 0.0f; + uy = 0.0f; + uz = 1.0f; } void CMatrix::SetRotateX(float angle) { SetRotateXOnly(angle); - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } @@ -246,18 +244,18 @@ void CMatrix::SetRotateY(float angle) { SetRotateYOnly(angle); - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } void CMatrix::SetRotateZ(float angle) { SetRotateZOnly(angle); - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } void @@ -270,21 +268,21 @@ CMatrix::SetRotate(float xAngle, float yAngle, float zAngle) float cZ = Cos(zAngle); float sZ = Sin(zAngle); - m_matrix.right.x = cZ * cY - (sZ * sX) * sY; - m_matrix.right.y = (cZ * sX) * sY + sZ * cY; - m_matrix.right.z = -cX * sY; + rx = cZ * cY - (sZ * sX) * sY; + ry = (cZ * sX) * sY + sZ * cY; + rz = -cX * sY; - m_matrix.up.x = -sZ * cX; - m_matrix.up.y = cZ * cX; - m_matrix.up.z = sX; + fx = -sZ * cX; + fy = cZ * cX; + fz = sX; - m_matrix.at.x = (sZ * sX) * cY + cZ * sY; - m_matrix.at.y = sZ * sY - (cZ * sX) * cY; - m_matrix.at.z = cX * cY; + ux = (sZ * sX) * cY + cZ * sY; + uy = sZ * sY - (cZ * sX) * cY; + uz = cX * cY; - m_matrix.pos.x = 0.0f; - m_matrix.pos.y = 0.0f; - m_matrix.pos.z = 0.0f; + px = 0.0f; + py = 0.0f; + pz = 0.0f; } void @@ -293,23 +291,23 @@ CMatrix::RotateX(float x) float c = Cos(x); float s = Sin(x); - float ry = m_matrix.right.y; - float rz = m_matrix.right.z; - float uy = m_matrix.up.y; - float uz = m_matrix.up.z; - float ay = m_matrix.at.y; - float az = m_matrix.at.z; - float py = m_matrix.pos.y; - float pz = m_matrix.pos.z; - - m_matrix.right.y = c * ry - s * rz; - m_matrix.right.z = c * rz + s * ry; - m_matrix.up.y = c * uy - s * uz; - m_matrix.up.z = c * uz + s * uy; - m_matrix.at.y = c * ay - s * az; - m_matrix.at.z = c * az + s * ay; - m_matrix.pos.y = c * py - s * pz; - m_matrix.pos.z = c * pz + s * py; + float ry = this->ry; + float rz = this->rz; + float uy = this->fy; + float uz = this->fz; + float ay = this->uy; + float az = this->uz; + float py = this->py; + float pz = this->pz; + + this->ry = c * ry - s * rz; + this->rz = c * rz + s * ry; + this->fy = c * uy - s * uz; + this->fz = c * uz + s * uy; + this->uy = c * ay - s * az; + this->uz = c * az + s * ay; + this->py = c * py - s * pz; + this->pz = c * pz + s * py; } void @@ -318,23 +316,23 @@ CMatrix::RotateY(float y) float c = Cos(y); float s = Sin(y); - float rx = m_matrix.right.x; - float rz = m_matrix.right.z; - float ux = m_matrix.up.x; - float uz = m_matrix.up.z; - float ax = m_matrix.at.x; - float az = m_matrix.at.z; - float px = m_matrix.pos.x; - float pz = m_matrix.pos.z; - - m_matrix.right.x = c * rx + s * rz; - m_matrix.right.z = c * rz - s * rx; - m_matrix.up.x = c * ux + s * uz; - m_matrix.up.z = c * uz - s * ux; - m_matrix.at.x = c * ax + s * az; - m_matrix.at.z = c * az - s * ax; - m_matrix.pos.x = c * px + s * pz; - m_matrix.pos.z = c * pz - s * px; + float rx = this->rx; + float rz = this->rz; + float ux = this->fx; + float uz = this->fz; + float ax = this->ux; + float az = this->uz; + float px = this->px; + float pz = this->pz; + + this->rx = c * rx + s * rz; + this->rz = c * rz - s * rx; + this->fx = c * ux + s * uz; + this->fz = c * uz - s * ux; + this->ux = c * ax + s * az; + this->uz = c * az - s * ax; + this->px = c * px + s * pz; + this->pz = c * pz - s * px; } void @@ -343,23 +341,23 @@ CMatrix::RotateZ(float z) float c = Cos(z); float s = Sin(z); - float ry = m_matrix.right.y; - float rx = m_matrix.right.x; - float uy = m_matrix.up.y; - float ux = m_matrix.up.x; - float ay = m_matrix.at.y; - float ax = m_matrix.at.x; - float py = m_matrix.pos.y; - float px = m_matrix.pos.x; + float ry = this->ry; + float rx = this->rx; + float uy = this->fy; + float ux = this->fx; + float ay = this->uy; + float ax = this->ux; + float py = this->py; + float px = this->px; - m_matrix.right.x = c * rx - s * ry; - m_matrix.right.y = c * ry + s * rx; - m_matrix.up.x = c * ux - s * uy; - m_matrix.up.y = c * uy + s * ux; - m_matrix.at.x = c * ax - s * ay; - m_matrix.at.y = c * ay + s * ax; - m_matrix.pos.x = c * px - s * py; - m_matrix.pos.y = c * py + s * px; + this->rx = c * rx - s * ry; + this->ry = c * ry + s * rx; + this->fx = c * ux - s * uy; + this->fy = c * uy + s * ux; + this->ux = c * ax - s * ay; + this->uy = c * ay + s * ax; + this->px = c * px - s * py; + this->py = c * py + s * px; } @@ -373,18 +371,18 @@ CMatrix::Rotate(float x, float y, float z) float cZ = Cos(z); float sZ = Sin(z); - float rx = m_matrix.right.x; - float ry = m_matrix.right.y; - float rz = m_matrix.right.z; - float ux = m_matrix.up.x; - float uy = m_matrix.up.y; - float uz = m_matrix.up.z; - float ax = m_matrix.at.x; - float ay = m_matrix.at.y; - float az = m_matrix.at.z; - float px = m_matrix.pos.x; - float py = m_matrix.pos.y; - float pz = m_matrix.pos.z; + float rx = this->rx; + float ry = this->ry; + float rz = this->rz; + float ux = this->fx; + float uy = this->fy; + float uz = this->fz; + float ax = this->ux; + float ay = this->uy; + float az = this->uz; + float px = this->px; + float py = this->py; + float pz = this->pz; float x1 = cZ * cY - (sZ * sX) * sY; float x2 = (cZ * sX) * sY + sZ * cY; @@ -396,18 +394,18 @@ CMatrix::Rotate(float x, float y, float z) float z2 = sZ * sY - (cZ * sX) * cY; float z3 = cX * cY; - m_matrix.right.x = x1 * rx + y1 * ry + z1 * rz; - m_matrix.right.y = x2 * rx + y2 * ry + z2 * rz; - m_matrix.right.z = x3 * rx + y3 * ry + z3 * rz; - m_matrix.up.x = x1 * ux + y1 * uy + z1 * uz; - m_matrix.up.y = x2 * ux + y2 * uy + z2 * uz; - m_matrix.up.z = x3 * ux + y3 * uy + z3 * uz; - m_matrix.at.x = x1 * ax + y1 * ay + z1 * az; - m_matrix.at.y = x2 * ax + y2 * ay + z2 * az; - m_matrix.at.z = x3 * ax + y3 * ay + z3 * az; - m_matrix.pos.x = x1 * px + y1 * py + z1 * pz; - m_matrix.pos.y = x2 * px + y2 * py + z2 * pz; - m_matrix.pos.z = x3 * px + y3 * py + z3 * pz; + this->rx = x1 * rx + y1 * ry + z1 * rz; + this->ry = x2 * rx + y2 * ry + z2 * rz; + this->rz = x3 * rx + y3 * ry + z3 * rz; + this->fx = x1 * ux + y1 * uy + z1 * uz; + this->fy = x2 * ux + y2 * uy + z2 * uz; + this->fz = x3 * ux + y3 * uy + z3 * uz; + this->ux = x1 * ax + y1 * ay + z1 * az; + this->uy = x2 * ax + y2 * ay + z2 * az; + this->uz = x3 * ax + y3 * ay + z3 * az; + this->px = x1 * px + y1 * py + z1 * pz; + this->py = x2 * px + y2 * py + z2 * pz; + this->pz = x3 * px + y3 * py + z3 * pz; } CMatrix & @@ -436,21 +434,18 @@ operator*(const CMatrix &m1, const CMatrix &m2) { // TODO: VU0 code CMatrix out; - RwMatrix *dst = &out.m_matrix; - const RwMatrix *src1 = &m1.m_matrix; - const RwMatrix *src2 = &m2.m_matrix; - dst->right.x = src1->right.x * src2->right.x + src1->up.x * src2->right.y + src1->at.x * src2->right.z; - dst->right.y = src1->right.y * src2->right.x + src1->up.y * src2->right.y + src1->at.y * src2->right.z; - dst->right.z = src1->right.z * src2->right.x + src1->up.z * src2->right.y + src1->at.z * src2->right.z; - dst->up.x = src1->right.x * src2->up.x + src1->up.x * src2->up.y + src1->at.x * src2->up.z; - dst->up.y = src1->right.y * src2->up.x + src1->up.y * src2->up.y + src1->at.y * src2->up.z; - dst->up.z = src1->right.z * src2->up.x + src1->up.z * src2->up.y + src1->at.z * src2->up.z; - dst->at.x = src1->right.x * src2->at.x + src1->up.x * src2->at.y + src1->at.x * src2->at.z; - dst->at.y = src1->right.y * src2->at.x + src1->up.y * src2->at.y + src1->at.y * src2->at.z; - dst->at.z = src1->right.z * src2->at.x + src1->up.z * src2->at.y + src1->at.z * src2->at.z; - dst->pos.x = src1->right.x * src2->pos.x + src1->up.x * src2->pos.y + src1->at.x * src2->pos.z + src1->pos.x; - dst->pos.y = src1->right.y * src2->pos.x + src1->up.y * src2->pos.y + src1->at.y * src2->pos.z + src1->pos.y; - dst->pos.z = src1->right.z * src2->pos.x + src1->up.z * src2->pos.y + src1->at.z * src2->pos.z + src1->pos.z; + out.rx = m1.rx * m2.rx + m1.fx * m2.ry + m1.ux * m2.rz; + out.ry = m1.ry * m2.rx + m1.fy * m2.ry + m1.uy * m2.rz; + out.rz = m1.rz * m2.rx + m1.fz * m2.ry + m1.uz * m2.rz; + out.fx = m1.rx * m2.fx + m1.fx * m2.fy + m1.ux * m2.fz; + out.fy = m1.ry * m2.fx + m1.fy * m2.fy + m1.uy * m2.fz; + out.fz = m1.rz * m2.fx + m1.fz * m2.fy + m1.uz * m2.fz; + out.ux = m1.rx * m2.ux + m1.fx * m2.uy + m1.ux * m2.uz; + out.uy = m1.ry * m2.ux + m1.fy * m2.uy + m1.uy * m2.uz; + out.uz = m1.rz * m2.ux + m1.fz * m2.uy + m1.uz * m2.uz; + out.px = m1.rx * m2.px + m1.fx * m2.py + m1.ux * m2.pz + m1.px; + out.py = m1.ry * m2.px + m1.fy * m2.py + m1.uy * m2.pz + m1.py; + out.pz = m1.rz * m2.px + m1.fz * m2.py + m1.uz * m2.pz + m1.pz; return out; } @@ -458,43 +453,50 @@ CMatrix & Invert(const CMatrix &src, CMatrix &dst) { // TODO: VU0 code - float (*scr_fm)[4] = (float (*)[4])&src.m_matrix; - float (*dst_fm)[4] = (float (*)[4])&dst.m_matrix; + dst.f[3][0] = dst.f[3][1] = dst.f[3][2] = 0.0f; - dst_fm[3][0] = dst_fm[3][1] = dst_fm[3][2] = 0.0f; + dst.f[0][0] = src.f[0][0]; + dst.f[0][1] = src.f[1][0]; + dst.f[0][2] = src.f[2][0]; - dst_fm[0][0] = scr_fm[0][0]; - dst_fm[0][1] = scr_fm[1][0]; - dst_fm[0][2] = scr_fm[2][0]; + dst.f[1][0] = src.f[0][1]; + dst.f[1][1] = src.f[1][1]; + dst.f[1][2] = src.f[2][1]; - dst_fm[1][0] = scr_fm[0][1]; - dst_fm[1][1] = scr_fm[1][1]; - dst_fm[1][2] = scr_fm[2][1]; + dst.f[2][0] = src.f[0][2]; + dst.f[2][1] = src.f[1][2]; + dst.f[2][2] = src.f[2][2]; - dst_fm[2][0] = scr_fm[0][2]; - dst_fm[2][1] = scr_fm[1][2]; - dst_fm[2][2] = scr_fm[2][2]; + dst.f[3][0] += dst.f[0][0] * src.f[3][0]; + dst.f[3][1] += dst.f[0][1] * src.f[3][0]; + dst.f[3][2] += dst.f[0][2] * src.f[3][0]; - dst_fm[3][0] += dst_fm[0][0] * scr_fm[3][0]; - dst_fm[3][1] += dst_fm[0][1] * scr_fm[3][0]; - dst_fm[3][2] += dst_fm[0][2] * scr_fm[3][0]; + dst.f[3][0] += dst.f[1][0] * src.f[3][1]; + dst.f[3][1] += dst.f[1][1] * src.f[3][1]; + dst.f[3][2] += dst.f[1][2] * src.f[3][1]; - dst_fm[3][0] += dst_fm[1][0] * scr_fm[3][1]; - dst_fm[3][1] += dst_fm[1][1] * scr_fm[3][1]; - dst_fm[3][2] += dst_fm[1][2] * scr_fm[3][1]; + dst.f[3][0] += dst.f[2][0] * src.f[3][2]; + dst.f[3][1] += dst.f[2][1] * src.f[3][2]; + dst.f[3][2] += dst.f[2][2] * src.f[3][2]; - dst_fm[3][0] += dst_fm[2][0] * scr_fm[3][2]; - dst_fm[3][1] += dst_fm[2][1] * scr_fm[3][2]; - dst_fm[3][2] += dst_fm[2][2] * scr_fm[3][2]; - - dst_fm[3][0] = -dst_fm[3][0]; - dst_fm[3][1] = -dst_fm[3][1]; - dst_fm[3][2] = -dst_fm[3][2]; + dst.f[3][0] = -dst.f[3][0]; + dst.f[3][1] = -dst.f[3][1]; + dst.f[3][2] = -dst.f[3][2]; return dst; } +void +CMatrix::CopyToRwMatrix(RwMatrix* matrix) +{ + matrix->right = GetRight(); + matrix->up = GetForward(); + matrix->at = GetUp(); + matrix->pos = GetPosition(); + RwMatrixUpdate(matrix); +} + CMatrix Invert(const CMatrix &matrix) { diff --git a/src/math/Matrix.h b/src/math/Matrix.h index bf811af7..6da4c767 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -3,9 +3,36 @@ class CMatrix { public: - RwMatrix m_matrix; +#ifdef GTA_PS2 + union + { + float f[4][4]; + struct + { + float rx, ry, rz; + RwMatrix *m_attachment; + float fx, fy, fz; + bool m_hasRwMatrix; // are we the owner? + float ux, uy, uz, uw; + float px, py, pz, pw; + }; + }; +#else + union + { + float f[4][4]; + struct + { + float rx, ry, rz, rw; + float fx, fy, fz, fw; + float ux, uy, uz, uw; + float px, py, pz, pw; + }; + }; + RwMatrix *m_attachment; bool m_hasRwMatrix; // are we the owner? +#endif CMatrix(void); CMatrix(CMatrix const &m); @@ -23,47 +50,41 @@ public: void UpdateRW(void); void operator=(CMatrix const &rhs); CMatrix &operator+=(CMatrix const &rhs); -#ifdef RWCORE_H - operator RwMatrix (void) const { - return m_matrix; - } - - operator RwMatrix *(void) { - return &m_matrix; - } -#endif CMatrix &operator*=(CMatrix const &rhs); - const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; } - CVector& GetPosition(void) { return *(CVector*)&m_matrix.pos; } - CVector &GetRight(void) { return *(CVector*)&m_matrix.right; } - CVector &GetForward(void) { return *(CVector*)&m_matrix.up; } - CVector &GetUp(void) { return *(CVector*)&m_matrix.at; } + CVector &GetPosition(void) { return *(CVector*)&px; } + CVector &GetRight(void) { return *(CVector*)℞ } + CVector &GetForward(void) { return *(CVector*)&fx; } + CVector &GetUp(void) { return *(CVector*)&ux; } + + const CVector &GetPosition(void) const { return *(CVector*)&px; } + const CVector &GetRight(void) const { return *(CVector*)℞ } + const CVector &GetForward(void) const { return *(CVector*)&fx; } + const CVector &GetUp(void) const { return *(CVector*)&ux; } + void SetTranslate(float x, float y, float z); void SetTranslate(const CVector &trans){ SetTranslate(trans.x, trans.y, trans.z); } void Translate(float x, float y, float z){ - m_matrix.pos.x += x; - m_matrix.pos.y += y; - m_matrix.pos.z += z; + px += x; + py += y; + pz += z; } void Translate(const CVector &trans){ Translate(trans.x, trans.y, trans.z); } void SetScale(float s); void Scale(float scale) { - float *pFloatMatrix = (float*)&m_matrix; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) - pFloatMatrix[i * 4 + j] *= scale; + f[i][j] *= scale; } void Scale(float sx, float sy, float sz) { - float *pFloatMatrix = (float*)&m_matrix; for (int i = 0; i < 3; i++){ - pFloatMatrix[i * 4 + 0] *= sx; - pFloatMatrix[i * 4 + 1] *= sy; - pFloatMatrix[i * 4 + 2] *= sz; + f[i][0] *= sx; + f[i][1] *= sy; + f[i][2] *= sz; } } @@ -75,17 +96,17 @@ public: float c = Cos(angle); float s = Sin(angle); - m_matrix.right.x = c * scale; - m_matrix.right.y = s * scale; - m_matrix.right.z = 0.0f; + rx = c * scale; + ry = s * scale; + rz = 0.0f; - m_matrix.up.x = -s * scale; - m_matrix.up.y = c * scale; - m_matrix.up.z = 0.0f; + fx = -s * scale; + fy = c * scale; + fz = 0.0f; - m_matrix.at.x = 0.0f; - m_matrix.at.y = 0.0f; - m_matrix.at.z = scale; + ux = 0.0f; + uy = 0.0f; + uz = scale; } void SetRotateX(float angle); void SetRotateY(float angle); @@ -97,22 +118,16 @@ public: void RotateZ(float z); void Reorthogonalise(void); - void CopyOnlyMatrix(CMatrix *other); + void CopyOnlyMatrix(const CMatrix &other); void SetUnity(void); void ResetOrientation(void); - void CopyRwMatrix(RwMatrix *matrix){ - m_matrix = *matrix; - } - void CopyToRwMatrix(RwMatrix *matrix){ - *matrix = m_matrix; - RwMatrixUpdate(matrix); - } + void CopyToRwMatrix(RwMatrix* matrix); void SetTranslateOnly(float x, float y, float z) { - m_matrix.pos.x = x; - m_matrix.pos.y = y; - m_matrix.pos.z = z; + px = x; + py = y; + pz = z; } void SetTranslateOnly(const CVector& pos) { SetTranslateOnly(pos.x, pos.y, pos.z); @@ -126,11 +141,11 @@ CMatrix Invert(const CMatrix &matrix); CMatrix operator*(const CMatrix &m1, const CMatrix &m2); inline CVector MultiplyInverse(const CMatrix &mat, const CVector &vec) { - CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z); + CVector v(vec.x - mat.px, vec.y - mat.py, vec.z - mat.pz); return CVector( - mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z, - mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z, - mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z); + mat.rx * v.x + mat.ry * v.y + mat.rz * v.z, + mat.fx * v.x + mat.fy * v.y + mat.fz * v.z, + mat.ux * v.x + mat.uy * v.y + mat.uz * v.z); } diff --git a/src/math/Quaternion.h b/src/math/Quaternion.h index a5a34626..47c94f7c 100644 --- a/src/math/Quaternion.h +++ b/src/math/Quaternion.h @@ -12,6 +12,11 @@ public: float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; } void Normalise(void); void Multiply(const CQuaternion &q1, const CQuaternion &q2); + void Invert(void){ // Conjugate would have been a better name + x = -x; + y = -y; + z = -z; + } const CQuaternion &operator+=(CQuaternion const &right) { x += right.x; diff --git a/src/math/Rect.h b/src/math/Rect.h index fa8d8de4..e9b25896 100644 --- a/src/math/Rect.h +++ b/src/math/Rect.h @@ -42,13 +42,30 @@ public: bottom += y; top += y; } - void Grow(float r){ + + void Grow(float r) { left -= r; right += r; top -= r; bottom += r; } + void Grow(float l, float r) + { + left -= l; + top -= l; + right += r; + bottom += r; + } + + void Grow(float l, float r, float t, float b) + { + left -= l; + top -= t; + right += r; + bottom += b; + } + float GetWidth(void) { return right - left; } float GetHeight(void) { return bottom - top; } }; diff --git a/src/math/Vector.cpp b/src/math/Vector.cpp index 42e1828e..ee76e555 100644 --- a/src/math/Vector.cpp +++ b/src/math/Vector.cpp @@ -23,24 +23,24 @@ CVector Multiply3x3(const CMatrix &mat, const CVector &vec) { // TODO: VU0 code - return CVector(mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z, - mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z, - mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z); + return CVector(mat.rx * vec.x + mat.fx * vec.y + mat.ux * vec.z, + mat.ry * vec.x + mat.fy * vec.y + mat.uy * vec.z, + mat.rz * vec.x + mat.fz * vec.y + mat.uz * vec.z); } CVector Multiply3x3(const CVector &vec, const CMatrix &mat) { - return CVector(mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z, - mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z, - mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z); + return CVector(mat.rx * vec.x + mat.ry * vec.y + mat.rz * vec.z, + mat.fx * vec.x + mat.fy * vec.y + mat.fz * vec.z, + mat.ux * vec.x + mat.uy * vec.y + mat.uz * vec.z); } CVector operator*(const CMatrix &mat, const CVector &vec) { // TODO: VU0 code - return CVector(mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x, - mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y, - mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z + mat.m_matrix.pos.z); + return CVector(mat.rx * vec.x + mat.fx * vec.y + mat.ux * vec.z + mat.px, + mat.ry * vec.x + mat.fy * vec.y + mat.uy * vec.z + mat.py, + mat.rz * vec.x + mat.fz * vec.y + mat.uz * vec.z + mat.pz); } diff --git a/src/math/Vector.h b/src/math/Vector.h index 4cc2171f..02128454 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -1,23 +1,22 @@ #pragma once -class CVector +class CVector : public RwV3d { public: - float x, y, z; CVector(void) {} - CVector(float x, float y, float z) : x(x), y(y), z(z) {} -#ifdef RWCORE_H - CVector(const RwV3d &v) : x(v.x), y(v.y), z(v.z) {} - - operator RwV3d (void) const { - RwV3d vecRw = { this->x, this->y, this->z }; - return vecRw; + CVector(float x, float y, float z) + { + this->x = x; + this->y = y; + this->z = z; } - - operator RwV3d *(void) { - return (RwV3d*)this; + + CVector(const RwV3d &v) + { + x = v.x; + y = v.y; + z = v.z; } -#endif // (0,1,0) means no rotation. So get right vector and its atan float Heading(void) const { return Atan2(-x, y); } float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); } diff --git a/src/math/VuVector.h b/src/math/VuVector.h index f90818e0..30d62cfc 100644 --- a/src/math/VuVector.h +++ b/src/math/VuVector.h @@ -8,18 +8,7 @@ public: CVuVector(float x, float y, float z) : CVector(x, y, z) {} CVuVector(float x, float y, float z, float w) : CVector(x, y, z), w(w) {} CVuVector(const CVector &v) : CVector(v.x, v.y, v.z) {} -#ifdef RWCORE_H - CVuVector(const RwV3d &v) : CVector(v.x, v.y, v.z) {} - - operator RwV3d (void) const { - RwV3d vecRw = { this->x, this->y, this->z }; - return vecRw; - } - - operator RwV3d *(void) { - return (RwV3d*)this; - } -#endif + CVuVector(const RwV3d &v) : CVector(v) {} /* void Normalise(void) { float sq = MagnitudeSqr(); diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp index 31bb2500..d0f868fa 100644 --- a/src/modelinfo/BaseModelInfo.cpp +++ b/src/modelinfo/BaseModelInfo.cpp @@ -5,8 +5,7 @@ #include "2dEffect.h" #include "BaseModelInfo.h" #include "ModelInfo.h" - -//--MIAMI: file done +#include "ColModel.h" CBaseModelInfo::CBaseModelInfo(ModelInfoType type) { @@ -88,7 +87,7 @@ CBaseModelInfo::Add2dEffect(C2dEffect *fx) if(m_2dEffectsID >= 0) m_num2dEffects++; else{ - m_2dEffectsID = CModelInfo::Get2dEffectStore().getIndex(fx); + m_2dEffectsID = CModelInfo::Get2dEffectStore().GetIndex(fx); m_num2dEffects = 1; } } @@ -97,7 +96,7 @@ C2dEffect* CBaseModelInfo::Get2dEffect(int n) { if(m_2dEffectsID >= 0) - return CModelInfo::Get2dEffectStore().getItem(m_2dEffectsID+n); + return CModelInfo::Get2dEffectStore().GetItem(m_2dEffectsID+n); else return nil; } diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h index e7dd9e4b..2d1dc8ac 100644 --- a/src/modelinfo/BaseModelInfo.h +++ b/src/modelinfo/BaseModelInfo.h @@ -1,10 +1,10 @@ #pragma once -#include "Collision.h" +struct CColModel; #define MAX_MODEL_NAME (21) -enum ModelInfoType : uint8 +enum ModelInfoType { MITYPE_NA, MITYPE_SIMPLE, @@ -17,7 +17,6 @@ enum ModelInfoType : uint8 MITYPE_XTRACOMPS, // unused but still in enum MITYPE_HAND // xbox and mobile }; -VALIDATE_SIZE(ModelInfoType, 1); class C2dEffect; @@ -25,7 +24,7 @@ class CBaseModelInfo { protected: char m_name[MAX_MODEL_NAME]; - ModelInfoType m_type; + uint8 m_type; uint8 m_num2dEffects; bool m_bOwnsColModel; CColModel *m_colModel; @@ -39,29 +38,29 @@ public: virtual ~CBaseModelInfo() {} virtual void Shutdown(void); virtual void DeleteRwObject(void) = 0; - virtual RwObject *CreateInstance(RwMatrix *) = 0; virtual RwObject *CreateInstance(void) = 0; + virtual RwObject *CreateInstance(RwMatrix *) = 0; virtual RwObject *GetRwObject(void) = 0; virtual void SetAnimFile(const char *file) {} virtual void ConvertAnimFileIndex(void) {} virtual int GetAnimFileIndex(void) { return -1; } // one day it becomes virtual - ModelInfoType GetModelType() const { return m_type; } + uint8 GetModelType() const { return m_type; } bool IsBuilding(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; } bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME || m_type == MITYPE_WEAPON; } bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE; } - char *GetName(void) { return m_name; } - void SetName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); } + char *GetModelName(void) { return m_name; } + void SetModelName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); } void SetColModel(CColModel *col, bool owns = false){ m_colModel = col; m_bOwnsColModel = owns; } CColModel *GetColModel(void) { return m_colModel; } bool DoesOwnColModel(void) { return m_bOwnsColModel; } void DeleteCollisionModel(void); void ClearTexDictionary(void) { m_txdSlot = -1; } - short GetObjectID(void) { return m_objectId; } + int16 GetObjectID(void) { return m_objectId; } void SetObjectID(int16 id) { m_objectId = id; } - short GetTxdSlot(void) { return m_txdSlot; } + int16 GetTxdSlot(void) { return m_txdSlot; } void AddRef(void); void RemoveRef(void); void SetTexDictionary(const char *name); diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp index 3fa9a36f..ba18bfa7 100644 --- a/src/modelinfo/ClumpModelInfo.cpp +++ b/src/modelinfo/ClumpModelInfo.cpp @@ -7,8 +7,6 @@ #include "ModelInfo.h" #include "AnimManager.h" -//--MIAMI: file done - void CClumpModelInfo::DeleteRwObject(void) { @@ -150,7 +148,7 @@ CClumpModelInfo::FindFrameFromIdCB(RwFrame *frame, void *data) return assoc->frame ? nil : frame; } -//--MIAMI: unused +// unused RwFrame* CClumpModelInfo::FindFrameFromNameCB(RwFrame *frame, void *data) { diff --git a/src/modelinfo/ModelIndices.cpp b/src/modelinfo/ModelIndices.cpp index 056c3733..98c7fb38 100644 --- a/src/modelinfo/ModelIndices.cpp +++ b/src/modelinfo/ModelIndices.cpp @@ -3,7 +3,7 @@ #include "General.h" #include "ModelIndices.h" -#define X(name, var) int16 var; +#define X(name, var) int16 var = -1; MODELINDICES #undef X diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index 182a0cea..836c4092 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -35,7 +35,7 @@ X("veg_treea1", MI_TREE3) \ X("veg_treeb1", MI_TREE6) \ X("veg_treea3", MI_TREE8) \ - X("doc_crane_cab", MODELID_CRANE_1) \ + X("doc_crane_cab0", MODELID_CRANE_1) \ X("doc_crane_cab01", MODELID_CRANE_2) \ X("doc_crane_cab02", MODELID_CRANE_3) \ X("doc_crane_cab03", MODELID_CRANE_4) \ diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index 961efa84..41515e20 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -5,8 +5,6 @@ #include "ModelIndices.h" #include "ModelInfo.h" -// --MIAMI: file done - CBaseModelInfo *CModelInfo::ms_modelInfoPtrs[MODELINFOSIZE]; CStore<CSimpleModelInfo, SIMPLEMODELSIZE> CModelInfo::ms_simpleModelStore; @@ -33,13 +31,13 @@ CModelInfo::Initialise(void) for(i = 0; i < MODELINFOSIZE; i++) ms_modelInfoPtrs[i] = nil; - ms_2dEffectStore.clear(); - ms_simpleModelStore.clear(); - ms_timeModelStore.clear(); - ms_weaponModelStore.clear(); - ms_clumpModelStore.clear(); - ms_pedModelStore.clear(); - ms_vehicleModelStore.clear(); + ms_2dEffectStore.Clear(); + ms_simpleModelStore.Clear(); + ms_timeModelStore.Clear(); + ms_weaponModelStore.Clear(); + ms_clumpModelStore.Clear(); + ms_pedModelStore.Clear(); + ms_vehicleModelStore.Clear(); m = AddSimpleModel(MI_CAR_DOOR); m->SetColModel(&CTempColModels::ms_colModelDoor1); @@ -109,20 +107,20 @@ CModelInfo::ShutDown(void) for(i = 0; i < ms_2dEffectStore.allocPtr; i++) ms_2dEffectStore.store[i].Shutdown(); - ms_2dEffectStore.clear(); - ms_simpleModelStore.clear(); - ms_timeModelStore.clear(); - ms_weaponModelStore.clear(); - ms_pedModelStore.clear(); - ms_clumpModelStore.clear(); - ms_vehicleModelStore.clear(); + ms_2dEffectStore.Clear(); + ms_simpleModelStore.Clear(); + ms_timeModelStore.Clear(); + ms_weaponModelStore.Clear(); + ms_pedModelStore.Clear(); + ms_clumpModelStore.Clear(); + ms_vehicleModelStore.Clear(); } CSimpleModelInfo* CModelInfo::AddSimpleModel(int id) { CSimpleModelInfo *modelinfo; - modelinfo = CModelInfo::ms_simpleModelStore.alloc(); + modelinfo = CModelInfo::ms_simpleModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->Init(); return modelinfo; @@ -132,7 +130,7 @@ CTimeModelInfo* CModelInfo::AddTimeModel(int id) { CTimeModelInfo *modelinfo; - modelinfo = CModelInfo::ms_timeModelStore.alloc(); + modelinfo = CModelInfo::ms_timeModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->Init(); return modelinfo; @@ -142,7 +140,7 @@ CWeaponModelInfo* CModelInfo::AddWeaponModel(int id) { CWeaponModelInfo *modelinfo; - modelinfo = CModelInfo::ms_weaponModelStore.alloc(); + modelinfo = CModelInfo::ms_weaponModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->Init(); return modelinfo; @@ -152,7 +150,7 @@ CClumpModelInfo* CModelInfo::AddClumpModel(int id) { CClumpModelInfo *modelinfo; - modelinfo = CModelInfo::ms_clumpModelStore.alloc(); + modelinfo = CModelInfo::ms_clumpModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; return modelinfo; @@ -162,7 +160,7 @@ CPedModelInfo* CModelInfo::AddPedModel(int id) { CPedModelInfo *modelinfo; - modelinfo = CModelInfo::ms_pedModelStore.alloc(); + modelinfo = CModelInfo::ms_pedModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; return modelinfo; @@ -172,7 +170,7 @@ CVehicleModelInfo* CModelInfo::AddVehicleModel(int id) { CVehicleModelInfo *modelinfo; - modelinfo = CModelInfo::ms_vehicleModelStore.alloc(); + modelinfo = CModelInfo::ms_vehicleModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; modelinfo->m_vehicleType = -1; @@ -189,7 +187,7 @@ CModelInfo::GetModelInfo(const char *name, int *id) CBaseModelInfo *modelinfo; for(int i = 0; i < MODELINFOSIZE; i++){ modelinfo = CModelInfo::ms_modelInfoPtrs[i]; - if(modelinfo && !CGeneral::faststricmp(modelinfo->GetName(), name)){ + if(modelinfo && !CGeneral::faststricmp(modelinfo->GetModelName(), name)){ if(id) *id = i; return modelinfo; @@ -207,7 +205,7 @@ CModelInfo::GetModelInfo(const char *name, int minIndex, int maxIndex) CBaseModelInfo *modelinfo; for(int i = minIndex; i <= maxIndex; i++){ modelinfo = CModelInfo::ms_modelInfoPtrs[i]; - if(modelinfo && !CGeneral::faststricmp(modelinfo->GetName(), name)) + if(modelinfo && !CGeneral::faststricmp(modelinfo->GetModelName(), name)) return modelinfo; } return nil; @@ -251,7 +249,7 @@ CModelInfo::IsPlaneModel(int32 id) void CModelInfo::ReInit2dEffects() { - ms_2dEffectStore.clear(); + ms_2dEffectStore.Clear(); for (int i = 0; i < MODELINFOSIZE; i++) { if (ms_modelInfoPtrs[i]) diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h index 1ac7b0bb..30f4c015 100644 --- a/src/modelinfo/ModelInfo.h +++ b/src/modelinfo/ModelInfo.h @@ -1,14 +1,13 @@ #pragma once #include "2dEffect.h" -#include "BaseModelInfo.h" #include "SimpleModelInfo.h" #include "TimeModelInfo.h" #include "WeaponModelInfo.h" #include "ClumpModelInfo.h" #include "PedModelInfo.h" #include "VehicleModelInfo.h" -#include "Instance.h" +#include "templates.h" class CModelInfo { diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp index bd515391..28de2507 100644 --- a/src/modelinfo/PedModelInfo.cpp +++ b/src/modelinfo/PedModelInfo.cpp @@ -10,8 +10,6 @@ #include "ModelInfo.h" #include "custompipes.h" -//--MIAMI: file done - void CPedModelInfo::DeleteRwObject(void) { @@ -48,7 +46,7 @@ CPedModelInfo::SetClump(RpClump *clump) if(m_hitColModel == nil) CreateHitColModelSkinned(clump); RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB); - if(strcmp(GetName(), "player") == 0) + if(strcmp(GetModelName(), "player") == 0) RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB); } diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h index 86e6b74a..79bd7eaa 100644 --- a/src/modelinfo/PedModelInfo.h +++ b/src/modelinfo/PedModelInfo.h @@ -1,6 +1,7 @@ #pragma once #include "ClumpModelInfo.h" +#include "ColModel.h" #include "PedType.h" enum PedNode { diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp index 2e6e557e..8da3a86a 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -6,8 +6,6 @@ #include "AnimManager.h" #include "custompipes.h" -//--MIAMI: file done - #define LOD_DISTANCE (300.0f) void @@ -167,7 +165,7 @@ CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID) for(i = minID; i <= maxID; i++){ mi = CModelInfo::GetModelInfo(i); if(mi && mi != this && - !CGeneral::faststrcmp(GetName()+3, mi->GetName()+3)){ + !CGeneral::faststrcmp(GetModelName()+3, mi->GetModelName()+3)){ assert(mi->IsSimple()); this->SetRelatedModel((CSimpleModelInfo*)mi); return; @@ -189,7 +187,7 @@ CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID) m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier; if(m_drawLast){ m_drawLast = false; - debug("%s was draw last\n", GetName()); + debug("%s was draw last\n", GetModelName()); } }else m_lodDistances[2] = NEAR_DRAW_DIST; diff --git a/src/modelinfo/TimeModelInfo.cpp b/src/modelinfo/TimeModelInfo.cpp index d4f92293..0db5fb78 100644 --- a/src/modelinfo/TimeModelInfo.cpp +++ b/src/modelinfo/TimeModelInfo.cpp @@ -2,6 +2,7 @@ #include "Camera.h" #include "ModelInfo.h" +#include "General.h" CTimeModelInfo* CTimeModelInfo::FindOtherTimeModel(void) @@ -10,7 +11,7 @@ CTimeModelInfo::FindOtherTimeModel(void) char *p; int i; - strcpy(name, GetName()); + strcpy(name, GetModelName()); // change _nt to _dy if(p = strstr(name, "_nt")) strncpy(p, "_dy", 4); @@ -23,7 +24,7 @@ CTimeModelInfo::FindOtherTimeModel(void) for(i = 0; i < MODELINFOSIZE; i++){ CBaseModelInfo *mi = CModelInfo::GetModelInfo(i); if (mi && mi->GetModelType() == MITYPE_TIME && - strncmp(name, mi->GetName(), 24) == 0){ + !CGeneral::faststrncmp(name, mi->GetModelName(), MAX_MODEL_NAME)){ m_otherTimeModelID = i; return (CTimeModelInfo*)mi; } diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index f9caffc5..dfd6519b 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -21,8 +21,6 @@ #include "ModelInfo.h" #include "custompipes.h" -//--MIAMI: done - int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 }; int8 CVehicleModelInfo::ms_compsUsed[2]; RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256]; @@ -333,7 +331,7 @@ CVehicleModelInfo::SetAtomicRendererCB(RpAtomic *atomic, void *data) name = GetFrameNodeName(RpAtomicGetFrame(atomic)); alpha = false; RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha); - if(strstr(name, "_hi") || strncmp(name, "extra", 5) == 0){ + if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) { if(alpha || strncmp(name, "windscreen", 10) == 0) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB); else @@ -359,7 +357,7 @@ CVehicleModelInfo::SetAtomicRendererCB_BigVehicle(RpAtomic *atomic, void *data) name = GetFrameNodeName(RpAtomicGetFrame(atomic)); alpha = false; RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha); - if(strstr(name, "_hi") || strncmp(name, "extra", 5) == 0){ + if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) { if(alpha) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle); else @@ -407,7 +405,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data) clump = (RpClump*)data; name = GetFrameNodeName(RpAtomicGetFrame(atomic)); - if(strcmp(name, "boat_hi") == 0 || strncmp(name, "extra", 5) == 0) + if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5)) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat); else if(strstr(name, "_hi")) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB); @@ -453,7 +451,7 @@ CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleRotorAlphaCB); else if(strncmp(name, "rearrotor", 9) == 0) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB); - else if(strstr(name, "_hi") || strncmp(name, "extra", 5) == 0){ + else if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) { if(alpha || strncmp(name, "windscreen", 10) == 0) CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB); else @@ -549,7 +547,7 @@ CVehicleModelInfo::PreprocessHierarchy(void) if(desc[i].flags & VEHICLE_FLAG_POS){ f = assoc.frame; - rwvec = (RwV3d*)&m_positions[desc[i].hierId]; + rwvec = &m_positions[desc[i].hierId]; *rwvec = *RwMatrixGetPos(RwFrameGetMatrix(f)); for(f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) RwV3dTransformPoints(rwvec, rwvec, 1, RwFrameGetMatrix(f)); @@ -924,7 +922,7 @@ CVehicleModelInfo::AvoidSameVehicleColour(uint8 *col1, uint8 *col2) } } -//--MIAMI: unused +// unused RwTexture* CreateCarColourTexture(uint8 r, uint8 g, uint8 b) { @@ -1011,11 +1009,11 @@ CVehicleModelInfo::LoadVehicleColours(void) continue; if(section == NONE){ - if(strncmp(&line[start], "col", 3) == 0) + if(line[start] == 'c' && line[start + 1] == 'o' && line[start + 2] == 'l') section = COLOURS; - else if(strncmp(&line[start], "car", 3) == 0) + if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r') section = CARS; - }else if(strncmp(&line[start], "end", 3) == 0){ + }else if(line[start] == 'e' && line[start + 1] == 'n' && line[start + 2] == 'd'){ section = NONE; }else if(section == COLOURS){ sscanf(&line[start], // BUG: games doesn't add start diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h index d03ab9bf..c7a41126 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -24,7 +24,7 @@ enum { ATOMIC_FLAG_NOCULL = 0x800, }; -enum eVehicleType : uint8{ +enum eVehicleType { VEHICLE_TYPE_CAR, VEHICLE_TYPE_BOAT, VEHICLE_TYPE_TRAIN, diff --git a/src/modelinfo/WeaponModelInfo.cpp b/src/modelinfo/WeaponModelInfo.cpp index bd8f5cb8..d9294c3f 100644 --- a/src/modelinfo/WeaponModelInfo.cpp +++ b/src/modelinfo/WeaponModelInfo.cpp @@ -4,8 +4,6 @@ #include "AnimManager.h" #include "VisibilityPlugins.h" -//--MIAMI: file done - void CWeaponModelInfo::SetAnimFile(const char *file) { diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp index 8d1be357..7d9fe640 100644 --- a/src/objects/CutsceneObject.cpp +++ b/src/objects/CutsceneObject.cpp @@ -46,7 +46,7 @@ CCutsceneObject::SetModelIndex(uint32 id) CEntity::SetModelIndex(id); assert(RwObjectGetType(m_rwObject) == rpCLUMP); RpAnimBlendClumpInit((RpClump*)m_rwObject); - (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = &m_vecMoveSpeed; + (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity3d = &m_vecMoveSpeed; (*RPANIMBLENDCLUMPDATA(m_rwObject))->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION_3D; } @@ -150,9 +150,9 @@ CCutsceneObject::PreRender(void) void CCutsceneObject::Render(void) { - RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLNONE); + SetCullMode(rwCULLMODECULLNONE); CObject::Render(); - RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLBACK); + SetCullMode(rwCULLMODECULLBACK); } bool diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp index 8656abbb..8dd1643d 100644 --- a/src/objects/DummyObject.cpp +++ b/src/objects/DummyObject.cpp @@ -3,8 +3,6 @@ #include "DummyObject.h" #include "Pools.h" -// --MIAMI: file done - CDummyObject::CDummyObject(CObject *obj) { SetModelIndexNoCreate(obj->GetModelIndex()); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 93b6d581..0605f54f 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -14,6 +14,12 @@ #include "soundlist.h" #include "WaterLevel.h" #include "Timecycle.h" +#include "Stats.h" +#include "SpecialFX.h" + +#define BEACHBALL_MAX_SCORE 250 +// the proportion of the ball speed compared to the player speed when it hits the player +#define BEACHBALL_SPEED_PROPORTION 0.4f int16 CObject::nNoTempObjects; //int16 CObject::nBodyCastHealth = 1000; @@ -33,8 +39,8 @@ CObject::CObject(void) m_bCameraToAvoidThisObject = false; ObjectCreatedBy = UNKNOWN_OBJECT; m_nEndOfLifeTime = 0; -// m_nRefModelIndex = -1; // duplicate -// bUseVehicleColours = false; // duplicate + // m_nRefModelIndex = -1; // duplicate + // bUseVehicleColours = false; // duplicate m_colour2 = 0; m_colour1 = m_colour2; m_nBonusValue = 0; @@ -47,7 +53,7 @@ CObject::CObject(void) bHasBeenDamaged = false; m_nRefModelIndex = -1; bUseVehicleColours = false; -// bIsStreetLight = false; // duplicate + // bIsStreetLight = false; // duplicate m_pCurSurface = nil; m_pCollidingEntity = nil; m_nBeachballBounces = 0; @@ -84,16 +90,16 @@ CObject::~CObject(void) { CRadar::ClearBlipForEntity(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(this)); - if(m_nRefModelIndex != -1) + if (m_nRefModelIndex != -1) CModelInfo::GetModelInfo(m_nRefModelIndex)->RemoveRef(); - if(ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0) + if (ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0) nNoTempObjects--; } -void -CObject::ProcessControl(void) -{ +void +CObject::ProcessControl(void) +{ CVector point, impulse; if (m_nCollisionDamageEffect) ObjectDamage(m_fDamageImpulse); @@ -107,7 +113,8 @@ CObject::ProcessControl(void) m_vecMoveSpeed *= fTimeStep; m_vecTurnSpeed *= fTimeStep; } - if ((GetModelIndex() == MI_EXPLODINGBARREL || GetModelIndex() == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible + int16 mi = GetModelIndex(); + if ((mi == MI_EXPLODINGBARREL || mi == MI_PETROLPUMP || mi == MI_PETROLPUMP2) && bHasBeenDamaged && bIsVisible && (CGeneral::GetRandomNumber() & 0x1F) == 10) { bExplosionProof = true; bIsVisible = false; @@ -115,11 +122,73 @@ CObject::ProcessControl(void) bAffectedByGravity = false; m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); } + if (mi == MI_RCBOMB) { + float fTurnForce = -(m_fTurnMass / 20.0f); + CPhysical::ApplyTurnForce(m_vecMoveSpeed * fTurnForce, -GetForward()); + float fScalar = 1.0f - m_vecMoveSpeed.MagnitudeSqr() / 5.0f; + float fScalarTimed = Pow(fScalar, CTimer::GetTimeStep()); + m_vecMoveSpeed *= fScalarTimed; + } + if (mi == MI_BEACHBALL) { + float fTimeStep = Pow(0.95f, CTimer::GetTimeStep()); + float fPreviousVecSpeedMag = m_vecMoveSpeed.Magnitude2D(); + m_vecMoveSpeed.x *= fTimeStep; + m_vecMoveSpeed.y *= fTimeStep; + m_vecMoveSpeed.z += fPreviousVecSpeedMag - m_vecMoveSpeed.Magnitude2D(); + if (!FindPlayerVehicle()) { + CVector distance; + distance.x = FindPlayerCoors().x - GetPosition().x; + distance.y = FindPlayerCoors().y - GetPosition().y; + distance.z = FindPlayerCoors().z - GetPosition().z; + if (distance.z > 0.0 && distance.z < 1.5f && distance.Magnitude2D() < 1.0f) { + CVector playerSpeed = FindPlayerSpeed(); + if (fPreviousVecSpeedMag < 0.05f && playerSpeed.Magnitude() > 0.1f) { + playerSpeed.z = 0.0f; + playerSpeed.Normalise(); + playerSpeed.z = 0.3f; + m_vecMoveSpeed = CVector( + playerSpeed.x * BEACHBALL_SPEED_PROPORTION, + playerSpeed.y * BEACHBALL_SPEED_PROPORTION, + 0.3f * BEACHBALL_SPEED_PROPORTION + ); + PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition()); + m_vecTurnSpeed += CVector( + ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f, + ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f, + 0.0f); + if (m_nBeachballBounces > 0) { + m_nBeachballBounces++; + } + if (m_nBeachballBounces > 0) { + sprintf(gString, "%d", m_nBeachballBounces); + CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f); + CStats::RegisterHighestScore(3, m_nBeachballBounces); + } + } + } + if (distance.z > -1.05 && distance.z < -0.6 && m_vecMoveSpeed.z < 0.0f && distance.Magnitude2D() < 0.9f) { + m_vecMoveSpeed.x += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f; + m_vecMoveSpeed.y += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f; + m_vecMoveSpeed.z = Max(m_vecMoveSpeed.z + 0.3f, 0.2f); + PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition()); + m_vecTurnSpeed.x += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f; + m_vecTurnSpeed.y += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f; + m_nBeachballBounces++; + m_nBeachballBounces = Min(m_nBeachballBounces, BEACHBALL_MAX_SCORE); + sprintf(gString, "%d", m_nBeachballBounces); + CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f); + CStats::RegisterHighestScore(3, m_nBeachballBounces); + } + } + } + if (bIsBIGBuilding) { + bIsInSafePosition = true; + } } -void +void CObject::Teleport(CVector vecPos) -{ +{ CWorld::Remove(this); m_matrix.GetPosition() = vecPos; m_matrix.UpdateRW(); @@ -245,7 +314,7 @@ CObject::Render(void) bool CObject::SetupLighting(void) { - if(bRenderScorched){ + if (bRenderScorched) { WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); return true; } else if (bIsPickup) { @@ -262,14 +331,14 @@ CObject::SetupLighting(void) void CObject::RemoveLighting(bool reset) { - if(reset) { + if (reset) { SetAmbientColours(); DeActivateDirectional(); } } -void -CObject::ObjectDamage(float amount) +void +CObject::ObjectDamage(float amount) { if (!m_nCollisionDamageEffect || !bUsesCollision) return; @@ -287,132 +356,361 @@ CObject::ObjectDamage(float amount) } #endif if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) { - const CVector& vecPos = m_matrix.GetPosition(); + const CVector &vecPos = m_matrix.GetPosition(); const float fDirectionZ = 0.0002f * amount; - switch (m_nCollisionDamageEffect) - { - case DAMAGE_EFFECT_CHANGE_MODEL: - bRenderDamaged = true; - break; - case DAMAGE_EFFECT_SPLIT_MODEL: - break; - case DAMAGE_EFFECT_SMASH_COMPLETELY: - bIsVisible = false; - bUsesCollision = false; - SetIsStatic(true); - bExplosionProof = true; - SetMoveSpeed(0.0f, 0.0f, 0.0f); - SetTurnSpeed(0.0f, 0.0f, 0.0f); - break; - case DAMAGE_EFFECT_CHANGE_THEN_SMASH: - if (!bRenderDamaged) { + switch (m_nCollisionDamageEffect) { + case DAMAGE_EFFECT_CHANGE_MODEL: + bRenderDamaged = true; + return; + case DAMAGE_EFFECT_SPLIT_MODEL: + return; + case DAMAGE_EFFECT_SMASH_AND_DAMAGE_TRAFFICLIGHTS: + { + static RwRGBA debrisColor = { 0xc8,0xc8,0xc8,0xff }; + if (bRenderDamaged) { + break; + } bRenderDamaged = true; + CVector min = 0.85f * GetColModel()->boundingBox.min; + CVector max = 0.85f * GetColModel()->boundingBox.max; + min.z = max.z; + min = GetMatrix() * min; + max = GetMatrix() * max; + CVector temp = (max - min) * 0.02f; + for (int32 i = 0; i < 50; i++) { + CVector vecDir = CVector( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + ); + ++nFrameGen; + int32 currentFrame = nFrameGen & 3; + CVector pos = min + temp * (float)i; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + float fColorFactor = CGeneral::GetRandomNumberInRange(0.6f, 1.2f); + RwRGBA color = debrisColor; + color.red *= fColorFactor; + color.green *= fColorFactor; + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-0.40f, 0.40f); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); + } + PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, min); + break; } - else { + case DAMAGE_EFFECT_CHANGE_THEN_SMASH: { + if (!bRenderDamaged) { + bRenderDamaged = true; + return; + } + // fall through + } + case DAMAGE_EFFECT_SMASH_COMPLETELY: { bIsVisible = false; bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); + break; } - break; - case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: { - bIsVisible = false; - bUsesCollision = false; - SetIsStatic(true); - bExplosionProof = true; - SetMoveSpeed(0.0f, 0.0f, 0.0f); - SetTurnSpeed(0.0f, 0.0f, 0.0f); - const RwRGBA color = { 96, 48, 0, 255 }; - for (int32 i = 0; i < 25; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); - ++nFrameGen; - int32 currentFrame = nFrameGen & 3; - float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f); - RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom) , color.blue, color.alpha }; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); - CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); + case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: + case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + const RwRGBA color = { 96, 48, 0, 255 }; + for (int32 i = 0; i < 25; i++) { + CVector vecDir = CVector( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ + ); + ++nFrameGen; + int32 currentFrame = nFrameGen & 3; + RwRGBA randomColor = color; + switch (m_nCollisionDamageEffect) { + case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: { + float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f); + randomColor.red *= fRandom; + randomColor.green *= fRandom; + randomColor.blue *= fRandom; + break; + } + case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY: { + randomColor.red = 0xff; + randomColor.green = 0xfc; + break; + } + } + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); + } + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); + break; } - PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); - break; - } - case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: { - bIsVisible = false; - bUsesCollision = false; - SetIsStatic(true); - bExplosionProof = true; - SetMoveSpeed(0.0f, 0.0f, 0.0f); - SetTurnSpeed(0.0f, 0.0f, 0.0f); - const RwRGBA color = { 128, 128, 128, 255 }; - for (int32 i = 0; i < 45; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); - ++nFrameGen; - int32 currentFrame = nFrameGen & 3; - float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 0.5f); - RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha }; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); - CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); + case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + static const RwRGBA color = { 128, 128, 128, 255 }; + CVector position = GetPosition(); + for (int32 i = 0; i < 45; i++) { + CVector vecDir = CVector( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ + ); + ++nFrameGen; + int32 currentFrame = nFrameGen & 3; + float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f); + RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha }; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); + } + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos); + break; } - PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos); - break; - } - case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: { - bIsVisible = false; - bUsesCollision = false; - SetIsStatic(true); - bExplosionProof = true; - SetMoveSpeed(0.0f, 0.0f, 0.0f); - SetTurnSpeed(0.0f, 0.0f, 0.0f); - const RwRGBA color1 = { 200, 0, 0, 255 }; - const RwRGBA color2 = { 200, 200, 200, 255 }; - for (int32 i = 0; i < 10; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); - ++nFrameGen; - int32 currentFrame = nFrameGen & 3; - RwRGBA color = color2; - if (nFrameGen & 1) - color = color1; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); - CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); + case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: + case DAMAGE_EFFECT_BURST_BEACHBALL: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + const RwRGBA color1 = { 200, 0, 0, 255 }; + const RwRGBA color2 = { 200, 200, 200, 255 }; + for (int32 i = 0; i < 10; i++) { + CVector vecDir = CVector( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ + ); + ++nFrameGen; + int32 currentFrame = nFrameGen & 3; + RwRGBA color = color2; + if (nFrameGen & 1) + color = color1; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); + } + if (m_nCollisionDamageEffect == DAMAGE_EFFECT_BURST_BEACHBALL) { + PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, vecPos); + } else { + PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos); + } + break; } - PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos); - break; - } - case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: { - bIsVisible = false; - bUsesCollision = false; - SetIsStatic(true); - bExplosionProof = true; - SetMoveSpeed(0.0f, 0.0f, 0.0f); - SetTurnSpeed(0.0f, 0.0f, 0.0f); - const RwRGBA color1 = { 200, 0, 0, 255 }; - const RwRGBA color2 = { 200, 200, 200, 255 }; - for (int32 i = 0; i < 32; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); - ++nFrameGen; - int32 currentFrame = nFrameGen & 3; - RwRGBA color = color2; - if (nFrameGen & 1) - color = color1; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); - CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); + case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + const RwRGBA color1 = { 200, 0, 0, 255 }; + const RwRGBA color2 = { 200, 200, 200, 255 }; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + for (int32 i = 0; i < 32; i++) { + CVector vecDir = CVector( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ + ); + ++nFrameGen; + int32 currentFrame = nFrameGen & 3; + const RwRGBA &color = nFrameGen & 1 ? color1 : color2; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); + } + PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); + break; } - PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); - break; - } + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1: + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2: + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3: + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4: + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + CRGBA possibleColor1; + CRGBA possibleColor2; + switch (m_nCollisionDamageEffect) { + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1: + possibleColor1 = CRGBA(0xC0, 0x3E, 0xC, 0xFF); + possibleColor2 = possibleColor1; + break; + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2: + possibleColor1 = CRGBA(0xA3, 0x36, 0x21, 0xFF); + possibleColor2 = possibleColor1; + break; + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3: + possibleColor1 = CRGBA(0x12, 0x31, 0x24, 0xFF); + possibleColor2 = possibleColor1; + break; + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4: + possibleColor1 = CRGBA(0xC0, 0xC8, 0xBE, 0xFF); + possibleColor2 = CRGBA(0x10, 0x57, 0x85, 0xFF); + break; + case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5: + possibleColor1 = CRGBA(0xD0, 0x94, 0x1B, 0xFF); + possibleColor2 = possibleColor1; + break; + } + for (int32 i = 0; i < 16; i++) { + CVector vecDir( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.15f) + fDirectionZ + ); + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + ++nFrameGen; + int32 nCurFrame = nFrameGen & 0x3; + CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2; + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0); + if (!(i % 7)) { + static CRGBA secondParticleColors[4] = { + CRGBA(0xA0, 0x60, 0x60, 0xFF), + CRGBA(0x60, 0xA0, 0x60, 0xFF), + CRGBA(0x60, 0x60, 0xA0, 0xFF), + CRGBA(0xA0, 0xA0, 0xA0, 0xFF) + }; + vecDir *= 0.5f; + CRGBA &secondParticleColor = secondParticleColors[nFrameGen & 3]; + int32 nSecondRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_DEBRIS, vecPos, vecDir, nil, 0.1f, secondParticleColor, nSecondRotationSpeed, 0, 1, 0); + } + } + PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); + break; + } + case DAMAGE_EFFECT_SMASH_VEGPALM: + { + static RwRGBA primaryColor1 = { 0x39, 0x4D, 0x29, 0xff }; + static RwRGBA primaryColor2 = { 0x94, 0x7D, 0x73, 0xff }; + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + float fRadius = GetColModel()->boundingSphere.radius; + for (int32 i = 0; i < 32; i++) { + CVector particleDir = CVector( + CGeneral::GetRandomNumberInRange(-0.25f, 0.25f), + CGeneral::GetRandomNumberInRange(-0.25f, 0.25f), + CGeneral::GetRandomNumberInRange(-0.05f, 0.05f) + fDirectionZ + ); + CVector particlePos = vecPos; + particlePos.z += CGeneral::GetRandomNumberInRange(0.0f, 1.0f) * fRadius; + ++nFrameGen; + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + int32 nCurFrame = nFrameGen & 0x3; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + RwRGBA& particleColor = nFrameGen & 1 ? primaryColor1 : primaryColor2; + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, particlePos, particleDir, nil, fSize, particleColor, nRotationSpeed, 0, nCurFrame, 0); + if ((i % 7) == 0) { + static RwRGBA secondaryColor = { 0x9A, 0x99, 0x99, 0x3E }; + CParticle::AddParticle(PARTICLE_DEBRIS, particlePos, particleDir, nil, 0.3, secondaryColor, nRotationSpeed, 0, 0, 0); + } + } + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); + break; + } + case DAMAGE_EFFECT_SMASH_BLACKBAG: + case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD: + case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL: + { + bIsVisible = false; + bUsesCollision = false; + if (!GetIsStatic()) { + RemoveFromMovingList(); + } + SetIsStatic(true); + bExplosionProof = true; + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + CRGBA possibleColor1; + CRGBA possibleColor2; + switch (m_nCollisionDamageEffect) { + case DAMAGE_EFFECT_SMASH_BLACKBAG: + possibleColor1 = CRGBA(0, 0, 0, 0xFF); + possibleColor2 = possibleColor1; + break; + case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD: + possibleColor1 = CRGBA(0x8F, 0x8A, 0x8C, 0xFF); + possibleColor2 = CRGBA(0x73, 0x75, 0x7B, 0xFF); + break; + case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL: + possibleColor1 = CRGBA(0x52, 0x92, 0x4A, 0xFF); + possibleColor2 = CRGBA(0xCE, 0xCF, 0xCE, 0xFF); + break; + } + for (int32 i = 0; i < 16; i++) { + CVector vecDir( + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ + ); + ++nFrameGen; + int32 nCurFrame = nFrameGen & 0x3; + CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2; + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0); + } + if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BLACKBAG) { + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); + } else if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD) { + PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); + } + break; + } + default: + DEV("Unhandled collision damage effect id: %d\n", m_nCollisionDamageEffect); + return; } } } @@ -424,9 +722,9 @@ CObject::RefModelInfo(int32 modelId) CModelInfo::GetModelInfo(modelId)->AddRef(); } -void -CObject::Init(void) -{ +void +CObject::Init(void) +{ m_type = ENTITY_TYPE_OBJECT; CObjectData::SetObjectData(GetModelIndex(), *this); m_nEndOfLifeTime = 0; @@ -447,8 +745,8 @@ CObject::Init(void) m_nCostValue = 0; m_pCollidingEntity = nil; CColPoint point; - CEntity* outEntity = nil; - const CVector& vecPos = m_matrix.GetPosition(); + CEntity *outEntity = nil; + const CVector &vecPos = m_matrix.GetPosition(); if (CWorld::ProcessVerticalLine(vecPos, vecPos.z - 10.0f, point, outEntity, true, false, false, false, false, false, nil)) m_pCurSurface = outEntity; else @@ -457,7 +755,7 @@ CObject::Init(void) if (GetModelIndex() == MI_BUOY) bTouchingWater = true; - if(CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON) + if (CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON) bIsWeapon = true; bIsStreetLight = IsLightObject(GetModelIndex()); @@ -486,9 +784,9 @@ CObject::CanBeDeleted(void) void CObject::DeleteAllMissionObjects() { - CObjectPool* objectPool = CPools::GetObjectPool(); + CObjectPool *objectPool = CPools::GetObjectPool(); for (int32 i = 0; i < objectPool->GetSize(); i++) { - CObject* pObject = objectPool->GetSlot(i); + CObject *pObject = objectPool->GetSlot(i); if (pObject && pObject->ObjectCreatedBy == MISSION_OBJECT) { CWorld::Remove(pObject); delete pObject; @@ -496,12 +794,12 @@ CObject::DeleteAllMissionObjects() } } -void -CObject::DeleteAllTempObjects() +void +CObject::DeleteAllTempObjects() { - CObjectPool* objectPool = CPools::GetObjectPool(); + CObjectPool *objectPool = CPools::GetObjectPool(); for (int32 i = 0; i < objectPool->GetSize(); i++) { - CObject* pObject = objectPool->GetSlot(i); + CObject *pObject = objectPool->GetSlot(i); if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT) { CWorld::Remove(pObject); delete pObject; @@ -509,13 +807,13 @@ CObject::DeleteAllTempObjects() } } -void -CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) +void +CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) { CObjectPool *objectPool = CPools::GetObjectPool(); for (int32 i = 0; i < objectPool->GetSize(); i++) { CObject *pObject = objectPool->GetSlot(i); - if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && fRadius * fRadius > pObject->GetPosition().MagnitudeSqr()) { + if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && (point - pObject->GetPosition()).MagnitudeSqr() < SQR(fRadius)) { CWorld::Remove(pObject); delete pObject; } @@ -523,11 +821,11 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) } bool -IsObjectPointerValid(CObject* pObject) +IsObjectPointerValid(CObject *pObject) { if (!pObject) return false; - int index = CPools::GetObjectPool()->GetJustIndex(pObject); + int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pObject); #ifdef FIX_BUGS if (index < 0 || index >= CPools::GetObjectPool()->GetSize()) #else diff --git a/src/objects/Object.h b/src/objects/Object.h index bc74b58b..e34043a8 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -32,23 +32,23 @@ enum CollisionDamageEffect DAMAGE_EFFECT_CHANGE_THEN_SMASH, DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY = 50, - DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY, + DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY = 51, DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY = 60, DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY = 70, DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80, DAMAGE_EFFECT_SMASH_NEWSTANDNEW1 = 91, - DAMAGE_EFFECT_SMASH_NEWSTANDNEW21, - DAMAGE_EFFECT_SMASH_NEWSTANDNEW31, - DAMAGE_EFFECT_SMASH_NEWSTANDNEW41, - DAMAGE_EFFECT_SMASH_NEWSTANDNEW51, + DAMAGE_EFFECT_SMASH_NEWSTANDNEW2 = 92, + DAMAGE_EFFECT_SMASH_NEWSTANDNEW3 = 93, + DAMAGE_EFFECT_SMASH_NEWSTANDNEW4 = 94, + DAMAGE_EFFECT_SMASH_NEWSTANDNEW5 = 95, DAMAGE_EFFECT_SMASH_BLACKBAG = 100, DAMAGE_EFFECT_SMASH_VEGPALM = 110, DAMAGE_EFFECT_BURST_BEACHBALL = 120, DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD = 131, - DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL, + DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL = 132, }; class CVehicle; @@ -76,7 +76,7 @@ public: uint8 m_nCollisionDamageEffect; uint8 m_nSpecialCollisionResponseCases; bool m_bCameraToAvoidThisObject; - int8 m_nBeachballBounces; + uint8 m_nBeachballBounces; uint32 m_obj_unused1; uint32 m_nEndOfLifeTime; int16 m_nRefModelIndex; diff --git a/src/objects/ObjectData.cpp b/src/objects/ObjectData.cpp index 04ac0b9c..8b23f0ae 100644 --- a/src/objects/ObjectData.cpp +++ b/src/objects/ObjectData.cpp @@ -6,8 +6,6 @@ #include "FileMgr.h" #include "ObjectData.h" -//--MIAMI: file done - CObjectInfo CObjectData::ms_aObjectInfo[NUMOBJECTINFO]; // Another ugly file reader diff --git a/src/objects/Projectile.cpp b/src/objects/Projectile.cpp index fc4b25cf..fe8b0c68 100644 --- a/src/objects/Projectile.cpp +++ b/src/objects/Projectile.cpp @@ -2,8 +2,6 @@ #include "Projectile.h" -// --MIAMI: file done - CProjectile::CProjectile(int32 model) : CObject() { m_fMass = 1.0f; diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index a024b77a..f3511366 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -18,8 +18,6 @@ #include <float.h> #endif -// --MIAMI: file done - CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype) { SetModelIndex(mi); @@ -314,7 +312,7 @@ CCivilianPed::ProcessControl(void) for (int j = 0; j < m_numNearPeds; ++j) { CPed *nearPed = m_nearPeds[j]; if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_WANDER_PATH) { - nearPed->m_nPedState = PED_UNKNOWN; + nearPed->SetPedState(PED_UNKNOWN); } } } @@ -420,7 +418,6 @@ CCivilianPed::ProcessControl(void) Avoid(); } -// --MIAMI: Done bool CPed::RunToReportCrime(eCrimeType crimeToReport) { diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h index a7fb766b..dcd49a96 100644 --- a/src/peds/CivilianPed.h +++ b/src/peds/CivilianPed.h @@ -23,6 +23,4 @@ public: void EnterVacantNearbyCars(void); bool IsOnStealWishList(int32); }; -#ifndef PED_SKIN -VALIDATE_SIZE(CCivilianPed, 0x53C); -#endif +//VALIDATE_SIZE(CCivilianPed, 0x53C); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 33b44d3e..9d22c98c 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -20,8 +20,6 @@ #include "Ropes.h" #include "Stinger.h" -// --MIAMI: file done except TODOs - CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP) { m_nCopType = copType; @@ -196,7 +194,7 @@ CCopPed::ClearPursuit(void) m_bZoneDisabled = false; ClearObjective(); if (IsPedInControl()) { - if (!m_pMyVehicle || wanted->m_nWantedLevel != 0) { + if (!m_pMyVehicle || wanted->GetWantedLevel() != 0) { if (m_pMyVehicle && (m_pMyVehicle->GetPosition() - GetPosition()).MagnitudeSqr() < sq(5.0f)) { m_nLastPedState = PED_IDLE; SetSeek((CEntity*)m_pMyVehicle, 2.5f); @@ -249,7 +247,7 @@ CCopPed::ArrestPlayer(void) CPed *suspect = (CPed*)m_pSeekTarget; if (suspect) { if (suspect->CanSetPedState()) - suspect->m_nPedState = PED_ARRESTED; + suspect->SetPedState(PED_ARRESTED); if (suspect->bInVehicle && m_pMyVehicle && suspect->m_pMyVehicle == m_pMyVehicle) { @@ -264,7 +262,7 @@ CCopPed::ArrestPlayer(void) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ARREST_GUN, 4.0f); CVector suspMidPos; - suspect->m_pedIK.GetComponentPosition(*(RwV3d *)&suspMidPos, PED_MID); + suspect->m_pedIK.GetComponentPosition(suspMidPos, PED_MID); m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(suspMidPos.x, suspMidPos.y, GetPosition().x, GetPosition().y); @@ -295,7 +293,7 @@ CCopPed::ScanForCrimes(void) if (!m_bIsInPursuit) { CPlayerPed *player = FindPlayerPed(); if ((m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) - && player->m_pWanted->m_nWantedLevel == 0) { + && player->m_pWanted->GetWantedLevel() == 0) { if (player->m_pMyVehicle #ifdef FIX_BUGS @@ -311,7 +309,7 @@ void CCopPed::CopAI(void) { CWanted *wanted = FindPlayerPed()->m_pWanted; - int wantedLevel = wanted->m_nWantedLevel; + int wantedLevel = wanted->GetWantedLevel(); CPhysical *playerOrHisVeh = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed(); if (wanted->m_bIgnoredByEveryone || wanted->m_bIgnoredByCops) { diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h index 06fe54b0..3f5ae06d 100644 --- a/src/peds/CopPed.h +++ b/src/peds/CopPed.h @@ -48,6 +48,4 @@ public: void ProcessStingerCop(void); }; -#ifndef PED_SKIN -VALIDATE_SIZE(CCopPed, 0x558); -#endif +VALIDATE_SIZE(CCopPed, 0x62C); diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 24d9a6a1..62b70d7d 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -9,8 +9,6 @@ #include "CarCtrl.h" #include "Accident.h" -// --MIAMI: file done - CEmergencyPed::CEmergencyPed(uint32 type) : CPed(type) { switch (type){ @@ -230,8 +228,8 @@ CEmergencyPed::MedicAI(void) if (nearestAccident) { m_pRevivedPed = nearestAccident->m_pVictim; m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed); - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f)); bIsRunning = true; m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; @@ -270,8 +268,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_STOP; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f)); bIsRunning = true; --m_pAttendedAccident->m_nMedicsAttending; @@ -324,8 +322,8 @@ CEmergencyPed::MedicAI(void) if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; else { - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, @@ -346,8 +344,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, diff --git a/src/peds/EmergencyPed.h b/src/peds/EmergencyPed.h index 390ba0bd..41bc86e5 100644 --- a/src/peds/EmergencyPed.h +++ b/src/peds/EmergencyPed.h @@ -36,6 +36,4 @@ public: void FiremanAI(void); void MedicAI(void); }; -#ifndef PED_SKIN -VALIDATE_SIZE(CEmergencyPed, 0x554); -#endif +//VALIDATE_SIZE(CEmergencyPed, 0x554); diff --git a/src/peds/Gangs.cpp b/src/peds/Gangs.cpp index 38e37430..2d6d1137 100644 --- a/src/peds/Gangs.cpp +++ b/src/peds/Gangs.cpp @@ -6,8 +6,6 @@ #include "Streaming.h" #include "Weapon.h" -// --MIAMI: file done - CGangInfo CGangs::Gang[NUM_GANGS]; bool CGangs::GangAttackWithCops[NUM_GANGS]; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index b7623a33..6a3df18b 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -38,8 +38,7 @@ #include "WindModifiers.h" #include "CutsceneShadow.h" #include "Clock.h" - -// --MIAMI: file done +#include "Wanted.h" CPed *gapTempPedList[50]; uint16 gnNumTempPedList; @@ -61,7 +60,6 @@ void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete(( float gfTommyFatness = 1.0f; -// --MIAMI: Done CPed::CPed(uint32 pedType) : m_pedIK(this) { #ifdef USE_CUTSCENE_SHADOW_FOR_PED @@ -113,15 +111,15 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_attackTimer = 0; m_timerUnused = 0; m_lookTimer = 0; - m_standardTimer = 0; + m_chatTimer = 0; m_shootTimer = 0; - m_hitRecoverTimer = 0; + m_carJackTimer = 0; m_duckAndCoverTimer = 0; m_moved = CVector2D(0.0f, 0.0f); m_fRotationCur = 0.0f; m_headingRate = 15.0f; m_fRotationDest = 0.0f; - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; m_walkAroundType = 0; m_pCurrentPhysSurface = nil; m_vecOffsetFromPhysSurface = CVector(0.0f, 0.0f, 0.0f); @@ -264,9 +262,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bVehExitWillBeInstant = false; bHasAlreadyBeenRecorded = false; bFallenDown = false; -#ifdef PED_SKIN bDontAcceptIKLookAts = false; -#endif bReachedAttractorHeadingTarget = false; bTurnedAroundOnAttractor = false; #ifdef KANGAROO_CHEAT @@ -321,7 +317,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bCanGiveUpSunbathing = true; m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); - DMAudio.SetEntityStatus(m_audioEntityId, 1); + DMAudio.SetEntityStatus(m_audioEntityId, true); m_fearFlags = CPedType::GetThreats(m_nPedType); m_threatEntity = nil; m_eventOrThreat = CVector2D(0.0f, 0.0f); @@ -365,16 +361,13 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_vehicleInAccident = nil; m_attractor = nil; m_positionInQueue = -1; -#ifdef PED_SKIN m_pWeaponModel = nil; -#endif m_delayedSoundID = -1; m_delayedSoundTimer = 0; CPopulation::UpdatePedCount((ePedType)m_nPedType, false); m_lastComment = UINT32_MAX; } -// --MIAMI: Done CPed::~CPed(void) { #ifdef USE_CUTSCENE_SHADOW_FOR_PED @@ -385,7 +378,7 @@ CPed::~CPed(void) GetPedAttractorManager()->DeRegisterPed(this, m_attractor); CRadar::ClearBlipForEntity(BLIP_CHAR, CPools::GetPedPool()->GetIndex(this)); if (InVehicle()){ - uint8 door_flag = GetCarDoorFlag(m_vehEnterType); + uint8 door_flag = GetCarDoorFlag(m_vehDoor); if (m_pMyVehicle->pDriver == this) m_pMyVehicle->pDriver = nil; else { @@ -411,7 +404,6 @@ CPed::~CPed(void) DMAudio.DestroyEntity(m_audioEntityId); } -// --MIAMI: Done void CPed::Initialise(void) { @@ -422,7 +414,6 @@ CPed::Initialise(void) debug("CPed ready\n"); } -// --MIAMI: Done void CPed::SetModelIndex(uint32 mi) { @@ -438,8 +429,7 @@ CPed::SetModelIndex(uint32 mi) if (!CanUseTorsoWhenLooking()) m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY; - // This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D. - (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta; + (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity2d = &m_vecAnimMoveDelta; if(modelInfo->GetHitColModel() == nil) modelInfo->CreateHitColModelSkinned(GetClump()); @@ -455,21 +445,18 @@ CPed::SetModelIndex(uint32 mi) #endif } -// --MIAMI: Done void CPed::SetPedStats(ePedStats pedStat) { m_pedStats = CPedStats::ms_apPedStats[pedStat]; } -// --MIAMI: Done void CPed::DeleteRwObject() { CEntity::DeleteRwObject(); } -// --MIAMI: Done void CPed::BuildPedLists(void) { @@ -545,7 +532,6 @@ CPed::BuildPedLists(void) } } -// --MIAMI: Done bool CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock) { @@ -567,7 +553,6 @@ CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock) colpoint, ent, true, false, false, shootablesDoBlock, false, false, false, shootablesDoBlock); } -// --MIAMI: Done // Some kind of binary sort void CPed::SortPeds(CPed **list, int min, int max) @@ -605,14 +590,12 @@ CPed::SortPeds(CPed **list, int min, int max) SortPeds(list, right, max); } -// --MIAMI: Done void CPed::SetMoveState(eMoveState state) { m_nMoveState = state; } -// --MIAMI: Done void CPed::SetMoveAnim(void) { @@ -634,7 +617,7 @@ CPed::SetMoveAnim(void) if (!animAssoc) { animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); if (!animAssoc) - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE); if (animAssoc && m_nPedState == PED_FIGHT) return; @@ -726,7 +709,6 @@ CPed::SetMoveAnim(void) } } -// --MIAMI: Done void CPed::StopNonPartialAnims(void) { @@ -738,7 +720,6 @@ CPed::StopNonPartialAnims(void) } } -// --MIAMI: Done void CPed::RestartNonPartialAnims(void) { @@ -750,7 +731,6 @@ CPed::RestartNonPartialAnims(void) } } -// --MIAMI: Done void CPed::SetStoredState(void) { @@ -769,7 +749,6 @@ CPed::SetStoredState(void) } } -// --MIAMI: Done void CPed::RestorePreviousState(void) { @@ -812,8 +791,7 @@ CPed::RestorePreviousState(void) SetWanderPath(m_nPedState == PED_FOLLOW_PATH ? m_nPathDir : CGeneral::GetRandomNumber() & 7); break; default: - PedState oldState = m_nLastPedState; - SetPedState(oldState); + SetPedState(m_nLastPedState); SetMoveState((eMoveState) m_nPrevMoveState); break; } @@ -821,7 +799,6 @@ CPed::RestorePreviousState(void) } } -// --MIAMI: Done uint32 CPed::ScanForThreats(void) { @@ -853,14 +830,18 @@ CPed::ScanForThreats(void) } } - CPed *deadPed = nil; + CPed *deadPed; if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR - && (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < sq(20.0f)) { + && (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < sq(20.0f) +#ifdef FIX_BUGS + && !deadPed->bIsInWater +#endif + ) { m_pEventEntity = deadPed; m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity); return PED_FLAG_DEADPEDS; } else { - uint32 flagsOfSomePed = 0; + uint32 flagsOfNearPed = 0; CPed *pedToFearFrom = nil; bool weSawOurEnemy = false; @@ -873,10 +854,11 @@ CPed::ScanForThreats(void) continue; } - // BUG: Explained at the same occurence of this bug above. Fixed at the bottom of the function. - flagsOfSomePed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType); + // BUG: Putting this here will result in returning the flags of farthest ped to us, since m_nearPeds is sorted by distance. + // Fixed at the bottom of the function. + flagsOfNearPed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType); - if (flagsOfSomePed & fearFlags) { + if (flagsOfNearPed & fearFlags) { if (m_nearPeds[i]->m_fHealth > 0.0f) { if (OurPedCanSeeThisOne(m_nearPeds[i], !!bIgnoreThreatsBehindObjects)) { if (m_nearPeds[i]->m_nPedState == PED_ATTACK) { @@ -944,8 +926,8 @@ CPed::ScanForThreats(void) if (driver) { // BUG: Same bug as above. Fixed at the bottom of function. - flagsOfSomePed = CPedType::GetFlag(driver->m_nPedType); - if (CPedType::GetFlag(driver->m_nPedType) & fearFlags) { + flagsOfNearPed = CPedType::GetFlag(driver->m_nPedType); + if (flagsOfNearPed & fearFlags) { if (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) { // FIX: Taken from VC @@ -968,16 +950,15 @@ CPed::ScanForThreats(void) #ifdef FIX_BUGS if (pedToFearFrom) - flagsOfSomePed = CPedType::GetFlag(((CPed*)m_threatEntity)->m_nPedType); + flagsOfNearPed = CPedType::GetFlag(((CPed*)m_threatEntity)->m_nPedType); else - flagsOfSomePed = 0; + flagsOfNearPed = 0; #endif - return flagsOfSomePed; + return flagsOfNearPed; } } -// --MIAMI: Done void CPed::ScanForDelayedResponseThreats(void) { @@ -997,7 +978,6 @@ CPed::ScanForDelayedResponseThreats(void) m_threatCheckTimer = 0; } -// --MIAMI: Done void CPed::CheckThreatValidity(void) { @@ -1013,7 +993,6 @@ CPed::CheckThreatValidity(void) m_threatFlags = 0; } -// --MIAMI: Done bool CPed::CanUseTorsoWhenLooking(void) { @@ -1024,7 +1003,6 @@ CPed::CanUseTorsoWhenLooking(void) return false; } -// --MIAMI: Done void CPed::SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious) { @@ -1041,7 +1019,6 @@ CPed::SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious) } } -// --MIAMI: Done void CPed::SetLookFlag(CEntity *target, bool keepTryingToLook, bool cancelPrevious) { @@ -1059,7 +1036,6 @@ CPed::SetLookFlag(CEntity *target, bool keepTryingToLook, bool cancelPrevious) } } -// --MIAMI: Done void CPed::ClearLookFlag(void) { if (bIsLooking) { @@ -1081,7 +1057,6 @@ CPed::ClearLookFlag(void) { } } -// --MIAMI: Done void CPed::MoveHeadToLook(void) { @@ -1160,7 +1135,6 @@ CPed::MoveHeadToLook(void) } } -// --MIAMI: Done void CPed::RestoreHeadPosition(void) { @@ -1174,7 +1148,6 @@ CPed::RestoreHeadPosition(void) } } -// --MIAMI: Done void CPed::SetAimFlag(float angle) { @@ -1188,13 +1161,12 @@ CPed::SetAimFlag(float angle) if (bIsDucking) m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; - if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) + if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; else m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } -// --MIAMI: Done void CPed::SetAimFlag(CEntity *to) { @@ -1211,7 +1183,6 @@ CPed::SetAimFlag(CEntity *to) m_lookTimer = 0; } -// --MIAMI: Done void CPed::ClearAimFlag(void) { @@ -1226,7 +1197,6 @@ CPed::ClearAimFlag(void) ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f; } -// --MIAMI: Done void CPed::AimGun(void) { @@ -1259,7 +1229,6 @@ CPed::AimGun(void) } } -// --MIAMI: Done void CPed::RestoreGunPosition(void) { @@ -1274,14 +1243,12 @@ CPed::RestoreGunPosition(void) } } -// --MIAMI: Done bool CPed::CanWeRunAndFireWithWeapon(void) { - return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm; + return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM); } -// --MIAMI: Done void CPed::ScanForInterestingStuff(void) { @@ -1299,7 +1266,8 @@ CPed::ScanForInterestingStuff(void) if (LookForInterestingNodes()) return; - if (m_nPedType == PEDTYPE_CRIMINAL && m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) { + if (m_nPedType == PEDTYPE_CRIMINAL && m_carJackTimer < CTimer::GetTimeInMilliseconds()) { + // Find a car to steal or a ped to mug if we haven't already decided to steal a car if (CGeneral::GetRandomNumber() % 100 < 10) { int mostExpensiveVehAround = -1; int bestMonetaryValue = 0; @@ -1322,10 +1290,10 @@ CPed::ScanForInterestingStuff(void) } if (bestMonetaryValue > 2000 && mostExpensiveVehAround != -1 && vehicles[mostExpensiveVehAround]) { SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, vehicles[mostExpensiveVehAround]); - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 5000; return; } - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 5000; } else if (m_objective != OBJECTIVE_MUG_CHAR && !(CGeneral::GetRandomNumber() & 7)) { CPed *charToMug = nil; for (int i = 0; i < m_numNearPeds; ++i) { @@ -1347,13 +1315,13 @@ CPed::ScanForInterestingStuff(void) if (charToMug) SetObjective(OBJECTIVE_MUG_CHAR, charToMug); - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 5000; } } if (m_nPedState == PED_WANDER_PATH) { if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 0.5f) { - if (CTimer::GetTimeInMilliseconds() > m_standardTimer) { + if (CTimer::GetTimeInMilliseconds() > m_chatTimer) { for (int i = 0; i < m_numNearPeds; i ++) { if (m_nearPeds[i] && m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) { if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 1.8f @@ -1369,12 +1337,11 @@ CPed::ScanForInterestingStuff(void) } } } else { - m_standardTimer = CTimer::GetTimeInMilliseconds() + 200; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 200; } } } -// --MIAMI: Done bool CPed::WillChat(CPed *stranger) { @@ -1400,7 +1367,6 @@ CPed::WillChat(CPed *stranger) return true; } -// --MIAMI: Done void CPed::CalculateNewVelocity(void) { @@ -1467,7 +1433,7 @@ CPed::CalculateNewVelocity(void) fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); if(!fightAssoc) - fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE); if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) { LimbOrientation newUpperLegs; @@ -1492,7 +1458,6 @@ CPed::CalculateNewVelocity(void) } } -// --MIAMI: Done float CPed::WorkOutHeadingForMovingFirstPerson(float offset) { @@ -1516,7 +1481,6 @@ CPed::WorkOutHeadingForMovingFirstPerson(float offset) return CGeneral::LimitRadianAngle(offset + angle); } -// --MIAMI: Done void CPed::UpdatePosition(void) { @@ -1584,7 +1548,6 @@ CPed::UpdatePosition(void) m_vecMoveSpeed.y += velocityChange.y; } -// --MIAMI: Done void CPed::CalculateNewOrientation(void) { @@ -1594,7 +1557,6 @@ CPed::CalculateNewOrientation(void) SetHeading(m_fRotationCur); } -// --MIAMI: Done void CPed::ClearAll(void) { @@ -1602,7 +1564,7 @@ CPed::ClearAll(void) return; SetPedState(PED_NONE); - m_nMoveState = PEDMOVE_NONE; + SetMoveState(PEDMOVE_NONE); m_pSeekTarget = nil; m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f); m_fleeFromPos = CVector2D(0.0f, 0.0f); @@ -1618,7 +1580,6 @@ CPed::ClearAll(void) m_pCollidingEntity = nil; } -// --MIAMI: Done void CPed::ProcessBuoyancy(void) { @@ -1737,7 +1698,6 @@ CPed::ProcessBuoyancy(void) bTouchingWater = false; } -// --MIAMI: Done? void CPed::ProcessControl(void) { @@ -1771,11 +1731,7 @@ CPed::ProcessControl(void) if (m_nPedState != PED_ARRESTED) { if (m_nPedState == PED_DEAD) { DeadPedMakesTyresBloody(); -#ifndef VC_PED_PORTS - if (CGame::nastyGame) { -#else if (CGame::nastyGame && !bIsInWater) { -#endif uint32 remainingBloodyFpTime = CTimer::GetTimeInMilliseconds() - m_bloodyFootprintCountOrDeathTime; float timeDependentDist; if (remainingBloodyFpTime >= 2000) { @@ -2332,11 +2288,7 @@ CPed::ProcessControl(void) ApplyMoveForce(forceDir); } - if ((bIsInTheAir && !DyingOrDead()) -#ifdef VC_PED_PORTS - || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL) -#endif - ) { + if ((bIsInTheAir && !DyingOrDead()) || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)) { if (m_nPedStateTimer > 0 && m_nPedStateTimer <= 1000) { forceDir = GetPosition() - m_vecHitLastPos; } else { @@ -2357,11 +2309,7 @@ CPed::ProcessControl(void) if (m_nCollisionRecords == 1 && m_aCollisionRecords[0] != nil && m_aCollisionRecords[0]->IsBuilding() && m_nPedStateTimer > 50.0f / (2.0f * adjustedTs) && m_nPedStateTimer * 1.0f / 250.0f > Abs(forceDir.z)) { offsetToCheck.x = -forceDir.y; -#ifdef VC_PED_PORTS offsetToCheck.z = 1.0f; -#else - offsetToCheck.z = 0.0f; -#endif offsetToCheck.y = forceDir.x; offsetToCheck.Normalise(); @@ -2386,7 +2334,6 @@ CPed::ProcessControl(void) } else { obstacleForFlyingOtherDirZ = 501.0f; } -#ifdef VC_PED_PORTS uint8 flyDir = 0; float feetZ = GetPosition().z - FEET_OFFSET; if ((obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ >= 500.0f) && (obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ <= feetZ)) { @@ -2403,7 +2350,6 @@ CPed::ProcessControl(void) SetLanding(); bIsStanding = true; } -#endif if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) { offsetToCheck *= -1.0f; } @@ -2424,12 +2370,6 @@ CPed::ProcessControl(void) } bIsInTheAir = false; } else if (m_vecDamageNormal.z > 0.4f) { -#ifndef VC_PED_PORTS - forceDir = m_vecDamageNormal; - forceDir.z = 0.0f; - forceDir.Normalise(); - ApplyMoveForce(2.0f * forceDir); -#else if (m_nPedState == PED_JUMP) { if (m_nWaitTimer <= 2000) { if (m_nWaitTimer < 1000) @@ -2446,7 +2386,6 @@ CPed::ProcessControl(void) } else { ApplyMoveForce(-4.0f * forceDir); } -#endif } } else if ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 3) & 7) { if (IsPlayer() && m_nPedState != PED_JUMP && pad0->JumpJustDown()) { @@ -2502,17 +2441,12 @@ CPed::ProcessControl(void) offsetToCheck.z += 0.5f; if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, nil)) { -#ifdef VC_PED_PORTS if (!bHeadStuckInCollision || FEET_OFFSET + foundCol.point.z < GetPosition().z) { GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; GetMatrix().UpdateRW(); if (bHeadStuckInCollision) bHeadStuckInCollision = false; } -#else - GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; - GetMatrix().UpdateRW(); -#endif SetLanding(); bIsStanding = true; } @@ -2614,6 +2548,48 @@ CPed::ProcessControl(void) if (m_nWaitState != WAITSTATE_FALSE) Wait(); +#ifdef CANCELLABLE_CAR_ENTER + static bool cancelJack = false; + if (IsPlayer()) { + if (EnteringCar() && m_pVehicleAnim) { + CPad *pad = CPad::GetPad(0); + + if (!pad->ArePlayerControlsDisabled()) { + int vehAnim = m_pVehicleAnim->animId; + + int16 padWalkX = pad->GetPedWalkLeftRight(); + int16 padWalkY = pad->GetPedWalkUpDown(); + if (Abs(padWalkX) > 0.0f || Abs(padWalkY) > 0.0f) { + if (vehAnim == ANIM_CAR_OPEN_LHS || vehAnim == ANIM_CAR_OPEN_RHS || vehAnim == ANIM_COACH_OPEN_L || vehAnim == ANIM_COACH_OPEN_R || + vehAnim == ANIM_VAN_OPEN_L || vehAnim == ANIM_VAN_OPEN) { + + if (!m_pMyVehicle->pDriver) { + cancelJack = false; + bCancelEnteringCar = true; + } else + cancelJack = true; + } else if (vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f) { + cancelJack = true; + } else if (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS) { + bCancelEnteringCar = true; + cancelJack = false; + } + } + if (cancelJack && vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f && m_pVehicleAnim->GetTimeLeft() < 0.78f) { + cancelJack = false; + QuitEnteringCar(); + RestorePreviousObjective(); + } + if (cancelJack && (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS)) { + cancelJack = false; + bCancelEnteringCar = true; + } + } + } else + cancelJack = false; + } +#endif + switch (m_nPedState) { case PED_IDLE: Idle(); @@ -2632,83 +2608,9 @@ CPed::ProcessControl(void) case PED_WANDER_PATH: WanderPath(); break; - case PED_SEEK_POS: - case PED_SEEK_ENTITY: - case PED_PURSUE: - case PED_SNIPER_MODE: - case PED_ROCKET_MODE: - case PED_DUMMY: - case PED_FACE_PHONE: - case PED_MAKE_CALL: - case PED_MUG: - case PED_AI_CONTROL: - case PED_FOLLOW_ROUTE: - case PED_CPR: - case PED_SOLICIT: - case PED_STEP_AWAY: - case PED_SUN_BATHE: - case PED_FLASH: - case PED_JOG: - case PED_UNKNOWN: - case PED_STATES_NO_AI: - case PED_ABSEIL: - case PED_SIT: - case PED_JUMP: - case PED_STAGGER: - case PED_DIVE_AWAY: - case PED_STATES_NO_ST: - case PED_ARREST_PLAYER: - case PED_PASSENGER: - case PED_TAXI_PASSENGER: - case PED_OPEN_DOOR: - case PED_DEAD: - case PED_DRAG_FROM_CAR: - case PED_STEAL_CAR: - case PED_EXIT_CAR: - break; case PED_ENTER_CAR: case PED_CARJACK: { -#ifdef CANCELLABLE_CAR_ENTER - if (!IsPlayer() || !m_pVehicleAnim) - break; - - CPad *pad = CPad::GetPad(0); - - if (pad->ArePlayerControlsDisabled()) - break; - - int vehAnim = m_pVehicleAnim->animId; - - static bool cancelJack = false; - int16 padWalkX = pad->GetPedWalkLeftRight(); - int16 padWalkY = pad->GetPedWalkUpDown(); - if (Abs(padWalkX) > 0.0f || Abs(padWalkY) > 0.0f) { - if (vehAnim == ANIM_CAR_OPEN_LHS || vehAnim == ANIM_CAR_OPEN_RHS || vehAnim == ANIM_COACH_OPEN_L || vehAnim == ANIM_COACH_OPEN_R || - vehAnim == ANIM_VAN_OPEN_L || vehAnim == ANIM_VAN_OPEN) { - - if (!m_pMyVehicle->pDriver) { - cancelJack = false; - bCancelEnteringCar = true; - } else - cancelJack = true; - } else if (vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f) { - cancelJack = true; - } else if (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS) { - bCancelEnteringCar = true; - cancelJack = false; - } - } - if (cancelJack && vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f && m_pVehicleAnim->GetTimeLeft() < 0.78f) { - cancelJack = false; - QuitEnteringCar(); - RestorePreviousObjective(); - } - if (cancelJack && (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS)) { - cancelJack = false; - bCancelEnteringCar = true; - } -#endif break; } case PED_FLEE_POS: @@ -2729,19 +2631,19 @@ CPed::ProcessControl(void) Flee(); break; case PED_FOLLOW_PATH: - CPed::FollowPath(); + FollowPath(); break; case PED_PAUSE: - CPed::Pause(); + Pause(); break; case PED_ATTACK: - CPed::Attack(); + Attack(); break; case PED_FIGHT: - CPed::Fight(); + Fight(); break; case PED_CHAT: - CPed::Chat(); + Chat(); break; case PED_AIM_GUN: if (m_pPointGunAt && m_pPointGunAt->IsPed() @@ -2936,7 +2838,6 @@ CPed::ProcessControl(void) ServiceTalking(); } -// --MIAMI: Done int32 CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) { @@ -3142,7 +3043,6 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) return ourCollidedSpheres; } -// --MIAMI: Done static void particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times) { @@ -3156,7 +3056,6 @@ particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times) } } -// --MIAMI: Done static void particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times) { @@ -3183,7 +3082,6 @@ particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times) } } -// --MIAMI: Done void CPed::PlayFootSteps(void) { @@ -3442,7 +3340,6 @@ CPed::PlayFootSteps(void) } } -// --MIAMI: Done // Actually GetLocalDirectionTo(Turn/Look) int CPed::GetLocalDirection(const CVector2D &posOffset) @@ -3458,14 +3355,12 @@ CPed::GetLocalDirection(const CVector2D &posOffset) return direction; } -// --MIAMI: Done bool CPed::SetDirectionToWalkAroundVehicle(CVehicle* veh) { return SetFollowPath(m_vecSeekPos, 0.0f, m_nMoveState, veh, m_pedInObjective, m_nMoveState == PEDMOVE_WALK ? 2000 : 250); } -// --MIAMI: Done void CPed::SetDirectionToWalkAroundObject(CEntity *obj) { @@ -3714,7 +3609,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) if (Abs(angleDiffBtwObjCenterAndForward) >= objTopRightHeading) { if (PI - objTopRightHeading >= Abs(angleDiffBtwObjCenterAndForward)) { if ((angleDiffBtwObjCenterAndForward <= 0.0f || objUpsideDown) && (angleDiffBtwObjCenterAndForward < 0.0f || !objUpsideDown)) { - if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { + if (goingToEnterCar && (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)) { m_walkAroundType = 0; } else { if (CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) >= 0.0f) { @@ -3732,7 +3627,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } else { - if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { + if (goingToEnterCar && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)) { m_walkAroundType = 0; } else { if (CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) <= 0.0f) { @@ -3750,7 +3645,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } - } else if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + } else if (goingToEnterCar && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) || CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) < 0.0f) { if (entityOnTopLeftOfObj == 1 || entityOnTopLeftOfObj && !entityOnTopRightOfObj && !entityOnBottomRightOfObj) { m_walkAroundType = 3; @@ -3758,7 +3653,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } else if (entityOnTopRightOfObj == 1 || entityOnTopRightOfObj && !entityOnTopLeftOfObj && !entityOnBottomLeftOfObj) { m_walkAroundType = 4; } - } else if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + } else if (goingToEnterCar && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) || CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) > 0.0f) { if (entityOnBottomLeftOfObj == 1 || entityOnBottomLeftOfObj && !entityOnTopRightOfObj && !entityOnBottomRightOfObj) { m_walkAroundType = 2; @@ -3781,10 +3676,10 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) if (Abs(angleDiffBtwObjCenterAndForward) < objTopRightHeading) { if (goingToEnterCar) { if (goingToEnterCarAndItsVan) { - if (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) + if (m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR) return; } - if (m_vehEnterType != CAR_DOOR_LF && m_vehEnterType != CAR_DOOR_LR && (!entityOnBottomRightOfObj || entityOnBottomLeftOfObj)) { + if (m_vehDoor != CAR_DOOR_LF && m_vehDoor != CAR_DOOR_LR && (!entityOnBottomRightOfObj || entityOnBottomLeftOfObj)) { m_fRotationDest = CGeneral::LimitRadianAngle(dirToSet - HALFPI); localPosToHead.x = adjustedColMax.x; localPosToHead.z = 0.0f; @@ -3813,9 +3708,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } else { if (PI - objTopRightHeading >= Abs(angleDiffBtwObjCenterAndForward)) { if (angleDiffBtwObjCenterAndForward <= 0.0f) { - if (!goingToEnterCar || !goingToEnterCarAndItsVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR) { + if (!goingToEnterCar || !goingToEnterCarAndItsVan || m_vehDoor != CAR_DOOR_LR && m_vehDoor != CAR_DOOR_RR) { if (goingToEnterCar) { - if (m_vehEnterType == CAR_DOOR_RF || (m_vehEnterType == CAR_DOOR_RR && !goingToEnterCarAndItsVan)) + if (m_vehDoor == CAR_DOOR_RF || (m_vehDoor == CAR_DOOR_RR && !goingToEnterCarAndItsVan)) return; } if (m_walkAroundType == 4 || m_walkAroundType == 3 @@ -3837,14 +3732,14 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) localPosToHead.z = 0.0f; localPosToHead.y = adjustedColMin.y; } - } else if (goingToEnterCar && goingToEnterCarAndItsVan && (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR)) { + } else if (goingToEnterCar && goingToEnterCarAndItsVan && (m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR)) { m_fRotationDest = CGeneral::LimitRadianAngle(PI + dirToSet); localPosToHead.x = adjustedColMin.x; localPosToHead.z = 0.0f; localPosToHead.y = adjustedColMin.y; } else { if (goingToEnterCar) { - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR && !goingToEnterCarAndItsVan) + if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR && !goingToEnterCarAndItsVan) return; } if (m_walkAroundType == 1 || m_walkAroundType == 2 @@ -3862,8 +3757,8 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } else { - if (goingToEnterCar && (!goingToEnterCarAndItsVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR)) { - if (m_vehEnterType != CAR_DOOR_LF && m_vehEnterType != CAR_DOOR_LR && (!entityOnTopRightOfObj || entityOnTopLeftOfObj)) { + if (goingToEnterCar && (!goingToEnterCarAndItsVan || m_vehDoor != CAR_DOOR_LR && m_vehDoor != CAR_DOOR_RR)) { + if (m_vehDoor != CAR_DOOR_LF && m_vehDoor != CAR_DOOR_LR && (!entityOnTopRightOfObj || entityOnTopLeftOfObj)) { m_fRotationDest = CGeneral::LimitRadianAngle(dirToSet - HALFPI); localPosToHead.x = adjustedColMax.x; @@ -3918,7 +3813,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 280.0f * dist * checkIntervalInTime; } -// --MIAMI: Done bool CPed::IsPedInControl(void) { @@ -3927,14 +3821,12 @@ CPed::IsPedInControl(void) && m_fHealth > 0.0f; } -// --MIAMI: Done bool CPed::IsPedShootable(void) { return m_nPedState <= PED_STATES_NO_ST; } -// --MIAMI: Done bool CPed::UseGroundColModel(void) { @@ -3944,7 +3836,6 @@ CPed::UseGroundColModel(void) m_nPedState == PED_DEAD; } -// --MIAMI: Done bool CPed::CanPedReturnToState(void) { @@ -3952,14 +3843,12 @@ CPed::CanPedReturnToState(void) m_nPedState != PED_FIGHT && m_nPedState != PED_STEP_AWAY && m_nPedState != PED_SNIPER_MODE && m_nPedState != PED_LOOK_ENTITY; } -// --MIAMI: Done bool CPed::CanSetPedState(void) { return !DyingOrDead() && m_nPedState != PED_ARRESTED && !EnteringCar() && m_nPedState != PED_STEAL_CAR; } -// --MIAMI: Done bool CPed::CanStrafeOrMouseControl(void) { @@ -3971,7 +3860,6 @@ CPed::CanStrafeOrMouseControl(void) m_nPedState == PED_ATTACK || m_nPedState == PED_FIGHT || m_nPedState == PED_AIM_GUN || m_nPedState == PED_JUMP || m_nPedState == PED_ANSWER_MOBILE; } -// --MIAMI: Done void CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg) { @@ -3980,7 +3868,6 @@ CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg) ped->m_pVehicleAnim = nil; } -// --MIAMI: Done void CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -4016,7 +3903,6 @@ CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg) ped->bGetUpAnimStarted = false; } -// --MIAMI: Done void CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -4029,7 +3915,6 @@ CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg) ped->RestorePreviousState(); } -// --MIAMI: Done void CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -4040,7 +3925,6 @@ CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg) // nothing */ } -// --MIAMI: Done void CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -4131,12 +4015,9 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } else if (ped->m_objective == OBJECTIVE_NONE && ped->CharCreatedBy != MISSION_CHAR && ped->m_nPedState == PED_IDLE && !ped->IsPlayer()) { ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f)); } - } -#ifdef VC_PED_PORTS - else if (ped->m_nPedState == PED_DRIVING) { + } else if (ped->m_nPedState == PED_DRIVING) { ped->m_nPedState = PED_IDLE; } -#endif if (animAssoc) animAssoc->blendDelta = -1000.0f; @@ -4160,13 +4041,15 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } if (veh && veh->IsBike()) // BUG? - veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType); + veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehDoor); else - veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehEnterType); + veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehDoor); if (veh->pDriver == ped) { veh->RemoveDriver(); +#ifndef FIX_BUGS // RemoveDriver does it anyway veh->SetStatus(STATUS_ABANDONED); +#endif if (veh->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) veh->m_nDoorLock = CARLOCK_UNLOCKED; if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle()) @@ -4182,7 +4065,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) if (veh->bIsBus && !veh->IsUpsideDown() && !veh->IsOnItsSide()) { float angleAfterExit; - if (ped->m_vehEnterType == CAR_DOOR_LF) { + if (ped->m_vehDoor == CAR_DOOR_LF) { angleAfterExit = HALFPI + veh->GetForward().Heading(); } else { angleAfterExit = veh->GetForward().Heading() - HALFPI; @@ -4222,7 +4105,6 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bHeldHostageInCar = false; } -// --MIAMI: Done void CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) { @@ -4233,7 +4115,7 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) uint8 exitFlags = 0; quickJackedAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_CAR_QJACKED); if (dragAssoc && dragAssoc->animId == ANIM_BIKE_HIT && ped->m_pMyVehicle) { - if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_RF) { + if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_RF) { CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_FALL_OFF, 100.0f); ped->m_pMyVehicle->m_nGettingOutFlags &= ~(CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF); } else { @@ -4255,9 +4137,9 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) vehicle = ped->m_pMyVehicle; if (vehicle && vehicle->IsBike()) - exitFlags = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehEnterType); + exitFlags = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehDoor); else - exitFlags = GetCarDoorFlag(ped->m_vehEnterType); + exitFlags = GetCarDoorFlag(ped->m_vehDoor); if (vehicle) vehicle->m_nGettingOutFlags &= ~exitFlags; @@ -4299,7 +4181,6 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) ped->bVehExitWillBeInstant = false; } -// --MIAMI: Done void CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -4478,7 +4359,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) } else if (veh->bIsBus) { veh->AddPassenger(ped); } else { - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: veh->AddPassenger(ped, 0); break; @@ -4508,9 +4389,9 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) int8 doorFlag; if (veh->IsBike()) { - doorFlag = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehEnterType); + doorFlag = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehDoor); } else { - doorFlag = GetEnterCarDoorFlag(ped->m_vehEnterType, veh->m_nNumMaxPassengers); + doorFlag = GetEnterCarDoorFlag(ped->m_vehDoor, veh->m_nNumMaxPassengers); } veh->m_nGettingInFlags &= ~doorFlag; @@ -4558,7 +4439,6 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bChangedSeat = true; } -// --MIAMI: Done bool CPed::CanBeDeleted(void) { @@ -4577,7 +4457,6 @@ CPed::CanBeDeleted(void) } } -//--MIAMI: done bool CPed::CanBeDeletedEvenInVehicle(void) { @@ -4593,7 +4472,6 @@ CPed::CanBeDeletedEvenInVehicle(void) } } -// --MIAMI: Done void CPed::AddWeaponModel(int id) { @@ -4621,7 +4499,6 @@ RemoveAllModelCB(RwObject *object, void *data) return object; } -// --MIAMI: Done void CPed::RemoveWeaponModel(int modelId) { @@ -4649,7 +4526,6 @@ CPed::RemoveWeaponModel(int modelId) m_wepModelID = -1; } -// --MIAMI: Done void CPed::RequestDelayedWeapon() { @@ -4669,7 +4545,6 @@ CPed::RequestDelayedWeapon() } } -// --MIAMI: Done void CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo) { @@ -4691,7 +4566,6 @@ CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo) } } -// --MIAMI: Done int32 CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused) { @@ -4728,14 +4602,12 @@ CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused) return slot; } -// --MIAMI: Done int CPed::GetWeaponSlot(eWeaponType weaponType) { return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot; } -// --MIAMI: Done void CPed::SetCurrentWeapon(int slot) { @@ -4758,14 +4630,12 @@ CPed::SetCurrentWeapon(int slot) } } -// --MIAMI: Done void CPed::SetCurrentWeapon(eWeaponType weaponType) { SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot); } -// --MIAMI: Done void CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo) { @@ -4786,7 +4656,6 @@ CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo) GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; } -// --MIAMI: Done void CPed::SetAmmo(eWeaponType weaponType, uint32 ammo) { @@ -4811,7 +4680,6 @@ CPed::SetAmmo(eWeaponType weaponType, uint32 ammo) GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; } -// --MIAMI: Done void CPed::ClearWeapons(void) { @@ -4822,7 +4690,6 @@ CPed::ClearWeapons(void) SetCurrentWeapon(WEAPONTYPE_UNARMED); } -// --MIAMI: Done void CPed::RemoveWeaponWhenEnteringVehicle(void) { @@ -4835,14 +4702,13 @@ CPed::RemoveWeaponWhenEnteringVehicle(void) RemoveWeaponModel(ourWeapon->m_nModelId); } } -// --MIAMI: Done, but enumarate weapon slots void CPed::ReplaceWeaponWhenExitingVehicle(void) { eWeaponType weaponType = GetWeapon()->m_eWeaponType; // If it's Uzi, we may have stored weapon. Uzi is the only gun we can use in car. - if (IsPlayer() && GetWeaponSlot(weaponType) == 5) { + if (IsPlayer() && GetWeaponSlot(weaponType) == WEAPONSLOT_SUBMACHINEGUN) { if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { SetCurrentWeapon(m_storedWeapon); m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; @@ -4852,7 +4718,6 @@ CPed::ReplaceWeaponWhenExitingVehicle(void) } } -// --MIAMI: Done void CPed::PreRender(void) { @@ -4861,11 +4726,7 @@ CPed::PreRender(void) CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]); -#ifdef PED_SKIN - if(IsClumpSkinned(GetClump())){ - UpdateRpHAnim(); - } -#endif + UpdateRpHAnim(); bool bIsWindModifierTurnedOn = false; float fAnyDirectionShift = 1.0f; @@ -5091,7 +4952,6 @@ CPed::PreRender(void) CVector vecTestTemp(-1.0f, -1.0f, -1.0f); -// --MIAMI: Done void CPed::Render(void) { @@ -5141,7 +5001,6 @@ CPed::Render(void) } } -// --MIAMI: Done void CPed::CheckAroundForPossibleCollisions(void) { @@ -5174,7 +5033,6 @@ CPed::CheckAroundForPossibleCollisions(void) } } -// --MIAMI: Done void CPed::SetIdle(void) { @@ -5191,18 +5049,17 @@ CPed::SetIdle(void) } } -// --MIAMI: Done void CPed::Idle(void) { CVehicle *veh = m_pMyVehicle; - if (veh && veh->m_nGettingOutFlags && m_vehEnterType) { + if (veh && veh->m_nGettingOutFlags && m_vehDoor) { - if (veh->m_nGettingOutFlags & GetCarDoorFlag(m_vehEnterType)) { + if (veh->m_nGettingOutFlags & GetCarDoorFlag(m_vehDoor)) { if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) { - CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType); + CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehDoor); CVector doorDist = GetPosition() - doorPos; if (doorDist.MagnitudeSqr() < sq(0.5f)) { @@ -5219,14 +5076,12 @@ CPed::Idle(void) m_moved = CVector2D(0.0f, 0.0f); } -// --MIAMI: Done void CPed::ClearPause(void) { RestorePreviousState(); } -// --MIAMI: Done void CPed::Pause(void) { @@ -5235,7 +5090,6 @@ CPed::Pause(void) ClearPause(); } -// --MIAMI: Done void CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl) { @@ -5301,14 +5155,12 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl) bFallenDown = true; } -// --MIAMI: Done void CPed::ClearFall(void) { SetGetUp(); } -// --MIAMI: Done void CPed::Fall(void) { @@ -5367,7 +5219,6 @@ CPed::Fall(void) } } -// --MIAMI: Done bool CPed::CheckIfInTheAir(void) { @@ -5389,7 +5240,6 @@ CPed::CheckIfInTheAir(void) return !foundGround; } -// --MIAMI: Done void CPed::SetInTheAir(void) { @@ -5408,7 +5258,6 @@ CPed::SetInTheAir(void) } -// --MIAMI: Done void CPed::InTheAir(void) { @@ -5432,7 +5281,6 @@ CPed::InTheAir(void) } } -// --MIAMI: Done void CPed::SetLanding(void) { @@ -5468,7 +5316,6 @@ CPed::SetLanding(void) bIsLanding = true; } -// --MIAMI: Done void CPed::SetGetUp(void) { @@ -5539,7 +5386,6 @@ CPed::SetGetUp(void) } } -// --MIAMI: Done void CPed::Mug(void) { @@ -5561,7 +5407,6 @@ CPed::Mug(void) } } -// --MIAMI: Done // Unused void CPed::SetLook(float direction) @@ -5573,7 +5418,6 @@ CPed::SetLook(float direction) } } -// --MIAMI: Done void CPed::SetLook(CEntity* to) { @@ -5584,7 +5428,6 @@ CPed::SetLook(CEntity* to) } } -// --MIAMI: Done void CPed::SetLookTimer(int time) { @@ -5593,7 +5436,6 @@ CPed::SetLookTimer(int time) } } -// --MIAMI: Done void CPed::SetAttackTimer(uint32 time) { @@ -5601,7 +5443,6 @@ CPed::SetAttackTimer(uint32 time) m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time; } -// --MIAMI: Done void CPed::SetShootTimer(uint32 time) { @@ -5610,7 +5451,6 @@ CPed::SetShootTimer(uint32 time) } } -// --MIAMI: Done void CPed::ClearLook(void) { @@ -5618,14 +5458,12 @@ CPed::ClearLook(void) ClearLookFlag(); } -// --MIAMI: Done void CPed::Look(void) { TurnBody(); } -// --MIAMI: Done bool CPed::TurnBody(void) { @@ -5659,7 +5497,6 @@ CPed::TurnBody(void) return turnDone; } -// --MIAMI: Done void CPed::SetSeek(CVector pos, float distanceToCountDone) { @@ -5667,7 +5504,7 @@ CPed::SetSeek(CVector pos, float distanceToCountDone) || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y) || m_nPedState == PED_FOLLOW_PATH) return; - if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) { + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) { ClearPointGunAt(); } @@ -5678,7 +5515,6 @@ CPed::SetSeek(CVector pos, float distanceToCountDone) m_distanceToCountSeekDone = distanceToCountDone; m_vecSeekPos = pos; } -// --MIAMI: Done void CPed::SetSeek(CEntity *seeking, float distanceToCountDone) { @@ -5701,7 +5537,6 @@ CPed::SetSeek(CEntity *seeking, float distanceToCountDone) SetMoveState(PEDMOVE_STILL); } -// --MIAMI: Done void CPed::ClearSeek(void) { @@ -5709,7 +5544,6 @@ CPed::ClearSeek(void) bRunningToPhone = false; } -// --MIAMI: Done bool CPed::Seek(void) { @@ -5882,7 +5716,6 @@ CPed::Seek(void) return true; } -// --MIAMI: Done void CPed::SetFlee(CVector2D const &from, int time) { @@ -5912,7 +5745,6 @@ CPed::SetFlee(CVector2D const &from, int time) } } -// --MIAMI: Done void CPed::SetFlee(CEntity *fleeFrom, int time) { @@ -5943,17 +5775,15 @@ CPed::SetFlee(CEntity *fleeFrom, int time) } } -// --MIAMI: Done void CPed::ClearFlee(void) { RestorePreviousState(); bUsePedNodeSeek = false; - m_standardTimer = 0; + m_chatTimer = 0; m_fleeTimer = 0; } -// --MIAMI: Done void CPed::Flee(void) { @@ -5995,7 +5825,7 @@ CPed::Flee(void) if (m_nPedStateTimer < CTimer::GetTimeInMilliseconds() && m_collidingThingTimer < CTimer::GetTimeInMilliseconds()) { - if (m_pNextPathNode && CTimer::GetTimeInMilliseconds() > m_standardTimer) { + if (m_pNextPathNode && CTimer::GetTimeInMilliseconds() > m_chatTimer) { curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y); if (m_nPathDir < curDirectionShouldBe) @@ -6038,7 +5868,7 @@ CPed::Flee(void) if (m_pNextPathNode && m_pNextPathNode != realLastNode && m_pNextPathNode != m_pLastPathNode && curDirectionShouldBe - nextDirection != 4) { m_nPathDir = nextDirection; - m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 2000; } else { bUsePedNodeSeek = false; SetMoveState(PEDMOVE_RUN); @@ -6141,7 +5971,6 @@ CPed::WanderRange(void) } } -// --MIAMI: Done bool CPed::SetWanderPath(int8 pathStateDest) { @@ -6190,7 +6019,6 @@ CPed::SetWanderPath(int8 pathStateDest) } } -// --MIAMI: Done void CPed::WanderPath(void) { @@ -6298,7 +6126,6 @@ CPed::WanderPath(void) Say(SOUND_PED_WAIT_DOUBLEBACK); } } -// --MIAMI: Done void CPed::Avoid(void) { @@ -6347,7 +6174,6 @@ CPed::Avoid(void) } } -// --MIAMI: Done CVector* CPed::SeekFollowingPath(void) { @@ -6369,7 +6195,6 @@ CPed::SeekFollowingPath(void) return &vecNextPathNode; } -// --MIAMI: Done bool CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* walkAroundEnt, CEntity* targetEnt, int time) { @@ -6422,7 +6247,6 @@ CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* walkA return SetFollowPathStatic(); } -// --MIAMI: Done bool CPed::SetFollowPathStatic(void) { @@ -6475,8 +6299,8 @@ CPed::SetFollowPathStatic(void) if (m_nLastPedState == PED_NONE) m_nLastPedState = oldLastState; - m_nPedState = PED_FOLLOW_PATH; - m_nMoveState = m_followPathMoveState; + SetPedState(PED_FOLLOW_PATH); + SetMoveState(m_followPathMoveState); } else { RestorePreviousState(); if (m_objective == OBJECTIVE_NONE) { @@ -6491,7 +6315,6 @@ CPed::SetFollowPathStatic(void) return true; } -// --MIAMI: Done bool CPed::SetFollowPathDynamic(void) { @@ -6855,8 +6678,8 @@ CPed::SetFollowPathDynamic(void) if (m_nLastPedState == PED_NONE) m_nLastPedState = oldLastState; - m_nPedState = PED_FOLLOW_PATH; - m_nMoveState = m_followPathMoveState; + SetPedState(PED_FOLLOW_PATH); + SetMoveState(m_followPathMoveState); return true; } else { @@ -6875,7 +6698,6 @@ CPed::SetFollowPathDynamic(void) } } -// --MIAMI: Done void CPed::ClearFollowPath() { @@ -6886,7 +6708,6 @@ CPed::ClearFollowPath() m_nCurPathNodeId = 0; } -// --MIAMI: Done void CPed::FollowPath(void) { @@ -6917,7 +6738,6 @@ CPed::FollowPath(void) } } -// --MIAMI: Done void CPed::SetEvasiveStep(CEntity *reason, uint8 animType) { @@ -6993,7 +6813,6 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType) } } -// --MIAMI: Done void CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump) { @@ -7099,7 +6918,7 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump) ClearLookFlag(); ClearAimFlag(); SetStoredState(); - m_nPedState = PED_DIVE_AWAY; + SetPedState(PED_DIVE_AWAY); animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_EV_DIVE, 8.0f); animAssoc->SetFinishCallback(PedEvadeCB, this); } @@ -7113,7 +6932,6 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump) } } -// --MIAMI: Done void CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -7151,7 +6969,6 @@ CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg) } } -// --MIAMI: Done void CPed::SetDie(AnimationId animId, float delta, float speed) { @@ -7215,7 +7032,6 @@ CPed::SetDie(AnimationId animId, float delta, float speed) } } -// --MIAMI: Done void CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -7225,7 +7041,6 @@ CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bIsPedDieAnimPlaying = false; } -// --MIAMI: Done void CPed::SetDead(void) { @@ -7258,14 +7073,12 @@ CPed::SetDead(void) CEventList::RegisterEvent(EVENT_DEAD_PED, EVENT_ENTITY_PED, this, nil, 1000); } -// --MIAMI: Done void CPed::Die(void) { // UNUSED: This is a perfectly empty function. } -// --MIAMI: Done void CPed::SetChat(CEntity *chatWith, uint32 time) { @@ -7278,11 +7091,10 @@ CPed::SetChat(CEntity *chatWith, uint32 time) SetMoveState(PEDMOVE_STILL); m_lookTimer = 0; SetLookFlag(chatWith, true); - m_standardTimer = CTimer::GetTimeInMilliseconds() + time; + m_chatTimer = CTimer::GetTimeInMilliseconds() + time; m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000; } -// --MIAMI: Done void CPed::Chat(void) { @@ -7299,7 +7111,7 @@ CPed::Chat(void) if (partner->m_nPedState != PED_CHAT) { ClearChat(); - m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 30000; if (partner->m_pedInObjective) { if (partner->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || partner->m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE) @@ -7332,13 +7144,12 @@ CPed::Chat(void) Say(SOUND_PED_CHAT); } } - if (m_standardTimer && CTimer::GetTimeInMilliseconds() > m_standardTimer) { + if (m_chatTimer && CTimer::GetTimeInMilliseconds() > m_chatTimer) { ClearChat(); - m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 30000; } } -// --MIAMI: Done void CPed::ClearChat(void) { @@ -7357,7 +7168,6 @@ CPed::ClearChat(void) } } -// --MIAMI: Done bool CPed::FacePhone(void) { @@ -7406,7 +7216,6 @@ CPed::FacePhone(void) #endif } -// --MIAMI: Done bool CPed::MakePhonecall(void) { @@ -7419,7 +7228,6 @@ CPed::MakePhonecall(void) return true; } -// --MIAMI: Done void StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg) { @@ -7428,7 +7236,6 @@ StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg) CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 4.0f); } -// --MIAMI: Done void FinishTalkingOnMobileCB(CAnimBlendAssociation *assoc, void *arg) { @@ -7441,7 +7248,6 @@ FinishTalkingOnMobileCB(CAnimBlendAssociation *assoc, void *arg) ped->m_lookTimer = 0; } -// --MIAMI: Done void CPed::SetAnswerMobile(void) { @@ -7458,7 +7264,6 @@ CPed::SetAnswerMobile(void) } } -// --MIAMI: Done void CPed::ClearAnswerMobile(void) { @@ -7478,7 +7283,6 @@ CPed::ClearAnswerMobile(void) } } -// --MIAMI: Done void CPed::AnswerMobile(void) { @@ -7511,7 +7315,6 @@ CPed::AnswerMobile(void) } } -// --MIAMI: Done void CPed::Teleport(CVector pos) { @@ -7525,7 +7328,6 @@ CPed::Teleport(CVector pos) CWorld::Add(this); } -// --MIAMI: Done void CPed::SetSeekCar(CVehicle *car, uint32 doorNode) { @@ -7543,13 +7345,12 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode) m_pMyVehicle = car; m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle); // m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget); - m_vehEnterType = doorNode; + m_vehDoor = doorNode; m_distanceToCountSeekDone = 0.5f; SetPedState(PED_SEEK_CAR); } -// --MIAMI: Done void CPed::SeekCar(void) { @@ -7561,9 +7362,9 @@ CPed::SeekCar(void) } if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) { - if (!vehToSeek->IsBike() && m_vehEnterType && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) { + if (!vehToSeek->IsBike() && m_vehDoor && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) { if (IsRoomToBeCarJacked()) { - dest = GetPositionToOpenCarDoor(vehToSeek, m_vehEnterType); + dest = GetPositionToOpenCarDoor(vehToSeek, m_vehDoor); } else if (m_nPedType == PEDTYPE_COP) { dest = GetPositionToOpenCarDoor(vehToSeek, CAR_DOOR_RF); } else { @@ -7572,7 +7373,7 @@ CPed::SeekCar(void) } else GetNearestDoor(vehToSeek, dest); } else { - if (m_hitRecoverTimer > CTimer::GetTimeInMilliseconds()) { + if (m_carJackTimer > CTimer::GetTimeInMilliseconds()) { SetMoveState(PEDMOVE_STILL); return; } @@ -7616,7 +7417,7 @@ CPed::SeekCar(void) if (IsPlayer()) { ClearObjective(); } else if (CharCreatedBy == RANDOM_CHAR) { - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 30000; } SetMoveState(PEDMOVE_STILL); TheCamera.ClearPlayerWeaponMode(); @@ -7644,7 +7445,7 @@ CPed::SeekCar(void) else if (2.0f * vehToSeek->GetColModel()->boundingBox.max.x > distToDestSqr) bCanPedEnterSeekedCar = true; - if (vehToSeek->m_nGettingInFlags & GetCarDoorFlag(m_vehEnterType)) + if (vehToSeek->m_nGettingInFlags & GetCarDoorFlag(m_vehDoor)) bVehEnterDoorIsBlocked = true; else bVehEnterDoorIsBlocked = false; @@ -7655,7 +7456,7 @@ CPed::SeekCar(void) if (1.6f + GetPosition().z > dest.z && GetPosition().z - 0.5f < dest.z) { #ifdef GTA_TRAIN if (vehToSeek->IsTrain()) { - SetEnterTrain(vehToSeek, m_vehEnterType); + SetEnterTrain(vehToSeek, m_vehDoor); } else #endif { @@ -7676,42 +7477,42 @@ CPed::SeekCar(void) case STATUS_PLAYER_DISABLED: if (vehToSeek->IsBike()) { if ((!m_leader || m_leader != vehToSeek->pDriver) && - ((m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_WINDSCREEN) && vehToSeek->pDriver || - (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) && vehToSeek->pPassengers[0])) { + ((m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_WINDSCREEN) && vehToSeek->pDriver || + (m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR) && vehToSeek->pPassengers[0])) { SetCarJack(vehToSeek); } else { - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } } else if (!vehToSeek->bIsBus && (!m_leader || m_leader != vehToSeek->pDriver) && - (m_vehEnterType == CAR_DOOR_LF && vehToSeek->pDriver || m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0] || m_vehEnterType == CAR_DOOR_LR && vehToSeek->pPassengers[1] || m_vehEnterType == CAR_DOOR_RR && vehToSeek->pPassengers[2])) { + (m_vehDoor == CAR_DOOR_LF && vehToSeek->pDriver || m_vehDoor == CAR_DOOR_RF && vehToSeek->pPassengers[0] || m_vehDoor == CAR_DOOR_LR && vehToSeek->pPassengers[1] || m_vehDoor == CAR_DOOR_RR && vehToSeek->pPassengers[2])) { SetCarJack(vehToSeek); - if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && m_vehEnterType != CAR_DOOR_LF) + if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && m_vehDoor != CAR_DOOR_LF) vehToSeek->pDriver->bFleeAfterExitingCar = true; } else { - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } break; case STATUS_ABANDONED: if (vehToSeek->IsBike()) { - if ((m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) && vehToSeek->pPassengers[0]) { + if ((m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR) && vehToSeek->pPassengers[0]) { if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) { if (IsPlayer()) - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } else { SetCarJack(vehToSeek); } } else { - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } - } else if (m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0]) { + } else if (m_vehDoor == CAR_DOOR_RF && vehToSeek->pPassengers[0]) { if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) { if (IsPlayer()) - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } else { SetCarJack(vehToSeek); } } else { - SetEnterCar(vehToSeek, m_vehEnterType); + SetEnterCar(vehToSeek, m_vehDoor); } break; case STATUS_WRECKED: @@ -7732,7 +7533,6 @@ CPed::SeekCar(void) } } -// --MIAMI: Done bool CPed::CheckForExplosions(CVector2D &area) { @@ -7777,7 +7577,6 @@ CPed::CheckForExplosions(CVector2D &area) return false; } -// --MIAMI: Done CPed * CPed::CheckForGunShots(void) { @@ -7793,7 +7592,6 @@ CPed::CheckForGunShots(void) return nil; } -// --MIAMI: Done CPed * CPed::CheckForDeadPeds(void) { @@ -7809,7 +7607,6 @@ CPed::CheckForDeadPeds(void) return nil; } -// --MIAMI: Done bool CPed::IsPlayer(void) const { @@ -7822,14 +7619,12 @@ CPed::IsPlayer(void) const #endif } -// --MIAMI: Done bool CPed::IsGangMember(void) const { return m_nPedType >= PEDTYPE_GANG1 && m_nPedType <= PEDTYPE_GANG9; } -// --MIAMI: Done bool IsPedPointerValid(CPed* pPed) { @@ -7840,13 +7635,12 @@ IsPedPointerValid(CPed* pPed) return pPed->m_entryInfoList.first || pPed == FindPlayerPed(); } -// --MIAMI: Done bool IsPedPointerValid_NotInWorld(CPed* pPed) { if (!pPed) return false; - int index = CPools::GetPedPool()->GetJustIndex(pPed); + int index = CPools::GetPedPool()->GetJustIndex_NoFreeAssert(pPed); #ifdef FIX_BUGS if (index < 0 || index >= NUMPEDS) #else @@ -7856,7 +7650,6 @@ IsPedPointerValid_NotInWorld(CPed* pPed) return true; } -// --MIAMI: Done bool CPed::IsPointerValid(void) { @@ -7870,7 +7663,6 @@ CPed::IsPointerValid(void) return false; } -// --MIAMI: Done void CPed::SetPedPositionInCar(void) { @@ -7963,7 +7755,6 @@ CPed::SetPedPositionInCar(void) GetMatrix() = newMat; } -// --MIAMI: Done void CPed::LookForSexyPeds(void) { @@ -7989,7 +7780,6 @@ CPed::LookForSexyPeds(void) m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000; } -// --MIAMI: Done void CPed::LookForSexyCars(void) { @@ -8019,7 +7809,6 @@ CPed::LookForSexyCars(void) } } -// --MIAMI: Done bool CPed::LookForInterestingNodes(void) { @@ -8029,7 +7818,7 @@ CPed::LookForInterestingNodes(void) C2dEffect *effect; CMatrix *objMat; - if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) & 7 || CTimer::GetTimeInMilliseconds() <= m_standardTimer) { + if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) & 7 || CTimer::GetTimeInMilliseconds() <= m_chatTimer) { return false; } bool found = false; @@ -8139,7 +7928,7 @@ CPed::LookForInterestingNodes(void) float angleToFace = CGeneral::GetRadianAngleBetweenPoints(effectFrontLocal.x, effectFrontLocal.y, 0.0f, 0.0f); randVal = CGeneral::GetRandomNumber() % 256; if (randVal <= m_randomSeed % 256) { - m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 2000; SetLookFlag(angleToFace, true); SetLookTimer(1000); return false; @@ -8161,7 +7950,6 @@ CPed::LookForInterestingNodes(void) return true; } -// --MIAMI: Done void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount) { @@ -8198,7 +7986,6 @@ PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 firs } } -// --MIAMI: Done void CPed::ClearWaitState(void) { @@ -8302,7 +8089,6 @@ CPed::ClearWaitState(void) m_nWaitState = WAITSTATE_FALSE; } -// --MIAMI: Done void CPed::SetWaitState(eWaitState state, void *time) { @@ -8362,7 +8148,7 @@ CPed::SetWaitState(eWaitState state, void *time) if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) { ClearObjective(); RestorePreviousState(); - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 30000; } break; case WAITSTATE_TURN180: @@ -8391,7 +8177,7 @@ CPed::SetWaitState(eWaitState state, void *time) if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) { ClearObjective(); RestorePreviousState(); - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 30000; } break; case WAITSTATE_LOOK_ABOUT: @@ -8522,7 +8308,6 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitState = state; } -// --MIAMI: Done void CPed::Wait(void) { @@ -8966,7 +8751,6 @@ CPed::Wait(void) RestoreHeadingRate(); } -// --MIAMI: Done void CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg) { @@ -8985,7 +8769,6 @@ CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg) ped->Wait(); } -// --MIAMI: Done void CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -8996,21 +8779,18 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg) ped->Wait(); } -// --MIAMI: Done void CPed::RestoreHeadingRate(void) { m_headingRate = m_pedStats->m_headingChangeRate; } -// --MIAMI: Done void CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg) { ((CPed*)arg)->RestoreHeadingRate(); } -// --MIAMI: Done void CPed::FlagToDestroyWhenNextProcessed(void) { @@ -9034,7 +8814,6 @@ CPed::FlagToDestroyWhenNextProcessed(void) m_pVehicleAnim = nil; } -// --MIAMI: Done void CPed::SetSolicit(uint32 time) { @@ -9043,14 +8822,14 @@ CPed::SetSolicit(uint32 time) if (CharCreatedBy != MISSION_CHAR && m_carInObjective->m_nNumGettingIn == 0 && CTimer::GetTimeInMilliseconds() < m_objectiveTimer) { - if (m_vehEnterType == CAR_DOOR_LF) { + if (m_vehDoor == CAR_DOOR_LF) { m_fRotationDest = m_carInObjective->GetForward().Heading() - HALFPI; } else { m_fRotationDest = m_carInObjective->GetForward().Heading() + HALFPI; } if (Abs(m_fRotationDest - m_fRotationCur) < HALFPI) { - m_standardTimer = CTimer::GetTimeInMilliseconds() + time; + m_chatTimer = CTimer::GetTimeInMilliseconds() + time; if(!m_carInObjective->bIsVan && !m_carInObjective->bIsBus) m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_HOOKERTALK, 4.0f); @@ -9060,12 +8839,11 @@ CPed::SetSolicit(uint32 time) } } -// --MIAMI: Done void CPed::Solicit(void) { - if (m_standardTimer >= CTimer::GetTimeInMilliseconds() && m_carInObjective) { - CVector doorPos = GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType, 0.0f); + if (m_chatTimer >= CTimer::GetTimeInMilliseconds() && m_carInObjective) { + CVector doorPos = GetPositionToOpenCarDoor(m_carInObjective, m_vehDoor, 0.0f); Say(SOUND_PED_SOLICIT); if (FindPlayerVehicle() == m_carInObjective) { FindPlayerPed()->Say(SOUND_PED_SOLICIT); @@ -9106,7 +8884,6 @@ CPed::Solicit(void) } } -// --MIAMI: Done void CPed::SetBuyIceCream(void) { @@ -9119,13 +8896,12 @@ CPed::SetBuyIceCream(void) SetPedState(PED_BUY_ICECREAM); } -// --MIAMI: Done void CPed::BuyIceCream(void) { if (m_carInObjective) { CPed *driver = m_carInObjective->pDriver; - if (driver && CTimer::GetTimeInMilliseconds() > m_standardTimer) { + if (driver && CTimer::GetTimeInMilliseconds() > m_chatTimer) { SetChat(driver, 8000); driver->SetChat(this, 8000); return; @@ -9138,7 +8914,6 @@ CPed::BuyIceCream(void) } } -// --MIAMI: Done bool CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) { @@ -9201,7 +8976,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) bool canHeadToRf = NTVF_RF <= 0.0f || NTVF_RF >= HALFPI; // Only order of conditions are different among enterTypes. - if (m_vehEnterType == CAR_DOOR_RR) { + if (m_vehDoor == CAR_DOOR_RR) { if (canHeadToRr) { foundPos = rightRearPos; foundIt = true; @@ -9215,7 +8990,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) foundPos = leftFrontPos; foundIt = true; } - } else if(m_vehEnterType == CAR_DOOR_RF) { + } else if(m_vehDoor == CAR_DOOR_RF) { if (canHeadToRf) { foundPos = rightFrontPos; foundIt = true; @@ -9229,7 +9004,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) foundPos = leftRearPos; foundIt = true; } - } else if (m_vehEnterType == CAR_DOOR_LF) { + } else if (m_vehDoor == CAR_DOOR_LF) { if (canHeadToLf) { foundPos = leftFrontPos; foundIt = true; @@ -9243,7 +9018,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) foundPos = rightRearPos; foundIt = true; } - } else if (m_vehEnterType == CAR_DOOR_LR) { + } else if (m_vehDoor == CAR_DOOR_LR) { if (canHeadToLr) { foundPos = leftRearPos; foundIt = true; @@ -9272,7 +9047,6 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) return true; } -// --MIAMI: Done void CPed::SetLeader(CEntity *leader) { @@ -9284,7 +9058,6 @@ CPed::SetLeader(CEntity *leader) } } -// --MIAMI: Done bool CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal) { @@ -9317,7 +9090,6 @@ CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal) return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false); } -// --MIAMI: Done void CPed::SetJump(void) { @@ -9332,7 +9104,6 @@ CPed::SetJump(void) } } -// --MIAMI: Done void CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -9442,7 +9213,6 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// --MIAMI: Done void CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -9454,7 +9224,6 @@ CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg) animAssoc->blendDelta = -1000.0f; } -// --MIAMI: Done void CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -9471,7 +9240,6 @@ CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bIsLanding = false; } -// --MIAMI: Done bool CPed::CanPedDriveOff(void) { @@ -9487,7 +9255,6 @@ CPed::CanPedDriveOff(void) } return true; } -// --MIAMI: Done void CPed::SetRadioStation(void) { @@ -9508,7 +9275,6 @@ CPed::SetRadioStation(void) } } -// --MIAMI: Done void CPed::WarpPedIntoCar(CVehicle *car) { @@ -9576,14 +9342,12 @@ CPed::WarpPedIntoCar(CVehicle *car) bChangedSeat = true; } -// --MIAMI: Done bool CPed::HasAttractor(void) { return m_attractor != nil; } -// --MIAMI: Done void CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float heading, float time, int32 qid) { @@ -9604,7 +9368,6 @@ CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float head m_positionInQueue = qid; } -// --MIAMI: Done void CPed::AttachPedToEntity(CEntity *ent, CVector offset, uint16 type, float rot, eWeaponType weapon) { @@ -9652,7 +9415,6 @@ CPed::AttachPedToEntity(CEntity *ent, CVector offset, uint16 type, float rot, eW PositionAttachedPed(); } -// --MIAMI: Done void CPed::DettachPedFromEntity(void) { @@ -9676,7 +9438,6 @@ CPed::DettachPedFromEntity(void) } } -// --MIAMI: Done void CPed::PositionAttachedPed() { @@ -9728,7 +9489,6 @@ CPed::PositionAttachedPed() } } -// --MIAMI: Done void CPed::Undress(const char* name) { @@ -9744,7 +9504,6 @@ CPed::Undress(const char* name) CWorld::Remove(this); } -// --MIAMI: Done void CPed::Dress(void) { @@ -9769,17 +9528,6 @@ CPed::Say(uint16 audio, int32 time) } } -void -CPed::SetWeaponLockOnTarget(CEntity *target) -{ - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - - m_pPointGunAt = (CPed*)target; - if (target) - ((CEntity*)target)->RegisterReference(&m_pPointGunAt); -} - #ifdef COMPATIBLE_SAVES #define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 608bb710..8b091d15 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -9,8 +9,8 @@ #include "Physical.h" #include "Weapon.h" #include "WeaponInfo.h" -#include "AnimationId.h" #include "PathFind.h" +#include "Collision.h" #define FEET_OFFSET 1.04f #define CHECK_NEARBY_THINGS_MAX_DIST 15.0f @@ -52,7 +52,7 @@ enum eFormation FORMATION_FRONT }; -enum FightState : int8 { +enum FightState { FIGHTSTATE_MOVE_FINISHED = -2, FIGHTSTATE_JUST_ATTACKED, FIGHTSTATE_NO_MOVE, @@ -187,7 +187,7 @@ enum eWaitState { WAITSTATE_PLAYANIM_HANDSUP_SIMPLE, }; -enum eObjective : uint32 { +enum eObjective { OBJECTIVE_NONE, OBJECTIVE_WAIT_ON_FOOT, OBJECTIVE_WAIT_ON_FOOT_FOR_COP, @@ -271,7 +271,7 @@ enum PedOnGroundState { PED_DEAD_ON_THE_FLOOR }; -enum PointBlankNecessity : uint8 { +enum PointBlankNecessity { NO_POINT_BLANK_PED, POINT_BLANK_FOR_WANTED_PED, POINT_BLANK_FOR_SOMEONE_ELSE @@ -492,10 +492,15 @@ public: uint32 bDonePositionOutOfCollision : 1; uint32 bCanAttackPlayerWithCops : 1; +#ifdef KANGAROO_CHEAT // our own flags uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle +#endif uint8 m_gangFlags; + uint8 m_unused15D; // these 3 can't be padding but had to actually have been members ... + uint8 m_unused15E; + uint8 m_unused15F; uint8 CharCreatedBy; eObjective m_objective; eObjective m_prevObjective; @@ -536,7 +541,7 @@ public: uint32 m_pathNodeTimer; CPathNode m_pathNodeObjPool[8]; CPathNode* m_pCurPathNode; - char m_nPathDir; + int8 m_nPathDir; CPathNode* m_pLastPathNode; CPathNode* m_pNextPathNode; CVector m_followPathDestPos; @@ -554,7 +559,7 @@ public: float m_fRotationCur; float m_fRotationDest; float m_headingRate; - uint16 m_vehEnterType; + uint16 m_vehDoor; int16 m_walkAroundType; CPhysical *m_pCurrentPhysSurface; CVector m_vecOffsetFromPhysSurface; @@ -598,7 +603,7 @@ public: uint32 m_curFightMove; uint32 m_lastFightMove; uint8 m_fightButtonPressure; - FightState m_fightState; + int8 m_fightState; bool m_takeAStepAfterAttack; uint8 m_bleedCounter; CFire *m_pFire; @@ -608,10 +613,10 @@ public: uint32 m_leaveCarTimer; uint32 m_getUpTimer; uint32 m_lookTimer; - uint32 m_standardTimer; + uint32 m_chatTimer; uint32 m_attackTimer; uint32 m_shootTimer; // shooting is a part of attack - uint32 m_hitRecoverTimer; + uint32 m_carJackTimer; uint32 m_objectiveTimer; uint32 m_duckTimer; uint32 m_duckAndCoverTimer; @@ -729,7 +734,7 @@ public: CPed *CheckForDeadPeds(void); bool CheckForExplosions(CVector2D &area); CPed *CheckForGunShots(void); - PointBlankNecessity CheckForPointBlankPeds(CPed*); + uint8 CheckForPointBlankPeds(CPed*); bool CheckIfInTheAir(void); void ClearAll(void); void SetPointGunAt(CEntity*); @@ -866,7 +871,6 @@ public: void PositionAttachedPed(); bool CanUseTorsoWhenLooking(); void ScanForDelayedResponseThreats(); - void SetWeaponLockOnTarget(CEntity*); // Static methods static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset); @@ -974,7 +978,7 @@ public: PedState GetPedState(void) { return m_nPedState; } void SetPedState(PedState state) { - if (GetPedState() == PED_FOLLOW_PATH) + if (GetPedState() == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH) ClearFollowPath(); m_nPedState = state; } @@ -1003,16 +1007,23 @@ public: // My names. Inlined in VC AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) { - if (m_nPedType == PEDTYPE_COP && !!weapon->m_bCop3rd) - return ANIM_WEAPON_FIRE_3RD; + if (m_nPedType == PEDTYPE_COP && weapon->IsFlagSet(WEAPONFLAG_COP3_RD)) + return Get3rdFireAnim(weapon); else return GetPrimaryFireAnim(weapon); } + static AnimationId Get3rdFireAnim(CWeaponInfo* weapon) { + if (weapon->IsFlagSet(WEAPONFLAG_COP3_RD)) + return ANIM_WEAPON_FIRE_3RD; + else + return (AnimationId)0; + } + static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) { - if (!!weapon->m_bGround2nd) + if (weapon->IsFlagSet(WEAPONFLAG_GROUND_2ND)) return ANIM_WEAPON_CROUCHFIRE; - else if (!!weapon->m_bGround3rd) + else if (weapon->IsFlagSet(WEAPONFLAG_GROUND_3RD)) return ANIM_WEAPON_FIRE_3RD; else if (kickFloorIfNone) return ANIM_KICK_FLOOR; @@ -1021,60 +1032,68 @@ public: } static AnimationId GetPrimaryFireAnim(CWeaponInfo* weapon) { - if (weapon->m_bAnimDetonate) + if (weapon->IsFlagSet(WEAPONFLAG_ANIMDETONATE)) return ANIM_BOMBER; else return ANIM_WEAPON_FIRE; } static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bReload) + if (weapon->IsFlagSet(WEAPONFLAG_RELOAD)) return ANIM_WEAPON_CROUCHRELOAD; else return (AnimationId)0; } static AnimationId GetCrouchFireAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bCrouchFire) + if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) return ANIM_WEAPON_CROUCHFIRE; else return (AnimationId)0; } static AnimationId GetReloadAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bReload) + if (weapon->IsFlagSet(WEAPONFLAG_RELOAD)) return ANIM_WEAPON_RELOAD; else return (AnimationId)0; } static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bFightMode) + if (weapon->IsFlagSet(WEAPONFLAG_FIGHTMODE)) return ANIM_MELEE_IDLE_FIGHTMODE; else return (AnimationId)0; } static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bFinish3rd) + if (weapon->IsFlagSet(WEAPONFLAG_FINISH_3RD)) return ANIM_MELEE_ATTACK_FINISH; else return (AnimationId)0; } static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bUse2nd) + if (weapon->IsFlagSet(WEAPONFLAG_USE_2ND)) return ANIM_WEAPON_FIRE_2ND; // or ANIM_MELEE_ATTACK_2ND else return (AnimationId)0; } static AnimationId GetMeleeStartAnim(CWeaponInfo* weapon) { - if (!!weapon->m_bPartialAttack) + if (weapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK)) return ANIM_MELEE_ATTACK_START; else return (AnimationId)0; } + + static AnimationId GetThrowAnim(CWeaponInfo *weapon) + { + if (weapon->IsFlagSet(WEAPONFLAG_THROW)) + return ANIM_THROWABLE_START_THROW; + else + return (AnimationId)0; + } // -- // My additions, because there were many, many instances of that. @@ -1097,6 +1116,16 @@ public: } // -- + inline void SetWeaponLockOnTarget(CEntity *target) + { + if (m_pPointGunAt) + m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); + + m_pPointGunAt = (CPed*)target; + if (target) + ((CEntity*)target)->RegisterReference(&m_pPointGunAt); + } + // Using this to abstract nodes of skinned and non-skinned meshes CVector GetNodePosition(int32 node) { @@ -1112,7 +1141,7 @@ public: RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID); RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); - RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, &mats[idx]); + RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]); } // set by 0482:set_threat_reaction_range_multiplier opcode diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 1f61118f..a0769b9c 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -30,8 +30,6 @@ #include "GameLogic.h" #include "Streaming.h" -//--MIAMI: file done - CVector vecPedCarDoorAnimOffset; CVector vecPedCarDoorLoAnimOffset; CVector vecPedVanRearDoorAnimOffset; @@ -44,7 +42,6 @@ CVector vecPedHarleyBikeJumpRhsAnimOffset; CVector vecPedDirtBikeJumpRhsAnimOffset; CVector vecPedBikeKickAnimOffset; -// --MIAMI: Done void CPed::SetObjectiveTimer(int time) { @@ -55,7 +52,6 @@ CPed::SetObjectiveTimer(int time) } } -// --MIAMI: Done void CPed::SetStoredObjective(void) { @@ -90,7 +86,6 @@ CPed::SetStoredObjective(void) } } -// --MIAMI: Done void CPed::ForceStoredObjective(eObjective objective) { @@ -124,7 +119,6 @@ CPed::ForceStoredObjective(eObjective objective) } } -// --MIAMI: Done bool CPed::IsTemporaryObjective(eObjective objective) { @@ -133,7 +127,6 @@ CPed::IsTemporaryObjective(eObjective objective) objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER; } -// --MIAMI: Done void CPed::SetObjective(eObjective newObj) { @@ -180,7 +173,6 @@ CPed::SetObjective(eObjective newObj) } } -// --MIAMI: Done void CPed::SetObjective(eObjective newObj, void *entity) { @@ -370,7 +362,6 @@ CPed::SetObjective(eObjective newObj, void *entity) } } -// --MIAMI: Done // Only used in 01E1: SET_CHAR_OBJ_FOLLOW_ROUTE opcode // IDA fails very badly in here, puts a fake loop and ignores SetFollowRoute call... void @@ -403,7 +394,6 @@ CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType) } } -// --MIAMI: Done void CPed::SetObjective(eObjective newObj, CVector dest) { @@ -543,7 +533,6 @@ CPed::SetObjective(eObjective newObj, CVector dest) } } -// --MIAMI: Done void CPed::SetObjective(eObjective newObj, float heading, const CVector& pos) { @@ -560,7 +549,6 @@ CPed::SetObjective(eObjective newObj, float heading, const CVector& pos) } } -// --MIAMI: Done void CPed::ClearObjective(void) { @@ -586,7 +574,6 @@ CPed::ClearObjective(void) } } -// --MIAMI: Done void CPed::ClearLeader(void) { @@ -606,7 +593,6 @@ CPed::ClearLeader(void) } } -// --MIAMI: Done void CPed::UpdateFromLeader(void) { @@ -765,7 +751,6 @@ CPed::UpdateFromLeader(void) } } -// --MIAMI: Done void CPed::RestorePreviousObjective(void) { @@ -788,7 +773,6 @@ CPed::RestorePreviousObjective(void) bObjectiveCompleted = false; } -// --MIAMI: Done void CPed::ProcessObjective(void) { @@ -924,10 +908,10 @@ CPed::ProcessObjective(void) m_pMyVehicle->SetStatus(STATUS_PHYSICS); m_pMyVehicle->AutoPilot.m_nPrevRouteNode = 0; if (m_nPedType == PEDTYPE_COP) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity); + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->GetWantedLevel() * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity); m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel(); } else { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity * 0.8f; m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY; } m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; @@ -1178,7 +1162,7 @@ CPed::ProcessObjective(void) bool foundSeat = false; if (m_carInObjective->IsBike()) { if (!m_carInObjective->pPassengers[0] && !(m_carInObjective->m_nGettingInFlags & (CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR))) { - m_vehEnterType = CAR_DOOR_RR; + m_vehDoor = CAR_DOOR_RR; foundSeat = true; } } else { @@ -1187,27 +1171,27 @@ CPed::ProcessObjective(void) if (m_carInObjective->pPassengers[2] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RR) { foundSeat = false; } else { - m_vehEnterType = CAR_DOOR_RR; + m_vehDoor = CAR_DOOR_RR; foundSeat = true; } } else { - m_vehEnterType = CAR_DOOR_LR; + m_vehDoor = CAR_DOOR_LR; foundSeat = true; } } else { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; foundSeat = true; } } for (int i = 2; i < m_carInObjective->m_nNumMaxPassengers; ++i) { if (!m_carInObjective->pPassengers[i] && !(m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RF)) { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; foundSeat = true; } } if (foundSeat) { - SetPosition(GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType)); - SetEnterCar(m_carInObjective, m_vehEnterType); + SetPosition(GetPositionToOpenCarDoor(m_carInObjective, m_vehDoor)); + SetEnterCar(m_carInObjective, m_vehDoor); } } m_objectiveTimer = 0; @@ -1334,14 +1318,14 @@ CPed::ProcessObjective(void) // I hope so CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); CVector maxShotPos = m_carInObjective->GetPosition() - ourHead; - maxShotPos.Normalise(); - maxShotPos = maxShotPos * wepInfo->m_fRange + ourHead; + maxShotPos *= wepInfo->m_fRange / maxShotPos.Magnitude(); + maxShotPos += ourHead; - CWorld::bIncludeDeadPeds = true; CColPoint foundCol; CEntity *foundEnt; - CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, - true, true, true, true, false, true, false); + + CWorld::bIncludeDeadPeds = true; + CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, true, true, true, true, false, true, false); CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); @@ -1520,7 +1504,7 @@ CPed::ProcessObjective(void) if (bInVehicle) { bScriptObjectiveCompleted = true; RestorePreviousObjective(); - } else if (m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) { + } else if (m_carJackTimer < CTimer::GetTimeInMilliseconds()) { CVehicle *carToSteal = nil; float closestCarDist = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST; CVector pos = GetPosition(); @@ -1545,7 +1529,7 @@ CPed::ProcessObjective(void) } if (carToSteal) { SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carToSteal); - m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000; + m_carJackTimer = CTimer::GetTimeInMilliseconds() + 5000; } else { RestorePreviousObjective(); RestorePreviousState(); @@ -1597,7 +1581,7 @@ CPed::ProcessObjective(void) Say(SOUND_PED_MUGGING); bRichFromMugging = true; - // VC FIX: ClearObjective() clears m_pedInObjective in VC (also same with VC_PED_PORTS), so get it before call + // FIX: ClearObjective() clears m_pedInObjective, so get it before call CPed *victim = m_pedInObjective; ClearObjective(); if (victim->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT @@ -1921,7 +1905,7 @@ CPed::ProcessObjective(void) ClearObjective(); CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle); m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity; m_pMyVehicle->SetStatus(STATUS_PHYSICS); } else { SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); @@ -2060,7 +2044,6 @@ CPed::ProcessObjective(void) } } -// --MIAMI: Done void CPed::SetFollowRoute(int16 currentPoint, int16 routeType) { @@ -2073,7 +2056,6 @@ CPed::SetFollowRoute(int16 currentPoint, int16 routeType) m_nextRoutePointPos = CRouteNode::GetPointPosition(GetNextPointOnRoute()); } -// --MIAMI: Done int CPed::GetNextPointOnRoute(void) { @@ -2101,7 +2083,6 @@ CPed::GetNextPointOnRoute(void) return nextPoint; } -// --MIAMI: Done bool CPed::HaveReachedNextPointOnRoute(float distToCountReached) { @@ -2112,7 +2093,6 @@ CPed::HaveReachedNextPointOnRoute(float distToCountReached) return false; } -// --MIAMI: Done bool CPed::CanSeeEntity(CEntity *entity, float threshold) { @@ -2138,7 +2118,6 @@ CPed::CanSeeEntity(CEntity *entity, float threshold) return neededTurn < threshold || TWOPI - threshold < neededTurn; } -// --MIAMI: Done // Only used while deciding which gun ped should switch to, if no ammo left. bool CPed::SelectGunIfArmed(void) @@ -2147,10 +2126,10 @@ CPed::SelectGunIfArmed(void) if (GetWeapon(i).m_nAmmoTotal > 0) { eWeaponType weaponType = GetWeapon(i).m_eWeaponType; - if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN || + if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_MP5 || weaponType == WEAPONTYPE_M4 || + weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN || weaponType == WEAPONTYPE_SPAS12_SHOTGUN || weaponType == WEAPONTYPE_STUBBY_SHOTGUN || - weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_M4 || weaponType == WEAPONTYPE_MP5 || - weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_FLAMETHROWER || weaponType == WEAPONTYPE_SNIPERRIFLE) { + weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_FLAMETHROWER) { SetCurrentWeapon(i); return true; } @@ -2159,7 +2138,6 @@ CPed::SelectGunIfArmed(void) SetCurrentWeapon(WEAPONTYPE_UNARMED); return false; } -// --MIAMI: Done void CPed::ReactToPointGun(CEntity *entWithGun) { @@ -2244,7 +2222,6 @@ CPed::ReactToPointGun(CEntity *entWithGun) } } -// --MIAMI: Done void CPed::ReactToAttack(CEntity *attacker) { @@ -2269,7 +2246,7 @@ CPed::ReactToAttack(CEntity *attacker) CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle); m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity; m_pMyVehicle->SetStatus(STATUS_PHYSICS); } @@ -2317,7 +2294,6 @@ CPed::ReactToAttack(CEntity *attacker) } } -// --MIAMI: Done void CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -2337,7 +2313,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) return; } - if (!ped->m_vehEnterType) { + if (!ped->m_vehDoor) { ped->QuitEnteringCar(); return; } @@ -2351,7 +2327,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) bool itsLow = !!veh->bLowVehicle; eDoors enterDoor; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: itsVan = false; enterDoor = DOOR_FRONT_RIGHT; @@ -2373,7 +2349,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) if (veh->IsBike()) { CPed *pedToDragOut = nil; if (veh->GetStatus() == STATUS_ABANDONED) { - if (ped->m_vehEnterType == CAR_WINDSCREEN) { + if (ped->m_vehDoor == CAR_WINDSCREEN) { ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_KICK, 6.0f); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); ((CBike*)veh)->bIsBeingPickedUp = true; @@ -2399,7 +2375,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); ((CBike*)veh)->bIsBeingPickedUp = true; } - } else if (ped->m_vehEnterType == CAR_WINDSCREEN) { + } else if (ped->m_vehDoor == CAR_WINDSCREEN) { if (veh->pDriver->m_nPedState != PED_DRIVING || veh->pDriver->bDontDragMeOutCar) { ped->QuitEnteringCar(); } else { @@ -2413,7 +2389,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) if (veh->pDriver) { if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) { ped->QuitEnteringCar(); - ped->SetFall(1000, ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, false); + ped->SetFall(1000, ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, false); return; } if (veh->pDriver->m_nPedState != PED_DRIVING || veh->pDriver->bDontDragMeOutCar) { @@ -2434,7 +2410,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) if (veh->pPassengers[0]) { if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) { ped->QuitEnteringCar(); - ped->SetFall(1000, ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, false); + ped->SetFall(1000, ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, false); return; } if (veh->pPassengers[0]->m_nPedState != PED_DRIVING || veh->pPassengers[0]->bDontDragMeOutCar) { @@ -2457,7 +2433,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) } if (pedToDragOut) { - pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, false); + pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehDoor, false); if (pedToDragOut->IsGangMember()) pedToDragOut->RegisterThreatWithGangPeds(ped); @@ -2535,7 +2511,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) } if (player != veh->pDriver) { - veh->pDriver->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, true); + veh->pDriver->SetBeingDraggedFromCar(veh, ped->m_vehDoor, true); if (veh->pDriver->IsGangMember()) veh->pDriver->RegisterThreatWithGangPeds(ped); } @@ -2562,7 +2538,6 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// --MIAMI: Done void CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -2585,7 +2560,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) eDoors door; CPed *pedInSeat = nil; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; pedInSeat = veh->pPassengers[0]; @@ -2643,21 +2618,21 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) if (veh->m_vecMoveSpeed.Magnitude() > 0.2f || veh->IsCar() && veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI && ((CAutomobile*)veh)->m_nWheelsOnGround == 0) { ped->QuitEnteringCar(); - if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) + if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR) ped->SetFall(1000, ANIM_KO_SPIN_R, false); else ped->SetFall(1000, ANIM_KO_SPIN_L, false); return; } - veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_OPEN_LHS, 1.0f); + veh->ProcessOpenDoor(ped->m_vehDoor, ANIM_CAR_OPEN_LHS, 1.0f); - if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_RF) + if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_RF) isVan = false; if (ped->m_nPedState != PED_CARJACK || isBus) { - if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR) { + if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR) { if (veh->IsBike()) { ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_R); } else if (isVan) { @@ -2682,14 +2657,14 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_RHS); } - if (ped->m_vehEnterType == CAR_DOOR_RF && pedInSeat && veh->IsCar()) + if (ped->m_vehDoor == CAR_DOOR_RF && pedInSeat && veh->IsCar()) pedInSeat->SetObjective(OBJECTIVE_LEAVE_CAR, veh); } ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); } else { CPed *pedToDragOut = nil; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: pedToDragOut = veh->pPassengers[0]; break; case CAR_DOOR_RR: pedToDragOut = veh->pPassengers[2]; break; case CAR_DOOR_LF: pedToDragOut = veh->pDriver; break; @@ -2703,7 +2678,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective); } - if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) { + if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR) { if (pedToDragOut && !pedToDragOut->bDontDragMeOutCar) { if (pedToDragOut->m_nPedState != PED_DRIVING) { @@ -2773,7 +2748,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) } if (player != pedToDragOut) { - pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, false); + pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehDoor, false); if (pedToDragOut->IsGangMember()) pedToDragOut->RegisterThreatWithGangPeds(ped); } @@ -2782,7 +2757,6 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) return; } -// --MIAMI: Done void CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -2844,7 +2818,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg) } if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) { - if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR) { + if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR) { if (veh->IsBike()) ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_R); else if (isLow) @@ -2868,7 +2842,6 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg) } } -// --MIAMI: Done void CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -2901,7 +2874,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) } return; } - if (ped->IsPlayer() && ped->m_vehEnterType == CAR_DOOR_LF + if (ped->IsPlayer() && ped->m_vehDoor == CAR_DOOR_LF && (Pads[0].GetAccelerate() >= 255.0f || Pads[0].GetBrake() >= 255.0f) && veh->IsCar() && !veh->pDriver) { @@ -2920,7 +2893,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) bool isBus = !!veh->bIsBus; bool isLow = !!veh->bLowVehicle; eDoors enterDoor; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: isVan = false; enterDoor = DOOR_FRONT_RIGHT; @@ -2966,7 +2939,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) ped->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 400; return; } - if (driver != ped && ped->m_vehEnterType != CAR_DOOR_LF) { + if (driver != ped && ped->m_vehDoor != CAR_DOOR_LF) { if (!driver->IsPlayer()) { driver->bUsePedNodeSeek = true; driver->m_pLastPathNode = nil; @@ -3018,7 +2991,6 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// --MIAMI: Done void CPed::PedShuffle(void) { @@ -3034,7 +3006,6 @@ CPed::PedShuffle(void) } } -// --MIAMI: Done void CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -3049,10 +3020,10 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg) bool isLow = !!veh->bLowVehicle; if (!veh->bIsBus) - veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_CLOSEDOOR_LHS, 1.0f); + veh->ProcessOpenDoor(ped->m_vehDoor, ANIM_CAR_CLOSEDOOR_LHS, 1.0f); eDoors door; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; break; case CAR_DOOR_RR: door = DOOR_REAR_RIGHT; break; case CAR_DOOR_LF: door = DOOR_FRONT_LEFT; break; @@ -3065,7 +3036,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg) if (door == DOOR_FRONT_LEFT || ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || veh->bIsBus || veh->m_nNumMaxPassengers == 0) { PedSetInCarCB(nil, ped); - } else if (ped->m_vehEnterType == CAR_DOOR_RF + } else if (ped->m_vehDoor == CAR_DOOR_RF && (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF || (veh->pDriver != nil && (veh->pDriver->m_objective != OBJECTIVE_LEAVE_CAR @@ -3101,7 +3072,6 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// --MIAMI: Done void CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg) { @@ -3113,7 +3083,6 @@ CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg) } } -// --MIAMI: Done void CPed::SetFormation(eFormation type) { @@ -3137,7 +3106,6 @@ CPed::SetFormation(eFormation type) m_pedFormation = type; } -// --MIAMI: Done CVector CPed::GetFormationPosition(void) { @@ -3186,7 +3154,6 @@ CPed::GetFormationPosition(void) return m_pedInObjective->GetMatrix() * formationOffset; } -// --MIAMI: Done void CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -3218,7 +3185,7 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) veh->m_vecMoveSpeed += CVector(0.001f, 0.001f, 0.001f); veh->m_vecTurnSpeed += CVector(0.001f, 0.001f, 0.001f); if (!veh->bIsBus) - veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_GETOUT_LHS, 1.0f); + veh->ProcessOpenDoor(ped->m_vehDoor, ANIM_CAR_GETOUT_LHS, 1.0f); /* // Duplicate and only in PC for some reason @@ -3228,7 +3195,7 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) } */ eDoors door; - switch (ped->m_vehEnterType) { + switch (ped->m_vehDoor) { case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; break; @@ -3293,9 +3260,15 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) } if (ped->bFleeAfterExitingCar || ped->bGonnaKillTheCarJacker) { - // POTENTIAL BUG? Why DOOR_FRONT_LEFT instead of door variable? or vice versa? +#ifdef FIX_BUGS + if (!veh->IsDoorMissing(door)) + ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING); + PedSetOutCarCB(nil, ped); + return; +#else if (!veh->IsDoorMissing(door)) ((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING); +#endif } else { switch (door) { case DOOR_FRONT_LEFT: @@ -3320,7 +3293,6 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) return; } -// --MIAMI: Done void CPed::LineUpPedWithCar(PedLineUpPhase phase) { @@ -3391,7 +3363,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) if (veh->GetUp().z <= -0.8f) vehIsUpsideDown = true; - if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { + if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) { if (vehIsUpsideDown) { m_fRotationDest = -PI + veh->GetForward().Heading(); } else if (veh->bIsBus) { @@ -3399,7 +3371,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) } else { m_fRotationDest = veh->GetForward().Heading(); } - } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { + } else if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) { if (vehIsUpsideDown) { m_fRotationDest = veh->GetForward().Heading(); } else if (veh->bIsBus) { @@ -3414,7 +3386,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) m_fRotationDest = veh->GetForward().Heading(); } else if (veh->bIsBus) { m_fRotationDest = 0.5f * PI + veh->GetForward().Heading(); - } else if (m_vehEnterType == CAR_WINDSCREEN) { + } else if (m_vehDoor == CAR_WINDSCREEN) { m_fRotationDest = veh->GetForward().Heading() + PI; } else { m_fRotationDest = veh->GetForward().Heading(); @@ -3522,7 +3494,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) if (phase == LINE_UP_TO_CAR_2) { neededPos = GetPosition(); } else { - neededPos = GetPositionToOpenCarDoor(veh, m_vehEnterType, seatPosMult); + neededPos = GetPositionToOpenCarDoor(veh, m_vehDoor, seatPosMult); } autoZPos = neededPos; @@ -3639,13 +3611,13 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) SetHeading(m_fRotationCur); } else { CMatrix vehDoorMat(veh->GetMatrix()); - vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, GetLocalPositionToOpenCarDoor(veh, m_vehEnterType, 0.0f)); + vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, GetLocalPositionToOpenCarDoor(veh, m_vehDoor, 0.0f)); - if (m_vehEnterType == CAR_WINDSCREEN || veh->bIsBus) { + if (m_vehDoor == CAR_WINDSCREEN || veh->bIsBus) { CMatrix correctionMat; - if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) + if (veh->bIsBus && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)) correctionMat.SetRotateZ(-HALFPI); - else if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) + else if (veh->bIsBus && (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)) correctionMat.SetRotateZ(HALFPI); else correctionMat.SetRotateZ(PI); @@ -3657,7 +3629,6 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) } -// --MIAMI: Done void CPed::SetCarJack(CVehicle* car) { @@ -3669,7 +3640,7 @@ CPed::SetCarJack(CVehicle* car) return; if (car->IsBike()) { - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_DOOR_RF: doorFlag = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF; door = DOOR_FRONT_RIGHT; @@ -3696,7 +3667,7 @@ CPed::SetCarJack(CVehicle* car) break; } } else { - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_DOOR_RF: doorFlag = CAR_DOOR_FLAG_RF; door = DOOR_FRONT_RIGHT; @@ -3737,10 +3708,9 @@ CPed::SetCarJack(CVehicle* car) if (m_nPedState != PED_CARJACK && !m_pVehicleAnim) if ((car->IsDoorReady(door) || car->IsDoorFullyOpen(door))) if (!car->bIsBeingCarJacked && !(doorFlag & car->m_nGettingInFlags) && !(doorFlag & car->m_nGettingOutFlags)) - SetCarJack_AllClear(car, m_vehEnterType, doorFlag); + SetCarJack_AllClear(car, m_vehDoor, doorFlag); } -// --MIAMI: Done void CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag) { @@ -3761,7 +3731,7 @@ CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag) Say(SOUND_PED_CAR_JACKING, 1000); CVector carEnterPos; - carEnterPos = GetPositionToOpenCarDoor(car, m_vehEnterType); + carEnterPos = GetPositionToOpenCarDoor(car, m_vehDoor); car->m_nGettingInFlags |= doorFlag; m_vecOffsetSeek = carEnterPos - GetPosition(); @@ -3774,7 +3744,7 @@ CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag) float zDiff = Max(0.0f, carEnterPos.z - GetPosition().z); bUsesCollision = false; - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_LHS : ANIM_CAR_ALIGN_LHS, 4.0f); else m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_RHS : ANIM_CAR_ALIGN_RHS, 4.0f); @@ -3783,7 +3753,6 @@ CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag) } } -// --MIAMI: Done void CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) { @@ -3800,14 +3769,14 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) if (veh->IsBike()) { ((CBike*)veh)->bIsBeingPickedUp = true; if (veh->pPassengers[0] != this && (vehEnterType != CAR_WINDSCREEN || veh->pPassengers[0])) - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; else - m_vehEnterType = CAR_DOOR_LR; + m_vehDoor = CAR_DOOR_LR; } else { - m_vehEnterType = vehEnterType; + m_vehDoor = vehEnterType; } - if (m_vehEnterType == CAR_DOOR_LF) { + if (m_vehDoor == CAR_DOOR_LF) { if (veh->pDriver && veh->pDriver->IsPlayer()) veh->SetStatus(STATUS_PLAYER_DISABLED); else @@ -3827,12 +3796,11 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) SetRadioStation(); if(veh->IsBike()) - veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehEnterType); + veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehDoor); else - veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType); + veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehDoor); } -// --MIAMI: Done void CPed::BeingDraggedFromCar(void) { @@ -3848,15 +3816,15 @@ CPed::BeingDraggedFromCar(void) assocGroup = ((CBike*)m_pMyVehicle)->m_bikeAnimType; } else { - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { - if (bWillBeQuickJacked && m_vehEnterType == CAR_DOOR_LF) { + if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) { + if (bWillBeQuickJacked && m_vehDoor == CAR_DOOR_LF) { enterAnim = ANIM_CAR_QJACKED; } else if (m_pMyVehicle->bLowVehicle) { enterAnim = ANIM_CAR_LJACKED_LHS; } else { enterAnim = ANIM_CAR_JACKED_LHS; } - } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { + } else if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) { if (m_pMyVehicle->bLowVehicle) enterAnim = ANIM_CAR_LJACKED_RHS; else @@ -3893,12 +3861,11 @@ CPed::BeingDraggedFromCar(void) static float mult = 5.f; if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) { if (m_pMyVehicle) { - m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult); + m_pMyVehicle->ProcessOpenDoor(m_vehDoor, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult); } } } -// --MIAMI: Done void CPed::SetEnterCar(CVehicle *car, uint32 unused) { @@ -3909,7 +3876,7 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused) uint8 doorFlag; eDoors door; if (car->IsBike()) { - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_DOOR_RF: doorFlag = CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF; door = DOOR_FRONT_RIGHT; @@ -3935,7 +3902,7 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused) break; } } else { - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_DOOR_RF: doorFlag = CAR_DOOR_FLAG_RF; door = DOOR_FRONT_RIGHT; @@ -3971,11 +3938,10 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused) || doorFlag && !car->IsDoorReady(door) && !car->IsDoorFullyOpen(door)) SetMoveState(PEDMOVE_STILL); else - SetEnterCar_AllClear(car, m_vehEnterType, doorFlag); + SetEnterCar_AllClear(car, m_vehDoor, doorFlag); } } -// --MIAMI: Done void CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) { @@ -3987,9 +3953,9 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) m_pSeekTarget = car; m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); - m_vehEnterType = doorNode; + m_vehDoor = doorNode; SetPedState(PED_ENTER_CAR); - if (m_vehEnterType == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && !car->IsBike()) { + if (m_vehDoor == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && !car->IsBike()) { car->bIsBeingCarJacked = true; } @@ -3997,7 +3963,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle); ((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++; bUsesCollision = false; - CVector doorOpenPos = GetPositionToOpenCarDoor(car, m_vehEnterType); + CVector doorOpenPos = GetPositionToOpenCarDoor(car, m_vehDoor); // Because buses have stairs if (!m_pMyVehicle->bIsBus) @@ -4020,7 +3986,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) car->AutoPilot.m_nCruiseSpeed = 0; } else { - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_RHS : ANIM_CAR_ALIGN_RHS, 4.0f); else m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_LHS : ANIM_CAR_ALIGN_LHS, 4.0f); @@ -4028,7 +3994,6 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) } } -// --MIAMI: Done void CPed::EnterCar(void) { @@ -4036,11 +4001,11 @@ CPed::EnterCar(void) CVehicle *veh = m_pMyVehicle; // Not used. - // CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehEnterType); + // CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehDoor); if (veh->CanPedOpenLocks(this)) { - if (m_vehEnterType && m_pVehicleAnim) { - veh->ProcessOpenDoor(m_vehEnterType, m_pVehicleAnim->animId, m_pVehicleAnim->currentTime); + if (m_vehDoor && m_pVehicleAnim) { + veh->ProcessOpenDoor(m_vehDoor, m_pVehicleAnim->animId, m_pVehicleAnim->currentTime); } } bIsInTheAir = false; @@ -4072,7 +4037,6 @@ CPed::EnterCar(void) } } -// --MIAMI: Done void CPed::QuitEnteringCar(void) { @@ -4096,10 +4060,10 @@ CPed::QuitEnteringCar(void) RestorePreviousObjective(); if (veh->IsBike()) { - veh->m_nGettingInFlags &= ~GetBikeDoorFlag(m_vehEnterType); + veh->m_nGettingInFlags &= ~GetBikeDoorFlag(m_vehDoor); ((CBike*)veh)->bIsBeingPickedUp = false; } else - veh->m_nGettingInFlags &= ~GetEnterCarDoorFlag(m_vehEnterType, veh->m_nNumMaxPassengers); + veh->m_nGettingInFlags &= ~GetEnterCarDoorFlag(m_vehDoor, veh->m_nNumMaxPassengers); } bUsesCollision = true; @@ -4121,7 +4085,6 @@ CPed::QuitEnteringCar(void) } } -// --MIAMI: Done void CPed::SetExitBoat(CVehicle *boat) { @@ -4133,7 +4096,7 @@ CPed::SetExitBoat(CVehicle *boat) newPos = { 0.0f, 0.0f, boatCol->boundingBox.min.z }; newPos = boat->GetMatrix() * newPos; newPos.z += 1.0f; - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; PedSetOutCarCB(nil, this); bIsStanding = true; m_pCurSurface = boat; @@ -4142,7 +4105,7 @@ CPed::SetExitBoat(CVehicle *boat) } else { if (boat->m_modelIndex == MI_SKIMMER) { if (!boat->bIsInWater) { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; PedSetOutCarCB(nil, this); bIsStanding = true; SetMoveState(PEDMOVE_STILL); @@ -4163,7 +4126,7 @@ CPed::SetExitBoat(CVehicle *boat) newPos.z += 2.0f; } - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; PedSetOutCarCB(nil, this); bIsStanding = true; m_pCurSurface = boat; @@ -4179,7 +4142,6 @@ CPed::SetExitBoat(CVehicle *boat) m_vecMoveSpeed = boat->m_vecMoveSpeed; } -// --MIAMI: Done // wantedDoorNode = 0 means that func. will determine it void CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) @@ -4404,14 +4366,14 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) // needed for PositionPedOutOfCollision() optedDoorNode = firstOptedDoor; - m_vehEnterType = firstOptedDoor; + m_vehDoor = firstOptedDoor; PositionPedOutOfCollision(); teleportNeeded = true; } } if (!teleportNeeded && veh->IsOnItsSide()) { - m_vehEnterType = optedDoorNode; + m_vehDoor = optedDoorNode; PositionPedOutOfCollision(); teleportNeeded = true; } @@ -4429,7 +4391,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) bUsesCollision = false; m_pSeekTarget = veh; m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget); - m_vehEnterType = optedDoorNode; + m_vehDoor = optedDoorNode; SetPedState(PED_EXIT_CAR); if (m_pVehicleAnim && m_pVehicleAnim->flags & ASSOC_PARTIAL) m_pVehicleAnim->blendDelta = -1000.0f; @@ -4442,16 +4404,16 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) PedSetOutCarCB(nil, this); } else { if (veh->GetUp().z <= -0.8f && !veh->IsBike()) { - if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { + if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) { m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS2); - } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { + } else if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) { m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS); } m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this); } else if (veh->IsBike()) { CBike* bike = (CBike*)veh; - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_BUMP_REAR: case CAR_BOOT: m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_GETOFF_BACK); @@ -4470,7 +4432,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) int8 exitFlags = 0; // Bike door flags incl. passenger jump off - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_BUMP_REAR: case CAR_DOOR_RR: case CAR_DOOR_LR: @@ -4484,7 +4446,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) } // Passenger get off - if (m_vehEnterType == CAR_BUMP_REAR || m_vehEnterType == CAR_BOOT) { + if (m_vehDoor == CAR_BUMP_REAR || m_vehDoor == CAR_BOOT) { m_pVehicleAnim->SetFinishCallback(RestoreHeadingRateCB, this); m_headingRate = 0.0f; @@ -4494,7 +4456,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) } } else { - switch (m_vehEnterType) { + switch (m_vehDoor) { case CAR_DOOR_RF: if (canJumpOut) { m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLOUT_RHS); @@ -4545,7 +4507,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) break; } if (!bBusJacked && !canJumpOut) { - veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType); + veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehDoor); } m_pVehicleAnim->SetFinishCallback(canJumpOut ? RestoreHeadingRateCB : PedAnimStepOutCarCB, this); } @@ -4564,14 +4526,13 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) } } -// --MIAMI: Done void CPed::ExitCar(void) { if (!m_pVehicleAnim) { if (InVehicle()) { if (m_pMyVehicle->IsBike()) { - if (m_vehEnterType == CAR_BOOT || m_vehEnterType == CAR_BUMP_REAR) { + if (m_vehDoor == CAR_BOOT || m_vehDoor == CAR_BUMP_REAR) { ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false); } } else if (m_pMyVehicle->IsCar()) { @@ -4605,7 +4566,7 @@ CPed::ExitCar(void) LineUpPedWithCar(LINE_UP_TO_CAR_FALL); } } else { - m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, exitAnim, animTime); + m_pMyVehicle->ProcessOpenDoor(m_vehDoor, exitAnim, animTime); if (m_pSeekTarget) { // Car is upside down @@ -4636,7 +4597,6 @@ CPed::ExitCar(void) } } -// --MIAMI: Done CVector CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component) { @@ -4649,7 +4609,6 @@ CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component) return vehDoorPos; } -// --MIAMI: Done void CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen) { @@ -4667,17 +4626,17 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen) angleDiff += TWOPI; if (Abs(angleDiff) < DEGTORAD(30.f) - && (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed > 1.5f && !m_vehEnterType || + && (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed > 1.5f && !m_vehDoor || !IsPlayer() && m_nPedType != PEDTYPE_COP && m_nMoveState == PEDMOVE_RUN && m_pedStats->m_temper > 65 - && !m_vehEnterType || m_vehEnterType == CAR_WINDSCREEN)) { - m_vehEnterType = CAR_WINDSCREEN; + && !m_vehDoor || m_vehDoor == CAR_WINDSCREEN)) { + m_vehDoor = CAR_WINDSCREEN; posToOpen = GetPositionToOpenCarDoor(veh, CAR_WINDSCREEN); return; } } } - } else if (m_vehEnterType == CAR_DOOR_LF && veh->pDriver && !veh->bLowVehicle && !veh->bIsBus) { + } else if (m_vehDoor == CAR_DOOR_LF && veh->pDriver && !veh->bLowVehicle && !veh->bIsBus) { enterOffset = &vecPedQuickDraggedOutCarAnimOffset; } @@ -4688,10 +4647,10 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen) if ((lfPos - GetPosition()).MagnitudeSqr2D() < (rfPos - GetPosition()).MagnitudeSqr2D()) { if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) { - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; posToOpen = lfPos; } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; posToOpen = rfPos; } } else { @@ -4705,20 +4664,19 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen) && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset) || (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) { - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; posToOpen = lfPos; } else { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; posToOpen = rfPos; } } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) { - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; posToOpen = lfPos; } } } -// --MIAMI: Done bool CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen) { @@ -4729,7 +4687,7 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen) switch (veh->GetModelIndex()) { case MI_BUS: - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; posToOpen = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF); return true; case MI_RHINO: @@ -4788,21 +4746,20 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen) CVector2D nextToCompare = rfPosDist; posToOpen = rfPos; - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; if (lrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) { - m_vehEnterType = CAR_DOOR_LR; + m_vehDoor = CAR_DOOR_LR; posToOpen = lrPos; nextToCompare = lrPosDist; } if (rrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) { - m_vehEnterType = CAR_DOOR_RR; + m_vehDoor = CAR_DOOR_RR; posToOpen = rrPos; } return canEnter; } -// --MIAMI: Done void CPed::GoToNearestDoor(CVehicle *veh) { @@ -4812,21 +4769,19 @@ CPed::GoToNearestDoor(CVehicle *veh) SetMoveState(PEDMOVE_RUN); } -// --MIAMI: Done // Unused void CPed::PedSetGetInCarPositionCB(CAnimBlendAssociation* assoc, void* arg) { CPed* pPed = (CPed*)arg; CMatrix mat(pPed->GetMatrix()); CVehicle* pVehicle = pPed->m_pMyVehicle; - const CVector& offset = (pVehicle->bIsVan && (pPed->m_vehEnterType == CAR_DOOR_RR || pPed->m_vehEnterType == CAR_DOOR_LR)) ? vecPedVanRearDoorAnimOffset : vecPedCarDoorAnimOffset; + const CVector& offset = (pVehicle->bIsVan && (pPed->m_vehDoor == CAR_DOOR_RR || pPed->m_vehDoor == CAR_DOOR_LR)) ? vecPedVanRearDoorAnimOffset : vecPedCarDoorAnimOffset; CVector position = Multiply3x3(mat, offset) + pPed->GetPosition(); CPedPlacement::FindZCoorForPed(&position); pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f); pPed->SetPosition(position); } -// --MIAMI: Done void CPed::SetAnimOffsetForEnterOrExitVehicle(void) { @@ -4908,8 +4863,8 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) vecPedVanRearDoorAnimOffset = lastFrame->translation; } } - // I think this is leftover and ANIM_TRAIN_GETOUT - enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_IDLE_STANCE3)->hierarchy; + + enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_TRAIN_GETOUT)->hierarchy; seq = enterAssoc->sequences; CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { @@ -4988,7 +4943,6 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) CAnimManager::RemoveAnimBlockRef(bikedBlock); } -// --MIAMI: Done void CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -5003,7 +4957,7 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void ped->bUsesCollision = true; ped->RestartNonPartialAnims(); draggedOutOffset = vecPedQuickDraggedOutCarAnimOffset; - if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR) + if (ped->m_vehDoor == CAR_DOOR_RF || ped->m_vehDoor == CAR_DOOR_RR) draggedOutOffset.x = -draggedOutOffset.x; finalPos = Multiply3x3(pedMat, draggedOutOffset) + ped->GetPosition(); @@ -5016,7 +4970,7 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void ped->m_fRotationCur = ped->m_fRotationDest; ped->CalculateNewOrientation(); - if (!veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedQuickDraggedOutCarAnimOffset)) + if (!veh->IsRoomForPedToLeaveCar(ped->m_vehDoor, &vecPedQuickDraggedOutCarAnimOffset)) ped->PositionPedOutOfCollision(); } @@ -5077,7 +5031,6 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void ped->m_nLastPedState = PED_WANDER_PATH; } -// --MIAMI: Done void CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -5107,7 +5060,7 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) } else { draggedOutOffset = vecPedDraggedOutCarAnimOffset; } - if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR) + if (ped->m_vehDoor == CAR_DOOR_RF || ped->m_vehDoor == CAR_DOOR_RR) draggedOutOffset.x = -draggedOutOffset.x; CVector posAfterBeingDragged = Multiply3x3(pedMat, draggedOutOffset); @@ -5116,7 +5069,7 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); ped->SetPosition(posAfterBeingDragged); - if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedDraggedOutCarAnimOffset)) { + if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehDoor, &vecPedDraggedOutCarAnimOffset)) { ped->PositionPedOutOfCollision(); } @@ -5174,7 +5127,6 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) ped->SetGetUp(); } -// --MIAMI: Done uint8 CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos) { @@ -5184,7 +5136,7 @@ CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos) CVehicleModelInfo* trainModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(train->m_modelIndex); CMatrix trainMat = CMatrix(train->GetMatrix()); - doorPos = trainModel->m_positions[m_vehEnterType]; + doorPos = trainModel->m_positions[m_vehDoor]; doorPos.x -= 1.5f; doorPos = Multiply3x3(trainMat, doorPos); doorPos += train->GetPosition(); @@ -5192,7 +5144,6 @@ CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos) return 1; } -// --MIAMI: Done uint8 CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos) { @@ -5235,23 +5186,22 @@ CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos) if (distMidEntry < distLeftEntry) { if (distMidEntry < distRightEntry) { enterPos = midEntryPos; - m_vehEnterType = TRAIN_POS_MID_ENTRY; + m_vehDoor = TRAIN_POS_MID_ENTRY; } else { enterPos = rightEntryPos; - m_vehEnterType = TRAIN_POS_RIGHT_ENTRY; + m_vehDoor = TRAIN_POS_RIGHT_ENTRY; } } else if (distRightEntry < distLeftEntry) { enterPos = rightEntryPos; - m_vehEnterType = TRAIN_POS_RIGHT_ENTRY; + m_vehDoor = TRAIN_POS_RIGHT_ENTRY; } else { enterPos = leftEntryPos; - m_vehEnterType = TRAIN_POS_LEFT_ENTRY; + m_vehDoor = TRAIN_POS_LEFT_ENTRY; } return 1; } -// --MIAMI: Done :D void CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -5284,7 +5234,7 @@ CPed::SetEnterTrain(CVehicle *train, uint32 unused) m_pMyVehicle = train; m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); - m_nPedState = PED_ENTER_TRAIN; + SetPedState(PED_ENTER_TRAIN); m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETIN, 4.0f); m_pVehicleAnim->SetFinishCallback(PedSetInTrainCB, this); bUsesCollision = false; @@ -5358,7 +5308,7 @@ CPed::SetExitTrain(CVehicle* train) CVector exitPos; GetNearestTrainPedPosition(train, exitPos); */ - m_nPedState = PED_EXIT_TRAIN; + SetPedState(PED_EXIT_TRAIN); m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETOUT, 4.0f); m_pVehicleAnim->SetFinishCallback(PedSetOutTrainCB, this); bUsesCollision = false; @@ -5384,7 +5334,7 @@ CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bUsesCollision = true; ped->m_pVehicleAnim = nil; ped->bInVehicle = false; - ped->m_nPedState = PED_IDLE; + ped->SetPedState(PED_IDLE); ped->RestorePreviousObjective(); ped->SetMoveState(PEDMOVE_STILL); @@ -5401,7 +5351,6 @@ CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg) } #endif -// --MIAMI: Done void CPed::RegisterThreatWithGangPeds(CEntity *attacker) { @@ -5452,7 +5401,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker) if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType && nearVehDriver->CharCreatedBy == RANDOM_CHAR) { if (nearVeh->IsVehicleNormal() && nearVeh->IsCar()) { - nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fUnkMaxVelocity * 0.8f; + nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fMaxCruiseVelocity * 0.8f; nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY; nearVeh->SetStatus(STATUS_PHYSICS); nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE; @@ -5465,7 +5414,6 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker) } } -// --MIAMI: Done // Some helper function which doesn't exist in og game. inline void SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVector2D farDist, CPathNode *closeNode, CPathNode *closeNode2, int runCount = 3) @@ -5495,7 +5443,6 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto } } -// --MIAMI: Done bool CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords) { @@ -5536,7 +5483,6 @@ CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords) return false; } -// --MIAMI: Done bool CPed::DuckAndCover(void) { @@ -5725,7 +5671,6 @@ CPed::DuckAndCover(void) return false; } -// --MIAMI: Done CVector CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset) { @@ -5773,7 +5718,6 @@ CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset) return veh->GetPosition() + doorPos; } -// --MIAMI: Done CVector CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult) { @@ -5859,7 +5803,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP } } -// --MIAMI: Done, but what is this parameter for? +// TODO: what is this parameter for? void CPed::SetDuck(uint32 time, bool sth) { @@ -5885,7 +5829,6 @@ CPed::SetDuck(uint32 time, bool sth) } } -// --MIAMI: Done void CPed::Duck(void) { @@ -5893,22 +5836,25 @@ CPed::Duck(void) ClearDuck(); else if (bIsDucking && bCrouchWhenShooting) { CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - CAnimBlendAssociation *attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); - if (!attackAssoc) { - if(!!weapon->m_bCrouchFire) - attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon)); + CAnimBlendAssociation *crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); + if (!crouchAnim) { + if(GetCrouchFireAnim(weapon)) + crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon)); } - if (!attackAssoc) { - if(!!weapon->m_bReload) - attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon)); + if (!crouchAnim) { + if(GetCrouchReloadAnim(weapon)) + crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon)); } - if (!attackAssoc) { + if (!crouchAnim) { bIsDucking = false; +#if defined FIX_BUGS || defined FREE_CAM + if (IsPlayer()) + bCrouchWhenShooting = false; +#endif } } } -// --MIAMI: Done void CPed::ClearDuck(bool clearTimer) { @@ -5931,7 +5877,6 @@ CPed::ClearDuck(bool clearTimer) } } -// --MIAMI: Done void CPed::InformMyGangOfAttack(CEntity *attacker) { @@ -5966,7 +5911,6 @@ CPed::InformMyGangOfAttack(CEntity *attacker) } } -// --MIAMI: Done void CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg) { @@ -5989,7 +5933,6 @@ CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg) veh->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_OK); } -// --MIAMI: Done void CPed::SetSeekBoatPosition(CVehicle *boat) { @@ -6005,7 +5948,6 @@ CPed::SetSeekBoatPosition(CVehicle *boat) SetPedState(PED_SEEK_IN_BOAT); } -// --MIAMI: Done void CPed::SeekBoatPosition(void) { @@ -6020,14 +5962,13 @@ CPed::SeekBoatPosition(void) m_vecSeekPos = boatMat * enterOffset; if (Seek()) { // We arrived to the boat - m_vehEnterType = 0; + m_vehDoor = 0; SetEnterCar(m_carInObjective, 0); } } else RestorePreviousState(); } -// --MIAMI: Done bool CPed::IsRoomToBeCarJacked(void) { @@ -6051,7 +5992,6 @@ CPed::IsRoomToBeCarJacked(void) return false; } -// --MIAMI: Done void CPed::AddInCarAnims(CVehicle* car, bool isDriver) { @@ -6086,7 +6026,6 @@ CPed::AddInCarAnims(CVehicle* car, bool isDriver) StopNonPartialAnims(); } -// --MIAMI: Done void CPed::RemoveDrivebyAnims() { @@ -6114,7 +6053,6 @@ CPed::RemoveDrivebyAnims() animAssoc->blendDelta = -1000.0f; } -// --MIAMI: Done void CPed::RemoveInCarAnims(void) { @@ -6127,7 +6065,6 @@ CPed::RemoveInCarAnims(void) } } -// --MIAMI: Done bool CPed::PositionPedOutOfCollision(void) { @@ -6157,9 +6094,9 @@ CPed::PositionPedOutOfCollision(void) foundAPos = true; } - } else if (m_vehEnterType != 0) { + } else if (m_vehDoor != 0) { // Try the normal way - CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehEnterType); + CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehDoor); newPos = pos; GetMatrix().SetTranslate(newPos); if (!CheckCollision()) { @@ -6169,7 +6106,7 @@ CPed::PositionPedOutOfCollision(void) } float vehRelativeExitX = vehCol->boundingBox.min.x - 0.355f; - if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) + if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) vehRelativeExitX = 0.355f + vehCol->boundingBox.max.x; if (!foundAPos) { @@ -6266,7 +6203,6 @@ CPed::PositionPedOutOfCollision(void) return true; } -// --MIAMI: Done // "Any" means he shouldn't have to be in vehicle. bool CPed::PositionAnyPedOutOfCollision(void) @@ -6279,7 +6215,6 @@ CPed::PositionAnyPedOutOfCollision(void) int smallestDistNearVeh = 999; int smallestDistSomewhereClose = 999; - CVector vehPos = m_pMyVehicle->GetPosition(); CVector potentialPos; potentialPos.y = GetPosition().y - 3.5f; potentialPos.z = GetPosition().z; @@ -6323,7 +6258,6 @@ CPed::PositionAnyPedOutOfCollision(void) return true; } -// --MIAMI: Done bool CPed::WarpPedToNearLeaderOffScreen(void) { @@ -6357,7 +6291,6 @@ CPed::WarpPedToNearLeaderOffScreen(void) return teleported; } -// --MIAMI: Done bool CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo) { @@ -6391,7 +6324,6 @@ CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo) return teleported; } -// --MIAMI: Done int32 CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWithTarget) { @@ -6490,19 +6422,19 @@ CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWith if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) { GoToNearestDoor(vehOfTarget); } else { - m_vehEnterType = 0; + m_vehDoor = 0; if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) { - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) { - m_vehEnterType = CAR_DOOR_LR; + m_vehDoor = CAR_DOOR_LR; } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) { - m_vehEnterType = CAR_DOOR_RR; + m_vehDoor = CAR_DOOR_RR; } // Unused - // GetPositionToOpenCarDoor(vehOfTarget, m_vehEnterType); - SetSeekCar(vehOfTarget, m_vehEnterType); + // GetPositionToOpenCarDoor(vehOfTarget, m_vehDoor); + SetSeekCar(vehOfTarget, m_vehDoor); SetMoveState(PEDMOVE_RUN); } } @@ -6666,7 +6598,6 @@ CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWith return ATTACK_IN_PROGRESS; } -// --MIAMI: Done int32 CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWithTarget) { @@ -6780,19 +6711,19 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) { GoToNearestDoor(vehOfTarget); } else { - m_vehEnterType = 0; + m_vehDoor = 0; if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) { - m_vehEnterType = CAR_DOOR_LF; + m_vehDoor = CAR_DOOR_LF; } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) { - m_vehEnterType = CAR_DOOR_RF; + m_vehDoor = CAR_DOOR_RF; } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) { - m_vehEnterType = CAR_DOOR_LR; + m_vehDoor = CAR_DOOR_LR; } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) { - m_vehEnterType = CAR_DOOR_RR; + m_vehDoor = CAR_DOOR_RR; } // Unused - // GetPositionToOpenCarDoor(vehOfTarget, m_vehEnterType); - SetSeekCar(vehOfTarget, m_vehEnterType); + // GetPositionToOpenCarDoor(vehOfTarget, m_vehDoor); + SetSeekCar(vehOfTarget, m_vehDoor); SetMoveState(PEDMOVE_RUN); } } @@ -6921,7 +6852,6 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith } } -// --MIAMI: Done bool CPed::CanBeDamagedByThisGangMember(CPed* who) { diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp index 05e72ed3..22e0e779 100644 --- a/src/peds/PedAttractor.cpp +++ b/src/peds/PedAttractor.cpp @@ -4,6 +4,7 @@ #include "General.h" #include "Vehicle.h" #include "World.h" +#include "MemoryHeap.h" const int gcMaxSizeOfAtmQueue = 1; const int gcMaxSizeOfSeatQueue = 1; @@ -12,14 +13,22 @@ const int gcMaxSizeOfPizzaQueue = 5; const int gcMaxSizeOfShelterQueue = 5; const int gcMaxSizeOfIceCreamQueue = 1; -//--MIAMI: file done - std::vector<CVector> CPedShelterAttractor::ms_displacements; CPedAttractorManager* GetPedAttractorManager() { - static CPedAttractorManager manager; - return &manager; +// mobile just has a static here: +/* + static CPedAttractorManager pedAttrMgr; + return &pedAttrMgr; +*/ + static CPedAttractorManager *pedAttrMgr; + if(pedAttrMgr == nil){ + PUSH_MEMID(MEMID_PED_ATTR); + pedAttrMgr = new CPedAttractorManager; + POP_MEMID(); + } + return pedAttrMgr; } CVehicleToEffect::CVehicleToEffect(CVehicle* pVehicle) : m_pVehicle(pVehicle) @@ -100,8 +109,10 @@ const C2dEffect* CPedAttractorManager::GetEffectForIceCreamVan(CVehicle* pVehicl return assoc->ChooseEffect(pos); } } + PUSH_MEMID(MEMID_PED_ATTR); CVehicleToEffect effect(pVehicle); vVehicleToEffect.push_back(effect); + POP_MEMID(); return effect.ChooseEffect(pos); } @@ -645,6 +656,7 @@ CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect, pRegisteredAttractor->RegisterPed(pPed); return pRegisteredAttractor; } + PUSH_MEMID(MEMID_PED_ATTR); switch (pEffect->pedattr.type) { case ATTRACTOR_ATM: vecAttractors.push_back(new CPedAtmAttractor(pEffect, matrix, gcMaxSizeOfAtmQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.15f, 0.1f, 0.1f)); break; case ATTRACTOR_SEAT: vecAttractors.push_back(new CPedSeatAttractor(pEffect, matrix, gcMaxSizeOfSeatQueue, 1.0f, 30000.0f, 3000.0f, 0.125f, 0.1f, 0.1f, 0.1f)); break; @@ -653,6 +665,7 @@ CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect, case ATTRACTOR_SHELTER: vecAttractors.push_back(new CPedShelterAttractor(pEffect, matrix, gcMaxSizeOfShelterQueue, 1.0f, 30000.0f, 3000.0f, 0.5f, 6.28f, 0.1f, 0.1f)); break; case ATTRACTOR_ICECREAM: vecAttractors.push_back(new CPedIceCreamAttractor(pEffect, matrix, gcMaxSizeOfIceCreamQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.3f, 0.1f, 0.1f)); break; } + POP_MEMID(); if (pRegisteredAttractor) pRegisteredAttractor->RegisterPed(pPed); return pRegisteredAttractor; diff --git a/src/peds/PedChat.cpp b/src/peds/PedChat.cpp index 470b7eeb..ec6719c6 100644 --- a/src/peds/PedChat.cpp +++ b/src/peds/PedChat.cpp @@ -4,8 +4,6 @@ #include "General.h" #include "Ped.h" -// --MIAMI: file done - // Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL) PedAudioData CommentWaitTime[56] = { { 500, 800, 500, 2 }, diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index 0367ef4c..e8fee649 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -26,8 +26,6 @@ #include "Glass.h" #include "SpecialFX.h" -//--MIAMI: file done - uint16 nPlayerInComboMove; RpClump* flyingClumpTemp; @@ -159,7 +157,6 @@ CheckForPedsOnGroundToAttack(CPed *attacker, CPed **pedOnGround) return stateToReturn; } -// --MIAMI: Done void CPed::SetPointGunAt(CEntity *to) { @@ -202,7 +199,6 @@ CPed::SetPointGunAt(CEntity *to) Say(SOUND_PED_ATTACK); } -// --MIAMI: Done void CPed::PointGunAt(void) { @@ -210,7 +206,7 @@ CPed::PointGunAt(void) float animLoopStart = weaponInfo->m_fAnimLoopStart; CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) { - if (!!weaponInfo->m_bCrouchFire) { + if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) { weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo)); animLoopStart = weaponInfo->m_fAnim2LoopStart; } @@ -223,14 +219,13 @@ CPed::PointGunAt(void) if (bIsDucking) m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; - if (weaponInfo->m_bCanAimWithArm) + if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; else m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } } -// --MIAMI: Done void CPed::ClearPointGunAt(void) { @@ -247,7 +242,7 @@ CPed::ClearPointGunAt(void) weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); if (!animAssoc || animAssoc->blendDelta < 0.0f) { - if (!!weaponInfo->m_bCrouchFire) { + if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) { animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo)); } } @@ -257,7 +252,6 @@ CPed::ClearPointGunAt(void) } } -// --MIAMI: Done void CPed::SetAttack(CEntity *victim) { @@ -271,7 +265,7 @@ CPed::SetAttack(CEntity *victim) if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE || (bIsDucking && !bCrouchWhenShooting)) return; - if (curWeapon->m_bReload && + if (curWeapon->IsFlagSet(WEAPONFLAG_RELOAD) && (RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) { if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected) bIsAttacking = false; @@ -281,10 +275,10 @@ CPed::SetAttack(CEntity *victim) return; } - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->IsFlagSet(WEAPONFLAG_FIGHTMODE) || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) { if (IsPlayer() || (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL - && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->m_bPartialAttack)) { + && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK))) { if (m_nPedState != PED_ATTACK) { SetPedState(PED_ATTACK); @@ -303,7 +297,7 @@ CPed::SetAttack(CEntity *victim) return; } - if (curWeapon->m_bPartialAttack && + if (curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK) && (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed >= 1.0f || m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN)) { @@ -326,7 +320,7 @@ CPed::SetAttack(CEntity *victim) if (m_pSeekTarget) m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); - if (curWeapon->m_bCanAim) { + if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM)) { CVector aimPos = GetRight() * 0.1f + GetForward() * 0.2f + GetPosition(); aimPos += GetUp() * 0.35f; CEntity *obstacle = CWorld::TestSphereAgainstWorld(aimPos, 0.2f, nil, true, false, false, true, false, false); @@ -354,7 +348,7 @@ CPed::SetAttack(CEntity *victim) } else if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) { SetAimFlag(m_fRotationCur); ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch(); - } else if (curWeapon->m_bCanAimWithArm) { + } else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) { SetAimFlag(m_fRotationCur); } } @@ -367,7 +361,7 @@ CPed::SetAttack(CEntity *victim) if (IsPlayer()) CPad::GetPad(0)->ResetAverageWeapon(); - PointBlankNecessity pointBlankStatus; + uint8 pointBlankStatus; if ((curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT || GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER) && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT @@ -380,7 +374,7 @@ CPed::SetAttack(CEntity *victim) if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed && (IsPlayer() || !m_carInObjective)) StartFightAttack(200); } else { - if (!curWeapon->m_bCanAim) + if (!curWeapon->IsFlagSet(WEAPONFLAG_CANAIM)) m_pSeekTarget = nil; if (m_nPedState != PED_AIM_GUN) @@ -388,7 +382,7 @@ CPed::SetAttack(CEntity *victim) SetPedState(PED_ATTACK); SetMoveState(PEDMOVE_NONE); - if (bCrouchWhenShooting && bIsDucking && !!curWeapon->m_bCrouchFire) { + if (bCrouchWhenShooting && bIsDucking && curWeapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) { CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon)); if (curMoveAssoc) { if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon))->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { @@ -402,9 +396,9 @@ CPed::SetAttack(CEntity *victim) animDelta = 1000.0f; AnimationId fireAnim; - if (curWeapon->m_bThrow) + if (curWeapon->IsFlagSet(WEAPONFLAG_THROW)) fireAnim = ANIM_THROWABLE_START_THROW; - else if (CGame::nastyGame && (curWeapon->m_bGround2nd || curWeapon->m_bGround3rd)) { + else if (CGame::nastyGame && (curWeapon->IsFlagSet(WEAPONFLAG_GROUND_2ND) || curWeapon->IsFlagSet(WEAPONFLAG_GROUND_3RD))) { PedOnGroundState pedOnGround = CheckForPedsOnGroundToAttack(this, nil); if (pedOnGround > PED_IN_FRONT_OF_ATTACKER || pedOnGround == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle()) { fireAnim = GetFireAnimGround(curWeapon, false); @@ -440,7 +434,6 @@ CPed::SetAttack(CEntity *victim) SetLookTimer(100); } -// --MIAMI: Done void CPed::ClearAttack(void) { @@ -461,7 +454,6 @@ CPed::ClearAttack(void) } } -// --MIAMI: Done void CPed::ClearAttackByRemovingAnim(void) { @@ -472,20 +464,20 @@ CPed::ClearAttackByRemovingAnim(void) CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon)); if (!weaponAssoc) { - if (!!weapon->m_bCrouchFire) + if (GetCrouchFireAnim(weapon)) weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon)); } if (!weaponAssoc) { - if(!!weapon->m_bFinish3rd) + if(GetFinishingAttackAnim(weapon)) weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFinishingAttackAnim(weapon)); } if (!weaponAssoc) { - if(!!weapon->m_bUse2nd) + if(GetSecondFireAnim(weapon)) weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(weapon)); } if (!weaponAssoc) { - if(!!weapon->m_bCop3rd) - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL); + if(Get3rdFireAnim(weapon)) + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), Get3rdFireAnim(weapon)); } if (weaponAssoc) { weaponAssoc->blendDelta = -8.0f; @@ -497,7 +489,6 @@ CPed::ClearAttackByRemovingAnim(void) } } -// --MIAMI: Done void CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) { @@ -507,10 +498,10 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) if (ped->m_nPedState != PED_ATTACK) { if (ped->bIsDucking && ped->IsPedInControl()) { - if (currentWeapon->m_bReload) { + if (GetCrouchReloadAnim(currentWeapon)) { reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon)); } - if (currentWeapon->m_bCrouchFire && attackAssoc) { + if (GetCrouchFireAnim(currentWeapon) && attackAssoc) { if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) { newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); @@ -527,11 +518,12 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) newAnim = CAnimManager::AddAnimation(ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_THROWABLE_THROW); } newAnim->SetFinishCallback(FinishedAttackCB, ped); + } else if (ped->bIsDucking && ped->bCrouchWhenShooting) { - if (currentWeapon->m_bReload) { + if (GetCrouchReloadAnim(currentWeapon)) { reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon)); } - if (currentWeapon->m_bCrouchFire && attackAssoc) { + if (GetCrouchFireAnim(currentWeapon) && attackAssoc) { if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) { newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); @@ -576,7 +568,6 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) } } -// --MIAMI: Done void CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) { @@ -588,17 +579,17 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) if (ped->bIsDucking && ped->bCrouchWhenShooting) { CAnimBlendAssociation *crouchFireAssoc = nil; - if (!!weapon->m_bCrouchFire) { + if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) { crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchFireAnim(weapon)); } - if (!!weapon->m_bReload && reloadAssoc) { + if (weapon->IsFlagSet(WEAPONFLAG_RELOAD) && reloadAssoc) { if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) { CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength); crouchAssoc->flags &= ~ASSOC_RUNNING; } } - } else if (weapon->m_bReloadLoop2Start && ped->bIsAttacking) { + } else if (weapon->IsFlagSet(WEAPONFLAG_RELOAD_LOOP2START) && ped->bIsAttacking) { CAnimBlendAssociation *fireAssoc = CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, GetPrimaryFireAnim(weapon), 8.0f); fireAssoc->SetFinishCallback(FinishedAttackCB, ped); @@ -610,8 +601,7 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) } } -// --MIAMI: Done -PointBlankNecessity +uint8 CPed::CheckForPointBlankPeds(CPed *pedToVerify) { float pbDistance = 1.1f; @@ -654,15 +644,12 @@ CPed::CheckForPointBlankPeds(CPed *pedToVerify) return NO_POINT_BLANK_PED; } -// --MIAMI: Done except commented things void CPed::Attack(void) { CAnimBlendAssociation *weaponAnimAssoc; int32 weaponAnim; - eWeaponType ourWeaponType; float weaponAnimTime; - eWeaponFire ourWeaponFire; float animLoopEnd; CWeaponInfo *ourWeapon; bool attackShouldContinue; @@ -672,11 +659,9 @@ CPed::Attack(void) float animLoopStart; CVector firePos; - ourWeaponType = GetWeapon()->m_eWeaponType; - ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType); - ourWeaponFire = ourWeapon->m_eWeaponFire; + ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); weaponAnimAssoc = nil; - attackShouldContinue = bIsAttacking; + attackShouldContinue = !!bIsAttacking; reloadAnimAssoc = nil; throwAssoc = nil; animLoopStart = ourWeapon->m_fAnimLoopStart; @@ -685,7 +670,7 @@ CPed::Attack(void) weaponAnim = ourWeapon->m_AnimToPlay; if (bIsDucking) { - if (!!ourWeapon->m_bCrouchFire && bCrouchWhenShooting) { + if(GetCrouchFireAnim(ourWeapon) && bCrouchWhenShooting) { weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(ourWeapon)); if (weaponAnimAssoc) { animLoopStart = ourWeapon->m_fAnim2LoopStart; @@ -693,21 +678,22 @@ CPed::Attack(void) delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; } } - } else { - AnimationId anim = GetFireAnimNotDucking(ourWeapon); - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), anim); - if (anim == ANIM_WEAPON_FIRE_3RD && weaponAnimAssoc) { + } else if (m_nPedType == PEDTYPE_COP && Get3rdFireAnim(ourWeapon)){ + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), Get3rdFireAnim(ourWeapon)); + if (weaponAnimAssoc) { animLoopStart = 11.f/30.f; animLoopEnd = 19.f/30.f; delayBetweenAnimAndFire = 14.f/30.f; } + } else { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(ourWeapon)); } - if (ourWeapon->m_bReload) { + if (GetReloadAnim(ourWeapon)) { reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon)); } - if (!!ourWeapon->m_bReload && !reloadAnimAssoc) { + if (GetCrouchReloadAnim(ourWeapon) && !reloadAnimAssoc) { reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon)); } @@ -723,8 +709,8 @@ CPed::Attack(void) reloadAnimAssoc->blendDelta = -8.0f; } - if (!!ourWeapon->m_bThrow) { - throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_THROWABLE_START_THROW); + if (GetThrowAnim(ourWeapon)) { + throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetThrowAnim(ourWeapon)); } if ( CTimer::GetTimeInMilliseconds() < m_shootTimer ) @@ -732,8 +718,8 @@ CPed::Attack(void) bool meleeAttackStarted = false; if ( !weaponAnimAssoc ) { - if (!!ourWeapon->m_bPartialAttack) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_ATTACK_START); + if (GetMeleeStartAnim(ourWeapon)) { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(ourWeapon)); if ( weaponAnimAssoc ) { if ( IsPlayer() ) meleeAttackStarted = true; @@ -756,7 +742,7 @@ CPed::Attack(void) } } if (!weaponAnimAssoc) { - if (!!ourWeapon->m_bUse2nd) { + if (GetSecondFireAnim(ourWeapon)) { weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(ourWeapon)); if (weaponAnimAssoc) { animLoopStart = ourWeapon->m_fAnim2LoopStart; @@ -777,15 +763,16 @@ CPed::Attack(void) if (!weaponAnimAssoc) { if (!throwAssoc) { if (attackShouldContinue) { - if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { - if (bCrouchWhenShooting && bIsDucking && !!ourWeapon->m_bCrouchFire) { + if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { + if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(ourWeapon)) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetCrouchFireAnim(ourWeapon), 8.0f); } else if(GetSecondFireAnim(ourWeapon) && CGeneral::GetRandomNumber() & 1){ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f); - } else if (!CGame::nastyGame || (!ourWeapon->m_bGround2nd && !ourWeapon->m_bGround3rd) || - ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { + } else if(!CGame::nastyGame || ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE || + !GetFireAnimGround(ourWeapon, false) || + CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimNotDucking(ourWeapon), 8.0f); @@ -820,20 +807,20 @@ CPed::Attack(void) } } - float animStart = ourWeapon->m_fAnimLoopStart * 0.4f; + float animStart = animLoopStart * 0.4f; weaponAnimTime = weaponAnimAssoc->currentTime; if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) { - if (!bIsDucking && !(m_nPedType == PEDTYPE_COP && ourWeapon->m_bCop3rd && weaponAnimAssoc->animId == ANIM_WEAPON_FIRE_3RD) && ourWeapon->m_bCanAimWithArm) + if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; else m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } - if (ourWeaponType != WEAPONTYPE_CHAINSAW + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_CHAINSAW || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) { - if (ourWeaponType == WEAPONTYPE_CHAINSAW) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW) { DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_ATTACK, 0.0f); } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { if (weaponAnimAssoc->speed < 1.0f) @@ -842,7 +829,7 @@ CPed::Attack(void) } else { firePos = ourWeapon->m_vecFireOffset; - if (ourWeaponType != WEAPONTYPE_KATANA && ourWeaponType != WEAPONTYPE_CHAINSAW) { + if(ourWeapon->m_AnimToPlay != ASSOCGRP_BASEBALLBAT && ourWeapon->m_AnimToPlay != ASSOCGRP_GOLFCLUB) { if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) { TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR); } else { @@ -857,11 +844,11 @@ CPed::Attack(void) GetWeapon()->Fire(this, &firePos); - if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE || - ourWeaponType == WEAPONTYPE_TEARGAS) { - RemoveWeaponModel(ourWeapon->m_nModelId); + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MOLOTOV || GetWeapon()->m_eWeaponType == WEAPONTYPE_GRENADE || GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE || + GetWeapon()->m_eWeaponType == WEAPONTYPE_TEARGAS) { + RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId); } - if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { + if (GetWeapon()->m_nAmmoTotal == 0 && ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { SelectGunIfArmed(); } @@ -873,13 +860,13 @@ CPed::Attack(void) switch (ourWeapon->m_AnimToPlay) { case ASSOCGRP_UNARMED: if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (ourWeaponType << 8))); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (GetWeapon()->m_eWeaponType << 8))); break; case ASSOCGRP_KNIFE: case ASSOCGRP_BASEBALLBAT: case ASSOCGRP_GOLFCLUB: case ASSOCGRP_CHAINSAW: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (GetWeapon()->m_eWeaponType << 8))); break; default: break; @@ -920,9 +907,9 @@ CPed::Attack(void) if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) { weaponAnimTime = weaponAnimAssoc->currentTime; - firePos = ourWeapon->m_vecFireOffset; if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) { + firePos = ourWeapon->m_vecFireOffset; TransformToNode(firePos, PED_HANDR); CVector gunshellPos( @@ -942,14 +929,13 @@ CPed::Attack(void) } if (IsPlayer()) { - eWeaponType weaponType = GetWeapon()->m_eWeaponType; - if (weaponType == WEAPONTYPE_BASEBALLBAT || weaponType == WEAPONTYPE_GOLFCLUB || weaponType == WEAPONTYPE_KATANA) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon()->m_eWeaponType == WEAPONTYPE_GOLFCLUB || GetWeapon()->m_eWeaponType == WEAPONTYPE_KATANA) { float loopEndWithDelay = animLoopEnd; if (loopEndWithDelay >= 98.0f) loopEndWithDelay = (14.0f / 30.0f) + delayBetweenAnimAndFire; if (weaponAnimAssoc->flags & ASSOC_RUNNING) { if (weaponAnimAssoc->currentTime >= animLoopStart && weaponAnimAssoc->currentTime <= loopEndWithDelay) - CSpecialFX::AddWeaponStreak(weaponType); + CSpecialFX::AddWeaponStreak(GetWeapon()->m_eWeaponType); } } } @@ -968,22 +954,14 @@ CPed::Attack(void) weaponAnimTime = weaponAnimAssoc->currentTime; // Anim loop end, either start the loop again or finish the attack - if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) { + if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE) { if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING) { - if (ourWeapon->m_bReload && !reloadAnimAssoc) { + if (GetReloadAnim(ourWeapon) && !reloadAnimAssoc) { if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) { - CAnimBlendAssociation *newReloadAssoc; - if (bIsDucking) { - newReloadAssoc = CAnimManager::BlendAnimation( - GetClump(), ourWeapon->m_AnimToPlay, - GetCrouchReloadAnim(ourWeapon), - 8.0f); - } else { - newReloadAssoc = CAnimManager::BlendAnimation( - GetClump(), ourWeapon->m_AnimToPlay, - GetReloadAnim(ourWeapon), - 8.0f); - } + CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation( + GetClump(), ourWeapon->m_AnimToPlay, + bIsDucking && GetCrouchReloadAnim(ourWeapon) ? GetCrouchReloadAnim(ourWeapon) : GetReloadAnim(ourWeapon), + 8.0f); newReloadAssoc->SetFinishCallback(FinishedReloadCB, this); } ClearLookFlag(); @@ -1003,20 +981,20 @@ CPed::Attack(void) PedOnGroundState pedOnGroundState; if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE && (CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER) - || ourWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { + || GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { AnimationId fireAnim = GetFireAnimGround(ourWeapon, false); if (weaponAnimAssoc->animId == fireAnim) weaponAnimAssoc->SetCurrentTime(0.1f); else { - if (fireAnim) { + if (GetFireAnimGround(ourWeapon, false)) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, fireAnim, 8.0f); } else { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_KICK_FLOOR, 8.0f); } } weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this); - } else if (!!ourWeapon->m_bUse2nd) { + } else if (GetSecondFireAnim(ourWeapon)) { if (weaponAnimAssoc->animId == GetSecondFireAnim(ourWeapon)) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE, 8.0f); } else { @@ -1027,23 +1005,23 @@ CPed::Attack(void) weaponAnimAssoc->SetCurrentTime(animLoopStart); weaponAnimAssoc->SetRun(); } - } - } else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { - weaponAnimAssoc->SetCurrentTime(animLoopEnd); - weaponAnimAssoc->flags &= ~ASSOC_RUNNING; - SetPointGunAt(m_pPointGunAt); - } else { - ClearAimFlag(); + } else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { + weaponAnimAssoc->SetCurrentTime(animLoopEnd); + weaponAnimAssoc->flags &= ~ASSOC_RUNNING; + SetPointGunAt(m_pPointGunAt); + } else { + ClearAimFlag(); - // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) - if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType); + // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) + if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); - // Fun fact: removing this part leds to reloading flamethrower - if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { - weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; - weaponAnimAssoc->flags &= ~ASSOC_RUNNING; - weaponAnimAssoc->blendDelta = -4.0f; + // Fun fact: removing this part leds to reloading flamethrower + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { + weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; + weaponAnimAssoc->flags &= ~ASSOC_RUNNING; + weaponAnimAssoc->blendDelta = -4.0f; + } } } @@ -1053,7 +1031,6 @@ CPed::Attack(void) bIsAttacking = attackShouldContinue; } -// --MIAMI: Done void CPed::StartFightAttack(uint8 buttonPressure) { @@ -1146,7 +1123,6 @@ CPed::StartFightAttack(uint8 buttonPressure) nPlayerInComboMove = 0; } -// --MIAMI: Done void CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) { @@ -1332,7 +1308,7 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) m_fightButtonPressure = 0; } else if (IsPlayer() && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && - !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bFightMode) { + !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_FIGHTMODE)) { CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 4.0f); moveAssoc->SetCurrentTime(0.0f); moveAssoc->speed = 1.2f; @@ -1390,7 +1366,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) } } -// --MIAMI: Done void CPed::Fight(void) { @@ -1400,7 +1375,7 @@ CPed::Fight(void) eWeaponType weapon = GetWeapon()->m_eWeaponType; CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon); - if (weaponInfo->m_bFightMode && weapon != WEAPONTYPE_UNARMED) { + if (weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE) && weapon != WEAPONTYPE_UNARMED) { fightWithWeapon = true; tFightMoves[FIGHTMOVE_MELEE1].startFireTime = weaponInfo->m_fAnimFrameFire; tFightMoves[FIGHTMOVE_MELEE1].endFireTime = weaponInfo->m_fAnimLoopEnd; @@ -1618,7 +1593,6 @@ CPed::Fight(void) } } -// --MIAMI: Done int32 CPed::ChooseAttackAI(uint8 buttonPressure, bool fightWithWeapon) { @@ -1649,9 +1623,9 @@ CPed::ChooseAttackAI(uint8 buttonPressure, bool fightWithWeapon) if (m_pedInObjective->OnGroundOrGettingUp()) { if (CGame::nastyGame && dist < 1.2f && !m_pedInObjective->IsPlayer() && (m_pedInObjective->m_nPedState == PED_DEAD || !m_pedInObjective->IsPedHeadAbovePos(-0.3f))) { - if (weaponInfo->m_bGround2nd) + if (weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_2ND)) return FIGHTMOVE_MELEE2; - if (weaponInfo->m_bGround3rd) + if (weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD)) return FIGHTMOVE_MELEE3; return FIGHTMOVE_GROUNDKICK; @@ -1705,7 +1679,6 @@ CPed::ChooseAttackAI(uint8 buttonPressure, bool fightWithWeapon) return FIGHTMOVE_SHUFFLE_F; } -// --MIAMI: Done int32 CPed::ChooseAttackPlayer(uint8 buttonPressure, bool fightWithWeapon) { @@ -1879,9 +1852,9 @@ CPed::ChooseAttackPlayer(uint8 buttonPressure, bool fightWithWeapon) Say(SOUND_PED_ATTACK); } else if (groundAttackAlivePed || groundAttackDeadPed) { - if (fightWithWeapon && weaponInfo->m_bGround2nd) { + if (fightWithWeapon && weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_2ND)) { choosenMove = FIGHTMOVE_MELEE2; - } else if (fightWithWeapon && weaponInfo->m_bGround3rd) { + } else if (fightWithWeapon && weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD)) { choosenMove = FIGHTMOVE_MELEE3; } else { choosenMove = FIGHTMOVE_GROUNDKICK; @@ -1946,7 +1919,6 @@ CPed::ChooseAttackPlayer(uint8 buttonPressure, bool fightWithWeapon) return choosenMove; } -// --MIAMI: Done void CPed::EndFight(uint8 endType) { @@ -1957,7 +1929,7 @@ CPed::EndFight(uint8 endType) RestorePreviousState(); CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); if (!animAssoc) - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE); if (animAssoc) animAssoc->flags |= ASSOC_DELETEFADEDOUT; @@ -1981,7 +1953,6 @@ CPed::EndFight(uint8 endType) m_nWaitTimer = 0; } -// --MIAMI: Done void CPed::PlayHitSound(CPed *hitTo) { @@ -2027,9 +1998,9 @@ CPed::PlayHitSound(CPed *hitTo) if (weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE) { if (m_curFightMove >= FIGHTMOVE_MELEE1) { if (m_curFightMove == FIGHTMOVE_MELEE3) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (weapon << 8) | ENTITY_TYPE_PED); } else { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | ENTITY_TYPE_PED); } return; } @@ -2054,10 +2025,9 @@ CPed::PlayHitSound(CPed *hitTo) } if (soundId != NO_SND) - DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | ENTITY_TYPE_PED); } -// --MIAMI: Done bool CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon) { @@ -2150,11 +2120,10 @@ CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon) if (m_fightState == FIGHTSTATE_NO_MOVE) m_fightState = FIGHTSTATE_1; - m_vecHitLastPos = *touchedNodePos; + m_vecHitLastPos = touchedNodePos; return false; } -// --MIAMI: Done void CPed::FightHitPed(CPed *victim, CVector &touchPoint, CVector &dir, int16 piece) { @@ -2165,7 +2134,7 @@ CPed::FightHitPed(CPed *victim, CVector &touchPoint, CVector &dir, int16 piece) bool fightingWithWeapon = false; int damageMult = tFightMoves[m_curFightMove].damage * ((CGeneral::GetRandomNumber() & 1) + 2) + 1; - if (weaponInfo->m_bFightMode) { + if (weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE)) { fightingWithWeapon = true; if (m_curFightMove >= FIGHTMOVE_MELEE1) { damageMult = weaponInfo->m_nDamage; @@ -2304,7 +2273,6 @@ CPed::FightHitPed(CPed *victim, CVector &touchPoint, CVector &dir, int16 piece) } } -// --MIAMI: Done void CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -2316,7 +2284,6 @@ CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// --MIAMI: Done void CPed::LoadFightData(void) { @@ -2392,8 +2359,8 @@ CPed::LoadFightData(void) break; } - if (strncmp(animName, "default", 8) != 0) { - if (strncmp(animName, "null", 5) != 0) { + if (strcmp(animName, "default") != 0) { + if (strcmp(animName, "null") != 0) { animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName); tFightMoves[moveId].animId = (AnimationId)animAssoc->animId; } else { @@ -2404,7 +2371,6 @@ CPed::LoadFightData(void) } } -// --MIAMI: Done void CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle) { @@ -2414,7 +2380,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount SetStoredState(); bFindNewNodeAfterStateRestore = false; SetPedState(PED_INVESTIGATE); - m_standardTimer = CTimer::GetTimeInMilliseconds() + time; + m_chatTimer = CTimer::GetTimeInMilliseconds() + time; m_eventType = event; m_eventOrThreat = pos; m_distanceToCountSeekDone = distanceToCountDone; @@ -2427,7 +2393,6 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount } -// --MIAMI: Done void CPed::InvestigateEvent(void) { @@ -2438,13 +2403,13 @@ CPed::InvestigateEvent(void) if (m_nWaitState == WAITSTATE_TURN180) return; - if (CTimer::GetTimeInMilliseconds() > m_standardTimer) { + if (CTimer::GetTimeInMilliseconds() > m_chatTimer) { - if (m_standardTimer) { + if (m_chatTimer) { if (m_eventType < EVENT_UNK) SetWaitState(WAITSTATE_TURN180, nil); - m_standardTimer = 0; + m_chatTimer = 0; } else { ClearInvestigateEvent(); } @@ -2505,7 +2470,7 @@ CPed::InvestigateEvent(void) Say(SOUND_PED_CHAT_EVENT); } else { - m_standardTimer = 0; + m_chatTimer = 0; } } else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) { @@ -2633,7 +2598,6 @@ CPed::InvestigateEvent(void) } } -// --MIAMI: Done void CPed::ClearInvestigateEvent(void) { @@ -2649,7 +2613,7 @@ CPed::ClearInvestigateEvent(void) animAssoc->flags |= ASSOC_DELETEFADEDOUT; } if (m_eventType > EVENT_EXPLOSION) - m_standardTimer = CTimer::GetTimeInMilliseconds() + 15000; + m_chatTimer = CTimer::GetTimeInMilliseconds() + 15000; bGonnaInvestigateEvent = false; m_pEventEntity = nil; @@ -2659,7 +2623,6 @@ CPed::ClearInvestigateEvent(void) SetMoveState(PEDMOVE_WALK); } -// --MIAMI: Done bool CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction) { @@ -3231,7 +3194,6 @@ RecurseFrameChildrenToCloneCB(RwFrame *frame, void *data) return newFrame; } -// --MIAMI: Done void CPed::RemoveBodyPart(PedNode nodeId, int8 direction) { @@ -3262,7 +3224,6 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction) } } -// --MIAMI: Done CObject* CPed::SpawnFlyingComponent(int pedNode, int8 direction) { @@ -3270,7 +3231,6 @@ CPed::SpawnFlyingComponent(int pedNode, int8 direction) return nil; } -// --MIAMI: Done // III leftover and unused void CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer) @@ -3313,14 +3273,12 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer) } } -// --MIAMI: Done bool CPed::IsPedHeadAbovePos(float zOffset) { return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z; } -// --MIAMI: Done bool CPed::PlacePedOnDryLand(void) { @@ -3372,7 +3330,6 @@ CPed::PlacePedOnDryLand(void) return true; } -// --MIAMI: Done void CPed::CollideWithPed(CPed *collideWith) { @@ -3573,7 +3530,7 @@ CPed::CollideWithPed(CPed *collideWith) animAssoc->flags |= ASSOC_FADEOUTWHENDONE; collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 1000; if (m_nPedState == PED_ATTACK) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f); } } else { // We're at his right side @@ -3639,7 +3596,6 @@ CPed::CollideWithPed(CPed *collideWith) } } -// --MIAMI: Done void CPed::KillPedWithCar(CVehicle *car, float impulse) { @@ -3877,7 +3833,6 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) } } -// --MIAMI: Done void CPed::DriveVehicle(void) { @@ -3991,7 +3946,7 @@ CPed::DriveVehicle(void) } if (neededAngForWheelie >= 0.15f) { if (bike->m_fBrakePedal <= 0.5f || velocityFwdDotProd <= 0.01f) { - if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fUnkMaxVelocity > velocityFwdDotProd) { + if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fMaxCruiseVelocity > velocityFwdDotProd) { targetUDLean = Min(0.1f, targetUDLean); } } else { @@ -4185,7 +4140,6 @@ CPed::DriveVehicle(void) } } -// --MIAMI: Done void CPed::RemoveWeaponAnims(int unused, float animDelta) { diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index 2925667a..475e04f1 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -7,8 +7,6 @@ #include "General.h" #include "RwHelper.h" -//--MIAMI: file done - LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(8.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) }; LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(8.0f) }; LimbMovementInfo CPedIK::ms_headRestoreInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) }; diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h index 7dcf0ef3..ee719fea 100644 --- a/src/peds/PedIK.h +++ b/src/peds/PedIK.h @@ -52,7 +52,6 @@ public: bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch); bool PointGunAtPosition(CVector const& position); void GetComponentPosition(RwV3d &pos, uint32 node); - void GetComponentPosition(CVector &pos, uint32 node) { GetComponentPosition(*(RwV3d*)pos, node); } void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch); void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch); diff --git a/src/peds/PedPlacement.cpp b/src/peds/PedPlacement.cpp index 8012650a..840d33fc 100644 --- a/src/peds/PedPlacement.cpp +++ b/src/peds/PedPlacement.cpp @@ -4,7 +4,6 @@ #include "PedPlacement.h" #include "World.h" -// --MIAMI: Done bool CPedPlacement::FindZCoorForPed(CVector* pos) { diff --git a/src/peds/PedRoutes.cpp b/src/peds/PedRoutes.cpp index 2de90eae..3ff080e6 100644 --- a/src/peds/PedRoutes.cpp +++ b/src/peds/PedRoutes.cpp @@ -3,8 +3,6 @@ #include "main.h" #include "PedRoutes.h" -// --MIAMI: file done - CRouteNode gaRoutes[NUMPEDROUTES]; void diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp index e16fcee6..bacb1a78 100644 --- a/src/peds/PedType.cpp +++ b/src/peds/PedType.cpp @@ -4,8 +4,6 @@ #include "FileMgr.h" #include "PedType.h" -// --MIAMI: file done - CPedType *CPedType::ms_apPedType[NUM_PEDTYPES]; CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS]; @@ -47,7 +45,7 @@ CPedType::LoadPedData(void) char *buf; char line[256]; char word[32]; - size_t bp, buflen; + ssize_t bp, buflen; int lp, linelen; int type; uint32 flags; @@ -56,9 +54,9 @@ CPedType::LoadPedData(void) type = NUM_PEDTYPES; buf = new char[16 * 1024]; - CFileMgr::SetDir("DATA"); - buflen = CFileMgr::LoadFile("PED.DAT", (uint8*)buf, 16 * 1024, "r"); - CFileMgr::SetDir(""); + CFileMgr::SetDir("DATA"); + buflen = CFileMgr::LoadFile("PED.DAT", (uint8*)buf, 16 * 1024, "r"); + CFileMgr::SetDir(""); for(bp = 0; bp < buflen; ){ // read file line by line @@ -81,7 +79,7 @@ CPedType::LoadPedData(void) // Game uses just "line" here since sscanf already trims whitespace, but this is safer sscanf(&line[lp], "%s", word); - if(strncmp(word, "Threat", 7) == 0){ + if(strcmp(word, "Threat") == 0){ flags = 0; lp += 7; while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){ @@ -94,7 +92,7 @@ CPedType::LoadPedData(void) lp++; } ms_apPedType[type]->m_threats = flags; - }else if(strncmp(word, "Avoid", 6) == 0){ + }else if(strcmp(word, "Avoid") == 0){ flags = 0; lp += 6; while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){ @@ -248,19 +246,18 @@ CPedStats::LoadPedStats(void) char *buf; char line[256]; char name[32]; - size_t bp, buflen; + ssize_t bp, buflen; int lp, linelen; int type; float fleeDist, headingChangeRate, attackStrength, defendWeakness; int fear, temper, lawfullness, sexiness, flags; - type = 0; buf = new char[16 * 1024]; - CFileMgr::SetDir("DATA"); - buflen = CFileMgr::LoadFile("PEDSTATS.DAT", (uint8*)buf, 16 * 1024, "r"); - CFileMgr::SetDir(""); + CFileMgr::SetDir("DATA"); + buflen = CFileMgr::LoadFile("PEDSTATS.DAT", (uint8*)buf, 16 * 1024, "r"); + CFileMgr::SetDir(""); for(bp = 0; bp < buflen; ){ // read file line by line diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 101d342e..fd0bf643 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -22,10 +22,14 @@ #include "Script.h" #include "Replay.h" #include "PedPlacement.h" +#include "VarConsole.h" #define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f bool CPlayerPed::bDontAllowWeaponChange; +#ifndef MASTER +bool CPlayerPed::bDebugPlayerInfo; +#endif const uint32 CPlayerPed::nSaveStructSize = #ifdef COMPATIBLE_SAVES @@ -47,7 +51,6 @@ CPlayerPed::~CPlayerPed() delete m_pWanted; } -// --MIAMI: Done CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) { m_fMoveSpeed = 0.0f; @@ -61,7 +64,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_pWanted->Initialise(); m_pArrestingCop = nil; m_currentWeapon = WEAPONTYPE_UNARMED; - m_nSelectedWepSlot = 0; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; m_nSpeedTimer = 0; m_bSpeedTimerFlag = false; SetWeaponLockOnTarget(nil); @@ -96,7 +99,6 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles"); } -// --MIAMI: Done void CPlayerPed::ClearWeaponTarget() { @@ -108,21 +110,18 @@ CPlayerPed::ClearWeaponTarget() ClearPointGunAt(); } -// --MIAMI: Done void CPlayerPed::SetWantedLevel(int32 level) { m_pWanted->SetWantedLevel(level); } -// --MIAMI: Done void CPlayerPed::SetWantedLevelNoDrop(int32 level) { m_pWanted->SetWantedLevelNoDrop(level); } -// --MIAMI: Done void CPlayerPed::MakeObjectTargettable(int32 handle) { @@ -134,7 +133,6 @@ CPlayerPed::MakeObjectTargettable(int32 handle) } } -// --MIAMI: Done // I don't know the actual purpose of parameter void CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) @@ -148,7 +146,6 @@ CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) } } -// --MIAMI: Done void CPlayerPed::ClearAdrenaline(void) { @@ -158,7 +155,6 @@ CPlayerPed::ClearAdrenaline(void) } } -// --MIAMI: Done CPlayerInfo * CPlayerPed::GetPlayerInfoForThisPlayerPed() { @@ -168,7 +164,6 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed() return nil; } -// --MIAMI: Done void CPlayerPed::SetupPlayerPed(int32 index) { @@ -182,23 +177,25 @@ CPlayerPed::SetupPlayerPed(int32 index) CWorld::Add(player); player->m_wepAccuracy = 100; + +#ifndef MASTER + VarConsole.Add("Debug PlayerPed", &CPlayerPed::bDebugPlayerInfo, true); + VarConsole.Add("Tweak Vehicle Handling", &CVehicle::m_bDisplayHandlingInfo, true); +#endif } -// --MIAMI: Done void CPlayerPed::DeactivatePlayerPed(int32 index) { CWorld::Remove(CWorld::Players[index].m_pPed); } -// --MIAMI: Done void CPlayerPed::ReactivatePlayerPed(int32 index) { CWorld::Add(CWorld::Players[index].m_pPed); } -// --MIAMI: Done void CPlayerPed::UseSprintEnergy(void) { @@ -215,7 +212,6 @@ CPlayerPed::UseSprintEnergy(void) } } -// --MIAMI: Done void CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) { @@ -228,7 +224,7 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) GetWeapon()->m_nAmmoInClip = Min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim)) + if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM)) ClearWeaponTarget(); // WEAPONTYPE_SNIPERRIFLE? Wut? @@ -240,7 +236,6 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) TheCamera.ClearPlayerWeaponMode(); } -// --MIAMI: Done void CPlayerPed::MakeChangesForNewWeapon(int32 slot) { @@ -248,7 +243,6 @@ CPlayerPed::MakeChangesForNewWeapon(int32 slot) MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType); } -// --MIAMI: Done void CPlayerPed::ReApplyMoveAnims(void) { @@ -268,7 +262,6 @@ CPlayerPed::ReApplyMoveAnims(void) } } -// --MIAMI: Done void CPlayerPed::SetInitialState(void) { @@ -300,7 +293,7 @@ CPlayerPed::SetInitialState(void) m_nLastPedState = PED_NONE; m_animGroup = ASSOCGRP_PLAYER; m_fMoveSpeed = 0.0f; - m_nSelectedWepSlot = WEAPONTYPE_UNARMED; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; m_nEvadeAmount = 0; m_pEvadingFrom = nil; bIsPedDieAnimPlaying = false; @@ -315,7 +308,6 @@ CPlayerPed::SetInitialState(void) m_attachWepAmmo = 0; } -// --MIAMI: Done void CPlayerPed::SetRealMoveAnim(void) { @@ -341,7 +333,7 @@ CPlayerPed::SetRealMoveAnim(void) if (!curIdleAssoc) curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); if (!curIdleAssoc) - curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE); if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) { @@ -358,7 +350,7 @@ CPlayerPed::SetRealMoveAnim(void) RestoreHeadingRate(); if (!curIdleAssoc) { - if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, + if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f, nil, true, false, false, false, false, false)) { curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f); @@ -372,7 +364,7 @@ CPlayerPed::SetRealMoveAnim(void) } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) { if (!curIdleAssoc) { - if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, + if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f, nil, true, false, false, false, false, false)) { curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f); @@ -388,7 +380,7 @@ CPlayerPed::SetRealMoveAnim(void) } else if (m_nPedState != PED_FIGHT) { if (m_fCurrentStamina < 0.0f && !bIsAimingGun && curIdleAssoc->animId != ANIM_IDLE_TIRED - && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) { + && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f, nil, true, false, false, false, false, false)) { CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f); } else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) { @@ -414,7 +406,7 @@ CPlayerPed::SetRealMoveAnim(void) delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); CAnimBlendAssociation *fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); if (!fightIdleAnim) - fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE); delete fightIdleAnim; delete curSprintAssoc; @@ -477,7 +469,7 @@ CPlayerPed::SetRealMoveAnim(void) curRunAssoc->blendAmount = 0.0f; curRunAssoc->blendDelta = 0.0f; - } else if (curSprintAssoc->blendDelta >= 0.0f) { + } else if (curSprintAssoc->blendDelta >= 0.0f) { // this condition is absent on mobile // Stop sprinting when tired curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; curSprintAssoc->blendDelta = -1.0f; @@ -559,7 +551,6 @@ CPlayerPed::SetRealMoveAnim(void) } } -// --MIAMI: Done void CPlayerPed::RestoreSprintEnergy(float restoreSpeed) { @@ -567,7 +558,6 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed) m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f; } -// --MIAMI: Done float CPlayerPed::DoWeaponSmoothSpray(void) { @@ -617,7 +607,6 @@ CPlayerPed::DoWeaponSmoothSpray(void) return -1.0f; } -// --MIAMI: Done void CPlayerPed::DoStuffToGoOnFire(void) { @@ -625,7 +614,6 @@ CPlayerPed::DoStuffToGoOnFire(void) TheCamera.ClearPlayerWeaponMode(); } -// --MIAMI: Done bool CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) { @@ -637,7 +625,6 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) return false; } -// --MIAMI: Done // Cancels landing anim while running & jumping? I think void CPlayerPed::RunningLand(CPad *padUsed) @@ -656,7 +643,6 @@ CPlayerPed::RunningLand(CPad *padUsed) } } -// --MIAMI: Done bool CPlayerPed::IsThisPedAnAimingPriority(CPed *suspect) { @@ -679,7 +665,6 @@ CPlayerPed::IsThisPedAnAimingPriority(CPed *suspect) return suspect->m_nPedState == PED_ABSEIL; } -// --MIAMI: Done void CPlayerPed::PlayerControlSniper(CPad *padUsed) { @@ -716,7 +701,6 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed) GetWeapon()->Update(m_audioEntityId, nil); } -// --MIAMI: Done // I think R* also used goto in here. void CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) @@ -748,17 +732,20 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) { - for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) { + // I don't know what kind of loop that was + m_nSelectedWepSlot = m_currentWeapon - 1; + do { if (m_nSelectedWepSlot < 0) m_nSelectedWepSlot = TOTAL_WEAPON_SLOTS - 1; - if (m_nSelectedWepSlot == 0) + if (m_nSelectedWepSlot == WEAPONSLOT_UNARMED) break; - if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { + if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) break; - } - } + + --m_nSelectedWepSlot; + } while (m_nSelectedWepSlot != WEAPONSLOT_UNARMED); } } } @@ -772,17 +759,17 @@ spentAmmoCheck: || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER) return; - if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR - || GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE) - m_nSelectedWepSlot = m_currentWeapon - 1; + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR + && GetWeapon(WEAPONSLOT_PROJECTILE).m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) + m_nSelectedWepSlot = WEAPONSLOT_PROJECTILE; else - m_nSelectedWepSlot = 2; + m_nSelectedWepSlot = m_currentWeapon - 1; - for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) { + for (; m_nSelectedWepSlot >= WEAPONSLOT_UNARMED; --m_nSelectedWepSlot) { // BUG: m_nSelectedWepSlot and GetWeapon(..) takes slot in VC but they compared them against weapon types in whole condition! jeez #ifdef FIX_BUGS - if (m_nSelectedWepSlot == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) { + if (m_nSelectedWepSlot == WEAPONSLOT_MELEE || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONSLOT_PROJECTILE) { #else if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 @@ -791,19 +778,19 @@ spentAmmoCheck: goto switchDetectDone; } } - m_nSelectedWepSlot = 0; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; } } switchDetectDone: if (m_nSelectedWepSlot != m_currentWeapon) { - if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) + if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) { RemoveWeaponAnims(m_currentWeapon, -1000.0f); MakeChangesForNewWeapon(m_nSelectedWepSlot); + } } } -// --MIAMI: Done void CPlayerPed::PlayerControlM16(CPad *padUsed) { @@ -840,7 +827,6 @@ CPlayerPed::PlayerControlM16(CPad *padUsed) GetWeapon()->Update(m_audioEntityId, nil); } -// --MIAMI: Done void CPlayerPed::PlayerControlFighter(CPad *padUsed) { @@ -855,7 +841,7 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed) bIsAttacking = false; } - if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) { + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->JumpJustDown()) { if (m_nEvadeAmount != 0 && m_pEvadingFrom) { SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1); m_nEvadeAmount = 0; @@ -866,7 +852,6 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed) } } -// --MIAMI: Done void CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) { @@ -900,13 +885,13 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) return; } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) { m_nMoveState = PEDMOVE_SPRINT; } if (m_nPedState != PED_FIGHT) SetRealMoveAnim(); - if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && + if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY)) && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) { ClearAttack(); @@ -927,7 +912,6 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) #endif } -// --MIAMI: Done void CPlayerPed::KeepAreaAroundPlayerClear(void) { @@ -977,7 +961,6 @@ CPlayerPed::KeepAreaAroundPlayerClear(void) } } -// --MIAMI: Done void CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft, bool priority) { @@ -1004,7 +987,6 @@ CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, } } -// --MIAMI: Done void CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority) { @@ -1034,14 +1016,14 @@ CPlayerPed::CanIKReachThisTarget(CVector target, CWeapon* weapon, bool zRotImpor float angleToFace = CGeneral::GetRadianAngleBetweenPoints(target.x, target.y, GetPosition().x, GetPosition().y); float angleDiff = CGeneral::LimitRadianAngle(angleToFace - m_fRotationCur); - return (!zRotImportant || CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_bCanAimWithArm || Abs(angleDiff) <= HALFPI) && - (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_bCanAimWithArm || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D()); + return (!zRotImportant || CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(angleDiff) <= HALFPI) && + (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D()); } void CPlayerPed::RotatePlayerToTrackTarget(void) { - if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) + if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) return; float angleToFace = CGeneral::GetRadianAngleBetweenPoints( @@ -1059,7 +1041,6 @@ CPlayerPed::RotatePlayerToTrackTarget(void) } } -// --MIAMI: Done bool CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft) { @@ -1102,7 +1083,6 @@ CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft) return true; } -// --MIAMI: Done bool CPlayerPed::FindWeaponLockOnTarget(void) { @@ -1154,11 +1134,11 @@ CPlayerPed::FindWeaponLockOnTarget(void) return true; } -// --MIAMI: Done void CPlayerPed::ProcessAnimGroups(void) { AssocGroupId groupToSet; +#ifdef PC_PLAYER_CONTROLS if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f)) && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && CanStrafeOrMouseControl()) { @@ -1193,7 +1173,9 @@ CPlayerPed::ProcessAnimGroups(void) else groupToSet = ASSOCGRP_PLAYERBACK; } - } else { + } else +#endif + { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) { groupToSet = ASSOCGRP_PLAYERROCKET; } else { @@ -1247,7 +1229,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) bCrouchWhenShooting = false; } - if(weaponInfo->m_bCanAim) + if(weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) m_wepAccuracy = 95; else m_wepAccuracy = 100; @@ -1307,7 +1289,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_bHaveTargetSelected = false; } if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && - !weaponInfo->m_bFightMode) { + !weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE)) { if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE || padUsed->WeaponJustDown()) @@ -1331,35 +1313,38 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) #ifdef FREE_CAM static int8 changedHeadingRate = 0; + static int8 pointedGun = 0; if (changedHeadingRate == 2) changedHeadingRate = 1; + if (pointedGun == 2) pointedGun = 1; // Rotate player/arm when shooting. We don't have auto-rotation anymore if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) { +#define CAN_AIM_WITH_ARM (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) && !bIsDucking && !bCrouchWhenShooting) // Weapons except throwable and melee ones if (weaponInfo->m_nWeaponSlot > 2) { - if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) { + if ((padUsed->GetTarget() && CAN_AIM_WITH_ARM) || padUsed->GetWeapon()) { float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation); // On this one we can rotate arm. - if (weaponInfo->m_bCanAimWithArm) { + if (CAN_AIM_WITH_ARM) { if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately! - SetWeaponLockOnTarget(nil); + SetPointGunAt(nil); bIsPointingGunAt = false; // to not stop after attack } - + pointedGun = 2; SetLookFlag(limitedCam, true); SetAimFlag(limitedCam); SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs. - + } else { m_fRotationDest = limitedCam; changedHeadingRate = 2; m_headingRate = 12.5f; // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly) - if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) { + if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) && padUsed->WeaponJustDown()) { m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur); float limitedRotDest = m_fRotationDest; @@ -1372,17 +1357,21 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2; } } - } else if (weaponInfo->m_bCanAimWithArm && m_nPedState != PED_ATTACK) - ClearPointGunAt(); + } } +#undef CAN_AIM_WITH_ARM } if (changedHeadingRate == 1) { changedHeadingRate = 0; RestoreHeadingRate(); } + if (pointedGun == 1 && m_nPedState != PED_ATTACK) { + pointedGun = 0; + ClearPointGunAt(); + } #endif - if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->m_bCanAim) { + if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) { if (m_pPointGunAt) { // what?? if (!m_pPointGunAt @@ -1405,7 +1394,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) return; } if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) || - (!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) { // this line isn't on Mobile, idk why + (!bCanPointGunAtTarget && !weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))) { // this line isn't on Mobile, idk why ClearWeaponTarget(); return; } @@ -1434,7 +1423,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) if (m_pPointGunAt) { CVector markPos; if (m_pPointGunAt->IsPed()) { - ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&markPos, PED_MID); + ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(markPos, PED_MID); } else { markPos = m_pPointGunAt->GetPosition(); } @@ -1450,10 +1439,9 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) bool CPlayerPed::MovementDisabledBecauseOfTargeting(void) { - return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm; + return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM); } -// --MIAMI: Done void CPlayerPed::PlayerControlZelda(CPad *padUsed) { @@ -1494,8 +1482,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) if (m_nPedState == PED_JUMP) { if (bIsInTheAir) { - if (bUsesCollision && !bHitSteepSlope && - (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) + if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) { float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O @@ -1512,7 +1499,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) return; } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) { if (!m_pCurrentPhysSurface || (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08)) m_nMoveState = PEDMOVE_SPRINT; } @@ -1520,7 +1507,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) if (m_nPedState != PED_FIGHT) SetRealMoveAnim(); - if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) + if (!bIsInTheAir && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) { ClearAttack(); ClearWeaponTarget(); @@ -1632,7 +1619,7 @@ CPlayerPed::ProcessControl(void) if (m_nEvadeAmount == 0) m_pEvadingFrom = nil; - if (m_pWanted->m_nWantedLevel > 0) + if (m_pWanted->GetWantedLevel() > 0) FindNewAttackPoints(); UpdateMeleeAttackers(); @@ -1766,7 +1753,7 @@ CPlayerPed::ProcessControl(void) if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK) && !m_attachedTo) { if (TheCamera.Using1stPersonWeaponMode()) { if (padUsed) - PlayerControlFighter(padUsed); + PlayerControlSniper(padUsed); } else if (TheCamera.Cams[0].Using3rdPersonMouseCam() #ifdef FREE_CAM @@ -1787,46 +1774,6 @@ CPlayerPed::ProcessControl(void) if (IsPedInControl() && m_nPedState != PED_ANSWER_MOBILE && padUsed) ProcessPlayerWeapon(padUsed); break; - case PED_LOOK_ENTITY: - case PED_LOOK_HEADING: - case PED_WANDER_RANGE: - case PED_WANDER_PATH: - case PED_PURSUE: - case PED_FOLLOW_PATH: - case PED_ROCKET_MODE: - case PED_DUMMY: - case PED_PAUSE: - case PED_FACE_PHONE: - case PED_MAKE_CALL: - case PED_CHAT: - case PED_MUG: - case PED_AI_CONTROL: - case PED_FOLLOW_ROUTE: - case PED_CPR: - case PED_SOLICIT: - case PED_BUY_ICECREAM: - case PED_INVESTIGATE: - case PED_STEP_AWAY: - case PED_ON_FIRE: - case PED_SUN_BATHE: - case PED_FLASH: - case PED_JOG: - case PED_UNKNOWN: - case PED_STATES_NO_AI: - case PED_ABSEIL: - case PED_SIT: - case PED_STAGGER: - case PED_DIVE_AWAY: - case PED_STATES_NO_ST: - case PED_ARREST_PLAYER: - case PED_DRIVING: - case PED_PASSENGER: - case PED_TAXI_PASSENGER: - case PED_OPEN_DOOR: - case PED_DIE: - case PED_DEAD: - case PED_HANDS_UP: - break; case PED_SEEK_ENTITY: m_vecSeekPos = m_pSeekTarget->GetPosition(); @@ -1906,6 +1853,8 @@ CPlayerPed::ProcessControl(void) if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim) BeingDraggedFromCar(); break; + default: + break; } if (padUsed && IsPedShootable() && m_nPedState != PED_ANSWER_MOBILE && m_nLastPedState != PED_ANSWER_MOBILE) { ProcessWeaponSwitch(padUsed); @@ -1968,7 +1917,6 @@ CPlayerPed::ProcessControl(void) UpdateRpHAnim(); } -// --MIAMI: Done bool CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty) { @@ -2052,7 +2000,6 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed) } } -// --MIAMI: Done void CPlayerPed::SetNearbyPedsToInteractWithPlayer(void) { @@ -2087,7 +2034,6 @@ CPlayerPed::SetNearbyPedsToInteractWithPlayer(void) } } -// --MIAMI: Done void CPlayerPed::UpdateMeleeAttackers(void) { @@ -2130,7 +2076,6 @@ CPlayerPed::UpdateMeleeAttackers(void) && m_pMeleeList[4] == this && m_pMeleeList[5] == this; } -// --MIAMI: Done void CPlayerPed::RemovePedFromMeleeList(CPed *ped) { @@ -2143,7 +2088,6 @@ CPlayerPed::RemovePedFromMeleeList(CPed *ped) ped->m_attackTimer = 0; } -// --MIAMI: Done void CPlayerPed::GetMeleeAttackCoords(CVector& coords, int8 dir, float dist) { @@ -2176,7 +2120,6 @@ CPlayerPed::GetMeleeAttackCoords(CVector& coords, int8 dir, float dist) } } -// --MIAMI: Done int32 CPlayerPed::FindMeleeAttackPoint(CPed *victim, CVector &dist, uint32 &endOfAttackOut) { diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index e09a67f0..1b7158b5 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -15,7 +15,7 @@ public: float m_fCurrentStamina; float m_fMaxStamina; float m_fStaminaProgress; - int8 m_nSelectedWepSlot; // eWeaponType + int8 m_nSelectedWepSlot; bool m_bSpeedTimerFlag; uint8 m_nEvadeAmount; uint32 m_nSpeedTimer; // m_nStandStillTimer? @@ -46,6 +46,9 @@ public: unsigned int m_nLastBusFareCollected; static bool bDontAllowWeaponChange; +#ifndef MASTER + static bool bDebugPlayerInfo; +#endif CPlayerPed(); ~CPlayerPed(); @@ -108,6 +111,4 @@ public: static const uint32 nSaveStructSize; }; -#ifndef PED_SKIN -VALIDATE_SIZE(CPlayerPed, 0x5F0); -#endif +//VALIDATE_SIZE(CPlayerPed, 0x5F0); diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 7314080b..5603e2c6 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -29,8 +29,6 @@ #include "Clock.h" #include "WaterLevel.h" -// --MIAMI: File done - #define MIN_CREATION_DIST 40.0f // not for start of the game (look at the GeneratePedsAtStartOfGame) #define CREATION_RANGE 10.0f // added over the MIN_CREATION_DIST. #define OFFSCREEN_CREATION_MULT 0.5f @@ -537,7 +535,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree CTheZones::GetZoneInfoForTimeOfDay(&playerCentreOfWorld, &zoneInfo); CWanted *wantedInfo = playerInfo->m_pPed->m_pWanted; - if (wantedInfo->m_nWantedLevel > 2) { + if (wantedInfo->GetWantedLevel() > 2) { if (!CGame::IsInInterior() && (CGeneral::GetRandomNumber() % 32 == 0) && FindPlayerVehicle()) forceAddingCop = true; @@ -558,11 +556,8 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree // Taxi side mission if (CTheScripts::IsPlayerOnAMission()) { CPed *player = FindPlayerPed(); - if (player && player->InVehicle()) { - int32 model = player->m_pMyVehicle->GetModelIndex(); - if (model == MI_TAXI || model == MI_CABBIE || model == MI_ZEBRA || model == MI_KAUFMAN) - missionAndWeatherMult = 1.0f; - } + if (player && player->InVehicle() && player->m_pMyVehicle->IsTaxi()) + missionAndWeatherMult = 1.0f; } if (CDarkel::FrenzyOnGoing()) missionAndWeatherMult = 1.0f; @@ -843,7 +838,7 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver) pedType = PEDTYPE_COP; break; default: - if (car->GetModelIndex() == MI_TAXI || car->GetModelIndex() == MI_CABBIE || car->GetModelIndex() == MI_ZEBRA || car->GetModelIndex() == MI_KAUFMAN) { + if (car->IsTaxi()) { if (isDriver) { pedType = PEDTYPE_CIVMALE; preferredModel = MI_TAXI_D; diff --git a/src/render/Antennas.cpp b/src/render/Antennas.cpp index b9da95cb..452069a0 100644 --- a/src/render/Antennas.cpp +++ b/src/render/Antennas.cpp @@ -2,8 +2,6 @@ #include "Antennas.h" -//--MIAMI: file done - CAntenna CAntennas::aAntennas[NUMANTENNAS]; void diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index 15bae90b..c7554356 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -129,7 +129,7 @@ CClouds::Render(void) CSprite::InitSpriteBuffer(); float minute = CClock::GetHours()*60 + CClock::GetMinutes() + CClock::GetSeconds()/60.0f; - RwV3d campos = *(RwV3d*)&TheCamera.GetPosition(); + RwV3d campos = TheCamera.GetPosition(); // Moon float moonfadeout = Abs(minute - 180.0f); // fully visible at 3AM diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp index c40577d7..e3d3416c 100644 --- a/src/render/Coronas.cpp +++ b/src/render/Coronas.cpp @@ -2,6 +2,7 @@ #include "main.h" #include "General.h" +#include "Entity.h" #include "RenderBuffer.h" #include "TxdStore.h" #include "Camera.h" @@ -12,8 +13,10 @@ #include "Collision.h" #include "Timecycle.h" #include "Coronas.h" - -//--MIAMI: file done +#include "PointLights.h" +#include "Shadows.h" +#include "Clock.h" +#include "Bridge.h" struct FlareDef { @@ -271,7 +274,7 @@ CCoronas::Render(void) CVector spriteCoors; float spritew, spriteh; - if(!CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){ + if(!CSprite::CalcScreenCoors(aCoronas[i].coors, &spriteCoors, &spritew, &spriteh, true)){ aCoronas[i].offScreen = true; aCoronas[i].sightClear = false; }else{ @@ -478,7 +481,7 @@ CCoronas::RenderReflections(void) CVector spriteCoors; float spritew, spriteh; - if(CSprite::CalcScreenCoors(coors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(coors, &spriteCoors, &spritew, &spriteh, true)) { float drawDist = 0.75f * aCoronas[i].drawDist; drawDist = Min(drawDist, 55.0f); if(spriteCoors.z < drawDist){ @@ -669,7 +672,7 @@ CCoronas::DoSunAndMoon(void) CVector spriteCoors; float spritew, spriteh; - if(CSprite::CalcScreenCoors(sunCoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(sunCoors, &spriteCoors, &spritew, &spriteh, true)) { SunScreenX = spriteCoors.x; SunScreenY = spriteCoors.y; }else{ @@ -715,3 +718,234 @@ CRegisteredCorona::Update(void) firstUpdate = false; registeredThisFrame = false; } + +void +CEntity::ProcessLightsForEntity(void) +{ + int i, n; + C2dEffect *effect; + CVector pos; + bool lightOn, lightFlickering; + uint32 flashTimer1, flashTimer2, flashTimer3; + + if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f) + return; + + flashTimer1 = 0; + flashTimer2 = 0; + flashTimer3 = 0; + + n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); + for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){ + effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); + + switch(effect->type){ + case EFFECT_LIGHT: + pos = GetMatrix() * effect->pos; + + lightOn = false; + lightFlickering = false; + switch(effect->light.lightType){ + case LIGHT_ON: + lightOn = true; + break; + case LIGHT_ON_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + lightOn = true; + break; + case LIGHT_FLICKER: + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) + lightOn = true; + break; + case LIGHT_FLICKER_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){ + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) + lightOn = true; + } + break; + case LIGHT_FLASH1: + if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) + lightOn = true; + break; + case LIGHT_FLASH1_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) + lightOn = true; + break; + case LIGHT_FLASH2: + if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) + lightOn = true; + break; + case LIGHT_FLASH2_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) + lightOn = true; + break; + case LIGHT_FLASH3: + if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) + lightOn = true; + break; + case LIGHT_FLASH3_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) + lightOn = true; + break; + case LIGHT_RANDOM_FLICKER: + if(m_randomSeed > 16) + lightOn = true; + else{ + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) + lightOn = true; + } + break; + case LIGHT_RANDOM_FLICKER_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ + if(m_randomSeed > 16) + lightOn = true; + else{ + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) + lightOn = true; + } + } + break; + case LIGHT_BRIDGE_FLASH1: + if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200) + lightOn = true; + break; + case LIGHT_BRIDGE_FLASH2: + if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60) + lightOn = true; + break; + } + + if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){ + if(lightOn) + bDoNotRender = false; + else + bDoNotRender = true; + return; + } + + // Corona + if(lightOn) + CCoronas::RegisterCorona((uintptr)this + i, + effect->col.r, effect->col.g, effect->col.b, 255, + pos, effect->light.size, effect->light.dist, + effect->light.corona, effect->light.flareType, effect->light.roadReflection, + effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, + !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); + else if(lightFlickering) + CCoronas::RegisterCorona((uintptr)this + i, + 0, 0, 0, 255, + pos, effect->light.size, effect->light.dist, + effect->light.corona, effect->light.flareType, effect->light.roadReflection, + effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, + !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); + + // Pointlight + bool alreadyProcessedFog; + alreadyProcessedFog = false; + if(effect->light.range != 0.0f && lightOn){ + if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){ + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), + effect->light.range, + 0.0f, 0.0f, 0.0f, + CPointLights::FOG_NONE, true); + }else{ + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), + effect->light.range, + effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f, + effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f, + effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f, + (effect->light.flags & LIGHTFLAG_FOG) >> 1, + true); + alreadyProcessedFog = true; + } + } + + if(!alreadyProcessedFog){ + if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){ + CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS, + pos, CVector(0.0f, 0.0f, 0.0f), + 0.0f, + effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, + CPointLights::FOG_ALWAYS, true); + }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){ + CPointLights::AddLight(CPointLights::LIGHT_FOGONLY, + pos, CVector(0.0f, 0.0f, 0.0f), + 0.0f, + effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, + CPointLights::FOG_NORMAL, true); + } + } + + // Light shadow + if(effect->light.shadowSize != 0.0f){ + if(lightOn){ + CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, + effect->light.shadow, &pos, + effect->light.shadowSize, 0.0f, + 0.0f, -effect->light.shadowSize, + 128, + effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + 15.0f, 1.0f, 40.0f, false, 0.0f); + }else if(lightFlickering){ + CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, + effect->light.shadow, &pos, + effect->light.shadowSize, 0.0f, + 0.0f, -effect->light.shadowSize, + 0, 0.0f, 0.0f, 0.0f, + 15.0f, 1.0f, 40.0f, false, 0.0f); + } + } + break; + + case EFFECT_SUNGLARE: + if(CWeather::SunGlare >= 0.0f){ + CVector pos = GetMatrix() * effect->pos; + CVector glareDir = pos - GetPosition(); + glareDir.Normalise(); + CVector camDir = TheCamera.GetPosition() - pos; + float dist = camDir.Magnitude(); + camDir *= 2.0f/dist; + glareDir += camDir; + glareDir.Normalise(); + float camAngle = -DotProduct(glareDir, CTimeCycle::GetSunDirection()); + if(camAngle > 0.0f){ + float intens = Sqrt(camAngle) * CWeather::SunGlare; + pos += camDir; + CCoronas::RegisterCorona((uintptr)this + 33 + i, + intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f, + intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f, + intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f, + 255, + pos, 0.5f*CWeather::SunGlare*Sqrt(dist), 120.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, + CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, + CCoronas::STREAK_OFF, 0.0f); + } + } + break; + } + } +}
\ No newline at end of file diff --git a/src/render/Credits.cpp b/src/render/Credits.cpp index f45c0aee..883ad2f2 100644 --- a/src/render/Credits.cpp +++ b/src/render/Credits.cpp @@ -9,8 +9,6 @@ #include "Credits.h" #include "Pad.h" -// --MIAMI: file done - bool CCredits::bCreditsGoing; uint32 CCredits::CreditsStartTime; @@ -803,8 +801,14 @@ CCredits::Render(void) if(TheCamera.m_WideScreenOn) TheCamera.DrawBordersForWideScreen(); +#ifdef FIX_BUGS if(lineoffset + DEFAULT_SCREEN_HEIGHT - scrolloffset < -10.0f) +#else + if(lineoffset + SCREEN_HEIGHT - scrolloffset < -10.0f) +#endif + { bCreditsGoing = false; + } } bool CCredits::AreCreditsDone(void) diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index 912399c9..507653f6 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -20,6 +20,16 @@ uint8 CDraw::FadeRed; uint8 CDraw::FadeGreen; uint8 CDraw::FadeBlue; +#ifdef PROPER_SCALING +bool CDraw::ms_bProperScaling = true; +#endif +#ifdef FIX_RADAR +bool CDraw::ms_bFixRadar = true; +#endif +#ifdef FIX_SPRITES +bool CDraw::ms_bFixSprites = true; +#endif + float CDraw::CalculateAspectRatio(void) { @@ -75,13 +85,9 @@ CDraw::SetFOV(float fov) ms_fFOV = fov; } -#ifdef ASPECT_RATIO_SCALE -float -ScaleAndCenterX(float x) +#ifdef PROPER_SCALING +float CDraw::ScaleY(float y) { - if (SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH) - return x; - else - return (SCREEN_WIDTH - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)) / 2 + SCREEN_SCALE_X(x); + return ms_bProperScaling ? y : y * ((float)DEFAULT_SCREEN_HEIGHT/SCREEN_HEIGHT_NTSC); } -#endif
\ No newline at end of file +#endif
\ No newline at end of file diff --git a/src/render/Draw.h b/src/render/Draw.h index 2976dc34..1a63c980 100644 --- a/src/render/Draw.h +++ b/src/render/Draw.h @@ -30,6 +30,16 @@ public: static uint8 FadeRed; static uint8 FadeGreen; static uint8 FadeBlue; + +#ifdef PROPER_SCALING + static bool ms_bProperScaling; +#endif +#ifdef FIX_RADAR + static bool ms_bFixRadar; +#endif +#ifdef FIX_SPRITES + static bool ms_bFixSprites; +#endif static void SetNearClipZ(float nearclip) { ms_fNearClipZ = nearclip; } static float GetNearClipZ(void) { return ms_fNearClipZ; } @@ -50,4 +60,7 @@ public: #endif static float GetAspectRatio(void) { return ms_fAspectRatio; } static void SetAspectRatio(float ratio) { ms_fAspectRatio = ratio; } +#ifdef PROPER_SCALING + static float ScaleY(float y); +#endif }; diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 3c0d3708..30e271fb 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -744,7 +744,7 @@ void CScrollBar::Render() RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); CVector coronaCoord, screenCoord; - float screenW, screenH; + float screenW, screenH; for (int i = 1; i < ARRAY_SIZE(m_MessageBar); ++i) { for (int j = 0; j < 5; ++j) @@ -756,7 +756,7 @@ void CScrollBar::Render() // Render main coronas if (m_MessageBar[i] & (1 << j)) { - if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true)) + if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true)) { CSprite::RenderBufferedOneXLUSprite( screenCoord.x, screenCoord.y, screenCoord.z, @@ -768,7 +768,7 @@ void CScrollBar::Render() // Render smaller and faded coronas for a trailing effect else if (m_MessageBar[i - 1] & (1 << j)) { - if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true)) + if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true)) { CSprite::RenderBufferedOneXLUSprite( screenCoord.x, screenCoord.y, screenCoord.z, @@ -935,7 +935,7 @@ CEscalator::AddThisOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, b m_lowerEnd = magnitudes[0] / length; m_upperEnd = (magnitudes[0] + magnitudes[1]) / length; - m_stepsCount = Max(24.0f, length / 0.6f); + m_stepsCount = Min(24.0f, length / 0.6f); CVector direction(m_pos0.x - m_pos1.x, m_pos0.y - m_pos1.y, 0.0f); direction.Normalise(); @@ -1291,7 +1291,7 @@ INITSAVEBUF for (int32 j = 0; j < 6; j++) { if (pPath->m_pObjects[j] != nil) - pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pPath->m_pObjects[j]) + 1); + pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1); } for (int32 j = 0; j < aArray[i].m_numNodes; j++) { diff --git a/src/render/Font.cpp b/src/render/Font.cpp index 5a6ff94f..de1ee8b4 100644 --- a/src/render/Font.cpp +++ b/src/render/Font.cpp @@ -3,6 +3,9 @@ #include "Sprite2d.h" #include "TxdStore.h" #include "Font.h" +#ifdef BUTTON_ICONS +#include "FileMgr.h" +#endif #include "Timer.h" void @@ -224,6 +227,12 @@ union tFontRenderStatePointer tFontRenderStatePointer FontRenderStatePointer; uint8 FontRenderStateBuf[1024]; +#ifdef BUTTON_ICONS +CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS]; +int CFont::PS2Symbol = BUTTON_NONE; +int CFont::ButtonsSlot = -1; +#endif // BUTTON_ICONS + void CFont::Initialise(void) { @@ -265,13 +274,13 @@ CFont::Initialise(void) SetScale(1.0f, 1.0f); SetSlantRefPoint(SCREEN_WIDTH, 0.0f); SetSlant(0.0f); - SetColor(CRGBA(0xFF, 0xFF, 0xFF, 0)); + SetColor(CRGBA(255, 255, 255, 0)); SetJustifyOff(); SetCentreOff(); SetWrapx(SCREEN_WIDTH); SetCentreSize(SCREEN_WIDTH); SetBackgroundOff(); - SetBackgroundColor(CRGBA(0x80, 0x80, 0x80, 0x80)); + SetBackgroundColor(CRGBA(128, 128, 128, 128)); SetBackGroundOnlyTextOff(); SetPropOn(); SetFontStyle(FONT_BANK); @@ -279,6 +288,34 @@ CFont::Initialise(void) SetAlphaFade(255.0f); SetDropShadowPosition(0); CTxdStore::PopCurrentTxd(); + +#ifdef BUTTON_ICONS + if (int file = CFileMgr::OpenFile("MODELS/X360BTNS.TXD")) { + CFileMgr::CloseFile(file); + ButtonsSlot = CTxdStore::AddTxdSlot("buttons"); + CTxdStore::LoadTxd(ButtonsSlot, "MODELS/X360BTNS.TXD"); + CTxdStore::AddRef(ButtonsSlot); + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(ButtonsSlot); + ButtonSprite[BUTTON_UP].SetTexture("thumblyu"); + ButtonSprite[BUTTON_DOWN].SetTexture("thumblyd"); + ButtonSprite[BUTTON_LEFT].SetTexture("thumblxl"); + ButtonSprite[BUTTON_RIGHT].SetTexture("thumblxr"); + ButtonSprite[BUTTON_CROSS].SetTexture("cross"); + ButtonSprite[BUTTON_CIRCLE].SetTexture("circle"); + ButtonSprite[BUTTON_SQUARE].SetTexture("square"); + ButtonSprite[BUTTON_TRIANGLE].SetTexture("triangle"); + ButtonSprite[BUTTON_L1].SetTexture("l1"); + ButtonSprite[BUTTON_L2].SetTexture("l2"); + ButtonSprite[BUTTON_L3].SetTexture("l3"); + ButtonSprite[BUTTON_R1].SetTexture("r1"); + ButtonSprite[BUTTON_R2].SetTexture("r2"); + ButtonSprite[BUTTON_R3].SetTexture("r3"); + ButtonSprite[BUTTON_RSTICK_LEFT].SetTexture("thumbrxl"); + ButtonSprite[BUTTON_RSTICK_RIGHT].SetTexture("thumbrxr"); + CTxdStore::PopCurrentTxd(); + } +#endif // BUTTON_ICONS } #ifdef MORE_LANGUAGES @@ -327,6 +364,13 @@ CFont::ReloadFonts(uint8 set) void CFont::Shutdown(void) { +#ifdef BUTTON_ICONS + if (ButtonsSlot != -1) { + for (int i = 0; i < MAX_BUTTON_ICONS; i++) + ButtonSprite[i].Delete(); + CTxdStore::RemoveTxdSlot(ButtonsSlot); + } +#endif Sprite[0].Delete(); Sprite[1].Delete(); #ifdef MORE_LANGUAGES @@ -346,9 +390,38 @@ CFont::InitPerFrame(void) Details.anonymous_25 = 0; FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf; SetDropShadowPosition(0); - NewLine = 0; + NewLine = false; +#ifdef BUTTON_ICONS + PS2Symbol = BUTTON_NONE; +#endif } +#ifdef BUTTON_ICONS +void +CFont::DrawButton(float x, float y) +{ + if (x <= 0.0f || x > SCREEN_WIDTH || y <= 0.0f || y > SCREEN_HEIGHT) + return; + + if (PS2Symbol != BUTTON_NONE) { + CRect rect; + rect.left = x; + rect.top = Details.scaleY + Details.scaleY + y; + rect.right = Details.scaleY * 17.0f + x; + rect.bottom = Details.scaleY * 19.0f + y; + + int vertexAlphaState; + void *raster; + RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vertexAlphaState); + RwRenderStateGet(rwRENDERSTATETEXTURERASTER, &raster); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); + ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, Details.color.a)); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState); + } +} +#endif + void CFont::PrintChar(float x, float y, wchar c) { @@ -371,10 +444,14 @@ CFont::PrintChar(float x, float y, wchar c) } #endif - if(Details.style == FONT_BANK || Details.style == FONT_STANDARD){ + if(RenderState.style == FONT_BANK || RenderState.style == FONT_STANDARD){ if (bDontPrint) return; if (RenderState.slant == 0.0f) { +#ifdef FIX_BUGS + if (c < 192) { +#else if (c < 193) { +#endif CSprite2d::AddToBuffer( CRect(x, y, x + 32.0f * RenderState.scaleX * 1.0f, @@ -390,9 +467,9 @@ CFont::PrintChar(float x, float y, wchar c) x + 32.0f * RenderState.scaleX * 1.0f, y + 33.0f * RenderState.scaleY * 0.5f), RenderState.color, - xoff / 16.0f, yoff / 12.8f, - (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f - 0.017f, - xoff / 16.0f, (yoff + 1.0f) / 12.8f, + xoff / 16.0f, yoff / 12.8f + 0.0021f, + (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f, + xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.017f, (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.017f); } } else @@ -466,6 +543,210 @@ bool CFont::IsAnsiCharacter(wchar *s) #endif void +CFont::RenderFontBuffer() +{ + if (FontRenderStatePointer.pRenderState == (CFontRenderState*)FontRenderStateBuf) return; + + float textPosX; + float textPosY; + CRGBA color; + bool bBold = false; + bool bFlash = false; + + Sprite[RenderState.style].SetRenderState(); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RenderState = *(CFontRenderState*)&FontRenderStateBuf[0]; + textPosX = RenderState.fTextPosX; + textPosY = RenderState.fTextPosY; + color = RenderState.color; + tFontRenderStatePointer pRenderStateBufPointer; + pRenderStateBufPointer.pRenderState = (CFontRenderState*)&FontRenderStateBuf[0]; + for (++pRenderStateBufPointer.pRenderState; pRenderStateBufPointer.pStr < FontRenderStatePointer.pStr; pRenderStateBufPointer.pStr++) { + if (*pRenderStateBufPointer.pStr == '\0') { + tFontRenderStatePointer tmpPointer = pRenderStateBufPointer; + tmpPointer.pStr++; + tmpPointer.Align(); + if (tmpPointer.pStr >= FontRenderStatePointer.pStr) + break; + + RenderState = *(tmpPointer.pRenderState++); + + pRenderStateBufPointer = tmpPointer; + + textPosX = RenderState.fTextPosX; + textPosY = RenderState.fTextPosY; + color = RenderState.color; + } + if (*pRenderStateBufPointer.pStr == '~') { +#ifdef BUTTON_ICONS + PS2Symbol = BUTTON_NONE; +#endif + pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold); +#ifdef BUTTON_ICONS + if(PS2Symbol != BUTTON_NONE) { + DrawButton(textPosX, textPosY); + textPosX += Details.scaleY * 17.0f; + PS2Symbol = BUTTON_NONE; + } +#endif + if (bFlash) { + if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) { + Details.bFlashState = !Details.bFlashState; + Details.nFlashTimer = CTimer::GetTimeInMilliseconds(); + } + Details.color.alpha = Details.bFlashState ? 0 : 255; + } + if (!RenderState.bIsShadow) + RenderState.color = color; + } + wchar c = *pRenderStateBufPointer.pStr; + c -= ' '; + if (RenderState.bFontHalfTexture) + c = FindNewCharacter(c); + else if (c > 155) + c = '\0'; + + if (RenderState.slant != 0.0f) + textPosY = (RenderState.slantRefX - textPosX) * RenderState.slant + RenderState.slantRefY; + PrintChar(textPosX, textPosY, c); + if (bBold) { + PrintChar(textPosX + 1.0f, textPosY, c); + PrintChar(textPosX + 2.0f, textPosY, c); + textPosX += 2.0f; + } +#ifdef FIX_BUGS + // PS2 uses different chars for some symbols + if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star +#endif + textPosX += RenderState.scaleX * GetCharacterWidth(c); + if (c == '\0') + textPosX += RenderState.fExtraSpace; + } + CSprite2d::RenderVertexBuffer(); + FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf; +} + +#ifdef MORE_LANGUAGES +bool +CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX) +{ + wchar *s, c, unused; + + if (IsJapanese()) { + float jx = 0.0f; + for (s = start; s < end; s++) { + if (*s == JAP_TERMINATION || *s == '~') + s = ParseToken(s, &unused, true); + if (NewLine) { + NewLine = false; + break; + } + jx += GetCharacterSize(*s - ' '); + } + s = start; + if (Details.centre) + x = japX - jx / 2.0f; + else if (Details.rightJustify) + x = japX - jx; + } + + for (s = start; s < end; s++) { + if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION)) + s = ParseToken(s, &unused); + if (NewLine && IsJapanese()) { + NewLine = false; + end = s; + return true; + } + c = *s - ' '; + if (Details.slant != 0.0f && !IsJapanese()) + y = (Details.slantRefX - x) * Details.slant + Details.slantRefY; + + PrintChar(x, y, c); + x += GetCharacterSize(c); + if (c == 0 && (!NewLine || !IsJapanese())) // space + x += spwidth; + } + return false; +} +#else +void +CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth) +{ + wchar *s; + + if (RenderState.style != Details.style) { + RenderFontBuffer(); + RenderState.style = Details.style; + } + + float dropShadowPosition = Details.dropShadowPosition; + if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) { + CRGBA color = Details.color; + Details.color = Details.dropColor; + Details.dropShadowPosition = 0; + Details.bIsShadow = true; + if (Details.slant != 0.0f) { + Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition); + Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition); + PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); + Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition); + Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition); + } else { + PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); + } + Details.color = color; + Details.dropShadowPosition = dropShadowPosition; + Details.bIsShadow = false; + } + if (FontRenderStatePointer.pStr >= (wchar*)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - (end - start + 26)) // why 26? + RenderFontBuffer(); + CFontRenderState *pRenderState = FontRenderStatePointer.pRenderState; + pRenderState->fTextPosX = x; + pRenderState->fTextPosY = y; + pRenderState->scaleX = Details.scaleX; + pRenderState->scaleY = Details.scaleY; + pRenderState->color = Details.color; + pRenderState->fExtraSpace = spwidth; + pRenderState->slant = Details.slant; + pRenderState->slantRefX = Details.slantRefX; + pRenderState->slantRefY = Details.slantRefY; + pRenderState->bFontHalfTexture = Details.bFontHalfTexture; + pRenderState->proportional = Details.proportional; + pRenderState->style = Details.style; + pRenderState->bIsShadow = Details.bIsShadow; + FontRenderStatePointer.pRenderState++; + + for(s = start; s < end;){ + if (*s == '~') { + for (wchar *i = ParseToken(s); s != i; FontRenderStatePointer.pStr++) { + *FontRenderStatePointer.pStr = *(s++); + } + if (Details.bFlash) { + if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) { + Details.bFlashState = !Details.bFlashState; + Details.nFlashTimer = CTimer::GetTimeInMilliseconds(); + } + Details.color.a = Details.bFlashState ? 0 : 255; + } + } else + *(FontRenderStatePointer.pStr++) = *(s++); + } + *(FontRenderStatePointer.pStr++) = '\0'; + FontRenderStatePointer.Align(); +} +#endif + +void +CFont::PrintStringFromBottom(float x, float y, wchar *str) +{ + y -= (32.0f * Details.scaleY / 2.0f + 2.0f * Details.scaleY) * GetNumberLines(x, y, str); + if (Details.slant != 0.0f) + y -= ((Details.slantRefX - x) * Details.slant + Details.slantRefY); + PrintString(x, y, str); +} + +void CFont::PrintString(float xstart, float ystart, wchar *s) { CRect rect; @@ -537,10 +818,10 @@ CFont::PrintString(float xstart, float ystart, wchar *s) x = xstart; #ifdef MORE_LANGUAGES if (IsJapaneseFont()) - y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY; else #endif - y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY; start = s; }else break; @@ -576,7 +857,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) else x = 0.0f; - y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY; numSpaces = 0; first = true; lineLength = 0.0f; @@ -599,7 +880,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) x = xstart; else x = 0.0f; - y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY; numSpaces = 0; first = true; lineLength = 0.0f; @@ -676,10 +957,10 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s) // Why even? #ifdef MORE_LANGUAGES if (IsJapanese()) - y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY; else #endif - y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY; }else{ // still space in current line t = GetNextSpace(s); @@ -750,7 +1031,7 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) else x = xstart; numLines++; - y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY; + y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY; }else{ // still space in current line t = GetNextSpace(s); @@ -778,11 +1059,11 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) rect->right = xstart + maxlength/2 + 4.0f; #ifdef MORE_LANGUAGES if (IsJapaneseFont()) { - rect->bottom = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + (4.0f / 2.75f); + rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f); rect->top = ystart - (4.0f / 2.75f); } else { #endif - rect->bottom = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f; + rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f; rect->top = ystart - 2.0f; #ifdef MORE_LANGUAGES } @@ -792,11 +1073,11 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) rect->right = xstart + Details.centreSize*0.5f + 4.0f; #ifdef MORE_LANGUAGES if (IsJapaneseFont()) { - rect->bottom = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + (4.0f / 2.75f); + rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f); rect->top = ystart - (4.0f / 2.75f); } else { #endif - rect->bottom = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f; + rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f; rect->top = ystart - 2.0f; #ifdef MORE_LANGUAGES } @@ -809,130 +1090,11 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) rect->bottom = ystart - 4.0f + 4.0f; #ifdef MORE_LANGUAGES if (IsJapaneseFont()) - rect->top = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f + (4.0f / 2.75f); + rect->top = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + (4.0f / 2.75f); else #endif - rect->top = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f + 2.0f; - } -} - -#ifdef MORE_LANGUAGES -bool -CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX) -{ - wchar *s, c, unused; - - if (IsJapanese()) { - float jx = 0.0f; - for (s = start; s < end; s++) { - if (*s == JAP_TERMINATION || *s == '~') - s = ParseToken(s, &unused, true); - if (NewLine) { - NewLine = false; - break; - } - jx += GetCharacterSize(*s - ' '); - } - s = start; - if (Details.centre) - x = japX - jx / 2.0f; - else if (Details.rightJustify) - x = japX - jx; - } - - for (s = start; s < end; s++) { - if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION)) - s = ParseToken(s, &unused); - if (NewLine && IsJapanese()) { - NewLine = false; - end = s; - return true; - } - c = *s - ' '; - if (Details.slant != 0.0f && !IsJapanese()) - y = (Details.slantRefX - x) * Details.slant + Details.slantRefY; - PrintChar(x, y, c); - x += GetCharacterSize(c); - if (c == 0 && (!NewLine || !IsJapanese())) // space - x += spwidth; - } - return false; -} -#else -void -CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth) -{ - wchar *s; - - if (RenderState.style != Details.style) { - RenderFontBuffer(); - RenderState.style = Details.style; - } - - float dropShadowPosition = Details.dropShadowPosition; - if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) { - CRGBA color = Details.color; - Details.color = Details.dropColor; - Details.dropShadowPosition = 0; - Details.bIsShadow = true; - if (Details.slant != 0.0f) { - Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition); - Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition); - PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); - Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition); - Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition); - } else { - PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); - } - Details.color = color; - Details.dropShadowPosition = dropShadowPosition; - Details.bIsShadow = false; - } - if (FontRenderStatePointer.pStr >= (wchar*)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - (end - start + 26)) // why 26? - RenderFontBuffer(); - CFontRenderState *pRenderState = FontRenderStatePointer.pRenderState; - pRenderState->fTextPosX = x; - pRenderState->fTextPosY = y; - pRenderState->scaleX = Details.scaleX; - pRenderState->scaleY = Details.scaleY; - pRenderState->color = Details.color; - pRenderState->fExtraSpace = spwidth; - pRenderState->slant = Details.slant; - pRenderState->slantRefX = Details.slantRefX; - pRenderState->slantRefY = Details.slantRefY; - pRenderState->bFontHalfTexture = Details.bFontHalfTexture; - pRenderState->proportional = Details.proportional; - pRenderState->style = Details.style; - pRenderState->bIsShadow = Details.bIsShadow; - FontRenderStatePointer.pRenderState++; - - for(s = start; s < end;){ - if (*s == '~') { - for (wchar *i = ParseToken(s); s != i; FontRenderStatePointer.pStr++) { - *FontRenderStatePointer.pStr = *(s++); - } - if (Details.bFlash) { - if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) { - Details.bFlashState = !Details.bFlashState; - Details.nFlashTimer = CTimer::GetTimeInMilliseconds(); - } - Details.color.a = Details.bFlashState ? 0 : 255; - } - } else - *(FontRenderStatePointer.pStr++) = *(s++); + rect->top = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + 2.0f; } - *(FontRenderStatePointer.pStr++) = '\0'; - FontRenderStatePointer.Align(); -} -#endif - -void -CFont::PrintStringFromBottom(float x, float y, wchar *str) -{ - y -= (32.0f * Details.scaleY / 2.0f + 2.0f * Details.scaleY) * GetNumberLines(x, y, str); - if (Details.slant == 0.0f) - y -= ((Details.slantRefX - x) * Details.slant + Details.slantRefY); - PrintString(x, y, str); } float @@ -972,10 +1134,11 @@ CFont::GetCharacterWidth(wchar c) else return Size[LanguageSet][Details.style][192]; #else - if (Details.proportional) - return Size[Details.style][c]; + + if (RenderState.proportional) + return Size[RenderState.style][c]; else - return Size[Details.style][209]; + return Size[RenderState.style][209]; #endif // MORE_LANGUAGES } @@ -1017,6 +1180,11 @@ CFont::GetCharacterSize(wchar c) else return Size[LanguageSet][Details.style][209] * Details.scaleX; #else + +#ifdef FIX_BUGS + // PS2 don't call FindNewCharacter in here at all, and also uses different chars for some symbols + if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star +#endif if (Details.bFontHalfTexture) c = FindNewCharacter(c); if (Details.proportional) @@ -1041,6 +1209,30 @@ CFont::GetStringWidth(wchar *s, bool spaces) do { while (*s == '~' || *s == JAP_TERMINATION) { s++; +#ifdef BUTTON_ICONS + switch (*s) { + case 'U': + case 'D': + case '<': + case '>': + case 'X': + case 'O': + case 'Q': + case 'T': + case 'K': + case 'M': + case 'A': + case 'J': + case 'V': + case 'C': + case '(': + case ')': + w += 17.0f * Details.scaleY; + break; + default: + break; + } +#endif while (!(*s == '~' || *s == JAP_TERMINATION)) s++; s++; } @@ -1055,6 +1247,30 @@ CFont::GetStringWidth(wchar *s, bool spaces) for (wchar c = *s; (c != ' ' || spaces) && c != '\0'; c = *(++s)) { if (c == '~') { s++; +#ifdef BUTTON_ICONS + switch (*s) { + case 'U': + case 'D': + case '<': + case '>': + case 'X': + case 'O': + case 'Q': + case 'T': + case 'K': + case 'M': + case 'A': + case 'J': + case 'V': + case 'C': + case '(': + case ')': + w += 17.0f * Details.scaleY; + break; + default: + break; + } +#endif while (*s != '~') { s++; } @@ -1120,80 +1336,6 @@ CFont::GetNextSpace(wchar *s) return s; } -#ifdef MORE_LANGUAGES -wchar* -CFont::ParseToken(wchar *s, bool japShit) -{ - s++; - if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) { - wchar c = *s; - if (IsJapanese()) - c &= 0x7FFF; - switch (c) { - case 'N': - case 'n': - NewLine = true; - break; - case 'b': SetColor(CRGBA(128, 167, 243, 255)); break; - case 'g': SetColor(CRGBA(95, 160, 106, 255)); break; - case 'h': SetColor(CRGBA(225, 225, 225, 255)); break; - case 'l': SetColor(CRGBA(0, 0, 0, 255)); break; - case 'p': SetColor(CRGBA(168, 110, 252, 255)); break; - case 'r': SetColor(CRGBA(113, 43, 73, 255)); break; - case 'w': SetColor(CRGBA(175, 175, 175, 255)); break; - case 'y': SetColor(CRGBA(210, 196, 106, 255)); break; - } - } else if (IsJapanese()) { - if ((*s & 0x7FFF) == 'N' || (*s & 0x7FFF) == 'n') - NewLine = true; - } - while ((!IsJapanese() || (*s != JAP_TERMINATION)) && *s != '~') s++; - return s + 1; -} -#else -wchar* -CFont::ParseToken(wchar *s) -{ - Details.anonymous_23 = false; - s++; - if(Details.color.r || Details.color.g || Details.color.b) - switch(*s){ - case 'B': - Details.bBold = !Details.bBold; - break; - case 'N': - case 'n': - NewLine = 1; - break; - case 'b': SetColor(CRGBA(27, 89, 130, 255)); Details.anonymous_23 = true; break; - case 'f': - Details.bFlash = !Details.bFlash; - if (!Details.bFlash) - Details.color.a = 255; - break; - case 'g': SetColor(CRGBA(255, 150, 225, 255)); Details.anonymous_23 = true; break; - case 'h': SetColor(CRGBA(225, 225, 225, 255)); Details.anonymous_23 = true; break; - case 'l': SetColor(CRGBA(0, 0, 0, 255)); Details.anonymous_23 = true; break; - case 'o': SetColor(CRGBA(229, 125, 126, 255)); Details.anonymous_23 = true; break; - case 'p': SetColor(CRGBA(168, 110, 252, 255)); Details.anonymous_23 = true; break; - case 'q': SetColor(CRGBA(199, 144, 203, 255)); Details.anonymous_23 = true; break; - case 'r': SetColor(CRGBA(255, 150, 225, 255)); Details.anonymous_23 = true; break; - case 't': SetColor(CRGBA(86, 212, 146, 255)); Details.anonymous_23 = true; break; - case 'w': SetColor(CRGBA(175, 175, 175, 255)); Details.anonymous_23 = true; break; -#ifdef FIX_BUGS - case 'x': SetColor(CRGBA(0, 255, 255, 255)); Details.anonymous_23 = true; break; -#else - case 'x': SetColor(CRGBA(132, 146, 197, 255)); Details.anonymous_23 = true; break; -#endif - case 'y': SetColor(CRGBA(255, 227, 79, 255)); Details.anonymous_23 = true; break; - } - while(*s != '~') s++; - if (*(++s) == '~') - s = ParseToken(s); - return s; -} -#endif - wchar* CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) { @@ -1277,6 +1419,24 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) color.g = 227; color.b = 79; break; +#ifdef BUTTON_ICONS + case 'U': PS2Symbol = BUTTON_UP; break; + case 'D': PS2Symbol = BUTTON_DOWN; break; + case '<': PS2Symbol = BUTTON_LEFT; break; + case '>': PS2Symbol = BUTTON_RIGHT; break; + case 'X': PS2Symbol = BUTTON_CROSS; break; + case 'O': PS2Symbol = BUTTON_CIRCLE; break; + case 'Q': PS2Symbol = BUTTON_SQUARE; break; + case 'T': PS2Symbol = BUTTON_TRIANGLE; break; + case 'K': PS2Symbol = BUTTON_L1; break; + case 'M': PS2Symbol = BUTTON_L2; break; + case 'A': PS2Symbol = BUTTON_L3; break; + case 'J': PS2Symbol = BUTTON_R1; break; + case 'V': PS2Symbol = BUTTON_R2; break; + case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; +#endif default: break; } @@ -1288,6 +1448,196 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) return s; } +#ifdef MORE_LANGUAGES +wchar* +CFont::ParseToken(wchar *s, bool japShit) +{ + s++; + if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) { + wchar c = *s; + if (IsJapanese()) + c &= 0x7FFF; + switch (c) { + case 'N': + case 'n': + NewLine = true; + break; + case 'b': SetColor(CRGBA(128, 167, 243, 255)); break; + case 'g': SetColor(CRGBA(95, 160, 106, 255)); break; + case 'h': SetColor(CRGBA(225, 225, 225, 255)); break; + case 'l': SetColor(CRGBA(0, 0, 0, 255)); break; + case 'p': SetColor(CRGBA(168, 110, 252, 255)); break; + case 'r': SetColor(CRGBA(113, 43, 73, 255)); break; + case 'w': SetColor(CRGBA(175, 175, 175, 255)); break; + case 'y': SetColor(CRGBA(210, 196, 106, 255)); break; +#ifdef BUTTON_ICONS + case 'U': PS2Symbol = BUTTON_UP; break; + case 'D': PS2Symbol = BUTTON_DOWN; break; + case '<': PS2Symbol = BUTTON_LEFT; break; + case '>': PS2Symbol = BUTTON_RIGHT; break; + case 'X': PS2Symbol = BUTTON_CROSS; break; + case 'O': PS2Symbol = BUTTON_CIRCLE; break; + case 'Q': PS2Symbol = BUTTON_SQUARE; break; + case 'T': PS2Symbol = BUTTON_TRIANGLE; break; + case 'K': PS2Symbol = BUTTON_L1; break; + case 'M': PS2Symbol = BUTTON_L2; break; + case 'A': PS2Symbol = BUTTON_L3; break; + case 'J': PS2Symbol = BUTTON_R1; break; + case 'V': PS2Symbol = BUTTON_R2; break; + case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; +#endif + } + } else if (IsJapanese()) { + if ((*s & 0x7FFF) == 'N' || (*s & 0x7FFF) == 'n') + NewLine = true; + } + while ((!IsJapanese() || (*s != JAP_TERMINATION)) && *s != '~') s++; + return s + 1; +} +#else +wchar* +CFont::ParseToken(wchar *s) +{ + Details.anonymous_23 = false; + s++; + if(Details.color.r || Details.color.g || Details.color.b) + switch(*s){ + case 'B': + Details.bBold = !Details.bBold; + break; + case 'N': + case 'n': + NewLine = true; + break; + case 'b': + Details.color.r = 27; + Details.color.g = 89; + Details.color.b = 130; + Details.anonymous_23 = true; + break; + case 'f': + Details.bFlash = !Details.bFlash; + if (!Details.bFlash) + Details.color.a = 255; + break; + case 'g': + Details.color.r = 255; + Details.color.g = 150; + Details.color.b = 225; + Details.anonymous_23 = true; + break; + case 'h': + Details.color.r = 225; + Details.color.g = 225; + Details.color.b = 225; + Details.anonymous_23 = true; + break; + case 'l': + Details.color.r = 0; + Details.color.g = 0; + Details.color.b = 0; + Details.anonymous_23 = true; + break; + case 'o': + Details.color.r = 229; + Details.color.g = 125; + Details.color.b = 126; + Details.anonymous_23 = true; + break; + case 'p': + Details.color.r = 168; + Details.color.g = 110; + Details.color.b = 252; + Details.anonymous_23 = true; + break; + case 'q': + Details.color.r = 199; + Details.color.g = 144; + Details.color.b = 203; + Details.anonymous_23 = true; + break; + case 'r': + Details.color.r = 255; + Details.color.g = 150; + Details.color.b = 225; + Details.anonymous_23 = true; + break; + case 't': + Details.color.r = 86; + Details.color.g = 212; + Details.color.b = 146; + Details.anonymous_23 = true; + break; + case 'w': + Details.color.r = 175; + Details.color.g = 175; + Details.color.b = 175; + Details.anonymous_23 = true; + break; + case 'x': +#ifdef FIX_BUGS + Details.color.r = 0; + Details.color.g = 255; + Details.color.b = 255; +#else + Details.color.r = 132; + Details.color.g = 146; + Details.color.b = 197; +#endif + Details.anonymous_23 = true; + break; + case 'y': + Details.color.r = 255; + Details.color.g = 227; + Details.color.b = 79; + Details.anonymous_23 = true; + break; +#ifdef BUTTON_ICONS + case 'U': PS2Symbol = BUTTON_UP; break; + case 'D': PS2Symbol = BUTTON_DOWN; break; + case '<': PS2Symbol = BUTTON_LEFT; break; + case '>': PS2Symbol = BUTTON_RIGHT; break; + case 'X': PS2Symbol = BUTTON_CROSS; break; + case 'O': PS2Symbol = BUTTON_CIRCLE; break; + case 'Q': PS2Symbol = BUTTON_SQUARE; break; + case 'T': PS2Symbol = BUTTON_TRIANGLE; break; + case 'K': PS2Symbol = BUTTON_L1; break; + case 'M': PS2Symbol = BUTTON_L2; break; + case 'A': PS2Symbol = BUTTON_L3; break; + case 'J': PS2Symbol = BUTTON_R1; break; + case 'V': PS2Symbol = BUTTON_R2; break; + case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; +#endif + } + while(*s != '~') s++; + if (*(++s) == '~') + s = ParseToken(s); + return s; +} +#endif + +void +CFont::FilterOutTokensFromString(wchar *str) +{ + int newIdx = 0; + wchar copy[256], *c; + UnicodeStrcpy(copy, str); + + for (c = copy; *c != '\0'; c++) { + if (*c == '~') { + c++; + while (*c != '~') c++; + } else { + str[newIdx++] = *c; + } + } + str[newIdx] = '\0'; +} + void CFont::DrawFonts(void) { @@ -1295,125 +1645,90 @@ CFont::DrawFonts(void) } void -CFont::RenderFontBuffer() +CFont::SetScale(float x, float y) { - if (FontRenderStatePointer.pRenderState == (CFontRenderState*)FontRenderStateBuf) return; - - float textPosX; - float textPosY; - CRGBA color; - bool bBold = false; - bool bFlash = false; +#ifdef MORE_LANGUAGES + /*if (IsJapanese()) { + x *= 1.35f; + y *= 1.25f; + }*/ +#endif + Details.scaleX = x; + Details.scaleY = y; +} - Sprite[RenderState.style].SetRenderState(); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RenderState = *(CFontRenderState*)&FontRenderStateBuf[0]; - textPosX = RenderState.fTextPosX; - textPosY = RenderState.fTextPosY; - color = RenderState.color; - tFontRenderStatePointer pRenderStateBufPointer; - pRenderStateBufPointer.pRenderState = (CFontRenderState*)&FontRenderStateBuf[0]; - for (++pRenderStateBufPointer.pRenderState; pRenderStateBufPointer.pStr < FontRenderStatePointer.pStr; pRenderStateBufPointer.pStr++) { - if (*pRenderStateBufPointer.pStr == '\0') { - tFontRenderStatePointer tmpPointer = pRenderStateBufPointer; - tmpPointer.pStr++; - tmpPointer.Align(); - if (tmpPointer.pStr >= FontRenderStatePointer.pStr) - break; +void +CFont::SetSlantRefPoint(float x, float y) +{ + Details.slantRefX = x; + Details.slantRefY = y; +} - RenderState = *(tmpPointer.pRenderState++); +void +CFont::SetSlant(float s) +{ + Details.slant = s; +} - pRenderStateBufPointer = tmpPointer; +void +CFont::SetColor(CRGBA col) +{ + Details.color = col; + if (Details.alphaFade < 255.0f) + Details.color.a *= Details.alphaFade / 255.0f; +} - textPosX = RenderState.fTextPosX; - textPosY = RenderState.fTextPosY; - color = RenderState.color; - } - if (*pRenderStateBufPointer.pStr == '~') { - pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold); - if (bFlash) { - if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) { - Details.bFlashState = !Details.bFlashState; - Details.nFlashTimer = CTimer::GetTimeInMilliseconds(); - } - Details.color.alpha = Details.bFlashState ? 0 : 255; - } - if (!RenderState.bIsShadow) - RenderState.color = color; - } - wchar c = *pRenderStateBufPointer.pStr; - c -= ' '; - if (RenderState.bFontHalfTexture) - c = FindNewCharacter(c); - else if (c > 155) - c = 0; +void +CFont::SetJustifyOn(void) +{ + Details.justify = true; + Details.centre = false; + Details.rightJustify = false; +} - if (RenderState.slant != 0.0f) - textPosY = (RenderState.slantRefX - textPosX) * RenderState.slant + RenderState.slantRefY; - PrintChar(textPosX, textPosY, c); - if (bBold) { - PrintChar(textPosX + 1.0f, textPosY, c); - PrintChar(textPosX + 2.0f, textPosY, c); - textPosX += 2.0f; - } - textPosX += RenderState.scaleX * (RenderState.proportional ? Size[RenderState.style][c] : Size[RenderState.style][209]); - if (c == '\0') - textPosX += RenderState.fExtraSpace; - } - CSprite2d::RenderVertexBuffer(); - FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf; +void +CFont::SetJustifyOff(void) +{ + Details.justify = false; + Details.rightJustify = false; } +void +CFont::SetCentreOn(void) +{ + Details.centre = true; + Details.justify = false; + Details.rightJustify = false; +} void -CFont::SetFontStyle(int16 style) +CFont::SetCentreOff(void) { - if (style == FONT_HEADING) { - Details.style = FONT_STANDARD; - Details.bFontHalfTexture = true; - } else { - Details.style = style; - Details.bFontHalfTexture = false; - } + Details.centre = false; } -wchar CFont::FindNewCharacter(wchar c) +void +CFont::SetWrapx(float x) { - if (c >= 16 && c <= 26) return c + 128; - if (c >= 8 && c <= 9) return c + 86; - if (c == 4) return c + 89; - if (c == 7) return 206; - if (c == 14) return 207; - if (c >= 33 && c <= 58) return c + 122; - if (c >= 65 && c <= 90) return c + 90; - if (c >= 96 && c <= 118) return c + 85; - if (c >= 119 && c <= 140) return c + 62; - if (c >= 141 && c <= 142) return 204; - if (c == 143) return 205; - if (c == 1) return 208; - return c; + Details.wrapX = x; } -wchar -CFont::character_code(uint8 c) +void +CFont::SetCentreSize(float s) { - if(c < 128) - return c; - return foreign_table[c-128]; + Details.centreSize = s; } +void +CFont::SetBackgroundOn(void) +{ + Details.background = true; +} void -CFont::SetScale(float x, float y) +CFont::SetBackgroundOff(void) { -#ifdef MORE_LANGUAGES - /*if (IsJapanese()) { - x *= 1.35f; - y *= 1.25f; - }*/ -#endif - Details.scaleX = x; - Details.scaleY = y; + Details.background = false; } void @@ -1423,11 +1738,67 @@ CFont::SetBackgroundColor(CRGBA col) } void -CFont::SetColor(CRGBA col) +CFont::SetBackGroundOnlyTextOn(void) { - Details.color = col; - if (Details.alphaFade < 255.0f) - Details.color.a *= Details.alphaFade / 255.0f; + Details.backgroundOnlyText = true; +} + +void +CFont::SetBackGroundOnlyTextOff(void) +{ + Details.backgroundOnlyText = false; +} + +void +CFont::SetRightJustifyOn(void) +{ + Details.rightJustify = true; + Details.justify = false; + Details.centre = false; +} + +void +CFont::SetRightJustifyOff(void) +{ + Details.rightJustify = false; + Details.justify = false; + Details.centre = false; +} + +void +CFont::SetPropOff(void) +{ + Details.proportional = false; +} + +void +CFont::SetPropOn(void) +{ + Details.proportional = true; +} + +void +CFont::SetFontStyle(int16 style) +{ + if (style == FONT_HEADING) { + Details.style = FONT_STANDARD; + Details.bFontHalfTexture = true; + } else { + Details.style = style; + Details.bFontHalfTexture = false; + } +} + +void +CFont::SetRightJustifyWrap(float wrap) +{ + Details.rightJustifyWrap = wrap; +} + +void +CFont::SetAlphaFade(float fade) +{ + Details.alphaFade = fade; } void @@ -1439,19 +1810,32 @@ CFont::SetDropColor(CRGBA col) } void -CFont::FilterOutTokensFromString(wchar *str) +CFont::SetDropShadowPosition(int16 pos) { - int newIdx = 0; - wchar copy[256], *c; - UnicodeStrcpy(copy, str); + Details.dropShadowPosition = pos; +} - for (c = copy; *c != '\0'; c++) { - if (*c == '~') { - c++; - while (*c != '~') c++; - } else { - str[newIdx++] = *c; - } - } - str[newIdx] = '\0'; +wchar CFont::FindNewCharacter(wchar c) +{ + if (c >= 16 && c <= 26) return c + 128; + if (c >= 8 && c <= 9) return c + 86; + if (c == 4) return c + 89; + if (c == 7) return 206; + if (c == 14) return 207; + if (c >= 33 && c <= 58) return c + 122; + if (c >= 65 && c <= 90) return c + 90; + if (c >= 96 && c <= 118) return c + 85; + if (c >= 119 && c <= 140) return c + 62; + if (c >= 141 && c <= 142) return 204; + if (c == 143) return 205; + if (c == 1) return 208; + return c; } + +wchar +CFont::character_code(uint8 c) +{ + if(c < 128) + return c; + return foreign_table[c-128]; +}
\ No newline at end of file diff --git a/src/render/Font.h b/src/render/Font.h index 8942bcc6..4b2dda2b 100644 --- a/src/render/Font.h +++ b/src/render/Font.h @@ -14,28 +14,28 @@ struct CFontDetails float slant; float slantRefX; float slantRefY; - bool justify; - bool centre; - bool rightJustify; - bool background; - bool backgroundOnlyText; - bool proportional; - bool bIsShadow; - bool bFlash; - bool bBold; + bool8 justify; + bool8 centre; + bool8 rightJustify; + bool8 background; + bool8 backgroundOnlyText; + bool8 proportional; + bool8 bIsShadow; + bool8 bFlash; + bool8 bBold; float alphaFade; CRGBA backgroundColor; float wrapX; float centreSize; float rightJustifyWrap; int16 style; - bool bFontHalfTexture; + bool8 bFontHalfTexture; uint32 bank; int16 dropShadowPosition; CRGBA dropColor; - bool bFlashState; + bool8 bFlashState; int nFlashTimer; - bool anonymous_23; + bool8 anonymous_23; uint32 anonymous_25; }; @@ -51,10 +51,10 @@ struct CFontRenderState float slant; float slantRefX; float slantRefY; - bool bIsShadow; - bool bFontHalfTexture; - bool proportional; - bool anonymous_14; + bool8 bIsShadow; + bool8 bFontHalfTexture; + bool8 proportional; + bool8 anonymous_14; int16 style; }; @@ -91,6 +91,31 @@ enum #define FONT_LOCALE(style) (style) #endif +#ifdef BUTTON_ICONS +enum +{ + BUTTON_NONE = -1, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_LEFT, + BUTTON_RIGHT, + BUTTON_CROSS, + BUTTON_CIRCLE, + BUTTON_SQUARE, + BUTTON_TRIANGLE, + BUTTON_L1, + BUTTON_L2, + BUTTON_L3, + BUTTON_R1, + BUTTON_R2, + BUTTON_R3, + BUTTON_RSTICK_LEFT, + BUTTON_RSTICK_RIGHT, + MAX_BUTTON_ICONS +}; +#endif // BUTTON_ICONS + + class CFont { #ifdef MORE_LANGUAGES @@ -106,11 +131,24 @@ public: static CFontDetails Details; static CFontRenderState RenderState; +#ifdef BUTTON_ICONS + static int32 ButtonsSlot; + static CSprite2d ButtonSprite[MAX_BUTTON_ICONS]; + static int PS2Symbol; + + static void DrawButton(float x, float y); +#endif // BUTTON_ICONS + + static void Initialise(void); static void Shutdown(void); static void InitPerFrame(void); static void PrintChar(float x, float y, wchar c); static void PrintString(float x, float y, wchar *s); +#ifdef XBOX_SUBTITLES + static void PrintStringFromBottom(float x, float y, wchar *str); + static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor); +#endif static int GetNumberLines(float xstart, float ystart, wchar *s); static void GetTextRect(CRect *rect, float xstart, float ystart, wchar *s); #ifdef MORE_LANGUAGES @@ -130,72 +168,33 @@ public: static uint16 *ParseToken(wchar *s, bool japShit = false); #else static uint16 *ParseToken(wchar *s); - static uint16* ParseToken(wchar *s, CRGBA &color, bool &flash, bool &bold); + static uint16 *ParseToken(wchar *s, CRGBA &color, bool &flash, bool &bold); #endif static void DrawFonts(void); static void RenderFontBuffer(void); static uint16 character_code(uint8 c); - static CFontDetails GetDetails() { return Details; } static void SetScale(float x, float y); - static void SetSlantRefPoint(float x, float y) { Details.slantRefX = x; Details.slantRefY = y; } - static void SetSlant(float s) { Details.slant = s; } - static void SetJustifyOn(void) { - Details.justify = true; - Details.centre = false; - Details.rightJustify = false; - } - static void SetJustifyOff(void) { - Details.justify = false; - Details.rightJustify = false; - } - static void SetRightJustifyOn(void) { - Details.rightJustify = true; - Details.justify = false; - Details.centre = false; - } - static void SetRightJustifyOff(void) { - Details.rightJustify = false; - Details.justify = false; - Details.centre = false; - } - static void SetCentreOn(void) { - Details.centre = true; - Details.justify = false; - Details.rightJustify = false; - } - static void SetCentreOff(void) { - Details.centre = false; - } - static void SetAlignment(uint8 alignment) { - if (alignment == ALIGN_LEFT) { - CFont::Details.justify = true; - CFont::Details.centre = false; - CFont::Details.rightJustify = false; - } - else if (alignment == ALIGN_CENTER) { - CFont::Details.justify = false; - CFont::Details.centre = true; - CFont::Details.rightJustify = false; - } - else if (alignment == ALIGN_RIGHT) { - CFont::Details.justify = false; - CFont::Details.centre = false; - CFont::Details.rightJustify = true; - } - } - static void SetWrapx(float x) { Details.wrapX = x; } - static void SetCentreSize(float s) { Details.centreSize = s; } - static void SetBackgroundOn(void) { Details.background = true; } - static void SetBackgroundOff(void) { Details.background = false; } - static void SetBackGroundOnlyTextOn(void) { Details.backgroundOnlyText = true; } - static void SetBackGroundOnlyTextOff(void) { Details.backgroundOnlyText = false; } - static void SetPropOn(void) { Details.proportional = true; } - static void SetPropOff(void) { Details.proportional = false; } + static void SetSlantRefPoint(float x, float y); + static void SetSlant(float s); + static void SetJustifyOn(void); + static void SetJustifyOff(void); + static void SetRightJustifyOn(void); + static void SetRightJustifyOff(void); + static void SetCentreOn(void); + static void SetCentreOff(void); + static void SetWrapx(float x); + static void SetCentreSize(float s); + static void SetBackgroundOn(void); + static void SetBackgroundOff(void); + static void SetBackGroundOnlyTextOn(void); + static void SetBackGroundOnlyTextOff(void); + static void SetPropOn(void); + static void SetPropOff(void); static void SetFontStyle(int16 style); - static void SetRightJustifyWrap(float wrap) { Details.rightJustifyWrap = wrap; } - static void SetAlphaFade(float fade) { Details.alphaFade = fade; } - static void SetDropShadowPosition(int16 pos) { Details.dropShadowPosition = pos; } + static void SetRightJustifyWrap(float wrap); + static void SetAlphaFade(float fade); + static void SetDropShadowPosition(int16 pos); static void SetBackgroundColor(CRGBA col); static void SetColor(CRGBA col); static void SetDropColor(CRGBA col); diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp index 536d94e0..a11495a9 100644 --- a/src/render/Glass.cpp +++ b/src/render/Glass.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "common.h" #include "Glass.h" #include "Timer.h" @@ -150,7 +150,11 @@ CFallingGlassPane::Render(void) fwdNorm.Normalise(); uint8 alpha = CGlass::CalcAlphaWithNormal(&fwdNorm); - int32 time = clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500); +#ifdef FIX_BUGS + uint16 time = clamp(CTimer::GetTimeInMilliseconds() > m_nTimer ? CTimer::GetTimeInMilliseconds() - m_nTimer : 0u, 0u, 500u); +#else + uint16 time = clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500); +#endif uint8 color = int32( float(alpha) * (float(time) / 500) ); diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 239d0de4..17291a61 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -24,8 +24,17 @@ #include "Stats.h" #include "main.h" #include "General.h" +#include "VarConsole.h" -// --MIAMI: file done +#if defined(FIX_BUGS) + #define SCREEN_SCALE_X_FIX(a) SCREEN_SCALE_X(a) + #define SCREEN_SCALE_Y_FIX(a) SCREEN_SCALE_Y(a) + #define SCALE_AND_CENTER_X_FIX(a) SCALE_AND_CENTER_X(a) +#else + #define SCREEN_SCALE_X_FIX(a) (a) + #define SCREEN_SCALE_Y_FIX(a) (a) + #define SCALE_AND_CENTER_X_FIX(a) (a) +#endif // Game has colors inlined in code. // For easier modification we collect them here: @@ -438,10 +447,10 @@ void CHud::Draw() } if (m_WeaponState != FADED_OUT) { CWeapon *weapon = playerPed->GetWeapon(); - uint32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition; - uint32 AmmoInClip = weapon->m_nAmmoInClip; - uint32 TotalAmmo = weapon->m_nAmmoTotal; - uint32 Ammo, Clip; + int32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition; + int32 AmmoInClip = weapon->m_nAmmoInClip; + int32 TotalAmmo = weapon->m_nAmmoTotal; + int32 Ammo, Clip; if (AmmoAmount <= 1 || AmmoAmount >= 1000) sprintf(sTemp, "%d", TotalAmmo); @@ -480,7 +489,7 @@ void CHud::Draw() CBaseModelInfo *weaponModel = CModelInfo::GetModelInfo(weaponInfo->m_nModelId); RwTexDictionary *weaponTxd = CTxdStore::GetSlot(weaponModel->GetTxdSlot())->texDict; if (weaponTxd) { - RwTexture *weaponIcon = RwTexDictionaryFindNamedTexture(weaponTxd, weaponModel->GetName()); + RwTexture *weaponIcon = RwTexDictionaryFindNamedTexture(weaponTxd, weaponModel->GetModelName()); if (weaponIcon) { RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); #ifndef FIX_BUGS @@ -608,11 +617,11 @@ void CHud::Draw() /* DrawWantedLevel */ - if (m_LastWanted == playerPed->m_pWanted->m_nWantedLevel) { + if (m_LastWanted == playerPed->m_pWanted->GetWantedLevel()) { alpha = DrawFadeState(HUD_WANTED_FADING, 0); } else { alpha = DrawFadeState(HUD_WANTED_FADING, 1); - m_LastWanted = playerPed->m_pWanted->m_nWantedLevel; + m_LastWanted = playerPed->m_pWanted->GetWantedLevel(); } if (m_WantedState != FADED_OUT) { @@ -628,7 +637,7 @@ void CHud::Draw() for (int i = 0; i < 6; i++) { if (FrontEndMenuManager.m_PrefsShowHud) { - if (playerPed->m_pWanted->m_nWantedLevel > i + if (playerPed->m_pWanted->GetWantedLevel() > i && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange + 2000 || CTimer::GetFrameCounter() & 4)) { @@ -641,7 +650,7 @@ void CHud::Draw() CFont::SetColor(WANTED_COLOR_FLASH); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); - } else if (playerPed->m_pWanted->m_nWantedLevel <= i) { + } else if (playerPed->m_pWanted->GetWantedLevel() <= i) { NOTWANTED_COLOR.a = alpha; CFont::SetColor(NOTWANTED_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); @@ -1051,16 +1060,17 @@ void CHud::Draw() CRadar::DrawMap(); if (FrontEndMenuManager.m_PrefsRadarMode != 1) { CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT)); + + rect.Translate(SCREEN_SCALE_X_FIX(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT)); + #ifdef FIX_BUGS - rect.Translate(SCREEN_SCALE_X(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT)); + rect.Grow(SCREEN_SCALE_X(6.0f), SCREEN_SCALE_X(6.0f), SCREEN_SCALE_Y(6.0f), SCREEN_SCALE_Y(6.0f)); #else - rect.Translate(RADAR_LEFT, SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT)); -#endif - rect.Grow(6.0f); - rect.Translate(0.0f, 2.0f); +#endif + rect.Translate(SCREEN_SCALE_X_FIX(0.0f), SCREEN_SCALE_Y_FIX(2.0f)); Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255)); - rect.Translate(0.0f, -2.0f); + rect.Translate(SCREEN_SCALE_X_FIX(0.0f), SCREEN_SCALE_Y_FIX(-2.0f)); Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR); } CRadar::DrawBlips(); @@ -1119,7 +1129,7 @@ void CHud::Draw() CFont::SetPropOff(); CFont::SetFontStyle(FONT_LOCALE(CTheScripts::IntroTextLines[i].m_nFont)); - CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text); + CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text); } } for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) { @@ -1172,6 +1182,10 @@ void CHud::Draw() onceItWasWidescreen = true; if (FrontEndMenuManager.m_PrefsShowSubtitles || !CCutsceneMgr::IsRunning()) { +#ifdef CUTSCENE_BORDERS_SWITCH + if (!FrontEndMenuManager.m_PrefsCutsceneBorders) + CFont::SetDropShadowPosition(2); +#endif CFont::SetCentreSize(SCREEN_WIDTH - SCREEN_SCALE_X(60.0f)); CFont::SetScale(SCREEN_SCALE_X(0.58f), SCREEN_SCALE_Y(1.2f)); CFont::PrintString(SCREEN_WIDTH / 2.f, SCREEN_SCALE_FROM_BOTTOM(80.0f), m_Message); @@ -1457,7 +1471,7 @@ void CHud::DrawAfterFade() CFont::SetPropOff(); CFont::SetFontStyle(line.m_nFont); - CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text); + CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text); } } for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) { @@ -1558,15 +1572,8 @@ void CHud::DrawAfterFade() CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); -#ifdef BETA_SLIDING_TEXT - - CFont::SetColor(ODDJOB2_COLOR); - CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_SCALE_Y(217.0f), m_BigMessage[5]); -#else - CFont::SetColor(ODDJOB2_COLOR); CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(217.0f), m_BigMessage[5]); -#endif } } @@ -1615,11 +1622,7 @@ void CHud::DrawAfterFade() CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, BigMessageAlpha[1])); CFont::SetColor(CRGBA(MISSIONTITLE_COLOR.r, MISSIONTITLE_COLOR.g, MISSIONTITLE_COLOR.b, BigMessageAlpha[1])); -#ifdef BETA_SLIDING_TEXT - CFont::PrintString(BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]); -#else CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]); -#endif } else { m_ZoneFadeTimer = 0; BigMessageX[1] = SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 60.0f); @@ -1767,6 +1770,9 @@ void CHud::Initialise() m_LastWanted = 0; m_LastWeapon = 0; +#ifndef MASTER + VarConsole.Add("Draw HUD", &m_Wants_To_Draw_Hud, false); +#endif CTxdStore::PopCurrentTxd(); } diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index 08298a1f..a94a5245 100644 --- a/src/render/MBlur.cpp +++ b/src/render/MBlur.cpp @@ -1,4 +1,3 @@ -#define WITHWINDOWS #ifndef LIBRW #define WITHD3D #endif @@ -7,10 +6,15 @@ #include <d3d8caps.h> #endif +#include "General.h" #include "RwHelper.h" #include "Camera.h" -#include "MBlur.h" +#include "Timecycle.h" +#include "Particle.h" #include "Timer.h" +#include "Hud.h" +#include "Frontend.h" +#include "MBlur.h" #include "postfx.h" // Originally taken from RW example 'mblur' @@ -21,6 +25,8 @@ bool CMBlur::ms_bScaledBlur; bool CMBlur::BlurOn; float CMBlur::Drunkness; +int32 CMBlur::pBufVertCount; + static RwIm2DVertex Vertex[4]; static RwIm2DVertex Vertex2[4]; static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 }; @@ -244,6 +250,84 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect) } void +CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect, RwIm2DVertex *verts, RwRGBA color, float u1Off, float v1Off, float u2Off, float v2Off, float z, int fullTexture) +{ + float x1 = rect->x; + float y1 = rect->y; + float x2 = rect->w; + float y2 = rect->h; + + float u1, v1, u2, v2; + if(fullTexture){ + u1 = 0.0f; + v1 = 0.0f; + u2 = 1.0f; + v2 = 1.0f; + }else{ + if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){ + x1 += HALFPX; + y1 += HALFPX; + x2 += HALFPX; + y2 += HALFPX; + }else{ + x1 -= HALFPX; + y1 -= HALFPX; + x2 -= HALFPX; + y2 -= HALFPX; + } + + int32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1); + int32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1); + u1 = x1/width + u1Off; + v1 = y1/height + v1Off; + u2 = x2/width + u2Off; + v2 = y2/height + v2Off; + u1 = clamp(u1, 0.0f, 1.0f); + v1 = clamp(v1, 0.0f, 1.0f); + u2 = clamp(u2, 0.0f, 1.0f); + v2 = clamp(v2, 0.0f, 1.0f); + } + + float recipz = 1.0f/z; + // TODO: CameraZ is wrong, what should we do? + RwIm2DVertexSetScreenX(&verts[0], x1); + RwIm2DVertexSetScreenY(&verts[0], y1); + RwIm2DVertexSetScreenZ(&verts[0], z); + RwIm2DVertexSetCameraZ(&verts[0], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&verts[0], recipz); + RwIm2DVertexSetU(&verts[0], u1, recipz); + RwIm2DVertexSetV(&verts[0], v1, recipz); + RwIm2DVertexSetIntRGBA(&verts[0], color.red, color.green, color.blue, color.alpha); + + RwIm2DVertexSetScreenX(&verts[1], x1); + RwIm2DVertexSetScreenY(&verts[1], y2); + RwIm2DVertexSetScreenZ(&verts[1], z); + RwIm2DVertexSetCameraZ(&verts[1], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&verts[1], recipz); + RwIm2DVertexSetU(&verts[1], u1, recipz); + RwIm2DVertexSetV(&verts[1], v2, recipz); + RwIm2DVertexSetIntRGBA(&verts[1], color.red, color.green, color.blue, color.alpha); + + RwIm2DVertexSetScreenX(&verts[2], x2); + RwIm2DVertexSetScreenY(&verts[2], y2); + RwIm2DVertexSetScreenZ(&verts[2], z); + RwIm2DVertexSetCameraZ(&verts[2], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&verts[2], recipz); + RwIm2DVertexSetU(&verts[2], u2, recipz); + RwIm2DVertexSetV(&verts[2], v2, recipz); + RwIm2DVertexSetIntRGBA(&verts[2], color.red, color.green, color.blue, color.alpha); + + RwIm2DVertexSetScreenX(&verts[3], x2); + RwIm2DVertexSetScreenY(&verts[3], y1); + RwIm2DVertexSetScreenZ(&verts[3], z); + RwIm2DVertexSetCameraZ(&verts[3], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&verts[3], recipz); + RwIm2DVertexSetU(&verts[3], u2, recipz); + RwIm2DVertexSetV(&verts[3], v1, recipz); + RwIm2DVertexSetIntRGBA(&verts[3], color.red, color.green, color.blue, color.alpha); +} + +void CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha) { #ifdef EXTENDED_COLOURFILTER @@ -357,7 +441,7 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, 80); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - // TODO(MIAMI): pBufVertCount = 0; + pBufVertCount = 0; }else{ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30); RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30); @@ -415,7 +499,8 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); } - // TODO(MIAMI): OverlayRenderFx + if(type != MOTION_BLUR_SNIPER) + OverlayRenderFx(cam, pFrontBuffer); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); @@ -437,4 +522,277 @@ CMBlur::ClearDrunkBlur() { Drunkness = 0.0f; CTimer::SetTimeScale(1.0f); -}
\ No newline at end of file +} + +#define NUM_RENDER_FX 64 + +static RwRect fxRect[NUM_RENDER_FX]; +static FxType fxType[NUM_RENDER_FX]; +static float fxZ[NUM_RENDER_FX]; + +bool +CMBlur::PosInside(RwRect *rect, float x1, float y1, float x2, float y2) +{ + if((rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f) && + (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) && + (rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) && + (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f)) + return false; + return true; +} + +bool +CMBlur::AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type) +{ + if(pBufVertCount >= NUM_RENDER_FX) + return false; + + rect->x = Max(rect->x, 0); + rect->y = Max(rect->y, 0); + rect->w = Min(rect->w, SCREEN_WIDTH); + rect->h = Min(rect->h, SCREEN_HEIGHT); + if(rect->x >= rect->w || rect->y >= rect->h) + return false; + + switch(type){ + case FXTYPE_WATER1: + case FXTYPE_WATER2: + case FXTYPE_BLOOD1: + case FXTYPE_BLOOD2: + case FXTYPE_HEATHAZE: // code seems to be duplicated for this case + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == type && PosInside(rect, fxRect[i].x-10.0f, fxRect[i].y-10.0f, fxRect[i].w+10.0f, fxRect[i].h+10.0f)) + return false; + // TODO: fix aspect ratio scaling + // radar + if(PosInside(rect, 40.0f, SCREEN_SCALE_FROM_BOTTOM(116.0f), 40.0f + SCREEN_SCALE_X(94.0f), SCREEN_SCALE_FROM_BOTTOM(116.0f - 76.0f))) + return false; + // HUD + if(PosInside(rect, 400.0f, 0.0f, SCREEN_WIDTH, 90.0f)) + return false; + // vehicle name + if(CHud::m_VehicleState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT)) + return false; + // zone name + if(CHud::m_ZoneState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT)) + return false; + break; + } + + fxRect[pBufVertCount] = *rect; + fxZ[pBufVertCount] = z; + fxType[pBufVertCount] = type; + pBufVertCount++; + + return true; +} + +void +CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf) +{ + bool drawWaterDrops = false; + RwIm2DVertex verts[4]; + int red = (0.75f*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.55f * 255; + int green = (0.75f*CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.55f * 255; + int blue = (0.75f*CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue())*0.55f * 255; + red = clamp(red, 0, 255); + green = clamp(green, 0, 255); + blue = clamp(blue, 0, 255); + + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + +#ifdef LIBRW + rw::SetRenderState(rw::STENCILENABLE, TRUE); +#else + RwD3D8SetRenderState(D3DRS_STENCILENABLE, TRUE); +#endif + + for(int i = 0; i < pBufVertCount; i++) + switch(fxType[i]){ + case FXTYPE_WATER1: + case FXTYPE_WATER2: + case FXTYPE_BLOOD1: + case FXTYPE_BLOOD2: { + drawWaterDrops = true; + int32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1); + int32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1); + + float u1Off = (fxRect[i].w - fxRect[i].x)/width; + float u2Off = u1Off - (fxRect[i].w - fxRect[i].x + 0.5f)*0.66f/width; + float halfHeight = (fxRect[i].h - fxRect[i].y + 0.5f)*0.25f/height; + + if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){ + if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2) + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + else + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + }else{ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + } + + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpDotRaster); +#ifdef LIBRW + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS); + rw::SetRenderState(rw::STENCILFUNCTIONREF, 1); + rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF); + rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF); + rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE); +#else + RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + RwD3D8SetRenderState(D3DRS_STENCILREF, 1); + RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF); + RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF); + RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); +#endif + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + + if(RwRasterGetDepth(RwCameraGetRaster(cam)) != 16){ + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf); +#ifdef LIBRW + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP); +#else + RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); + RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); +#endif + if(BlurOn){ + if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2) + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 255), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false); + else + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(225, 225, 225, 160), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDDESTALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVDESTALPHA); + }else{ + if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2) + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false); + else + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(128, 128, 128, 32), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + } + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + break; + } + case FXTYPE_SPLASH1: + case FXTYPE_SPLASH2: + case FXTYPE_SPLASH3: + drawWaterDrops = true; + break; + + case FXTYPE_HEATHAZE: + if(TheCamera.GetScreenFadeStatus() == FADE_0 && frontBuf){ + int alpha = FrontEndMenuManager.m_PrefsBrightness > 255 ? + FrontEndMenuManager.m_PrefsBrightness - 90 : + FrontEndMenuManager.m_PrefsBrightness - 130; + alpha = clamp(alpha, 16, 200)/2; + + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(0, 0, 0, alpha), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpHeatHazeRaster); +#ifdef LIBRW + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS); + rw::SetRenderState(rw::STENCILFUNCTIONREF, 1); + rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF); + rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF); + rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE); +#else + RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + RwD3D8SetRenderState(D3DRS_STENCILREF, 1); + RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF); + RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF); + RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); +#endif + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 255, 255, alpha), + CGeneral::GetRandomNumberInRange(-0.002f, 0.002f), + CGeneral::GetRandomNumberInRange(-0.002f, 0.002f), + CGeneral::GetRandomNumberInRange(-0.002f, 0.002f), + CGeneral::GetRandomNumberInRange(-0.002f, 0.002f), + fxZ[i], false); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf); +#ifdef LIBRW + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP); +#else + RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); + RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); +#endif + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + break; + } +#ifdef LIBRW + rw::SetRenderState(rw::STENCILENABLE, FALSE); +#else + RwD3D8SetRenderState(D3DRS_STENCILENABLE, FALSE); +#endif + + if(drawWaterDrops){ + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + + // Draw drops + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[0]); + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == FXTYPE_WATER1 || fxType[i] == FXTYPE_BLOOD1){ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD1 ? 255 : 192), + 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[1]); + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == FXTYPE_WATER2 || fxType[i] == FXTYPE_BLOOD2){ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD2 ? 255 : 192), + 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCarSplashRaster[0]); + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == FXTYPE_SPLASH1 || fxType[i] == FXTYPE_SPLASH2 || fxType[i] == FXTYPE_SPLASH3){ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(200, 200, 200, 255), + 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + + // Darken the water drops + int alpha = 192*0.5f; + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[0]); + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == FXTYPE_WATER1){ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha), + 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[1]); + for(int i = 0; i < pBufVertCount; i++) + if(fxType[i] == FXTYPE_WATER2){ + CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha), + 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6); + } + } + + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + pBufVertCount = 0; +} diff --git a/src/render/MBlur.h b/src/render/MBlur.h index c2572256..3dc53082 100644 --- a/src/render/MBlur.h +++ b/src/render/MBlur.h @@ -2,12 +2,14 @@ enum FxType { - FXTYPE_0 = 0, - FXTYPE_1, - FXTYPE_2, - FXTYPE_3, - FXTYPE_4, - FXTYPE_5, + FXTYPE_WATER1, + FXTYPE_WATER2, + FXTYPE_BLOOD1, + FXTYPE_BLOOD2, + FXTYPE_HEATHAZE, + FXTYPE_SPLASH1, + FXTYPE_SPLASH2, + FXTYPE_SPLASH3 }; class CMBlur @@ -19,16 +21,19 @@ public: static bool BlurOn; static float Drunkness; + static int32 pBufVertCount; + public: static RwBool MotionBlurOpen(RwCamera *cam); static RwBool MotionBlurClose(void); static void CreateImmediateModeData(RwCamera *cam, RwRect *rect); + static void CreateImmediateModeData(RwCamera *cam, RwRect *rect, RwIm2DVertex *verts, RwRGBA color, float u1Off, float v1Off, float u2Off, float v2Off, float z, int fullTexture); static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha); static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha); static void SetDrunkBlur(float drunkness); static void ClearDrunkBlur(); - //TODO - static void AddRenderFx(RwCamera *,RwRect *,float,FxType) - {} + static bool PosInside(RwRect *rect, float x1, float y1, float x2, float y2); + static bool AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type); + static void OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf); }; diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp index 5fef6e21..3ea5678c 100644 --- a/src/render/Occlusion.cpp +++ b/src/render/Occlusion.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "main.h" +#include "Entity.h" #include "Occlusion.h" #include "Game.h" #include "Camera.h" @@ -8,6 +9,7 @@ #include "Draw.h" #include "Timer.h" #include "RwHelper.h" +#include "VarConsole.h" int32 COcclusion::NumOccludersOnMap; int16 COcclusion::FarAwayList; @@ -30,20 +32,20 @@ CVector gOccluderCoorsOnScreen[8]; CVector gOccluderCoors[8]; #ifndef MASTER -bool bDisplayOccDebugStuff; +bool bDispayOccDebugStuff; // disPAY, yeah #endif void COcclusion::Init(void) { NumOccludersOnMap = 0; +#ifndef MASTER + VarConsole.Add("Occlusion debug", &bDispayOccDebugStuff, true); +#endif FarAwayList = -1; NearbyList = -1; ListWalkThroughFA = -1; PreviousListWalkThroughFA = -1; -#ifndef MASTER - bDisplayOccDebugStuff = false; -#endif } void @@ -457,7 +459,7 @@ bool COcclusion::IsPositionOccluded(CVector pos, float side) { RwIm2DVertex vertexbufferT[2]; void COcclusion::Render() { - if (!bDisplayOccDebugStuff || !(CTimer::GetTimeInMilliseconds() & 0x200)) + if (!bDispayOccDebugStuff || !(CTimer::GetTimeInMilliseconds() & 0x200)) return; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); @@ -493,3 +495,36 @@ void COcclusion::Render() { DefinedState(); } #endif + +bool CEntity::IsEntityOccluded(void) { + + CVector coors; + float width, height; + + if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height)) + return false; + + float area = Max(width, height) * GetBoundRadius() * 0.9f; + + for (int i = 0; i < COcclusion::NumActiveOccluders; i++) { + if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) { + if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) { + return true; + } + + if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) { + CVector min = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min; + CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.max; + + if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; + if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; + if (CalcScreenCoors(CVector(max.x, min.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; + if (CalcScreenCoors(CVector(min.x, max.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue; + + return true; + } + } + } + + return false; +}
\ No newline at end of file diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h index 8a444525..e0edef53 100644 --- a/src/render/Occlusion.h +++ b/src/render/Occlusion.h @@ -58,5 +58,5 @@ bool CalcScreenCoors(CVector const &in, CVector *out, float *outw, float *outh); bool CalcScreenCoors(CVector const &in, CVector *out); #ifndef MASTER -extern bool bDisplayOccDebugStuff; +extern bool bDispayOccDebugStuff; #endif
\ No newline at end of file diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index 6a42bc4d..51249844 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -213,19 +213,19 @@ RwTexture *gpSparkTex; RwTexture *gpNewspaperTex; RwTexture *gpGunSmokeTex; RwTexture *gpDotTex; -RwTexture *gpHeathazeTex; +RwTexture *gpHeatHazeTex; RwTexture *gpBeastieTex; -RwTexture *gpRaindripTex1[MAX_RAINDRIP_FILES]; -RwTexture *gpRaindripTex2[MAX_RAINDRIP_FILES]; +RwTexture *gpRainDripTex[MAX_RAINDRIP_FILES]; +RwTexture *gpRainDripDarkTex[MAX_RAINDRIP_FILES]; RwRaster *gpSparkRaster; RwRaster *gpNewspaperRaster; RwRaster *gpGunSmokeRaster; RwRaster *gpDotRaster; -RwRaster *gpHeathazeRaster; +RwRaster *gpHeatHazeRaster; RwRaster *gpBeastieRaster; -RwRaster *gpRaindripRaster1[MAX_RAINDRIP_FILES]; -RwRaster *gpRaindripRaster2[MAX_RAINDRIP_FILES]; +RwRaster *gpRainDripRaster[MAX_RAINDRIP_FILES]; +RwRaster *gpRainDripDarkRaster[MAX_RAINDRIP_FILES]; float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE]; CParticle *CParticle::m_pUnusedListHead; @@ -411,9 +411,11 @@ void CParticle::Initialise() gpFlame5Tex = RwTextureRead("flame5", nil); -#ifdef FIX_BUGS +//#ifdef FIX_BUGS +#if 0 gpFlame5Raster = RwTextureGetRaster(gpFlame5Tex); #else + // this seems to have become more of a design choice gpFlame5Raster = RwTextureGetRaster(gpFlame1Tex); // copy-paste bug ? #endif @@ -465,23 +467,23 @@ void CParticle::Initialise() gpDotTex = RwTextureRead("dot", nil); gpDotRaster = RwTextureGetRaster(gpDotTex); - gpHeathazeTex = RwTextureRead("heathaze", nil); - gpHeathazeRaster = RwTextureGetRaster(gpHeathazeTex); + gpHeatHazeTex = RwTextureRead("heathaze", nil); + gpHeatHazeRaster = RwTextureGetRaster(gpHeatHazeTex); gpBeastieTex = RwTextureRead("beastie", nil); gpBeastieRaster = RwTextureGetRaster(gpBeastieTex); - gpRaindripTex1[0] = RwTextureRead("raindrip64", nil); - gpRaindripRaster1[0] = RwTextureGetRaster(gpRaindripTex1[0]); + gpRainDripTex[0] = RwTextureRead("raindrip64", nil); + gpRainDripRaster[0] = RwTextureGetRaster(gpRainDripTex[0]); - gpRaindripTex1[1] = RwTextureRead("raindripb64", nil); - gpRaindripRaster1[1] = RwTextureGetRaster(gpRaindripTex1[1]); + gpRainDripTex[1] = RwTextureRead("raindripb64", nil); + gpRainDripRaster[1] = RwTextureGetRaster(gpRainDripTex[1]); - gpRaindripTex2[0] = RwTextureRead("raindrip64_d", nil); - gpRaindripRaster2[0] = RwTextureGetRaster(gpRaindripTex2[0]); + gpRainDripDarkTex[0] = RwTextureRead("raindrip64_d", nil); + gpRainDripDarkRaster[0] = RwTextureGetRaster(gpRainDripDarkTex[0]); - gpRaindripTex2[1] = RwTextureRead("raindripb64_d", nil); - gpRaindripRaster2[1] = RwTextureGetRaster(gpRaindripTex2[1]); + gpRainDripDarkTex[1] = RwTextureRead("raindripb64_d", nil); + gpRainDripDarkRaster[1] = RwTextureGetRaster(gpRainDripDarkTex[1]); CTxdStore::PopCurrentTxd(); @@ -586,7 +588,7 @@ void CParticle::Initialise() break; case PARTICLE_TEARGAS: - entry->m_ppRaster = &gpHeathazeRaster; + entry->m_ppRaster = &gpHeatHazeRaster; break; case PARTICLE_SHARD: @@ -749,11 +751,11 @@ void CParticle::Shutdown() for ( int32 i = 0; i < MAX_RAINDRIP_FILES; i++ ) { - RwTextureDestroy(gpRaindripTex1[i]); - gpRaindripTex1[i] = nil; + RwTextureDestroy(gpRainDripTex[i]); + gpRainDripTex[i] = nil; - RwTextureDestroy(gpRaindripTex2[i]); - gpRaindripTex2[i] = nil; + RwTextureDestroy(gpRainDripDarkTex[i]); + gpRainDripDarkTex[i] = nil; } RwTextureDestroy(gpBoatWakeTex); @@ -812,8 +814,8 @@ void CParticle::Shutdown() RwTextureDestroy(gpDotTex); gpDotTex = nil; - RwTextureDestroy(gpHeathazeTex); - gpHeathazeTex = nil; + RwTextureDestroy(gpHeatHazeTex); + gpHeatHazeTex = nil; RwTextureDestroy(gpBeastieTex); gpBeastieTex = nil; @@ -941,7 +943,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe CVector screen; float w, h; - if ( !CSprite::CalcScreenCoors(vecPos, screen, &w, &h, true) ) + if ( !CSprite::CalcScreenCoors(vecPos, &screen, &w, &h, true) ) return nil; pParticle->m_vecPosition = screen; @@ -1913,9 +1915,9 @@ void CParticle::Render() FxType fxtype; if ( particle->m_nCurrentFrame != 0 ) - fxtype = FXTYPE_1; + fxtype = FXTYPE_WATER2; else - fxtype = FXTYPE_0; + fxtype = FXTYPE_WATER1; CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype); @@ -1939,9 +1941,9 @@ void CParticle::Render() FxType fxtype; if ( particle->m_nCurrentFrame ) - fxtype = FXTYPE_3; + fxtype = FXTYPE_BLOOD2; else - fxtype = FXTYPE_2; + fxtype = FXTYPE_BLOOD1; CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype); @@ -1957,7 +1959,7 @@ void CParticle::Render() rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH * 0.15f)); - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_4); + CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE); canDraw = false; } @@ -1993,7 +1995,7 @@ void CParticle::Render() break; } - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_4); + CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE); canDraw = false; } @@ -2034,7 +2036,7 @@ void CParticle::Render() float w; float h; - if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) ) + if ( CSprite::CalcScreenCoors(particle->m_vecPosition, &coors, &w, &h, true) ) { if ( i == PARTICLE_ENGINE_STEAM @@ -2115,7 +2117,7 @@ void CParticle::Render() * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) * CDraw::GetFarClipZ() / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * coors.z ) + CSprite::GetNearScreenZ(); - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_5); + CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_SPLASH1); } else { @@ -2189,7 +2191,7 @@ void CParticle::Render() float fTrailLength; CVector vecScreenPosition; - if ( CSprite::CalcScreenCoors(vecPrevPos, vecScreenPosition, &fTrailLength, &fRotation, true) ) + if ( CSprite::CalcScreenCoors(vecPrevPos, &vecScreenPosition, &fTrailLength, &fRotation, true) ) { CVector2D vecDist ( @@ -2329,9 +2331,9 @@ void CParticle::AddJetExplosion(CVector const &vecPos, float fPower, float fSize vecStepPos, CVector ( - CGeneral::GetRandomNumberInRange(-0.2f, 0.2f), - CGeneral::GetRandomNumberInRange(-0.2f, 0.2f), - CGeneral::GetRandomNumberInRange(-0.2f, 0.0f) + CGeneral::GetRandomNumberInRange(-0.02f, 0.02f), + CGeneral::GetRandomNumberInRange(-0.02f, 0.02f), + CGeneral::GetRandomNumberInRange(-0.02f, 0.0f) ), nil, fSize, color, 0, 0, 0, 0); @@ -2470,3 +2472,43 @@ void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos) } } + +void +CEntity::AddSteamsFromGround(CVector *unused) +{ + int i, n; + C2dEffect *effect; + CVector pos; + + n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); + for(i = 0; i < n; i++){ + effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); + if(effect->type != EFFECT_PARTICLE) + continue; + + pos = GetMatrix() * effect->pos; + switch(effect->particle.particleType){ + case 0: + CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 1: + CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 2: + CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false); + break; + case 3: + CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 4: + CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 5: + CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 6: + CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false); + break; + } + } +} diff --git a/src/render/Particle.h b/src/render/Particle.h index 9c496fe1..5542dc02 100644 --- a/src/render/Particle.h +++ b/src/render/Particle.h @@ -99,5 +99,10 @@ public: extern bool clearWaterDrop; extern int32 numWaterDropOnScreen; +extern RwRaster *gpCarSplashRaster[]; +extern RwRaster *gpHeatHazeRaster; +extern RwRaster *gpDotRaster; +extern RwRaster *gpRainDripRaster[]; +extern RwRaster *gpRainDripDarkRaster[]; VALIDATE_SIZE(CParticle, 0x58); diff --git a/src/render/ParticleType.h b/src/render/ParticleType.h index 0af9a1e1..9578083d 100644 --- a/src/render/ParticleType.h +++ b/src/render/ParticleType.h @@ -88,5 +88,5 @@ enum tParticleType MAX_PARTICLES, PARTICLE_FIRST = PARTICLE_SPARK, - PARTICLE_LAST = PARTICLE_RAINDROP_2D + PARTICLE_LAST = PARTICLE_HEATHAZE_IN_DIST };
\ No newline at end of file diff --git a/src/render/PlayerSkin.cpp b/src/render/PlayerSkin.cpp index 261bbec0..ee944ca7 100644 --- a/src/render/PlayerSkin.cpp +++ b/src/render/PlayerSkin.cpp @@ -14,8 +14,7 @@ #include "RwHelper.h" #include "Timer.h" #include "Lights.h" - -//--MIAMI: file done +#include "MemoryMgr.h" RpClump *gpPlayerClump; float gOldFov; @@ -75,6 +74,7 @@ LoadPlayerDff(void) void CPlayerSkin::Initialise(void) { + // empty on PS2 m_txdSlot = CTxdStore::AddTxdSlot("skin"); CTxdStore::Create(m_txdSlot); CTxdStore::AddRef(m_txdSlot); @@ -83,6 +83,7 @@ CPlayerSkin::Initialise(void) void CPlayerSkin::Shutdown(void) { + // empty on PS2 CTxdStore::RemoveTxdSlot(m_txdSlot); } diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp index b09b07bd..3e73c57f 100644 --- a/src/render/PointLights.cpp +++ b/src/render/PointLights.cpp @@ -11,8 +11,6 @@ #include "Timer.h" #include "PointLights.h" -//--MIAMI: file done - int16 CPointLights::NumLights; CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS]; CVector CPointLights::aCachedMapReads[32]; @@ -239,7 +237,7 @@ CPointLights::RenderFogEffect(void) // more intensity the closer to line intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH); - if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)) { float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000; float size = FogSizes[r>>1]; CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, @@ -287,7 +285,7 @@ CPointLights::RenderFogEffect(void) intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS); CVector fogcoors(xi, yi, groundZ + 1.6f); - if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)) { float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000; float size = FogSizes[r>>1]; CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f8dbed1e..8c4714fb 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1,4 +1,4 @@ -#define WITH_D3D +#define WITHD3D #include "common.h" #include "main.h" @@ -24,9 +24,10 @@ #include "Occlusion.h" #include "Renderer.h" #include "custompipes.h" +#include "Frontend.h" -//--MIAMI: file done - +bool gbShowPedRoadGroups; +bool gbShowCarRoadGroups; bool gbShowCollisionPolys; bool gbShowCollisionLines; bool gbBigWhiteDebugLightSwitchedOn; @@ -37,6 +38,10 @@ bool gbDontRenderPeds; bool gbDontRenderObjects; bool gbDontRenderVehicles; +// unused +int16 TestCloseThings; +int16 TestBigThings; + struct EntityInfo { CEntity *ent; @@ -61,14 +66,10 @@ CVehicle *CRenderer::m_pFirstPersonVehicle; bool CRenderer::m_loadingPriority; float CRenderer::ms_lodDistScale = 1.2f; -#ifdef FIX_BUGS -#define LOD_DISTANCE (300.0f*TheCamera.LODDistMultiplier) -#else -#define LOD_DISTANCE 300.0f -#endif -#define FADE_DISTANCE 20.0f -#define STREAM_DISTANCE 30.0f - +// unused +BlockedRange CRenderer::aBlockedRanges[16]; +BlockedRange* CRenderer::pFullBlockedRanges; +BlockedRange* CRenderer::pEmptyBlockedRanges; void CRenderer::Init(void) @@ -344,379 +345,46 @@ enum { PASS_BLEND // normal blend }; -static RwRGBAReal black; - -#ifdef RW_D3D9 -struct BuildingInst -{ - rw::RawMatrix combinedMat; - rw::d3d9::InstanceDataHeader *instHeader; - uint8 fadeAlpha; - bool lighting; -}; -static BuildingInst blendInsts[3][2000]; -static int numBlendInsts[3]; - static void SetStencilState(int state) { switch(state){ // disable stencil case 0: - rw::d3d::setRenderState(D3DRS_STENCILENABLE, FALSE); + rw::SetRenderState(rw::STENCILENABLE, FALSE); break; // test against stencil case 1: - rw::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE); - rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL); - rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - rw::d3d::setRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - rw::d3d::setRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - rw::d3d::setRenderState(D3DRS_STENCILMASK, 0xFF); - rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF); + rw::SetRenderState(rw::STENCILENABLE, TRUE); + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILNOTEQUAL); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP); + rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFF); + rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF); break; // write to stencil case 2: - rw::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE); - rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); - rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF); + rw::SetRenderState(rw::STENCILENABLE, TRUE); + rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS); + rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE); + rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF); break; } } -static void -SetMatrix(BuildingInst *building, rw::Matrix *worldMat) -{ - using namespace rw; - RawMatrix world, worldview; - Camera *cam = engine->currentCamera; - convMatrix(&world, worldMat); - RawMatrix::mult(&worldview, &world, &cam->devView); - RawMatrix::mult(&building->combinedMat, &worldview, &cam->devProj); -} - -static bool -IsTextureTransparent(RwTexture *tex) -{ - if(tex == nil || tex->raster == nil) - return false; - return PLUGINOFFSET(rw::d3d::D3dRaster, tex->raster, rw::d3d::nativeRasterOffset)->hasAlpha; -} - -// Render all opaque meshes and put atomics that needs blending -// into the deferred list. -static void -AtomicFirstPass(RpAtomic *atomic, int pass) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_D3D9); - building->fadeAlpha = 255; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - - bool setupDone = false; - bool defer = false; - SetMatrix(building, atomic->getFrame()->getLTM()); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ - Material *m = inst->material; - - if(inst->vertexAlpha || m->color.alpha != 255 || - IsTextureTransparent(m->texture)){ - defer = true; - continue; - } - - // alright we're rendering this atomic - if(!setupDone){ - setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); - setIndices(building->instHeader->indexBuffer); - setVertexDeclaration(building->instHeader->vertexDeclaration); - setVertexShader(default_amb_VS); - d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); - if(building->lighting) - setAmbient(pAmbient->color); - else - setAmbient(black); - setupDone = true; - } - - setMaterial(m->color, m->surfaceProps); - - if(m->texture){ - d3d::setTexture(0, m->texture); - setPixelShader(default_tex_PS); - }else - setPixelShader(default_PS); - - drawInst(building->instHeader, inst); - } - if(defer) - numBlendInsts[pass]++; -} - -static void -AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_D3D9); - building->fadeAlpha = fadeAlpha; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - SetMatrix(building, atomic->getFrame()->getLTM()); - numBlendInsts[pass]++; -} - -static void -RenderBlendPass(int pass) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - setVertexShader(default_amb_VS); - - int i; - for(i = 0; i < numBlendInsts[pass]; i++){ - BuildingInst *building = &blendInsts[pass][i]; - - setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); - setIndices(building->instHeader->indexBuffer); - setVertexDeclaration(building->instHeader->vertexDeclaration); - d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); - if(building->lighting) - setAmbient(pAmbient->color); - else - setAmbient(black); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ - Material *m = inst->material; - if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) - continue; // already done this one - - rw::RGBA color = m->color; - color.alpha = (color.alpha * building->fadeAlpha)/255; - setMaterial(color, m->surfaceProps); - - if(m->texture){ - d3d::setTexture(0, m->texture); - setPixelShader(default_tex_PS); - }else - setPixelShader(default_PS); - - drawInst(building->instHeader, inst); - } - } -} -#endif -#ifdef RW_GL3 -struct BuildingInst -{ - rw::Matrix matrix; - rw::gl3::InstanceDataHeader *instHeader; - uint8 fadeAlpha; - bool lighting; -}; -static BuildingInst blendInsts[3][2000]; -static int numBlendInsts[3]; - -static void -SetStencilState(int state) -{ - switch(state){ - // disable stencil - case 0: - glDisable(GL_STENCIL_TEST); - break; - // test against stencil - case 1: - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_NOTEQUAL, 0xFF, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilMask(0xFF); - break; - // write to stencil - case 2: - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - break; - } -} - -static bool -IsTextureTransparent(RwTexture *tex) -{ - if(tex == nil || tex->raster == nil) - return false; - return PLUGINOFFSET(rw::gl3::Gl3Raster, tex->raster, rw::gl3::nativeRasterOffset)->hasAlpha; -} - -// Render all opaque meshes and put atomics that needs blending -// into the deferred list. -static void -AtomicFirstPass(RpAtomic *atomic, int pass) -{ - using namespace rw; - using namespace rw::gl3; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_GL3); - building->fadeAlpha = 255; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - - WorldLights lights; - lights.numAmbients = 1; - lights.numDirectionals = 0; - lights.numLocals = 0; - if(building->lighting) - lights.ambient = pAmbient->color; - else - lights.ambient = black; - - bool setupDone = false; - bool defer = false; - building->matrix = *atomic->getFrame()->getLTM(); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ - Material *m = inst->material; - - if(inst->vertexAlpha || m->color.alpha != 255 || - IsTextureTransparent(m->texture)){ - defer = true; - continue; - } - - // alright we're rendering this atomic - if(!setupDone){ - defaultShader->use(); - setWorldMatrix(&building->matrix); -#ifdef RW_GL_USE_VAOS - glBindVertexArray(building->instHeader->vao); -#else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); - glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); - setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - setLights(&lights); - setupDone = true; - } - - setMaterial(m->color, m->surfaceProps); - - setTexture(0, m->texture); - - drawInst(building->instHeader, inst); - } -#ifndef RW_GL_USE_VAOS - disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - if(defer) - numBlendInsts[pass]++; -} - -static void -AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) -{ - using namespace rw; - using namespace rw::gl3; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_GL3); - building->fadeAlpha = fadeAlpha; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - building->matrix = *atomic->getFrame()->getLTM(); - numBlendInsts[pass]++; -} - -static void -RenderBlendPass(int pass) -{ - using namespace rw; - using namespace rw::gl3; - - defaultShader->use(); - WorldLights lights; - lights.numAmbients = 1; - lights.numDirectionals = 0; - lights.numLocals = 0; - - int i; - for(i = 0; i < numBlendInsts[pass]; i++){ - BuildingInst *building = &blendInsts[pass][i]; - -#ifdef RW_GL_USE_VAOS - glBindVertexArray(building->instHeader->vao); -#else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); - glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); - setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - setWorldMatrix(&building->matrix); - if(building->lighting) - lights.ambient = pAmbient->color; - else - lights.ambient = black; - setLights(&lights); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ - Material *m = inst->material; - if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) - continue; // already done this one - - rw::RGBA color = m->color; - color.alpha = (color.alpha * building->fadeAlpha)/255; - setMaterial(color, m->surfaceProps); - - setTexture(0, m->texture); - - drawInst(building->instHeader, inst); - } -#ifndef RW_GL_USE_VAOS - disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - } -} -#endif - void CRenderer::RenderOneBuilding(CEntity *ent, float camdist) { if(ent->m_rwObject == nil) return; + + ent->bImBeingRendered = true; // TODO: this seems wrong, but do we even need it? + assert(RwObjectGetType(ent->m_rwObject) == rpATOMIC); RpAtomic *atomic = (RpAtomic*)ent->m_rwObject; CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->GetModelIndex()); - ent->bImBeingRendered = true; // TODO: this seems wrong, but do we even need it? - int pass = PASS_BLEND; if(mi->m_additive) // very questionable pass = PASS_ADD; @@ -735,16 +403,16 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist) alpha = mi->m_alpha * fadefactor; if(alpha == 255) - AtomicFirstPass(atomic, pass); + WorldRender::AtomicFirstPass(atomic, pass); else{ // not quite sure what this is about, do we have to do that? RpGeometry *geo = RpAtomicGetGeometry(lodatm); if(geo != RpAtomicGetGeometry(atomic)) RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); - AtomicFullyTransparent(atomic, pass, alpha); + WorldRender::AtomicFullyTransparent(atomic, pass, alpha); } }else - AtomicFirstPass(atomic, pass); + WorldRender::AtomicFirstPass(atomic, pass); ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it? } @@ -799,16 +467,16 @@ CRenderer::RenderWorld(int pass) RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); - RenderBlendPass(PASS_NOZ); + WorldRender::RenderBlendPass(PASS_NOZ); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); break; case 2: // Transparent RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RenderBlendPass(PASS_ADD); + WorldRender::RenderBlendPass(PASS_ADD); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RenderBlendPass(PASS_BLEND); + WorldRender::RenderBlendPass(PASS_BLEND); break; } } @@ -892,9 +560,9 @@ CRenderer::ClearForFrame(void) ms_nNoOfInVisibleEntities = 0; gSortedVehiclesAndPeds.Clear(); - numBlendInsts[PASS_NOZ] = 0; - numBlendInsts[PASS_ADD] = 0; - numBlendInsts[PASS_BLEND] = 0; + WorldRender::numBlendInsts[PASS_NOZ] = 0; + WorldRender::numBlendInsts[PASS_ADD] = 0; + WorldRender::numBlendInsts[PASS_BLEND] = 0; } #endif @@ -1253,7 +921,21 @@ CRenderer::ConstructRenderList(void) ms_nNoOfInVisibleEntities = 0; } ms_vecCameraPosition = TheCamera.GetPosition(); - // TODO: blocked ranges, but unused + + // unused + pFullBlockedRanges = nil; + pEmptyBlockedRanges = aBlockedRanges; + for(int i = 0; i < 16; i++){ + aBlockedRanges[i].prev = &aBlockedRanges[i-1]; + aBlockedRanges[i].next = &aBlockedRanges[i+1]; + } + aBlockedRanges[0].prev = nil; + aBlockedRanges[15].next = nil; + + // unused + TestCloseThings = 0; + TestBigThings = 0; + ScanWorld(); } @@ -1333,7 +1015,7 @@ CRenderer::ScanWorld(void) vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix); + RwV3dTransformPoints(vectors, vectors, 9, cammatrix); m_loadingPriority = false; if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || @@ -1403,8 +1085,19 @@ CRenderer::ScanWorld(void) poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y); ScanSectorPoly(poly, 3, ScanSectorList); } - - ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); + +#ifdef NO_ISLAND_LOADING + if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_BEACH)); + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_MAINLAND)); + } else +#endif + { +#ifdef FIX_BUGS + if(CCollision::ms_collisionInMemory != LEVEL_GENERIC) +#endif + ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); + } ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); } } @@ -1453,7 +1146,7 @@ CRenderer::RequestObjectsInFrustum(void) vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix); + RwV3dTransformPoints(vectors, vectors, 9, cammatrix); if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || #ifdef FIX_BUGS @@ -1492,7 +1185,17 @@ CRenderer::RequestObjectsInFrustum(void) } } -// --MIAMI: Done +bool +CEntity::SetupLighting(void) +{ + return false; +} + +void +CEntity::RemoveLighting(bool) +{ +} + bool CPed::SetupLighting(void) { @@ -1518,7 +1221,6 @@ CPed::SetupLighting(void) return false; } -// --MIAMI: Done void CPed::RemoveLighting(bool reset) { diff --git a/src/render/Renderer.h b/src/render/Renderer.h index b579bb4c..9b202098 100644 --- a/src/render/Renderer.h +++ b/src/render/Renderer.h @@ -2,6 +2,16 @@ class CEntity; +#ifdef FIX_BUGS +#define LOD_DISTANCE (300.0f*TheCamera.LODDistMultiplier) +#else +#define LOD_DISTANCE 300.0f +#endif +#define FADE_DISTANCE 20.0f +#define STREAM_DISTANCE 30.0f + +extern bool gbShowPedRoadGroups; +extern bool gbShowCarRoadGroups; extern bool gbShowCollisionPolys; extern bool gbShowCollisionLines; extern bool gbBigWhiteDebugLightSwitchedOn; @@ -15,6 +25,13 @@ extern bool gbDontRenderVehicles; class CVehicle; class CPtrList; +// unused +struct BlockedRange +{ + float a, b; // unknown + BlockedRange *prev, *next; +}; + class CRenderer { static int32 ms_nNoOfVisibleEntities; @@ -32,6 +49,10 @@ class CRenderer static CVector ms_vecCameraPosition; static CVehicle *m_pFirstPersonVehicle; + // unused + static BlockedRange aBlockedRanges[16]; + static BlockedRange *pFullBlockedRanges; + static BlockedRange *pEmptyBlockedRanges; public: static float ms_lodDistScale; static bool m_loadingPriority; diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp index dada2439..bd69f875 100644 --- a/src/render/Rubbish.cpp +++ b/src/render/Rubbish.cpp @@ -13,8 +13,6 @@ #include "RenderBuffer.h" #include "Rubbish.h" -//--MIAMI: file done - #define RUBBISH_MAX_DIST (23.0f) #define RUBBISH_FADE_DIST (20.0f) diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp index a964ceb6..2b1df555 100644 --- a/src/render/Shadows.cpp +++ b/src/render/Shadows.cpp @@ -25,6 +25,7 @@ #include "CutsceneObject.h" #include "CutsceneShadow.h" #include "Clock.h" +#include "VarConsole.h" #ifdef DEBUGMENU SETTWEAKPATH("Shadows"); @@ -57,6 +58,9 @@ CStaticShadow CShadows::aStaticShadows [MAX_STATICSHADOWS]; CPolyBunch *CShadows::pEmptyBunchList; CPermanentShadow CShadows::aPermanentShadows[MAX_PERMAMENTSHADOWS]; +#ifndef MASTER +bool gbCountPolysInShadow; +#endif void CShadows::Init(void) @@ -154,6 +158,10 @@ CShadows::Init(void) { aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; } + +#ifndef MASTER + VarConsole.Add("Count polys in shadow", &gbCountPolysInShadow, true); +#endif } void @@ -2229,7 +2237,7 @@ CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn, sphere.Set(2.0f, center); RwV3d point; - RwV3dTransformPoints(&point, center, 1, &invMatrix); + RwV3dTransformPoints(&point, ¢er, 1, &invMatrix); CColSphere colSphere; colSphere.Set(2.0f, CVector(point), 0, 0); @@ -2252,7 +2260,7 @@ CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn, p[1] += offset; p[2] += offset; - if ( !ShadowRenderTriangleCB((RwV3d *)p, n, &proj) ) + if ( !ShadowRenderTriangleCB(p, &n, &proj) ) break; } i++; diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp index 0251878a..07039c17 100644 --- a/src/render/Skidmarks.cpp +++ b/src/render/Skidmarks.cpp @@ -6,8 +6,6 @@ #include "Replay.h" #include "Skidmarks.h" -//--MIAMI: file done - CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS]; RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6]; diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 665a41ab..35b0b2fc 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -186,7 +186,7 @@ CSpecialFX::Render2DFXs(void) CFont::SetCentreOff(); CFont::SetPropOn(); CFont::SetColor(CRGBA(0, 255, 0, 200)); - FONT_LOCALE(FONT_STANDARD); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63 AsciiToUnicode(gString, gUString); CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); @@ -211,7 +211,7 @@ CSpecialFX::Render2DFXs(void) CFont::SetCentreOff(); CFont::SetPropOn(); CFont::SetColor(CRGBA(100, 100, 100, 200)); - FONT_LOCALE(FONT_STANDARD); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); @@ -645,8 +645,6 @@ MarkerAtomicCB(RpAtomic *atomic, void *data) return atomic; } -// --MIAMI: C3dMarker and C3dMarkers done - bool C3dMarker::AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate) { @@ -849,7 +847,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else { + } else if (type == MARKERTYPE_CYLINDER) { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -862,10 +860,16 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod); pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin; - if (type == MARKERTYPE_ARROW) + if (type == MARKERTYPE_ARROW) { pos.z += 0.25f * pMarker->m_fStdSize * someSin; + } else if (type == MARKERTYPE_0) { + if (someSin > 0.0f) + pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a; + else + pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a; + } if (pMarker->m_nRotateRate != 0) { - RwV3d pos = pMarker->m_Matrix.m_matrix.pos; + CVector pos = pMarker->m_Matrix.GetPosition(); pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep())); pMarker->m_Matrix.GetPosition() = pos; } @@ -888,7 +892,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->DeleteMarkerObject(); pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); - if (type == MARKERTYPE_CYLINDER) { + if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) { if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) @@ -899,6 +903,10 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } } pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z); + if (type == MARKERTYPE_2) { + pMarker->m_Matrix.RotateX(PI); + pMarker->m_Matrix.GetPosition() = pos; + } pMarker->m_Matrix.UpdateRW(); if (type == MARKERTYPE_ARROW) { if (dist < 25.0f) { @@ -909,7 +917,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else { + } else if (type == MARKERTYPE_CYLINDER) { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -1347,13 +1355,18 @@ CMoneyMessage::Render() RwV3d vecOut; float fDistX, fDistY; if (CSprite::CalcScreenCoors(m_vecPosition + CVector(0.0f, 0.0f, fLifeTime), &vecOut, &fDistX, &fDistY, true)) { - fDistX *= (0.7 * fLifeTime + 2.0) * m_fSize; - fDistY *= (0.7 * fLifeTime + 2.0) * m_fSize; + fDistX *= (0.7f * fLifeTime + 2.0f) * m_fSize; + fDistY *= (0.7f * fLifeTime + 2.0f) * m_fSize; CFont::SetPropOn(); CFont::SetBackgroundOff(); float fScaleY = Min(fDistY / 100.0f, MAX_SCALE); float fScaleX = Min(fDistX / 100.0f, MAX_SCALE); - CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here? + +#ifdef FIX_BUGS + CFont::SetScale(SCREEN_SCALE_X(fScaleX), SCREEN_SCALE_Y(fScaleY)); +#else + CFont::SetScale(fScaleX, fScaleY); +#endif CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetJustifyOff(); @@ -1384,21 +1397,25 @@ CMoneyMessages::Render() void CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity) { - uint32 nIndex = 0; - while (aMoneyMessages[nIndex].m_nTimeRegistered != 0) { - if (++nIndex >= NUMMONEYMESSAGES) return; - } - - // Add data of this money message to the array - AsciiToUnicode(pText, aMoneyMessages[nIndex].m_aText); + uint32 i; +#ifdef FIX_BUGS + for(i = 0; i < NUMMONEYMESSAGES && aMoneyMessages[i].m_nTimeRegistered != 0; i++); +#else + for(i = 0; aMoneyMessages[i].m_nTimeRegistered != 0 && i < NUMMONEYMESSAGES; i++); +#endif - aMoneyMessages[nIndex].m_nTimeRegistered = CTimer::GetTimeInMilliseconds(); - aMoneyMessages[nIndex].m_vecPosition = vecPos; - aMoneyMessages[nIndex].m_Colour.red = bRed; - aMoneyMessages[nIndex].m_Colour.green = bGreen; - aMoneyMessages[nIndex].m_Colour.blue = bBlue; - aMoneyMessages[nIndex].m_fSize = fSize; - aMoneyMessages[nIndex].m_fOpacity = fOpacity; + if(i < NUMMONEYMESSAGES) { + // Add data of this money message to the array + AsciiToUnicode(pText, aMoneyMessages[i].m_aText); + + aMoneyMessages[i].m_nTimeRegistered = CTimer::GetTimeInMilliseconds(); + aMoneyMessages[i].m_vecPosition = vecPos; + aMoneyMessages[i].m_Colour.red = bRed; + aMoneyMessages[i].m_Colour.green = bGreen; + aMoneyMessages[i].m_Colour.blue = bBlue; + aMoneyMessages[i].m_fSize = fSize; + aMoneyMessages[i].m_fOpacity = fOpacity; + } } CRGBA FoamColour(255, 255, 255, 255); diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp index 401eebd0..ba6ab291 100644 --- a/src/render/Sprite.cpp +++ b/src/render/Sprite.cpp @@ -33,7 +33,11 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh, // this is used to scale correctly if you zoom in with sniper rifle float fovScale = fov / CDraw::GetFOV(); +#ifdef FIX_SPRITES + *outw = CDraw::ms_bFixSprites ? (fovScale * recip * SCREEN_HEIGHT) : (fovScale * SCREEN_SCALE_AR(recip) * SCREEN_WIDTH); +#else *outw = fovScale * SCREEN_SCALE_AR(recip) * SCREEN_WIDTH; +#endif *outh = fovScale * recip * SCREEN_HEIGHT; return true; diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp index 0cd0e8bb..92f326f8 100644 --- a/src/render/Sprite2d.cpp +++ b/src/render/Sprite2d.cpp @@ -277,7 +277,11 @@ CSprite2d::SetMaskVertices(int n, float *positions) RwIm2DVertexSetScreenZ(&maVertices[i], NearScreenZ); RwIm2DVertexSetCameraZ(&maVertices[i], NearCamZ); RwIm2DVertexSetRecipCameraZ(&maVertices[i], RecipNearClip); - RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC +#if !defined(GTA_PS2_STUFF) && defined(RWLIBS) + RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0); +#else + RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); +#endif } } diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp index b20a2443..95d9fe3c 100644 --- a/src/render/Timecycle.cpp +++ b/src/render/Timecycle.cpp @@ -10,8 +10,6 @@ #include "FileMgr.h" #include "Timecycle.h" -//--MIAMI: done - uint8 CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS]; uint8 CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS]; uint8 CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS]; @@ -172,8 +170,9 @@ CTimeCycle::Initialise(void) for(w = 0; w < NUMWEATHERS; w++) for(h = 0; h < NUMHOURS; h++){ li = 0; - while(work_buff[bi] == '/'){ - while(work_buff[bi] != '\n') + while(work_buff[bi] == '/' || work_buff[bi] == '\n' || + work_buff[bi] == '\0' || work_buff[bi] == ' ' || work_buff[bi] == '\r'){ + while(work_buff[bi] != '\n' && work_buff[bi] != '\0' && work_buff[bi] != '\r') bi++; bi++; } diff --git a/src/render/VarConsole.cpp b/src/render/VarConsole.cpp new file mode 100644 index 00000000..372a091a --- /dev/null +++ b/src/render/VarConsole.cpp @@ -0,0 +1,786 @@ +#include "common.h" +#include "VarConsole.h" +#include "Font.h" +#include "Pad.h" + +#define VAR_CONSOLE_PAD 1 + +CVarConsole VarConsole; + +void +CVarConsole::Initialise() +{ + m_nCountEntries = 0; + m_nCurPage = 1; + m_bIsOpen = false; + m_nCurEntry = 0; + m_nFirstEntryOnPage = 0; +} + +void +CVarConsole::Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT8; + m_aEntries[i].I8_step = step; + m_aEntries[i].I8_min = min; + m_aEntries[i].I8_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT16; + m_aEntries[i].I16_step = step; + m_aEntries[i].I16_min = min; + m_aEntries[i].I16_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT32; + m_aEntries[i].I32_step = step; + m_aEntries[i].I32_min = min; + m_aEntries[i].I32_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt64Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT64; + m_aEntries[i].I64_step = step; + m_aEntries[i].I64_min = min; + m_aEntries[i].I64_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT8; + m_aEntries[i].I8_step = step; + m_aEntries[i].I8_min = min; + m_aEntries[i].I8_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT16; + m_aEntries[i].I16_step = step; + m_aEntries[i].I16_min = min; + m_aEntries[i].I16_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT32; + m_aEntries[i].I32_step = step; + m_aEntries[i].I32_min = min; + m_aEntries[i].I32_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint64Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT64; + m_aEntries[i].I64_step = step; + m_aEntries[i].I64_min = min; + m_aEntries[i].I64_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, float *pVal, float step, float min, float max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pFloatValue = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_FLOAT; + m_aEntries[i].F_step = step; + m_aEntries[i].F_min = min; + m_aEntries[i].F_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pBoolValue = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool8 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL8; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool16 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL16; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool32 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL32; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, void (*pCallback)(void)) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pCallback = pCallback; + m_aEntries[i].VarType = VCE_TYPE_FUNCTION; + m_nCountEntries++; +} + +void +CVarConsole::Remove(char *text) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + { + for (int j = i; j < m_nCountEntries-1; j++) + m_aEntries[j] = m_aEntries[j+1]; + m_nCountEntries--; + return; + } + } +} + +void +CVarConsole::SortPages() +{ + m_nNumPages = m_nCountEntries / 30 + 1; +} + +void +CVarConsole::Display() +{ + char s[256]; + wchar ws[256]; + + CFont::SetColor(CRGBA(200, 200, 200, 255)); + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.6f)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetPropOn(); + CFont::SetWrapx(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetRightJustifyWrap(0.0f); + sprintf(s, "PAGE %d", m_nCurPage); + AsciiToUnicode(s, ws); + CFont::SetRightJustifyOn(); + CFont::PrintString(SCREEN_SCALE_X(310.0f), SCREEN_SCALE_Y(30.0f), ws); + CFont::SetRightJustifyOff(); + int y = 45; + for (int i = m_nFirstEntryOnPage; i < m_nCountEntries && i < m_nFirstEntryOnPage + 30; i++) + { + switch (m_aEntries[i].VarType) + { + case VCE_TYPE_INT8: + sprintf(s, "(%d) %s:I8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt8Value); + break; + case VCE_TYPE_INT16: + sprintf(s, "(%d) %s:I16:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt16Value); + break; + case VCE_TYPE_INT32: + sprintf(s, "(%d) %s:I32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt32Value); + break; + case VCE_TYPE_INT64: +#ifdef FIX_BUGS + sprintf(s, "(%d) %s:I64:%lld", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt64Value); +#else + sprintf(s, "(%d) %s:I64:%d", i + 1, m_aEntries[i].text, (int32)*m_aEntries[i].pInt64Value); +#endif + break; + case VCE_TYPE_UINT8: + sprintf(s, "(%d) %s:U8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint8Value); + break; + case VCE_TYPE_UINT16: + sprintf(s, "(%d) %s:U6:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint16Value); + break; + case VCE_TYPE_UINT32: + sprintf(s, "(%d) %s:U32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint32Value); + break; + case VCE_TYPE_UINT64: +#ifdef FIX_BUGS + sprintf(s, "(%d) %s:U64:%llu", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint64Value); +#else + sprintf(s, "(%d) %s:U64:%d", i + 1, m_aEntries[i].text, (uint32)*m_aEntries[i].pUint64Value); +#endif + break; + case VCE_TYPE_FLOAT: + sprintf(s, "(%d) %s:F:%f", i + 1, m_aEntries[i].text, *m_aEntries[i].pFloatValue); + break; + case VCE_TYPE_BOOL: + if (*m_aEntries[i].pBoolValue) + sprintf(s, "(%d) %s:B:TRUE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B : FALSE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL8: + if (*m_aEntries[i].pUint8Value == FALSE) + sprintf(s, "(%d) %s:B8:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B8:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL16: + if (*m_aEntries[i].pUint16Value == FALSE) + sprintf(s, "(%d) %s:B16:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B16:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL32: + if (*m_aEntries[i].pUint32Value == FALSE) + sprintf(s, "(%d) %s:B32:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B32:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_FUNCTION: + sprintf(s, "(%d) %s:FUNCTION:call this function?", i + 1, m_aEntries[i].text); + break; + } + AsciiToUnicode(s, ws); + if (m_nCurEntry == i) { + CFont::SetBackgroundOn(); +#ifdef FIX_BUGS + CFont::SetBackgroundColor(CRGBA(128, 128, 128, 128)); +#endif + } +#ifdef FIX_BUGS + else + CFont::SetBackgroundColor(CRGBA(128, 128, 128, 0)); +#endif + + CFont::SetColor(CRGBA(200, 200, 200, 255)); + CFont::PrintString(SCREEN_SCALE_X(30.0f), SCREEN_SCALE_Y(y), ws); + if (m_nCurEntry == i) + CFont::SetBackgroundOff(); + y += 12; + } +} + +void +CVarConsole::ModifyLeft() +{ + CVarConsoleEntry &entry = m_aEntries[m_nCurEntry]; + switch (entry.VarType) + { + case VCE_TYPE_INT8: + *entry.pInt8Value -= entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt8Value < entry.I8_min) + *entry.pInt8Value = entry.I8_max; + } else { + if (*entry.pInt8Value < entry.I8_min) + *entry.pInt8Value = entry.I8_min; + } + break; + case VCE_TYPE_INT16: + *entry.pInt16Value -= entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt16Value < entry.I16_min) + *entry.pInt16Value = entry.I16_max; + } + else { + if (*entry.pInt16Value < entry.I16_min) + *entry.pInt16Value = entry.I16_min; + } + break; + case VCE_TYPE_INT32: + *entry.pInt32Value -= entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt32Value < entry.I32_min) + *entry.pInt32Value = entry.I32_max; + } + else { + if (*entry.pInt32Value < entry.I32_min) + *entry.pInt32Value = entry.I32_min; + } + break; + case VCE_TYPE_INT64: + *entry.pInt64Value -= entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt64Value < entry.I64_min) + *entry.pInt64Value = entry.I64_max; + } + else { + if (*entry.pInt64Value < entry.I64_min) + *entry.pInt64Value = entry.I64_min; + } + break; + case VCE_TYPE_UINT8: + *entry.pUint8Value -= entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*(int8*)entry.pUint8Value < entry.I8_min) + *entry.pUint8Value = entry.I8_max; + } + else { + if (*(int8*)entry.pUint8Value < entry.I8_min) + *entry.pUint8Value = entry.I8_min; + } + break; + case VCE_TYPE_UINT16: + *entry.pUint16Value -= entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*(int16*)entry.pUint16Value < entry.I16_min) + *entry.pUint16Value = entry.I16_max; + } + else { + if (*(int16*)entry.pUint16Value < entry.I16_min) + *entry.pUint16Value = entry.I16_min; + } + break; + case VCE_TYPE_UINT32: + *entry.pUint32Value -= entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*(int32*)entry.pUint32Value < entry.I32_min) + *entry.pUint32Value = entry.I32_max; + } + else { + if (*(int32*)entry.pUint32Value < entry.I32_min) + *entry.pUint32Value = entry.I32_min; + } + break; + case VCE_TYPE_UINT64: + *entry.pUint64Value -= entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*(int64*)entry.pUint64Value < entry.I64_min) + *entry.pUint64Value = entry.I64_max; + } + else { + if (*(int64*)entry.pUint64Value < entry.I64_min) + *entry.pUint64Value = entry.I64_min; + } + break; + case VCE_TYPE_FLOAT: + *entry.pFloatValue -= entry.F_step; + if (entry.bAllowExceedBounds) { + if (*entry.pFloatValue < entry.F_min) + *entry.pFloatValue = entry.F_max; + } + else { + if (*entry.pFloatValue < entry.F_min) + *entry.pFloatValue = entry.F_min; + } + break; + case VCE_TYPE_BOOL: + if (entry.bAllowExceedBounds) + *entry.pBoolValue ^= true; + else + *entry.pBoolValue = false; + break; + case VCE_TYPE_BOOL8: + if (entry.bAllowExceedBounds) + *entry.pUint8Value = *entry.pUint8Value == false; + else + *entry.pUint8Value = false; + break; + case VCE_TYPE_BOOL16: + if (entry.bAllowExceedBounds) + *entry.pUint16Value = *entry.pUint16Value == false; + else + *entry.pUint16Value = false; + break; + case VCE_TYPE_BOOL32: + if (entry.bAllowExceedBounds) + *entry.pUint32Value = *entry.pUint32Value == false; + else + *entry.pUint32Value = false; + break; + case VCE_TYPE_FUNCTION: + entry.pCallback(); + break; + default: + return; + } +} + +void +CVarConsole::ModifyRight() +{ + CVarConsoleEntry &entry = m_aEntries[m_nCurEntry]; + switch (entry.VarType) + { + case VCE_TYPE_INT8: + *entry.pInt8Value += entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt8Value > entry.I8_max) + *entry.pInt8Value = entry.I8_min; + } + else { + if (*entry.pInt8Value > entry.I8_max) + *entry.pInt8Value = entry.I8_max; + } + break; + case VCE_TYPE_INT16: + *entry.pInt16Value += entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt16Value > entry.I16_max) + *entry.pInt16Value = entry.I16_min; + } + else { + if (*entry.pInt16Value > entry.I16_max) + *entry.pInt16Value = entry.I16_max; + } + break; + case VCE_TYPE_INT32: + *entry.pInt32Value += entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt32Value > entry.I32_max) + *entry.pInt32Value = entry.I32_min; + } + else { + if (*entry.pInt32Value > entry.I32_max) + *entry.pInt32Value = entry.I32_max; + } + break; + case VCE_TYPE_INT64: + *entry.pInt64Value += entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt64Value > entry.I64_max) + *entry.pInt64Value = entry.I64_min; + } + else { + if (*entry.pInt64Value > entry.I64_max) + *entry.pInt64Value = entry.I64_max; + } + break; + case VCE_TYPE_UINT8: + *entry.pUint8Value += entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint8Value > (uint8)entry.I8_max) + *entry.pUint8Value = entry.I8_min; + } + else { + if (*entry.pUint8Value > (uint8)entry.I8_max) + *entry.pUint8Value = entry.I8_max; + } + break; + case VCE_TYPE_UINT16: + *entry.pUint16Value += entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint16Value > (uint16)entry.I16_max) + *entry.pUint16Value = entry.I16_min; + } + else { + if (*entry.pUint16Value > (uint16)entry.I16_max) + *entry.pUint16Value = entry.I16_max; + } + break; + case VCE_TYPE_UINT32: + *entry.pUint32Value += entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint32Value > (uint32)entry.I32_max) + *entry.pUint32Value = entry.I32_min; + } + else { + if (*entry.pUint32Value > (uint32)entry.I32_max) + *entry.pUint32Value = entry.I32_max; + } + break; + case VCE_TYPE_UINT64: + *entry.pUint64Value += entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint64Value > (uint64)entry.I64_max) + *entry.pUint64Value = entry.I64_min; + } + else { + if (*entry.pUint64Value > (uint64)entry.I64_max) + *entry.pUint64Value = entry.I64_max; + } + break; + case VCE_TYPE_FLOAT: + *entry.pFloatValue += entry.F_step; + if (entry.bAllowExceedBounds) { + if (*entry.pFloatValue > entry.F_max) + *entry.pFloatValue = entry.F_min; + } + else { + if (*entry.pFloatValue > entry.F_max) + *entry.pFloatValue = entry.F_max; + } + break; + case VCE_TYPE_BOOL: + if (entry.bAllowExceedBounds) + *entry.pBoolValue ^= true; + else + *entry.pBoolValue = true; + break; + case VCE_TYPE_BOOL8: + if (entry.bAllowExceedBounds) + *entry.pUint8Value = *entry.pUint8Value == false; + else + *entry.pUint8Value = true; + break; + case VCE_TYPE_BOOL16: + if (entry.bAllowExceedBounds) + *entry.pUint16Value = *entry.pUint16Value == false; + else + *entry.pUint16Value = true; + break; + case VCE_TYPE_BOOL32: + if (entry.bAllowExceedBounds) + *entry.pUint32Value = *entry.pUint32Value == false; + else + *entry.pUint32Value = true; + break; + case VCE_TYPE_FUNCTION: + entry.pCallback(); + break; + default: + return; + } +} + +void +CVarConsole::Enter() +{ + m_bIsOpen = true; +} + +void +CVarConsole::Exit() +{ + m_bIsOpen = false; +} + +void +CVarConsole::Input() +{ + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadDownJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadDown()) + { + m_nCurEntry++; + if (m_nCurEntry < m_nCountEntries) + { + if (m_nCurEntry > m_nFirstEntryOnPage + 29) + { + m_nFirstEntryOnPage = m_nCurEntry; + ++m_nCurPage; + } + } + else + { + m_nCurEntry = m_nCountEntries - 1; + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadUpJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadUp()) + { + m_nCurEntry--; + if (m_nCurEntry < m_nFirstEntryOnPage) + { + m_nFirstEntryOnPage = m_nCurEntry - 29; + --m_nCurPage; + } + if (m_nFirstEntryOnPage < 0) + { + m_nCurEntry = 0; + m_nFirstEntryOnPage = 0; + m_nCurPage = 1; + } + } + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetSquare()) + ModifyLeft(); + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetTriangle()) + ModifyRight(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadLeftJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadLeft()) + ModifyLeft(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadRightJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadRight()) + ModifyRight(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder2JustDown()) + { + if (m_nCurPage > 1) + { + m_nCurPage--; + m_nFirstEntryOnPage -= 30; + m_nCurEntry = m_nFirstEntryOnPage; + if (m_nFirstEntryOnPage < 0) + { + m_nFirstEntryOnPage = 0; + m_nCurEntry = m_nFirstEntryOnPage; + m_nCurPage = 1; + } + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder2JustDown()) + { + if (m_nCurPage < m_nNumPages) + { + m_nCurPage++; + m_nFirstEntryOnPage += 30; + m_nCurEntry = m_nFirstEntryOnPage; + if (m_nFirstEntryOnPage >= m_nCountEntries) + { + m_nFirstEntryOnPage -= 30; + m_nCurEntry = m_nFirstEntryOnPage; + m_nCurPage--; + } + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown()) + Exit(); +} + +void +CVarConsole::Process() +{ + Input(); + SortPages(); + Display(); +} + +bool8 +CVarConsole::Open() +{ + return m_bIsOpen; +} + +void +CVarConsole::Check() +{ + if (Open()) + Process(); + else if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown()) + Enter(); +}
\ No newline at end of file diff --git a/src/render/VarConsole.h b/src/render/VarConsole.h new file mode 100644 index 00000000..5179a10d --- /dev/null +++ b/src/render/VarConsole.h @@ -0,0 +1,92 @@ +#pragma once + +enum eVarConsoleEntryType +{ + VCE_TYPE_INT8, + VCE_TYPE_INT16, + VCE_TYPE_INT32, + VCE_TYPE_INT64, + VCE_TYPE_UINT8, + VCE_TYPE_UINT16, + VCE_TYPE_UINT32, + VCE_TYPE_UINT64, + VCE_TYPE_FLOAT, + VCE_TYPE_BOOL, + VCE_TYPE_BOOL8, + VCE_TYPE_BOOL16, + VCE_TYPE_BOOL32, + VCE_TYPE_FUNCTION, +}; + +struct CVarConsoleEntry +{ + char *text; + int8 *pInt8Value; + int16 *pInt16Value; + int32 *pInt32Value; + int64 *pInt64Value; + uint8 *pUint8Value; + uint16 *pUint16Value; + uint32 *pUint32Value; + uint64 *pUint64Value; + float *pFloatValue; + bool *pBoolValue; + void (*pCallback)(void); + int8 I8_step, I8_max, I8_min; + int16 I16_step, I16_max, I16_min; + int32 I32_step, I32_max, I32_min; + int64 I64_step, I64_max, I64_min; + float F_step, F_max, F_min; + bool8 bAllowExceedBounds; + uint8 VarType; +}; + + +class CVarConsole +{ + int32 m_nCountEntries; + bool8 m_bIsOpen; + int32 m_nCurEntry; + int32 m_nFirstEntryOnPage; + int32 m_nCurPage; + int32 m_nNumPages; + CVarConsoleEntry m_aEntries[91]; +public: +#ifdef FIX_BUGS + CVarConsole() { Initialise(); } +#endif + void Initialise(); + void Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar); + void Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar); + void Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar); + void Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar); + void Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar); + void Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar); + void Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar); + void Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar); + void Add(char *text, float *pVal, float step, float min, float max, bool8 isVar); + void Add(char *text, bool *pVal, bool8 isVar); + void Add(char *text, bool8 *pVal, bool8 isVar); + void Add(char *text, bool16 *pVal, bool8 isVar); + void Add(char *text, bool32 *pVal, bool8 isVar); + void Add(char *text, void (*pVar)(void)); + + void Remove(char *text); + + void SortPages(); + void Display(); + + void ModifyLeft(); + void ModifyRight(); + + void Enter(); + void Exit(); + + void Input(); + void Process(); + + bool8 Open(); + void Check(); +}; + +extern CVarConsole VarConsole;
\ No newline at end of file diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index 91304be3..53b4d30e 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -13,8 +13,6 @@ #include "Camera.h" #include "Particle.h" -// --MIAMI: file done - #define WATERCANNONVERTS 4 #define WATERCANNONINDEXES 12 diff --git a/src/render/WaterCreatures.cpp b/src/render/WaterCreatures.cpp index d3bd2701..92fb74ee 100644 --- a/src/render/WaterCreatures.cpp +++ b/src/render/WaterCreatures.cpp @@ -1,11 +1,12 @@ +#include "common.h" #include "WaterCreatures.h" #include "ModelIndices.h" #include "World.h" #include "WaterLevel.h" #include "Camera.h" #include "PlayerPed.h" -#include "config.h" #include "General.h" +#include "Object.h" int CWaterCreatures::nNumActiveSeaLifeForms; CWaterCreature CWaterCreatures::aWaterCreatures[NUM_WATER_CREATURES]; diff --git a/src/render/WaterCreatures.h b/src/render/WaterCreatures.h index 9ef8198c..32754a10 100644 --- a/src/render/WaterCreatures.h +++ b/src/render/WaterCreatures.h @@ -1,5 +1,6 @@ #pragma once -#include "Object.h" + +class CObject; enum eFishSlotState { WATER_CREATURE_INIT = 0, diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 88c45c79..08fd5e6e 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "main.h" #include "FileMgr.h" +#include "FileLoader.h" #include "TxdStore.h" #include "Timer.h" #include "Weather.h" @@ -17,6 +18,7 @@ #include "ParticleMgr.h" #include "RwHelper.h" #include "Streaming.h" +#include "ColStore.h" #include "CdStream.h" #include "Pad.h" #include "RenderBuffer.h" @@ -43,8 +45,8 @@ float _TEXTURE_WAKE_ADDV; int32 CWaterLevel::ms_nNoOfWaterLevels; float CWaterLevel::ms_aWaterZs[48]; CRect CWaterLevel::ms_aWaterRects[48]; -uint8 CWaterLevel::aWaterBlockList[WATER_BLOCK_SECTORS][WATER_BLOCK_SECTORS]; -uint8 CWaterLevel::aWaterFineBlockList[WATER_FINEBLOCK_SECTORS][WATER_FINEBLOCK_SECTORS]; +int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; +int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; bool CWaterLevel::WavesCalculatedThisFrame; @@ -56,7 +58,7 @@ int32 CWaterLevel::m_nRenderWaterLayers; RpAtomic *CWaterLevel::ms_pWavyAtomic; RpAtomic *CWaterLevel::ms_pMaskAtomic; -//"Custom" Don´t Render Water Toggle +//"Custom" Don't Render Water Toggle bool gbDontRenderWater; @@ -111,27 +113,167 @@ float fMinWaterAlphaMult = -30.0f; void -WaterLevelInitialise(Const char *pWaterDat) +CWaterLevel::Initialise(Const char *pWaterDat) { - CWaterLevel::ms_nNoOfWaterLevels = 0; - - int32 hFile; + ms_nNoOfWaterLevels = 0; +#ifdef MASTER + int32 hFile = -1; + do { hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); } while ( hFile < 0 ); +#else + int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); +#endif - if ( hFile > 0 ) + if (hFile > 0) + { + CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); + CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); + CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); + CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); + CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); + CFileMgr::CloseFile(hFile); + } +#ifndef MASTER + else { - CFileMgr::Read(hFile, (char *)&CWaterLevel::ms_nNoOfWaterLevels, sizeof(CWaterLevel::ms_nNoOfWaterLevels)); - CFileMgr::Read(hFile, (char *)CWaterLevel::ms_aWaterZs, sizeof(CWaterLevel::ms_aWaterZs)); - CFileMgr::Read(hFile, (char *)CWaterLevel::ms_aWaterRects, sizeof(CWaterLevel::ms_aWaterRects)); - CFileMgr::Read(hFile, (char *)CWaterLevel::aWaterBlockList, sizeof(CWaterLevel::aWaterBlockList)); - CFileMgr::Read(hFile, (char *)CWaterLevel::aWaterFineBlockList, sizeof(CWaterLevel::aWaterFineBlockList)); + printf("Init waterlevels\n"); + + // collision is streamed in VC + CColStore::LoadAllCollision(); + + CFileMgr::SetDir(""); + hFile = CFileMgr::OpenFile(pWaterDat, "r"); + + char *line; + + while ((line = CFileLoader::LoadLine(hFile))) + { + if (*line && *line != ';' && !strstr(line, "* ;end of file")) + { + float z, l, b, r, t; + sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t); + AddWaterLevel(l, b, r, t, z); + } + } + CFileMgr::CloseFile(hFile); + + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) + { + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) + { + aWaterFineBlockList[x][y] = NO_WATER; + } + } + + // rasterize water rects read from file + for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) + { + int32 l = WATER_HUGE_X(ms_aWaterRects[i].left + WATER_X_OFFSET); + int32 r = WATER_HUGE_X(ms_aWaterRects[i].right + WATER_X_OFFSET) + 1.0f; + int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top); + int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f; + + l = clamp(l, 0, MAX_SMALL_SECTORS - 1); + r = clamp(r, 0, MAX_SMALL_SECTORS - 1); + t = clamp(t, 0, MAX_SMALL_SECTORS - 1); + b = clamp(b, 0, MAX_SMALL_SECTORS - 1); + + for (int32 x = l; x <= r; x++) + { + for (int32 y = t; y <= b; y++) + { + aWaterFineBlockList[x][y] = i; + } + } + } + + // remove tiles that are obscured by land + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) + { + float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE - WATER_X_OFFSET; + + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) + { + if (CWaterLevel::aWaterFineBlockList[x][y] >= 0) + { + float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE; + + int32 i; + for (i = 0; i <= 8; i++) + { + for (int32 j = 0; j <= 8; j++) + { + CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]); + + if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y) && + (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos))) + continue; + + // at least one point in the tile wasn't blocked, so don't remove water + i = 1000; + break; + } + } + + if (i < 1000) + aWaterFineBlockList[x][y] = NO_WATER; + } + } + } + + RemoveIsolatedWater(); + + // calculate coarse tiles from fine tiles + for (int32 x = 0; x < MAX_LARGE_SECTORS; x++) + { + for (int32 y = 0; y < MAX_LARGE_SECTORS; y++) + { + if (aWaterFineBlockList[x * 2][y * 2] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2]; + } + else if (aWaterFineBlockList[x * 2 + 1][y * 2] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2]; + } + else if (aWaterFineBlockList[x * 2][y * 2 + 1] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2 + 1]; + } + else if (aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2 + 1]; + } + else + { + aWaterBlockList[x][y] = NO_WATER; + } + } + } + + hFile = CFileMgr::OpenFileForWriting("data\\waterpro.dat"); + + if (hFile > 0) + { + CFileMgr::Write(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); + CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); + CFileMgr::Write(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); + CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); + CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); + + CFileMgr::CloseFile(hFile); + } + + // collision is streamed in VC + CColStore::RemoveAllCollision(); } +#endif CTxdStore::PushCurrentTxd(); @@ -158,7 +300,7 @@ WaterLevelInitialise(Const char *pWaterDat) CTxdStore::PopCurrentTxd(); - CWaterLevel::CreateWavyAtomic(); + CreateWavyAtomic(); printf("Done Initing waterlevels\n"); } @@ -397,6 +539,170 @@ CWaterLevel::DestroyWavyAtomic() #undef _DELETE_ATOMIC } +#ifndef MASTER +void +CWaterLevel::AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel) +{ + ms_aWaterRects[ms_nNoOfWaterLevels] = CRect(fXLeft, fYBottom, fXRight, fYTop); + ms_aWaterZs[ms_nNoOfWaterLevels] = fLevel; + ms_nNoOfWaterLevels++; +} + +bool +CWaterLevel::WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel) +{ + if (ms_nNoOfWaterLevels <= 0) return false; + + for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) + { + if (fX >= ms_aWaterRects[i].left && fX <= ms_aWaterRects[i].right + && fY >= ms_aWaterRects[i].top && fY <= ms_aWaterRects[i].bottom) + { + if (pfOutLevel) *pfOutLevel = ms_aWaterZs[i]; + + return true; + } + } + + return false; +} + +bool +CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos) +{ + static CVector2D tab[] = + { + { 50.0f, 50.0f }, + { -50.0f, 50.0f }, + { -50.0f, -50.0f }, + { 50.0f, -50.0f }, + { 50.0f, 0.0f }, + { -50.0f, 0.0f }, + { 0.0f, -50.0f }, + { 0.0f, 50.0f }, + }; + + CEntity *entity; + CColPoint col; + CVector lineStart, lineEnd; + + lineStart = worldPos; + + if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) + { + lineStart.x += 0.4f; + lineStart.y += 0.4f; + + if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) + { + return false; + } + } + + for (int32 i = 0; i < ARRAY_SIZE(tab); i++) + { + lineStart = worldPos; + lineEnd = worldPos; + + lineEnd.x += tab[i].x; + lineEnd.y += tab[i].y; + lineEnd.z += 100.0f; + + if ((lineEnd.x > WORLD_MIN_X && lineEnd.x < WORLD_MAX_X) && (lineEnd.y > WORLD_MIN_Y && lineEnd.y < WORLD_MAX_Y)) + { + if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil)) + { + lineStart.x += 0.4f; + lineStart.y += 0.4f; + lineEnd.x += 0.4f; + lineEnd.y += 0.4f; + + if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil)) + { + return false; + } + } + } + } + + return true; +} + +void +CWaterLevel::RemoveIsolatedWater() +{ + bool (*isConnected)[MAX_SMALL_SECTORS] = new bool[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; + + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) + { + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) + { + isConnected[x][y] = false; + } + } + + isConnected[0][0] = true; + bool keepGoing; + + do + { + keepGoing = false; + + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) + { + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) + { + if (aWaterFineBlockList[x][y] < 0 || isConnected[x][y]) + continue; + + if (x > 0 && isConnected[x - 1][y]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (y > 0 && isConnected[x][y - 1]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (x + 1 < MAX_SMALL_SECTORS && isConnected[x + 1][y]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (y + 1 < MAX_SMALL_SECTORS && isConnected[x][y + 1]) + { + isConnected[x][y] = true; + keepGoing = true; + } + } + } + } + while (keepGoing); + + int32 numRemoved = 0; + + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) + { + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) + { + if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 6.0f) + { + numRemoved++; + aWaterFineBlockList[x][y] = NO_WATER; + } + } + } + + printf("Removed %d isolated patches of water\n", numRemoved); + + delete[] isConnected; +} +#endif + bool CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ) { @@ -542,38 +848,38 @@ inline bool _IsColideWithBlock(int32 x, int32 y, int32 &block) { block = CWaterLevel::aWaterFineBlockList[x + 0][y + 0]; - if (!(block & 0x80)) + if (block >= 0) return true; block = CWaterLevel::aWaterFineBlockList[x + 0][y + 1]; - if (!(block & 0x80)) + if (block >= 0) { block = CWaterLevel::aWaterFineBlockList[x + 0][y + 2]; - if (!(block & 0x80)) + if (block >= 0) return true; } block = CWaterLevel::aWaterFineBlockList[x + 1][y + 0]; - if (!(block & 0x80)) + if (block >= 0) return true; block = CWaterLevel::aWaterFineBlockList[x + 1][y + 1]; - if (!(block & 0x80)) + if (block >= 0) { block = CWaterLevel::aWaterFineBlockList[x + 1][y + 2]; - if (!(block & 0x80)) + if (block >= 0) return true; } block = CWaterLevel::aWaterFineBlockList[x + 2][y + 0]; - if (!(block & 0x80)) + if (block >= 0) return true; block = CWaterLevel::aWaterFineBlockList[x + 2][y + 1]; - if (!(block & 0x80)) + if (block >= 0) { block = CWaterLevel::aWaterFineBlockList[x + 2][y + 2]; - if (!(block & 0x80)) + if (block >= 0) return true; } @@ -589,7 +895,7 @@ SectorRadius(float fSize) void CWaterLevel::RenderWater() { -//"Custom" Don´t Render Water Toggle +//"Custom" Don't Render Water Toggle #ifndef MASTER if (gbDontRenderWater) return; @@ -693,10 +999,10 @@ CWaterLevel::RenderWater() { for ( int32 y = nStartY; y <= nEndY; y++ ) { - if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80) - || !(aWaterBlockList[2*x+1][2*y+0] & 0x80) - || !(aWaterBlockList[2*x+0][2*y+1] & 0x80) - || !(aWaterBlockList[2*x+1][2*y+1] & 0x80) ) + if ( aWaterBlockList[2*x+0][2*y+0] >= 0 + || aWaterBlockList[2*x+1][2*y+0] >= 0 + || aWaterBlockList[2*x+0][2*y+1] >= 0 + || aWaterBlockList[2*x+1][2*y+1] >= 0 ) { float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET; float fY = WATER_FROM_HUGE_SECTOR_Y(y); @@ -716,16 +1022,16 @@ CWaterLevel::RenderWater() float fZ; - if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80) ) + if ( aWaterBlockList[2*x+0][2*y+0] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ]; - if ( !(aWaterBlockList[2*x+1][2*y+0] & 0x80) ) + if ( aWaterBlockList[2*x+1][2*y+0] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ]; - if ( !(aWaterBlockList[2*x+0][2*y+1] & 0x80) ) + if ( aWaterBlockList[2*x+0][2*y+1] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ]; - if ( !(aWaterBlockList[2*x+1][2*y+1] & 0x80) ) + if ( aWaterBlockList[2*x+1][2*y+1] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ]; if ( fHugeSectorDistToCamSqr >= SQR(500.0f) ) @@ -960,10 +1266,10 @@ CWaterLevel::RenderTransparentWater(void) { for ( int32 y = nStartY; y <= nEndY; y++ ) { - if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80) - || !(aWaterBlockList[2*x+1][2*y+0] & 0x80) - || !(aWaterBlockList[2*x+0][2*y+1] & 0x80) - || !(aWaterBlockList[2*x+1][2*y+1] & 0x80) ) + if ( aWaterBlockList[2*x+0][2*y+0] >= 0 + || aWaterBlockList[2*x+1][2*y+0] >= 0 + || aWaterBlockList[2*x+0][2*y+1] >= 0 + || aWaterBlockList[2*x+1][2*y+1] >= 0 ) { float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET; float fY = WATER_FROM_HUGE_SECTOR_Y(y); @@ -991,7 +1297,7 @@ CWaterLevel::RenderTransparentWater(void) { for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ ) { - if ( !(aWaterBlockList[x2][y2] & 0x80) ) + if ( aWaterBlockList[x2][y2] >= 0 ) { float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2) - WATER_X_OFFSET; float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2); @@ -1025,7 +1331,7 @@ CWaterLevel::RenderTransparentWater(void) float fZ; // WS - if ( !(aWaterFineBlockList[2*x2+0][2*y2+0] & 0x80) ) + if ( aWaterFineBlockList[2*x2+0][2*y2+0] >= 0 ) { float fSmallX = fLargeX; float fSmallY = fLargeY; @@ -1042,7 +1348,7 @@ CWaterLevel::RenderTransparentWater(void) } // SE - if ( !(aWaterFineBlockList[2*x2+1][2*y2+0] & 0x80) ) + if ( aWaterFineBlockList[2*x2+1][2*y2+0] >= 0 ) { float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); float fSmallY = fLargeY; @@ -1059,7 +1365,7 @@ CWaterLevel::RenderTransparentWater(void) } // WN - if ( !(aWaterFineBlockList[2*x2+0][2*y2+1] & 0x80) ) + if ( aWaterFineBlockList[2*x2+0][2*y2+1] >= 0 ) { float fSmallX = fLargeX; float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); @@ -1076,7 +1382,7 @@ CWaterLevel::RenderTransparentWater(void) } //NE - if ( !(aWaterFineBlockList[2*x2+1][2*y2+1] & 0x80) ) + if ( aWaterFineBlockList[2*x2+1][2*y2+1] >= 0 ) { float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); @@ -2588,7 +2894,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY) { for ( int32 y = nStartY; y <= nEndY; y++ ) { - if ( !(aWaterFineBlockList[x][y] & 0x80) ) + if ( aWaterFineBlockList[x][y] >= 0 ) { float fSectorX = WATER_FROM_SMALL_SECTOR_X(x) - WATER_X_OFFSET; float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y); diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h index 0e682305..6d6614d8 100644 --- a/src/render/WaterLevel.h +++ b/src/render/WaterLevel.h @@ -2,10 +2,10 @@ #define WATER_X_OFFSET (400.0f) -#define WATER_BLOCK_SECTORS MAX_LARGE_SECTORS -#define WATER_FINEBLOCK_SECTORS MAX_SMALL_SECTORS #define WATER_Z_OFFSET (0.5f) +#define NO_WATER -128 + #define MAX_SMALL_SECTORS 128 #define MAX_LARGE_SECTORS 64 #define MAX_HUGE_SECTORS 32 @@ -25,7 +25,6 @@ #define WATER_WIDTH ((WATER_END_X - WATER_START_X)) #define WATER_HEIGHT ((WATER_END_Y - WATER_START_Y)) - #define WATER_UNSIGN_X(x) ( (x) + (WATER_WIDTH /2) ) #define WATER_UNSIGN_Y(y) ( (y) + (WATER_HEIGHT/2) ) #define WATER_SIGN_X(x) ( (x) - (WATER_WIDTH /2) ) @@ -38,7 +37,7 @@ // 128x128 Small blocks 32x32 each #define WATER_TO_FINEBLOCK_X(x) ( WATER_UNSIGN_X(x) / WATER_FINEBLOCK_SECTORS ) #define WATER_TO_FINEBLOCK_Y(x) ( WATER_UNSIGN_Y(x) / WATER_FINEBLOCK_SECTORS ) - + // 32 #define WATER_SMALL_X(x) ( WATER_UNSIGN_X(x) / MAX_SMALL_SECTORS ) #define WATER_SMALL_Y(y) ( WATER_UNSIGN_Y(y) / MAX_SMALL_SECTORS ) @@ -104,31 +103,36 @@ public: static int32 ms_nNoOfWaterLevels; static float ms_aWaterZs[48]; static CRect ms_aWaterRects[48]; - static uint8 aWaterBlockList[WATER_BLOCK_SECTORS][WATER_BLOCK_SECTORS]; // 64x64 Large blocks 64x64 each - static uint8 aWaterFineBlockList[WATER_FINEBLOCK_SECTORS][WATER_FINEBLOCK_SECTORS]; // 128x128 Small blocks 32x32 each + static int8 aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; // 64x64 Large blocks 64x64 each + static int8 aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; // 128x128 Small blocks 32x32 each static bool WavesCalculatedThisFrame; - + static bool RequireWavySector; static bool MaskCalculatedThisFrame; static CVector PreCalculatedMaskPosn; static bool m_bRenderSeaBed; static int32 m_nRenderWaterLayers; - + static RpAtomic *ms_pWavyAtomic; static RpAtomic *ms_pMaskAtomic; + static void Initialise(Const char *pWaterDat); // out of class in III PC and later because of SecuROM static void Shutdown(); - + static void CreateWavyAtomic(); static void DestroyWavyAtomic(); - - + + static void AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel); + static bool WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel = nil); + static bool TestVisibilityForFineWaterBlocks(const CVector &worldPos); + static void RemoveIsolatedWater(); + static bool GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ); static bool GetWaterLevel(CVector coors, float *pfOutLevel, bool bDontCheckZ) { return GetWaterLevel(coors.x, coors.y, coors.z, pfOutLevel, bDontCheckZ); } static bool GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel); static float GetWaterWavesOnly(short x, short y); // unused static CVector GetWaterNormal(float fX, float fY); - + static void RenderWater(); static void RenderTransparentWater(void); // unused @@ -151,11 +155,11 @@ public: static bool PreCalcWavySector(RwRGBA const &color); //fucked up static bool PreCalcWavyMask(float fX, float fY, float fZ, float fSectorX, float fSectorY, float fCamPosX, float fCamPosY, float fCamDirX, float fCamDirY, RwRGBA const&color); #endif - - + + static void RenderBoatWakes(void); static void RenderWakeSegment(CVector2D &vecA, CVector2D &vecB, CVector2D &vecC, CVector2D &vecD, float &fSizeA, float &fSizeB, float &fAlphaA, float &fAlphaB, float &fWakeZ); - + // unused static void RenderOneSlopedUnderWaterPoly(float fX, float fY, float fZ, RwRGBA const&color); // UNUSED static void RenderOneFlatSmallWaterPolyBlended(float fX, float fY, float fZ, float fCamX, float fCamY, RwRGBA const &color, RwRGBA const &colorTrans, float fDrawDist); @@ -163,20 +167,18 @@ public: static void RenderAndEmptyRenderBuffer(); static bool GetGroundLevel(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance); - + // unused static bool IsLocationOutOfWorldBounds_WS(CVector const &vecPosn, int nOffset); // unused static bool GetGroundLevel_WS(CVector const & vecPosn, float *pfOutLevel, ColData *pData, float fDistance); static bool GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel); - + static void RenderSeaBirds(); static void RenderShipsOnHorizon(); - + static void HandleSeaLifeForms(); - + static void HandleBeachToysStuff(void); static CEntity *CreateBeachToy(CVector const &vec, eBeachToy beachtoy); }; - -extern void WaterLevelInitialise(Const char *datFile);
\ No newline at end of file diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 3f242362..ffbd7e8f 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -21,8 +21,6 @@ #include "SpecialFX.h" #include "Replay.h" -//--MIAMI: file done - int32 CWeather::SoundHandle = -1; int32 CWeather::WeatherTypeInList; @@ -54,7 +52,7 @@ bool CWeather::bScriptsForceRain; tRainStreak Streaks[NUM_RAIN_STREAKS]; -const int16 WeatherTypesList[] = { +int16 WeatherTypesList[] = { WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, @@ -73,7 +71,7 @@ const int16 WeatherTypesList[] = { WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY }; -const int16 WeatherTypesList_WithHurricanes[] = { +int16 WeatherTypesList_WithHurricanes[] = { WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, @@ -139,7 +137,7 @@ void CWeather::Init(void) ForcedWeatherType = WEATHER_RANDOM; SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1); if (SoundHandle >= 0) - DMAudio.SetEntityStatus(SoundHandle, 1); + DMAudio.SetEntityStatus(SoundHandle, true); } void CWeather::Update(void) @@ -226,15 +224,15 @@ void CWeather::Update(void) // Rain float fNewRain; if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) { - // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s - fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f; + // if raining for >1 hour, values: 0, 0.33, switching every ~16.5s + fNewRain = (((uint16)CTimer::GetTimeInMilliseconds() >> 14) & 1) * 0.33f; if (OldWeatherType != WEATHER_RAINY && OldWeatherType != WEATHER_HURRICANE) { if (InterpolationValue < 0.4f) // if rain has just started (<24 minutes), always 0.5 fNewRain = 0.5f; else - // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s - fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f; + // if rain is ongoing for >24 minutes, values: 0.25, 0.5, switching every ~16.5s + fNewRain = 0.25f + (((uint16)CTimer::GetTimeInMilliseconds() >> 14) & 1) * 0.25f; } fNewRain = Max(fNewRain, 0.5f); } @@ -647,3 +645,18 @@ void CWeather::RenderRainStreaks(void) TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; } + +#ifdef SECUROM +void CWeather::ForceHurricaneWeather() +{ + for (int i = 0; i < ARRAY_SIZE(WeatherTypesList_WithHurricanes); i++) + { + WeatherTypesList[i] = WEATHER_HURRICANE; + WeatherTypesList_WithHurricanes[i] = WEATHER_HURRICANE; + } + + CWeather::OldWeatherType = WEATHER_HURRICANE; + CWeather::NewWeatherType = WEATHER_HURRICANE; + CWeather::ForcedWeatherType = WEATHER_HURRICANE; +} +#endif diff --git a/src/render/Weather.h b/src/render/Weather.h index ef62ebb6..bda57d55 100644 --- a/src/render/Weather.h +++ b/src/render/Weather.h @@ -55,6 +55,8 @@ public: static void AddRain(); static void AddHeatHaze(); static void AddBeastie(); + + static void ForceHurricaneWeather(); }; enum { diff --git a/src/rw/ClumpRead.cpp b/src/rw/ClumpRead.cpp index b8d72d23..9c027dc5 100644 --- a/src/rw/ClumpRead.cpp +++ b/src/rw/ClumpRead.cpp @@ -1,7 +1,5 @@ #include "common.h" -//--MIAMI: done - struct rpGeometryList { RpGeometry **geometries; diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp index e0dff850..772e1961 100644 --- a/src/rw/Lights.cpp +++ b/src/rw/Lights.cpp @@ -11,8 +11,6 @@ #include "Frontend.h" #include "MBlur.h" -//--MIAMI: done - RpLight *pAmbient; RpLight *pDirect; RpLight *pExtraDirectionals[4] = { nil }; diff --git a/src/rw/MemoryHeap.cpp b/src/rw/MemoryHeap.cpp new file mode 100644 index 00000000..285a7c70 --- /dev/null +++ b/src/rw/MemoryHeap.cpp @@ -0,0 +1,499 @@ +#include "common.h" +#include "main.h" +#include "FileMgr.h" +#include "Timer.h" +#include "ModelInfo.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "MemoryHeap.h" + +// TODO(MIAMI) + +#ifdef USE_CUSTOM_ALLOCATOR + +//#define MEMORYHEAP_ASSERT(cond) { if (!(cond)) { printf("ASSERT File:%s Line:%d\n", __FILE__, __LINE__); exit(1); } } +//#define MEMORYHEAP_ASSERT_MESSAGE(cond, message) { if (!(cond)) { printf("ASSERT File:%s Line:%d:\n\t%s\n", __FILE__, __LINE__, message); exit(1); } } + +#define MEMORYHEAP_ASSERT(cond) assert(cond) +#define MEMORYHEAP_ASSERT_MESSAGE(cond, message) assert(cond) + +// registered pointers that we keep track of +void **gPtrList[4000]; +int32 numPtrs; +int32 gPosnInList; +// indices into the ptr list in here are free +CStack<int32, 4000> m_ptrListIndexStack; +// how much memory we've moved +uint32 memMoved; + +CMemoryHeap gMainHeap; + +void +CMemoryHeap::Init(uint32 total) +{ + MEMORYHEAP_ASSERT((total != 0xF) != 0); + + m_totalMemUsed = 0; + m_memUsed = nil; + m_currentMemID = MEMID_FREE; + m_blocksUsed = nil; + m_totalBlocksUsed = 0; + m_unkMemId = -1; + + uint8 *mem = (uint8*)malloc(total); + assert(((uintptr)mem & 0xF) == 0); + m_start = (HeapBlockDesc*)mem; + m_end = (HeapBlockDesc*)(mem + total - sizeof(HeapBlockDesc)); + m_start->m_memId = MEMID_FREE; + m_start->m_size = total - 2*sizeof(HeapBlockDesc); + m_end->m_memId = MEMID_GAME; + m_end->m_size = 0; + + m_freeList.m_last.m_size = INT_MAX; + m_freeList.Init(); + m_freeList.Insert(m_start); + + // TODO: figure out what these are and use sizeof + m_fixedSize[0].Init(0x10); + m_fixedSize[1].Init(0x20); + m_fixedSize[2].Init(0xE0); + m_fixedSize[3].Init(0x60); + m_fixedSize[4].Init(0x1C0); + m_fixedSize[5].Init(0x50); + + m_currentMemID = MEMID_FREE; // disable registration + m_memUsed = (uint32*)Malloc(NUM_MEMIDS * sizeof(uint32)); + m_blocksUsed = (uint32*)Malloc(NUM_MEMIDS * sizeof(uint32)); + RegisterMalloc(GetDescFromHeapPointer(m_memUsed)); + RegisterMalloc(GetDescFromHeapPointer(m_blocksUsed)); + + m_currentMemID = MEMID_GAME; + for(int i = 0; i < NUM_MEMIDS; i++){ + m_memUsed[i] = 0; + m_blocksUsed[i] = 0; + } +} + +void +CMemoryHeap::RegisterMalloc(HeapBlockDesc *block) +{ + block->m_memId = m_currentMemID; + if(m_currentMemID == MEMID_FREE) + return; + m_totalMemUsed += block->m_size + sizeof(HeapBlockDesc); + m_memUsed[m_currentMemID] += block->m_size + sizeof(HeapBlockDesc); + m_blocksUsed[m_currentMemID]++; + m_totalBlocksUsed++; +} + +void +CMemoryHeap::RegisterFree(HeapBlockDesc *block) +{ + if(block->m_memId == MEMID_FREE) + return; + m_totalMemUsed -= block->m_size + sizeof(HeapBlockDesc); + m_memUsed[block->m_memId] -= block->m_size + sizeof(HeapBlockDesc); + m_blocksUsed[block->m_memId]--; + m_totalBlocksUsed--; +} + +void* +CMemoryHeap::Malloc(uint32 size) +{ + static int recursion = 0; + + // weird way to round up + if((size & 0xF) != 0) + size = (size&~0xF) + 0x10; + + recursion++; + + // See if we can allocate from one of the fixed-size lists + for(int i = 0; i < NUM_FIXED_MEMBLOCKS; i++){ + CommonSize *list = &m_fixedSize[i]; + if(m_fixedSize[i].m_size == size){ + HeapBlockDesc *block = list->Malloc(); + if(block){ + RegisterMalloc(block); + recursion--; + return block->GetDataPointer(); + } + break; + } + } + + // now try the normal free list + HeapBlockDesc *next; + for(HeapBlockDesc *block = m_freeList.m_first.m_next; + block != &m_freeList.m_last; + block = next){ + MEMORYHEAP_ASSERT(block->m_memId == MEMID_FREE); + MEMORYHEAP_ASSERT_MESSAGE(block >= m_start && block <= m_end, "Block outside of memory"); + + // make sure block has maximum size + uint32 initialsize = block->m_size; + uint32 blocksize = CombineFreeBlocks(block); +#ifdef FIX_BUGS + // has to be done here because block can be moved + next = block->m_next; +#endif + if(initialsize != blocksize){ + block->RemoveHeapFreeBlock(); + HeapBlockDesc *pos = block->m_prev->FindSmallestFreeBlock(block->m_size); + block->InsertHeapFreeBlock(pos->m_prev); + } + if(block->m_size >= size){ + // got space to allocate from! + block->RemoveHeapFreeBlock(); + FillInBlockData(block, block->GetNextConsecutive(), size); + recursion--; + return block->GetDataPointer(); + } +#ifndef FIX_BUGS + next = block->m_next; +#endif + } + + // oh no, we're losing, try to free some stuff + static bool removeCollision = false; + static bool removeIslands = false; + static bool removeBigBuildings = false; + size_t initialMemoryUsed = CStreaming::ms_memoryUsed; + CStreaming::MakeSpaceFor(0xCFE800 - CStreaming::ms_memoryUsed); + if (recursion > 10) + CGame::TidyUpMemory(true, false); + else if (recursion > 6) + CGame::TidyUpMemory(false, true); + if (initialMemoryUsed == CStreaming::ms_memoryUsed && recursion > 11) { + if (!removeCollision && !CGame::playingIntro) { + CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC); + removeCollision = true; + } + else if (!removeIslands && !CGame::playingIntro) { + CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); + removeIslands = true; + } + else if (!removeBigBuildings) { + CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); + CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); + CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); + } + else { + LoadingScreen("NO MORE MEMORY", nil, nil); + LoadingScreen("NO MORE MEMORY", nil, nil); + } + CGame::TidyUpMemory(true, false); + } + void *mem = Malloc(size); + if (removeCollision) { + CTimer::Stop(); + // TODO: different on PS2 + CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory); + removeCollision = false; + CTimer::Update(); + } + if (removeBigBuildings || removeIslands) { + CTimer::Stop(); + if (!CGame::playingIntro) + CStreaming::RequestBigBuildings(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + removeBigBuildings = false; + removeIslands = false; + CTimer::Update(); + } + recursion--; + return mem; +} + +void* +CMemoryHeap::Realloc(void *ptr, uint32 size) +{ + if(ptr == nil) + return Malloc(size); + + // weird way to round up + if((size & 0xF) != 0) + size = (size&~0xF) + 0x10; + + HeapBlockDesc *block = GetDescFromHeapPointer(ptr); + +#ifdef FIX_BUGS + // better handling of size < block->m_size + if(size == 0){ + Free(ptr); + return nil; + } + if(block->m_size >= size){ + // shrink allocated block + RegisterFree(block); + PushMemId(block->m_memId); + FillInBlockData(block, block->GetNextConsecutive(), size); + PopMemId(); + return ptr; + } +#else + // not growing. just returning here is a bit cheap though + if(block->m_size >= size) + return ptr; +#endif + + // have to grow allocated block + HeapBlockDesc *next = block->GetNextConsecutive(); + MEMORYHEAP_ASSERT_MESSAGE(next >= m_start && next <= m_end, "Block outside of memory"); + if(next->m_memId == MEMID_FREE){ + // try to grow the current block + // make sure the next free block has maximum size + uint32 freespace = CombineFreeBlocks(next); + HeapBlockDesc *end = next->GetNextConsecutive(); + MEMORYHEAP_ASSERT_MESSAGE(end >= m_start && end <= m_end, "Block outside of memory"); + // why the sizeof here? + if(block->m_size + next->m_size + sizeof(HeapBlockDesc) >= size){ + // enough space to grow + next->RemoveHeapFreeBlock(); + RegisterFree(block); + PushMemId(block->m_memId); + FillInBlockData(block, next->GetNextConsecutive(), size); + PopMemId(); + return ptr; + } + } + + // can't grow the existing block, have to get a new one and copy + PushMemId(block->m_memId); + void *dst = Malloc(size); + PopMemId(); + memcpy(dst, ptr, block->m_size); + Free(ptr); + return dst; +} + +void +CMemoryHeap::Free(void *ptr) +{ + HeapBlockDesc *block = GetDescFromHeapPointer(ptr); + MEMORYHEAP_ASSERT_MESSAGE(block->m_memId != MEMID_FREE, "MemoryHeap corrupt"); + MEMORYHEAP_ASSERT(m_unkMemId == -1 || m_unkMemId == block->m_memId); + + RegisterFree(block); + block->m_memId = MEMID_FREE; + CombineFreeBlocks(block); + FreeBlock(block); + if(block->m_ptrListIndex != -1){ + int32 idx = block->m_ptrListIndex; + gPtrList[idx] = nil; + m_ptrListIndexStack.push(idx); + } + block->m_ptrListIndex = -1; +} + +// allocate 'size' bytes from 'block' +void +CMemoryHeap::FillInBlockData(HeapBlockDesc *block, HeapBlockDesc *end, uint32 size) +{ + block->m_size = size; + block->m_ptrListIndex = -1; + HeapBlockDesc *remainder = block->GetNextConsecutive(); + MEMORYHEAP_ASSERT(remainder <= end); + + if(remainder < end-1){ + RegisterMalloc(block); + + // can fit another block in the remaining space + remainder->m_size = GetSizeBetweenBlocks(remainder, end); + remainder->m_memId = MEMID_FREE; + MEMORYHEAP_ASSERT(remainder->m_size != 0); + FreeBlock(remainder); + }else{ + // fully allocate this one + if(remainder < end) + // no gaps allowed + block->m_size = GetSizeBetweenBlocks(block, end); + RegisterMalloc(block); + } +} + +// Make sure free block has no other free blocks after it +uint32 +CMemoryHeap::CombineFreeBlocks(HeapBlockDesc *block) +{ + HeapBlockDesc *next = block->GetNextConsecutive(); + if(next->m_memId != MEMID_FREE) + return block->m_size; + // get rid of free blocks after this one and adjust size + for(; next->m_memId == MEMID_FREE; next = next->GetNextConsecutive()) + next->RemoveHeapFreeBlock(); + block->m_size = GetSizeBetweenBlocks(block, next); + return block->m_size; +} + +// Try to move all registered memory blocks into more optimal location +void +CMemoryHeap::TidyHeap(void) +{ + for(int i = 0; i < numPtrs; i++){ + if(gPtrList[i] == nil || *gPtrList[i] == nil) + continue; + HeapBlockDesc *newblock = WhereShouldMemoryMove(*gPtrList[i]); + if(newblock) + *gPtrList[i] = MoveHeapBlock(newblock, GetDescFromHeapPointer(*gPtrList[i])); + } +} + +// MIAMI: this is empty +void +CMemoryHeap::RegisterMemPointer(void *ptr) +{ + HeapBlockDesc *block = GetDescFromHeapPointer(*(void**)ptr); + + if(block->m_ptrListIndex != -1) + return; // already registered + + int index; + if(m_ptrListIndexStack.sp > 0){ + // re-use a previously free'd index + index = m_ptrListIndexStack.pop(); + }else{ + // have to find a new index + index = gPosnInList; + + void **pp = gPtrList[index]; + // we're replacing an old pointer here?? + if(pp && *pp && *pp != (void*)0xDDDDDDDD) + GetDescFromHeapPointer(*pp)->m_ptrListIndex = -1; + + gPosnInList++; + if(gPosnInList == 4000) + gPosnInList = 0; + if(numPtrs < 4000) + numPtrs++; + } + gPtrList[index] = (void**)ptr; + block->m_ptrListIndex = index; +} + +void* +CMemoryHeap::MoveMemory(void *ptr) +{ + HeapBlockDesc *newblock = WhereShouldMemoryMove(ptr); + if(newblock) + return MoveHeapBlock(newblock, GetDescFromHeapPointer(ptr)); + else + return ptr; +} + +HeapBlockDesc* +CMemoryHeap::WhereShouldMemoryMove(void *ptr) +{ + HeapBlockDesc *block = GetDescFromHeapPointer(ptr); + MEMORYHEAP_ASSERT(block->m_memId != MEMID_FREE); + + HeapBlockDesc *next = block->GetNextConsecutive(); + if(next->m_memId != MEMID_FREE) + return nil; + + // we want to move the block into another block + // such that the free space between this and the next block can be minimized + HeapBlockDesc *newblock = m_freeList.m_first.FindSmallestFreeBlock(block->m_size); + // size of free space wouldn't decrease, so return + if(newblock->m_size >= block->m_size + next->m_size) + return nil; + // size of free space wouldn't decrease enough + if(newblock->m_size >= 16 + 1.125f*block->m_size) // what are 16 and 1.125 here? sizeof(HeapBlockDesc)? + return nil; + return newblock; +} + +void* +CMemoryHeap::MoveHeapBlock(HeapBlockDesc *dst, HeapBlockDesc *src) +{ + PushMemId(src->m_memId); + dst->RemoveHeapFreeBlock(); + FillInBlockData(dst, dst->GetNextConsecutive(), src->m_size); + PopMemId(); + memcpy(dst->GetDataPointer(), src->GetDataPointer(), src->m_size); + memMoved += src->m_size; + dst->m_ptrListIndex = src->m_ptrListIndex; + src->m_ptrListIndex = -1; + Free(src->GetDataPointer()); + return dst->GetDataPointer(); +} + +uint32 +CMemoryHeap::GetMemoryUsed(int32 id) +{ + return m_memUsed[id]; +} + +uint32 +CMemoryHeap::GetBlocksUsed(int32 id) +{ + return m_blocksUsed[id]; +} + +void +CMemoryHeap::PopMemId(void) +{ + assert(m_idStack.sp > 0); + m_currentMemID = m_idStack.pop(); + assert(m_currentMemID != MEMID_FREE); +} + +void +CMemoryHeap::PushMemId(int32 id) +{ + MEMORYHEAP_ASSERT(id != MEMID_FREE); + assert(m_idStack.sp < 16); + m_idStack.push(m_currentMemID); + m_currentMemID = id; +} + +void +CMemoryHeap::ParseHeap(void) +{ + char tmp[16]; + int fd = CFileMgr::OpenFileForWriting("heap.txt"); + CTimer::Stop(); + + // CMemoryHeap::IntegrityCheck(); + + uint32 addrQW = 0; + for(HeapBlockDesc *block = m_start; block < m_end; block = block->GetNextConsecutive()){ + char chr = '*'; // free + if(block->m_memId != MEMID_FREE) + chr = block->m_memId-1 + 'A'; + int numQW = block->m_size>>4; + + if((addrQW & 0x3F) == 0){ + sprintf(tmp, "\n%5dK:", addrQW>>6); + CFileMgr::Write(fd, tmp, 8); + } + CFileMgr::Write(fd, "#", 1); // the descriptor, has to be 16 bytes!!!! + addrQW++; + + while(numQW--){ + if((addrQW & 0x3F) == 0){ + sprintf(tmp, "\n%5dK:", addrQW>>6); + CFileMgr::Write(fd, tmp, 8); + } + CFileMgr::Write(fd, &chr, 1); + addrQW++; + } + } + + CTimer::Update(); + CFileMgr::CloseFile(fd); +} + + +void +CommonSize::Init(uint32 size) +{ + m_freeList.Init(); + m_size = size; + m_failed = 0; + m_remaining = 0; +} + +#endif diff --git a/src/rw/MemoryHeap.h b/src/rw/MemoryHeap.h new file mode 100644 index 00000000..1a9a51f8 --- /dev/null +++ b/src/rw/MemoryHeap.h @@ -0,0 +1,204 @@ +#pragma once + +// some windows shit +#ifdef MoveMemory +#undef MoveMemory +#endif + +#ifdef USE_CUSTOM_ALLOCATOR +#define PUSH_MEMID(id) gMainHeap.PushMemId(id) +#define POP_MEMID() gMainHeap.PopMemId() +#define REGISTER_MEMPTR(ptr) gMainHeap.RegisterMemPointer(ptr) +#else +#define PUSH_MEMID(id) +#define POP_MEMID() +#define REGISTER_MEMPTR(ptr) +#endif + +enum { + MEMID_FREE, + MEMID_GAME = 1, // "Game" + MEMID_WORLD = 2, // "World" + MEMID_ANIMATION = 3, // "Animation" + MEMID_POOLS = 4, // "Pools" + MEMID_DEF_MODELS = 5, // "Default Models" + MEMID_STREAM = 6, // "Streaming" + MEMID_STREAM_MODELS = 7, // "Streamed Models" + MEMID_STREAM_LODS = 8, // "Streamed LODs" + MEMID_STREAM_TEXUTRES = 9, // "Streamed Textures" + MEMID_STREAM_COLLISION = 10, // "Streamed Collision" + MEMID_STREAM_ANIMATION = 11, // "Streamed Animation" + MEMID_TEXTURES = 12, // "Textures" + MEMID_COLLISION = 13, // "Collision" + MEMID_PRE_ALLOC = 14, // "PreAlloc" + MEMID_GAME_PROCESS = 15, // "Game Process" + MEMID_SCRIPT = 16, // "Script" + MEMID_CARS = 17, // "Cars" + MEMID_RENDER = 18, // "Render" + MEMID_PED_ATTR = 19, // "Ped Attr" + NUM_MEMIDS, + + NUM_FIXED_MEMBLOCKS = 6 +}; + +template<typename T, uint32 N> +class CStack +{ +public: + T values[N]; + uint32 sp; + + CStack() : sp(0) {} + void push(const T& val) { values[sp++] = val; } + T& pop() { return values[--sp]; } +}; + + +struct HeapBlockDesc +{ + uint32 m_size; + int16 m_memId; + int16 m_ptrListIndex; + HeapBlockDesc *m_next; + HeapBlockDesc *m_prev; + + HeapBlockDesc *GetNextConsecutive(void) + { + return (HeapBlockDesc*)((uintptr)this + sizeof(HeapBlockDesc) + m_size); + } + + void *GetDataPointer(void) + { + return (void*)((uintptr)this + sizeof(HeapBlockDesc)); + } + + void RemoveHeapFreeBlock(void) + { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } + + // after node + void InsertHeapFreeBlock(HeapBlockDesc *node) + { + m_next = node->m_next; + node->m_next->m_prev = this; + m_prev = node; + node->m_next = this; + } + + HeapBlockDesc *FindSmallestFreeBlock(uint32 size) + { + HeapBlockDesc *b; + for(b = m_next; b->m_size < size; b = b->m_next); + return b; + } +}; + +#ifdef USE_CUSTOM_ALLOCATOR +// TODO: figure something out for 64 bit pointers +static_assert(sizeof(HeapBlockDesc) == 0x10, "HeapBlockDesc must have 0x10 size otherwise most of assumptions don't make sense"); +#endif + +struct HeapBlockList +{ + HeapBlockDesc m_first; + HeapBlockDesc m_last; + + void Init(void) + { + m_first.m_next = &m_last; + m_last.m_prev = &m_first; + } + + void Insert(HeapBlockDesc *node) + { + node->InsertHeapFreeBlock(&m_first); + } +}; + +struct CommonSize +{ + HeapBlockList m_freeList; + uint32 m_size; + uint32 m_failed; + uint32 m_remaining; + + void Init(uint32 size); + void Free(HeapBlockDesc *node) + { + m_freeList.Insert(node); + m_remaining++; + } + HeapBlockDesc *Malloc(void) + { + if(m_freeList.m_first.m_next == &m_freeList.m_last){ + m_failed++; + return nil; + } + HeapBlockDesc *block = m_freeList.m_first.m_next; + m_remaining--; + block->RemoveHeapFreeBlock(); + block->m_ptrListIndex = -1; + return block; + } +}; + +class CMemoryHeap +{ +public: + HeapBlockDesc *m_start; + HeapBlockDesc *m_end; + HeapBlockList m_freeList; + CommonSize m_fixedSize[NUM_FIXED_MEMBLOCKS]; + uint32 m_totalMemUsed; + CStack<int32, 16> m_idStack; + uint32 m_currentMemID; + uint32 *m_memUsed; + uint32 m_totalBlocksUsed; + uint32 *m_blocksUsed; + uint32 m_unkMemId; + + CMemoryHeap(void) : m_start(nil) {} + void Init(uint32 total); + void RegisterMalloc(HeapBlockDesc *block); + void RegisterFree(HeapBlockDesc *block); + void *Malloc(uint32 size); + void *Realloc(void *ptr, uint32 size); + void Free(void *ptr); + void FillInBlockData(HeapBlockDesc *block, HeapBlockDesc *end, uint32 size); + uint32 CombineFreeBlocks(HeapBlockDesc *block); + void *MoveMemory(void *ptr); + HeapBlockDesc *WhereShouldMemoryMove(void *ptr); + void *MoveHeapBlock(HeapBlockDesc *dst, HeapBlockDesc *src); + void PopMemId(void); + void PushMemId(int32 id); + void RegisterMemPointer(void *ptr); + void TidyHeap(void); + uint32 GetMemoryUsed(int32 id); + uint32 GetBlocksUsed(int32 id); + int32 GetLargestFreeBlock(void) { return m_freeList.m_last.m_prev->m_size; } + + void ParseHeap(void); + + HeapBlockDesc *GetDescFromHeapPointer(void *block) + { + return (HeapBlockDesc*)((uintptr)block - sizeof(HeapBlockDesc)); + } + uint32 GetSizeBetweenBlocks(HeapBlockDesc *first, HeapBlockDesc *second) + { + return (uintptr)second - (uintptr)first - sizeof(HeapBlockDesc); + } + void FreeBlock(HeapBlockDesc *block){ + for(int i = 0; i < NUM_FIXED_MEMBLOCKS; i++){ + if(m_fixedSize[i].m_size == block->m_size){ + m_fixedSize[i].Free(block); + return; + } + } + HeapBlockDesc *b = m_freeList.m_first.FindSmallestFreeBlock(block->m_size); + block->InsertHeapFreeBlock(b->m_prev); + } +}; + +extern CMemoryHeap gMainHeap; diff --git a/src/rw/MemoryMgr.cpp b/src/rw/MemoryMgr.cpp new file mode 100644 index 00000000..2379692c --- /dev/null +++ b/src/rw/MemoryMgr.cpp @@ -0,0 +1,130 @@ +#include "common.h" +#include "MemoryHeap.h" +#include "MemoryMgr.h" + + +uint8 *pMemoryTop; + +void +InitMemoryMgr(void) +{ +#ifdef USE_CUSTOM_ALLOCATOR +#ifdef GTA_PS2 +#error "finish this" +#else + // randomly allocate 128mb + gMainHeap.Init(128*1024*1024); +#endif +#endif +} + + +RwMemoryFunctions memFuncs = { + MemoryMgrMalloc, + MemoryMgrFree, + MemoryMgrRealloc, + MemoryMgrCalloc +}; + +#ifdef USE_CUSTOM_ALLOCATOR +// game seems to be using heap directly here, but this is nicer +void *operator new(size_t sz) { return MemoryMgrMalloc(sz); } +void *operator new[](size_t sz) { return MemoryMgrMalloc(sz); } +void operator delete(void *ptr) noexcept { MemoryMgrFree(ptr); } +void operator delete[](void *ptr) noexcept { MemoryMgrFree(ptr); } +#endif + +void* +MemoryMgrMalloc(size_t size) +{ +#ifdef USE_CUSTOM_ALLOCATOR + void *mem = gMainHeap.Malloc(size); +#else + void *mem = malloc(size); +#endif + if((uint8*)mem + size > pMemoryTop) + pMemoryTop = (uint8*)mem + size ; + return mem; +} + +void* +MemoryMgrRealloc(void *ptr, size_t size) +{ +#ifdef USE_CUSTOM_ALLOCATOR + void *mem = gMainHeap.Realloc(ptr, size); +#else + void *mem = realloc(ptr, size); +#endif + if((uint8*)mem + size > pMemoryTop) + pMemoryTop = (uint8*)mem + size ; + return mem; +} + +void* +MemoryMgrCalloc(size_t num, size_t size) +{ +#ifdef USE_CUSTOM_ALLOCATOR + void *mem = gMainHeap.Malloc(num*size); +#else + void *mem = calloc(num, size); +#endif + if((uint8*)mem + size > pMemoryTop) + pMemoryTop = (uint8*)mem + size ; +#ifdef FIX_BUGS + memset(mem, 0, num*size); +#endif + return mem; +} + +void +MemoryMgrFree(void *ptr) +{ +#ifdef USE_CUSTOM_ALLOCATOR +#ifdef FIX_BUGS + // i don't suppose this is handled by RW? + if(ptr == nil) return; +#endif + gMainHeap.Free(ptr); +#else + free(ptr); +#endif +} + +void * +RwMallocAlign(RwUInt32 size, RwUInt32 align) +{ +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) + uintptr ptralign = align-1; + void *mem = (void *)MemoryMgrMalloc(size + sizeof(uintptr) + ptralign); + + ASSERT(mem != nil); + + void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign); + + ASSERT(addr != nil); +#else + void *mem = (void *)MemoryMgrMalloc(size + align); + + ASSERT(mem != nil); + + void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1)); + + ASSERT(addr != nil); +#endif + + *(((void **)addr) - 1) = mem; + + return addr; +} + +void +RwFreeAlign(void *mem) +{ + ASSERT(mem != nil); + + void *addr = *(((void **)mem) - 1); + + ASSERT(addr != nil); + + MemoryMgrFree(addr); +} diff --git a/src/rw/MemoryMgr.h b/src/rw/MemoryMgr.h new file mode 100644 index 00000000..e2962806 --- /dev/null +++ b/src/rw/MemoryMgr.h @@ -0,0 +1,12 @@ +#pragma once + +extern RwMemoryFunctions memFuncs; +void InitMemoryMgr(void); + +void *MemoryMgrMalloc(size_t size); +void *MemoryMgrRealloc(void *ptr, size_t size); +void *MemoryMgrCalloc(size_t num, size_t size); +void MemoryMgrFree(void *ptr); + +void *RwMallocAlign(RwUInt32 size, RwUInt32 align); +void RwFreeAlign(void *mem); diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 7d62a01c..609dd79b 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -1,6 +1,4 @@ -#if defined RW_D3D9 || defined RWLIBS #define WITHD3D -#endif #include "common.h" #include "Timecycle.h" @@ -18,7 +16,7 @@ bool gPS2alphaTest = true; #else bool gPS2alphaTest = false; #endif -bool gBackfaceCulling; +bool gBackfaceCulling = true; #if !defined(FINAL) || defined(DEBUGMENU) static bool charsetOpen; @@ -63,45 +61,6 @@ void FlushObrsPrintfs() #endif } -void * -RwMallocAlign(RwUInt32 size, RwUInt32 align) -{ -#ifdef FIX_BUGS - uintptr ptralign = align-1; - void *mem = (void *)malloc(size + sizeof(uintptr) + ptralign); - - ASSERT(mem != nil); - - void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign); - - ASSERT(addr != nil); -#else - void *mem = (void *)malloc(size + align); - - ASSERT(mem != nil); - - void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1)); - - ASSERT(addr != nil); -#endif - - *(((void **)addr) - 1) = mem; - - return addr; -} - -void -RwFreeAlign(void *mem) -{ - ASSERT(mem != nil); - - void *addr = *(((void **)mem) - 1); - - ASSERT(addr != nil); - - free(addr); -} - void DefinedState(void) { @@ -294,7 +253,8 @@ SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable) parent = stack[sp--]; else parent = i; - assert(parent >= 0 && parent < numBones); + + //assert(parent >= 0 && parent < numBones); } } @@ -302,7 +262,7 @@ RpHAnimAnimation* HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier) { int i; -#ifdef FIX_BUGS +#if defined FIX_BUGS || defined LIBRW int numNodes = hier->numNodes*2; // you're supposed to have at least two KFs per node #else int numNodes = hier->numNodes; @@ -316,7 +276,7 @@ HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier) frame->q.real = 1.0f; frame->q.imag.x = frame->q.imag.y = frame->q.imag.z = 0.0f; frame->t.x = frame->t.y = frame->t.z = 0.0f; -#ifdef FIX_BUGS +#if defined FIX_BUGS || defined LIBRW // times are subtracted and divided giving NaNs // so they can't both be 0 frame->time = i/hier->numNodes; @@ -328,26 +288,6 @@ HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier) return anim; } -RpAtomic* -AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data) -{ - if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){ - RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic); -#ifdef LIBRW - if(hier && hier->interpolator->currentAnim){ - RpHAnimAnimationDestroy(hier->interpolator->currentAnim); - hier->interpolator->currentAnim = nil; - } -#else - if(hier && hier->currentAnim){ - RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim); - hier->currentAnim = nil; - } -#endif - } - return atomic; -} - void RenderSkeleton(RpHAnimHierarchy *hier) { @@ -542,7 +482,7 @@ CameraSize(RwCamera * camera, RwRect * rect, RwRaster *zRaster; // BUG: game just changes camera raster's sizes, but this is a hack -#ifdef FIX_BUGS +#if defined FIX_BUGS || defined LIBRW /* * Destroy rasters... */ diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index cf086e5a..9352d1fd 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -3,9 +3,6 @@ extern bool gPS2alphaTest; extern bool gBackfaceCulling; -void *RwMallocAlign(RwUInt32 size, RwUInt32 align); -void RwFreeAlign(void *mem); - void OpenCharsetSafe(); void CreateDebugFont(); void DestroyDebugFont(); diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp index c5252f77..632cec02 100644 --- a/src/rw/TexRead.cpp +++ b/src/rw/TexRead.cpp @@ -5,7 +5,7 @@ #define WITHD3D #endif #include "common.h" -#ifndef LIBRW +#ifdef ANISOTROPIC_FILTERING #include "rpanisot.h" #endif #include "crossplatform.h" @@ -55,12 +55,9 @@ RwTextureGtaStreamRead(RwStream *stream) texNumLoaded++; } - if(tex == nil) - return nil; - -#ifndef LIBRW - if(RpAnisotTextureGetMaxAnisotropy(tex) > 1) - RpAnisotTextureSetMaxAnisotropy(tex, RpAnisotTextureGetMaxAnisotropy(tex)); +#ifdef ANISOTROPIC_FILTERING + if(tex && RpAnisotGetMaxSupportedMaxAnisotropy() > 1) // BUG? this was RpAnisotTextureGetMaxAnisotropy, but that doesn't make much sense + RpAnisotTextureSetMaxAnisotropy(tex, RpAnisotGetMaxSupportedMaxAnisotropy()); #endif return tex; diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index c79cb52b..871ef287 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -1,5 +1,6 @@ #include "common.h" +#include "RwHelper.h" #include "templates.h" #include "main.h" #include "Entity.h" @@ -11,10 +12,7 @@ #include "VisibilityPlugins.h" #include "World.h" #include "custompipes.h" - -//--MIAMI: file done - -#define FADE_DISTANCE 20.0f +#include "MemoryHeap.h" CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList; CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaBoatAtomicList; @@ -39,6 +37,8 @@ float CVisibilityPlugins::ms_bigVehicleLod1Dist; float CVisibilityPlugins::ms_pedLod1Dist; float CVisibilityPlugins::ms_pedFadeDist; +#define RENDERCALLBACK AtomicDefaultRenderCallBack + void CVisibilityPlugins::Initialise(void) { @@ -132,6 +132,10 @@ CVisibilityPlugins::InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist) return !!m_alphaBoatAtomicList.InsertSorted(item); } +// can't increase this yet unfortunately... +// probably have to fix fading for this so material alpha isn't overwritten +#define VEHICLE_LODDIST_MULTIPLIER (TheCamera.GenerationDistMultiplier) + void CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) { @@ -144,13 +148,13 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) else ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f); - ms_vehicleLod0Dist = sq(70.0f * TheCamera.GenerationDistMultiplier); - ms_vehicleLod1Dist = sq(90.0f * TheCamera.GenerationDistMultiplier); - ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier); - ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier); - ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier); - ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier); - ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); + ms_vehicleLod0Dist = sq(70.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_vehicleLod1Dist = sq(90.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_vehicleFadeDist = sq(100.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_bigVehicleLod0Dist = sq(60.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_bigVehicleLod1Dist = sq(150.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier); + ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); } static float DistToCameraSq; @@ -187,7 +191,7 @@ CVisibilityPlugins::RenderAtomicList(CLinkList<AlphaObjectInfo> &list) { CLink<AlphaObjectInfo> *node; for(node = list.tail.prev; node != &list.head; node = node->prev) - AtomicDefaultRenderCallBack(node->item.atomic); + RENDERCALLBACK(node->item.atomic); } void @@ -257,11 +261,11 @@ CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic) mi = GetAtomicModelInfo(atomic); len = Sqrt(DistToCameraSq); - lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / TheCamera.GenerationDistMultiplier); + lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / VEHICLE_LODDIST_MULTIPLIER); if(lodatm){ if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic)) RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE); - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -278,7 +282,7 @@ CVisibilityPlugins::RenderObjNormalAtomic(RpAtomic *atomic) len = RwV3dLength(&view); if(RwV3dDotProduct(&view, RwMatrixGetUp(m)) < -0.3f*len && len > 8.0f) return atomic; - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); return atomic; } @@ -292,7 +296,7 @@ CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha) flags = RpGeometryGetFlags(geo); RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR); RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); RpGeometrySetFlags(geo, flags); return atomic; @@ -312,7 +316,7 @@ CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic) maxdist = mi->GetLodDistance(0); distsq = RwV3dDotProduct(&view, &view); if(distsq < maxdist*maxdist) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); return atomic; } @@ -334,7 +338,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) fadefactor = 1.0f; alpha = mi->m_alpha * fadefactor; if(alpha == 255) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); else{ RpGeometry *geo = RpAtomicGetGeometry(lodatm); uint32 flags = RpGeometryGetFlags(geo); @@ -342,7 +346,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); if(geo != RpAtomicGetGeometry(atomic)) RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); RpGeometrySetFlags(geo, flags); } @@ -371,7 +375,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot)) return atomic; } - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -395,10 +399,10 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic) if(flags & ATOMIC_FLAG_DRAWLAST){ // sort before clump if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); }else{ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } } return atomic; @@ -420,7 +424,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic) if(dot > 0.0f) return atomic; } - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -442,7 +446,7 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic) return atomic; if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -451,7 +455,7 @@ RpAtomic* CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic) { if(DistToCameraSq < ms_bigVehicleLod1Dist) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); return atomic; } @@ -461,9 +465,9 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic) if(DistToCameraSq < ms_vehicleLod0Dist){ if(GetAtomicId(atomic) & ATOMIC_FLAG_DRAWLAST){ if(!InsertAtomicIntoBoatSortedList(atomic, DistToCameraSq)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); }else - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -485,7 +489,7 @@ CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic) if(dot > 0.0f) return atomic; } - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -508,7 +512,7 @@ CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic) return atomic; if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -523,7 +527,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic) if(DistToCameraSq >= ms_vehicleLod0Dist){ alpha = GetClumpAlpha(clump); if(alpha == 255) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); else RenderAlphaAtomic(atomic, alpha); } @@ -535,7 +539,7 @@ RpAtomic* CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic) { if(DistToCameraSq >= ms_bigVehicleLod1Dist) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); return atomic; } @@ -555,7 +559,7 @@ CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic) if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot)) return atomic; } - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -579,10 +583,10 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic) if(flags & ATOMIC_FLAG_DRAWLAST){ // sort before clump if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); }else{ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } } return atomic; @@ -600,7 +604,7 @@ CVisibilityPlugins::RenderVehicleRotorAlphaCB(RpAtomic *atomic) RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn); dot = RwV3dDotProduct(&cam2atm, &RwFrameGetLTM(clumpframe)->at); if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot*20.0f)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -618,7 +622,7 @@ CVisibilityPlugins::RenderVehicleTailRotorAlphaCB(RpAtomic *atomic) RwV3dSub(&cam2atm, &atmMat->pos, ms_pCameraPosn); dot = RwV3dDotProduct(&cam2atm, &clumpMat->up) + RwV3dDotProduct(&cam2atm, &clumpMat->right); if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - dot)) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); } return atomic; } @@ -628,7 +632,7 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic) { if(CWorld::Players[0].m_pSkinTexture) RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture); - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); return atomic; } @@ -642,7 +646,7 @@ CVisibilityPlugins::RenderPedCB(RpAtomic *atomic) if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){ alpha = GetClumpAlpha(RpAtomicGetClump(atomic)); if(alpha == 255) - AtomicDefaultRenderCallBack(atomic); + RENDERCALLBACK(atomic); else RenderAlphaAtomic(atomic, alpha); } @@ -833,12 +837,11 @@ CVisibilityPlugins::GetAtomicId(RpAtomic *atomic) return ATOMICEXT(atomic)->flags; } -// This is rather useless, but whatever void CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb) { if(cb == nil) - cb = AtomicDefaultRenderCallBack; // not necessary + cb = RENDERCALLBACK; // not necessary RpAtomicSetRenderCallBack(atomic, cb); } @@ -867,12 +870,12 @@ CVisibilityPlugins::FrameCopyConstructor(void *dst, const void *src, int32, int3 } void -CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, uintptr id) +CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, intptr id) { FRAMEEXT(frame)->id = id; } -uintptr +intptr CVisibilityPlugins::GetFrameHierarchyId(RwFrame *frame) { return FRAMEEXT(frame)->id; @@ -909,7 +912,7 @@ void CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo) { CVehicleModelInfo *vmi; - SetFrameHierarchyId(RpClumpGetFrame(clump), (uintptr)modelInfo); + SetFrameHierarchyId(RpClumpGetFrame(clump), (intptr)modelInfo); // Unused switch (modelInfo->GetModelType()) { diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h index 03833c9c..13365c7a 100644 --- a/src/rw/VisibilityPlugins.h +++ b/src/rw/VisibilityPlugins.h @@ -115,10 +115,10 @@ public: struct FrameExt { // BUG: this is abused to hold a pointer by SetClumpModelInfo - uintptr id; + intptr id; }; - static void SetFrameHierarchyId(RwFrame *frame, uintptr id); - static uintptr GetFrameHierarchyId(RwFrame *frame); + static void SetFrameHierarchyId(RwFrame *frame, intptr id); + static intptr GetFrameHierarchyId(RwFrame *frame); static void *FrameConstructor(void *object, int32 offset, int32 len); static void *FrameDestructor(void *object, int32 offset, int32 len); diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 82f66308..54685b66 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -41,8 +41,6 @@ #include "Timecycle.h" #include "Fluff.h" -// --MIAMI: file done - #define BLOCK_COUNT 22 #define SIZE_OF_SIMPLEVARS 0xE4 @@ -326,6 +324,11 @@ GenericLoad() ReadDataFromBufferPointer(buf, CWeather::OldWeatherType); ReadDataFromBufferPointer(buf, CWeather::NewWeatherType); ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType); +#ifdef SECUROM + if (CTimer::m_FrameCounter > 72000){ + buf += align4bytes(4); + } +#endif ReadDataFromBufferPointer(buf, CWeather::InterpolationValue); ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList); #ifdef COMPATIBLE_SAVES @@ -342,7 +345,11 @@ GenericLoad() #endif ReadDataFromBufferPointer(buf, CGame::currArea); ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro); +#ifdef LOAD_INI_SETTINGS + buf += align4bytes(sizeof(CPad::bInvertLook4Pad)); +#else ReadDataFromBufferPointer(buf, CPad::bInvertLook4Pad); +#endif ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour); ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn); ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter); diff --git a/src/save/MemoryCard.cpp b/src/save/MemoryCard.cpp index a24b754c..d6e95d33 100644 --- a/src/save/MemoryCard.cpp +++ b/src/save/MemoryCard.cpp @@ -1,6 +1,7 @@ #define WITHWINDOWS #include "common.h" #ifdef PS2_MENU +#include "crossplatform.h" #include "MemoryCard.h" #include "main.h" #include "DMAudio.h" @@ -11,6 +12,7 @@ #include "Clock.h" #include "MBlur.h" #include "Date.h" +#include "Font.h" #include "FileMgr.h" #include "Game.h" #include "GameLogic.h" diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp index dd0926cf..70ca31d2 100644 --- a/src/save/PCSave.cpp +++ b/src/save/PCSave.cpp @@ -12,8 +12,6 @@ #include "PCSave.h" #include "Text.h" -// --MIAMI: file done - const char* _psGetUserFilesFolder(); C_PcSave PcSaveHelper; diff --git a/src/skel/events.cpp b/src/skel/events.cpp index 6589ab71..3e1e95b3 100644 --- a/src/skel/events.cpp +++ b/src/skel/events.cpp @@ -9,8 +9,6 @@ #include "events.h" -// --MIAMI: file done - /* ***************************************************************************** */ diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index c219e711..055712f3 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -1,22 +1,30 @@ #if defined RW_GL3 && !defined LIBRW_SDL2 #ifdef _WIN32 -#include <windows.h> +#include <shlobj.h> +#include <basetsd.h> #include <mmsystem.h> +#include <regstr.h> #include <shellapi.h> #include <windowsx.h> -#include <basetsd.h> -#include <regstr.h> -#include <shlobj.h> + +DWORD _dwOperatingSystemVersion; +#include "resource.h" +#else +long _dwOperatingSystemVersion; +#ifndef __APPLE__ +#include <sys/sysinfo.h> +#else +#include <mach/mach_host.h> +#include <sys/sysctl.h> +#endif +#include <errno.h> +#include <locale.h> +#include <signal.h> +#include <stddef.h> #endif -#define WITHWINDOWS #include "common.h" - -#pragma warning( push ) -#pragma warning( disable : 4005) -#pragma warning( pop ) - #if (defined(_MSC_VER)) #include <tchar.h> #endif /* (defined(_MSC_VER)) */ @@ -40,11 +48,10 @@ #include "Sprite2d.h" #include "AnimViewer.h" #include "Font.h" +#include "MemoryMgr.h" #define MAX_SUBSYSTEMS (16) -// --MIAMI: file done - rw::EngineOpenParams openParams; static RwBool ForegroundApp = TRUE; @@ -70,29 +77,9 @@ static psGlobalType PsGlobal; #define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var) -#undef MAKEPOINTS -#define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l))) - size_t _dwMemAvailPhys; RwUInt32 gGameState; -#ifdef _WIN32 -DWORD _dwOperatingSystemVersion; -#include "resource.h" -#else -long _dwOperatingSystemVersion; -#ifndef __APPLE__ -#include <sys/sysinfo.h> -#else -#include <mach/mach_host.h> -#include <sys/sysctl.h> -#endif -#include <stddef.h> -#include <locale.h> -#include <signal.h> -#include <errno.h> -#endif - #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS char gSelectedJoystickName[128] = ""; #endif @@ -218,6 +205,10 @@ psGrabScreen(RwCamera *pCamera) RwImageSetFromRaster(pImage, pRaster); return pImage; } +#else + rw::Image *image = RwCameraGetRaster(pCamera)->toImage(); + if(image) + return image; #endif return nil; } @@ -282,7 +273,11 @@ psMouseSetPos(RwV2d *pos) RwMemoryFunctions* psGetMemoryFunctions(void) { +#ifdef USE_CUSTOM_ALLOCATOR + return &memFuncs; +#else return nil; +#endif } /* @@ -878,6 +873,36 @@ void _InputInitialiseJoys() PSGLOBAL(joy1id) = -1; PSGLOBAL(joy2id) = -1; + // Load our gamepad mappings. +#define SDL_GAMEPAD_DB_PATH "gamecontrollerdb.txt" + FILE *f = fopen(SDL_GAMEPAD_DB_PATH, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + size_t fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *db = (char*)malloc(fsize + 1); + if (fread(db, 1, fsize, f) == fsize) { + db[fsize] = '\0'; + + if (glfwUpdateGamepadMappings(db) == GLFW_FALSE) + Error("glfwUpdateGamepadMappings didn't succeed, check " SDL_GAMEPAD_DB_PATH ".\n"); + } else + Error("fread on " SDL_GAMEPAD_DB_PATH " wasn't successful.\n"); + + free(db); + fclose(f); + } else + printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from re3/gamefiles to GTA3 directory. Some gamepads may not be recognized.\n"); + +#undef SDL_GAMEPAD_DB_PATH + + // But always overwrite it with the one in SDL_GAMECONTROLLERCONFIG. + char const* EnvControlConfig = getenv("SDL_GAMECONTROLLERCONFIG"); + if (EnvControlConfig != nil) { + glfwUpdateGamepadMappings(EnvControlConfig); + } + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { if (glfwJoystickPresent(i) && !IsThisJoystickBlacklisted(i)) { if (PSGLOBAL(joy1id) == -1) @@ -1204,15 +1229,15 @@ void InitialiseLanguage() } } - TheText.Unload(); - TheText.Load(); - #ifndef _WIN32 // TODO this is needed for strcasecmp to work correctly across all languages, but can these cause other problems?? setlocale(LC_CTYPE, "C"); setlocale(LC_COLLATE, "C"); setlocale(LC_NUMERIC, "C"); #endif + + TheText.Unload(); + TheText.Load(); } /* @@ -1494,6 +1519,10 @@ main(int argc, char *argv[]) RwV2d pos; RwInt32 i; +#ifdef USE_CUSTOM_ALLOCATOR + InitMemoryMgr(); +#endif + #ifndef _WIN32 struct sigaction act; act.sa_sigaction = terminateHandler; @@ -1608,6 +1637,13 @@ main(int argc, char *argv[]) { CFileMgr::SetDirMyDocuments(); +#ifdef LOAD_INI_SETTINGS + // At this point InitDefaultControlConfigJoyPad must have set all bindings to default and ms_padButtonsInited to number of detected buttons. + // We will load stored bindings below, but let's cache ms_padButtonsInited before LoadINIControllerSettings and LoadSettings clears it, + // so we can add new joy bindings **on top of** stored bindings. + int connectedPadButtons = ControlsManager.ms_padButtonsInited; +#endif + int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r"); if ( gta3set ) @@ -1617,6 +1653,14 @@ main(int argc, char *argv[]) } CFileMgr::SetDir(""); + +#ifdef LOAD_INI_SETTINGS + LoadINIControllerSettings(); + if (connectedPadButtons != 0) { + ControlsManager.InitDefaultControlConfigJoyPad(connectedPadButtons); + SaveINIControllerSettings(); + } +#endif } #ifdef _WIN32 @@ -2130,6 +2174,12 @@ void joysChangeCB(int jid, int event) #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS strcpy(gSelectedJoystickName, glfwGetJoystickName(jid)); #endif + // This is behind LOAD_INI_SETTINGS, because otherwise the Init call below will destroy/overwrite your bindings. +#ifdef LOAD_INI_SETTINGS + int count; + glfwGetJoystickButtons(PSGLOBAL(joy1id), &count); + ControlsManager.InitDefaultControlConfigJoyPad(count); +#endif } else if (PSGLOBAL(joy2id) == -1) PSGLOBAL(joy2id) = jid; diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index a21d5674..2bb23460 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -11,8 +11,7 @@ #include "skeleton.h" #include "platform.h" #include "main.h" - -// --MIAMI: file done +#include "MemoryHeap.h" static RwBool DefaultVideoMode = TRUE; diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index a437a3b4..4963450a 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -2,7 +2,6 @@ #define _WIN32_WINDOWS 0x0500 #define WINVER 0x0500 -#define DIRECTINPUT_VERSION 0x0800 #include <winerror.h> #include <windows.h> @@ -20,13 +19,7 @@ #pragma warning( push ) #pragma warning( disable : 4005) -#ifdef USE_D3D9 -#include <d3d9.h> -#else -#include <d3d8.h> -#endif #include <ddraw.h> -#include <dinput.h> #include <DShow.h> #pragma warning( pop ) @@ -41,6 +34,9 @@ #pragma comment( lib, "strmiids.lib" ) #pragma comment( lib, "dinput8.lib" ) +#define WITHD3D +#define WITHDINPUT +#include "common.h" #if (defined(_MSC_VER)) #include <tchar.h> #endif /* (defined(_MSC_VER)) */ @@ -53,8 +49,6 @@ #define MAX_SUBSYSTEMS (16) -// --MIAMI: file done - static RwBool ForegroundApp = TRUE; static RwBool RwInitialised = FALSE; @@ -83,7 +77,6 @@ static psGlobalType PsGlobal; #define JIF(x) if (FAILED(hr=(x))) \ {debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;} -#include "common.h" #include "main.h" #include "FileMgr.h" #include "Text.h" @@ -94,11 +87,14 @@ static psGlobalType PsGlobal; #include "Frontend.h" #include "Game.h" #include "PCSave.h" -#include "MemoryCard.h" -#include "Sprite2d.h" #include "AnimViewer.h" -#include "Font.h" +#include "MemoryMgr.h" +#ifdef PS2_MENU +#include "MemoryCard.h" +#include "Font.h" +#endif + VALIDATE_SIZE(psGlobalType, 0x28); // DirectShow interfaces @@ -256,6 +252,10 @@ psGrabScreen(RwCamera *pCamera) RwImageSetFromRaster(pImage, pRaster); return pImage; } +#else + rw::Image *image = RwCameraGetRaster(pCamera)->toImage(); + if(image) + return image; #endif return nil; } @@ -309,7 +309,11 @@ psMouseSetPos(RwV2d *pos) RwMemoryFunctions* psGetMemoryFunctions(void) { +#ifdef USE_CUSTOM_ALLOCATOR + return &memFuncs; +#else return nil; +#endif } /* @@ -2009,6 +2013,10 @@ WinMain(HINSTANCE instance, } #endif +#ifdef USE_CUSTOM_ALLOCATOR + InitMemoryMgr(); +#endif + /* * Initialize the platform independent data. * This will in turn initialize the platform specific data... @@ -2137,8 +2145,15 @@ WinMain(HINSTANCE instance, { CFileMgr::SetDirMyDocuments(); +#ifdef LOAD_INI_SETTINGS + // At this point InitDefaultControlConfigJoyPad must have set all bindings to default and ms_padButtonsInited to number of detected buttons. + // We will load stored bindings below, but let's cache ms_padButtonsInited before LoadINIControllerSettings and LoadSettings clears it, + // so we can add new joy bindings **on top of** stored bindings. + int connectedPadButtons = ControlsManager.ms_padButtonsInited; +#endif + int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r"); - + if ( gta3set ) { ControlsManager.LoadSettings(gta3set); @@ -2146,6 +2161,14 @@ WinMain(HINSTANCE instance, } CFileMgr::SetDir(""); + +#ifdef LOAD_INI_SETTINGS + LoadINIControllerSettings(); + if (connectedPadButtons != 0) { + ControlsManager.InitDefaultControlConfigJoyPad(connectedPadButtons); + SaveINIControllerSettings(); + } +#endif } SetErrorMode(SEM_FAILCRITICALERRORS); diff --git a/src/text/Messages.cpp b/src/text/Messages.cpp index db0865ae..81339ae0 100644 --- a/src/text/Messages.cpp +++ b/src/text/Messages.cpp @@ -11,8 +11,6 @@ #include "Font.h" -// --MIAMI: file done - tMessage CMessages::BriefMessages[NUMBRIEFMESSAGES]; tPreviousBrief CMessages::PreviousBriefs[NUMPREVIOUSBRIEFS]; tBigMessage CMessages::BIGMessages[NUMBIGMESSAGES]; diff --git a/src/text/Text.cpp b/src/text/Text.cpp index 5adc576a..5f55d4f7 100644 --- a/src/text/Text.cpp +++ b/src/text/Text.cpp @@ -9,8 +9,6 @@ #include "Text.h" #include "Timer.h" -//--MIAMI: file done - static wchar WideErrorString[25]; CText TheText; @@ -111,14 +109,14 @@ wchar* CText::Get(const char *key) { uint8 result = false; -#ifdef FIX_BUGS +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) wchar *outstr = keyArray.Search(key, data.chars, &result); #else wchar *outstr = keyArray.Search(key, &result); #endif if (!result && bHasMissionTextOffsets && bIsMissionTextLoaded) -#ifdef FIX_BUGS +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) outstr = mission_keyArray.Search(key, mission_data.chars, &result); #else outstr = mission_keyArray.Search(key, &result); @@ -205,7 +203,7 @@ CText::GetNameOfLoadedMissionText(char *outName) void CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset) { -#if DUMB +#if THIS_IS_STUPID char *_buf = (char*)buf; for (int i = 0; i < sizeof(ChunkHeader); i++) { CFileMgr::Read(file, &_buf[i], 1); @@ -318,7 +316,7 @@ CKeyArray::Load(size_t length, int file, size_t* offset) entries = new CKeyEntry[numEntries]; rawbytes = (char*)entries; -#if DUMB +#if THIS_IS_STUPID for (uint32 i = 0; i < length; i++) { CFileMgr::Read(file, &rawbytes[i], 1); (*offset)++; @@ -340,7 +338,7 @@ CKeyArray::Unload(void) void CKeyArray::Update(wchar *chars) { -#ifndef FIX_BUGS +#if !defined(FIX_BUGS) && !defined(FIX_BUGS_64) int i; for(i = 0; i < numEntries; i++) entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value); @@ -368,7 +366,7 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi } wchar* -#ifdef FIX_BUGS +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) CKeyArray::Search(const char *key, wchar *data, uint8 *result) #else CKeyArray::Search(const char *key, uint8 *result) @@ -378,7 +376,7 @@ CKeyArray::Search(const char *key, uint8 *result) char errstr[25]; int i; -#ifdef FIX_BUGS +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) found = BinarySearch(key, entries, 0, numEntries-1); if (found) { *result = true; @@ -412,7 +410,7 @@ CData::Load(size_t length, int file, size_t * offset) chars = new wchar[numChars]; rawbytes = (char*)chars; -#if DUMB +#if THIS_IS_STUPID for(uint32 i = 0; i < length; i++){ CFileMgr::Read(file, &rawbytes[i], 1); (*offset)++; @@ -434,7 +432,7 @@ CData::Unload(void) void CMissionTextOffsets::Load(size_t table_size, int file, size_t *offset, int) { -#if DUMB +#if THIS_IS_STUPID size_t num_of_entries = table_size / sizeof(CMissionTextOffsets::Entry); for (size_t mi = 0; mi < num_of_entries; mi++) { for (uint32 i = 0; i < sizeof(data[mi].szMissionName); i++) { diff --git a/src/text/Text.h b/src/text/Text.h index 33dc313e..1174216c 100644 --- a/src/text/Text.h +++ b/src/text/Text.h @@ -7,7 +7,7 @@ void TextCopy(wchar *dst, const wchar *src); struct CKeyEntry { -#ifdef FIX_BUGS +#if defined(FIX_BUGS) || defined(FIX_BUGS_64) uint32 valueOffset; #else wchar *value; @@ -30,7 +30,7 @@ public: void Unload(void); void Update(wchar *chars); CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high); -#ifdef FIX_BUGS +#if defined (FIX_BUGS) || defined(FIX_BUGS_64) wchar *Search(const char *key, wchar *data, uint8 *result); #else wchar *Search(const char *key, uint8* result); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 251dac30..961b8108 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -49,8 +49,7 @@ #include "Object.h" #include "Automobile.h" #include "Bike.h" - -//--MIAMI: file done +#include "Wanted.h" bool bAllCarCheat; @@ -252,12 +251,15 @@ CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f); CVector vecDAMAGE_ENGINE_POS_SMALL(-0.1f, -0.1f, 0.0f); CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f); +#pragma optimize("", off) // a workaround for another compiler bug + void CAutomobile::ProcessControl(void) { int i; float wheelRot; CColModel *colModel; + float brake = 0.0f; if(bUsingSpecialColModel) colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; @@ -285,17 +287,17 @@ CAutomobile::ProcessControl(void) // Improve grip of vehicles in certain cases bool strongGrip1 = false; bool strongGrip2 = false; - if(FindPlayerVehicle() && this != FindPlayerVehicle() && + if(FindPlayerVehicle() && this != FindPlayerVehicle() && FindPlayerPed()->m_pWanted->GetWantedLevel() > 3 && (AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY || AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE || - AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_FARAWAY || AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_CLOSE)){ - if(FindPlayerSpeed().Magnitude() > 0.3f){ - strongGrip1 = true; - if(FindPlayerSpeed().Magnitude() > 0.4f && - m_vecMoveSpeed.Magnitude() < 0.3f) - strongGrip2 = true; - else if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f) - strongGrip2 = true; - } + AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_FARAWAY || AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_CLOSE) && + FindPlayerSpeed().Magnitude() > 0.3f){ + + strongGrip1 = true; + if(FindPlayerSpeed().Magnitude() > 0.4f && + m_vecMoveSpeed.Magnitude() < 0.3f) + strongGrip2 = true; + else if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f) + strongGrip2 = true; }else if(GetModelIndex() == MI_RCBANDIT && GetStatus() != STATUS_PLAYER_REMOTE) strongGrip1 = true; @@ -448,7 +450,7 @@ CAutomobile::ProcessControl(void) m_fBrakePedal = 1.0f; m_fGasPedal = 0.0f; } - if(CPad::GetPad(0)->WeaponJustDown()) + if(CPad::GetPad(0)->CarGunJustDown()) ActivateBomb(); break; @@ -680,7 +682,6 @@ CAutomobile::ProcessControl(void) AutoPilot.m_nCarMission == MISSION_PLANE_FLYTOCOORS) skipPhysics = true; - float brake; if(skipPhysics){ bHasContacted = false; bIsInSafePosition = false; @@ -735,7 +736,7 @@ CAutomobile::ProcessControl(void) float fwdSpeed = Abs(DotProduct(m_vecMoveSpeed, GetForward())); CVector contactPoints[4]; // relative to model CVector contactSpeeds[4]; // speed at contact points - CVector springDirections[4]; // normalized, in model space + CVector springDirections[4]; // normalized, in world space for(i = 0; i < 4; i++){ // Set spring under certain circumstances @@ -809,7 +810,7 @@ CAutomobile::ProcessControl(void) // dampen springs for(i = 0; i < 4; i++) - if(m_aSuspensionSpringRatio[i] < 1.0f) + if(m_aSuspensionSpringRatio[i] < 0.99999f) ApplySpringDampening(pHandling->fSuspensionDampingLevel, springDirections[i], contactPoints[i], contactSpeeds[i]); @@ -835,11 +836,16 @@ CAutomobile::ProcessControl(void) if(bAudioChangingGear && m_fGasPedal > 0.4f && m_fBrakePedal < 0.1f && fwdSpeed > 0.15f && this == FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){ - if(GetStatus() == STATUS_PLAYER && pHandling->Flags & HANDLING_IS_BUS){ + if(GetStatus() == STATUS_PLAYER && !(pHandling->Flags & HANDLING_IS_BUS)){ if(m_nBusDoorTimerEnd == 0) m_nBusDoorTimerEnd = 1000; - else if(m_nBusDoorTimerEnd > CTimer::GetTimeStepInMilliseconds()) - m_nBusDoorTimerEnd -= CTimer::GetTimeStepInMilliseconds(); + else { + uint32 timeStepInMs = CTimer::GetTimeStepInMilliseconds(); + if(m_nBusDoorTimerEnd > timeStepInMs) + m_nBusDoorTimerEnd -= timeStepInMs; + else + m_nBusDoorTimerEnd = 0; + } } if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) && @@ -850,7 +856,7 @@ CAutomobile::ProcessControl(void) brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep(); bool neutralHandling = GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && (pHandling->Flags & HANDLING_NEUTRALHANDLING); float brakeBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias; - float brakeBiasRear = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fBrakeBias); + float brakeBiasRear = neutralHandling ? 1.0f : 2.0f-pHandling->fBrakeBias; // looks like a bug, but it was correct in III... float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias; float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront; @@ -918,10 +924,10 @@ CAutomobile::ProcessControl(void) CVector wheelFwd, wheelRight, tmp; if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal; @@ -938,7 +944,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB); WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT], m_nWheelsOnGround, fThrust, @@ -961,10 +967,10 @@ CAutomobile::ProcessControl(void) } if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal; @@ -981,7 +987,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB); WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT], m_nWheelsOnGround, fThrust, @@ -1008,9 +1014,7 @@ CAutomobile::ProcessControl(void) if(!IsRealHeli()){ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f; - else{ + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f) m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f; @@ -1018,13 +1022,13 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f) m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f; } m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT]; } if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f; - else{ + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f) m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f; @@ -1032,6 +1036,8 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f) m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f; } m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT]; } @@ -1042,7 +1048,7 @@ CAutomobile::ProcessControl(void) if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){ CVector wheelFwd = GetForward(); - CVector wheelRight = GetRight(); + CVector wheelRight = GetRight(); // overwritten for resp. wheel float rearBrake = brake; float rearTraction = traction; @@ -1058,7 +1064,7 @@ CAutomobile::ProcessControl(void) if(m_fTireTemperature > 2.0f) m_fTireTemperature = 2.0f; } - }else if(m_doingBurnout && !mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)){ + }else if(m_doingBurnout && mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)){ rearBrake = 0.0f; rearTraction = 0.0f; // BUG: missing timestep @@ -1068,12 +1074,11 @@ CAutomobile::ProcessControl(void) } if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){ - if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; - wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal)*m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal; wheelFwd.Normalise(); wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal); @@ -1085,7 +1090,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB); WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT]; - if(Damage.GetWheelStatus(VEHWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT], m_nWheelsOnGround, fThrust, @@ -1110,16 +1115,15 @@ CAutomobile::ProcessControl(void) #ifdef FIX_BUGS // Shouldn't we reset these after the left wheel? wheelFwd = GetForward(); - wheelRight = GetRight(); + wheelRight = GetRight(); // actually useless #endif if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){ - if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; - wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal; wheelFwd.Normalise(); wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal); @@ -1131,7 +1135,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB); WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT]; - if(Damage.GetWheelStatus(VEHWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT], m_nWheelsOnGround, fThrust, @@ -1154,7 +1158,7 @@ CAutomobile::ProcessControl(void) } } - if(m_doingBurnout && !mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && + if(m_doingBurnout && mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && (m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING || m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)){ m_fTireTemperature += 0.001f*CTimer::GetTimeStep(); if(m_fTireTemperature > 3.0f) @@ -1167,9 +1171,9 @@ CAutomobile::ProcessControl(void) if(!IsRealHeli()){ if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){ - if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f; - else{ + if(bIsHandbrakeOn) + m_aWheelSpeed[CARWHEEL_REAR_LEFT] = 0.0f; + else if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] < 2.0f) m_aWheelSpeed[CARWHEEL_REAR_LEFT] -= 0.2f; @@ -1177,13 +1181,15 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] > -2.0f) m_aWheelSpeed[CARWHEEL_REAR_LEFT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f; } m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT]; } if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){ - if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f; - else{ + if(bIsHandbrakeOn) + m_aWheelSpeed[CARWHEEL_REAR_RIGHT] = 0.0f; + else if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] < 2.0f) m_aWheelSpeed[CARWHEEL_REAR_RIGHT] -= 0.2f; @@ -1191,6 +1197,8 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] > -2.0f) m_aWheelSpeed[CARWHEEL_REAR_RIGHT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f; } m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT]; } @@ -1206,10 +1214,10 @@ CAutomobile::ProcessControl(void) CVector wheelFwd, wheelRight, tmp; if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal; @@ -1226,7 +1234,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB); WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT], m_nWheelsOnGround, fThrust, @@ -1249,10 +1257,10 @@ CAutomobile::ProcessControl(void) } if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)) - fThrust = 0.0f; - else + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) fThrust = acceleration; + else + fThrust = 0.0f; wheelFwd = GetForward(); wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal; @@ -1269,7 +1277,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB); WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT], m_nWheelsOnGround, fThrust, @@ -1296,9 +1304,7 @@ CAutomobile::ProcessControl(void) if (!IsRealHeli()) { if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f; - else{ + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f) m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f; @@ -1306,13 +1312,13 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f) m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f; } m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT]; } if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){ - if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f) - m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f; - else{ + if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){ if(acceleration > 0.0f){ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f) m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f; @@ -1320,6 +1326,8 @@ CAutomobile::ProcessControl(void) if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f) m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f; } + }else{ + m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f; } m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT]; } @@ -1415,7 +1423,12 @@ CAutomobile::ProcessControl(void) if (GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_RCGOBLIN) FlyingControl(FLIGHT_MODEL_RCHELI); else if (m_nWheelsOnGround < 4 && !(GetModelIndex() == MI_SEASPAR && bTouchingWater) || - CPad::GetPad(0)->GetAccelerate() != 0 || CPad::GetPad(0)->GetCarGunUpDown() > 1.0f || + CPad::GetPad(0)->GetAccelerate() != 0 || +#ifndef FREE_CAM + CPad::GetPad(0)->GetCarGunUpDown() > 1.0f || +#else + ((!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) && CPad::GetPad(0)->GetCarGunUpDown() > 1.0f) || +#endif Abs(m_vecMoveSpeed.x) > 0.02f || Abs(m_vecMoveSpeed.y) > 0.02f || Abs(m_vecMoveSpeed.z) > 0.02f) @@ -1674,8 +1687,8 @@ CAutomobile::ProcessControl(void) Abs(m_vecMoveSpeed.y) < 0.005f && Abs(m_vecMoveSpeed.z) < 0.005f && !(m_fDamageImpulse > 0.0f && m_pDamageEntity == FindPlayerPed()) && - (m_aSuspensionSpringRatioPrev[0] < 1.0f && m_aSuspensionSpringRatioPrev[1] < 1.0f && - m_aSuspensionSpringRatioPrev[2] < 1.0f && m_aSuspensionSpringRatioPrev[3] < 1.0f)){ + (m_aSuspensionSpringRatioPrev[0] < 1.0f || m_aSuspensionSpringRatioPrev[1] < 1.0f || + m_aSuspensionSpringRatioPrev[2] < 1.0f || m_aSuspensionSpringRatioPrev[3] < 1.0f)){ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecTurnSpeed.z = 0.0f; } @@ -1699,6 +1712,8 @@ CAutomobile::ProcessControl(void) } } +#pragma optimize("", on) + void CAutomobile::Teleport(CVector pos) { @@ -1720,11 +1735,11 @@ CAutomobile::PreRender(void) int i, j, n; CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); - if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){ + if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_WINDSCREEN]){ // Rotate Rhino turret CMatrix m; CVector p; - m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET])); + m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN])); p = m.GetPosition(); m.SetRotateZ(m_fCarGunLR); m.Translate(p); @@ -3188,7 +3203,11 @@ CAutomobile::ProcessControlInputs(uint8 pad) // Brake if player isn't in control // BUG: game always uses pad 0 here +#ifdef FIX_BUGS if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){ +#else + if(CPad::GetPad(0)->ArePlayerControlsDisabled()){ +#endif m_fBrakePedal = 1.0f; bIsHandbrakeOn = true; m_fGasPedal = 0.0f; @@ -3206,7 +3225,7 @@ void CAutomobile::FireTruckControl(void) { if(this == FindPlayerVehicle()){ - if(!CPad::GetPad(0)->GetWeapon()) + if(!CPad::GetPad(0)->GetCarGunFired()) return; #ifdef FREE_CAM if (!CCamera::bFreeCam) @@ -3835,7 +3854,7 @@ CAutomobile::DoDriveByShootings(void) return; CWeapon *weapon = pDriver->GetWeapon(); - if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5) + if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != WEAPONSLOT_SUBMACHINEGUN) return; weapon->Update(pDriver->m_audioEntityId, nil); @@ -4862,10 +4881,10 @@ CAutomobile::BurstTyre(uint8 wheel, bool applyForces) return; switch(wheel){ - case CAR_PIECE_WHEEL_LF: wheel = VEHWHEEL_FRONT_LEFT; break; - case CAR_PIECE_WHEEL_LR: wheel = VEHWHEEL_REAR_LEFT; break; - case CAR_PIECE_WHEEL_RF: wheel = VEHWHEEL_FRONT_RIGHT; break; - case CAR_PIECE_WHEEL_RR: wheel = VEHWHEEL_REAR_RIGHT; break; + case CAR_PIECE_WHEEL_LF: wheel = CARWHEEL_FRONT_LEFT; break; + case CAR_PIECE_WHEEL_RF: wheel = CARWHEEL_FRONT_RIGHT; break; + case CAR_PIECE_WHEEL_LR: wheel = CARWHEEL_REAR_LEFT; break; + case CAR_PIECE_WHEEL_RR: wheel = CARWHEEL_REAR_RIGHT; break; } int status = Damage.GetWheelStatus(wheel); @@ -5074,7 +5093,7 @@ CAutomobile::BlowUpCarsInPath(void) m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO && !m_aCollisionRecords[i]->bRenderScorched){ if(this == FindPlayerVehicle()) - CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, this, FindPlayerPed(), 2000); + CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, m_aCollisionRecords[i], FindPlayerPed(), 2000); ((CVehicle*)m_aCollisionRecords[i])->BlowUpCar(this); } } @@ -5110,7 +5129,6 @@ CAutomobile::HasCarStoppedBecauseOfLight(void) return false; } -// --MIAMI: Done void CPed::DeadPedMakesTyresBloody(void) { @@ -5134,7 +5152,6 @@ CPed::DeadPedMakesTyresBloody(void) } } -// --MIAMI: Done void CPed::MakeTyresMuddySectorList(CPtrList &list) { @@ -5245,7 +5262,6 @@ CPed::MakeTyresMuddySectorList(CPtrList &list) } } - void CAutomobile::SetBusDoorTimer(uint32 timer, uint8 type) { @@ -5602,7 +5618,7 @@ CAutomobile::SetBumperDamage(int32 component, ePanels panel, bool noFlyingCompon int status = Damage.GetPanelStatus(panel); if(m_aCarNodes[component] == nil){ printf("Trying to damage component %d of %s\n", - component, CModelInfo::GetModelInfo(GetModelIndex())->GetName()); + component, CModelInfo::GetModelInfo(GetModelIndex())->GetModelName()); return; } if(status == PANEL_STATUS_SMASHED1){ @@ -5622,7 +5638,7 @@ CAutomobile::SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents int status = Damage.GetDoorStatus(door); if(m_aCarNodes[component] == nil){ printf("Trying to damage component %d of %s\n", - component, CModelInfo::GetModelInfo(GetModelIndex())->GetName()); + component, CModelInfo::GetModelInfo(GetModelIndex())->GetModelName()); return; } @@ -5764,7 +5780,7 @@ CAutomobile::PopBoot(void) case DOOR_STATUS_OK: case DOOR_STATUS_SMASHED: Doors[DOOR_BOOT].m_fAngle = Doors[DOOR_BOOT].m_fMinAngle; - CMatrix mat(RwFrameGetMatrix(m_aCarNodes[DOOR_BOOT])); + CMatrix mat(RwFrameGetMatrix(m_aCarNodes[CAR_BOOT])); CVector pos = mat.GetPosition(); float axes[3] = { 0.0f, 0.0f, 0.0f }; axes[Doors[DOOR_BOOT].m_nAxis] = Doors[DOOR_BOOT].m_fAngle; @@ -5781,7 +5797,7 @@ CAutomobile::PopBootUsingPhysics(void) case DOOR_STATUS_OK: case DOOR_STATUS_SMASHED: Damage.SetDoorStatus(DOOR_BOOT, DOOR_STATUS_SWINGING); - Doors[DOOR_BOOT].m_fAngle = -2.0f; + Doors[DOOR_BOOT].m_fAngVel = -2.0f; } void @@ -5809,7 +5825,7 @@ CAutomobile::KnockPedOutCar(eWeaponType weapon, uint16 door, CPed *ped) if(ped == nil) return; - ped->m_vehEnterType = door; + ped->m_vehDoor = door; ped->SetPedState(PED_IDLE); CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_IDLE_STANCE, 100.0f); CPed::PedSetOutCarCB(nil, ped); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index b2f0643c..16d86917 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -7,8 +7,6 @@ class CObject; -// These are used for all the wheel arrays -// DON'T confuse with VEHWHEEL, which are vehicle components enum { CARWHEEL_FRONT_LEFT, CARWHEEL_REAR_LEFT, @@ -35,6 +33,9 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 m_auto_unused2; +#if (defined GTA_PS2 && !defined FIX_BUGS) + uint8 m_bombType : 3; +#endif uint8 bTaxiLight : 1; uint8 bFixedColour : 1; uint8 bBigWheels : 1; @@ -44,6 +45,9 @@ public: uint8 bTankDetonateCars : 1; uint8 bStuckInSand : 1; uint8 bHeliDestroyed : 1; +#if (defined GTA_PS2 && !defined FIX_BUGS) + CEntity* m_pBombRigger; +#endif int16 m_doingBurnout; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp index 30d63aca..a84a43e5 100644 --- a/src/vehicles/Bike.cpp +++ b/src/vehicles/Bike.cpp @@ -37,8 +37,6 @@ #include "Bike.h" #include "Debug.h" -//--MIAMI: file done - const uint32 CBike::nSaveStructSize = #ifdef COMPATIBLE_SAVES 1260; @@ -202,9 +200,11 @@ CVector vecTestResistance(0.9995f, 0.9f, 0.95f); float fDAxisX = 1.0f; float fDAxisXExtra = 100.0f; float fDAxisY = 1000.0f; -float fInAirXRes = 0.88f; +float fInAirXRes = 0.98f; float fFlySpeedMult = -0.6f; +#pragma optimize("", off) // a workaround for another compiler bug =P, original had optimize off for this function too though + void CBike::ProcessControl(void) { @@ -476,7 +476,7 @@ CBike::ProcessControl(void) if(m_vecMoveSpeedAvg.MagnitudeSqr() <= sq(moveSpeedLimit*CTimer::GetTimeStep()) && m_vecTurnSpeedAvg.MagnitudeSqr() <= sq(turnSpeedLimit*CTimer::GetTimeStep()) && - m_fDistanceTravelled < distanceLimit && + m_fDistanceTravelled < distanceLimit || makeStatic){ m_nStaticFrames++; @@ -1144,7 +1144,12 @@ CBike::ProcessControl(void) float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[i]; if(suspChange > 0.3f && (i == BIKESUSP_F1 || i == BIKESUSP_R1) && speedsq > 0.04f){ if(GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PHYSICS){ +#ifdef FIX_BUGS + // only two wheels but 4 suspensions + if(m_wheelStatus[i/2] == WHEEL_STATUS_BURST) +#else if(m_wheelStatus[i] == WHEEL_STATUS_BURST) +#endif DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange); else DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, suspChange); @@ -1213,7 +1218,8 @@ CBike::ProcessControl(void) // Balance bike if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){ - float onSideness = clamp(DotProduct(GetRight(), m_vecAvgSurfaceNormal), -1.0f, 1.0f); + float onSideness = DotProduct(GetRight(), m_vecAvgSurfaceNormal); + onSideness = clamp(onSideness, -1.0f, 1.0f); CVector worldCOM = Multiply3x3(GetMatrix(), m_vecCentreOfMass); // Keep bike upright if(bBalancedByRider){ @@ -1256,6 +1262,8 @@ CBike::ProcessControl(void) } } +#pragma optimize("", on) + void CBike::Teleport(CVector pos) { @@ -1596,7 +1604,7 @@ CBike::PreRender(void) CVector forkAxis(0.0f, Sin(DEGTORAD(mi->m_bikeSteerAngle)), -Cos(DEGTORAD(mi->m_bikeSteerAngle))); forkAxis.Normalise(); // as if that's not already the case CQuaternion quat; - quat.Set((RwV3d*)&forkAxis, -m_fWheelAngle); + quat.Set(&forkAxis, -m_fWheelAngle); quat.Get(rot.m_attachment); rot.Update(); @@ -1834,7 +1842,12 @@ CBike::ProcessControlInputs(uint8 pad) m_fSteerInput = clamp(m_fSteerInput, -1.0f, 1.0f); // Lean forward/backward - float updown = -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f + CPad::GetPad(pad)->GetCarGunUpDown()/128.0f; + float updown; +#ifdef FREE_CAM + if (CCamera::bFreeCam) updown = CPad::IsAffectedByController ? -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f : CPad::GetPad(pad)->GetCarGunUpDown()/128.0f; + else +#endif + updown = -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f + CPad::GetPad(pad)->GetCarGunUpDown()/128.0f; m_fLeanInput += (updown - m_fLeanInput)*0.2f*CTimer::GetTimeStep(); m_fLeanInput = clamp(m_fLeanInput, -1.0f, 1.0f); @@ -2599,7 +2612,7 @@ CBike::KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBa ped->SetPedState(PED_IDLE); CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_IDLE_STANCE, 100.0f); - ped->m_vehEnterType = CAR_DOOR_LF; + ped->m_vehDoor = CAR_DOOR_LF; CPed::PedSetOutCarCB(nil, ped); ped->SetMoveState(PEDMOVE_STILL); if(GetUp().z < 0.0f) @@ -2684,7 +2697,7 @@ CBike::KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBa switch(direction){ case 0: anim = ANIM_KO_SKID_BACK; break; case 1: anim = ANIM_KD_RIGHT; break; - case 2: anim = ANIM_KO_SKID_FRONT; break; + case 2: anim = ANIM_BIKE_FALL_R; break; case 3: anim = ANIM_KD_LEFT; break; } if(m_nWheelsOnGround == 0) diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h index 3fcf66a2..219d8872 100644 --- a/src/vehicles/Bike.h +++ b/src/vehicles/Bike.h @@ -2,6 +2,7 @@ #include "Vehicle.h" #include "Skidmarks.h" +#include "AnimManager.h" enum eBikeNodes { BIKE_NODE_NONE, diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index feaa80de..5aed5814 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -27,20 +27,19 @@ #include "RpAnimBlend.h" #include "Record.h" #include "Shadows.h" - -//--MIAMI: file done +#include "Wanted.h" #define INVALID_ORIENTATION (-9999.99f) -float fShapeLength = 0.4f; -float fShapeTime = 0.05f; -float fRangeMult = 0.6f; -float fTimeMult; - float CBoat::MAX_WAKE_LENGTH = 50.0f; float CBoat::MIN_WAKE_INTERVAL = 2.0f; float CBoat::WAKE_LIFETIME = 150.0f; +float fShapeLength = 0.4f; +float fShapeTime = 0.05f; +float fRangeMult = 0.6f; +float fTimeMult = 1.2f/CBoat::WAKE_LIFETIME; + CBoat *CBoat::apFrameWakeGeneratingBoats[4]; const uint32 CBoat::nSaveStructSize = @@ -135,9 +134,9 @@ CBoat::ProcessControl(void) m_fBuoyancy *= 0.99f; #ifdef FIX_BUGS - if(FindPlayerPed() && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && GetModelIndex() == MI_PREDATOR){ + if(FindPlayerPed() && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && GetModelIndex() == MI_PREDATOR){ #else - if(FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && GetModelIndex() == MI_PREDATOR){ + if(FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && GetModelIndex() == MI_PREDATOR){ #endif CVehicle *playerVeh = FindPlayerVehicle(); if(playerVeh && playerVeh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT && @@ -443,7 +442,7 @@ CBoat::ProcessControl(void) CVector wakePos = GetPosition() + sternPos; // no actual particles for player... }else if(IsVisible() && ((CTimer::GetFrameCounter() + m_randomSeed) & 1) && - CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&propellerWorld) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ + CVisibilityPlugins::GetDistanceSquaredFromCamera(&propellerWorld) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ jetDir.z = 0.015f; jetDir.x *= 3.5f; jetDir.y *= 3.5f; @@ -613,7 +612,7 @@ CBoat::ProcessControl(void) splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater; CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true); if(splashPos.z-waterLevel < 3.0f && - CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ + CVisibilityPlugins::GetDistanceSquaredFromCamera(&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ splashPos.z = waterLevel + 0.1f; CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashPos, 0.75f*splashDir, nil, splashSize+0.1f, splashColor, CGeneral::GetRandomNumberInRange(0.0f, 10.0f), CGeneral::GetRandomNumberInRange(0.0f, 90.0f), @@ -670,7 +669,7 @@ CBoat::ProcessControl(void) splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater; CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true); if(splashPos.z-waterLevel < 3.0f && - CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ + CVisibilityPlugins::GetDistanceSquaredFromCamera(&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){ splashPos.z = waterLevel + 0.1f; CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashPos, 0.75f*splashDir, nil, splashSize+0.1f, splashColor, CGeneral::GetRandomNumberInRange(0.0f, 10.0f), CGeneral::GetRandomNumberInRange(0.0f, 90.0f), @@ -964,7 +963,14 @@ CBoat::PreRender(void) // FIX: Planes can also be controlled with GetCarGunUpDown #ifdef FIX_BUGS static float steeringUpDown = 0.0f; - steeringUpDown += ((Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f ? (-CPad::GetPad(0)->GetCarGunUpDown() / 128.0f) : (-CPad::GetPad(0)->GetSteeringUpDown() / 128.0f)) - steeringUpDown) * Min(1.f, CTimer::GetTimeStep() / 5.f); +#ifdef FREE_CAM + if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) +#endif + steeringUpDown += ((Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f ? (-CPad::GetPad(0)->GetCarGunUpDown()/128.0f) : (-CPad::GetPad(0)->GetSteeringUpDown()/128.0f)) - steeringUpDown) * Min(1.f, CTimer::GetTimeStep()/5.f); +#ifdef FREE_CAM + else + steeringUpDown = -CPad::GetPad(0)->GetSteeringUpDown()/128.0f; +#endif #else float steeringUpDown = -CPad::GetPad(0)->GetSteeringUpDown()/128.0f; #endif @@ -1246,7 +1252,7 @@ CBoat::Teleport(CVector v) CWorld::Add(this); } -//--MIAMI: unused +// unused bool CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats) { @@ -1278,7 +1284,7 @@ CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats) return numVerts != 0; } -//--MIAMI: unused +// unused float CBoat::IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat) { diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index 77d66cbf..78e67d49 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -18,8 +18,6 @@ #include "Zones.h" #include "Occlusion.h" -// --MIAMI: file done - uint8 CTheCarGenerators::ProcessCounter; uint32 CTheCarGenerators::NumOfCarGenerators; CCarGenerator CTheCarGenerators::CarGeneratorArray[NUM_CARGENS]; diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp index 2a571a67..b5926867 100644 --- a/src/vehicles/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -12,8 +12,6 @@ #include "Object.h" #include "World.h" -// --MIAMI: file done - #define MAX_DISTANCE_TO_FIND_CRANE (10.0f) #define CRANE_UPDATE_RADIUS (300.0f) #define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f) @@ -629,11 +627,11 @@ void CCranes::Save(uint8* buf, uint32* size) for (int i = 0; i < NUM_CRANES; i++) { CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]); if (pCrane->m_pCraneEntity != nil) - pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex(pCrane->m_pCraneEntity) + 1); + pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pCrane->m_pCraneEntity) + 1); if (pCrane->m_pHook != nil) - pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pCrane->m_pHook) + 1); + pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pCrane->m_pHook) + 1); if (pCrane->m_pVehiclePickedUp != nil) - pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex(pCrane->m_pVehiclePickedUp) + 1); + pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pCrane->m_pVehiclePickedUp) + 1); } VALIDATESAVEBUF(*size); diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h index 45ea7a8d..e842ed3f 100644 --- a/src/vehicles/Cranes.h +++ b/src/vehicles/Cranes.h @@ -11,7 +11,7 @@ class CBuilding; class CCrane { public: - enum CraneState : uint8 { + enum CraneState { IDLE = 0, GOING_TOWARDS_TARGET = 1, LIFTING_TARGET = 2, @@ -19,7 +19,7 @@ public: ROTATING_TARGET = 4, DROPPING_TARGET = 5 }; - enum CraneStatus : uint8 { + enum CraneStatus { NONE = 0, ACTIVATED = 1, DEACTIVATED = 2 @@ -46,8 +46,8 @@ public: CVector2D m_vecHookVelocity; CVehicle *m_pVehiclePickedUp; uint32 m_nTimeForNextCheck; - CraneStatus m_nCraneStatus; - CraneState m_nCraneState; + uint8 m_nCraneStatus; + uint8 m_nCraneState; uint8 m_nVehiclesCollected; bool m_bIsCrusher; bool m_bIsMilitaryCrane; @@ -88,7 +88,7 @@ public: static bool IsThisCarBeingCarriedByAnyCrane(CVehicle* pVehicle); static bool IsThisCarBeingTargettedByAnyCrane(CVehicle* pVehicle); static void Save(uint8* buf, uint32* size); - static void Load(uint8* buf, uint32 size); // on mobile it's CranesLoad outside of the class + static void Load(uint8* buf, uint32 size); // out of class in III PC and later because of SecuROM static uint32 CarsCollectedMilitaryCrane; static int32 NumCranes; diff --git a/src/vehicles/Floater.cpp b/src/vehicles/Floater.cpp index 92e3d80e..08688a3c 100644 --- a/src/vehicles/Floater.cpp +++ b/src/vehicles/Floater.cpp @@ -7,8 +7,6 @@ #include "Vehicle.h" #include "Floater.h" -//--MIAMI: done - cBuoyancy mod_Buoyancy; float fVolMultiplier = 1.0f; diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp index f96835d3..8438c5c9 100644 --- a/src/vehicles/HandlingMgr.cpp +++ b/src/vehicles/HandlingMgr.cpp @@ -2,10 +2,9 @@ #include "main.h" #include "FileMgr.h" +#include "Physical.h" #include "HandlingMgr.h" -//--MIAMI: done - cHandlingDataMgr mod_HandlingManager; const char *HandlingFilename = "HANDLING.CFG"; @@ -172,7 +171,7 @@ cHandlingDataMgr::LoadHandlingData(void) end = start+1; // yeah, this is kinda crappy - if(strncmp(line, ";the end", 9) == 0) + if(strcmp(line, ";the end") == 0) keepGoing = 0; else if(line[0] != ';'){ if(line[0] == '!'){ @@ -299,7 +298,7 @@ cHandlingDataMgr::LoadHandlingData(void) case 11: handling->fTractionBias = atof(word); break; case 12: handling->Transmission.nNumberOfGears = atoi(word); break; case 13: handling->Transmission.fMaxVelocity = atof(word); break; - case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4f; break; + case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break; case 15: handling->Transmission.nDriveType = word[0]; break; case 16: handling->Transmission.nEngineType = word[0]; break; case 17: handling->fBrakeDeceleration = atof(word); break; @@ -348,39 +347,45 @@ cHandlingDataMgr::FindExactWord(const char *word, const char *words, int wordLen void cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling) { - // TODO: figure out what exactly is being converted here - float velocity, a, b, specificVolume; + // convert distance to m, time to 1/50s + float velocity, a, b; - handling->Transmission.fEngineAcceleration /= 2500.0f; - handling->Transmission.fMaxVelocity /= 180.0f; - handling->fBrakeDeceleration /= 2500.0f; + handling->Transmission.fEngineAcceleration *= 1.0f/(50.0f*50.0f); + handling->Transmission.fMaxVelocity *= 1000.0f/(60.0f*60.0f * 50.0f); + handling->fBrakeDeceleration *= 1.0f/(50.0f*50.0f); handling->fTurnMass = (sq(handling->Dimension.x) + sq(handling->Dimension.y)) * handling->fMass / 12.0f; if(handling->fTurnMass < 10.0f) handling->fTurnMass *= 5.0f; handling->fInvMass = 1.0f/handling->fMass; handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass; - handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * 0.008f*handling->fMass; + handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->fMass; - // What the hell is going on here? - specificVolume = handling->Dimension.x*handling->Dimension.z*0.5f / handling->fMass; // ? + // Don't quite understand this. What seems to be going on is that + // we calculate a drag (air resistance) deceleration for a given velocity and + // find the intersection between that and the max engine acceleration. + // at that point the car cannot accelerate any further and we've found the max velocity. a = 0.0f; b = 100.0f; velocity = handling->Transmission.fMaxVelocity; while(a < b && velocity > 0.0f){ velocity -= 0.01f; + // what's the 1/6? a = handling->Transmission.fEngineAcceleration/6.0f; - b = -velocity * (1.0f/(specificVolume * sq(velocity) + 1.0f) - 1.0f); + // no density or drag coefficient here... + float a_drag = 0.5f*SQR(velocity) * handling->Dimension.x*handling->Dimension.z / handling->fMass; + // can't make sense of this... maybe v - v/(drag + 1) ? but that doesn't make so much sense either + b = -velocity * (1.0f/(a_drag + 1.0f) - 1.0f); } if(handling->nIdentifier == HANDLING_RCBANDIT){ - handling->Transmission.fUnkMaxVelocity = handling->Transmission.fMaxVelocity; + handling->Transmission.fMaxCruiseVelocity = handling->Transmission.fMaxVelocity; handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity; }else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){ - handling->Transmission.fUnkMaxVelocity = velocity; + handling->Transmission.fMaxCruiseVelocity = velocity; handling->Transmission.fMaxVelocity = velocity * 1.2f; handling->Transmission.fMaxReverseVelocity = -0.05f; }else{ - handling->Transmission.fUnkMaxVelocity = velocity; + handling->Transmission.fMaxCruiseVelocity = velocity; handling->Transmission.fMaxVelocity = velocity * 1.2f; handling->Transmission.fMaxReverseVelocity = -0.2f; } diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index 52e69441..8d290f7d 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -120,6 +120,11 @@ enum tVehicleType NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR, }; +enum tField // most likely a handling field enum, never used so :shrug: +{ + +}; + enum { HANDLING_1G_BOOST = 1, @@ -170,7 +175,7 @@ struct tHandlingData float fSteeringLock; float fTractionLoss; float fTractionBias; - float fABS; // should be VC leftover + float fUnused; float fSuspensionForceLevel; float fSuspensionDampingLevel; float fSuspensionUpperLimit; @@ -239,6 +244,8 @@ struct tFlyingHandlingData CVector vecSpeedRes; }; +class CVehicle; + class cHandlingDataMgr { float field_0; // unused it seems @@ -258,6 +265,7 @@ public: void Initialise(void); void LoadHandlingData(void); int FindExactWord(const char *word, const char *words, int wordLen, int numWords); + void ConvertDataToWorldUnits(tHandlingData *handling); void ConvertDataToGameUnits(tHandlingData *handling); void ConvertBikeDataToGameUnits(tBikeHandlingData *handling); int32 GetHandlingId(const char *name); @@ -265,7 +273,7 @@ public: tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; } tFlyingHandlingData *GetFlyingPointer(uint8 id); tBoatHandlingData *GetBoatPointer(uint8 id); - bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'R'; } - bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; } + bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'F'; } + bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'R'; } }; extern cHandlingDataMgr mod_HandlingManager; diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 644fdde8..38550c38 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -32,8 +32,6 @@ #include "Replay.h" #endif -//--MIAMI: done - enum { HELI_STATUS_HOVER, @@ -480,7 +478,7 @@ CHeli::ProcessControl(void) // Shoot int shootTimeout; if (m_heliType == HELI_TYPE_RANDOM) { - switch (FindPlayerPed()->m_pWanted->m_nWantedLevel) { + switch (FindPlayerPed()->m_pWanted->GetWantedLevel()) { case 0: case 1: case 2: shootTimeout = 999999; break; @@ -762,7 +760,7 @@ CHeli::InitHelis(void) } CHeli* -GenerateHeli(bool catalina) +CHeli::GenerateHeli(bool catalina) { CHeli *heli; CVector heliPos; @@ -800,7 +798,7 @@ GenerateHeli(bool catalina) id++; found = true; for(i = 0; i < 4; i++) - if(CHeli::pHelis[i] && CHeli::pHelis[i]->m_nHeliId == id) + if(pHelis[i] && pHelis[i]->m_nHeliId == id) found = false; } heli->m_nHeliId = id; diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h index 1f372e42..c5ae08e2 100644 --- a/src/vehicles/Heli.h +++ b/src/vehicles/Heli.h @@ -83,13 +83,14 @@ public: bool SendDownSwat(void); static void InitHelis(void); + static CHeli *GenerateHeli(bool catalina); // out of class in III PC and later because of SecuROM static void UpdateHelis(void); static void SpecialHeliPreRender(void); static bool TestRocketCollision(CVector *coors); static bool TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, int32 damage); static bool TestSniperCollision(CVector *line0, CVector *line1); - static void StartCatalinaFlyBy(void); + static void StartCatalinaFlyBy(void); // out of class in III PC and later because of SecuROM static void RemoveCatalinaHeli(void); static CHeli *FindPointerToCatalinasHeli(void); static void CatalinaTakeOff(void); diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index 620a04fb..48f7b8c0 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -18,8 +18,7 @@ #include "HandlingMgr.h" #include "Heli.h" #include "Plane.h" - -//--MIAMI: file done +#include "MemoryHeap.h" CPlaneNode *pPathNodes; CPlaneNode *pPath2Nodes; @@ -564,7 +563,9 @@ CPlane::ProcessControl(void) if(m_rwObject && RwObjectGetType(m_rwObject) == rpCLUMP){ DeleteRwObject(); if(mi->m_planeLodId != -1){ + PUSH_MEMID(MEMID_WORLD); m_rwObject = CModelInfo::GetModelInfo(mi->m_planeLodId)->CreateInstance(); + POP_MEMID(); if(m_rwObject) m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject))); } @@ -1001,7 +1002,7 @@ CPlane::TestRocketCollision(CVector *rocketPos) return false; } -//--MIAMI: unused +// unused // BUG: not in CPlane in the game void CPlane::CreateIncomingCesna(void) @@ -1025,7 +1026,7 @@ CPlane::CreateIncomingCesna(void) printf("CPlane::CreateIncomingCesna(void)\n"); } -//--MIAMI: unused +// unused void CPlane::CreateDropOffCesna(void) { @@ -1048,7 +1049,7 @@ CPlane::CreateDropOffCesna(void) printf("CPlane::CreateDropOffCesna(void)\n"); } -//--MIAMI: all unused +// all unused const CVector CPlane::FindDrugPlaneCoordinates(void) { return pDrugRunCesna->GetPosition(); } const CVector CPlane::FindDropOffCesnaCoordinates(void) { return pDropOffCesna->GetPosition(); } bool CPlane::HasCesnaLanded(void) { return CesnaMissionStatus == CESNA_STATUS_LANDED; } diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp index 1a4af307..5f0cf36a 100644 --- a/src/vehicles/Train.cpp +++ b/src/vehicles/Train.cpp @@ -388,7 +388,7 @@ void CTrain::AddPassenger(CPed *ped) { #ifdef GTA_TRAIN - int i = ped->m_vehEnterType; + int i = ped->m_vehDoor; if((i == TRAIN_POS_LEFT_ENTRY || i == TRAIN_POS_MID_ENTRY || i == TRAIN_POS_RIGHT_ENTRY) && pPassengers[i] == nil){ pPassengers[i] = ped; m_nNumPassengers++; diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp index cc994ac6..1aeabfe0 100644 --- a/src/vehicles/Transmission.cpp +++ b/src/vehicles/Transmission.cpp @@ -4,8 +4,6 @@ #include "HandlingMgr.h" #include "Transmission.h" -//--MIAMI: done - void cTransmission::InitGearRatios(void) { @@ -123,7 +121,7 @@ cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, fl else fCheat = 1.0f; float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat; - float accel = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/Abs(targetVelocity); + float accel = (targetVelocity - fVelocity) * (fEngineAcceleration*accelMul) / Abs(targetVelocity); if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat)) fAcceleration = gasPedal * accel * CTimer::GetTimeStep(); else diff --git a/src/vehicles/Transmission.h b/src/vehicles/Transmission.h index 8eeef1e8..a3d15513 100644 --- a/src/vehicles/Transmission.h +++ b/src/vehicles/Transmission.h @@ -18,7 +18,7 @@ public: uint8 Flags; float fEngineAcceleration; float fMaxVelocity; - float fUnkMaxVelocity; + float fMaxCruiseVelocity; float fMaxReverseVelocity; float fCurVelocity; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 228c4f66..0ecc5004 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -33,8 +33,6 @@ #include "Weather.h" #include "Coronas.h" -//--MIAMI: done - bool CVehicle::bWheelsOnlyCheat; bool CVehicle::bAllDodosCheat; bool CVehicle::bCheat3; @@ -48,6 +46,9 @@ bool CVehicle::bAllTaxisHaveNitro; bool CVehicle::m_bDisableMouseSteering = true; bool CVehicle::bDisableRemoteDetonation; bool CVehicle::bDisableRemoteDetonationOnContact; +#ifndef MASTER +bool CVehicle::m_bDisplayHandlingInfo; +#endif void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); } void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); } @@ -146,6 +147,7 @@ CVehicle::CVehicle(uint8 CreatedBy) m_nAlarmState = 0; m_nDoorLock = CARLOCK_UNLOCKED; m_nLastWeaponDamage = -1; + m_pLastDamageEntity = nil; m_fMapObjectHeightAhead = m_fMapObjectHeightBehind = 0.0f; m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); if(m_audioEntityId >= 0) @@ -330,6 +332,9 @@ CVehicle::FlyingControl(eFlightModel flightModel) float fSteerLR = CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; float fSteerUD = CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; float fGunUD = Abs(CPad::GetPad(0)->GetCarGunUpDown()); +#ifdef FREE_CAM + if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) +#endif if(fGunUD > 1.0f) fSteerUD = -CPad::GetPad(0)->GetCarGunUpDown() / 128.0f; @@ -503,9 +508,15 @@ CVehicle::FlyingControl(eFlightModel flightModel) fYaw = CPad::GetPad(0)->GetLookRight(); if (CPad::GetPad(0)->GetLookLeft()) fYaw = -1.0f; +#ifdef FREE_CAM + if (!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) +#endif if(Abs(CPad::GetPad(0)->GetCarGunLeftRight()) > 1.0f) fYaw = CPad::GetPad(0)->GetCarGunLeftRight() / 128.0f; } +#ifdef FREE_CAM + if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) +#endif if(Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f) fPitch = -CPad::GetPad(0)->GetCarGunUpDown() / 128.0f; if (CPad::GetPad(0)->GetHorn()) { @@ -836,11 +847,11 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon if(IsBike()) brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f); else if(pHandling->fMass < 500.0f) - brake = mod_HandlingManager.fWheelFriction / m_fMass; + brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass; else if(GetModelIndex() == MI_RCBANDIT) - brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass; + brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass; else - brake = mod_HandlingManager.fWheelFriction / m_fMass; + brake = mod_HandlingManager.fWheelFriction / pHandling->fMass; #ifdef FIX_BUGS brake *= CTimer::GetTimeStepFix(); #endif @@ -909,7 +920,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon float turnImpulse = turnSpeed*GetMass(wheelContactPoint, turnDirection); ApplyMoveForce(impulse * direction); - ApplyTurnForce(turnImpulse * direction, wheelContactPoint); + ApplyTurnForce(turnImpulse * turnDirection, wheelContactPoint); } } @@ -1232,7 +1243,7 @@ CVehicle::InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage if (m_randomSeed < DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE) { CCarCtrl::SwitchVehicleToRealPhysics(this); AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fUnkMaxVelocity; + AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fMaxCruiseVelocity; SetStatus(STATUS_PHYSICS); } } @@ -1426,13 +1437,13 @@ CVehicle::ShufflePassengersToMakeSpace(void) if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) { pPassengers[2] = pPassengers[1]; pPassengers[1] = nil; - pPassengers[2]->m_vehEnterType = CAR_DOOR_RR; + pPassengers[2]->m_vehDoor = CAR_DOOR_RR; return true; } if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) { pPassengers[0] = pPassengers[1]; pPassengers[1] = nil; - pPassengers[0]->m_vehEnterType = CAR_DOOR_RF; + pPassengers[0]->m_vehDoor = CAR_DOOR_RF; return true; } return false; @@ -1443,13 +1454,13 @@ CVehicle::ShufflePassengersToMakeSpace(void) if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) { pPassengers[1] = pPassengers[2]; pPassengers[2] = nil; - pPassengers[1]->m_vehEnterType = CAR_DOOR_LR; + pPassengers[1]->m_vehDoor = CAR_DOOR_LR; return true; } if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) { pPassengers[0] = pPassengers[2]; pPassengers[2] = nil; - pPassengers[0]->m_vehEnterType = CAR_DOOR_RF; + pPassengers[0]->m_vehDoor = CAR_DOOR_RF; return true; } return false; @@ -1460,13 +1471,13 @@ CVehicle::ShufflePassengersToMakeSpace(void) if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) { pPassengers[1] = pPassengers[0]; pPassengers[0] = nil; - pPassengers[1]->m_vehEnterType = CAR_DOOR_LR; + pPassengers[1]->m_vehDoor = CAR_DOOR_LR; return true; } if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) { pPassengers[2] = pPassengers[0]; pPassengers[0] = nil; - pPassengers[2]->m_vehEnterType = CAR_DOOR_RR; + pPassengers[2]->m_vehDoor = CAR_DOOR_RR; return true; } return false; @@ -1482,7 +1493,7 @@ CVehicle::MakeNonDraggedPedsLeaveVehicle(CPed *ped1, CPed *ped2, CPlayerPed *&pl cop = nil; if(ped1->IsPlayer() && ped2->m_nPedType == PEDTYPE_COP && - ((CPlayerPed*)ped1)->m_pWanted->m_nWantedLevel > 0 && + ((CPlayerPed*)ped1)->m_pWanted->GetWantedLevel() > 0 && ped2->m_pedInObjective == ped1){ player = (CPlayerPed*)ped1; cop = (CCopPed*)ped2; @@ -1512,7 +1523,7 @@ CVehicle::MakeNonDraggedPedsLeaveVehicle(CPed *ped1, CPed *ped2, CPlayerPed *&pl int numPeds3 = 0; for(i = 0; i < numPeds; i++){ if(peds[i]->IsPlayer() && ped2->m_nPedType == PEDTYPE_COP && - ((CPlayerPed*)peds[i])->m_pWanted->m_nWantedLevel > 0 && + ((CPlayerPed*)peds[i])->m_pWanted->GetWantedLevel() > 0 && ped2->m_pedInObjective == peds[i]){ player = (CPlayerPed*)peds[i]; cop = (CCopPed*)ped2; @@ -1873,7 +1884,7 @@ CVehicle::AddPassenger(CPed *passenger) int i; if(IsBike()) - ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + ApplyTurnForce(-0.02f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); else ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, passenger->GetPosition().x - GetPosition().x, @@ -1896,7 +1907,7 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n) return AddPassenger(passenger); if(IsBike()) - ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + ApplyTurnForce(-0.02f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); else ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, passenger->GetPosition().x - GetPosition().x, @@ -1914,7 +1925,10 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n) void CVehicle::RemoveDriver(void) { - SetStatus(STATUS_ABANDONED); +#ifdef FIX_BUGS + if (GetStatus() != STATUS_WRECKED) +#endif + SetStatus(STATUS_ABANDONED); if(pDriver == FindPlayerPed()){ if(GetModelIndex() == MI_POLICE && CStreaming::HasModelLoaded(MI_SHOTGUN)){ if(bFreebies){ @@ -2492,7 +2506,7 @@ IsVehiclePointerValid(CVehicle* pVehicle) { if (!pVehicle) return false; - int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle); + int index = CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pVehicle); #ifdef FIX_BUGS if (index < 0 || index >= NUMVEHICLES) #else diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 004f1fd9..4a361215 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -3,15 +3,15 @@ #include "Physical.h" #include "AutoPilot.h" #include "ModelIndices.h" -#include "AnimManager.h" -#include "Weapon.h" +#include "AnimationId.h" +#include "WeaponType.h" +#include "Collision.h" #include "HandlingMgr.h" class CPed; class CPlayerPed; class CCopPed; class CFire; -struct tHandlingData; enum { RANDOM_VEHICLE = 1, @@ -102,14 +102,6 @@ enum eLights VEHLIGHT_REAR_RIGHT, }; -enum eWheels -{ - VEHWHEEL_FRONT_LEFT, - VEHWHEEL_FRONT_RIGHT, - VEHWHEEL_REAR_LEFT, - VEHWHEEL_REAR_RIGHT, -}; - enum { CAR_PIECE_BONNET = 1, @@ -248,8 +240,9 @@ public: uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed uint8 bParking : 1; uint8 bCanPark : 1; - +#if (!defined GTA_PS2 || defined FIX_BUGS) uint8 m_bombType : 3; +#endif uint8 bDriverLastFrame : 1; int8 m_numPedsUseItAsCover; @@ -259,7 +252,9 @@ public: float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode uint8 m_nCurrentGear; float m_fChangeGearTime; +#if (!defined GTA_PS2 || defined FIX_BUGS) CEntity* m_pBombRigger; +#endif uint32 m_nSetPieceExtendedRangeTime; uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats) uint32 m_nTimeOfDeath; @@ -281,7 +276,7 @@ public: int8 m_comedyControlState; CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car float m_fSteerInput; - eVehicleType m_vehType; + uint8 m_vehType; static void *operator new(size_t); static void *operator new(size_t sz, int slot); @@ -407,6 +402,9 @@ public: static bool m_bDisableMouseSteering; static bool bDisableRemoteDetonation; static bool bDisableRemoteDetonationOnContact; +#ifndef MASTER + static bool m_bDisplayHandlingInfo; +#endif }; void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle); diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 13032300..445f31a0 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -25,8 +25,6 @@ #include "SurfaceTable.h" #include "Heli.h" -// --MIAMI: file done - #ifdef SQUEEZE_PERFORMANCE uint32 bulletInfoInUse; #endif diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp index 515dff94..74137dc0 100644 --- a/src/weapons/Explosion.cpp +++ b/src/weapons/Explosion.cpp @@ -121,7 +121,12 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT #endif int n = 0; +#ifdef FIX_BUGS + while (n < ARRAY_SIZE(gaExplosion) && gaExplosion[n].m_nIteration != 0) +#else + // array overrun is UB while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion)) +#endif n++; if (n == ARRAY_SIZE(gaExplosion)) return false; @@ -220,7 +225,7 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT } else if (veh->IsComponentPresent(CAR_BOOT)) { veh->GetComponentWorldPosition(CAR_BOOT, componentPos); } - if (componentPos != nil) { + if (componentPos.x != 0.0f) { int rn = (CGeneral::GetRandomNumber() & 1) + 1; for (int i = 0; i < rn; i++) CParticle::AddJetExplosion(componentPos, (CGeneral::GetRandomNumber() & 7) / 7.0f + 1.5f, 0.5f); diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp index 754da5f7..10aa3ef5 100644 --- a/src/weapons/ProjectileInfo.cpp +++ b/src/weapons/ProjectileInfo.cpp @@ -17,8 +17,6 @@ uint32 projectileInUse; #endif -// --MIAMI: file done except TODOs - CProjectileInfo gaProjectileInfo[NUM_PROJECTILES]; CProjectile *CProjectileInfo::ms_apProjectile[NUM_PROJECTILES]; @@ -159,8 +157,12 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, } int i = 0; +#ifdef FIX_BUGS + while (i < ARRAY_SIZE(gaProjectileInfo) && gaProjectileInfo[i].m_bInUse) i++; +#else + // array overrun is UB while (gaProjectileInfo[i].m_bInUse && i < ARRAY_SIZE(gaProjectileInfo)) i++; - +#endif if (i == ARRAY_SIZE(gaProjectileInfo)) return false; diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp index ae7b9d2d..788bcbe1 100644 --- a/src/weapons/ShotInfo.cpp +++ b/src/weapons/ShotInfo.cpp @@ -10,8 +10,6 @@ #include "Ped.h" #include "Fire.h" -// --MIAMI: file done - CShotInfo gaShotInfo[NUMSHOTINFOS]; float CShotInfo::ms_afRandTable[20]; @@ -78,7 +76,7 @@ CShotInfo::AddShot(CEntity *sourceEntity, eWeaponType weapon, CVector startPos, gaShotInfo[slot].m_areaAffected.z += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)]; } gaShotInfo[slot].m_areaAffected.Normalise(); - if (weaponInfo->m_bRandSpeed) + if (weaponInfo->IsFlagSet(WEAPONFLAG_RAND_SPEED)) gaShotInfo[slot].m_areaAffected *= CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] + weaponInfo->m_fSpeed; else gaShotInfo[slot].m_areaAffected *= weaponInfo->m_fSpeed; @@ -119,10 +117,10 @@ CShotInfo::Update() shot.m_inUse = false; } - if (weaponInfo->m_bSlowsDown) + if (weaponInfo->IsFlagSet(WEAPONFLAG_SLOWS_DOWN)) shot.m_areaAffected *= pow(0.96, CTimer::GetTimeStep()); // FRAMERATE - if (weaponInfo->m_bExpands) + if (weaponInfo->IsFlagSet(WEAPONFLAG_EXPANDS)) shot.m_radius += 0.075f * CTimer::GetTimeStep(); shot.m_startPos += CTimer::GetTimeStep() * shot.m_areaAffected; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index d1f9490d..3ef7d2a1 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -44,6 +44,10 @@ float fPlayerAimScale = 2.5f; bool CWeapon::bPhotographHasBeenTaken; +#ifdef SECUROM +int32 sniperPirateCheck = 0x00797743; // 'Cwy\0' ??? +#endif + CWeaponInfo * CWeapon::GetInfo() { @@ -499,14 +503,14 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) bool collided = false; if (victimPed->m_nPedState == PED_DRIVING && (m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE - || info->m_bFightMode)) + || info->IsFlagSet(WEAPONFLAG_FIGHTMODE))) continue; float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius; if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() ) { CVector victimPedPos = victimPed->GetPosition(); - if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() ) + if ( SQR(victimPedRadius) > (victimPedPos-fireSource).MagnitudeSqr() ) { CVector collisionDist; CColModel* victimPedCol = &CTempColModels::ms_colModelPed1; @@ -528,9 +532,9 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) CColSphere *sphere = &victimPedCol->spheres[s]; if (useLocalPos) - collisionDist = sphere->center - (*fireSource); + collisionDist = sphere->center - fireSource; else - collisionDist = victimPedPos + sphere->center - (*fireSource); + collisionDist = victimPedPos + sphere->center - fireSource; if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() ) { @@ -873,7 +877,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CPed *threatAttack = (CPed*)shooterPed->m_pPointGunAt; if ( threatAttack->IsPed() ) { - threatAttack->m_pedIK.GetComponentPosition(*(RwV3d *)&target, PED_MID); + threatAttack->m_pedIK.GetComponentPosition(target, PED_MID); threatAttack->ReactToPointGun(shooter); } else @@ -911,7 +915,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CWorld::bIncludeDeadPeds = true; CWorld::bIncludeBikers = true; - CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeDeadPeds = false; CWorld::bIncludeBikers = false; } @@ -924,7 +928,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) shooterPed->TransformToNode(target, PED_HANDR); CWorld::bIncludeBikers = true; - CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeBikers = false; } } @@ -935,7 +939,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CWorld::bIncludeBikers = true; CWorld::bIncludeDeadPeds = true; CWorld::bIncludeCarTyres = true; - CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeBikers = false; CWorld::bIncludeDeadPeds = false; CWorld::bIncludeCarTyres = false; @@ -981,7 +985,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) target *= info->m_fRange; target += *fireSource; CWorld::pIgnoreEntity = shooter; - CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); CWorld::pIgnoreEntity = nil; int32 rotSpeed = 1; @@ -1008,13 +1012,13 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) target.y += rotOffset.y * info->m_fRange; CParticle::HandleShootableBirdsStuff(shooter, *fireSource); - if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->m_bCanAim)) + if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->IsFlagSet(WEAPONFLAG_CANAIM))) { CWeapon::DoDoomAiming(shooter, fireSource, &target); } CWorld::bIncludeBikers = true; - CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeBikers = false; int32 rotSpeed = 1; @@ -1457,7 +1461,8 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, #ifndef FIX_BUGS CVector dist = point->point - (*source); - CVector smokePos = point->point - Max(0.1f * dist.Magnitude(), 0.2f) / dist.Magnitude(); + float distMagnitude = dist.Magnitude(); + CVector smokePos = point->point - Max(distMagnitude / 10.0f, 0.2f) * dist / distMagnitude; #else CVector smokePos = point->point; #endif // !FIX_BUGS @@ -1472,7 +1477,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, } case ENTITY_TYPE_VEHICLE: { - if (point->pieceB >= SURFACE_LAMP_POST && point->pieceB <= SURFACE_METAL_CHAIN_FENCE) { + if (point->pieceB >= CAR_PIECE_WHEEL_LF && point->pieceB <= CAR_PIECE_WHEEL_RR) { ((CVehicle*)victim)->BurstTyre(point->pieceB, true); for (int32 i = 0; i < 4; i++) @@ -1486,9 +1491,9 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal * 0.05f); #ifndef FIX_BUGS - CVector dist = point.point - (*fireSource); + CVector dist = point->point - (*source); CVector offset = dist - Max(0.2f * dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f); - CVector smokePos = *fireSource + offset; + CVector smokePos = *source + offset; #else CVector smokePos = point->point; #endif @@ -1682,7 +1687,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) CWorld::bIncludeCarTyres = true; CWorld::bIncludeBikers = true; CWorld::bIncludeDeadPeds = true; - CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeDeadPeds = false; CWorld::bIncludeCarTyres = false; } @@ -1702,7 +1707,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) { CVector pos; if (shooterPed->m_pPointGunAt->IsPed()) { - ((CPed*)shooterPed->m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&pos, PED_MID); + ((CPed*)shooterPed->m_pPointGunAt)->m_pedIK.GetComponentPosition(pos, PED_MID); } else { pos = ((CPed*)shooterPed->m_pPointGunAt)->GetPosition(); } @@ -1715,7 +1720,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) CWorld::bIncludeDeadPeds = true; CWorld::bIncludeBikers = true; - CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); CWorld::bIncludeDeadPeds = false; } CWorld::bIncludeBikers = false; @@ -1866,7 +1871,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) { case ENTITY_TYPE_VEHICLE: { - if (point.pieceB >= SURFACE_LAMP_POST && point.pieceB <= SURFACE_METAL_CHAIN_FENCE) { + if (point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR) { ((CVehicle*)victim)->BurstTyre(point.pieceB, true); for (int32 i = 0; i < 4; i++) @@ -2166,7 +2171,7 @@ CWeapon::LaserScopeDot(CVector *pOutPos, float *pOutSize) CVector pos = foundCol.point; float w, h; - if ( CSprite::CalcScreenCoors(foundCol.point, pos, &w, &h, true) ) + if ( CSprite::CalcScreenCoors(foundCol.point, &pos, &w, &h, true) ) { *pOutPos = pos; *pOutSize = w * 0.05f; @@ -2200,6 +2205,13 @@ CWeapon::FireSniper(CEntity *shooter) } } +#ifdef SECUROM + if (sniperPirateCheck){ + // if not pirated game + // sniperPirateCheck = 0; + } +#endif + #ifndef FIX_BUGS CWeaponInfo *info = GetInfo(); //unused #endif @@ -2216,6 +2228,10 @@ CWeapon::FireSniper(CEntity *shooter) dir.Normalise(); dir *= 16.0f; +#ifdef SECUROM + if (sniperPirateCheck) return true; +#endif + CBulletInfo::AddBullet(shooter, m_eWeaponType, source, dir); if ( shooter == FindPlayerPed() ) @@ -2261,7 +2277,7 @@ CWeapon::TakePhotograph(CEntity *shooter) CVector pos; float w, h; - if ( CSprite::CalcScreenCoors(pedPos, pos, &w, &h, false) ) + if ( CSprite::CalcScreenCoors(pedPos, &pos, &w, &h, false) ) { if ( SCREEN_WIDTH * 0.1f < pos.x && SCREEN_WIDTH * 0.9f > pos.x && SCREEN_HEIGHT * 0.1f < pos.y && SCREEN_HEIGHT * 0.9f > pos.y ) @@ -2328,7 +2344,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter) CVector source = cam->Source; CVector target = cam->Front*info->m_fRange + source; - if (CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true)) { + if (ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false)) { CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, source, target); } CWorld::pIgnoreEntity = nil; @@ -3157,7 +3173,6 @@ CWeapon::HasWeaponAmmoToBeUsed(void) return m_nAmmoTotal != 0; } -// --MIAMI: Done bool CPed::IsPedDoingDriveByShooting(void) { @@ -3175,7 +3190,7 @@ CPed::IsPedDoingDriveByShooting(void) bool CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) { - return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects); + return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, false, ignoreSomeObjects, true); } diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index b911805d..acb11a88 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -105,7 +105,6 @@ CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) return &ms_apWeaponInfos[weaponType]; } -// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value void CWeaponInfo::Initialise(void) { @@ -130,19 +129,14 @@ CWeaponInfo::Initialise(void) ms_apWeaponInfos[i].m_fAnim2LoopEnd = 0.0f; ms_apWeaponInfos[i].m_fAnim2FrameFire = 0.0f; ms_apWeaponInfos[i].m_fAnimBreakout = 0.0f; - ms_apWeaponInfos[i].m_bUseGravity = 1; - ms_apWeaponInfos[i].m_bSlowsDown = 1; - ms_apWeaponInfos[i].m_bRandSpeed = 1; - ms_apWeaponInfos[i].m_bExpands = 1; - ms_apWeaponInfos[i].m_bExplodes = 1; - ms_apWeaponInfos[i].m_nWeaponSlot = 0; + ms_apWeaponInfos[i].m_Flags = WEAPONFLAG_USE_GRAVITY | WEAPONFLAG_SLOWS_DOWN | WEAPONFLAG_RAND_SPEED | WEAPONFLAG_EXPANDS | WEAPONFLAG_EXPLODES; + ms_apWeaponInfos[i].m_nWeaponSlot = WEAPONSLOT_UNARMED; } debug("Loading weapon data...\n"); LoadWeaponData(); debug("CWeaponInfo ready\n"); } -// --MIAMI: Done, commented parts wait for weapons port void CWeaponInfo::LoadWeaponData(void) { @@ -170,10 +164,9 @@ CWeaponInfo::LoadWeaponData(void) line[linelen] = '\0'; // skip white space - for (lp = 0; line[lp] <= ' '; lp++); + for (lp = 0; line[lp] <= ' ' && line[lp] != '\0'; lp++); - if (lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines - line[lp] == '#') + if (line[lp] == '\0' || line[lp] == '#') continue; spread = 0.0f; @@ -248,30 +241,7 @@ CWeaponInfo::LoadWeaponData(void) ms_apWeaponInfos[weaponType].m_fAnimBreakout = animBreakout / 30.0f; ms_apWeaponInfos[weaponType].m_nModelId = modelId; ms_apWeaponInfos[weaponType].m_nModel2Id = modelId2; - - ms_apWeaponInfos[weaponType].m_bUseGravity = flags & 1; - ms_apWeaponInfos[weaponType].m_bSlowsDown = (flags >> 1) & 1; - ms_apWeaponInfos[weaponType].m_bDissipates = (flags >> 2) & 1; - ms_apWeaponInfos[weaponType].m_bRandSpeed = (flags >> 3) & 1; - ms_apWeaponInfos[weaponType].m_bExpands = (flags >> 4) & 1; - ms_apWeaponInfos[weaponType].m_bExplodes = (flags >> 5) & 1; - ms_apWeaponInfos[weaponType].m_bCanAim = (flags >> 6) & 1; - ms_apWeaponInfos[weaponType].m_bCanAimWithArm = (flags >> 7) & 1; - ms_apWeaponInfos[weaponType].m_b1stPerson = (flags >> 8) & 1; - ms_apWeaponInfos[weaponType].m_bHeavy = (flags >> 9) & 1; - ms_apWeaponInfos[weaponType].m_bThrow = (flags >> 10) & 1; - ms_apWeaponInfos[weaponType].m_bReloadLoop2Start = (flags >> 11) & 1; - ms_apWeaponInfos[weaponType].m_bUse2nd = (flags >> 12) & 1; - ms_apWeaponInfos[weaponType].m_bGround2nd = (flags >> 13) & 1; - ms_apWeaponInfos[weaponType].m_bFinish3rd = (flags >> 14) & 1; - ms_apWeaponInfos[weaponType].m_bReload = (flags >> 15) & 1; - ms_apWeaponInfos[weaponType].m_bFightMode = (flags >> 16) & 1; - ms_apWeaponInfos[weaponType].m_bCrouchFire = (flags >> 17) & 1; - ms_apWeaponInfos[weaponType].m_bCop3rd = (flags >> 18) & 1; - ms_apWeaponInfos[weaponType].m_bGround3rd = (flags >> 19) & 1; - ms_apWeaponInfos[weaponType].m_bPartialAttack = (flags >> 20) & 1; - ms_apWeaponInfos[weaponType].m_bAnimDetonate = (flags >> 21) & 1; - + ms_apWeaponInfos[weaponType].m_Flags = flags; ms_apWeaponInfos[weaponType].m_nWeaponSlot = weaponSlot; if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && !CWeapon::IsShotgun(weaponType)) diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h index 6e09e9f2..0f53dded 100644 --- a/src/weapons/WeaponInfo.h +++ b/src/weapons/WeaponInfo.h @@ -4,7 +4,31 @@ #include "AnimationId.h" #include "WeaponType.h" -enum AssocGroupId; +enum +{ + WEAPONFLAG_USE_GRAVITY = 1, + WEAPONFLAG_SLOWS_DOWN = 1 << 1, + WEAPONFLAG_DISSIPATES = 1 << 2, + WEAPONFLAG_RAND_SPEED = 1 << 3, + WEAPONFLAG_EXPANDS = 1 << 4, + WEAPONFLAG_EXPLODES = 1 << 5, + WEAPONFLAG_CANAIM = 1 << 6, + WEAPONFLAG_CANAIM_WITHARM = 1 << 7, + WEAPONFLAG_1ST_PERSON = 1 << 8, + WEAPONFLAG_HEAVY = 1 << 9, + WEAPONFLAG_THROW = 1 << 10, + WEAPONFLAG_RELOAD_LOOP2START = 1 << 11, + WEAPONFLAG_USE_2ND = 1 << 12, + WEAPONFLAG_GROUND_2ND = 1 << 13, + WEAPONFLAG_FINISH_3RD = 1 << 14, + WEAPONFLAG_RELOAD = 1 << 15, + WEAPONFLAG_FIGHTMODE = 1 << 16, + WEAPONFLAG_CROUCHFIRE = 1 << 17, + WEAPONFLAG_COP3_RD = 1 << 18, + WEAPONFLAG_GROUND_3RD = 1 << 19, + WEAPONFLAG_PARTIALATTACK = 1 << 20, + WEAPONFLAG_ANIMDETONATE = 1 << 21, +}; class CWeaponInfo { static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS]; @@ -34,31 +58,7 @@ public: float m_fAnimBreakout; int32 m_nModelId; int32 m_nModel2Id; - // flags - uint8 m_bUseGravity : 1; - uint8 m_bSlowsDown : 1; - uint8 m_bDissipates : 1; - uint8 m_bRandSpeed : 1; - uint8 m_bExpands : 1; - uint8 m_bExplodes : 1; - uint8 m_bCanAim : 1; - uint8 m_bCanAimWithArm : 1; - - uint8 m_b1stPerson : 1; - uint8 m_bHeavy : 1; - uint8 m_bThrow : 1; - uint8 m_bReloadLoop2Start : 1; - uint8 m_bUse2nd : 1; - uint8 m_bGround2nd : 1; - uint8 m_bFinish3rd : 1; - uint8 m_bReload : 1; - - uint8 m_bFightMode : 1; - uint8 m_bCrouchFire : 1; - uint8 m_bCop3rd : 1; - uint8 m_bGround3rd : 1; - uint8 m_bPartialAttack : 1; - uint8 m_bAnimDetonate : 1; + uint32 m_Flags; uint32 m_nWeaponSlot; @@ -69,6 +69,7 @@ public: static eWeaponType FindWeaponType(char *name); static void Shutdown(void); static bool IsWeaponSlotAmmoMergeable(uint32 slot) { return slot == WEAPONSLOT_SHOTGUN || slot == WEAPONSLOT_SUBMACHINEGUN || slot == WEAPONSLOT_RIFLE; } + bool IsFlagSet(uint32 flag) const { return (m_Flags & flag) != 0; } }; VALIDATE_SIZE(CWeaponInfo, 0x64); |