Merge branch 'master' of https://github.com/GTAmodding/re3 into wiiu

This commit is contained in:
GaryOderNichts 2021-01-29 22:19:04 +01:00
commit 5ed83f0e61
29 changed files with 1210 additions and 452 deletions

View File

@ -1,116 +0,0 @@
name: re3 conan+cmake
on:
pull_request:
push:
release:
types: published
jobs:
build-cmake:
strategy:
matrix:
include:
- os: 'windows-latest'
platform: 'gl3'
gl3_gfxlib: 'glfw'
audio: 'openal'
# - os: 'windows-latest'
# platform: 'gl3'
# gl3_gfxlib: 'sdl2'
# audio: 'openal'
- os: 'windows-latest'
platform: 'd3d9'
audio: 'openal'
# - os: 'windows-latest'
# platform: 'd3d9'
# audio: 'miles'
- os: 'ubuntu-latest'
platform: 'gl3'
gl3_gfxlib: 'glfw'
audio: 'openal'
# - os: 'ubuntu-latest'
# platform: 'gl3'
# gl3_gfxlib: 'sdl2'
# audio: 'openal'
- os: 'macos-latest'
platform: 'gl3'
gl3_gfxlib: 'glfw'
audio: 'openal'
# - os: 'macos-latest'
# platform: 'gl3'
# gl3_gfxlib: 'sdl2'
# audio: 'openal'
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.platform == 'ps2' || matrix.gl3_gfxlib == 'sdl2' || matrix.audio == 'miles' }}
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: "Checkout Miles SDK Import Library project"
uses: actions/checkout@v2
if: ${{ matrix.audio == 'miles' }}
with:
repository: 'withmorten/re3mss'
path: 're3mss'
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: "Use XCode 11 as default (conan-center-index does not provide XCode 12 binaries at the moment)"
if: startsWith(matrix.os, 'macos')
run: |
sudo xcode-select --switch /Applications/Xcode_11.7.app
- name: "Setup conan"
run: |
python -m pip install conan
conan config init
conan config set log.print_run_commands=True
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
conan remote add madebr_ps2dev https://api.bintray.com/conan/madebr/ps2dev
- name: "Add os=playstation2 + gcc.version=3.2 to .conan/settings.yml"
shell: python
run: |
import os, yaml
settings_path = os.path.expanduser("~/.conan/settings.yml")
yml = yaml.safe_load(open(settings_path))
yml["os"]["playstation2"] = None
yml["compiler"]["gcc"]["version"].append("3.2")
yml["compiler"]["gcc"]["version"].sort()
yaml.safe_dump(yml, open(settings_path, "w"))
- name: "Create host profile"
shell: bash
run: |
if test "${{ matrix.platform }}" = "ps2"; then
cp vendor/librw/conan/playstation2 host_profile
else
cp ~/.conan/profiles/default host_profile
fi
- name: "Export Playstation 2 CMake toolchain conan recipe"
run: |
conan export vendor/librw/cmake/ps2toolchain ps2dev-cmaketoolchain/master@
- name: "Export librw conan recipe"
run: |
conan export vendor/librw librw/master@
- name: "Export Miles SDK conan recipe"
if: ${{ matrix.audio == 'miles' }}
run: |
conan export re3mss miles-sdk/master@
- name: "Download/build dependencies (conan install)"
run: |
conan install ${{ github.workspace }} re3/master@ -if build -o re3:audio=${{ matrix.audio }} -o librw:platform=${{ matrix.platform }} -o librw:gl3_gfxlib=${{ matrix.gl3_gfxlib || 'glfw' }} --build missing -pr:h ./host_profile -pr:b default -s re3:build_type=RelWithDebInfo -s librw:build_type=RelWithDebInfo
env:
CONAN_SYSREQUIRES_MODE: enabled
- name: "Build re3 (conan build)"
run: |
conan build ${{ github.workspace }} -if build -bf build -pf package
- name: "Package re3 (conan package)"
run: |
conan package ${{ github.workspace }} -if build -bf build -pf package
- name: "Create binary package (cpack)"
working-directory: ./build
run: |
cpack -C RelWithDebInfo
- name: "Archive binary package (github artifacts)"
uses: actions/upload-artifact@v2
with:
name: "${{ matrix.os }}-${{ matrix.platform }}"
path: build/*.tar.xz
if-no-files-found: error

View File

@ -77,6 +77,6 @@ if(${PROJECT}_INSTALL)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_GENERATOR "TXZ") set(CPACK_GENERATOR "ZIP")
include(CPack) include(CPack)
endif() endif()

View File

@ -31,6 +31,16 @@ such that we have a working game at all times.
- (Optional) If you want to use optional features like Russian language or menu map, copy the files in /gamefiles folder to your game root folder. - (Optional) If you want to use optional features like Russian language or menu map, copy the files in /gamefiles folder to your game root folder.
- Move re3.exe to GTA 3 directory and run it. - Move re3.exe to GTA 3 directory and run it.
## Latest standalone executables to download
(Put content of selected archive into gamedir)
- [MacOS 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/macos-latest-gl3.zip)
- [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/ubuntu-latest-gl3.zip)
- [Windows D3D9 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/windows-latest-d3d9.zip)
- [Windows OpenGL 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/windows-latest-gl3.zip)
- [Windows D3D9 MSS 32bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_x86/master/re3_Release_win-x86-librw_d3d9-mss.zip)
## Building from Source ## Building from Source
If you gonna use premake, then before starting you may want to point GTA_III_RE_DIR environment variable to GTA3 root folder, if you want executable to be moved there via post-build script. If you gonna use premake, then before starting you may want to point GTA_III_RE_DIR environment variable to GTA3 root folder, if you want executable to be moved there via post-build script.

BIN
gamefiles/TEXT/english.gxt Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ end
workspace "re3" workspace "re3"
language "C++" language "C++"
configurations { "Debug", "Release" } configurations { "Debug", "Release", "Vanilla" }
startproject "re3" startproject "re3"
location "build" location "build"
symbols "Full" symbols "Full"
@ -113,13 +113,16 @@ workspace "re3"
filter "configurations:Debug" filter "configurations:Debug"
defines { "DEBUG" } defines { "DEBUG" }
filter "configurations:Release" filter "configurations:not Debug"
defines { "NDEBUG" } defines { "NDEBUG" }
optimize "Speed" optimize "Speed"
if(_OPTIONS["lto"]) then if(_OPTIONS["lto"]) then
flags { "LinkTimeOptimization" } flags { "LinkTimeOptimization" }
end end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter { "platforms:win*" } filter { "platforms:win*" }
system "windows" system "windows"

View File

@ -477,8 +477,16 @@ CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts
if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f) if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f)
return false; return false;
float p0dist = DotProduct(line.p1 - line.p0, normal);
#ifdef FIX_BUGS
// line lines in the plane, assume no collision
if (p0dist == 0.0f)
return false;
#endif
// intersection parameter on line // intersection parameter on line
t = -plane.CalcPoint(line.p0) / DotProduct(line.p1 - line.p0, normal); t = -plane.CalcPoint(line.p0) / p0dist;
// find point of intersection // find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t; CVector p = line.p0 + (line.p1-line.p0)*t;
@ -1286,8 +1294,17 @@ CCollision::ProcessLineTriangle(const CColLine &line,
if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f) if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f)
return false; return false;
float p0dist = DotProduct(line.p1 - line.p0, normal);
#ifdef FIX_BUGS
// line lines in the plane, assume no collision
if (p0dist == 0.0f)
return false;
#endif
// intersection parameter on line // intersection parameter on line
t = -plane.CalcPoint(line.p0) / DotProduct(line.p1 - line.p0, normal); t = -plane.CalcPoint(line.p0) / p0dist;
// early out if we're beyond the mindist // early out if we're beyond the mindist
if(t >= mindist) if(t >= mindist)
return false; return false;

View File

@ -2034,7 +2034,11 @@ float CGarages::FindDoorHeightForMI(int32 mi)
void CGarage::TidyUpGarage() void CGarage::TidyUpGarage()
{ {
uint32 i = CPools::GetVehiclePool()->GetSize(); uint32 i = CPools::GetVehiclePool()->GetSize();
#ifdef FIX_BUGS
while (i--) { while (i--) {
#else
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || !pVehicle->IsCar()) if (!pVehicle || !pVehicle->IsCar())
continue; continue;
@ -2052,7 +2056,11 @@ void CGarage::TidyUpGarage()
void CGarage::TidyUpGarageClose() void CGarage::TidyUpGarageClose()
{ {
uint32 i = CPools::GetVehiclePool()->GetSize(); uint32 i = CPools::GetVehiclePool()->GetSize();
#ifdef FIX_BUGS
while (i--) { while (i--) {
#else
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || !pVehicle->IsCar()) if (!pVehicle || !pVehicle->IsCar())
continue; continue;

View File

@ -1671,6 +1671,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS; pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
pBoat->AutoPilot.m_vecDestinationCoors = pos; pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->SetStatus(STATUS_PHYSICS); pBoat->SetStatus(STATUS_PHYSICS);
pBoat->bEngineOn = true;
pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed); pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed);
pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0; return 0;

View File

@ -43,6 +43,6 @@ char *CdStreamGetImageName(int32 cd);
void CdStreamRemoveImages(void); void CdStreamRemoveImages(void);
int32 CdStreamGetNumImages(void); int32 CdStreamGetNumImages(void);
#ifndef _WIN32 #ifdef FLUSHABLE_STREAMING
extern bool flushStream[MAX_CDCHANNELS]; extern bool flushStream[MAX_CDCHANNELS];
#endif #endif

View File

@ -70,7 +70,9 @@ static int wiiu_thread_create(OSThread *thread, const void *attr, void *(*start_
// #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) // #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)
#ifdef FLUSHABLE_STREAMING
bool flushStream[MAX_CDCHANNELS]; bool flushStream[MAX_CDCHANNELS];
#endif
struct CdReadInfo struct CdReadInfo
{ {
@ -134,7 +136,7 @@ CdStreamInitThread(void)
#ifdef __WIIU__ #ifdef __WIIU__
OSInitSemaphore(&gCdStreamSema, 0); OSInitSemaphore(&gCdStreamSema, 0);
#else #else
gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 0);
if (gCdStreamSema == SEM_FAILED) { if (gCdStreamSema == SEM_FAILED) {
@ -153,7 +155,7 @@ CdStreamInitThread(void)
OSInitSemaphore(&gpReadInfo[i].pDoneSemaphore, 0); OSInitSemaphore(&gpReadInfo[i].pDoneSemaphore, 0);
#else #else
sprintf(semName,"/semaphore_done%d",i); sprintf(semName,"/semaphore_done%d",i);
gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 1); gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 0);
if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED)
{ {
@ -162,9 +164,10 @@ CdStreamInitThread(void)
return; return;
} }
#endif #endif
#ifdef ONE_THREAD_PER_CHANNEL #ifdef ONE_THREAD_PER_CHANNEL
sprintf(semName,"/semaphore_start%d",i); sprintf(semName,"/semaphore_start%d",i);
gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 1); gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 0);
if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) if (gpReadInfo[i].pStartSemaphore == SEM_FAILED)
{ {
@ -243,6 +246,7 @@ CdStreamInit(int32 numChannels)
gNumImages = 0; gNumImages = 0;
gNumChannels = numChannels; gNumChannels = numChannels;
ASSERT( gNumChannels != 0 );
gpReadInfo = (CdReadInfo *)calloc(numChannels, sizeof(CdReadInfo)); gpReadInfo = (CdReadInfo *)calloc(numChannels, sizeof(CdReadInfo));
ASSERT( gpReadInfo != nil ); ASSERT( gpReadInfo != nil );
@ -324,10 +328,12 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) {
if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size)
return STREAM_SUCCESS; return STREAM_SUCCESS;
#ifdef FLUSHABLE_STREAMING
flushStream[channel] = 1; flushStream[channel] = 1;
CdStreamSync(channel); CdStreamSync(channel);
//return STREAM_NONE; #else
return STREAM_NONE;
#endif
} }
pChannel->hFile = hImage - 1; pChannel->hFile = hImage - 1;
@ -399,34 +405,35 @@ CdStreamSync(int32 channel)
CdReadInfo *pChannel = &gpReadInfo[channel]; CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil ); ASSERT( pChannel != nil );
#ifdef FLUSHABLE_STREAMING
if (flushStream[channel]) { if (flushStream[channel]) {
#ifdef ONE_THREAD_PER_CHANNEL
pChannel->nSectorsToRead = 0; pChannel->nSectorsToRead = 0;
#ifdef ONE_THREAD_PER_CHANNEL
pthread_kill(pChannel->pChannelThread, SIGUSR1); pthread_kill(pChannel->pChannelThread, SIGUSR1);
if (pChannel->bReading) { if (pChannel->bReading) {
pChannel->bLocked = true; pChannel->bLocked = true;
while (pChannel->bLocked)
sem_wait(pChannel->pDoneSemaphore);
}
#else #else
pChannel->nSectorsToRead = 0;
if (pChannel->bReading) { if (pChannel->bReading) {
pChannel->bLocked = true; pChannel->bLocked = true;
#ifdef __WIIU__ #ifdef __WIIU__
OSCancelThread(&_gCdStreamThread); OSCancelThread(&_gCdStreamThread);
#else
pthread_kill(_gCdStreamThread, SIGUSR1);
#endif
#endif
#ifdef __WIIU__
while (pChannel->bLocked) while (pChannel->bLocked)
OSWaitSemaphore(&pChannel->pDoneSemaphore); OSWaitSemaphore(&pChannel->pDoneSemaphore);
#else #else
pthread_kill(_gCdStreamThread, SIGUSR1);
while (pChannel->bLocked) while (pChannel->bLocked)
sem_wait(pChannel->pDoneSemaphore); sem_wait(pChannel->pDoneSemaphore);
#endif #endif
} }
#endif
pChannel->bReading = false; pChannel->bReading = false;
flushStream[channel] = false; flushStream[channel] = false;
return STREAM_NONE; return STREAM_NONE;
} }
#endif
if ( pChannel->nSectorsToRead != 0 ) if ( pChannel->nSectorsToRead != 0 )
{ {
@ -435,8 +442,11 @@ CdStreamSync(int32 channel)
#ifdef __WIIU__ #ifdef __WIIU__
OSWaitSemaphore(&pChannel->pDoneSemaphore); OSWaitSemaphore(&pChannel->pDoneSemaphore);
#else #else
while (pChannel->bLocked && pChannel->nSectorsToRead != 0){
sem_wait(pChannel->pDoneSemaphore); sem_wait(pChannel->pDoneSemaphore);
#endif }
#endif
pChannel->bLocked = false;
} }
pChannel->bReading = false; pChannel->bReading = false;
@ -492,7 +502,12 @@ void *CdStreamThread(void *param)
#else #else
sem_wait(gCdStreamSema); sem_wait(gCdStreamSema);
#endif #endif
int32 channel = GetFirstInQueue(&gChannelRequestQ); int32 channel = GetFirstInQueue(&gChannelRequestQ);
// spurious wakeup
if (channel == -1)
continue;
#else #else
int channel = *((int*)param); int channel = *((int*)param);
while (gpReadInfo[channel].nThreadStatus != 2){ while (gpReadInfo[channel].nThreadStatus != 2){
@ -633,7 +648,9 @@ void
CdStreamRemoveImages(void) CdStreamRemoveImages(void)
{ {
for ( int32 i = 0; i < gNumChannels; i++ ) { for ( int32 i = 0; i < gNumChannels; i++ ) {
#ifdef FLUSHABLE_STREAMING
flushStream[i] = 1; flushStream[i] = 1;
#endif
CdStreamSync(i); CdStreamSync(i);
} }

View File

@ -908,7 +908,7 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i)
uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
{ {
int32 c; uint32 c;
switch (color) { switch (color) {
case RADAR_TRACE_RED: case RADAR_TRACE_RED:
if (bright) if (bright)

View File

@ -202,11 +202,15 @@ CStreaming::Init2(void)
// allocate streaming buffers // allocate streaming buffers
if(ms_streamingBufferSize & 1) ms_streamingBufferSize++; if(ms_streamingBufferSize & 1) ms_streamingBufferSize++;
#ifndef ONE_THREAD_PER_CHANNEL
ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
ms_streamingBufferSize /= 2; ms_streamingBufferSize /= 2;
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
#ifdef ONE_THREAD_PER_CHANNEL #else
ms_pStreamingBuffer[2] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
ms_streamingBufferSize /= 2;
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
ms_pStreamingBuffer[2] = ms_pStreamingBuffer[1] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
#endif #endif
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
@ -1942,9 +1946,10 @@ CStreaming::LoadRequestedModels(void)
} }
// Let's load models first, then process it. Unfortunately processing models are still single-threaded. // Let's load models in 4 threads; when one of them becomes idle, process the file, and fill thread with another file. Unfortunately processing models are still single-threaded.
// Currently only supported on POSIX streamer. // Currently only supported on POSIX streamer.
#ifdef ONE_THREAD_PER_CHANNEL // WIP - some files are loaded swapped (CdStreamPosix problem?)
#if 0 //def ONE_THREAD_PER_CHANNEL
void void
CStreaming::LoadAllRequestedModels(bool priority) CStreaming::LoadAllRequestedModels(bool priority)
{ {
@ -1962,14 +1967,18 @@ CStreaming::LoadAllRequestedModels(bool priority)
int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)]; int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)];
int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)]; int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)];
int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)]; int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)];
bool first = true; int readOrder[4] = {-1}; // Channel IDs ordered by read time
int readI = 0;
int processI = 0; int processI = 0;
bool first = true;
// All those "first" checks are because of variables aren't initialized in first pass.
while (true) { while (true) {
// Enumerate files and start reading
for (int i=0; i<ARRAY_SIZE(ms_pStreamingBuffer); i++) { for (int i=0; i<ARRAY_SIZE(ms_pStreamingBuffer); i++) {
// Channel has file to load
if (!first && streamIds[i] != -1) { if (!first && streamIds[i] != -1) {
processI = i;
continue; continue;
} }
@ -1982,12 +1991,16 @@ CStreaming::LoadAllRequestedModels(bool priority)
if (ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)) { if (ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)) {
streamIds[i] = -1; streamIds[i] = -1;
// Big file, needs 2 buffer
if (size > (uint32)ms_streamingBufferSize) { if (size > (uint32)ms_streamingBufferSize) {
if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer)) if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer))
continue; break;
else if (!first && streamIds[i+1] != -1) else if (!first && streamIds[i+1] != -1)
continue; continue;
} else { } else {
// Buffer of current channel is part of a "big file", pass
if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize) if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize)
continue; continue;
} }
@ -1997,8 +2010,18 @@ CStreaming::LoadAllRequestedModels(bool priority)
streamIds[i] = streamId; streamIds[i] = streamId;
streamSizes[i] = size; streamSizes[i] = size;
streamPoses[i] = posn; streamPoses[i] = posn;
if (!first)
assert(readOrder[readI] == -1);
//printf("read: order %d, ch %d, id %d, size %d\n", readI, i, streamId, size);
CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size); CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size);
processI = i; readOrder[readI] = i;
if (first && readI+1 != ARRAY_SIZE(readOrder))
readOrder[readI+1] = -1;
readI = (readI + 1) % ARRAY_SIZE(readOrder);
} else { } else {
ms_aInfoForModel[streamId].RemoveFromList(); ms_aInfoForModel[streamId].RemoveFromList();
DecrementRef(streamId); DecrementRef(streamId);
@ -2006,33 +2029,40 @@ CStreaming::LoadAllRequestedModels(bool priority)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
streamIds[i] = -1; streamIds[i] = -1;
} }
} else } else {
streamIds[i] = -1; streamIds[i] = -1;
break;
}
} }
first = false; first = false;
int nextChannel = readOrder[processI];
// Now process // Now start processing
if (streamIds[processI] == -1) if (nextChannel == -1 || streamIds[nextChannel] == -1)
break; break;
//printf("process: order %d, ch %d, id %d\n", processI, nextChannel, streamIds[nextChannel]);
// Try again on error // Try again on error
while (CdStreamSync(processI) != STREAM_NONE) { while (CdStreamSync(nextChannel) != STREAM_NONE) {
CdStreamRead(processI, ms_pStreamingBuffer[processI], imgOffset+streamPoses[processI], streamSizes[processI]); CdStreamRead(nextChannel, ms_pStreamingBuffer[nextChannel], imgOffset+streamPoses[nextChannel], streamSizes[nextChannel]);
} }
ms_aInfoForModel[streamIds[processI]].m_loadState = STREAMSTATE_READING; ms_aInfoForModel[streamIds[nextChannel]].m_loadState = STREAMSTATE_READING;
MakeSpaceFor(streamSizes[processI] * CDSTREAM_SECTOR_SIZE); MakeSpaceFor(streamSizes[nextChannel] * CDSTREAM_SECTOR_SIZE);
ConvertBufferToObject(ms_pStreamingBuffer[processI], streamIds[processI]); ConvertBufferToObject(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]);
if(ms_aInfoForModel[streamIds[processI]].m_loadState == STREAMSTATE_STARTED) if(ms_aInfoForModel[streamIds[nextChannel]].m_loadState == STREAMSTATE_STARTED)
FinishLoadingLargeFile(ms_pStreamingBuffer[processI], streamIds[processI]); FinishLoadingLargeFile(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]);
if(streamIds[processI] < STREAM_OFFSET_TXD){ if(streamIds[nextChannel] < STREAM_OFFSET_TXD){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[processI]); CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[nextChannel]);
if(mi->IsSimple()) if(mi->IsSimple())
mi->m_alpha = 255; mi->m_alpha = 255;
} }
streamIds[processI] = -1; streamIds[nextChannel] = -1;
readOrder[processI] = -1;
processI = (processI + 1) % ARRAY_SIZE(readOrder);
} }
ms_bLoadingBigModel = false; ms_bLoadingBigModel = false;
@ -2128,7 +2158,7 @@ CStreaming::FlushRequestList(void)
next = si->m_next; next = si->m_next;
RemoveModel(si - ms_aInfoForModel); RemoveModel(si - ms_aInfoForModel);
} }
#ifndef _WIN32 #ifdef FLUSHABLE_STREAMING
if(ms_channel[0].state == CHANNELSTATE_READING) { if(ms_channel[0].state == CHANNELSTATE_READING) {
flushStream[0] = 1; flushStream[0] = 1;
} }

View File

@ -85,7 +85,11 @@ public:
static int32 ms_oldSectorX; static int32 ms_oldSectorX;
static int32 ms_oldSectorY; static int32 ms_oldSectorY;
static int32 ms_streamingBufferSize; static int32 ms_streamingBufferSize;
#ifndef ONE_THREAD_PER_CHANNEL
static int8 *ms_pStreamingBuffer[2]; static int8 *ms_pStreamingBuffer[2];
#else
static int8 *ms_pStreamingBuffer[4];
#endif
static size_t ms_memoryUsed; static size_t ms_memoryUsed;
static CStreamingChannel ms_channel[2]; static CStreamingChannel ms_channel[2];
static int32 ms_channelError; static int32 ms_channelError;

View File

@ -360,7 +360,7 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
} else if(e->bUsesCollision) } else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough)) ignoreSeeThrough))
entity = e; entity = e;
} }
@ -445,7 +445,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
e->m_scanCode = GetCurrentScanCode(); e->m_scanCode = GetCurrentScanCode();
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough, poly)) ignoreSeeThrough, poly))
entity = e; entity = e;
} }

View File

@ -897,66 +897,66 @@ CCullZone::PointFallsWithinZone(CVector pos, float radius)
CVector ExtraFudgePointsCoors[] = { CVector ExtraFudgePointsCoors[] = {
CVector(978.0, -394.0, 18.0), CVector(978.0f, -394.0f, 18.0f),
CVector(1189.7, -414.6, 27.0), CVector(1189.7f, -414.6f, 27.0f),
CVector(978.8, -391.0, 19.0), CVector(978.8f, -391.0f, 19.0f),
CVector(1199.0, -502.3, 28.0), CVector(1199.0f, -502.3f, 28.0f),
CVector(1037.0, -391.9, 18.4), CVector(1037.0f, -391.9f, 18.4f),
CVector(1140.0, -608.7, 16.0), CVector(1140.0f, -608.7f, 16.0f),
CVector(1051.0, -26.0, 11.0), CVector(1051.0f, -26.0f, 11.0f),
CVector(951.5, -345.1, 12.0), CVector(951.5f, -345.1f, 12.0f),
CVector(958.2, -394.6, 16.0), CVector(958.2f, -394.6f, 16.0f),
CVector(1036.5, -390.0, 15.2), CVector(1036.5f, -390.0f, 15.2f),
CVector(960.6, -390.5, 20.9), CVector(960.6f, -390.5f, 20.9f),
CVector(1061.0, -640.6, 16.3), CVector(1061.0f, -640.6f, 16.3f),
CVector(1034.5, -388.96, 14.78), CVector(1034.5f, -388.96f, 14.78f),
CVector(1038.4, -13.98, 12.2), CVector(1038.4f, -13.98f, 12.2f),
CVector(1047.2, -16.7, 10.6), CVector(1047.2f, -16.7f, 10.6f),
CVector(1257.9, -333.3, 40.0), CVector(1257.9f, -333.3f, 40.0f),
CVector(885.6, -424.9, 17.0), CVector(885.6f, -424.9f, 17.0f),
CVector(1127.5, -795.8, 17.7), CVector(1127.5f, -795.8f, 17.7f),
CVector(1133.0, -716.0, 19.0), CVector(1133.0f, -716.0f, 19.0f),
CVector(1125.0, -694.0, 18.5), CVector(1125.0f, -694.0f, 18.5f),
CVector(1125.0, -670.0, 16.3), CVector(1125.0f, -670.0f, 16.3f),
CVector(1051.6, 36.3, 17.9), CVector(1051.6f, 36.3f, 17.9f),
CVector(1054.6, -11.4, 15.0), CVector(1054.6f, -11.4f, 15.0f),
CVector(1058.9, -278.0, 15.0), CVector(1058.9f, -278.0f, 15.0f),
CVector(1059.4, -261.0, 10.9), CVector(1059.4f, -261.0f, 10.9f),
CVector(1051.5, -638.5, 16.5), CVector(1051.5f, -638.5f, 16.5f),
CVector(1058.2, -643.4, 15.5), CVector(1058.2f, -643.4f, 15.5f),
CVector(1058.2, -643.4, 18.0), CVector(1058.2f, -643.4f, 18.0f),
CVector(826.0, -260.0, 7.0), CVector(826.0f, -260.0f, 7.0f),
CVector(826.0, -260.0, 11.0), CVector(826.0f, -260.0f, 11.0f),
CVector(833.0, -603.6, 16.4), CVector(833.0f, -603.6f, 16.4f),
CVector(833.0, -603.6, 20.0), CVector(833.0f, -603.6f, 20.0f),
CVector(1002.0, -318.5, 10.5), CVector(1002.0f, -318.5f, 10.5f),
CVector(998.0, -318.0, 9.8), CVector(998.0f, -318.0f, 9.8f),
CVector(1127.0, -183.0, 18.1), CVector(1127.0f, -183.0f, 18.1f),
CVector(1123.0, -331.5, 23.8), CVector(1123.0f, -331.5f, 23.8f),
CVector(1123.8, -429.0, 24.0), CVector(1123.8f, -429.0f, 24.0f),
CVector(1197.0, -30.0, 13.7), CVector(1197.0f, -30.0f, 13.7f),
CVector(1117.5, -230.0, 17.3), CVector(1117.5f, -230.0f, 17.3f),
CVector(1117.5, -230.0, 20.0), CVector(1117.5f, -230.0f, 20.0f),
CVector(1120.0, -281.6, 21.5), CVector(1120.0f, -281.6f, 21.5f),
CVector(1120.0, -281.6, 24.0), CVector(1120.0f, -281.6f, 24.0f),
CVector(1084.5, -1022.7, 17.0), CVector(1084.5f, -1022.7f, 17.0f),
CVector(1071.5, 5.4, 4.6), CVector(1071.5f, 5.4f, 4.6f),
CVector(1177.2, -215.7, 27.6), CVector(1177.2f, -215.7f, 27.6f),
CVector(841.6, -460.0, 19.7), CVector(841.6f, -460.0f, 19.7f),
CVector(874.8, -456.6, 16.6), CVector(874.8f, -456.6f, 16.6f),
CVector(918.3, -451.8, 17.8), CVector(918.3f, -451.8f, 17.8f),
CVector(844.0, -495.7, 16.7), CVector(844.0f, -495.7f, 16.7f),
CVector(842.0, -493.4, 21.0), CVector(842.0f, -493.4f, 21.0f),
CVector(1433.5, -774.4, 16.9), CVector(1433.5f, -774.4f, 16.9f),
CVector(1051.0, -205.0, 7.5), CVector(1051.0f, -205.0f, 7.5f),
CVector(885.5, -425.6, 15.6), CVector(885.5f, -425.6f, 15.6f),
CVector(182.6, -470.4, 27.8), CVector(182.6f, -470.4f, 27.8f),
CVector(132.5, -930.2, 29.0), CVector(132.5f, -930.2f, 29.0f),
CVector(124.7, -904.0, 28.0), CVector(124.7f, -904.0f, 28.0f),
CVector(-50.0, -686.0, 22.0), CVector(-50.0f, -686.0f, 22.0f),
CVector(-49.1, -694.5, 22.5), CVector(-49.1f, -694.5f, 22.5f),
CVector(1063.8, -404.45, 16.2), CVector(1063.8f, -404.45f, 16.2f),
CVector(1062.2, -405.5, 17.0) CVector(1062.2f, -405.5f, 17.0f)
}; };
int32 NumTestPoints; int32 NumTestPoints;
int32 aTestPointsX[100]; int32 aTestPointsX[100];

View File

@ -396,8 +396,13 @@ enum Config {
#endif #endif
#endif #endif
// IMG
#define BIG_IMG // allows to read larger img files // Streaming
#if !defined(_WIN32) && !defined(__SWITCH__)
//#define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash - also not utilized too much right now(see commented LoadAllRequestedModels in Streaming.cpp)
#define FLUSHABLE_STREAMING // Make it possible to interrupt reading when processing file isn't needed anymore.
#endif
#define BIG_IMG // Not complete - allows to read larger img files
//#define SQUEEZE_PERFORMANCE //#define SQUEEZE_PERFORMANCE
#ifdef SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE
@ -417,6 +422,7 @@ enum Config {
#define IO_BUFFER_SIZE (128*1024) #define IO_BUFFER_SIZE (128*1024)
#define INI_BUFFER_SIZE (8*1024) // 8k should be enough for the ini file #define INI_BUFFER_SIZE (8*1024) // 8k should be enough for the ini file
#endif #endif
// -------
#if defined __MWERKS__ || defined VANILLA_DEFINES #if defined __MWERKS__ || defined VANILLA_DEFINES
#define FINAL #define FINAL

View File

@ -201,6 +201,9 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
if(!RsCameraBeginUpdate(Scene.camera)) if(!RsCameraBeginUpdate(Scene.camera))
return false; return false;
#ifdef FIX_BUGS
CSprite2d::SetRecipNearClip();
#endif
CSprite2d::InitPerFrame(); CSprite2d::InitPerFrame();
if(Alpha != 0) if(Alpha != 0)
@ -1107,8 +1110,13 @@ DisplayGameDebugText()
#endif // #ifdef DRAW_GAME_VERSION_TEXT #endif // #ifdef DRAW_GAME_VERSION_TEXT
FrameSamples++; FrameSamples++;
#ifdef FIX_BUGS
FramesPerSecondCounter += frameTime / 1000.f; // convert to seconds
FramesPerSecond = FrameSamples / FramesPerSecondCounter;
#else
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f); FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
FramesPerSecond = FramesPerSecondCounter / FrameSamples; FramesPerSecond = FramesPerSecondCounter / FrameSamples;
#endif
if ( FrameSamples > 30 ) if ( FrameSamples > 30 )
{ {

View File

@ -400,6 +400,9 @@ bool LoadINISettings()
ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult); ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult);
ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult); ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult);
#endif #endif
#ifdef NEW_RENDERER
ReadIniIfExists("Rendering", "NewRenderer", &gbNewRenderer);
#endif
#ifdef PROPER_SCALING #ifdef PROPER_SCALING
ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling); ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling);
@ -483,6 +486,9 @@ void SaveINISettings()
StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
#endif #endif
#ifdef NEW_RENDERER
StoreIni("Rendering", "NewRenderer", gbNewRenderer);
#endif
#ifdef PROPER_SCALING #ifdef PROPER_SCALING
StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling); StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling);

View File

@ -332,7 +332,12 @@ glossRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos; V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
glUniform3fv(U(u_eye), 1, (float*)&eyePos); glUniform3fv(U(u_eye), 1, (float*)&eyePos);
glUniform4fv(U(u_reflProps), 1, (float*)&GlossMult); float reflProps[4];
reflProps[0] = GlossMult;
reflProps[1] = 0.0f;
reflProps[2] = 0.0f;
reflProps[3] = 0.0f;
glUniform4fv(U(u_reflProps), 1, reflProps);
SetRenderState(VERTEXALPHA, TRUE); SetRenderState(VERTEXALPHA, TRUE);
SetRenderState(SRCBLEND, BLENDONE); SetRenderState(SRCBLEND, BLENDONE);

View File

@ -1545,7 +1545,7 @@ CPed::ProcessBuoyancy(void)
CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f), CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f),
((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f), ((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f),
((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f), ((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f),
(CGeneral::GetRandomNumber() % 256 * 48.0f) + 48); CGeneral::GetRandomNumberInRange(48.0f, 96.0f));
if (bInVehicle) if (bInVehicle)
return; return;

View File

@ -1,6 +1,7 @@
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4005) #pragma warning( disable : 4005)
#pragma warning( pop ) #pragma warning( pop )
#define FORCE_PC_SCALING
#include "common.h" #include "common.h"
#ifdef ANISOTROPIC_FILTERING #ifdef ANISOTROPIC_FILTERING
#include "rpanisot.h" #include "rpanisot.h"

View File

@ -49,8 +49,8 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char *folder = strtok(pathCopy, "*"); char *folder = strtok(pathCopy, "*");
char *extension = strtok(NULL, "*"); char *extension = strtok(NULL, "*");
// because strtok doesn't return NULL for last delimiter // because I remember like strtok might not return NULL for last delimiter
if (extension - folder == strlen(pathname)) if (extension && extension - folder == strlen(pathname))
extension = nil; extension = nil;
// Case-sensitivity and backslashes... // Case-sensitivity and backslashes...
@ -226,7 +226,7 @@ char* casepath(char const* path, bool checkPathFirst)
rl = 1; rl = 1;
} }
bool cantProceed = false; // just convert slashes in what's left in string, not case sensitivity bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't)
bool mayBeTrailingSlash = false; bool mayBeTrailingSlash = false;
char* c; char* c;
while (c = strsep(&p, "/\\")) while (c = strsep(&p, "/\\"))
@ -290,7 +290,7 @@ char* casepath(char const* path, bool checkPathFirst)
} }
if (rl > l + 2) { if (rl > l + 2) {
debug("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%d chars)\n\tCorrected: %s (%d chars)\n\n", path, l, out, rl); debug("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%zu chars)\n\tCorrected: %s (%zu chars)\n\n", path, l, out, rl);
} }
return out; return out;
} }

View File

@ -1239,10 +1239,11 @@ void terminateHandler(int sig, siginfo_t *info, void *ucontext) {
RsGlobal.quit = TRUE; RsGlobal.quit = TRUE;
} }
#ifdef FLUSHABLE_STREAMING
void dummyHandler(int sig){ void dummyHandler(int sig){
// Don't kill the app pls // Don't kill the app pls
} }
#endif
#endif #endif
void resizeCB(GLFWwindow* window, int width, int height) { void resizeCB(GLFWwindow* window, int width, int height) {
@ -1415,7 +1416,7 @@ bool rshiftStatus = false;
void void
keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods) keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
if (key >= 0 && key <= GLFW_KEY_LAST) { if (key >= 0 && key <= GLFW_KEY_LAST && action != GLFW_REPEAT) {
RsKeyCodes ks = (RsKeyCodes)keymap[key]; RsKeyCodes ks = (RsKeyCodes)keymap[key];
if (key == GLFW_KEY_LEFT_SHIFT) if (key == GLFW_KEY_LEFT_SHIFT)
@ -1426,7 +1427,6 @@ keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
if (action == GLFW_RELEASE) RsKeyboardEventHandler(rsKEYUP, &ks); if (action == GLFW_RELEASE) RsKeyboardEventHandler(rsKEYUP, &ks);
else if (action == GLFW_PRESS) RsKeyboardEventHandler(rsKEYDOWN, &ks); else if (action == GLFW_PRESS) RsKeyboardEventHandler(rsKEYDOWN, &ks);
else if (action == GLFW_REPEAT) RsKeyboardEventHandler(rsKEYDOWN, &ks);
} }
} }
@ -1496,11 +1496,13 @@ main(int argc, char *argv[])
act.sa_sigaction = terminateHandler; act.sa_sigaction = terminateHandler;
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL); sigaction(SIGTERM, &act, NULL);
#ifdef FLUSHABLE_STREAMING
struct sigaction sa; struct sigaction sa;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_handler = dummyHandler; sa.sa_handler = dummyHandler;
sa.sa_flags = 0; sa.sa_flags = 0;
sigaction(SIGUSR1, &sa, NULL); // Needed for CdStreamPosix sigaction(SIGUSR1, &sa, NULL);
#endif
#endif #endif
/* /*
@ -2067,22 +2069,30 @@ void CapturePad(RwInt32 padID)
const float *axes = glfwGetJoystickAxes(glfwPad, &numAxes); const float *axes = glfwGetJoystickAxes(glfwPad, &numAxes);
GLFWgamepadstate gamepadState; GLFWgamepadstate gamepadState;
if (ControlsManager.m_bFirstCapture == false) if (ControlsManager.m_bFirstCapture == false) {
{
memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState)); memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
} else {
// In case connected gamepad doesn't have L-R trigger axes.
ControlsManager.m_NewState.mappedButtons[15] = ControlsManager.m_NewState.mappedButtons[16] = 0;
} }
ControlsManager.m_NewState.buttons = (uint8*)buttons; ControlsManager.m_NewState.buttons = (uint8*)buttons;
ControlsManager.m_NewState.numButtons = numButtons; ControlsManager.m_NewState.numButtons = numButtons;
ControlsManager.m_NewState.id = glfwPad; ControlsManager.m_NewState.id = glfwPad;
ControlsManager.m_NewState.isGamepad = glfwJoystickIsGamepad(glfwPad); ControlsManager.m_NewState.isGamepad = glfwGetGamepadState(glfwPad, &gamepadState);
if (ControlsManager.m_NewState.isGamepad) { if (ControlsManager.m_NewState.isGamepad) {
glfwGetGamepadState(glfwPad, &gamepadState);
memcpy(&ControlsManager.m_NewState.mappedButtons, gamepadState.buttons, sizeof(gamepadState.buttons)); memcpy(&ControlsManager.m_NewState.mappedButtons, gamepadState.buttons, sizeof(gamepadState.buttons));
ControlsManager.m_NewState.mappedButtons[15] = gamepadState.axes[4] > -0.8f; float lt = gamepadState.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER], rt = gamepadState.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER];
ControlsManager.m_NewState.mappedButtons[16] = gamepadState.axes[5] > -0.8f;
// glfw returns 0.0 for non-existent axises(which is bullocks) so we treat it as deadzone, and keep value of previous frame.
// otherwise if this axis is present, -1 = released, 1 = pressed
if (lt != 0.0f)
ControlsManager.m_NewState.mappedButtons[15] = lt > -0.8f;
if (rt != 0.0f)
ControlsManager.m_NewState.mappedButtons[16] = rt > -0.8f;
} }
// TODO I'm not sure how to find/what to do with L2-R2, if joystick isn't registered in SDL database. // TODO? L2-R2 axes(not buttons-that's fine) on joysticks that don't have SDL gamepad mapping AREN'T handled, and I think it's impossible to do without mapping.
if (ControlsManager.m_bFirstCapture == true) { if (ControlsManager.m_bFirstCapture == true) {
memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState)); memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
@ -2096,12 +2106,13 @@ void CapturePad(RwInt32 padID)
RsPadEventHandler(rsPADBUTTONUP, (void *)&bs); RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
// Gamepad axes are guaranteed to return 0.0f if that particular gamepad doesn't have that axis. // Gamepad axes are guaranteed to return 0.0f if that particular gamepad doesn't have that axis.
// And that's really good for sticks, because gamepads return 0.0 for them when sticks are in released state.
if ( glfwPad != -1 ) { if ( glfwPad != -1 ) {
leftStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[0] : numAxes >= 1 ? axes[0] : 0.0f; leftStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[GLFW_GAMEPAD_AXIS_LEFT_X] : numAxes >= 1 ? axes[0] : 0.0f;
leftStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[1] : numAxes >= 2 ? axes[1] : 0.0f; leftStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[GLFW_GAMEPAD_AXIS_LEFT_Y] : numAxes >= 2 ? axes[1] : 0.0f;
rightStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[2] : numAxes >= 3 ? axes[2] : 0.0f; rightStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[GLFW_GAMEPAD_AXIS_RIGHT_X] : numAxes >= 3 ? axes[2] : 0.0f;
rightStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[3] : numAxes >= 4 ? axes[3] : 0.0f; rightStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y] : numAxes >= 4 ? axes[3] : 0.0f;
} }
{ {

View File

@ -6188,7 +6188,7 @@ Those Colombians'll be here any minute!
Goddam they're here!! LOCK'N'LOAD!! Goddam they're here!! LOCK'N'LOAD!!
[LOVE2_7] [LOVE2_7]
~g~ Now dump the car! ~g~Now dump the car!
[LOVE2_8] [LOVE2_8]
~g~Now get out of Newport! ~g~Now get out of Newport!

View File

@ -6290,7 +6290,7 @@ Those Colombians'll be here any minute!
Goddam they're here!! LOCK'N'LOAD!! Goddam they're here!! LOCK'N'LOAD!!
[LOVE2_7] [LOVE2_7]
~g~ Now dump the car! ~g~Now dump the car!
[LOVE2_8] [LOVE2_8]
~g~Now get out of Newport! ~g~Now get out of Newport!

View File

@ -3653,7 +3653,7 @@ Port 1 Fichier Protégé.
~1~ sur 12! ~1~ sur 12!
[T4X4_2C] [T4X4_2C]
~y~ Passe le premier point de passage pour déclencher le chrono. ~y~ Chaque point de passage te rapportera ~y~10 secondes~g~. ~y~Passe le premier point de passage pour déclencher le chrono. ~y~ Chaque point de passage te rapportera ~y~10 secondes~g~.
[T4X4_3A] [T4X4_3A]
~g~Tu as ~y~5 minutes~g~ pour franchir ~y~20~g~ points de passage. ~g~Tu peux les franchir dans ~y~n'importe quel ordre. ~g~Tu as ~y~5 minutes~g~ pour franchir ~y~20~g~ points de passage. ~g~Tu peux les franchir dans ~y~n'importe quel ordre.
@ -5045,7 +5045,7 @@ Tu as prouvé que tu étais un bon investissement, ce qui est rare en ces jours
~w~Merci Chico. A plus tard. ~w~Merci Chico. A plus tard.
[FM1_W] [FM1_W]
. ~w~Ok Fido, tu attends ici et tu surveilles la caisse pendant que je vais m'éclater. ~w~Ok Fido, tu attends ici et tu surveilles la caisse pendant que je vais m'éclater.
[FM1_X] [FM1_X]
~w~Ok Fido, tirons-nous d'ici. Ouuulaa! ~w~Ok Fido, tirons-nous d'ici. Ouuulaa!

View File

@ -2084,7 +2084,7 @@ Die Yakuza werden das als Kriegserklãrung des Kartells auffassen.
~r~Die Yakuza haben dich erkannt! ~r~Die Yakuza haben dich erkannt!
[LOVE2_6] [LOVE2_6]
~r~ Du hast alle Zeugen aus dem Weg gerãumt!! ~r~Du hast alle Zeugen aus dem Weg gerãumt!!
[LOVE3_A] [LOVE3_A]
In scheinheiligen Zeiten wie diesen sind bestimmte wertvolle Waren schwer zu importieren. In scheinheiligen Zeiten wie diesen sind bestimmte wertvolle Waren schwer zu importieren.
@ -3245,7 +3245,7 @@ Wollen sehen, ob du so gut bist, wie du sagst.
~w~Hepburn Heights. Knöpf dir ein paar Diablos vor. ~w~Hepburn Heights. Knöpf dir ein paar Diablos vor.
[YD2_G2] [YD2_G2]
~w~ Aber denk dran, ~r~du steigst nicht aus dem Wagen!! ~w~Aber denk dran, ~r~du steigst nicht aus dem Wagen!!
[YD2_H] [YD2_H]
~w~Okay, fahr uns zurück auf Yardie-Gebiet! LOS, LOS, LOS!! ~w~Okay, fahr uns zurück auf Yardie-Gebiet! LOS, LOS, LOS!!
@ -5054,7 +5054,7 @@ Und stiehl ein paar Sachen, damit ich die Versicherung kassieren kann.
~w~Ah, mein Junge! ~w~Ah, mein Junge!
[TM3_N2] [TM3_N2]
~w~ Hallo, Paps. ~w~Hallo, Paps.
[TM3_O] [TM3_O]
~w~Hast du endlich eine Frau gefunden? ~w~Hast du endlich eine Frau gefunden?
@ -5198,13 +5198,13 @@ Du bist eine sichere Bank. So etwas ist selten in diesen schlechten Zeiten.
~w~Okay, Fiffi, lass uns 'nen Abgang machen. Huuh! ~w~Okay, Fiffi, lass uns 'nen Abgang machen. Huuh!
[FM1_Q] [FM1_Q]
~w~ Hey, Maria! Meine Traumfrau! ~w~Hey, Maria! Meine Traumfrau!
[FM1_S1] [FM1_S1]
~w~Vielleicht solltest du mal die Party in der Lagerhalle am Ostende von Atlantic Quays auschecken. ~w~Vielleicht solltest du mal die Party in der Lagerhalle am Ostende von Atlantic Quays auschecken.
[FM1_U] [FM1_U]
~w~ Gracias. Und viel Spaß. Ist gutes Zeug. ~w~Gracias. Und viel Spaß. Ist gutes Zeug.
[FM1_V] [FM1_V]
~w~Na los, Fiffi, sehen wir uns mal die Party an! ~w~Na los, Fiffi, sehen wir uns mal die Party an!
@ -6263,7 +6263,7 @@ Die Kolumbianer müssen jeden Moment hier sein!
Verdammt, da sind sie!! LOS, LADEN!! Verdammt, da sind sie!! LOS, LADEN!!
[LOVE2_7] [LOVE2_7]
~g~ Jetzt lass den Wagen stehen! ~g~Jetzt lass den Wagen stehen!
[LOVE2_8] [LOVE2_8]
~g~Jetzt verschwinde aus Newport! ~g~Jetzt verschwinde aus Newport!

View File

@ -1373,7 +1373,7 @@ Y si nos está vendiendo..., mátalo.
Aquí viene nuestro amiguito. El señor Bocón en persona. Aquí viene nuestro amiguito. El señor Bocón en persona.
[FM2_G] [FM2_G]
¿Te han seguido? Ya sabes que esto es nuestro secretito. ¿Te siguieron? Ya sabes que esto es nuestro secretito.
[FM2_H] [FM2_H]
No, no, no me han seguido. ¿Tienes lo mío? No, no, no me han seguido. ¿Tienes lo mío?
@ -8081,10 +8081,10 @@ REPETIR MISIÓN
¿REINTENTAR? ¿REINTENTAR?
[FED_VPL] [FED_VPL]
FLUJO DE VEHÍCULOS RENDERIZADO DE VEHÍCULOS
[FED_PRM] [FED_PRM]
LUCES EN PEATONES ILUMINAR CONTORNOS DE PEATONES
[FED_RGL] [FED_RGL]
BRILLO DE CARRETERAS BRILLO DE CARRETERAS
@ -8096,7 +8096,7 @@ FILTRO DE COLOR
MAPAS DE LUZ DEL MUNDO MAPAS DE LUZ DEL MUNDO
[FED_MBL] [FED_MBL]
DESENFOQ. MOVIMIENTO DESENFOQUE DE MOVIMIENTO
[FEM_SIM] [FEM_SIM]
SIMPLE SIMPLE
@ -8122,6 +8122,9 @@ XBOX
[FEC_IVP] [FEC_IVP]
INVERTIR VERTICALIDAD MANDO INVERTIR VERTICALIDAD MANDO
[FEM_TWP]
Poner o quitar punto de referencia
{ end of file } { end of file }
[DUMMY] [DUMMY]