diff options
author | majestic <majesticcoding@gmail.com> | 2020-10-09 04:22:50 +0200 |
---|---|---|
committer | majestic <majesticcoding@gmail.com> | 2020-10-09 04:28:31 +0200 |
commit | c091a5c11a826665f083ee7e73635f03aa4b550d (patch) | |
tree | 21f0d517e5210b1bc28d39ebfe67c2b0bcbb2772 | |
parent | Merge branch 'miami' of https://github.com/GTAmodding/re3 into miami (diff) | |
parent | Fix POSIX streaming (diff) | |
download | re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar.gz re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar.bz2 re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar.lz re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar.xz re3-c091a5c11a826665f083ee7e73635f03aa4b550d.tar.zst re3-c091a5c11a826665f083ee7e73635f03aa4b550d.zip |
35 files changed, 1063 insertions, 512 deletions
diff --git a/.travis.yml b/.travis.yml index 51ef58eb..c124a9f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,44 @@ language: cpp -os: linux dist: focal -matrix: +os: linux +jobs: include: - env: TARGET=release_linux-amd64-librw_gl3_glfw-oal + os: linux - env: TARGET=debug_linux-amd64-librw_gl3_glfw-oal + os: linux + - env: TARGET=release_macosx-amd64-librw_gl3_glfw-oal PREMAKE5=premake-5.0.0-alpha15 + compiler: clang + os: osx + osx_image: xcode12u + - env: TARGET=debug_macosx-amd64-librw_gl3_glfw-oal PREMAKE5=premake-5.0.0-alpha15 + compiler: clang + os: osx + osx_image: xcode12u +addons: + apt: + update: true + packages: + - linux-libc-dev + - libopenal-dev + - libglew-dev + - libglfw3-dev + - libsndfile1-dev + - libmpg123-dev + - gcc-8-multilib + - g++-8-multilib + homebrew: + packages: + - libsndfile + - mpg123 + - glew + - glfw + - openal-soft script: - - sudo apt-get update - - sudo apt-get -y install linux-libc-dev libopenal-dev libglew-dev libglfw3-dev libsndfile1-dev libmpg123-dev gcc-8-multilib g++-8-multilib - mkdir -p "$TRAVIS_BUILD_DIR/build" - cd "$TRAVIS_BUILD_DIR" - - ./premake5Linux --with-librw gmake2 - - cd build - - CC=gcc-8 CXX=g++-8 make config=$TARGET -j4 verbose=1 + - if [ "$TRAVIS_OS_NAME" = linux ]; then ./premake5Linux --with-librw gmake2; fi + - if [ "$TRAVIS_OS_NAME" = osx ]; then curl -L -o "${PREMAKE5}.zip" "https://github.com/premake/premake-core/releases/download/v5.0.0-alpha15/${PREMAKE5}-src.zip" && unzip -q "${PREMAKE5}.zip" && cd "$PREMAKE5" && make -f Bootstrap.mak osx && cd .. && "./${PREMAKE5}/bin/release/premake5" --with-librw gmake2; fi + - cd build + - if [ "$TRAVIS_OS_NAME" = linux ]; then env CC=gcc-8 CXX=g++-8 make config=$TARGET -j4 verbose=1; fi + - if [ "$TRAVIS_OS_NAME" = osx ]; then make config=$TARGET -j4 verbose=1; fi diff --git a/premake5.lua b/premake5.lua index b61a9c4c..fb408fe0 100644 --- a/premake5.lua +++ b/premake5.lua @@ -84,6 +84,12 @@ workspace "reVC" platforms { "bsd-amd64-librw_gl3_glfw-oal" } + + filter { "system:macosx" } + platforms { + "macosx-arm64-librw_gl3_glfw-oal", + "macosx-amd64-librw_gl3_glfw-oal", + } filter "configurations:Debug" defines { "DEBUG" } @@ -100,6 +106,9 @@ workspace "reVC" filter { "platforms:bsd*" } system "bsd" + + filter { "platforms:macosx*" } + system "macosx" filter { "platforms:*x86*" } architecture "x86" @@ -109,6 +118,13 @@ workspace "reVC" filter { "platforms:*arm*" } architecture "ARM" + + filter { "platforms:macosx-arm64-*" } + buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" } + + filter { "platforms:macosx-amd64-*" } + buildoptions { "-target", "x86_64-apple-macos10.12", "-std=gnu++14" } + filter { "platforms:*librw_d3d9*" } defines { "RW_D3D9" } @@ -162,7 +178,14 @@ project "librw" filter "platforms:bsd*" includedirs { "/usr/local/include" } libdirs { "/usr/local/lib" } - + + filter "platforms:macosx*" + -- Support MacPorts and Homebrew + includedirs { "/opt/local/include" } + includedirs {"/usr/local/include" } + libdirs { "/opt/local/lib" } + libdirs { "/usr/local/lib" } + filter "platforms:*RW34*" flags { "ExcludeFromBuild" } filter {} @@ -277,6 +300,11 @@ project "reVC" filter "platforms:bsd*oal" links { "openal", "mpg123", "sndfile", "pthread" } + + filter "platforms:macosx*oal" + links { "openal", "mpg123", "sndfile", "pthread" } + includedirs { "/usr/local/opt/openal-soft/include" } + libdirs { "/usr/local/opt/openal-soft/lib" } if _OPTIONS["with-opus"] then filter {} @@ -330,3 +358,11 @@ project "reVC" links { "GL", "GLEW", "glfw", "sysinfo" } includedirs { "/usr/local/include" } libdirs { "/usr/local/lib" } + + filter "platforms:macosx*gl3_glfw*" + links { "GLEW", "glfw" } + linkoptions { "-framework OpenGL" } + includedirs { "/opt/local/include" } + includedirs { "/usr/local/include" } + libdirs { "/opt/local/lib" } + libdirs { "/usr/local/lib" } diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 290bacad..dc07d142 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -1462,7 +1462,7 @@ void CGarage::UpdateCrusherShake(float X, float Y) } // This is dumb but there is no way to avoid goto. What was there originally even? -static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, int8 nIndex) +static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, uint8 nIndex) { bool bNeedToFindDoorEntities = false; if (pDoor) { diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 95e93b6c..aa4e109f 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -12020,7 +12020,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) script_assert(pVehicle); bool bIsBurst = false; CBike* pBike = (CBike*)pVehicle; - if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) { + if (pVehicle->IsBike()) { if (ScriptParams[1] == 4) { for (int i = 0; i < 2; i++) { if (pBike->m_wheelStatus[i] == WHEEL_STATUS_BURST) diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 704e77b8..2fa81d24 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -1749,7 +1749,7 @@ CCamera::CamControl(void) if(PrevMode != Cams[ActiveCam].Mode || switchedFromObbe || Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED || Cams[ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING) - if(CPad::GetPad(0)->CycleCameraModeUpJustDown() && + if(CPad::GetPad(0)->CycleCameraModeJustDown() && !CReplay::IsPlayingBack() && (m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) && !m_WideScreenOn && diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index e114a29a..a6ab62bc 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -34,11 +34,11 @@ struct CdReadInfo bool bReading; int32 nStatus; #ifdef ONE_THREAD_PER_CHANNEL - int8 nThreadStatus; // 0: created 1:initalized 2:abort now - pthread_t pChannelThread; - sem_t pStartSemaphore; + int8 nThreadStatus; // 0: created 1:priority set up 2:abort now + pthread_t pChannelThread; + sem_t *pStartSemaphore; #endif - sem_t pDoneSemaphore; // used for CdStreamSync + sem_t *pDoneSemaphore; // used for CdStreamSync int32 hFile; }; @@ -51,8 +51,8 @@ char *gImgNames[MAX_CDIMAGES]; #ifndef ONE_THREAD_PER_CHANNEL pthread_t _gCdStreamThread; -sem_t gCdStreamSema; // released when we have new thing to read(so channel is set) -int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now +sem_t *gCdStreamSema; // released when we have new thing to read(so channel is set) +int8 gCdStreamThreadStatus; // 0: created 1:priority set up 2:abort now Queue gChannelRequestQ; bool _gbCdStreamOverlapped; #endif @@ -69,49 +69,50 @@ void CdStreamInitThread(void) { int status; - + char semName[20]; #ifndef ONE_THREAD_PER_CHANNEL gChannelRequestQ.items = (int32 *)calloc(gNumChannels + 1, sizeof(int32)); gChannelRequestQ.head = 0; gChannelRequestQ.tail = 0; gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); - status = sem_init(&gCdStreamSema, 0, 0); -#endif + gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); - if (status == -1) { + if (gCdStreamSema == SEM_FAILED) { CDTRACE("failed to create stream semaphore"); ASSERT(0); return; } - +#endif if ( gNumChannels > 0 ) { for ( int32 i = 0; i < gNumChannels; i++ ) { - status = sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0); + sprintf(semName,"/semaphore_done%d",i); + gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 1); - if (status == -1) + if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) { CDTRACE("failed to create sync semaphore"); ASSERT(0); return; } #ifdef ONE_THREAD_PER_CHANNEL - status = sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0); + sprintf(semName,"/semaphore_start%d",i); + gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 1); - if (status == -1) + if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) { CDTRACE("failed to create start semaphore"); ASSERT(0); return; } - gpReadInfo[i].nThreadStatus = 0; + gpReadInfo[i].nThreadStatus = 0; int *channelI = (int*)malloc(sizeof(int)); *channelI = i; - status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI); + status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI); if (status == -1) { @@ -124,32 +125,32 @@ CdStreamInitThread(void) } #ifndef ONE_THREAD_PER_CHANNEL - debug("Using one streaming thread for all channels\n"); - status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil); - gCdStreamThreadStatus = 0; - - if (status == -1) - { - CDTRACE("failed to create sync thread"); - ASSERT(0); - return; - } + debug("Using one streaming thread for all channels\n"); + gCdStreamThreadStatus = 0; + status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil); + + if (status == -1) + { + CDTRACE("failed to create sync thread"); + ASSERT(0); + return; + } #else - debug("Using seperate streaming threads for each channel\n"); + debug("Using separate streaming threads for each channel\n"); #endif } void CdStreamInit(int32 numChannels) { - struct statvfs fsInfo; - - if((statvfs("models/gta3.img", &fsInfo)) < 0) - { - CDTRACE("can't get filesystem info"); - ASSERT(0); - return; - } + struct statvfs fsInfo; + + if((statvfs("models/gta3.img", &fsInfo)) < 0) + { + CDTRACE("can't get filesystem info"); + ASSERT(0); + return; + } #ifdef __linux__ _gdwCdStreamFlags = O_RDONLY | O_NOATIME; #else @@ -163,7 +164,7 @@ CdStreamInit(int32 numChannels) debug("Using no buffered loading for streaming\n"); } */ - void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, fsInfo.f_bsize); + void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, (RwUInt32)fsInfo.f_bsize); ASSERT( pBuffer != nil ); gNumImages = 0; @@ -185,27 +186,27 @@ uint32 GetGTA3ImgSize(void) { ASSERT( gImgFiles[0] > 0 ); - struct stat statbuf; + struct stat statbuf; - char path[PATH_MAX]; - realpath(gImgNames[0], path); - if (stat(path, &statbuf) == -1) { + char path[PATH_MAX]; + realpath(gImgNames[0], path); + if (stat(path, &statbuf) == -1) { // Try case-insensitivity char* real = casepath(gImgNames[0], false); if (real) { realpath(real, path); free(real); - if (stat(path, &statbuf) != -1) + if (stat(path, &statbuf) != -1) goto ok; } - CDTRACE("can't get size of gta3.img"); - ASSERT(0); - return 0; - } -ok: - return statbuf.st_size; + CDTRACE("can't get size of gta3.img"); + ASSERT(0); + return 0; + } + ok: + return (uint32)statbuf.st_size; } void @@ -213,15 +214,13 @@ CdStreamShutdown(void) { // Destroying semaphores and free(gpReadInfo) will be done at threads #ifndef ONE_THREAD_PER_CHANNEL - gCdStreamThreadStatus = 2; - sem_post(&gCdStreamSema); -#endif - -#ifdef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) { - gpReadInfo[i].nThreadStatus = 2; - sem_post(&gpReadInfo[i].pStartSemaphore); - } + gCdStreamThreadStatus = 2; + sem_post(gCdStreamSema); +#else + for ( int32 i = 0; i < gNumChannels; i++ ) { + gpReadInfo[i].nThreadStatus = 2; + sem_post(gpReadInfo[i].pStartSemaphore); + } #endif } @@ -241,27 +240,33 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); - pChannel->hFile = hImage - 1; - if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) - return STREAM_NONE; + if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { + if (pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) + return STREAM_SUCCESS; + + flushStream[channel] = 1; + CdStreamSync(channel); + //return STREAM_NONE; + } - pChannel->nStatus = STREAM_NONE; - pChannel->nSectorOffset = _GET_OFFSET(offset); - pChannel->nSectorsToRead = size; - pChannel->pBuffer = buffer; - pChannel->bLocked = 0; + pChannel->hFile = hImage - 1; + pChannel->nStatus = STREAM_NONE; + pChannel->nSectorOffset = _GET_OFFSET(offset); + pChannel->nSectorsToRead = size; + pChannel->pBuffer = buffer; + pChannel->bLocked = 0; #ifndef ONE_THREAD_PER_CHANNEL - AddToQueue(&gChannelRequestQ, channel); - if ( sem_post(&gCdStreamSema) != 0 ) - printf("Signal Sema Error\n"); + AddToQueue(&gChannelRequestQ, channel); + if ( sem_post(gCdStreamSema) != 0 ) + printf("Signal Sema Error\n"); #else - if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) - printf("Signal Sema Error\n"); + if ( sem_post(pChannel->pStartSemaphore) != 0 ) + printf("Signal Sema Error\n"); #endif - return STREAM_SUCCESS; + return STREAM_SUCCESS; } int32 @@ -272,29 +277,29 @@ CdStreamGetStatus(int32 channel) ASSERT( pChannel != nil ); #ifdef ONE_THREAD_PER_CHANNEL - if (pChannel->nThreadStatus == 2) - return STREAM_NONE; + if (pChannel->nThreadStatus == 2) + return STREAM_NONE; #else - if (gCdStreamThreadStatus == 2) - return STREAM_NONE; + if (gCdStreamThreadStatus == 2) + return STREAM_NONE; #endif - if ( pChannel->bReading ) - return STREAM_READING; + if ( pChannel->bReading ) + return STREAM_READING; - if ( pChannel->nSectorsToRead != 0 ) - return STREAM_WAITING; + if ( pChannel->nSectorsToRead != 0 ) + return STREAM_WAITING; - if ( pChannel->nStatus != STREAM_NONE ) - { - int32 status = pChannel->nStatus; + if ( pChannel->nStatus != STREAM_NONE ) + { + int32 status = pChannel->nStatus; - pChannel->nStatus = STREAM_NONE; + pChannel->nStatus = STREAM_NONE; - return status; - } + return status; + } - return STREAM_NONE; + return STREAM_NONE; } int32 @@ -314,30 +319,35 @@ CdStreamSync(int32 channel) if (flushStream[channel]) { #ifdef ONE_THREAD_PER_CHANNEL pChannel->nSectorsToRead = 0; - pthread_kill(gpReadInfo[channel].pChannelThread, SIGINT); + pthread_kill(pChannel->pChannelThread, SIGUSR1); + if (pChannel->bReading) { + pChannel->bLocked = true; + sem_wait(pChannel->pDoneSemaphore); + } #else + pChannel->nSectorsToRead = 0; if (pChannel->bReading) { - pChannel->nSectorsToRead = 0; - pthread_kill(_gCdStreamThread, SIGINT); - } else { - pChannel->nSectorsToRead = 0; + pChannel->bLocked = true; + pthread_kill(_gCdStreamThread, SIGUSR1); + sem_wait(pChannel->pDoneSemaphore); + } #endif pChannel->bReading = false; flushStream[channel] = false; - return STREAM_NONE; + return STREAM_NONE; } - if ( pChannel->nSectorsToRead != 0 ) - { - pChannel->bLocked = true; + if ( pChannel->nSectorsToRead != 0 ) + { + pChannel->bLocked = true; - sem_wait(&pChannel->pDoneSemaphore); - } + sem_wait(pChannel->pDoneSemaphore); + } - pChannel->bReading = false; + pChannel->bReading = false; - return pChannel->nStatus; + return pChannel->nStatus; } void @@ -382,53 +392,52 @@ void *CdStreamThread(void *param) debug("Created cdstream thread\n"); #ifndef ONE_THREAD_PER_CHANNEL - while (gCdStreamThreadStatus != 2) { - sem_wait(&gCdStreamSema); - int32 channel = GetFirstInQueue(&gChannelRequestQ); + while (gCdStreamThreadStatus != 2) { + sem_wait(gCdStreamSema); + int32 channel = GetFirstInQueue(&gChannelRequestQ); #else - int channel = *((int*)param); - while (gpReadInfo[channel].nThreadStatus != 2){ - sem_wait(&gpReadInfo[channel].pStartSemaphore); + int channel = *((int*)param); + while (gpReadInfo[channel].nThreadStatus != 2){ + sem_wait(gpReadInfo[channel].pStartSemaphore); #endif - ASSERT( channel < gNumChannels ); CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); -#ifdef ONE_THREAD_PER_CHANNEL - if (gpReadInfo[channel].nThreadStatus == 0){ - gpReadInfo[channel].nThreadStatus = 1; -#else - if (gCdStreamThreadStatus == 0){ - gCdStreamThreadStatus = 1; -#endif - -#ifdef __linux__ - pid_t tid = syscall(SYS_gettid); - int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1); -#endif - } - // spurious wakeup or we sent interrupt signal for flushing if(pChannel->nSectorsToRead == 0) - continue; + continue; pChannel->bReading = true; + // Not standard POSIX :shrug: +#ifdef __linux__ +#ifdef ONE_THREAD_PER_CHANNEL + if (gpReadInfo[channel].nThreadStatus == 0){ + gpReadInfo[channel].nThreadStatus = 1; +#else + if (gCdStreamThreadStatus == 0){ + gCdStreamThreadStatus = 1; +#endif + pid_t tid = syscall(SYS_gettid); + int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1); + } +#endif if ( pChannel->nStatus == STREAM_NONE ) { - ASSERT(pChannel->hFile >= 0); - ASSERT(pChannel->pBuffer != nil ); + ASSERT(pChannel->hFile >= 0); + ASSERT(pChannel->pBuffer != nil ); lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET); - if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { + if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { // pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel - pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_NONE : STREAM_ERROR; - } else { - pChannel->nStatus = STREAM_NONE; - } + // STREAM_WAITING is a little hack to make CStreaming not process this data + pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_WAITING : STREAM_ERROR; + } else { + pChannel->nStatus = STREAM_NONE; + } } - + #ifndef ONE_THREAD_PER_CHANNEL RemoveFirstInQueue(&gChannelRequestQ); #endif @@ -437,22 +446,33 @@ void *CdStreamThread(void *param) if ( pChannel->bLocked ) { - sem_post(&pChannel->pDoneSemaphore); + sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; } + char semName[20]; #ifndef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) - { - sem_destroy(&gpReadInfo[i].pDoneSemaphore); - } - sem_destroy(&gCdStreamSema); + for ( int32 i = 0; i < gNumChannels; i++ ) + { + sem_close(gpReadInfo[i].pDoneSemaphore); + sprintf(semName,"/semaphore_done%d",i); + sem_unlink(semName); + } + sem_close(gCdStreamSema); + sem_unlink("/semaphore_cd_stream"); free(gChannelRequestQ.items); #else - sem_destroy(&gpReadInfo[channel].pStartSemaphore); - sem_destroy(&gpReadInfo[channel].pDoneSemaphore); + sem_close(gpReadInfo[channel].pStartSemaphore); + sprintf(semName,"/semaphore_start%d",channel); + sem_unlink(semName); + + sem_close(gpReadInfo[channel].pDoneSemaphore); + sprintf(semName,"/semaphore_done%d",channel); + sem_unlink(semName); #endif - free(gpReadInfo); + if (gpReadInfo) + free(gpReadInfo); + gpReadInfo = nil; pthread_exit(nil); } @@ -469,7 +489,7 @@ CdStreamAddImage(char const *path) char* real = casepath(path, false); if (real) { - gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags); + gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags); free(real); } } @@ -502,8 +522,10 @@ CdStreamGetImageName(int32 cd) void CdStreamRemoveImages(void) { - for ( int32 i = 0; i < gNumChannels; i++ ) + for ( int32 i = 0; i < gNumChannels; i++ ) { + flushStream[i] = 1; CdStreamSync(i); + } for ( int32 i = 0; i < gNumImages; i++ ) { diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index 7eb1e186..b22ddcb2 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -10,6 +10,8 @@ #include "main.h" #include "Accident.h" +// --MIAMI: file done + int32 CEventList::ms_nFirstFreeSlotIndex; CEvent gaEvent[NUMEVENTS]; @@ -57,6 +59,7 @@ CEventList::Update(void) } } +// ok void CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout) { @@ -195,7 +198,6 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event) return found; } -// --MIAMI: Done void CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare) { diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 635192ea..da678fd3 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -1052,7 +1052,11 @@ CFileLoader::Load2dEffect(const char *line) &effect->attractor.dir.z, &probability); effect->attractor.type = flags; +#ifdef FIX_BUGS + effect->attractor.probability = clamp(probability, 0, 255); +#else effect->attractor.probability = probability; +#endif break; case EFFECT_PED_ATTRACTOR: sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f", diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index 4477a190..d3695cb4 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -142,17 +142,17 @@ static size_t myfread(void *buf, size_t elt, size_t n, int fd) { if(myfiles[fd].isText){ - char *p; + unsigned char *p; size_t i; int c; n *= elt; - p = (char*)buf; + p = (unsigned char*)buf; for(i = 0; i < n; i++){ c = myfgetc(fd); if(c == EOF) break; - *p++ = c; + *p++ = (unsigned char)c; } return i / elt; } @@ -163,12 +163,12 @@ static size_t myfwrite(void *buf, size_t elt, size_t n, int fd) { if(myfiles[fd].isText){ - char *p; + unsigned char *p; size_t i; int c; n *= elt; - p = (char*)buf; + p = (unsigned char*)buf; for(i = 0; i < n; i++){ c = *p++; myfputc(c, fd); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index eee8b4b2..59649e93 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -352,7 +352,7 @@ CMenuManager::CMenuManager() m_PrefsUseVibration = 0; m_PrefsShowHud = 1; m_PrefsRadarMode = 0; - field_10 = 0; + m_DisplayControllerOnFoot = false; m_bShutDownFrontEndRequested = false; m_bStartUpFrontEndRequested = false; pEditString = nil; @@ -950,6 +950,13 @@ CMenuManager::DrawStandardMenus(bool activeScreen) break; } break; + // This one is still in enum and ProcessOnOffMenuOptions, but removed from other places + case MENUACTION_CTRLDISPLAY: + if (m_DisplayControllerOnFoot) + rightText = TheText.Get("FEC_ONF"); + else + rightText = TheText.Get("FEC_INC"); + break; #endif case MENUACTION_FRAMESYNC: rightText = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF"); @@ -4206,6 +4213,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } +// --MIAMI: Done void CMenuManager::ProcessOnOffMenuOptions() { @@ -4213,78 +4221,78 @@ CMenuManager::ProcessOnOffMenuOptions() #ifdef LEGACY_MENU_OPTIONS case MENUACTION_CTRLVIBRATION: m_PrefsUseVibration = !m_PrefsUseVibration; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; case MENUACTION_CTRLCONFIG: CPad::GetPad(0)->Mode++; if (CPad::GetPad(0)->Mode > 3) CPad::GetPad(0)->Mode = 0; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; #endif + case MENUACTION_INVERTPADY: + CPad::bInvertLook4Pad = !CPad::bInvertLook4Pad; + SaveSettings(); // FIX: Why don't SaveSettings? Because of it's an hidden option? :( + break; + case MENUACTION_CTRLDISPLAY: + m_DisplayControllerOnFoot = !m_DisplayControllerOnFoot; + break; case MENUACTION_FRAMESYNC: m_PrefsVsyncDisp = !m_PrefsVsyncDisp; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - SaveSettings(); + SaveSettings(); // FIX: Again... This makes me very unhappy break; case MENUACTION_FRAMELIMIT: m_PrefsFrameLimiter = !m_PrefsFrameLimiter; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; case MENUACTION_TRAILS: CMBlur::BlurOn = !CMBlur::BlurOn; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); - if (CMBlur::BlurOn) - CMBlur::MotionBlurOpen(Scene.camera); - else - CMBlur::MotionBlurClose(); break; case MENUACTION_SUBTITLES: m_PrefsShowSubtitles = !m_PrefsShowSubtitles; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; #ifndef ASPECT_RATIO_SCALE case MENUACTION_WIDESCREEN: m_PrefsUseWideScreen = !m_PrefsUseWideScreen; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; #endif + case MENUACTION_LEGENDS: + m_PrefsShowLegends = !m_PrefsShowLegends; + break; + case MENUACTION_HUD: + m_PrefsShowHud = !m_PrefsShowHud; + SaveSettings(); + break; +#ifdef LEGACY_MENU_OPTIONS case MENUACTION_SETDBGFLAG: CTheScripts::InvertDebugFlag(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT: gbBigWhiteDebugLightSwitchedOn = !gbBigWhiteDebugLightSwitchedOn; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; case MENUACTION_COLLISIONPOLYS: gbShowCollisionPolys = !gbShowCollisionPolys; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; +#endif case MENUACTION_SHOWHEADBOB: TheCamera.m_bHeadBob = !TheCamera.m_bHeadBob; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; case MENUACTION_INVVERT: MousePointerStateHelper.bInvertVertically = !MousePointerStateHelper.bInvertVertically; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; case MENUACTION_DYNAMICACOUSTIC: m_PrefsDMA = !m_PrefsDMA; DMAudio.SetDynamicAcousticModelingStatus(m_PrefsDMA); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; case MENUACTION_MOUSESTEER: - CVehicle::m_bDisableMouseSteering = !CVehicle::m_bDisableMouseSteering; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - SaveSettings(); + if (m_ControlMethod == CONTROL_STANDARD) { + CVehicle::m_bDisableMouseSteering = !CVehicle::m_bDisableMouseSteering; + SaveSettings(); + } break; } } diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 6cd58e7d..0dab83a4 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -207,8 +207,8 @@ enum eMenuAction MENUACTION_YES, MENUACTION_NO, MENUACTION_CHANGEMENU, - MENUACTION_UNK5, MENUACTION_INVERTPADY, + MENUACTION_CTRLDISPLAY, MENUACTION_FRAMESYNC, MENUACTION_FRAMELIMIT, MENUACTION_TRAILS, @@ -466,7 +466,7 @@ public: bool m_PrefsUseVibration; bool m_PrefsShowHud; int32 m_PrefsRadarMode; - uint8 field_10; + bool m_DisplayControllerOnFoot; bool m_bShutDownFrontEndRequested; bool m_bStartUpFrontEndRequested; int32 m_KeyPressedCode; @@ -702,4 +702,4 @@ VALIDATE_SIZE(CMenuManager, 0x688); extern CMenuManager FrontEndMenuManager; extern CMenuScreen aScreens[]; -#endif
\ No newline at end of file +#endif diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 910a8c52..b723eb1d 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -54,6 +54,8 @@ #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))); @@ -66,7 +68,9 @@ bool CPad::bDisplayNoControllerMessage; bool CPad::bObsoleteControllerMessage; bool CPad::bOldDisplayNoControllerMessage; bool CPad::m_bMapPadOneToPadTwo; +bool CPad::m_bDebugCamPCOn; bool CPad::bHasPlayerCheated; +bool CPad::bInvertLook4Pad; #ifdef GTA_PS2 unsigned char act_direct[6]; unsigned char act_align[6]; @@ -93,6 +97,74 @@ extern bool gbFastTime; extern bool gGravityCheat; #endif +void SpecialCarCheats() +{ + if ( !CVehicle::bCheat9 ) + { + ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_INFERNUS))->m_wheelScale *= 1.3f; + ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHEETAH))->m_wheelScale *= 1.3f; + ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_PHEONIX))->m_wheelScale *= 1.3f; + ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_DELUXO))->m_wheelScale *= 1.3f; + mod_HandlingManager.GetHandlingData(HANDLING_LANDSTAL)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_PATRIOT)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_BOBCAT)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_BFINJECT)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_RANCHER)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_DESPERAD)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->Transmission.fEngineAcceleration *= 2.0f; + + mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.fMaxVelocity *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.InitGearRatios(); + + mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.fEngineAcceleration *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.fMaxVelocity *= 2.0f; + mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.InitGearRatios(); + + mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fCollisionDamageMultiplier *= 0.25f; + mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fMass *= 2.5f; + mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fTurnMass *= 4.0f; + + mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fCollisionDamageMultiplier *= 0.25f; + mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fMass *= 2.5f; + mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fTurnMass *= 4.0f; + + mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fCollisionDamageMultiplier *= 0.25f; + mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fMass *= 2.5f; + mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fTurnMass *= 4.0f; + + mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fCollisionDamageMultiplier *= 0.25f; + mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fMass *= 2.5f; + mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fTurnMass *= 4.0f; + + mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fCollisionDamageMultiplier *= 0.25f; + mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fMass *= 2.5f; + mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fTurnMass *= 4.0f; + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + CVehicle::bCheat9 = true; + CPad::bHasPlayerCheated = true; + } +} + +void PickUpChicksCheat() +{ + if ( FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike()) ) + { + CVehicle *vehicle = FindPlayerVehicle(); + if ( FindPlayerVehicle()->m_vehType == 5 ) + { + if ( vehicle->pPassengers[0] ) + vehicle->pPassengers[0]->SetObjective(OBJECTIVE_LEAVE_CAR, vehicle); + } + CPed* someoneElse = (CPed*)CWorld::TestSphereAgainstWorld(vehicle->GetPosition(), 6.0f, FindPlayerPed(), false, false, true, false, false, false); + if ( someoneElse && someoneElse->m_nPedState != PED_DRIVING ) + { + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + someoneElse->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, vehicle); + } + } +} + void WeaponCheat1() { CHud::SetHelpMessage(TheText.Get("CHEAT2"), true); @@ -127,6 +199,11 @@ void WeaponCheat1() CStreaming::SetModelIsDeletable(MI_RUGER); CStreaming::SetModelIsDeletable(MI_SNIPERRIFLE); CStreaming::SetModelIsDeletable(MI_FLAMETHROWER); +#ifdef MOBILE_IMPROVEMENTS + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponWhenEnteringVehicle(); + } +#endif } void WeaponCheat2() @@ -162,6 +239,11 @@ void WeaponCheat2() CStreaming::SetModelIsDeletable(MI_M4); CStreaming::SetModelIsDeletable(MI_LASERSCOPE); CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER); +#ifdef MOBILE_IMPROVEMENTS + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponWhenEnteringVehicle(); + } +#endif } void WeaponCheat3() @@ -197,6 +279,12 @@ void WeaponCheat3() CStreaming::SetModelIsDeletable(MI_LASERSCOPE); CStreaming::SetModelIsDeletable(MI_MINIGUN); CStreaming::SetModelIsDeletable(MI_MINIGUN2); + +#ifdef MOBILE_IMPROVEMENTS + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponWhenEnteringVehicle(); + } +#endif } void HealthCheat() @@ -213,6 +301,7 @@ void HealthCheat() } } +// TODO(Miami): this is HELLA different on mobile, although it mostly has debug oriented things like player exiting it's current car and enters spawned one etc. void VehicleCheat(int model) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); @@ -232,7 +321,7 @@ void VehicleCheat(int model) #ifdef FIX_BUGS CAutomobile* vehicle = new CAutomobile(model, RANDOM_VEHICLE); #else - CAutomobile* vehicle = new CAutomobile(MI_RHINO, MISSION_VEHICLE); + CAutomobile* vehicle = new CAutomobile(model, MISSION_VEHICLE); #endif if (vehicle != nil) { CVector pos = ThePaths.m_pathNodes[node].GetPosition(); @@ -249,6 +338,7 @@ void VehicleCheat(int model) CPad::bHasPlayerCheated = true; } + void BlowUpCarsCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); @@ -262,7 +352,8 @@ void BlowUpCarsCheat() void ChangePlayerCheat() { - int modelId; + // I don't know wtf is going on in here... + int modelId, anotherModelId; if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); @@ -270,21 +361,22 @@ void ChangePlayerCheat() AssocGroupId AnimGrp = ped->m_animGroup; do { - do - modelId = CGeneral::GetRandomNumberInRange(0, MI_WFYG2+1); - while (!CModelInfo::GetModelInfo(modelId)); - } while (modelId == MI_TAXI_D); + do { + modelId = CGeneral::GetRandomNumberInRange(0, MI_PGA); + anotherModelId = modelId+1; + } while (!CModelInfo::GetModelInfo(anotherModelId)); + } while (anotherModelId >= MI_SPECIAL01 && anotherModelId <= MI_SPECIAL04 || modelId == MI_TAXI_D); - uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags; + uint8 flags = CStreaming::ms_aInfoForModel[anotherModelId].m_flags; ped->DeleteRwObject(); - CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(anotherModelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE); CStreaming::LoadAllRequestedModels(false); ped->m_modelIndex = -1; - ped->SetModelIndex(modelId); + ped->SetModelIndex(anotherModelId); ped->m_animGroup = AnimGrp; - if (modelId != MI_PLAYER) { + if (modelId != -1) { if (!(flags & STREAMFLAGS_DONT_REMOVE)) - CStreaming::SetModelIsDeletable(modelId); + CStreaming::SetModelIsDeletable(anotherModelId); } } } @@ -430,11 +522,6 @@ void StrongGripCheat() CPad::bHasPlayerCheated = true; } -void NastyLimbsCheat() -{ - CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat; -} - void FannyMagnetCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); @@ -566,6 +653,7 @@ void FlyingFishCheat(void) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); CVehicle::bCheat8 = !CVehicle::bCheat8; + CPad::bHasPlayerCheated = true; } void DoShowChaseStatCheat(void) { @@ -643,6 +731,8 @@ void CPad::Initialise(void) bObsoleteControllerMessage = false; bOldDisplayNoControllerMessage = false; bDisplayNoControllerMessage = false; + m_bMapPadOneToPadTwo = false; + m_bDebugCamPCOn = false; } #endif @@ -675,9 +765,9 @@ void CPad::Clear(bool bResetPlayerControls) if ( bResetPlayerControls ) DisablePlayerControls = PLAYERCONTROL_ENABLED; + JustOutOfFrontend = 0; bApplyBrakes = false; - for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ ) bHornHistory[i] = false; @@ -703,6 +793,14 @@ void CPad::ClearMouseHistory() OldMouseControllerState.Clear(); } +// unused +void CPad::ClearKeyBoardHistory() +{ + NewKeyState.Clear(); + OldKeyState.Clear(); + TempKeyState.Clear(); +} + CMouseControllerState::CMouseControllerState() { LMB = 0; @@ -1101,9 +1199,6 @@ void CPad::AddToCheatString(char c) else if ( !_CHEATCMP("T33L1413") ) StrongGripCheat(); - // "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS - else if ( !_CHEATCMP("X1RT31DC1S") ) - NastyLimbsCheat(); #undef _CHEATCMP } #endif @@ -1120,6 +1215,7 @@ int Cheat_strncmp(char* sourceStr, char* origCheatStr) return 0; } +// TODO(Miami): Mobile has changed some of the cheats to include debugging things void CPad::AddToPCCheatString(char c) { for (int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i--) @@ -1394,6 +1490,16 @@ void CPad::AddToPCCheatString(char c) KeyBoardCheatString[0] = ' '; BackToTheFuture(); } + // LOADSOFLITTLETHINGS + else if (!Cheat_strncmp(KeyBoardCheatString, "VLUJUoHSU_VTMo`J]bV")) { + KeyBoardCheatString[0] = ' '; + SpecialCarCheats(); + } + // HOPINGIRL + else if (!Cheat_strncmp(KeyBoardCheatString, "OWPH[dSVI")) { + KeyBoardCheatString[0] = ' '; + PickUpChicksCheat(); + } //CERTAINDEATH else if (!Cheat_strncmp(KeyBoardCheatString, "KYHFQiLHU]RK")) { KeyBoardCheatString[0] = ' '; @@ -1410,10 +1516,6 @@ void CPad::AddToPCCheatString(char c) FannyMagnetCheat(); } - // "NASTYLIMBSCHEAT" - if (!_CHEATCMP("TAEHCSBMILYTSAN")) - NastyLimbsCheat(); - #ifdef KANGAROO_CHEAT // "KANGAROO" if (!_CHEATCMP("OORAGNAK")) @@ -1861,6 +1963,9 @@ void CPad::Update(int16 pad) if ( !bDisplayNoControllerMessage ) CGame::bDemoMode = false; + + if ( JustOutOfFrontend != 0 ) + --JustOutOfFrontend; } void CPad::DoCheats(void) @@ -1945,7 +2050,6 @@ CPad *CPad::GetPad(int32 pad) #define CURMODE (Mode) #endif - int16 CPad::GetSteeringLeftRight(void) { if ( ArePlayerControlsDisabled() ) @@ -2108,7 +2212,6 @@ int16 CPad::GetPedWalkLeftRight(void) return 0; } - int16 CPad::GetPedWalkUpDown(void) { if ( ArePlayerControlsDisabled() ) @@ -2172,6 +2275,36 @@ int16 CPad::GetAnalogueUpDown(void) return 0; } +int16 CPad::GetAnalogueLeftRight(void) +{ + switch (CURMODE) + { + case 0: + case 2: + { + int16 axis = NewState.LeftStickX; + int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2; + + if ( Abs(axis) > Abs(dpad) ) + return axis; + else + return dpad; + + break; + } + + case 1: + case 3: + { + return NewState.LeftStickX; + + break; + } + } + + return 0; +} + bool CPad::GetLookLeft(void) { if ( ArePlayerControlsDisabled() ) @@ -2283,7 +2416,6 @@ bool CPad::HornJustDown(void) return false; } - bool CPad::GetCarGunFired(void) { if ( ArePlayerControlsDisabled() ) @@ -2414,6 +2546,10 @@ bool CPad::GetExitVehicle(void) if ( ArePlayerControlsDisabled() ) return false; + + if ( JustOutOfFrontend != 0 ) + return false; + switch (CURMODE) { case 0: @@ -2441,6 +2577,9 @@ bool CPad::ExitVehicleJustDown(void) if ( ArePlayerControlsDisabled() ) return false; + if ( JustOutOfFrontend != 0 ) + return false; + switch (CURMODE) { case 0: @@ -2567,6 +2706,53 @@ int16 CPad::GetAccelerate(void) return 0; } +bool CPad::CycleCameraModeJustDown(void) +{ + bool result; + switch (CURMODE) + { + case 0: + case 2: + case 3: + { + result = !!(NewState.Select && !OldState.Select); + + break; + } + + case 1: + { + result = !!(NewState.DPadUp && !OldState.DPadUp); + + break; + } + default: + { + result = false; + break; + } + } + + if (!result) + { + switch (CURMODE) + { + case 1: + { + result = !!(NewState.DPadDown && !OldState.DPadDown); + break; + } + default: + { + result = false; + break; + } + } + } + + return result; +} + bool CPad::CycleCameraModeUpJustDown(void) { switch (CURMODE) @@ -2654,7 +2840,6 @@ bool CPad::ChangeStationJustDown(void) return false; } - bool CPad::CycleWeaponLeftJustDown(void) { if ( ArePlayerControlsDisabled() ) @@ -2813,23 +2998,23 @@ bool CPad::ShiftTargetRightJustDown(void) if ( ArePlayerControlsDisabled() ) return false; - return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); + return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1) || !!(NewState.RightShoulder2 && !OldState.RightShoulder2); } bool CPad::GetAnaloguePadUp(void) { static int16 oldfStickY = 0; - int16 Y = CPad::GetPad(0)->GetAnalogueUpDown(); + int16 leftStickY = CPad::GetPad(0)->GetLeftStickY(); - if ( Y < 0 && oldfStickY >= 0 ) + if ( leftStickY < -15 && oldfStickY >= -5 ) { - oldfStickY = Y; + oldfStickY = leftStickY; return true; } else { - oldfStickY = Y; + oldfStickY = leftStickY; return false; } } @@ -2838,16 +3023,16 @@ bool CPad::GetAnaloguePadDown(void) { static int16 oldfStickY = 0; - int16 Y = CPad::GetPad(0)->GetAnalogueUpDown(); + int16 leftStickY = CPad::GetPad(0)->GetLeftStickY(); - if ( Y > 0 && oldfStickY <= 0 ) + if ( leftStickY > 15 && oldfStickY <= 5 ) { - oldfStickY = Y; + oldfStickY = leftStickY; return true; } else { - oldfStickY = Y; + oldfStickY = leftStickY; return false; } } @@ -2856,16 +3041,16 @@ bool CPad::GetAnaloguePadLeft(void) { static int16 oldfStickX = 0; - int16 X = CPad::GetPad(0)->GetPedWalkLeftRight(); + int16 leftStickX = CPad::GetPad(0)->GetLeftStickX(); - if ( X < 0 && oldfStickX >= 0 ) + if ( leftStickX < -15 && oldfStickX >= -5 ) { - oldfStickX = X; + oldfStickX = leftStickX; return true; } else { - oldfStickX = X; + oldfStickX = leftStickX; return false; } } @@ -2874,16 +3059,16 @@ bool CPad::GetAnaloguePadRight(void) { static int16 oldfStickX = 0; - int16 X = CPad::GetPad(0)->GetPedWalkLeftRight(); + int16 leftStickX = CPad::GetPad(0)->GetLeftStickX(); - if ( X > 0 && oldfStickX <= 0 ) + if ( leftStickX > 15 && oldfStickX <= 5 ) { - oldfStickX = X; + oldfStickX = leftStickX; return true; } else { - oldfStickX = X; + oldfStickX = leftStickX; return false; } } @@ -2896,7 +3081,7 @@ bool CPad::GetAnaloguePadLeftJustUp(void) if ( X == 0 && oldfStickX < 0 ) { - oldfStickX = X; + oldfStickX = 0; return true; } @@ -2916,7 +3101,7 @@ bool CPad::GetAnaloguePadRightJustUp(void) if ( X == 0 && oldfStickX > 0 ) { - oldfStickX = X; + oldfStickX = 0; return true; } @@ -3022,23 +3207,35 @@ int16 CPad::SniperModeLookLeftRight(void) int16 axis = NewState.LeftStickX; int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2; - if ( Abs(axis) > Abs(dpad) ) - return axis; - else + if ( Abs(axis) > Abs(dpad) ) { + if ( Abs(axis) > 35.0f ) { + return (axis > 0.f ? axis - 35.f : axis + 35.f) * (128.f / (128 - 35)); + } else { + return 0; + } + } else return dpad; } int16 CPad::SniperModeLookUpDown(void) { int16 axis = NewState.LeftStickY; -#ifdef FIX_BUGS - axis = -axis; -#endif - int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2; + int16 dpad; - if ( Abs(axis) > Abs(dpad) ) - return axis; - else + if (CPad::bInvertLook4Pad) { + axis = -axis; + dpad = (NewState.DPadDown - NewState.DPadUp) / 2; + } else { + dpad = (NewState.DPadUp - NewState.DPadDown) / 2; + } + + if ( Abs(axis) > Abs(dpad) ) { + if ( Abs(axis) > 35.0f ) { + return (axis > 0.f ? axis - 35.f : axis + 35.f) * (128.f / (128 - 35)); + } else { + return 0; + } + } else return dpad; } @@ -3061,9 +3258,8 @@ int16 CPad::LookAroundUpDown(void) { int16 axis = GetPad(0)->NewState.RightStickY; -#ifdef FIX_BUGS - axis = -axis; -#endif + if (CPad::bInvertLook4Pad) + axis = -axis; if ( Abs(axis) > 85 && !GetLookBehindForPed() ) return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) ) @@ -3076,7 +3272,6 @@ int16 CPad::LookAroundUpDown(void) return 0; } - void CPad::ResetAverageWeapon(void) { AverageWeapon = GetWeapon(); @@ -3085,6 +3280,9 @@ void CPad::ResetAverageWeapon(void) void CPad::PrintErrorMessage(void) { + if (TheCamera.m_WideScreenOn) + return; + 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)); @@ -3135,29 +3333,33 @@ void CPad::ResetCheats(void) { CWeather::ReleaseWeather(); + gbFastTime = false; CPopulation::ms_bGivePedsWeapons = false; - - CPed::bNastyLimbsCheat = false; - CPed::bFannyMagnetCheat = false; - CPed::bPedCheat2 = false; - CPed::bPedCheat3 = false; + CTimer::SetTimeScale(1.0f); CVehicle::bWheelsOnlyCheat = false; CVehicle::bAllDodosCheat = false; CVehicle::bCheat3 = false; CVehicle::bCheat4 = false; CVehicle::bCheat5 = false; + CVehicle::bAllTaxisHaveNitro = false; + CVehicle::bHoverCheat = false; CVehicle::bCheat8 = false; + CVehicle::bCheat9 = false; + CVehicle::bCheat10 = false; #ifdef RESTORE_ALLCARSHELI_CHEAT bAllCarCheat = false; #endif gbBlackCars = false; gbPinkCars = false; + CCarCtrl::bMadDriversCheat = false; CTrafficLights::bGreenLightsCheat = false; CStats::ShowChaseStatOnScreen = 0; - gbFastTime = false; - CTimer::SetTimeScale(1.0f); + CPed::bNastyLimbsCheat = false; + CPed::bFannyMagnetCheat = false; + CPed::bPedCheat3 = false; + } char *CPad::EditString(char *pStr, int32 nSize) @@ -3362,3 +3564,13 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize) return pRsKeys; } + +void CPad::FixPadsAfterSave(void) +{ + UpdatePads(); + if ( bObsoleteControllerMessage ) + { + bObsoleteControllerMessage = false; + GetPad(0)->Phase = 0; + } +} diff --git a/src/core/Pad.h b/src/core/Pad.h index cde2d3c5..01f5bb9b 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -158,6 +158,7 @@ public: uint8 ShakeFreq; bool bHornHistory[HORNHISTORY_SIZE]; uint8 iCurrHornHistory; + int8 JustOutOfFrontend; int8 bApplyBrakes; char CheatString[12]; int32 LastTimeTouched; @@ -174,7 +175,9 @@ public: static bool bObsoleteControllerMessage; static bool bOldDisplayNoControllerMessage; static bool m_bMapPadOneToPadTwo; + static bool m_bDebugCamPCOn; static bool bHasPlayerCheated; + static bool bInvertLook4Pad; static CKeyboardState OldKeyState; static CKeyboardState NewKeyState; @@ -190,6 +193,7 @@ public: #endif void Clear(bool bResetPlayerControls); void ClearMouseHistory(); + void ClearKeyBoardHistory(); void UpdateMouse(); CControllerState ReconcileTwoControllersInput(CControllerState const &State1, CControllerState const &State2); void StartShake(int16 nDur, uint8 nFreq); @@ -219,6 +223,7 @@ public: int16 GetPedWalkLeftRight(void); int16 GetPedWalkUpDown(void); int16 GetAnalogueUpDown(void); + int16 GetAnalogueLeftRight(void); bool GetLookLeft(void); bool GetLookRight(void); bool GetLookBehindForCar(void); @@ -234,6 +239,7 @@ public: int32 GetWeapon(void); bool WeaponJustDown(void); int16 GetAccelerate(void); + bool CycleCameraModeJustDown(void); bool CycleCameraModeUpJustDown(void); bool CycleCameraModeDownJustDown(void); bool ChangeStationJustDown(void); @@ -261,6 +267,7 @@ public: int16 LookAroundLeftRight(void); int16 LookAroundUpDown(void); void ResetAverageWeapon(void); + static void FixPadsAfterSave(void); static void PrintErrorMessage(void); static void ResetCheats(void); static char *EditString(char *pStr, int32 nSize); diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index b9fc369d..5317040f 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -750,9 +750,7 @@ void CRadar::DrawBlips() void CRadar::DrawMap() { if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) { -#if 1 // from VC CalculateCachedSinCos(); -#endif if (FindPlayerVehicle()) { float speed = FindPlayerSpeed().Magnitude(); if (speed < RADAR_MIN_SPEED) @@ -1366,33 +1364,8 @@ void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D & void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in) { float s, c; -#if 1 s = -cachedSin; c = cachedCos; -#else - // Original code - - s = -Sin(TheCamera.GetForward().Heading()); - c = Cos(TheCamera.GetForward().Heading()); - - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) { - s = 0.0f; - c = 1.0f; - } - else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) { - CVector forward; - - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) { - forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward(); - forward.Normalise(); // a bit useless... - } - else - forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; - - s = -Sin(forward.Heading()); - c = Cos(forward.Heading()); - } -#endif out.x = s * in.y + c * in.x; out.y = c * in.y - s * in.x; @@ -1419,35 +1392,8 @@ void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &i void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in) { float s, c; -#if 1 s = cachedSin; c = cachedCos; -#else - // Original code - - float s, c; - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) { - s = 0.0f; - c = 1.0f; - } - else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) { - s = Sin(TheCamera.GetForward().Heading()); - c = Cos(TheCamera.GetForward().Heading()); - } - else { - CVector forward; - - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) { - forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward(); - forward.Normalise(); // a bit useless... - } - else - forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; - - s = Sin(forward.Heading()); - c = Cos(forward.Heading()); - } -#endif float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_radarRange); float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_radarRange); @@ -1534,10 +1480,10 @@ CRadar::ToggleTargetMarker(float x, float y) if (!ms_RadarTrace[nextBlip].m_bInUse) break; } -#ifdef FIX_BUGS + if (nextBlip == NUMRADARBLIPS) return; -#endif + ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD; ms_RadarTrace[nextBlip].m_nColor = 0x333333FF; ms_RadarTrace[nextBlip].m_bDim = 1; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index d296496e..ddde4664 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -46,7 +46,11 @@ CStreamingInfo CStreaming::ms_endRequestedList; int32 CStreaming::ms_oldSectorX; int32 CStreaming::ms_oldSectorY; int32 CStreaming::ms_streamingBufferSize; +#ifndef ONE_THREAD_PER_CHANNEL int8 *CStreaming::ms_pStreamingBuffer[2]; +#else +int8 *CStreaming::ms_pStreamingBuffer[4]; +#endif size_t CStreaming::ms_memoryUsed; CStreamingChannel CStreaming::ms_channel[2]; int32 CStreaming::ms_channelError; @@ -197,6 +201,10 @@ CStreaming::Init2(void) ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); ms_streamingBufferSize /= 2; ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; +#ifdef ONE_THREAD_PER_CHANNEL + ms_pStreamingBuffer[2] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); + ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; +#endif debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); // PC only, figure out how much memory we got @@ -2196,6 +2204,110 @@ CStreaming::LoadRequestedModels(void) } } + +// Let's load models first, then process it. Unfortunately processing models are still single-threaded. +// Currently only supported on POSIX streamer. +#ifdef ONE_THREAD_PER_CHANNEL +void +CStreaming::LoadAllRequestedModels(bool priority) +{ + static bool bInsideLoadAll = false; + int imgOffset, streamId, status; + int i; + uint32 posn, size; + + if(bInsideLoadAll) + return; + bInsideLoadAll = true; + + FlushChannels(); + imgOffset = GetCdImageOffset(CdStreamGetLastPosn()); + + int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)]; + int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)]; + int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)]; + bool first = true; + int processI = 0; + + while (true) { + // Enumerate files and start reading + for (int i=0; i<ARRAY_SIZE(ms_pStreamingBuffer); i++) { + if (!first && streamIds[i] != -1) { + processI = i; + continue; + } + + if(ms_endRequestedList.m_prev != &ms_startRequestedList){ + streamId = GetNextFileOnCd(0, priority); + if(streamId == -1){ + streamIds[i] = -1; + break; + } + + if (ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)) { + streamIds[i] = -1; + if (size > (uint32)ms_streamingBufferSize) { + if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer)) + continue; + else if (!first && streamIds[i+1] != -1) + continue; + } else { + if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize) + continue; + } + ms_aInfoForModel[streamId].RemoveFromList(); + DecrementRef(streamId); + + streamIds[i] = streamId; + streamSizes[i] = size; + streamPoses[i] = posn; + CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size); + processI = i; + } else { + ms_aInfoForModel[streamId].RemoveFromList(); + DecrementRef(streamId); + + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; + streamIds[i] = -1; + } + } else + streamIds[i] = -1; + } + + first = false; + + // Now process + if (streamIds[processI] == -1) + break; + + // Try again on error + while (CdStreamSync(processI) != STREAM_NONE) { + CdStreamRead(processI, ms_pStreamingBuffer[processI], imgOffset+streamPoses[processI], streamSizes[processI]); + } + ms_aInfoForModel[streamIds[processI]].m_loadState = STREAMSTATE_READING; + + MakeSpaceFor(streamSizes[processI] * CDSTREAM_SECTOR_SIZE); + ConvertBufferToObject(ms_pStreamingBuffer[processI], streamIds[processI]); + if(ms_aInfoForModel[streamIds[processI]].m_loadState == STREAMSTATE_STARTED) + FinishLoadingLargeFile(ms_pStreamingBuffer[processI], streamIds[processI]); + + if(streamIds[processI] < STREAM_OFFSET_TXD){ + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[processI]); + if(mi->IsSimple()) + mi->m_alpha = 255; + } + streamIds[processI] = -1; + } + + ms_bLoadingBigModel = false; + for(i = 0; i < 4; i++){ + ms_channel[1].streamIds[i] = -1; + ms_channel[1].offsets[i] = -1; + } + ms_channel[1].state = CHANNELSTATE_IDLE; + bInsideLoadAll = false; +} +#else void CStreaming::LoadAllRequestedModels(bool priority) { @@ -2256,6 +2368,7 @@ CStreaming::LoadAllRequestedModels(bool priority) ms_channel[1].state = CHANNELSTATE_IDLE; bInsideLoadAll = false; } +#endif void CStreaming::FlushChannels(void) @@ -2287,6 +2400,14 @@ CStreaming::FlushRequestList(void) next = si->m_next; RemoveModel(si - ms_aInfoForModel); } +#ifndef _WIN32 + if(ms_channel[0].state == CHANNELSTATE_READING) { + flushStream[0] = 1; + } + if(ms_channel[1].state == CHANNELSTATE_READING) { + flushStream[1] = 1; + } +#endif FlushChannels(); } @@ -2815,10 +2936,15 @@ CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem) void CStreaming::MakeSpaceFor(int32 size) { - // BUG: ms_memoryAvailable can be uninitialized - // the code still happens to work in that case because ms_memoryAvailable is unsigned - // but it's not nice.... - +#ifdef FIX_BUGS +#define MB (1024 * 1024) + if(ms_memoryAvailable == 0) { + extern size_t _dwMemAvailPhys; + ms_memoryAvailable = (_dwMemAvailPhys - 10 * MB) / 2; + if(ms_memoryAvailable < 65 * MB) ms_memoryAvailable = 65 * MB; + } +#undef MB +#endif while(ms_memoryUsed >= ms_memoryAvailable - size) if(!RemoveLeastUsedModel(STREAMFLAGS_20)){ DeleteRwObjectsBehindCamera(ms_memoryAvailable - size); diff --git a/src/core/common.h b/src/core/common.h index 16d32b32..c4c133fa 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -106,7 +106,7 @@ typedef uint16_t wchar; inline uint32 dpb(uint32 b, uint32 p, uint32 s, uint32 w) { uint32 m = MASK(p,s); - return w & ~m | b<<p & m; + return (w & ~m) | ((b<<p) & m); } inline uint32 ldb(uint32 p, uint32 s, uint32 w) { diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 1393314c..2e112442 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -100,7 +100,8 @@ void FastWeatherCheat(); void OnlyRenderWheelsCheat(); void ChittyChittyBangBangCheat(); void StrongGripCheat(); -void NastyLimbsCheat(); +void SpecialCarCheats(); +void PickUpChicksCheat(); DebugMenuEntry *carCol1; DebugMenuEntry *carCol2; @@ -370,7 +371,8 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Only render wheels", OnlyRenderWheelsCheat); DebugMenuAddCmd("Cheats", "Chitty chitty bang bang", ChittyChittyBangBangCheat); DebugMenuAddCmd("Cheats", "Strong grip", StrongGripCheat); - DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); + DebugMenuAddCmd("Cheats", "Special car", SpecialCarCheats); + DebugMenuAddCmd("Cheats", "Pickup chicks", PickUpChicksCheat); static int spawnCarId = MI_LANDSTAL; e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_VICECHEE, carnames); diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index a8057d26..58aba733 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -257,6 +257,9 @@ enum MI_VICE8, MI_WFYG2 = 106, // last regular ped MI_SPECIAL01 = 109, + MI_SPECIAL02 = 110, + MI_SPECIAL03 = 111, + MI_SPECIAL04 = 112, MI_SPECIAL21 = 129, MI_LAST_PED = MI_SPECIAL21, diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h index d9a3f59a..d03ab9bf 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -137,7 +137,7 @@ public: void SetVehicleComponentFlags(RwFrame *frame, uint32 flags); void PreprocessHierarchy(void); void GetWheelPosn(int32 n, CVector &pos); - CVector GetFrontSeatPosn(void) { return m_positions[m_vehicleType == VEHICLE_TYPE_BOAT ? BOAT_POS_FRONTSEAT : CAR_POS_FRONTSEAT]; }; + const CVector &GetFrontSeatPosn(void) { return m_vehicleType == VEHICLE_TYPE_BOAT ? m_positions[BOAT_POS_FRONTSEAT] : m_positions[CAR_POS_FRONTSEAT]; } int32 ChooseComponent(void); int32 ChooseSecondComponent(void); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index f6d54268..c5b19241 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -136,7 +136,6 @@ CVector vecPedBikeKickAnimOffset; bool CPed::bNastyLimbsCheat; bool CPed::bFannyMagnetCheat; -bool CPed::bPedCheat2; bool CPed::bPedCheat3; CVector2D CPed::ms_vec2DFleePosition; @@ -14404,7 +14403,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) return true; } -extern CVector vecTestTemp(-1.0f, -1.0f, -1.0f); +CVector vecTestTemp(-1.0f, -1.0f, -1.0f); // --MIAMI: Done void @@ -21441,4 +21440,4 @@ CPed::SetLook(float direction) SetPedState(PED_LOOK_HEADING); SetLookFlag(direction, false); } -}
\ No newline at end of file +} diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 3ee38df3..1f0e9243 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -1114,7 +1114,6 @@ public: static bool bNastyLimbsCheat; static bool bFannyMagnetCheat; - static bool bPedCheat2; static bool bPedCheat3; static CVector2D ms_vec2DFleePosition; diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp index 1ea9da50..79ce0461 100644 --- a/src/render/Occlusion.cpp +++ b/src/render/Occlusion.cpp @@ -366,6 +366,12 @@ COcclusion::ProcessBeforeRendering(void) } NumActiveOccluders--; i--; + // Taken from Mobile! +#ifdef FIX_BUGS + if (i == -1) { + i = 0; + } +#endif } } } @@ -481,4 +487,4 @@ void COcclusion::Render() { DefinedState(); } -#endif
\ No newline at end of file +#endif diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index 2f0c3809..6a42bc4d 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -1220,8 +1220,11 @@ void CParticle::Update() if ( psystem->m_Type == PARTICLE_HEATHAZE || psystem->m_Type == PARTICLE_HEATHAZE_IN_DIST ) { +#ifdef FIX_BUGS + int32 nSinCosIndex = (int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) + SIN_COS_TABLE_SIZE) % SIN_COS_TABLE_SIZE; +#else int32 nSinCosIndex = int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) % SIN_COS_TABLE_SIZE; - +#endif vecMoveStep.x = Sin(nSinCosIndex); vecMoveStep.y = Sin(nSinCosIndex); @@ -1233,8 +1236,11 @@ void CParticle::Update() if ( psystem->m_Type == PARTICLE_BEASTIE ) { +#ifdef FIX_BUGS + int32 nSinCosIndex = (int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) + SIN_COS_TABLE_SIZE) % SIN_COS_TABLE_SIZE; +#else int32 nSinCosIndex = int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) % SIN_COS_TABLE_SIZE; - +#endif particle->m_vecVelocity.x = 0.50f * Cos(nSinCosIndex); particle->m_vecVelocity.y = Cos(nSinCosIndex); particle->m_vecVelocity.z = 0.25f * Sin(nSinCosIndex); @@ -1750,7 +1756,11 @@ void CParticle::Update() } if ( particle->m_nRotationStep != 0 ) +#ifdef FIX_BUGS + particle->m_nRotation = CGeneral::LimitAngle(particle->m_nRotation + particle->m_nRotationStep); +#else particle->m_nRotation += particle->m_nRotationStep; +#endif if ( particle->m_fCurrentZRadius != 0.0f ) { @@ -2403,7 +2413,7 @@ void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos) { float fHeadingRad = entity->GetForward().Heading(); float fHeading = RADTODEG(fHeadingRad); - float fBirdAngle = Cos(DEGTORAD(1.5f)); + float fBirdAngle = ::Cos(DEGTORAD(1.5f)); tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[PARTICLE_BIRD_FRONT]; CParticle *particle = psystem->m_pParticles; diff --git a/src/render/WaterCreatures.cpp b/src/render/WaterCreatures.cpp index 906aba4a..51228073 100644 --- a/src/render/WaterCreatures.cpp +++ b/src/render/WaterCreatures.cpp @@ -160,16 +160,16 @@ void CWaterCreatures::CreateOne(CVector pos, int16 modelID) { && CWaterLevel::GetWaterDepth(pos, &fDepth, &fLevelNoWaves, nil) && fDepth > 4.5f) { if (modelID == -1 || modelID > 64) - modelID = CGeneral::GetRandomNumberInRange(0.0f, 64.0f); + modelID = CGeneral::GetRandomNumberInRange(0, 64); WaterCreatureProperties *creature = &aProperties[modelID]; pos.z = fLevelNoWaves - creature->fLevel; - float fRightMult = CGeneral::GetRandomNumberInRange(0.0f, 0.01); + float fRightMult = CGeneral::GetRandomNumberInRange(0.0f, 0.01f); float angle = CWaterCreatures::CalculateFishHeading(FindPlayerPed()->GetPosition(), pos); CObject *fish = CreateSeaLifeForm(pos, modelID, angle); - if (!fish) - return; + if (!fish) return; + fish->SetRwObjectAlpha(255); CWaterCreature *wc = GetFishStructSlot(); wc->Allocate(fish, fRightMult, 0.0f, creature->fWaterDepth, 255, WATER_CREATURE_ALLOCATED); diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index b38f1bd9..b98b8243 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -213,9 +213,7 @@ GenericSave(int file) #endif WriteDataToBufferPointer(buf, CGame::currArea); WriteDataToBufferPointer(buf, CVehicle::bAllTaxisHaveNitro); - // TODO(Miami): Pad invert Y - bool invertY = 0; - WriteDataToBufferPointer(buf, invertY); + WriteDataToBufferPointer(buf, CPad::bInvertLook4Pad); WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColour); WriteDataToBufferPointer(buf, CTimeCycle::m_bExtraColourOn); WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColourInter); @@ -279,7 +277,8 @@ GenericSave(int file) return false; } - + + CPad::FixPadsAfterSave(); return true; } @@ -352,9 +351,7 @@ GenericLoad() #endif ReadDataFromBufferPointer(buf, CGame::currArea); ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro); - // TODO(Miami): Pad invert Y - bool invertY = 0; - ReadDataFromBufferPointer(buf, invertY); + ReadDataFromBufferPointer(buf, CPad::bInvertLook4Pad); ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour); ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn); ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter); diff --git a/src/skel/events.cpp b/src/skel/events.cpp index 3e1e95b3..6589ab71 100644 --- a/src/skel/events.cpp +++ b/src/skel/events.cpp @@ -9,6 +9,8 @@ #include "events.h" +// --MIAMI: file done + /* ***************************************************************************** */ diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index b40130c4..0f520cad 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -81,7 +81,12 @@ 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> @@ -449,15 +454,27 @@ psInitialize(void) #endif #endif +#ifndef __APPLE__ struct sysinfo systemInfo; sysinfo(&systemInfo); - _dwMemAvailPhys = systemInfo.freeram; - _dwOperatingSystemVersion = OS_WINXP; // To fool other classes - debug("Physical memory size %u\n", systemInfo.totalram); debug("Available physical memory %u\n", systemInfo.freeram); - +#else + uint64_t size = 0; + uint64_t page_size = 0; + size_t uint64_len = sizeof(uint64_t); + size_t ull_len = sizeof(unsigned long long); + sysctl((int[]){CTL_HW, HW_PAGESIZE}, 2, &page_size, &ull_len, NULL, 0); + sysctl((int[]){CTL_HW, HW_MEMSIZE}, 2, &size, &uint64_len, NULL, 0); + vm_statistics_data_t vm_stat; + mach_msg_type_number_t count = HOST_VM_INFO_COUNT; + host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &count); + _dwMemAvailPhys = (uint64_t)(vm_stat.free_count * page_size); + debug("Physical memory size %llu\n", _dwMemAvailPhys); + debug("Available physical memory %llu\n", size); +#endif + _dwOperatingSystemVersion = OS_WINXP; // To fool other classes #endif TheText.Unload(); @@ -1211,7 +1228,9 @@ void terminateHandler(int sig, siginfo_t *info, void *ucontext) { } void dummyHandler(int sig){ + // Don't kill the app pls } + #endif void resizeCB(GLFWwindow* window, int width, int height) { @@ -1458,9 +1477,10 @@ main(int argc, char *argv[]) act.sa_flags = SA_SIGINFO; sigaction(SIGTERM, &act, NULL); struct sigaction sa; + sigemptyset(&sa.sa_mask); sa.sa_handler = dummyHandler; sa.sa_flags = 0; - sigaction(SIGINT, &sa, NULL); // Needed for CdStreamPosix + sigaction(SIGUSR1, &sa, NULL); // Needed for CdStreamPosix #endif /* diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 01a4f094..1316985d 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -841,8 +841,8 @@ CAutomobile::ProcessControl(void) m_nBusDoorTimerEnd -= CTimer::GetTimeStepInMilliseconds(); } - if(m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[1] < 1.0f || - m_aSuspensionSpringRatio[2] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f) + if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) && + (m_aSuspensionSpringRatio[1] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f)) ApplyTurnForce(-GRAVITY*Min(m_fTurnMass, 2500.0f)*GetUp(), -1.0f*GetForward()); } diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 1664ffd0..8c9dd241 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -959,17 +959,24 @@ CBoat::PreRender(void) matrix.Translate(pos); matrix.UpdateRW(); } + // 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); +#else + float steeringUpDown = -CPad::GetPad(0)->GetSteeringUpDown()/128.0f; +#endif if(m_aBoatNodes[BOAT_REARFLAP_LEFT]){ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_LEFT])); pos = matrix.GetPosition(); - matrix.SetRotateX(-CPad::GetPad(0)->GetSteeringUpDown()/128.0f); + matrix.SetRotateX(steeringUpDown); matrix.Translate(pos); matrix.UpdateRW(); } if(m_aBoatNodes[BOAT_REARFLAP_RIGHT]){ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_RIGHT])); pos = matrix.GetPosition(); - matrix.SetRotateX(-CPad::GetPad(0)->GetSteeringUpDown()/128.0f); + matrix.SetRotateX(steeringUpDown); matrix.Translate(pos); matrix.UpdateRW(); } diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index b0fa91a4..598b8342 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -28,8 +28,13 @@ uint32 CTheCarGenerators::CurrentActiveCount; void CCarGenerator::SwitchOff() { - m_nUsesRemaining = 0; - --CTheCarGenerators::CurrentActiveCount; +#ifdef FIX_BUGS + if (m_nUsesRemaining != 0) +#endif + { + m_nUsesRemaining = 0; + --CTheCarGenerators::CurrentActiveCount; + } } void CCarGenerator::SwitchOn() diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index e3d73771..6e86dbe4 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -41,6 +41,8 @@ bool CVehicle::bCheat3; bool CVehicle::bCheat4; bool CVehicle::bCheat5; bool CVehicle::bCheat8; +bool CVehicle::bCheat9; +bool CVehicle::bCheat10; bool CVehicle::bHoverCheat; bool CVehicle::bAllTaxisHaveNitro; bool CVehicle::m_bDisableMouseSteering = true; diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 6bd6f7c6..004f1fd9 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -187,7 +187,7 @@ public: CAutoPilot AutoPilot; uint8 m_currentColour1; uint8 m_currentColour2; - uint8 m_aExtras[2]; + int8 m_aExtras[2]; int16 m_nAlarmState; int16 m_nRouteSeed; CPed *pDriver; @@ -400,6 +400,8 @@ public: static bool bCheat4; static bool bCheat5; static bool bCheat8; + static bool bCheat9; + static bool bCheat10; static bool bHoverCheat; static bool bAllTaxisHaveNitro; static bool m_bDisableMouseSteering; diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 0efe6688..375a2ca9 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -23,6 +23,9 @@ #include "WeaponInfo.h" #include "World.h" #include "SurfaceTable.h" +#include "Heli.h" + +// --MIAMI: file done #ifdef SQUEEZE_PERFORMANCE uint32 bulletInfoInUse; @@ -32,9 +35,14 @@ uint32 bulletInfoInUse; #define NUM_PED_BLOOD_PARTICLES (8) #define BLOOD_PARTICLE_OFFSET (CVector(0.0f, 0.0f, 0.0f)) #define NUM_VEHICLE_SPARKS (16) +#define NUM_TYRE_POP_SMOKES (4) #define NUM_OTHER_SPARKS (8) #define BULLET_HIT_FORCE (7.5f) -#define MAP_BORDER (1960.0f) + +#define BULLET_BOUNDARY_MIN_X -2400.0f +#define BULLET_BOUNDARY_MAX_X 1600.0f +#define BULLET_BOUNDARY_MIN_Y -2000.0f +#define BULLET_BOUNDARY_MAX_Y 2000.0f CBulletInfo gaBulletInfo[CBulletInfo::NUM_BULLETS]; bool bPlayerSniperBullet; @@ -106,14 +114,18 @@ void CBulletInfo::Update(void) } CVector vecOldPos = pBullet->m_vecPosition; CVector vecNewPos = pBullet->m_vecPosition + pBullet->m_vecSpeed * CTimer::GetTimeStep() * 0.5f; - CWorld::bIncludeCarTyres = true; + + if ( vecNewPos.x <= BULLET_BOUNDARY_MIN_X || vecNewPos.x >= BULLET_BOUNDARY_MAX_X || vecNewPos.y <= BULLET_BOUNDARY_MIN_Y || vecNewPos.y >= BULLET_BOUNDARY_MAX_Y ) { + pBullet->m_bInUse = false; + continue; + } CWorld::bIncludeDeadPeds = true; + CWorld::bIncludeBikers = true; + CWorld::bIncludeCarTyres = true; CWorld::pIgnoreEntity = pBullet->m_pSource; CColPoint point; CEntity* pHitEntity; if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, false, false, true)) { - if (pBullet->m_pSource && (pHitEntity->IsPed() || pHitEntity->IsVehicle())) - CStats::BulletsThatHit++; CWeapon::CheckForShootingVehicleOccupant(&pHitEntity, &point, pBullet->m_eWeaponType, vecOldPos, vecNewPos); if (pHitEntity->IsPed()) { @@ -128,7 +140,7 @@ void CBulletInfo::Update(void) CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000); pBullet->m_bInUse = false; #ifdef SQUEEZE_PERFORMANCE - bulletInfoInUse--; + bulletInfoInUse--; #endif vecNewPos = point.point; } @@ -159,13 +171,24 @@ void CBulletInfo::Update(void) } } else if (pHitEntity->IsVehicle()) { - CVehicle* pVehicle = (CVehicle*)pHitEntity; - pVehicle->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage); - if (pBullet->m_eWeaponType == WEAPONTYPE_FLAMETHROWER) // huh? - gFireManager.StartFire(pVehicle, pBullet->m_pSource, 0.8f, true); - else { - for (int j = 0; j < NUM_VEHICLE_SPARKS; j++) - CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20); + CEntity *source = pBullet->m_pSource; + if ( !source || !source->IsPed() || ((CPed*)source)->m_attachedTo != pHitEntity) { + if ( point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR ) { + ((CVehicle*)pHitEntity)->BurstTyre(point.pieceB, true); + for (int j=0; j<NUM_TYRE_POP_SMOKES; j++) { + CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, point.point, point.normal / 20); + } + } else { + // CVector sth(0.0f, 0.0f, 0.0f); // unused + ((CVehicle*)pHitEntity)->InflictDamage(source, pBullet->m_eWeaponType, pBullet->m_nDamage); + if ( pBullet->m_eWeaponType == WEAPONTYPE_FLAMETHROWER ) { + gFireManager.StartFire(pHitEntity, pBullet->m_pSource, 0.8f, 1); + } else { + for (int j=0; j<NUM_VEHICLE_SPARKS; j++) { + CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20); + } + } + } } #ifdef FIX_BUGS pBullet->m_bInUse = false; @@ -174,19 +197,28 @@ void CBulletInfo::Update(void) #endif vecNewPos = point.point; #endif - } - else { + } else { for (int j = 0; j < NUM_OTHER_SPARKS; j++) CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20); - if (pHitEntity->IsObject()) { - CObject* pObject = (CObject*)pHitEntity; - if (!pObject->bInfiniteMass) { - if (pObject->IsStatic() && pObject->m_fUprootLimit <= 0.0f) { - pObject->bIsStatic = false; - pObject->AddToMovingList(); + CEntity *source = pBullet->m_pSource; + if ( !source || !source->IsPed() || ((CPed*)source)->m_attachedTo != pHitEntity) { + if (pHitEntity->IsObject()) { + CObject *pHitObject = (CObject*)pHitEntity; + if ( !pHitObject->bInfiniteMass && pHitObject->m_fCollisionDamageMultiplier < 99.9f) { + bool notStatic = !pHitObject->IsStatic(); + if (notStatic && pHitObject->m_fUprootLimit <= 0.0f) { + pHitObject->bIsStatic = false; + pHitObject->AddToMovingList(); + } + + notStatic = !pHitObject->IsStatic(); + if (!notStatic) { + CVector moveForce = point.normal * -BULLET_HIT_FORCE; + pHitObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z); + } + } else if (pHitObject->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY) { + pHitObject->ObjectDamage(50.f); } - if (!pObject->IsStatic()) - pObject->ApplyMoveForce(-BULLET_HIT_FORCE * point.normal); } } #ifdef FIX_BUGS @@ -200,35 +232,52 @@ void CBulletInfo::Update(void) if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { cAudioScriptObject* pAudio; switch (pHitEntity->GetType()) { - case ENTITY_TYPE_BUILDING: - pAudio = new cAudioScriptObject(); - pAudio->Posn = pHitEntity->GetPosition(); - pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_1; - pAudio->AudioEntity = AEHANDLE_NONE; - DMAudio.CreateOneShotScriptObject(pAudio); - break; - case ENTITY_TYPE_OBJECT: - pAudio = new cAudioScriptObject(); - pAudio->Posn = pHitEntity->GetPosition(); - pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_2; - pAudio->AudioEntity = AEHANDLE_NONE; - DMAudio.CreateOneShotScriptObject(pAudio); - break; - case ENTITY_TYPE_DUMMY: - pAudio = new cAudioScriptObject(); - pAudio->Posn = pHitEntity->GetPosition(); - pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_3; - pAudio->AudioEntity = AEHANDLE_NONE; - DMAudio.CreateOneShotScriptObject(pAudio); - break; - case ENTITY_TYPE_PED: - DMAudio.PlayOneShot(((CPed*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f); - ((CPed*)pHitEntity)->Say(SOUND_PED_BULLET_HIT); - break; - case ENTITY_TYPE_VEHICLE: - DMAudio.PlayOneShot(((CVehicle*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f); - break; - default: break; + case ENTITY_TYPE_BUILDING: + if (!DMAudio.IsAudioInitialised()) + break; + + pAudio = new cAudioScriptObject(); + if (pAudio) + pAudio->Reset(); + pAudio->Posn = pHitEntity->GetPosition(); + pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_1; + pAudio->AudioEntity = AEHANDLE_NONE; + DMAudio.CreateOneShotScriptObject(pAudio); + break; + case ENTITY_TYPE_OBJECT: + if (!DMAudio.IsAudioInitialised()) + break; + + pAudio = new cAudioScriptObject(); + if (pAudio) + pAudio->Reset(); + pAudio->Posn = pHitEntity->GetPosition(); + pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_2; + pAudio->AudioEntity = AEHANDLE_NONE; + DMAudio.CreateOneShotScriptObject(pAudio); + break; + case ENTITY_TYPE_DUMMY: + if (!DMAudio.IsAudioInitialised()) + break; + + pAudio = new cAudioScriptObject(); + if (pAudio) + pAudio->Reset(); + pAudio->Posn = pHitEntity->GetPosition(); + pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_3; + pAudio->AudioEntity = AEHANDLE_NONE; + DMAudio.CreateOneShotScriptObject(pAudio); + break; + case ENTITY_TYPE_PED: + ++CStats::BulletsThatHit; + DMAudio.PlayOneShot(((CPed*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f); + ((CPed*)pHitEntity)->Say(SOUND_PED_BULLET_HIT); + break; + case ENTITY_TYPE_VEHICLE: + ++CStats::BulletsThatHit; + DMAudio.PlayOneShot(((CVehicle*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f); + break; + default: break; } } CGlass::WasGlassHitByBullet(pHitEntity, point.point); @@ -237,19 +286,14 @@ void CBulletInfo::Update(void) CWorld::pIgnoreEntity = nil; CWorld::bIncludeDeadPeds = false; CWorld::bIncludeCarTyres = false; + CWorld::bIncludeBikers = false; if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { bPlayerSniperBullet = true; PlayerSniperBulletStart = pBullet->m_vecPosition; PlayerSniperBulletEnd = vecNewPos; } pBullet->m_vecPosition = vecNewPos; - if (pBullet->m_vecPosition.x < -MAP_BORDER || pBullet->m_vecPosition.x > MAP_BORDER || - pBullet->m_vecPosition.y < -MAP_BORDER || pBullet->m_vecPosition.y > MAP_BORDER) { - pBullet->m_bInUse = false; -#ifdef SQUEEZE_PERFORMANCE - bulletInfoInUse--; -#endif - } + CHeli::TestSniperCollision(&PlayerSniperBulletStart, &PlayerSniperBulletEnd); } } diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp index 4150852a..71cd9cfb 100644 --- a/src/weapons/ProjectileInfo.cpp +++ b/src/weapons/ProjectileInfo.cpp @@ -17,9 +17,16 @@ uint32 projectileInUse; #endif +// --MIAMI: file done except TODOs + CProjectileInfo gaProjectileInfo[NUM_PROJECTILES]; CProjectile *CProjectileInfo::ms_apProjectile[NUM_PROJECTILES]; +#define PROJECTILE_BOUNDARY_MIN_X -2390.0f +#define PROJECTILE_BOUNDARY_MAX_X 1590.0f +#define PROJECTILE_BOUNDARY_MIN_Y -1990.0f +#define PROJECTILE_BOUNDARY_MAX_Y 1990.0f + void CProjectileInfo::Initialise() { @@ -53,7 +60,6 @@ CProjectileInfo::GetProjectileInfo(int32 id) return &gaProjectileInfo[id]; } -// --MIAMI: Mostly done bool CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, float speed) { @@ -67,70 +73,87 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, switch (weapon) { - case WEAPONTYPE_ROCKET: - { - float vy = 0.35f; - time = CTimer::GetTimeInMilliseconds() + 2000; - if (entity->GetModelIndex() == MI_SPARROW || entity->GetModelIndex() == MI_HUNTER || entity->GetModelIndex() == MI_SENTINEL) { - matrix = ped->GetMatrix(); - matrix.GetPosition() = pos; - CVector vecSpeed = ((CPhysical*)entity)->m_vecMoveSpeed; - vy += Max(0.0f, DotProduct(vecSpeed, entity->GetForward())) + Max(0.0f, DotProduct(vecSpeed, entity->GetUp())); - } else { - if (ped->IsPlayer()) { - matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front; - matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up; - matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front); + case WEAPONTYPE_ROCKET: + { + float vy = 0.35f; + time = CTimer::GetTimeInMilliseconds() + 2000; + if (entity->GetModelIndex() == MI_SPARROW || entity->GetModelIndex() == MI_HUNTER || entity->GetModelIndex() == MI_SENTINEL) { + matrix = ped->GetMatrix(); matrix.GetPosition() = pos; - } else if (ped->m_pSeekTarget != nil) { - float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z); - float rz = Atan2(-ped->GetForward().x, ped->GetForward().y); - vy = 0.35f * speed + 0.15f; - matrix.SetTranslate(0.0f, 1.0f, 1.0f); - matrix.Rotate(0.0f, ry, rz); - matrix.GetPosition() += pos; + CVector vecSpeed = ((CPhysical*)entity)->m_vecMoveSpeed; + vy += Max(0.0f, DotProduct(vecSpeed, entity->GetForward())) + Max(0.0f, DotProduct(vecSpeed, entity->GetUp())); } else { - matrix = ped->GetMatrix(); + if (ped->IsPlayer()) { + matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front; + matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up; + matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front); + matrix.GetPosition() = pos; + } else if (ped->m_pSeekTarget != nil) { + float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z); + float rz = Atan2(-ped->GetForward().x, ped->GetForward().y); + vy = 0.35f * speed + 0.15f; + matrix.SetTranslate(0.0f, 1.0f, 1.0f); + matrix.Rotate(0.0f, ry, rz); + matrix.GetPosition() += pos; + } else { + matrix = ped->GetMatrix(); + } } + velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f)); + gravity = false; + break; } - velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f)); - gravity = false; - break; - } - case WEAPONTYPE_MOLOTOV: - { - time = CTimer::GetTimeInMilliseconds() + 2000; - float scale = 0.22f * speed + 0.15f; - if (scale < 0.2f) - scale = 0.2f; - float angle = Atan2(-ped->GetForward().x, ped->GetForward().y); - matrix.SetTranslate(0.0f, 0.0f, 0.0f); - matrix.RotateZ(angle); - matrix.GetPosition() += pos; - velocity.x = -1.0f * scale * Sin(angle); - velocity.y = scale * Cos(angle); - velocity.z = (0.2f * speed + 0.4f) * scale; - break; - } - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_DETONATOR_GRENADE: - { - time = CTimer::GetTimeInMilliseconds() + 2000; - float scale = 0.0f; - if (speed != 0.0f) - scale = 0.22f * speed + 0.15f; - float angle = Atan2(-ped->GetForward().x, ped->GetForward().y); - matrix.SetTranslate(0.0f, 0.0f, 0.0f); - matrix.RotateZ(angle); - matrix.GetPosition() += pos; - SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5; - velocity.x = -1.0f * scale * Sin(angle); - velocity.y = scale * Cos(angle); - velocity.z = (0.4f * speed + 0.4f) * scale; - elasticity = 0.5f; - break; - } - default: + case WEAPONTYPE_MOLOTOV: + { + time = CTimer::GetTimeInMilliseconds() + 2000; + float scale = 0.22f * speed + 0.15f; + if (scale < 0.2f) + scale = 0.2f; + float angle = Atan2(-ped->GetForward().x, ped->GetForward().y); + matrix.SetTranslate(0.0f, 0.0f, 0.0f); + matrix.RotateZ(angle); + matrix.GetPosition() += pos; + velocity.x = -1.0f * scale * Sin(angle); + velocity.y = scale * Cos(angle); + velocity.z = (0.2f * speed + 0.4f) * scale; + break; + } + case WEAPONTYPE_TEARGAS: + { + time = CTimer::GetTimeInMilliseconds() + 20000; + float scale = 0.0f; + if (speed != 0.0f) + scale = 0.22f * speed + 0.15f; + float angle = Atan2(-ped->GetForward().x, ped->GetForward().y); + matrix.SetTranslate(0.0f, 0.0f, 0.0f); + matrix.RotateZ(angle); + matrix.GetPosition() += pos; + SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5; + velocity.x = -1.0f * scale * Sin(angle); + velocity.y = scale * Cos(angle); + velocity.z = (0.4f * speed + 0.4f) * scale; + elasticity = 0.5f; + break; + } + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_DETONATOR_GRENADE: + { + time = CTimer::GetTimeInMilliseconds() + 2000; + float scale = 0.0f; + if (speed != 0.0f) + scale = 0.22f * speed + 0.15f; + float angle = Atan2(-ped->GetForward().x, ped->GetForward().y); + matrix.SetTranslate(0.0f, 0.0f, 0.0f); + matrix.RotateZ(angle); + matrix.GetPosition() += pos; + SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5; + velocity.x = -1.0f * scale * Sin(angle); + velocity.y = scale * Cos(angle); + velocity.z = (0.4f * speed + 0.4f) * scale; + elasticity = 0.5f; + break; + } + default: Error("Undefined projectile type, AddProjectile, ProjectileInfo.cpp"); break; } @@ -143,19 +166,20 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, switch (weapon) { - case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET: ms_apProjectile[i] = new CProjectile(MI_MISSILE); break; - case WEAPONTYPE_FLAMETHROWER: + case WEAPONTYPE_TEARGAS: + ms_apProjectile[i] = new CProjectile(MI_TEARGAS); break; - case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_MOLOTOV: ms_apProjectile[i] = new CProjectile(MI_MOLOTOV); break; - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_DETONATOR_GRENADE: + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_DETONATOR_GRENADE: ms_apProjectile[i] = new CProjectile(MI_GRENADE); break; - default: break; + default: break; } if (ms_apProjectile[i] == nil) @@ -189,7 +213,18 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, void CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile) { - RemoveNotAdd(info->m_pSource, info->m_eWeaponType, projectile->GetPosition()); + // TODO(Miami): New parameter: 1 + switch (info->m_eWeaponType) { + case WEAPONTYPE_GRENADE: + CExplosion::AddExplosion(nil, info->m_pSource, EXPLOSION_GRENADE, projectile->GetPosition(), 0); + break; + case WEAPONTYPE_MOLOTOV: + CExplosion::AddExplosion(nil, info->m_pSource, EXPLOSION_MOLOTOV, projectile->GetPosition(), 0); + break; + case WEAPONTYPE_ROCKET: + CExplosion::AddExplosion(nil, info->m_pSource->IsVehicle() ? ((CVehicle*)info->m_pSource)->pDriver : info->m_pSource, EXPLOSION_ROCKET, projectile->GetPosition(), 0); + break; + } #ifdef SQUEEZE_PERFORMANCE projectileInUse--; #endif @@ -202,18 +237,17 @@ CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile void CProjectileInfo::RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos) { - switch (weaponType) - { - case WEAPONTYPE_GRENADE: - CExplosion::AddExplosion(nil, entity, EXPLOSION_GRENADE, pos, 0); - break; - case WEAPONTYPE_MOLOTOV: - CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0); - break; - case WEAPONTYPE_ROCKET: - CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0); - break; - default: break; + // TODO(Miami): New parameter: 1 + switch (weaponType) { + case WEAPONTYPE_GRENADE: + CExplosion::AddExplosion(nil, entity, EXPLOSION_GRENADE, pos, 0); + break; + case WEAPONTYPE_MOLOTOV: + CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0); + break; + case WEAPONTYPE_ROCKET: + CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0); + break; } } @@ -225,6 +259,8 @@ CProjectileInfo::Update() return; #endif + int tearGasOffset = -0.0f; // unused + for (int i = 0; i < ARRAY_SIZE(gaProjectileInfo); i++) { if (!gaProjectileInfo[i].m_bInUse) continue; @@ -240,21 +276,48 @@ CProjectileInfo::Update() gaProjectileInfo[i].m_bInUse = false; continue; } + if ( (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_TEARGAS) && ms_apProjectile[i]->m_fElasticity > 0.1f ) { + if ( Abs(ms_apProjectile[i]->m_vecMoveSpeed.x) < 0.05f && Abs(ms_apProjectile[i]->m_vecMoveSpeed.y) < 0.05f && Abs(ms_apProjectile[i]->m_vecMoveSpeed.z) < 0.05f ) { + ms_apProjectile[i]->m_fElasticity = 0.03f; + } + } + const CVector &projectilePos = ms_apProjectile[i]->GetPosition(); + CVector nextPos = CTimer::GetTimeStep() * ms_apProjectile[i]->m_vecMoveSpeed + projectilePos; + + if ( nextPos.x <= PROJECTILE_BOUNDARY_MIN_X || nextPos.x >= PROJECTILE_BOUNDARY_MAX_X || nextPos.y <= PROJECTILE_BOUNDARY_MIN_Y || nextPos.y >= PROJECTILE_BOUNDARY_MAX_Y ) { + // Not RemoveProjectile, because we don't want no explosion + gaProjectileInfo[i].m_bInUse = false; + CWorld::Remove(ms_apProjectile[i]); + delete ms_apProjectile[i]; + continue; + } + if ( gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_TEARGAS && CTimer::GetTimeInMilliseconds() > gaProjectileInfo[i].m_nExplosionTime - 19500 ) { + CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(0.2f, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0); + CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(-0.2f, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0); + CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(tearGasOffset, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0); + + // TODO(Miami): SetPedsChoking + /*if ( CTimer::GetTimeInMilliseconds() & 0x200 ) + CWorld::SetPedsChoking(projectilePos.x, projectilePos.y, projectilePos.z, 6.0f, gaProjectileInfo[i].m_pSource); + */ + } if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) { - CParticle::AddParticle(PARTICLE_SMOKE, ms_apProjectile[i]->GetPosition(), CVector(0.0f, 0.0f, 0.0f)); + CParticle::AddParticlesAlongLine(PARTICLE_ROCKET_SMOKE, gaProjectileInfo[i].m_vecPos, projectilePos, CVector(0.0f, 0.0f, 0.0f), 0.7f, 0, 0, 0, 3000); } - if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime) { + if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime || gaProjectileInfo[i].m_nExplosionTime == 0) { if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) { CVector pos = ms_apProjectile[i]->GetPosition(); CWorld::pIgnoreEntity = ms_apProjectile[i]; if (ms_apProjectile[i]->bHasCollided || !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false) - || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) { + || CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos)) { RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]); } CWorld::pIgnoreEntity = nil; + ms_apProjectile[i]->m_vecMoveSpeed *= 1.07f; + } else if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV) { CVector pos = ms_apProjectile[i]->GetPosition(); CWorld::pIgnoreEntity = ms_apProjectile[i]; @@ -263,8 +326,7 @@ CProjectileInfo::Update() || ((gaProjectileInfo[i].m_vecPos - gaProjectileInfo[i].m_pSource->GetPosition()).MagnitudeSqr() >= 2.0f)) { if (ms_apProjectile[i]->bHasCollided - || !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false) - || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) { + || !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)) { RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]); } } @@ -315,13 +377,12 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo return result; } -// --MIAMI: Done void CProjectileInfo::RemoveDetonatorProjectiles() { for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) { if (gaProjectileInfo[i].m_bInUse && gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) { - CExplosion::AddExplosion(nil, gaProjectileInfo[i].m_pSource, EXPLOSION_GRENADE, gaProjectileInfo[i].m_vecPos, 0); // TODO(Miami): New parameter (1) + CExplosion::AddExplosion(nil, gaProjectileInfo[i].m_pSource, EXPLOSION_GRENADE, gaProjectileInfo[i].m_vecPos, 0); // TODO(Miami): New parameter: 1 gaProjectileInfo[i].m_bInUse = false; CWorld::Remove(ms_apProjectile[i]); delete ms_apProjectile[i]; diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index 6debf725..b911805d 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -249,28 +249,28 @@ CWeaponInfo::LoadWeaponData(void) ms_apWeaponInfos[weaponType].m_nModelId = modelId; ms_apWeaponInfos[weaponType].m_nModel2Id = modelId2; - ms_apWeaponInfos[weaponType].m_bUseGravity = flags; - ms_apWeaponInfos[weaponType].m_bSlowsDown = flags >> 1; - ms_apWeaponInfos[weaponType].m_bDissipates = flags >> 2; - ms_apWeaponInfos[weaponType].m_bRandSpeed = flags >> 3; - ms_apWeaponInfos[weaponType].m_bExpands = flags >> 4; - ms_apWeaponInfos[weaponType].m_bExplodes = flags >> 5; - ms_apWeaponInfos[weaponType].m_bCanAim = flags >> 6; - ms_apWeaponInfos[weaponType].m_bCanAimWithArm = flags >> 7; - ms_apWeaponInfos[weaponType].m_b1stPerson = flags >> 8; - ms_apWeaponInfos[weaponType].m_bHeavy = flags >> 9; - ms_apWeaponInfos[weaponType].m_bThrow = flags >> 10; - ms_apWeaponInfos[weaponType].m_bReloadLoop2Start = flags >> 11; - ms_apWeaponInfos[weaponType].m_bUse2nd = flags >> 12; - ms_apWeaponInfos[weaponType].m_bGround2nd = flags >> 13; - ms_apWeaponInfos[weaponType].m_bFinish3rd = flags >> 14; - ms_apWeaponInfos[weaponType].m_bReload = flags >> 15; - ms_apWeaponInfos[weaponType].m_bFightMode = flags >> 16; - ms_apWeaponInfos[weaponType].m_bCrouchFire = flags >> 17; - ms_apWeaponInfos[weaponType].m_bCop3rd = flags >> 18; - ms_apWeaponInfos[weaponType].m_bGround3rd = flags >> 19; - ms_apWeaponInfos[weaponType].m_bPartialAttack = flags >> 20; - ms_apWeaponInfos[weaponType].m_bAnimDetonate = flags >> 21; + 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_nWeaponSlot = weaponSlot; |