Merge branch 'master' of git://github.com/GTAmodding/re3
This commit is contained in:
commit
886db44936
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
529
src/CdStream.cpp
Normal file
529
src/CdStream.cpp
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
#include "common.h"
|
||||||
|
#include "patcher.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__)
|
||||||
|
|
||||||
|
struct CdReadInfo
|
||||||
|
{
|
||||||
|
uint32 nSectorOffset;
|
||||||
|
uint32 nSectorsToRead;
|
||||||
|
void *pBuffer;
|
||||||
|
char field_C;
|
||||||
|
bool bLocked;
|
||||||
|
bool bInUse;
|
||||||
|
char _pad0;
|
||||||
|
int32 nStatus;
|
||||||
|
HANDLE hSemaphore;
|
||||||
|
HANDLE hFile;
|
||||||
|
OVERLAPPED Overlapped;
|
||||||
|
};
|
||||||
|
VALIDATE_SIZE(CdReadInfo, 0x30);
|
||||||
|
|
||||||
|
char gCdImageNames[MAX_CDIMAGES+1][64];
|
||||||
|
int32 gNumImages;
|
||||||
|
int32 gNumChannels;
|
||||||
|
|
||||||
|
HANDLE gImgFiles[MAX_CDIMAGES];
|
||||||
|
|
||||||
|
HANDLE _gCdStreamThread;
|
||||||
|
HANDLE gCdStreamSema;
|
||||||
|
DWORD _gCdStreamThreadId;
|
||||||
|
|
||||||
|
CdReadInfo *gpReadInfo;
|
||||||
|
Queue gChannelRequestQ;
|
||||||
|
|
||||||
|
int32 lastPosnRead;
|
||||||
|
|
||||||
|
BOOL _gbCdStreamOverlapped;
|
||||||
|
BOOL _gbCdStreamAsync;
|
||||||
|
DWORD _gdwCdStreamFlags;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CdStreamInitThread(void)
|
||||||
|
{
|
||||||
|
SetLastError(0);
|
||||||
|
|
||||||
|
if ( gNumChannels > 0 )
|
||||||
|
{
|
||||||
|
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||||
|
{
|
||||||
|
gpReadInfo[i].hSemaphore = CreateSemaphore(NULL, 0, 2, NULL);
|
||||||
|
|
||||||
|
if ( gpReadInfo[i].hSemaphore == NULL )
|
||||||
|
{
|
||||||
|
CDTRACE("failed to create sync semaphore");
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gChannelRequestQ.items = (int32 *)LocalAlloc(LMEM_ZEROINIT, sizeof(int32) * (gNumChannels + 1));
|
||||||
|
gChannelRequestQ.head = 0;
|
||||||
|
gChannelRequestQ.tail = 0;
|
||||||
|
gChannelRequestQ.size = gNumChannels + 1;
|
||||||
|
ASSERT(gChannelRequestQ.items != NULL );
|
||||||
|
|
||||||
|
gCdStreamSema = CreateSemaphore(NULL, 0, 5, "CdStream");
|
||||||
|
|
||||||
|
if ( gCdStreamSema == NULL )
|
||||||
|
{
|
||||||
|
CDTRACE("failed to create stream semaphore");
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gCdStreamThread = CreateThread(NULL, 64*1024/*64KB*/, CdStreamThread, NULL, CREATE_SUSPENDED, &_gCdStreamThreadId);
|
||||||
|
|
||||||
|
if ( _gCdStreamThread == NULL )
|
||||||
|
{
|
||||||
|
CDTRACE("failed to create streaming thread");
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetThreadPriority(_gCdStreamThread, GetThreadPriority(GetCurrentThread()) - 1);
|
||||||
|
|
||||||
|
ResumeThread(_gCdStreamThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CdStreamInit(int32 numChannels)
|
||||||
|
{
|
||||||
|
DWORD SectorsPerCluster;
|
||||||
|
DWORD BytesPerSector;
|
||||||
|
DWORD NumberOfFreeClusters;
|
||||||
|
DWORD TotalNumberOfClusters;
|
||||||
|
|
||||||
|
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
|
||||||
|
|
||||||
|
_gdwCdStreamFlags = 0;
|
||||||
|
|
||||||
|
if ( BytesPerSector <= CDSTREAM_SECTOR_SIZE )
|
||||||
|
{
|
||||||
|
_gdwCdStreamFlags |= FILE_FLAG_NO_BUFFERING;
|
||||||
|
debug("Using no buffered loading for streaming\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
_gbCdStreamOverlapped = TRUE;
|
||||||
|
|
||||||
|
_gdwCdStreamFlags |= FILE_FLAG_OVERLAPPED;
|
||||||
|
|
||||||
|
_gbCdStreamAsync = FALSE;
|
||||||
|
|
||||||
|
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, BytesPerSector);
|
||||||
|
ASSERT( pBuffer != NULL );
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
|
||||||
|
gNumImages = 0;
|
||||||
|
|
||||||
|
gNumChannels = numChannels;
|
||||||
|
|
||||||
|
gpReadInfo = (CdReadInfo *)LocalAlloc(LMEM_ZEROINIT, sizeof(CdReadInfo) * numChannels);
|
||||||
|
ASSERT( gpReadInfo != NULL );
|
||||||
|
|
||||||
|
CDDEBUG("read info %p", gpReadInfo);
|
||||||
|
|
||||||
|
CdStreamAddImage("MODELS\\GTA3.IMG");
|
||||||
|
|
||||||
|
int32 nStatus = CdStreamRead(0, pBuffer, 0, 1);
|
||||||
|
|
||||||
|
CdStreamRemoveImages();
|
||||||
|
|
||||||
|
if ( nStatus == STREAM_SUCCESS )
|
||||||
|
{
|
||||||
|
_gbCdStreamAsync = TRUE;
|
||||||
|
|
||||||
|
debug("Using async loading for streaming\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_gdwCdStreamFlags &= ~FILE_FLAG_OVERLAPPED;
|
||||||
|
|
||||||
|
_gbCdStreamOverlapped = FALSE;
|
||||||
|
|
||||||
|
_gbCdStreamAsync = TRUE;
|
||||||
|
|
||||||
|
debug("Using sync loading for streaming\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CdStreamInitThread();
|
||||||
|
|
||||||
|
ASSERT( pBuffer != NULL );
|
||||||
|
RwFreeAlign(pBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
GetGTA3ImgSize(void)
|
||||||
|
{
|
||||||
|
ASSERT( gImgFiles[0] != NULL );
|
||||||
|
return (uint32)GetFileSize(gImgFiles[0], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CdStreamShutdown(void)
|
||||||
|
{
|
||||||
|
if ( _gbCdStreamAsync )
|
||||||
|
{
|
||||||
|
LocalFree(gChannelRequestQ.items);
|
||||||
|
CloseHandle(gCdStreamSema);
|
||||||
|
CloseHandle(_gCdStreamThread);
|
||||||
|
|
||||||
|
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||||
|
CloseHandle(gpReadInfo[i].hSemaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalFree(gpReadInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
||||||
|
{
|
||||||
|
ASSERT( channel < gNumChannels );
|
||||||
|
ASSERT( buffer != NULL );
|
||||||
|
|
||||||
|
lastPosnRead = size + offset;
|
||||||
|
|
||||||
|
ASSERT( _GET_INDEX(offset) < MAX_CDIMAGES );
|
||||||
|
HANDLE hImage = gImgFiles[_GET_INDEX(offset)];
|
||||||
|
ASSERT( hImage != NULL );
|
||||||
|
|
||||||
|
|
||||||
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
|
ASSERT( pChannel != NULL );
|
||||||
|
|
||||||
|
pChannel->hFile = hImage;
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
|
||||||
|
if ( _gbCdStreamAsync )
|
||||||
|
{
|
||||||
|
if ( pChannel->nSectorsToRead != 0 || pChannel->bInUse )
|
||||||
|
return STREAM_NONE;
|
||||||
|
|
||||||
|
pChannel->nStatus = STREAM_NONE;
|
||||||
|
pChannel->nSectorOffset = _GET_OFFSET(offset);
|
||||||
|
pChannel->nSectorsToRead = size;
|
||||||
|
pChannel->pBuffer = buffer;
|
||||||
|
pChannel->bLocked = 0;
|
||||||
|
|
||||||
|
AddToQueue(&gChannelRequestQ, channel);
|
||||||
|
|
||||||
|
if ( !ReleaseSemaphore(gCdStreamSema, 1, NULL) )
|
||||||
|
printf("Signal Sema Error\n");
|
||||||
|
|
||||||
|
return STREAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _gbCdStreamOverlapped )
|
||||||
|
{
|
||||||
|
ASSERT( channel < gNumChannels );
|
||||||
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
|
ASSERT( pChannel != NULL );
|
||||||
|
|
||||||
|
pChannel->Overlapped.Offset = _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE;
|
||||||
|
|
||||||
|
if ( !ReadFile(hImage, buffer, size * CDSTREAM_SECTOR_SIZE, NULL, &pChannel->Overlapped)
|
||||||
|
&& GetLastError() != ERROR_IO_PENDING )
|
||||||
|
return STREAM_NONE;
|
||||||
|
else
|
||||||
|
return STREAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
DWORD NumberOfBytesRead;
|
||||||
|
|
||||||
|
if ( !ReadFile(hImage, buffer, size * CDSTREAM_SECTOR_SIZE, &NumberOfBytesRead, NULL) )
|
||||||
|
return STREAM_NONE;
|
||||||
|
else
|
||||||
|
return STREAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CdStreamGetStatus(int32 channel)
|
||||||
|
{
|
||||||
|
ASSERT( channel < gNumChannels );
|
||||||
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
|
ASSERT( pChannel != NULL );
|
||||||
|
|
||||||
|
if ( _gbCdStreamAsync )
|
||||||
|
{
|
||||||
|
if ( pChannel->bInUse )
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _gbCdStreamOverlapped )
|
||||||
|
{
|
||||||
|
ASSERT( pChannel->hFile != NULL );
|
||||||
|
if ( WaitForSingleObjectEx(pChannel->hFile, 0, TRUE) == WAIT_OBJECT_0 )
|
||||||
|
return STREAM_NONE;
|
||||||
|
else
|
||||||
|
return STREAM_READING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STREAM_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CdStreamGetLastPosn(void)
|
||||||
|
{
|
||||||
|
return lastPosnRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CdStreamSync(int32 channel)
|
||||||
|
{
|
||||||
|
ASSERT( channel < gNumChannels );
|
||||||
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
|
ASSERT( pChannel != NULL );
|
||||||
|
|
||||||
|
if ( _gbCdStreamAsync )
|
||||||
|
{
|
||||||
|
if ( pChannel->nSectorsToRead != 0 )
|
||||||
|
{
|
||||||
|
pChannel->bLocked = true;
|
||||||
|
|
||||||
|
ASSERT( pChannel->hSemaphore != NULL );
|
||||||
|
|
||||||
|
WaitForSingleObject(pChannel->hSemaphore, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pChannel->bInUse = false;
|
||||||
|
|
||||||
|
return pChannel->nStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD NumberOfBytesTransferred;
|
||||||
|
|
||||||
|
if ( _gbCdStreamOverlapped && pChannel->hFile )
|
||||||
|
{
|
||||||
|
ASSERT(pChannel->hFile != NULL );
|
||||||
|
if ( GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
|
||||||
|
return STREAM_NONE;
|
||||||
|
else
|
||||||
|
return STREAM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STREAM_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AddToQueue(Queue *queue, int32 item)
|
||||||
|
{
|
||||||
|
ASSERT( queue != NULL );
|
||||||
|
ASSERT( queue->items != NULL );
|
||||||
|
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 != NULL );
|
||||||
|
if ( queue->head == queue->tail )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ASSERT( queue->items != NULL );
|
||||||
|
return queue->items[queue->head];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoveFirstInQueue(Queue *queue)
|
||||||
|
{
|
||||||
|
ASSERT( queue != NULL );
|
||||||
|
if ( queue->head == queue->tail )
|
||||||
|
{
|
||||||
|
debug("Queue is empty\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->head = (queue->head + 1) % queue->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
||||||
|
{
|
||||||
|
debug("Created cdstream thread\n");
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
WaitForSingleObject(gCdStreamSema, INFINITE);
|
||||||
|
|
||||||
|
int32 channel = GetFirstInQueue(&gChannelRequestQ);
|
||||||
|
ASSERT( channel < gNumChannels );
|
||||||
|
|
||||||
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
|
ASSERT( pChannel != NULL );
|
||||||
|
|
||||||
|
pChannel->bInUse = true;
|
||||||
|
|
||||||
|
if ( pChannel->nStatus == STREAM_NONE )
|
||||||
|
{
|
||||||
|
if ( _gbCdStreamOverlapped )
|
||||||
|
{
|
||||||
|
pChannel->Overlapped.Offset = pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE;
|
||||||
|
|
||||||
|
ASSERT(pChannel->hFile != NULL );
|
||||||
|
ASSERT(pChannel->pBuffer != NULL );
|
||||||
|
|
||||||
|
DWORD NumberOfBytesTransferred;
|
||||||
|
|
||||||
|
if ( ReadFile(pChannel->hFile,
|
||||||
|
pChannel->pBuffer,
|
||||||
|
pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE,
|
||||||
|
NULL,
|
||||||
|
&pChannel->Overlapped) )
|
||||||
|
{
|
||||||
|
pChannel->nStatus = STREAM_NONE;
|
||||||
|
}
|
||||||
|
else if ( GetLastError() == ERROR_IO_PENDING
|
||||||
|
&& GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
|
||||||
|
{
|
||||||
|
pChannel->nStatus = STREAM_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pChannel->nStatus = STREAM_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(pChannel->hFile != NULL );
|
||||||
|
ASSERT(pChannel->pBuffer != NULL );
|
||||||
|
|
||||||
|
SetFilePointer(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
DWORD NumberOfBytesRead;
|
||||||
|
if ( ReadFile(pChannel->hFile,
|
||||||
|
pChannel->pBuffer,
|
||||||
|
pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE,
|
||||||
|
&NumberOfBytesRead,
|
||||||
|
NULL) )
|
||||||
|
{
|
||||||
|
pChannel->nStatus = STREAM_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveFirstInQueue(&gChannelRequestQ);
|
||||||
|
|
||||||
|
pChannel->nSectorsToRead = 0;
|
||||||
|
|
||||||
|
if ( pChannel->bLocked )
|
||||||
|
{
|
||||||
|
ASSERT( pChannel->hSemaphore != NULL );
|
||||||
|
ReleaseSemaphore(pChannel->hSemaphore, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pChannel->bInUse = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CdStreamAddImage(char const *path)
|
||||||
|
{
|
||||||
|
ASSERT(path != NULL);
|
||||||
|
ASSERT(gNumImages < MAX_CDIMAGES);
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
|
||||||
|
gImgFiles[gNumImages] = CreateFile(path,
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
_gdwCdStreamFlags | FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_READONLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
ASSERT( gImgFiles[gNumImages] != NULL );
|
||||||
|
if ( gImgFiles[gNumImages] == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strcpy(gCdImageNames[gNumImages], path);
|
||||||
|
|
||||||
|
gNumImages++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
CdStreamGetImageName(int32 cd)
|
||||||
|
{
|
||||||
|
ASSERT(cd < MAX_CDIMAGES);
|
||||||
|
if ( gImgFiles[cd] != NULL )
|
||||||
|
return gCdImageNames[cd];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CdStreamRemoveImages(void)
|
||||||
|
{
|
||||||
|
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||||
|
CdStreamSync(i);
|
||||||
|
|
||||||
|
for ( int32 i = 0; i < gNumImages; i++ )
|
||||||
|
{
|
||||||
|
SetLastError(0);
|
||||||
|
|
||||||
|
CloseHandle(gImgFiles[i]);
|
||||||
|
gImgFiles[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gNumImages = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CdStreamGetNumImages(void)
|
||||||
|
{
|
||||||
|
return gNumImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x405B50, CdStreamInitThread, PATCH_JUMP);
|
||||||
|
InjectHook(0x405C80, CdStreamInit, PATCH_JUMP);
|
||||||
|
//InjectHook(0x405DB0, debug, PATCH_JUMP);
|
||||||
|
InjectHook(0x405DC0, GetGTA3ImgSize, PATCH_JUMP);
|
||||||
|
InjectHook(0x405DD0, CdStreamShutdown, PATCH_JUMP);
|
||||||
|
InjectHook(0x405E40, CdStreamRead, PATCH_JUMP);
|
||||||
|
InjectHook(0x405F90, CdStreamGetStatus, PATCH_JUMP);
|
||||||
|
InjectHook(0x406000, CdStreamGetLastPosn, PATCH_JUMP);
|
||||||
|
InjectHook(0x406010, CdStreamSync, PATCH_JUMP);
|
||||||
|
InjectHook(0x4060B0, AddToQueue, PATCH_JUMP);
|
||||||
|
InjectHook(0x4060F0, GetFirstInQueue, PATCH_JUMP);
|
||||||
|
InjectHook(0x406110, RemoveFirstInQueue, PATCH_JUMP);
|
||||||
|
InjectHook(0x406140, CdStreamThread, PATCH_JUMP);
|
||||||
|
InjectHook(0x406270, CdStreamAddImage, PATCH_JUMP);
|
||||||
|
InjectHook(0x4062E0, CdStreamGetImageName, PATCH_JUMP);
|
||||||
|
InjectHook(0x406300, CdStreamRemoveImages, PATCH_JUMP);
|
||||||
|
InjectHook(0x406370, CdStreamGetNumImages, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
47
src/CdStream.h
Normal file
47
src/CdStream.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_CDIMAGES 8
|
||||||
|
#define CDSTREAM_SECTOR_SIZE 2048
|
||||||
|
|
||||||
|
#define _GET_INDEX(a) (a >> 24)
|
||||||
|
#define _GET_OFFSET(a) (a & 0xFFFFFF)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STREAM_NONE = uint8( 0),
|
||||||
|
STREAM_SUCCESS = uint8( 1),
|
||||||
|
STREAM_READING = uint8(-1), // 0xFF,
|
||||||
|
STREAM_ERROR = uint8(-2), // 0xFE,
|
||||||
|
STREAM_ERROR_NOCD = uint8(-3), // 0xFD,
|
||||||
|
STREAM_ERROR_WRONGCD = uint8(-4), // 0xFC,
|
||||||
|
STREAM_ERROR_OPENCD = uint8(-5), // 0xFB,
|
||||||
|
STREAM_WAITING = uint8(-6) // 0xFA,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Queue
|
||||||
|
{
|
||||||
|
int32 *items;
|
||||||
|
int32 head;
|
||||||
|
int32 tail;
|
||||||
|
int32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
VALIDATE_SIZE(Queue, 0x10);
|
||||||
|
|
||||||
|
|
||||||
|
void CdStreamInitThread(void);
|
||||||
|
void CdStreamInit(int32 numChannels);
|
||||||
|
uint32 GetGTA3ImgSize(void);
|
||||||
|
void CdStreamShutdown(void);
|
||||||
|
int32 CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size);
|
||||||
|
int32 CdStreamGetStatus(int32 channel);
|
||||||
|
int32 CdStreamGetLastPosn(void);
|
||||||
|
int32 CdStreamSync(int32 channel);
|
||||||
|
void AddToQueue(Queue *queue, int32 item);
|
||||||
|
int32 GetFirstInQueue(Queue *queue);
|
||||||
|
void RemoveFirstInQueue(Queue *queue);
|
||||||
|
DWORD WINAPI CdStreamThread(LPVOID lpThreadParameter);
|
||||||
|
bool CdStreamAddImage(char const *path);
|
||||||
|
char *CdStreamGetImageName(int32 cd);
|
||||||
|
void CdStreamRemoveImages(void);
|
||||||
|
int32 CdStreamGetNumImages(void);
|
1182
src/FileLoader.cpp
Normal file
1182
src/FileLoader.cpp
Normal file
File diff suppressed because it is too large
Load Diff
42
src/FileLoader.h
Normal file
42
src/FileLoader.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CFileLoader
|
||||||
|
{
|
||||||
|
static char ms_line[256];
|
||||||
|
public:
|
||||||
|
static void LoadLevel(const char *filename);
|
||||||
|
static void LoadCollisionFromDatFile(int currlevel);
|
||||||
|
static char *LoadLine(int fd);
|
||||||
|
static RwTexDictionary *LoadTexDictionary(const char *filename);
|
||||||
|
static void LoadCollisionFile(const char *filename);
|
||||||
|
static void LoadCollisionModel(uint8 *buf, CColModel &model, char *name);
|
||||||
|
static void LoadModelFile(const char *filename);
|
||||||
|
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||||
|
static void LoadClumpFile(const char *filename);
|
||||||
|
static bool LoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool StartLoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool FinishLoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool LoadAtomicFile(RwStream *stream, uint32 id);
|
||||||
|
static RpAtomic *SetRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||||
|
static RpClump *LoadAtomicFile2Return(const char *filename);
|
||||||
|
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
|
||||||
|
|
||||||
|
static void LoadObjectTypes(const char *filename);
|
||||||
|
static void LoadObject(const char *line);
|
||||||
|
static void LoadTimeObject(const char *line);
|
||||||
|
static void LoadClumpObject(const char *line);
|
||||||
|
static void LoadVehicleObject(const char *line);
|
||||||
|
static void LoadPedObject(const char *line);
|
||||||
|
static int LoadPathHeader(const char *line, char *type);
|
||||||
|
static void LoadPedPathNode(const char *line, int id, int node);
|
||||||
|
static void LoadCarPathNode(const char *line, int id, int node);
|
||||||
|
static void Load2dEffect(const char *line);
|
||||||
|
|
||||||
|
static void LoadScene(const char *filename);
|
||||||
|
static void LoadObjectInstance(const char *line);
|
||||||
|
static void LoadZone(const char *line);
|
||||||
|
static void LoadCullZone(const char *line);
|
||||||
|
static void LoadPickup(const char *line);
|
||||||
|
|
||||||
|
static void LoadMapZones(const char *filename);
|
||||||
|
};
|
@ -9,6 +9,7 @@ bool &CGame::frenchGame = *(bool*)0x95CDCB;
|
|||||||
bool &CGame::germanGame = *(bool*)0x95CD1E;
|
bool &CGame::germanGame = *(bool*)0x95CD1E;
|
||||||
bool &CGame::noProstitutes = *(bool*)0x95CDCF;
|
bool &CGame::noProstitutes = *(bool*)0x95CDCF;
|
||||||
bool &CGame::playingIntro = *(bool*)0x95CDC2;
|
bool &CGame::playingIntro = *(bool*)0x95CDC2;
|
||||||
|
char *CGame::aDatFile = (char*)0x773A48;
|
||||||
|
|
||||||
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
|
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
|
||||||
WRAPPER bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }
|
WRAPPER bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
static bool &germanGame;
|
static bool &germanGame;
|
||||||
static bool &noProstitutes;
|
static bool &noProstitutes;
|
||||||
static bool &playingIntro;
|
static bool &playingIntro;
|
||||||
|
static char *aDatFile; //[32];
|
||||||
|
|
||||||
static void Process(void);
|
static void Process(void);
|
||||||
static bool InitialiseOnceBeforeRW(void);
|
static bool InitialiseOnceBeforeRW(void);
|
||||||
|
@ -1995,7 +1995,10 @@ STARTPATCHES
|
|||||||
InjectHook(0x492720, CPad::UpdatePads, PATCH_JUMP);
|
InjectHook(0x492720, CPad::UpdatePads, PATCH_JUMP);
|
||||||
InjectHook(0x492C60, &CPad::ProcessPCSpecificStuff, PATCH_JUMP);
|
InjectHook(0x492C60, &CPad::ProcessPCSpecificStuff, PATCH_JUMP);
|
||||||
InjectHook(0x492C70, &CPad::Update, PATCH_JUMP);
|
InjectHook(0x492C70, &CPad::Update, PATCH_JUMP);
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable : 4573)
|
||||||
InjectHook(0x492F00, (void (*)())CPad::DoCheats, PATCH_JUMP);
|
InjectHook(0x492F00, (void (*)())CPad::DoCheats, PATCH_JUMP);
|
||||||
|
#pragma warning( pop )
|
||||||
InjectHook(0x492F20, (void (CPad::*)(int16))&CPad::DoCheats, PATCH_JUMP);
|
InjectHook(0x492F20, (void (CPad::*)(int16))&CPad::DoCheats, PATCH_JUMP);
|
||||||
InjectHook(0x492F30, CPad::StopPadsShaking, PATCH_JUMP);
|
InjectHook(0x492F30, CPad::StopPadsShaking, PATCH_JUMP);
|
||||||
InjectHook(0x492F50, &CPad::StopShaking, PATCH_JUMP);
|
InjectHook(0x492F50, &CPad::StopShaking, PATCH_JUMP);
|
||||||
|
@ -4,6 +4,34 @@
|
|||||||
#include "TimeCycle.h"
|
#include "TimeCycle.h"
|
||||||
#include "skeleton.h"
|
#include "skeleton.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
RwMallocAlign(RwUInt32 size, RwUInt32 align)
|
||||||
|
{
|
||||||
|
void *mem = (void *)malloc(size + align);
|
||||||
|
|
||||||
|
ASSERT(mem != NULL);
|
||||||
|
|
||||||
|
void *addr = (void *)((((RwUInt32)mem) + align) & ~(align - 1));
|
||||||
|
|
||||||
|
ASSERT(addr != NULL);
|
||||||
|
|
||||||
|
*(((void **)addr) - 1) = mem;
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RwFreeAlign(void *mem)
|
||||||
|
{
|
||||||
|
ASSERT(mem != NULL);
|
||||||
|
|
||||||
|
void *addr = *(((void **)mem) - 1);
|
||||||
|
|
||||||
|
ASSERT(addr != NULL);
|
||||||
|
|
||||||
|
free(addr);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DefinedState(void)
|
DefinedState(void)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
|
||||||
|
void RwFreeAlign(void *mem);
|
||||||
|
|
||||||
void DefinedState(void);
|
void DefinedState(void);
|
||||||
RwFrame *GetFirstChild(RwFrame *frame);
|
RwFrame *GetFirstChild(RwFrame *frame);
|
||||||
RwObject *GetFirstObject(RwFrame *frame);
|
RwObject *GetFirstObject(RwFrame *frame);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
#include "Weather.h"
|
#include "Weather.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "TempColModels.h"
|
#include "TempColModels.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
||||||
|
WRAPPER void CWorld::Add(CEntity *entity) { EAXJMP(0x4AE930); }
|
||||||
|
|
||||||
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
|
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
|
||||||
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
|
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
|
||||||
CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
|
CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
|
||||||
|
@ -55,6 +55,7 @@ public:
|
|||||||
static bool &bForceProcessControl;
|
static bool &bForceProcessControl;
|
||||||
static bool &bProcessCutsceneOnly;
|
static bool &bProcessCutsceneOnly;
|
||||||
|
|
||||||
|
static void Add(CEntity *entity);
|
||||||
|
|
||||||
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
|
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
|
||||||
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
|
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
|
||||||
|
@ -139,7 +139,7 @@ CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump,
|
|||||||
DestroyAssociations();
|
DestroyAssociations();
|
||||||
|
|
||||||
animBlock = CAnimManager::GetAnimationBlock(blockName);
|
animBlock = CAnimManager::GetAnimationBlock(blockName);
|
||||||
assocList = new CAnimBlendAssociation[animBlock->numAnims];
|
assocList = new CAnimBlendAssociation[numAssocs];
|
||||||
|
|
||||||
numAssociations = 0;
|
numAssociations = 0;
|
||||||
for(i = 0; i < numAssocs; i++){
|
for(i = 0; i < numAssocs; i++){
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
#include "AnimManager.h"
|
#include "AnimManager.h"
|
||||||
#include "AnimBlendAssociation.h"
|
#include "AnimBlendAssociation.h"
|
||||||
|
#include "RwHelper.h"
|
||||||
// TODO: implement those
|
|
||||||
#define RwFreeAlign RwFree
|
|
||||||
#define RwMallocAlign(sz, algn) RwMalloc(sz)
|
|
||||||
|
|
||||||
CAnimBlendAssociation::CAnimBlendAssociation(void)
|
CAnimBlendAssociation::CAnimBlendAssociation(void)
|
||||||
{
|
{
|
||||||
@ -57,6 +54,7 @@ CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n)
|
|||||||
void
|
void
|
||||||
CAnimBlendAssociation::FreeAnimBlendNodeArray(void)
|
CAnimBlendAssociation::FreeAnimBlendNodeArray(void)
|
||||||
{
|
{
|
||||||
|
assert(nodes != nil);
|
||||||
RwFreeAlign(nodes);
|
RwFreeAlign(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
|
#include "RwHelper.h"
|
||||||
|
|
||||||
// TODO: implement those
|
|
||||||
#define RwFreeAlign RwFree
|
|
||||||
#define RwMallocAlign(sz, algn) RwMalloc(sz)
|
|
||||||
|
|
||||||
CAnimBlendClumpData::CAnimBlendClumpData(void)
|
CAnimBlendClumpData::CAnimBlendClumpData(void)
|
||||||
{
|
{
|
||||||
|
11
src/common.h
11
src/common.h
@ -76,13 +76,6 @@ extern void **rwengine;
|
|||||||
#define HUD_FROM_RIGHT(a) (SCREEN_WIDTH - HUD_STRETCH_X(a))
|
#define HUD_FROM_RIGHT(a) (SCREEN_WIDTH - HUD_STRETCH_X(a))
|
||||||
#define HUD_FROM_BOTTOM(a) (SCREEN_HEIGHT - HUD_STRETCH_Y(a))
|
#define HUD_FROM_BOTTOM(a) (SCREEN_HEIGHT - HUD_STRETCH_Y(a))
|
||||||
|
|
||||||
struct GlobalScene
|
|
||||||
{
|
|
||||||
RpWorld *world;
|
|
||||||
RwCamera *camera;
|
|
||||||
};
|
|
||||||
extern GlobalScene &Scene;
|
|
||||||
|
|
||||||
#include "math/Vector.h"
|
#include "math/Vector.h"
|
||||||
#include "math/Vector2D.h"
|
#include "math/Vector2D.h"
|
||||||
#include "math/Matrix.h"
|
#include "math/Matrix.h"
|
||||||
@ -136,10 +129,6 @@ inline float sq(float x) { return x*x; }
|
|||||||
int myrand(void);
|
int myrand(void);
|
||||||
void mysrand(unsigned int seed);
|
void mysrand(unsigned int seed);
|
||||||
|
|
||||||
extern uint8 work_buff[55000];
|
|
||||||
extern char gString[256];
|
|
||||||
extern wchar *gUString;
|
|
||||||
|
|
||||||
void re3_debug(char *format, ...);
|
void re3_debug(char *format, ...);
|
||||||
void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...);
|
void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...);
|
||||||
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
|
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
|
|
||||||
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
||||||
|
WRAPPER void CCarCtrl::AddToCarArray(int id, int vehclass) { EAXJMP(0x4182F0); }
|
||||||
|
@ -6,4 +6,5 @@ class CCarCtrl
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void SwitchVehicleToRealPhysics(CVehicle*);
|
static void SwitchVehicleToRealPhysics(CVehicle*);
|
||||||
|
static void AddToCarArray(int id, int vehclass);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "Garages.h"
|
#include "Garages.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
7
src/control/HandlingDataMgr.cpp
Normal file
7
src/control/HandlingDataMgr.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "HandlingDatamgr.h"
|
||||||
|
|
||||||
|
cHandlingDataMgr &mod_HandlingManager = *(cHandlingDataMgr*)0x728060;
|
||||||
|
|
||||||
|
WRAPPER int32 cHandlingDataMgr::GetHandlingId(const char *name){ EAXJMP(0x546B70); }
|
8
src/control/HandlingDataMgr.h
Normal file
8
src/control/HandlingDataMgr.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class cHandlingDataMgr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int32 GetHandlingId(const char *name);
|
||||||
|
};
|
||||||
|
extern cHandlingDataMgr &mod_HandlingManager;
|
5
src/control/ObjectData.cpp
Normal file
5
src/control/ObjectData.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "ObjectData.h"
|
||||||
|
|
||||||
|
WRAPPER void CObjectData::Initialise(const char *filename) { EAXJMP(0x4BC0E0); }
|
7
src/control/ObjectData.h
Normal file
7
src/control/ObjectData.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CObjectData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Initialise(const char *filename);
|
||||||
|
};
|
@ -45,6 +45,43 @@ CPathInfoForObject *&InfoForTilePeds = *(CPathInfoForObject**)0x8F1AE4;
|
|||||||
CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824;
|
CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824;
|
||||||
CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0;
|
CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0;
|
||||||
|
|
||||||
|
void
|
||||||
|
CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = id*12 + node;
|
||||||
|
InfoForTilePeds[i].type = type;
|
||||||
|
InfoForTilePeds[i].next = next;
|
||||||
|
InfoForTilePeds[i].x = x;
|
||||||
|
InfoForTilePeds[i].y = y;
|
||||||
|
InfoForTilePeds[i].z = z;
|
||||||
|
InfoForTilePeds[i].numLeftLanes = 0;
|
||||||
|
InfoForTilePeds[i].numRightLanes = 0;
|
||||||
|
InfoForTilePeds[i].crossing = crossing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = id*12 + node;
|
||||||
|
InfoForTileCars[i].type = type;
|
||||||
|
InfoForTileCars[i].next = next;
|
||||||
|
InfoForTileCars[i].x = x;
|
||||||
|
InfoForTileCars[i].y = y;
|
||||||
|
InfoForTileCars[i].z = z;
|
||||||
|
InfoForTileCars[i].numLeftLanes = numLeft;
|
||||||
|
InfoForTileCars[i].numRightLanes = numRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPathFind::RegisterMapObject(CTreadable *mapObject)
|
||||||
|
{
|
||||||
|
m_mapObjects[m_numMapObjects++] = mapObject;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPathFind::PreparePathData(void)
|
CPathFind::PreparePathData(void)
|
||||||
{
|
{
|
||||||
@ -457,8 +494,8 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
// Crosses road
|
// Crosses road
|
||||||
if(objectpathinfo[istart + iseg].next == jseg && objectpathinfo[istart + iseg].flag & 1 ||
|
if(objectpathinfo[istart + iseg].next == jseg && objectpathinfo[istart + iseg].crossing ||
|
||||||
objectpathinfo[jstart + jseg].next == iseg && objectpathinfo[jstart + jseg].flag & 1)
|
objectpathinfo[jstart + jseg].next == iseg && objectpathinfo[jstart + jseg].crossing)
|
||||||
m_connectionFlags[m_numConnections] |= ConnectionCrossRoad;
|
m_connectionFlags[m_numConnections] |= ConnectionCrossRoad;
|
||||||
else
|
else
|
||||||
m_connectionFlags[m_numConnections] &= ~ConnectionCrossRoad;
|
m_connectionFlags[m_numConnections] &= ~ConnectionCrossRoad;
|
||||||
|
@ -65,8 +65,10 @@ struct CPathInfoForObject
|
|||||||
int8 next;
|
int8 next;
|
||||||
int8 numLeftLanes;
|
int8 numLeftLanes;
|
||||||
int8 numRightLanes;
|
int8 numRightLanes;
|
||||||
uint8 flag;
|
uint8 crossing : 1;
|
||||||
};
|
};
|
||||||
|
extern CPathInfoForObject *&InfoForTileCars;
|
||||||
|
extern CPathInfoForObject *&InfoForTilePeds;
|
||||||
|
|
||||||
struct CTempNode
|
struct CTempNode
|
||||||
{
|
{
|
||||||
@ -123,6 +125,11 @@ public:
|
|||||||
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
||||||
float unk, CTempDetachedNode *detachednodes, int unused);
|
float unk, CTempDetachedNode *detachednodes, int unused);
|
||||||
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
||||||
|
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
|
||||||
|
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
|
||||||
|
void RegisterMapObject(CTreadable *mapObject);
|
||||||
|
|
||||||
|
bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
|
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
|
||||||
|
|
||||||
|
5
src/control/PedStats.cpp
Normal file
5
src/control/PedStats.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "PedStats.h"
|
||||||
|
|
||||||
|
WRAPPER int32 CPedStats::GetPedStatType(char *type) { EAXJMP(0x4EF780); }
|
@ -15,3 +15,9 @@ struct PedStat
|
|||||||
int16 m_flags;
|
int16 m_flags;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PedStat) == 0x34, "PedStat: error");
|
static_assert(sizeof(PedStat) == 0x34, "PedStat: error");
|
||||||
|
|
||||||
|
class CPedStats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int32 GetPedStatType(char *type);
|
||||||
|
};
|
5
src/control/PedType.cpp
Normal file
5
src/control/PedType.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "PedType.h"
|
||||||
|
|
||||||
|
WRAPPER int32 CPedType::FindPedType(char *type) { EAXJMP(0x4EEC10); }
|
7
src/control/PedType.h
Normal file
7
src/control/PedType.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CPedType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int32 FindPedType(char *type);
|
||||||
|
};
|
@ -6,7 +6,10 @@ class CBuilding : public CEntity
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// TODO: ReplaceWithNewModel
|
// TODO: ReplaceWithNewModel
|
||||||
// TODO: ctor
|
CBuilding(void) {
|
||||||
|
m_type = ENTITY_TYPE_BUILDING;
|
||||||
|
bUsesCollision = true;
|
||||||
|
}
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
static void operator delete(void*, size_t);
|
static void operator delete(void*, size_t);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <rpskin.h>
|
#include <rpskin.h>
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "lights.h"
|
#include "lights.h"
|
||||||
#include "PointLights.h"
|
#include "PointLights.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
|
@ -8,6 +8,9 @@ class CDummy : public CEntity
|
|||||||
public:
|
public:
|
||||||
CEntryInfoList m_entryInfoList;
|
CEntryInfoList m_entryInfoList;
|
||||||
|
|
||||||
|
CDummy(void) { m_type = ENTITY_TYPE_DUMMY; }
|
||||||
|
// TODO: Add, Remove
|
||||||
|
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
static void operator delete(void*, size_t);
|
static void operator delete(void*, size_t);
|
||||||
};
|
};
|
||||||
|
13
src/entities/DummyObject.cpp
Normal file
13
src/entities/DummyObject.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "DummyObject.h"
|
||||||
|
#include "Pools.h"
|
||||||
|
|
||||||
|
CDummyObject::CDummyObject(CObject *obj)
|
||||||
|
{
|
||||||
|
SetModelIndexNoCreate(obj->GetModelIndex());
|
||||||
|
if(obj->m_rwObject)
|
||||||
|
AttachToRwObject(obj->m_rwObject);
|
||||||
|
obj->DetachFromRwObject();
|
||||||
|
m_level = obj->m_level;
|
||||||
|
}
|
@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
#include "Dummy.h"
|
#include "Dummy.h"
|
||||||
|
|
||||||
class CDummyObject : CDummy
|
class CObject;
|
||||||
|
|
||||||
|
class CDummyObject : public CDummy
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
CDummyObject(void) {}
|
||||||
|
CDummyObject(CObject *obj);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");
|
static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");
|
||||||
|
@ -48,7 +48,7 @@ CEntity::CEntity(void)
|
|||||||
bHasHitWall = false;
|
bHasHitWall = false;
|
||||||
bImBeingRendered = false;
|
bImBeingRendered = false;
|
||||||
m_flagD8 = false;
|
m_flagD8 = false;
|
||||||
m_flagD10 = false;
|
bIsSubway = false;
|
||||||
bDrawLast = false;
|
bDrawLast = false;
|
||||||
m_flagD40 = false;
|
m_flagD40 = false;
|
||||||
m_flagD80 = false;
|
m_flagD80 = false;
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
uint32 bHasHitWall : 1;
|
uint32 bHasHitWall : 1;
|
||||||
uint32 bImBeingRendered : 1;
|
uint32 bImBeingRendered : 1;
|
||||||
uint32 m_flagD8 : 1;
|
uint32 m_flagD8 : 1;
|
||||||
uint32 m_flagD10 : 1;
|
uint32 bIsSubway : 1; // set when subway, but maybe different meaning?
|
||||||
uint32 bDrawLast : 1;
|
uint32 bDrawLast : 1;
|
||||||
uint32 m_flagD40 : 1;
|
uint32 m_flagD40 : 1;
|
||||||
uint32 m_flagD80 : 1; // CObject visibility?
|
uint32 m_flagD80 : 1; // CObject visibility?
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "PedStat.h"
|
|
||||||
#include "DMaudio.h"
|
#include "DMaudio.h"
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
#include "PedType.h"
|
#include "PedType.h"
|
||||||
|
27
src/main.cpp
27
src/main.cpp
@ -1,5 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "General.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "Clouds.h"
|
#include "Clouds.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
@ -55,6 +57,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
GlobalScene &Scene = *(GlobalScene*)0x726768;
|
||||||
|
|
||||||
uint8 work_buff[55000];
|
uint8 work_buff[55000];
|
||||||
char gString[256];
|
char gString[256];
|
||||||
wchar *gUString = (wchar*)0x74B018;
|
wchar *gUString = (wchar*)0x74B018;
|
||||||
@ -576,6 +580,29 @@ ResetLoadingScreenBar(void)
|
|||||||
NumberOfChunksLoaded = 0.0f;
|
NumberOfChunksLoaded = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
GetRandomSplashScreen(void)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
static int index2 = 0;
|
||||||
|
static char splashName[128];
|
||||||
|
static int splashIndex[24] = {
|
||||||
|
25, 22, 4, 13,
|
||||||
|
1, 21, 14, 16,
|
||||||
|
10, 12, 5, 9,
|
||||||
|
11, 18, 3, 2,
|
||||||
|
19, 23, 7, 17,
|
||||||
|
15, 6, 8, 20
|
||||||
|
};
|
||||||
|
|
||||||
|
index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
|
||||||
|
index2++;
|
||||||
|
if(index2 == 6)
|
||||||
|
index2 = 0;
|
||||||
|
sprintf(splashName, "loadsc%d", index);
|
||||||
|
return splashName;
|
||||||
|
}
|
||||||
|
|
||||||
#include "rwcore.h"
|
#include "rwcore.h"
|
||||||
#include "rpworld.h"
|
#include "rpworld.h"
|
||||||
#include "rpmatfx.h"
|
#include "rpmatfx.h"
|
||||||
|
18
src/main.h
Normal file
18
src/main.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct GlobalScene
|
||||||
|
{
|
||||||
|
RpWorld *world;
|
||||||
|
RwCamera *camera;
|
||||||
|
};
|
||||||
|
extern GlobalScene &Scene;
|
||||||
|
|
||||||
|
extern uint8 work_buff[55000];
|
||||||
|
extern char gString[256];
|
||||||
|
extern wchar *gUString;
|
||||||
|
|
||||||
|
class CSprite2d;
|
||||||
|
|
||||||
|
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
|
||||||
|
CSprite2d *LoadSplash(const char *name);
|
||||||
|
char *GetRandomSplashScreen(void);
|
@ -41,6 +41,9 @@ public:
|
|||||||
virtual RwObject *GetRwObject(void) = 0;
|
virtual RwObject *GetRwObject(void) = 0;
|
||||||
|
|
||||||
bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
|
bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
|
||||||
|
bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE ||
|
||||||
|
m_type == MITYPE_MLO || m_type == MITYPE_XTRACOMPS; // unused but what the heck
|
||||||
|
}
|
||||||
char *GetName(void) { return m_name; }
|
char *GetName(void) { return m_name; }
|
||||||
void SetName(const char *name) { strncpy(m_name, name, 24); }
|
void SetName(const char *name) { strncpy(m_name, name, 24); }
|
||||||
void SetColModel(CColModel *col, bool free = false){
|
void SetColModel(CColModel *col, bool free = false){
|
||||||
|
@ -320,9 +320,12 @@ enum
|
|||||||
MI_CAR_PANEL,
|
MI_CAR_PANEL,
|
||||||
MI_CAR_BONNET,
|
MI_CAR_BONNET,
|
||||||
MI_CAR_BOOT,
|
MI_CAR_BOOT,
|
||||||
MI_CAR_WEEL,
|
MI_CAR_WHEEL,
|
||||||
MI_BODYPARTA,
|
MI_BODYPARTA,
|
||||||
MI_BODYPARTB,
|
MI_BODYPARTB,
|
||||||
|
|
||||||
|
MI_AIRTRAIN_VLO = 198,
|
||||||
|
MI_LOPOLYGUY,
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitModelIndices(void);
|
void InitModelIndices(void);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "TempColModels.h"
|
||||||
|
#include "ModelIndices.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408;
|
CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408;
|
||||||
@ -18,6 +20,8 @@ void
|
|||||||
CModelInfo::Initialise(void)
|
CModelInfo::Initialise(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
CSimpleModelInfo *m;
|
||||||
|
|
||||||
for(i = 0; i < MODELINFOSIZE; i++)
|
for(i = 0; i < MODELINFOSIZE; i++)
|
||||||
ms_modelInfoPtrs[i] = nil;
|
ms_modelInfoPtrs[i] = nil;
|
||||||
ms_2dEffectStore.clear();
|
ms_2dEffectStore.clear();
|
||||||
@ -26,10 +30,58 @@ CModelInfo::Initialise(void)
|
|||||||
ms_clumpModelStore.clear();
|
ms_clumpModelStore.clear();
|
||||||
ms_pedModelStore.clear();
|
ms_pedModelStore.clear();
|
||||||
ms_vehicleModelStore.clear();
|
ms_vehicleModelStore.clear();
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_DOOR);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelDoor1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BUMPER);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBumper1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_PANEL);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelPanel1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BONNET);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBonnet1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BOOT);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBoot1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_WHEEL);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelWheel1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_BODYPARTA);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBodyPart1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_BODYPARTB);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBodyPart2);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CModelInfo::Shutdown(void)
|
CModelInfo::ShutDown(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < ms_simpleModelStore.allocPtr; i++)
|
for(i = 0; i < ms_simpleModelStore.allocPtr; i++)
|
||||||
@ -42,6 +94,8 @@ CModelInfo::Shutdown(void)
|
|||||||
ms_pedModelStore.store[i].Shutdown();
|
ms_pedModelStore.store[i].Shutdown();
|
||||||
for(i = 0; i < ms_vehicleModelStore.allocPtr; i++)
|
for(i = 0; i < ms_vehicleModelStore.allocPtr; i++)
|
||||||
ms_vehicleModelStore.store[i].Shutdown();
|
ms_vehicleModelStore.store[i].Shutdown();
|
||||||
|
for(i = 0; i < ms_2dEffectStore.allocPtr; i++)
|
||||||
|
ms_2dEffectStore.store[i].Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSimpleModelInfo*
|
CSimpleModelInfo*
|
||||||
@ -115,10 +169,12 @@ CModelInfo::GetModelInfo(const char *name, int *id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
// InjectHook(0x50B920, CModelInfo::AddSimpleModel, PATCH_JUMP);
|
InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP);
|
||||||
// InjectHook(0x50B9C0, CModelInfo::AddTimeModel, PATCH_JUMP);
|
InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP);
|
||||||
// InjectHook(0x50BA10, CModelInfo::AddClumpModel, PATCH_JUMP);
|
InjectHook(0x50B920, CModelInfo::AddSimpleModel, PATCH_JUMP);
|
||||||
// InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
|
InjectHook(0x50B9C0, CModelInfo::AddTimeModel, PATCH_JUMP);
|
||||||
// InjectHook(0x50BA60, CModelInfo::AddPedModel, PATCH_JUMP);
|
InjectHook(0x50BA10, CModelInfo::AddClumpModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x50BA60, CModelInfo::AddVehicleModel, PATCH_JUMP);
|
||||||
InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
|
InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -20,7 +20,7 @@ class CModelInfo
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void Initialise(void);
|
static void Initialise(void);
|
||||||
static void Shutdown(void);
|
static void ShutDown(void);
|
||||||
|
|
||||||
static CSimpleModelInfo *AddSimpleModel(int id);
|
static CSimpleModelInfo *AddSimpleModel(int id);
|
||||||
static CTimeModelInfo *AddTimeModel(int id);
|
static CTimeModelInfo *AddTimeModel(int id);
|
||||||
@ -28,6 +28,8 @@ public:
|
|||||||
static CPedModelInfo *AddPedModel(int id);
|
static CPedModelInfo *AddPedModel(int id);
|
||||||
static CVehicleModelInfo *AddVehicleModel(int id);
|
static CVehicleModelInfo *AddVehicleModel(int id);
|
||||||
|
|
||||||
|
static CStore<C2dEffect, TWODFXSIZE> &Get2dEffectStore(void) { return ms_2dEffectStore; }
|
||||||
|
|
||||||
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
|
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
|
||||||
static CBaseModelInfo *GetModelInfo(int id){
|
static CBaseModelInfo *GetModelInfo(int id){
|
||||||
return ms_modelInfoPtrs[id];
|
return ms_modelInfoPtrs[id];
|
||||||
|
@ -21,7 +21,7 @@ enum PedNode {
|
|||||||
class CPedModelInfo : public CClumpModelInfo
|
class CPedModelInfo : public CClumpModelInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void *m_animGroup; // TODO
|
int32 m_animGroup;
|
||||||
int32 m_pedType;
|
int32 m_pedType;
|
||||||
int32 m_pedStatType;
|
int32 m_pedStatType;
|
||||||
uint32 m_carsCanDrive;
|
uint32 m_carsCanDrive;
|
||||||
|
@ -53,7 +53,7 @@ CSimpleModelInfo::Init(void)
|
|||||||
m_atomics[1] = nil;
|
m_atomics[1] = nil;
|
||||||
m_atomics[2] = nil;
|
m_atomics[2] = nil;
|
||||||
m_numAtomics = 0;
|
m_numAtomics = 0;
|
||||||
m_furthest = 0;
|
m_firstDamaged = 0;
|
||||||
m_normalCull = 0;
|
m_normalCull = 0;
|
||||||
m_isDamaged = 0;
|
m_isDamaged = 0;
|
||||||
m_isBigBuilding = 0;
|
m_isBigBuilding = 0;
|
||||||
@ -103,11 +103,10 @@ float
|
|||||||
CSimpleModelInfo::GetLargestLodDistance(void)
|
CSimpleModelInfo::GetLargestLodDistance(void)
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
// TODO: what exactly is going on here?
|
if(m_firstDamaged == 0 || m_isDamaged)
|
||||||
if(m_furthest != 0 && !m_isDamaged)
|
|
||||||
d = m_lodDistances[m_furthest-1];
|
|
||||||
else
|
|
||||||
d = m_lodDistances[m_numAtomics-1];
|
d = m_lodDistances[m_numAtomics-1];
|
||||||
|
else
|
||||||
|
d = m_lodDistances[m_firstDamaged-1];
|
||||||
return d * TheCamera.LODDistMultiplier;
|
return d * TheCamera.LODDistMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +115,8 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
i = 0;
|
i = 0;
|
||||||
// TODO: what exactly is going on here?
|
|
||||||
if(m_isDamaged)
|
if(m_isDamaged)
|
||||||
i = m_furthest;
|
i = m_firstDamaged;
|
||||||
for(; i < m_numAtomics; i++)
|
for(; i < m_numAtomics; i++)
|
||||||
if(dist < m_lodDistances[i] *TheCamera.LODDistMultiplier)
|
if(dist < m_lodDistances[i] *TheCamera.LODDistMultiplier)
|
||||||
return m_atomics[i];
|
return m_atomics[i];
|
||||||
|
@ -11,9 +11,9 @@ public:
|
|||||||
float m_lodDistances[3];
|
float m_lodDistances[3];
|
||||||
uint8 m_numAtomics;
|
uint8 m_numAtomics;
|
||||||
uint8 m_alpha;
|
uint8 m_alpha;
|
||||||
uint16 m_furthest : 2; // 0: numAtomics-1 is furthest visible
|
uint16 m_firstDamaged : 2; // 0: no damage model
|
||||||
// 1: atomic 0 is furthest
|
// 1: 1 and 2 are damage models
|
||||||
// 2: atomic 1 is furthest
|
// 2: 2 is damage model
|
||||||
uint16 m_normalCull : 1;
|
uint16 m_normalCull : 1;
|
||||||
uint16 m_isDamaged : 1;
|
uint16 m_isDamaged : 1;
|
||||||
uint16 m_isBigBuilding : 1;
|
uint16 m_isBigBuilding : 1;
|
||||||
|
@ -12,7 +12,9 @@ public:
|
|||||||
|
|
||||||
int32 GetTimeOn(void) { return m_timeOn; }
|
int32 GetTimeOn(void) { return m_timeOn; }
|
||||||
int32 GetTimeOff(void) { return m_timeOff; }
|
int32 GetTimeOff(void) { return m_timeOff; }
|
||||||
|
void SetTimes(int32 on, int32 off) { m_timeOn = on; m_timeOff = off; }
|
||||||
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
|
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
|
||||||
|
void SetOtherTimeModel(int32 other) { m_otherTimeModelID = other; }
|
||||||
CTimeModelInfo *FindOtherTimeModel(void);
|
CTimeModelInfo *FindOtherTimeModel(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
|
static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
|
||||||
|
@ -35,6 +35,17 @@ enum {
|
|||||||
NUM_VEHICLE_TYPES
|
NUM_VEHICLE_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VEHICLE_CLASS_POOR,
|
||||||
|
VEHICLE_CLASS_RICH,
|
||||||
|
VEHICLE_CLASS_EXECUTIVE,
|
||||||
|
VEHICLE_CLASS_WORKER,
|
||||||
|
VEHICLE_CLASS_SPECIAL,
|
||||||
|
VEHICLE_CLASS_BIG,
|
||||||
|
VEHICLE_CLASS_TAXI,
|
||||||
|
NUM_VEHICLE_CLASSES
|
||||||
|
};
|
||||||
|
|
||||||
class CVehicleModelInfo : public CClumpModelInfo
|
class CVehicleModelInfo : public CClumpModelInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
void **rwengine = *(void***)0x5A10E1;
|
void **rwengine = *(void***)0x5A10E1;
|
||||||
|
|
||||||
GlobalScene &Scene = *(GlobalScene*)0x726768;
|
|
||||||
|
|
||||||
DebugMenuAPI gDebugMenuAPI;
|
DebugMenuAPI gDebugMenuAPI;
|
||||||
|
|
||||||
WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
|
WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
enum {
|
||||||
|
EFFECT_LIGHT,
|
||||||
|
EFFECT_PARTICLE,
|
||||||
|
EFFECT_ATTRACTOR
|
||||||
|
};
|
||||||
|
|
||||||
class C2dEffect
|
class C2dEffect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -7,26 +13,26 @@ public:
|
|||||||
float size;
|
float size;
|
||||||
float innerRange;
|
float innerRange;
|
||||||
uint8 flash;
|
uint8 flash;
|
||||||
uint8 wet;
|
uint8 roadReflection;
|
||||||
uint8 flare;
|
uint8 flareType;
|
||||||
uint8 shadowIntens;
|
uint8 shadowIntensity;
|
||||||
uint8 flag;
|
uint8 flags;
|
||||||
RwTexture *corona;
|
RwTexture *corona;
|
||||||
RwTexture *shadow;
|
RwTexture *shadow;
|
||||||
};
|
};
|
||||||
struct Particle {
|
struct Particle {
|
||||||
int particleType;
|
int particleType;
|
||||||
float dir[3];
|
CVector dir;
|
||||||
float scale;
|
float scale;
|
||||||
};
|
};
|
||||||
struct Attractor {
|
struct Attractor {
|
||||||
CVector dir;
|
CVector dir;
|
||||||
uint8 flag;
|
uint8 flags;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
};
|
};
|
||||||
|
|
||||||
CVector pos;
|
CVector pos;
|
||||||
RwRGBA col;
|
CRGBA col;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
union {
|
union {
|
||||||
Light light;
|
Light light;
|
||||||
@ -35,5 +41,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
C2dEffect(void) {}
|
C2dEffect(void) {}
|
||||||
|
void Shutdown(void){
|
||||||
|
if(type == 0){ // TODO: enum
|
||||||
|
if(light.corona)
|
||||||
|
RwTextureDestroy(light.corona);
|
||||||
|
if(light.shadow)
|
||||||
|
RwTextureDestroy(light.shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(C2dEffect) == 0x34, "C2dEffect: error");
|
static_assert(sizeof(C2dEffect) == 0x34, "C2dEffect: error");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
#include "TxdStore.h"
|
#include "TxdStore.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
@ -432,7 +432,7 @@ void CHud::Draw()
|
|||||||
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth >= 10
|
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth >= 10
|
||||||
|| CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
|
|| CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
|
||||||
|
|
||||||
AsciiToUnicode("[", sPrintIcon);
|
AsciiToUnicode("{", sPrintIcon);
|
||||||
sprintf(sTemp, "%03d", (int32)CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth);
|
sprintf(sTemp, "%03d", (int32)CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth);
|
||||||
AsciiToUnicode(sTemp, sPrint);
|
AsciiToUnicode(sTemp, sPrint);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "ParticleMgr.h"
|
#include "ParticleMgr.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Weather.h"
|
#include "Weather.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
#include "Treadable.h"
|
#include "Treadable.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Sprite.h"
|
#include "Sprite.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Sprite2d.h"
|
#include "Sprite2d.h"
|
||||||
|
@ -83,6 +83,7 @@ static psGlobalType &PsGlobal = *(psGlobalType*)0x72CF60;
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
#include "Pad.h"
|
#include "Pad.h"
|
||||||
|
@ -8,8 +8,10 @@ public:
|
|||||||
T store[n];
|
T store[n];
|
||||||
|
|
||||||
T *alloc(void){
|
T *alloc(void){
|
||||||
if(this->allocPtr >= n)
|
if(this->allocPtr >= n){
|
||||||
printf("Size of this thing:%d needs increasing\n", n);
|
printf("Size of this thing:%d needs increasing\n", n);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
return &this->store[this->allocPtr++];
|
return &this->store[this->allocPtr++];
|
||||||
}
|
}
|
||||||
void clear(void){
|
void clear(void){
|
||||||
|
Loading…
Reference in New Issue
Block a user