summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/AnimViewer.cpp4
-rw-r--r--src/core/Cam.cpp2
-rw-r--r--src/core/Camera.cpp16
-rw-r--r--src/core/Camera.h3
-rw-r--r--src/core/CdStream.cpp10
-rw-r--r--src/core/CdStream.h6
-rw-r--r--src/core/CdStreamPosix.cpp516
-rw-r--r--src/core/Collision.cpp2
-rw-r--r--src/core/ControllerConfig.cpp45
-rw-r--r--src/core/FileLoader.cpp2
-rw-r--r--src/core/FileMgr.cpp59
-rw-r--r--src/core/Fire.cpp8
-rw-r--r--src/core/Frontend.cpp44
-rw-r--r--src/core/Frontend.h3
-rw-r--r--src/core/Game.cpp2
-rw-r--r--src/core/Pad.cpp4
-rw-r--r--src/core/Pools.cpp4
-rw-r--r--src/core/Profile.cpp4
-rw-r--r--src/core/Profile.h4
-rw-r--r--src/core/Streaming.cpp11
-rw-r--r--src/core/SurfaceTable.cpp2
-rw-r--r--src/core/SurfaceTable.h2
-rw-r--r--src/core/Timer.cpp31
-rw-r--r--src/core/World.cpp1
-rw-r--r--src/core/Zones.cpp6
-rw-r--r--src/core/config.h11
-rw-r--r--src/core/main.cpp13
-rw-r--r--src/core/main.h4
-rw-r--r--src/core/patcher.cpp20
-rw-r--r--src/core/re3.cpp51
30 files changed, 794 insertions, 96 deletions
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index 4092a210..35106a6b 100644
--- a/src/core/AnimViewer.cpp
+++ b/src/core/AnimViewer.cpp
@@ -120,7 +120,7 @@ CAnimViewer::Initialise(void) {
if (!CFileMgr::ReadLine(fd, gString, 255))
break;
- sscanf(gString, "%s %s", &modelName, &animGroup);
+ sscanf(gString, "%s %s", modelName, animGroup);
int groupId;
for (groupId = 0; groupId < NUM_ANIM_ASSOC_GROUPS; groupId++) {
if (!strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)groupId)))
@@ -423,4 +423,4 @@ CAnimViewer::Shutdown(void)
CTimer::Shutdown();
CStreaming::Shutdown();
CTxdStore::RemoveTxdSlot(animTxdSlot);
-} \ No newline at end of file
+}
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index 30336423..b6d46580 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -885,7 +885,7 @@ CCam::PrintMode(void)
sprintf(buf, " ");
sprintf(buf, " ");
- static char *modes[] = { "None",
+ static Const char *modes[] = { "None",
"Top Down", "GTA Classic", "Behind Car", "Follow Ped",
"Aiming", "Debug", "Sniper", "Rocket", "Model Viewer", "Bill",
"Syphon", "Circle", "Cheesy Zoom", "Wheel", "Fixed",
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index ffaa5884..623b2ea9 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -80,6 +80,10 @@ CCamera::CCamera(void)
Init();
}
+CCamera::CCamera(float)
+{
+}
+
void
CCamera::Init(void)
{
@@ -87,7 +91,12 @@ CCamera::Init(void)
float fMouseAccelHorzntl = m_fMouseAccelHorzntl;
float fMouseAccelVertical = m_fMouseAccelVertical;
#endif
+#ifdef FIX_BUGS
+ static const CCamera DummyCamera = CCamera(0.f);
+ *this = DummyCamera;
+#else
memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh?
+#endif
#ifdef GTA3_1_1_PATCH
m_fMouseAccelHorzntl = fMouseAccelHorzntl;
m_fMouseAccelVertical = fMouseAccelVertical;
@@ -744,6 +753,7 @@ CCamera::CamControl(void)
case VEHICLE_TYPE_BOAT:
ReqMode = CCam::MODE_BEHINDBOAT;
break;
+ default: break;
}
// Car zoom value
@@ -2991,7 +3001,7 @@ CCamera::SetZoomValueFollowPedScript(int16 dist)
case 0: m_fPedZoomValueScript = 0.25f; break;
case 1: m_fPedZoomValueScript = 1.5f; break;
case 2: m_fPedZoomValueScript = 2.9f; break;
- default: m_fPedZoomValueScript = m_fPedZoomValueScript; break;
+ default: break;
}
m_bUseScriptZoomValuePed = true;
@@ -3006,7 +3016,7 @@ CCamera::SetZoomValueCamStringScript(int16 dist)
case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break;
case 1: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; break;
case 2: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; break;
- default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
+ default: break;
}
} else
#endif
@@ -3015,7 +3025,7 @@ CCamera::SetZoomValueCamStringScript(int16 dist)
case 0: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_1; break;
case 1: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_2; break;
case 2: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_3; break;
- default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
+ default: break;
}
}
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 94bcbd23..80fc878e 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -403,7 +403,7 @@ public:
int m_BlurRed;
int m_BlurType;
-uint32 unknown; // some counter having to do with music
+ uint32 unknown; // some counter having to do with music
int m_iWorkOutSpeedThisNumFrames;
int m_iNumFramesSoFar;
@@ -549,6 +549,7 @@ uint32 unknown; // some counter having to do with music
// High level and misc
CCamera(void);
+ CCamera(float);
void Init(void);
void Process(void);
void CamControl(void);
diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp
index 666041e1..d9978040 100644
--- a/src/core/CdStream.cpp
+++ b/src/core/CdStream.cpp
@@ -1,3 +1,4 @@
+#ifdef _WIN32
#define WITHWINDOWS
#include "common.h"
@@ -16,9 +17,8 @@ struct CdReadInfo
char field_C;
bool bLocked;
bool bInUse;
- char _pad0;
int32 nStatus;
- HANDLE hSemaphore;
+ HANDLE hSemaphore; // used for CdStreamSync
HANDLE hFile;
OVERLAPPED Overlapped;
};
@@ -32,7 +32,7 @@ int32 gNumChannels;
HANDLE gImgFiles[MAX_CDIMAGES];
HANDLE _gCdStreamThread;
-HANDLE gCdStreamSema;
+HANDLE gCdStreamSema; // released when we have new thing to read(so channel is set)
DWORD _gCdStreamThreadId;
CdReadInfo *gpReadInfo;
@@ -296,6 +296,7 @@ CdStreamGetLastPosn(void)
return lastPosnRead;
}
+// wait for channel to finish reading
int32
CdStreamSync(int32 channel)
{
@@ -324,6 +325,7 @@ CdStreamSync(int32 channel)
if ( _gbCdStreamOverlapped && pChannel->hFile )
{
ASSERT(pChannel->hFile != nil );
+ // Beware: This is blocking call (because of last parameter)
if ( GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
return STREAM_NONE;
else
@@ -406,6 +408,7 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
{
pChannel->nStatus = STREAM_NONE;
}
+ // Beware: This is blocking call (because of last parameter)
else if ( GetLastError() == ERROR_IO_PENDING
&& GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
{
@@ -508,3 +511,4 @@ CdStreamGetNumImages(void)
{
return gNumImages;
}
+#endif
diff --git a/src/core/CdStream.h b/src/core/CdStream.h
index ba6c63a3..d0f9a855 100644
--- a/src/core/CdStream.h
+++ b/src/core/CdStream.h
@@ -41,4 +41,8 @@ void RemoveFirstInQueue(Queue *queue);
bool CdStreamAddImage(char const *path);
char *CdStreamGetImageName(int32 cd);
void CdStreamRemoveImages(void);
-int32 CdStreamGetNumImages(void); \ No newline at end of file
+int32 CdStreamGetNumImages(void);
+
+#ifndef _WIN32
+extern bool flushStream[MAX_CDCHANNELS];
+#endif
diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp
new file mode 100644
index 00000000..7c49f5f1
--- /dev/null
+++ b/src/core/CdStreamPosix.cpp
@@ -0,0 +1,516 @@
+#ifndef _WIN32
+#include "common.h"
+#include "crossplatform.h"
+#include <pthread.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+
+#include "CdStream.h"
+#include "rwcore.h"
+#include "RwHelper.h"
+
+#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
+#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
+
+// #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp)
+
+bool flushStream[MAX_CDCHANNELS];
+
+struct CdReadInfo
+{
+ uint32 nSectorOffset;
+ uint32 nSectorsToRead;
+ void *pBuffer;
+ bool bLocked;
+ bool bReading;
+ int32 nStatus;
+#ifdef ONE_THREAD_PER_CHANNEL
+ int8 nThreadStatus; // 0: created 1:initalized 2:abort now
+ pthread_t pChannelThread;
+ sem_t pStartSemaphore;
+#endif
+ sem_t pDoneSemaphore; // used for CdStreamSync
+ int32 hFile;
+};
+
+char gCdImageNames[MAX_CDIMAGES+1][64];
+int32 gNumImages;
+int32 gNumChannels;
+
+int32 gImgFiles[MAX_CDIMAGES]; // -1: error 0:unused otherwise: fd
+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
+Queue gChannelRequestQ;
+bool _gbCdStreamOverlapped;
+#endif
+
+CdReadInfo *gpReadInfo;
+
+int32 lastPosnRead;
+
+int _gdwCdStreamFlags;
+
+void *CdStreamThread(void* channelId);
+
+void
+CdStreamInitThread(void)
+{
+ int status;
+
+#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
+
+
+ if (status == -1) {
+ CDTRACE("failed to create stream semaphore");
+ ASSERT(0);
+ return;
+ }
+
+
+ if ( gNumChannels > 0 )
+ {
+ for ( int32 i = 0; i < gNumChannels; i++ )
+ {
+ status = sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0);
+
+ if (status == -1)
+ {
+ CDTRACE("failed to create sync semaphore");
+ ASSERT(0);
+ return;
+ }
+#ifdef ONE_THREAD_PER_CHANNEL
+ status = sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0);
+
+ if (status == -1)
+ {
+ CDTRACE("failed to create start semaphore");
+ ASSERT(0);
+ return;
+ }
+ gpReadInfo[i].nThreadStatus = 0;
+ int *channelI = (int*)malloc(sizeof(int));
+ *channelI = i;
+ status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI);
+
+ if (status == -1)
+ {
+ CDTRACE("failed to create sync thread");
+ ASSERT(0);
+ return;
+ }
+#endif
+ }
+ }
+
+#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;
+ }
+#else
+ debug("Using seperate 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;
+ }
+
+ _gdwCdStreamFlags = O_RDONLY | O_NOATIME;
+
+ // People say it's slower
+/*
+ if ( fsInfo.f_bsize <= CDSTREAM_SECTOR_SIZE )
+ {
+ _gdwCdStreamFlags |= O_DIRECT;
+ debug("Using no buffered loading for streaming\n");
+ }
+*/
+ void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, fsInfo.f_bsize);
+ ASSERT( pBuffer != nil );
+
+ gNumImages = 0;
+
+ gNumChannels = numChannels;
+
+ gpReadInfo = (CdReadInfo *)calloc(sizeof(CdReadInfo), numChannels);
+ ASSERT( gpReadInfo != nil );
+
+ CDDEBUG("read info %p", gpReadInfo);
+
+ CdStreamInitThread();
+
+ ASSERT( pBuffer != nil );
+ RwFreeAlign(pBuffer);
+}
+
+uint32
+GetGTA3ImgSize(void)
+{
+ ASSERT( gImgFiles[0] > 0 );
+ struct stat statbuf;
+
+ char path[PATH_MAX];
+ realpath(gImgNames[0], path);
+ if (stat(path, &statbuf) == -1) {
+ // Try case-insensitivity
+ char *r = (char*)alloca(strlen(gImgNames[0]) + 2);
+ if (casepath(gImgNames[0], r))
+ {
+ realpath(r, path);
+ if (stat(path, &statbuf) != -1)
+ goto ok;
+ }
+
+ CDTRACE("can't get size of gta3.img");
+ ASSERT(0);
+ return 0;
+ }
+ok:
+ return statbuf.st_size;
+}
+
+void
+CdStreamShutdown(void)
+{
+ // Destroying semaphores and free(gpReadInfo) will be done at threads
+#ifndef ONE_THREAD_PER_CHANNEL
+ free(gChannelRequestQ.items);
+ 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);
+ }
+#endif
+}
+
+
+int32
+CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
+{
+ ASSERT( channel < gNumChannels );
+ ASSERT( buffer != nil );
+
+ lastPosnRead = size + offset;
+
+ ASSERT( _GET_INDEX(offset) < MAX_CDIMAGES );
+ int32 hImage = gImgFiles[_GET_INDEX(offset)];
+ ASSERT( hImage > 0 );
+
+ CdReadInfo *pChannel = &gpReadInfo[channel];
+ ASSERT( pChannel != nil );
+
+ pChannel->hFile = hImage - 1;
+
+ if ( pChannel->nSectorsToRead != 0 || pChannel->bReading )
+ return STREAM_NONE;
+
+ 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");
+#else
+ if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 )
+ printf("Signal Sema Error\n");
+#endif
+
+ return STREAM_SUCCESS;
+}
+
+int32
+CdStreamGetStatus(int32 channel)
+{
+ ASSERT( channel < gNumChannels );
+ CdReadInfo *pChannel = &gpReadInfo[channel];
+ ASSERT( pChannel != nil );
+
+#ifdef ONE_THREAD_PER_CHANNEL
+ if (pChannel->nThreadStatus == 2)
+ return STREAM_NONE;
+#else
+ if (gCdStreamThreadStatus == 2)
+ return STREAM_NONE;
+#endif
+
+ if ( pChannel->bReading )
+ return STREAM_READING;
+
+ if ( pChannel->nSectorsToRead != 0 )
+ return STREAM_WAITING;
+
+ if ( pChannel->nStatus != STREAM_NONE )
+ {
+ int32 status = pChannel->nStatus;
+
+ pChannel->nStatus = STREAM_NONE;
+
+ return status;
+ }
+
+ return STREAM_NONE;
+}
+
+int32
+CdStreamGetLastPosn(void)
+{
+ return lastPosnRead;
+}
+
+// wait for channel to finish reading
+int32
+CdStreamSync(int32 channel)
+{
+ ASSERT( channel < gNumChannels );
+ CdReadInfo *pChannel = &gpReadInfo[channel];
+ ASSERT( pChannel != nil );
+
+ if (flushStream[channel]) {
+#ifdef ONE_THREAD_PER_CHANNEL
+ pChannel->nSectorsToRead = 0;
+ pthread_kill(gpReadInfo[channel].pChannelThread, SIGINT);
+#else
+ if (pChannel->bReading) {
+ pChannel->nSectorsToRead = 0;
+ pthread_kill(_gCdStreamThread, SIGINT);
+ } else {
+ pChannel->nSectorsToRead = 0;
+ }
+#endif
+ pChannel->bReading = false;
+ flushStream[channel] = false;
+ return STREAM_NONE;
+ }
+
+ if ( pChannel->nSectorsToRead != 0 )
+ {
+ pChannel->bLocked = true;
+
+ sem_wait(&pChannel->pDoneSemaphore);
+ }
+
+ pChannel->bReading = false;
+
+ return pChannel->nStatus;
+}
+
+void
+AddToQueue(Queue *queue, int32 item)
+{
+ ASSERT( queue != nil );
+ ASSERT( queue->items != nil );
+ queue->items[queue->tail] = item;
+
+ queue->tail = (queue->tail + 1) % queue->size;
+
+ if ( queue->head == queue->tail )
+ debug("Queue is full\n");
+}
+
+int32
+GetFirstInQueue(Queue *queue)
+{
+ ASSERT( queue != nil );
+ if ( queue->head == queue->tail )
+ return -1;
+
+ ASSERT( queue->items != nil );
+ return queue->items[queue->head];
+}
+
+void
+RemoveFirstInQueue(Queue *queue)
+{
+ ASSERT( queue != nil );
+ if ( queue->head == queue->tail )
+ {
+ debug("Queue is empty\n");
+ return;
+ }
+
+ queue->head = (queue->head + 1) % queue->size;
+}
+
+void *CdStreamThread(void *param)
+{
+ debug("Created cdstream thread\n");
+
+#ifndef ONE_THREAD_PER_CHANNEL
+ 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);
+#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
+ pid_t tid = syscall(SYS_gettid);
+ int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1);
+ }
+
+ // spurious wakeup or we sent interrupt signal for flushing
+ if(pChannel->nSectorsToRead == 0)
+ continue;
+
+ pChannel->bReading = true;
+
+ if ( pChannel->nStatus == STREAM_NONE )
+ {
+ 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) {
+ // 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;
+ }
+ }
+
+#ifndef ONE_THREAD_PER_CHANNEL
+ RemoveFirstInQueue(&gChannelRequestQ);
+#endif
+
+ pChannel->nSectorsToRead = 0;
+
+ if ( pChannel->bLocked )
+ {
+ sem_post(&pChannel->pDoneSemaphore);
+ }
+ pChannel->bReading = false;
+ }
+#ifndef ONE_THREAD_PER_CHANNEL
+ for ( int32 i = 0; i < gNumChannels; i++ )
+ {
+ sem_destroy(&gpReadInfo[i].pDoneSemaphore);
+ }
+ sem_destroy(&gCdStreamSema);
+#else
+ sem_destroy(&gpReadInfo[channel].pStartSemaphore);
+ sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
+#endif
+ free(gpReadInfo);
+ pthread_exit(nil);
+}
+
+bool
+CdStreamAddImage(char const *path)
+{
+ ASSERT(path != nil);
+ ASSERT(gNumImages < MAX_CDIMAGES);
+
+ gImgFiles[gNumImages] = open(path, _gdwCdStreamFlags);
+
+ // Fix case sensitivity and backslashes.
+ if (gImgFiles[gNumImages] == -1) {
+ char *r = (char*)alloca(strlen(path) + 2);
+ if (casepath(path, r))
+ {
+ gImgFiles[gNumImages] = open(r, _gdwCdStreamFlags);
+ }
+ }
+
+ if ( gImgFiles[gNumImages] == -1 ) {
+ assert(false);
+ return false;
+ }
+
+ gImgNames[gNumImages] = strdup(path);
+ gImgFiles[gNumImages]++; // because -1: error 0: not used
+
+ strcpy(gCdImageNames[gNumImages], path);
+
+ gNumImages++;
+
+ return true;
+}
+
+char *
+CdStreamGetImageName(int32 cd)
+{
+ ASSERT(cd < MAX_CDIMAGES);
+ if ( gImgFiles[cd] > 0)
+ return gCdImageNames[cd];
+
+ return nil;
+}
+
+void
+CdStreamRemoveImages(void)
+{
+ for ( int32 i = 0; i < gNumChannels; i++ )
+ CdStreamSync(i);
+
+ for ( int32 i = 0; i < gNumImages; i++ )
+ {
+ close(gImgFiles[i] - 1);
+ free(gImgNames[i]);
+ gImgFiles[i] = 0;
+ }
+
+ gNumImages = 0;
+}
+
+int32
+CdStreamGetNumImages(void)
+{
+ return gNumImages;
+}
+#endif
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index 48abbd9a..c29c1d28 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -112,7 +112,7 @@ CCollision::SortOutCollisionAfterLoad(void)
void
CCollision::LoadCollisionScreen(eLevelName level)
{
- static char *levelNames[4] = {
+ static Const char *levelNames[4] = {
"",
"IND_ZON",
"COM_ZON",
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index cba8186f..6a5080e5 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -4,7 +4,8 @@
#endif
#include "common.h"
-#include "crossplatform.h"
+#include "platform.h"
+#include "crossplatform.h" // for Windows version
#include "ControllerConfig.h"
#include "Pad.h"
#include "FileMgr.h"
@@ -163,14 +164,14 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, rsPADDOWN, KEYBOARD);
SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, 'E', OPTIONAL_EXTRA);
-
- if ( _dwOperatingSystemVersion != OS_WIN98 )
- {
+
+ if ( _dwOperatingSystemVersion == OS_WIN98 )
+ SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
+ else
+ {
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsLSHIFT, OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsRSHIFT, KEYBOARD);
- }
- else
- SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
+ }
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, rsRCTRL, KEYBOARD);
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, ' ', OPTIONAL_EXTRA);
@@ -216,19 +217,19 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (PED_JUMPING, rsRCTRL, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_JUMPING, ' ', OPTIONAL_EXTRA);
-
- if ( _dwOperatingSystemVersion != OS_WIN98 )
- {
+
+ if ( _dwOperatingSystemVersion == OS_WIN98 )
+ SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
+ else
+ {
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsLSHIFT, OPTIONAL_EXTRA);
#ifndef FIX_BUGS
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD
#else
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, KEYBOARD);
#endif
- }
- else
- SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
-
+ }
+
SetControllerKeyAssociatedWithAction (PED_CYCLE_TARGET_LEFT, '[', KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_CYCLE_TARGET_RIGHT, ']', OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
@@ -609,6 +610,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown(int32 button,
case MOUSE:
state = &CPad::GetPad(PAD1)->PCTempMouseState;
break;
+ default: break;
}
if (pad != NULL)
@@ -1023,7 +1025,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonUp(int32 button, eC
case JOYSTICK:
state = &CPad::GetPad(PAD1)->PCTempJoyState;
break;
-
+ default: break;
}
if (process)
@@ -1292,6 +1294,7 @@ bool CControllerConfigManager::GetIsKeyboardKeyDown(RsKeyCodes keycode)
if (CPad::GetPad(PAD1)->GetApps())
return true;
break;
+ default: break;
}
return false;
@@ -1492,6 +1495,7 @@ bool CControllerConfigManager::GetIsKeyboardKeyJustDown(RsKeyCodes keycode)
if (CPad::GetPad(PAD1)->GetAppsJustDown())
return true;
break;
+ default: break;
}
return false;
@@ -1529,6 +1533,7 @@ bool CControllerConfigManager::GetIsMouseButtonDown(RsKeyCodes keycode)
if (CPad::GetPad(PAD1)->GetMouseX2())
return true;
break;
+ default: break;
}
return false;
@@ -1566,6 +1571,7 @@ bool CControllerConfigManager::GetIsMouseButtonUp(RsKeyCodes keycode)
if (CPad::GetPad(PAD1)->GetMouseX2Up())
return true;
break;
+ default: break;
}
return false;
@@ -1746,6 +1752,7 @@ void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction
DeleteMatchingCommonControls (action, key, type);
DeleteMatching1rst3rdPersonControls (action, key, type);
break;
+ default: break;
}
}
}
@@ -1769,6 +1776,7 @@ bool CControllerConfigManager::GetIsKeyBlank(int32 key, eControllerType type)
if (key != 0)
return false;
break;
+ default: break;
}
return true;
@@ -1835,6 +1843,7 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
case PED_SNIPER_ZOOM_OUT:
return ACTIONTYPE_1RSTPERSON;
break;
+ default: break;
}
return ACTIONTYPE_NONE;
@@ -1860,6 +1869,7 @@ void CControllerConfigManager::ClearSettingsAssociatedWithAction(e_ControllerAct
m_aSettings[action][type].m_Key = 0;
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
break;
+ default: break;
}
ResetSettingOrder(action);
@@ -1880,6 +1890,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextWithOrderNumber(e_Contr
return GetControllerSettingTextMouse (action);
case JOYSTICK:
return GetControllerSettingTextJoystick(action);
+ default: break;
}
}
}
@@ -2223,6 +2234,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextKeyBoard(e_ControllerAc
return TheText.Get("FEC_SFT"); // "SHIFT"
break;
}
+ default: break;
}
}
}
@@ -2255,6 +2267,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextMouse(e_ControllerActio
case 7:
return TheText.Get("FEC_MXT"); // MXB2
break;
+ default: break;
}
return NULL;
@@ -2374,6 +2387,7 @@ bool CControllerConfigManager::GetIsActionAButtonCombo(e_ControllerAction action
case PED_CYCLE_TARGET_RIGHT:
return true;
break;
+ default: break;
}
return false;
@@ -2394,6 +2408,7 @@ wchar *CControllerConfigManager::GetButtonComboText(e_ControllerAction action)
case VEHICLE_LOOKBEHIND:
return TheText.Get("FEC_LBC"); // Use Look Left With Look Right.
break;
+ default: break;
}
return NULL;
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index aaa13c56..589ec23c 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -783,7 +783,7 @@ CFileLoader::LoadClumpObject(const char *line)
char model[24], txd[24];
CClumpModelInfo *mi;
- if(sscanf(line, "%d %s %s", &id, &model, &txd) == 3){
+ if(sscanf(line, "%d %s %s", &id, model, txd) == 3){
mi = CModelInfo::AddClumpModel(id);
mi->SetName(model);
mi->SetTexDictionary(txd);
diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp
index 46d725cd..1939c861 100644
--- a/src/core/FileMgr.cpp
+++ b/src/core/FileMgr.cpp
@@ -1,6 +1,8 @@
#define _CRT_SECURE_NO_WARNINGS
#include <fcntl.h>
+#ifdef _WIN32
#include <direct.h>
+#endif
#include "common.h"
#include "FileMgr.h"
@@ -24,6 +26,31 @@ struct myFILE
#define NUMFILES 20
static myFILE myfiles[NUMFILES];
+
+#if !defined(_WIN32)
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include "crossplatform.h"
+#define _getcwd getcwd
+
+// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
+void mychdir(char const *path)
+{
+ char *r = (char*)alloca(strlen(path) + 2);
+ if (casepath(path, r))
+ {
+ chdir(r);
+ }
+ else
+ {
+ errno = ENOENT;
+ }
+}
+#else
+#define mychdir chdir
+#endif
+
/* Force file to open as binary but remember if it was text mode */
static int
myfopen(const char *filename, const char *mode)
@@ -45,7 +72,31 @@ found:
mode++;
*p++ = 'b';
*p = '\0';
- myfiles[fd].file = fopen(filename, realmode);
+
+#if !defined(_WIN32)
+ char *newPath = strdup(filename);
+ // Normally casepath() fixes backslashes, but if the mode is sth other than r/rb it will create new file with backslashes on linux, so fix backslashes here
+ char *nextBs;
+ while(nextBs = strstr(newPath, "\\")){
+ *nextBs = '/';
+ }
+#else
+ const char *newPath = filename;
+#endif
+
+ myfiles[fd].file = fopen(newPath, realmode);
+// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
+#if !defined(_WIN32)
+ if (!myfiles[fd].file) {
+ char *r = (char*)alloca(strlen(newPath) + 2);
+ if (casepath(newPath, r))
+ {
+ myfiles[fd].file = fopen(r, realmode);
+ }
+ }
+
+ free(newPath);
+#endif
if(myfiles[fd].file == nil)
return 0;
return fd;
@@ -191,7 +242,7 @@ CFileMgr::ChangeDir(const char *dir)
if(dir[strlen(dir)-1] != '\\')
strcat(ms_dirName, "\\");
}
- chdir(ms_dirName);
+ mychdir(ms_dirName);
}
void
@@ -204,14 +255,14 @@ CFileMgr::SetDir(const char *dir)
if(dir[strlen(dir)-1] != '\\')
strcat(ms_dirName, "\\");
}
- chdir(ms_dirName);
+ mychdir(ms_dirName);
}
void
CFileMgr::SetDirMyDocuments(void)
{
SetDir(""); // better start at the root if user directory is relative
- chdir(_psGetUserFilesFolder());
+ mychdir(_psGetUserFilesFolder());
}
int
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 65b6deb2..933c73da 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -128,7 +128,7 @@ CFire::ProcessFire(void)
lightpos.z = m_vecPos.z + 5.0f;
if (!m_pEntity) {
- CShadows::StoreStaticShadow((uint32)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos,
+ CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos,
7.0f, 0.0f, 0.0f, -7.0f,
255, // this is 0 on PC which results in no shadow
nRandNumber / 2, nRandNumber / 2, 0,
@@ -199,7 +199,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
{
CPed *ped = (CPed *)entityOnFire;
CVehicle *veh = (CVehicle *)entityOnFire;
-
+
if (entityOnFire->IsPed()) {
if (ped->m_pFire)
return nil;
@@ -212,7 +212,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
return nil;
}
CFire *fire = GetNextFreeFire();
-
+
if (fire) {
if (entityOnFire->IsPed()) {
ped->m_pFire = fire;
@@ -243,7 +243,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
veh->m_pCarFire = fire;
if (fleeFrom) {
CEventList::RegisterEvent(EVENT_CAR_SET_ON_FIRE, EVENT_ENTITY_VEHICLE,
- entityOnFire, (CPed *)fleeFrom, 10000);
+ entityOnFire, (CPed *)fleeFrom, 10000);
}
}
}
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 5663b9ab..d27a98ec 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -6,6 +6,7 @@
#define WITHWINDOWS
#include "common.h"
#include "crossplatform.h"
+#include "platform.h"
#include "Frontend.h"
#include "Font.h"
#include "Pad.h"
@@ -411,7 +412,7 @@ CMenuManager::ThingsToDoBeforeLeavingPage()
// ------ Functions not in the game/inlined ends
void
-CMenuManager::BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2)
+CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2)
{
if (!text)
return;
@@ -900,6 +901,7 @@ CMenuManager::Draw()
float smallestSliderBar = lineHeight * 0.1f;
bool foundTheHoveringItem = false;
wchar unicodeTemp[64];
+ char asciiTemp[32];
#ifdef MENU_MAP
if (m_nCurrScreen == MENUPAGE_MAP) {
@@ -1054,15 +1056,18 @@ CMenuManager::Draw()
#else
switch (m_PrefsUseWideScreen) {
case AR_AUTO:
- rightText = (wchar*)L"AUTO";
+ sprintf(asciiTemp, "AUTO");
break;
case AR_4_3:
- rightText = (wchar*)L"4:3";
+ sprintf(asciiTemp, "4:3");
break;
case AR_16_9:
- rightText = (wchar*)L"16:9";
+ sprintf(asciiTemp, "16:9");
break;
}
+
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
#endif
break;
case MENUACTION_RADIO:
@@ -1102,13 +1107,12 @@ CMenuManager::Draw()
break;
#ifdef IMPROVED_VIDEOMODE
case MENUACTION_SCREENMODE:
- char mode[32];
if (m_nSelectedScreenMode == 0)
- sprintf(mode, "FULLSCREEN");
+ sprintf(asciiTemp, "FULLSCREEN");
else
- sprintf(mode, "WINDOWED");
+ sprintf(asciiTemp, "WINDOWED");
- AsciiToUnicode(mode, unicodeTemp);
+ AsciiToUnicode(asciiTemp, unicodeTemp);
rightText = unicodeTemp;
break;
#endif
@@ -4794,6 +4798,21 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
+#ifdef ASPECT_RATIO_SCALE
+ case MENUACTION_WIDESCREEN:
+ if (changeValueBy > 0) {
+ m_PrefsUseWideScreen++;
+ if (m_PrefsUseWideScreen > 2)
+ m_PrefsUseWideScreen = 2;
+ } else {
+ m_PrefsUseWideScreen--;
+ if (m_PrefsUseWideScreen < 0)
+ m_PrefsUseWideScreen = 0;
+ }
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
+ SaveSettings();
+ break;
+#endif
case MENUACTION_SCREENRES:
if (m_bGameNotLoaded) {
RwChar** videoMods = _psGetVideoModeList();
@@ -4903,17 +4922,13 @@ CMenuManager::ProcessOnOffMenuOptions()
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings();
break;
- case MENUACTION_WIDESCREEN:
#ifndef ASPECT_RATIO_SCALE
+ case MENUACTION_WIDESCREEN:
m_PrefsUseWideScreen = !m_PrefsUseWideScreen;
-#else
- m_PrefsUseWideScreen++;
- if (m_PrefsUseWideScreen > 2)
- m_PrefsUseWideScreen = 0;
-#endif
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings();
break;
+#endif
case MENUACTION_SETDBGFLAG:
CTheScripts::InvertDebugFlag();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
@@ -5005,6 +5020,7 @@ CMenuManager::SaveLoadFileError_SetUpErrorScreen()
case SAVESTATUS_DELETEFAILED10:
ChangeScreen(MENUPAGE_DELETE_FAILED, 0, true, false);
break;
+ default: break;
}
}
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 99597a15..16da5cb1 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -598,7 +598,7 @@ public:
#endif
public:
- static void BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2);
+ static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
static void CentreMousePointer();
void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
@@ -664,4 +664,3 @@ VALIDATE_SIZE(CMenuManager, 0x564);
#endif
extern CMenuManager FrontEndMenuManager;
-extern unsigned long _dwOperatingSystemVersion; \ No newline at end of file
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 6a6b31e7..9aea817e 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -2,7 +2,7 @@
#pragma warning( disable : 4005)
#pragma warning( pop )
#include "common.h"
-#include "crossplatform.h"
+#include "platform.h"
#include "Game.h"
#include "main.h"
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 8e9858ce..f6685388 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -523,7 +523,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
double xpos = 1.0f, ypos;
glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
- if (xpos != NULL) {
+ if (xpos != 0.f) {
state.MMB = true;
state.RMB = true;
state.LMB = true;
@@ -579,7 +579,7 @@ void CPad::UpdateMouse()
#else
double xpos = 1.0f, ypos;
glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
- if (xpos == NULL)
+ if (xpos == 0.f)
return;
int32 signX = 1;
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index bc65f6b6..b361c36f 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -90,7 +90,11 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
// relocate to another slot??
CObject *newObject = new CObject(object->GetModelIndex(), false);
CWorld::Remove(object);
+#ifdef FIX_BUGS
+ *newObject = *object;
+#else
memcpy(newObject, object, ms_pObjectPool->GetMaxEntrySize());
+#endif
CWorld::Add(newObject);
object->m_rwObject = nil;
delete object;
diff --git a/src/core/Profile.cpp b/src/core/Profile.cpp
index 05d54133..0aa18ab8 100644
--- a/src/core/Profile.cpp
+++ b/src/core/Profile.cpp
@@ -7,7 +7,7 @@ float CProfile::ms_afCumulativeTime[NUM_PROFILES];
float CProfile::ms_afEndTime[NUM_PROFILES];
float CProfile::ms_afMaxEndTime[NUM_PROFILES];
float CProfile::ms_afMaxCumulativeTime[NUM_PROFILES];
-char *CProfile::ms_pProfileString[NUM_PROFILES];
+Const char *CProfile::ms_pProfileString[NUM_PROFILES];
RwRGBA CProfile::ms_aBarColours[NUM_PROFILES];
void CProfile::Initialise()
@@ -68,4 +68,4 @@ void CProfile::ShowResults()
ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = Max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
ms_afMaxCumulativeTime[PROFILE_TOTAL] = Max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/core/Profile.h b/src/core/Profile.h
index d2e8054b..4fe693ae 100644
--- a/src/core/Profile.h
+++ b/src/core/Profile.h
@@ -19,10 +19,10 @@ class CProfile
static float ms_afEndTime[NUM_PROFILES];
static float ms_afMaxEndTime[NUM_PROFILES];
static float ms_afMaxCumulativeTime[NUM_PROFILES];
- static char *ms_pProfileString[NUM_PROFILES];
+ static Const char *ms_pProfileString[NUM_PROFILES];
static RwRGBA ms_aBarColours[NUM_PROFILES];
public:
static void Initialise();
static void SuspendProfile(eProfile profile);
static void ShowResults();
-}; \ No newline at end of file
+};
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index c1f0be5d..03a7757a 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -804,6 +804,7 @@ CStreaming::RequestIslands(eLevelName level)
if(islandLODmainland != -1)
RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
+ default: break;
}
}
@@ -1618,7 +1619,7 @@ CStreaming::GetCdImageOffset(int32 lastPosn)
int dist, mindist;
img = -1;
- mindist = INT_MAX;
+ mindist = INT32_MAX;
offset = ms_imageOffsets[ms_lastImageRead];
if(lastPosn <= offset || lastPosn > offset + ms_imageSize){
// last read position is not in last image
@@ -1667,8 +1668,8 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
streamIdFirst = -1;
streamIdNext = -1;
- posnFirst = UINT_MAX;
- posnNext = UINT_MAX;
+ posnFirst = UINT32_MAX;
+ posnNext = UINT32_MAX;
for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = next){
next = si->m_next;
@@ -1919,7 +1920,7 @@ CStreaming::ProcessLoadingChannel(int32 ch)
void
CStreaming::RetryLoadFile(int32 ch)
{
- char *key;
+ Const char *key;
CPad::StopPadsShaking();
@@ -2005,7 +2006,7 @@ CStreaming::LoadAllRequestedModels(bool priority)
status = CdStreamRead(0, ms_pStreamingBuffer[0], imgOffset+posn, size);
while(CdStreamSync(0) || status == STREAM_NONE);
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_READING;
-
+
MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
ConvertBufferToObject(ms_pStreamingBuffer[0], streamId);
if(ms_aInfoForModel[streamId].m_loadState == STREAMSTATE_STARTED)
diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp
index 7212fc65..08a84cfd 100644
--- a/src/core/SurfaceTable.cpp
+++ b/src/core/SurfaceTable.cpp
@@ -9,7 +9,7 @@
float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
void
-CSurfaceTable::Initialise(char *filename)
+CSurfaceTable::Initialise(Const char *filename)
{
int lineno, fieldno;
char *line;
diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h
index 4af6a265..12246dce 100644
--- a/src/core/SurfaceTable.h
+++ b/src/core/SurfaceTable.h
@@ -100,7 +100,7 @@ class CSurfaceTable
{
static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
public:
- static void Initialise(char *filename);
+ static void Initialise(Const char *filename);
static int GetAdhesionGroup(uint8 surfaceType);
static float GetWetMultiplier(uint8 surfaceType);
static float GetAdhesiveLimit(CColPoint &colpoint);
diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp
index aca7c1dc..ed5580fd 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -1,5 +1,6 @@
#define WITHWINDOWS
#include "common.h"
+#include "crossplatform.h"
#include "DMAudio.h"
#include "Record.h"
@@ -16,15 +17,19 @@ float CTimer::ms_fTimeStepNonClipped;
bool CTimer::m_UserPause;
bool CTimer::m_CodePause;
-uint32 oldPcTimer;
-
-uint32 suspendPcTimer;
-
uint32 _nCyclesPerMS = 1;
+#ifdef _WIN32
LARGE_INTEGER _oldPerfCounter;
-
LARGE_INTEGER perfSuspendCounter;
+#define RsTimerType uint32
+#else
+#define RsTimerType double
+#endif
+
+RsTimerType oldPcTimer;
+
+RsTimerType suspendPcTimer;
uint32 suspendDepth;
@@ -45,6 +50,7 @@ void CTimer::Initialise(void)
m_snPreviousTimeInMilliseconds = 0;
m_snTimeInMilliseconds = 1;
+#ifdef _WIN32
LARGE_INTEGER perfFreq;
if ( QueryPerformanceFrequency(&perfFreq) )
{
@@ -53,6 +59,7 @@ void CTimer::Initialise(void)
QueryPerformanceCounter(&_oldPerfCounter);
}
else
+#endif
{
OutputDebugString("Performance counter not available, using millesecond timer\n");
_nCyclesPerMS = 0;
@@ -77,6 +84,7 @@ void CTimer::Update(void)
{
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
+#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 )
{
LARGE_INTEGER pc;
@@ -106,10 +114,11 @@ void CTimer::Update(void)
}
}
else
+#endif
{
- uint32 timer = RsTimer();
+ RsTimerType timer = RsTimer();
- uint32 updInMs = timer - oldPcTimer;
+ RsTimerType updInMs = timer - oldPcTimer;
// We need that real frame time to fix transparent menu bug.
#ifndef FIX_BUGS
@@ -158,9 +167,11 @@ void CTimer::Suspend(void)
if ( ++suspendDepth > 1 )
return;
+#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 )
QueryPerformanceCounter(&perfSuspendCounter);
else
+#endif
suspendPcTimer = RsTimer();
}
@@ -169,6 +180,7 @@ void CTimer::Resume(void)
if ( --suspendDepth != 0 )
return;
+#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 )
{
LARGE_INTEGER pc;
@@ -177,19 +189,23 @@ void CTimer::Resume(void)
_oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart;
}
else
+#endif
oldPcTimer += RsTimer() - suspendPcTimer;
}
uint32 CTimer::GetCyclesPerMillisecond(void)
{
+#ifdef _WIN32
if (_nCyclesPerMS != 0)
return _nCyclesPerMS;
else
+#endif
return 1;
}
uint32 CTimer::GetCurrentTimeInCycles(void)
{
+#ifdef _WIN32
if ( _nCyclesPerMS != 0 )
{
LARGE_INTEGER pc;
@@ -197,6 +213,7 @@ uint32 CTimer::GetCurrentTimeInCycles(void)
return (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
}
else
+#endif
return RsTimer() - oldPcTimer;
}
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 6ea3489b..493ce042 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -2212,6 +2212,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
case ENTITY_TYPE_OBJECT:
pObject->ObjectDamage(300.0f * fDamageMultiplier);
break;
+ default: break;
}
}
}
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index c0fa7cbe..8e73a07b 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -752,9 +752,9 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
meant for a different array, but the game doesn't brake
if save data stored is -1.
*/
- MapZoneArray[i].child = GetPointerForZoneIndex((int32)MapZoneArray[i].child);
- MapZoneArray[i].parent = GetPointerForZoneIndex((int32)MapZoneArray[i].parent);
- MapZoneArray[i].next = GetPointerForZoneIndex((int32)MapZoneArray[i].next);
+ MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
+ MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
+ MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
diff --git a/src/core/config.h b/src/core/config.h
index 17cea982..30f6b898 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -195,19 +195,22 @@ enum Config {
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
#define MORE_LANGUAGES // Add more translations to the game
-#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
+#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
//#define USE_TEXTURE_POOL
-//#define AUDIO_OAL
+#ifdef _WIN32
#define AUDIO_MSS
+#else
+#define AUDIO_OAL
+#endif
// Particle
//#define PC_PARTICLE
//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// Pad
-#ifndef RW_GL3
+#if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT
#endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
@@ -225,7 +228,7 @@ enum Config {
#define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
#define TRIANGLE_BACK_BUTTON
// #define CIRCLE_BACK_BUTTON
-#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
+#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
#define BETA_SLIDING_TEXT
// Script
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 00ae3774..dc61f03f 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -401,7 +401,7 @@ DestroySplashScreen(void)
splashTxdId = -1;
}
-char*
+Const char*
GetRandomSplashScreen(void)
{
int index;
@@ -424,10 +424,10 @@ GetRandomSplashScreen(void)
return splashName;
}
-char*
+Const char*
GetLevelSplashScreen(int level)
{
- static char *splashScreens[4] = {
+ static Const char *splashScreens[4] = {
nil,
"splash1",
"splash2",
@@ -1281,7 +1281,7 @@ void TheGame(void)
CGame::Initialise("DATA\\GTA3.DAT");
#endif
- char *splash = GetRandomSplashScreen(); // inlined here
+ Const char *splash = GetRandomSplashScreen(); // inlined here
LoadingScreen("Starting Game", NULL, splash);
@@ -1315,7 +1315,7 @@ void TheGame(void)
if (FrontEndMenuManager.m_bWantToLoad)
#endif
{
- char *splash1 = GetLevelSplashScreen(CGame::currLevel);
+ Const char *splash1 = GetLevelSplashScreen(CGame::currLevel);
LoadSplash(splash1);
}
@@ -1776,6 +1776,8 @@ void GameInit()
}
}
+// Not used anyway. PS2 main() port
+#ifdef _WIN32
int
main(int argc, char *argv[])
{
@@ -1847,3 +1849,4 @@ main(int argc, char *argv[])
return 0;
}
+#endif
diff --git a/src/core/main.h b/src/core/main.h
index 90b13fbb..32a880d6 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -22,8 +22,8 @@ void LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
void LoadingIslandScreen(const char *levelName);
CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
-char *GetLevelSplashScreen(int level);
-char *GetRandomSplashScreen(void);
+Const char *GetLevelSplashScreen(int level);
+Const char *GetRandomSplashScreen(void);
void LittleTest(void);
void ValidateVersion();
void ResetLoadingScreenBar(void);
diff --git a/src/core/patcher.cpp b/src/core/patcher.cpp
index e5242e9d..83e06886 100644
--- a/src/core/patcher.cpp
+++ b/src/core/patcher.cpp
@@ -24,7 +24,7 @@ StaticPatcher::Apply()
}
ms_head = nil;
}
-
+#ifdef _WIN32
std::vector<uint32> usedAddresses;
static DWORD protect[2];
@@ -75,4 +75,20 @@ InjectHook_internal(uint32 address, uint32 hook, int type)
VirtualProtect((void*)(address + 1), 4, protect[0], &protect[1]);
else
VirtualProtect((void*)address, 5, protect[0], &protect[1]);
-} \ No newline at end of file
+}
+#else
+void
+Protect_internal(uint32 address, uint32 size)
+{
+}
+
+void
+Unprotect_internal(void)
+{
+}
+
+void
+InjectHook_internal(uint32 address, uint32 hook, int type)
+{
+}
+#endif
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index bbac265f..0e62f3a5 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -1,7 +1,7 @@
-#include <direct.h>
#include <csignal>
#define WITHWINDOWS
#include "common.h"
+#include "crossplatform.h"
#include "patcher.h"
#include "Renderer.h"
#include "Credits.h"
@@ -28,6 +28,11 @@
#include "debugmenu.h"
#include "Frontend.h"
+#ifndef _WIN32
+#include "assert.h"
+#include <stdarg.h>
+#endif
+
#include <list>
#ifdef RWLIBS
@@ -36,7 +41,7 @@ extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list
#ifdef USE_PS2_RAND
-unsigned __int64 myrand_seed = 1;
+unsigned long long myrand_seed = 1;
#else
unsigned long int myrand_seed = 1;
#endif
@@ -207,13 +212,22 @@ static const char *carnames[] = {
"bloodra", "bloodrb", "vicechee"
};
-static std::list<CTweakVar *> TweakVarsList;
+static CTweakVar** TweakVarsList;
+static int TweakVarsListSize = -1;
static bool bAddTweakVarsNow = false;
static const char *pTweakVarsDefaultPath = NULL;
void CTweakVars::Add(CTweakVar *var)
{
- TweakVarsList.push_back(var);
+ if(TweakVarsListSize == -1) {
+ TweakVarsList = (CTweakVar**)malloc(64 * sizeof(CTweakVar*));
+ TweakVarsListSize = 0;
+ }
+ if(TweakVarsListSize > 63)
+ TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var));
+
+ TweakVarsList[TweakVarsListSize++] = var;
+// TweakVarsList.push_back(var);
if ( bAddTweakVarsNow )
var->AddDBG(pTweakVarsDefaultPath);
@@ -223,8 +237,8 @@ void CTweakVars::AddDBG(const char *path)
{
pTweakVarsDefaultPath = path;
- for(auto i = TweakVarsList.begin(); i != TweakVarsList.end(); ++i)
- (*i)->AddDBG(pTweakVarsDefaultPath);
+ for(int i = 0; i < TweakVarsListSize; ++i)
+ TweakVarsList[i]->AddDBG(pTweakVarsDefaultPath);
bAddTweakVarsNow = true;
}
@@ -395,6 +409,7 @@ static char re3_buff[re3_buffsize];
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func)
{
+#ifdef _WIN32
int nCode;
strcpy_s(re3_buff, re3_buffsize, "Assertion failed!" );
@@ -439,13 +454,22 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
return;
abort();
+#else
+ // TODO
+ printf("\nRE3 ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
+ assert(false);
+#endif
}
void re3_debug(const char *format, ...)
{
va_list va;
va_start(va, format);
+#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va);
+#else
+ vsprintf(re3_buff, format, va);
+#endif
va_end(va);
printf("%s", re3_buff);
@@ -457,18 +481,26 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
char buff[re3_buffsize *2];
va_list va;
va_start(va, format);
+#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
sprintf_s(buff, re3_buffsize * 2, "[%s.%s:%d]: %s", filename, func, lineno, re3_buff);
+#else
+ vsprintf(re3_buff, format, va);
+ va_end(va);
- OutputDebugStringA(buff);
+ sprintf(buff, "[%s.%s:%d]: %s", filename, func, lineno, re3_buff);
+#endif
+
+ OutputDebugString(buff);
}
void re3_usererror(const char *format, ...)
{
va_list va;
va_start(va, format);
+#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
@@ -477,6 +509,11 @@ void re3_usererror(const char *format, ...)
raise(SIGABRT);
_exit(3);
+#else
+ vsprintf(re3_buff, format, va);
+ printf("\nRE3 Error!\n\t%s\n",re3_buff);
+ assert(false);
+#endif
}
#ifdef VALIDATE_SAVE_SIZE