mirror of
https://github.com/GTAmodding/re3.git
synced 2025-07-14 10:04:08 +00:00
Merge remote-tracking branch 'origin/master' into miami
# Conflicts: # premake5.lua # src/core/ZoneCull.cpp # src/core/Zones.cpp # src/objects/CutsceneHead.cpp # src/render/Clouds.cpp
This commit is contained in:
commit
33dfaf7da1
56 changed files with 1418 additions and 385 deletions
|
@ -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
|
||||
|
|
|
@ -41,4 +41,8 @@ void RemoveFirstInQueue(Queue *queue);
|
|||
bool CdStreamAddImage(char const *path);
|
||||
char *CdStreamGetImageName(int32 cd);
|
||||
void CdStreamRemoveImages(void);
|
||||
int32 CdStreamGetNumImages(void);
|
||||
int32 CdStreamGetNumImages(void);
|
||||
|
||||
#ifndef _WIN32
|
||||
extern bool flushStream[MAX_CDCHANNELS];
|
||||
#endif
|
||||
|
|
516
src/core/CdStreamPosix.cpp
Normal file
516
src/core/CdStreamPosix.cpp
Normal file
|
@ -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
|
|
@ -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 ?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define WITHWINDOWS
|
||||
#include "common.h"
|
||||
#include "crossplatform.h"
|
||||
#include "platform.h"
|
||||
#include "Frontend.h"
|
||||
#include "Font.h"
|
||||
#include "Pad.h"
|
||||
|
@ -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);
|
||||
|
|
|
@ -664,4 +664,3 @@ VALIDATE_SIZE(CMenuManager, 0x564);
|
|||
#endif
|
||||
|
||||
extern CMenuManager FrontEndMenuManager;
|
||||
extern unsigned long _dwOperatingSystemVersion;
|
|
@ -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"
|
||||
|
|
|
@ -1618,7 +1618,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 +1667,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;
|
||||
|
@ -2005,7 +2005,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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
Protect_internal(uint32 address, uint32 size)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Unprotect_internal(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InjectHook_internal(uint32 address, uint32 hook, int type)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue