Merge remote-tracking branch 'origin/master' into miami

# Conflicts:
#	premake5.lua
#	src/core/ZoneCull.cpp
#	src/core/Zones.cpp
#	src/objects/CutsceneHead.cpp
#	src/render/Clouds.cpp
This commit is contained in:
Sergeanur 2020-05-13 00:19:21 +03:00
commit 33dfaf7da1
56 changed files with 1418 additions and 385 deletions

View File

@ -19,12 +19,20 @@ 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.
## Preparing the environment for building
Currently only building on VS2015/2017/2019 (Windows) and GCC (Linux) is tested.
- Clone the repo.
- Run `git submodule init` and `git submodule update`.
- Point GTA_III_RE_DIR environment variable to GTA3 root folder.
- Run premake
- On Windows: one of the `premake-vsXXXX.cmd` variants on root folder
- On Linux: proceed to [Building on Linux](https://github.com/GTAmodding/re3/wiki/Building-on-Linux).
- There are various settings at the very bottom of [config.h](https://github.com/GTAmodding/re3/tree/master/src/core/config.h), you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
> :information_source: **Rendering engine** re3 uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of re3, but you also can use LIBRW enviorenment variable to specify path to your own librw. > :information_source: **Rendering engine** re3 uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of re3, but you also can use LIBRW enviorenment variable to specify path to your own librw.
> :warning: **Notice for builders** There are various settings at the very bottom of `config.h`, you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
https://github.com/GTAmodding/re3/tree/master/src/core/config.h
## Contributing ## Contributing
### Unreversed / incomplete classes (at least the ones we know) ### Unreversed / incomplete classes (at least the ones we know)
@ -141,11 +149,3 @@ but here are some observations:
* do *not* use `dw` for `DWORD` or so, we're not programming win32 * do *not* use `dw` for `DWORD` or so, we're not programming win32
* Generally, try to make the code look as if R* could have written it * Generally, try to make the code look as if R* could have written it
### Environment Variables
Here you can find a list of variables that you might need to set in windows:
```
"GTA_III_RE_DIR" * path to "gta3_re" game folder usually where this plugin run.
"GTA_III_DIR" * path to "GTAIII" game folder.
"LIBRW" * path to LIBRW.
```

View File

@ -50,7 +50,12 @@ extern "C" {
#else // OPENAL #else // OPENAL
#ifndef _WIN32
#include <AL/al.h>
#include <string.h>
#else
#include <al.h> #include <al.h>
#endif
#ifndef GUID_DEFINED #ifndef GUID_DEFINED
#define GUID_DEFINED #define GUID_DEFINED

View File

@ -29,6 +29,7 @@ workspace "reVC"
location "build" location "build"
symbols "Full" symbols "Full"
staticruntime "off" staticruntime "off"
filter { "system:windows" } filter { "system:windows" }
platforms { platforms {
"win-x86-RW33_d3d8-mss", "win-x86-RW33_d3d8-mss",
@ -36,6 +37,11 @@ workspace "reVC"
"win-x86-librw_gl3_glfw-mss", "win-x86-librw_gl3_glfw-mss",
} }
filter { "system:linux" }
platforms {
"linux-x86-librw_gl3_glfw-oal",
}
filter "configurations:Debug" filter "configurations:Debug"
defines { "DEBUG" } defines { "DEBUG" }
@ -46,6 +52,9 @@ workspace "reVC"
filter { "platforms:win*" } filter { "platforms:win*" }
system "windows" system "windows"
filter { "platforms:linux*" }
system "linux"
filter { "platforms:*x86*" } filter { "platforms:*x86*" }
architecture "x86" architecture "x86"
@ -57,33 +66,32 @@ workspace "reVC"
filter "platforms:*librw_gl3_glfw*" filter "platforms:*librw_gl3_glfw*"
defines { "RW_GL3" } defines { "RW_GL3" }
includedirs { path.join(_OPTIONS["glfwdir"], "include") }
includedirs { path.join(_OPTIONS["glewdir"], "include") }
filter "platforms:win*librw_gl3_glfw*"
defines { "GLEW_STATIC" }
if(not _OPTIONS["with-librw"]) then if(not _OPTIONS["with-librw"]) then
libdirs { path.join(Librw, "lib/win-x86-gl3/%{cfg.buildcfg}") } libdirs { path.join(Librw, "lib/win-x86-gl3/%{cfg.buildcfg}") }
end end
defines { "GLEW_STATIC" }
includedirs { path.join(_OPTIONS["glfwdir"], "include") }
includedirs { path.join(_OPTIONS["glewdir"], "include") }
filter {}
pbcommands = { filter "platforms:linux*librw_gl3_glfw*"
"setlocal EnableDelayedExpansion", if(not _OPTIONS["with-librw"]) then
"set file=$(TargetPath)", libdirs { path.join(Librw, "lib/linux-x86-gl3/%{cfg.buildcfg}") }
"FOR %%i IN (\"%file%\") DO (", end
"set filename=%%~ni",
"set fileextension=%%~xi", filter {}
"set target=!path!!filename!!fileextension!",
"copy /y \"!file!\" \"!target!\"",
")" }
function setpaths (gamepath, exepath, scriptspath) function setpaths (gamepath, exepath, scriptspath)
scriptspath = scriptspath or "" scriptspath = scriptspath or ""
if (gamepath) then if (gamepath) then
cmdcopy = { "set \"path=" .. gamepath .. scriptspath .. "\"" } postbuildcommands {
table.insert(cmdcopy, pbcommands) '{COPY} "%{cfg.buildtarget.abspath}" "' .. gamepath .. scriptspath .. '%{cfg.buildtarget.name}"'
postbuildcommands (cmdcopy) }
debugdir (gamepath) debugdir (gamepath)
if (exepath) then if (exepath) then
debugcommand (gamepath .. exepath) -- Used VS variable $(TargetFileName) because it doesn't accept premake tokens. Does debugcommand even work outside VS??
debugcommand (gamepath .. "$(TargetFileName)")
dir, file = exepath:match'(.*/)(.*)' dir, file = exepath:match'(.*/)(.*)'
debugdir (gamepath .. (dir or "")) debugdir (gamepath .. (dir or ""))
end end
@ -111,17 +119,12 @@ project "reVC"
kind "WindowedApp" kind "WindowedApp"
targetname "reVC" targetname "reVC"
targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}" targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
targetextension ".exe"
characterset ("MBCS")
linkoptions "/SAFESEH:NO"
defines { "MIAMI" } defines { "MIAMI" }
files { addSrcFiles("src") } files { addSrcFiles("src") }
files { addSrcFiles("src/animation") } files { addSrcFiles("src/animation") }
files { addSrcFiles("src/audio") } files { addSrcFiles("src/audio") }
--files { addSrcFiles("src/audio/miles") } files { addSrcFiles("src/audio/oal") }
--files { addSrcFiles("src/audio/openal") }
files { addSrcFiles("src/control") } files { addSrcFiles("src/control") }
files { addSrcFiles("src/core") } files { addSrcFiles("src/core") }
files { addSrcFiles("src/entities") } files { addSrcFiles("src/entities") }
@ -133,7 +136,6 @@ project "reVC"
files { addSrcFiles("src/rw") } files { addSrcFiles("src/rw") }
files { addSrcFiles("src/save") } files { addSrcFiles("src/save") }
files { addSrcFiles("src/skel") } files { addSrcFiles("src/skel") }
files { addSrcFiles("src/skel/win") }
files { addSrcFiles("src/skel/glfw") } files { addSrcFiles("src/skel/glfw") }
files { addSrcFiles("src/text") } files { addSrcFiles("src/text") }
files { addSrcFiles("src/vehicles") } files { addSrcFiles("src/vehicles") }
@ -144,6 +146,7 @@ project "reVC"
includedirs { "src" } includedirs { "src" }
includedirs { "src/animation" } includedirs { "src/animation" }
includedirs { "src/audio" } includedirs { "src/audio" }
includedirs { "src/audio/oal" }
includedirs { "src/control" } includedirs { "src/control" }
includedirs { "src/core" } includedirs { "src/core" }
includedirs { "src/entities" } includedirs { "src/entities" }
@ -155,7 +158,6 @@ project "reVC"
includedirs { "src/rw" } includedirs { "src/rw" }
includedirs { "src/save/" } includedirs { "src/save/" }
includedirs { "src/skel/" } includedirs { "src/skel/" }
includedirs { "src/skel/win" }
includedirs { "src/skel/glfw" } includedirs { "src/skel/glfw" }
includedirs { "src/text" } includedirs { "src/text" }
includedirs { "src/vehicles" } includedirs { "src/vehicles" }
@ -168,7 +170,21 @@ project "reVC"
libdirs { "milessdk/lib" } libdirs { "milessdk/lib" }
setpaths("$(GTA_VC_RE_DIR)/", "$(TargetFileName)", "") if(os.getenv("GTA_VC_RE_DIR")) then
setpaths("$(GTA_VC_RE_DIR)/", "%(cfg.buildtarget.name)", "")
end
filter "platforms:win*"
files { addSrcFiles("src/skel/win") }
includedirs { "src/skel/win" }
linkoptions "/SAFESEH:NO"
characterset ("MBCS")
targetextension ".exe"
filter "platforms:linux*"
targetextension ".elf"
defines { "OPENAL" }
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:*RW33*" filter "platforms:*RW33*"
staticruntime "on" staticruntime "on"
@ -195,7 +211,10 @@ project "reVC"
filter "platforms:*d3d9*" filter "platforms:*d3d9*"
links { "d3d9" } links { "d3d9" }
filter "platforms:*gl3_glfw*" filter "platforms:win*gl3_glfw*"
libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") } libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") }
libdirs { path.join(_OPTIONS["glfwdir"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) } libdirs { path.join(_OPTIONS["glfwdir"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
links { "opengl32", "glew32s", "glfw3" } links { "opengl32", "glew32s", "glfw3" }
filter "platforms:linux*gl3_glfw*"
links { "GL", "GLEW", "glfw" }

BIN
premake5Linux Executable file

Binary file not shown.

View File

@ -1,6 +1,10 @@
#include "common.h" #include "common.h"
#if defined _WIN32 && !defined __MINGW32__
#include "ctype.h" #include "ctype.h"
#else
#include <cwctype>
#endif
#include "General.h" #include "General.h"
#include "RwHelper.h" #include "RwHelper.h"

View File

@ -102,7 +102,7 @@ const struct {
{ "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 }, { "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 },
{ "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 }, { "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 },
{ "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 }, { "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 },
{ NULL, NULL } { NULL, 0 }
}; };
int int

View File

@ -6,6 +6,7 @@
#include "AudioScriptObject.h" #include "AudioScriptObject.h"
#include "sampman.h" #include "sampman.h"
#include "Text.h" #include "Text.h"
#include "crossplatform.h"
cDMAudio DMAudio; cDMAudio DMAudio;

View File

@ -23,6 +23,12 @@
*/ */
#include "aldlist.h" #include "aldlist.h"
#ifndef _WIN32
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#endif
#ifdef AUDIO_OAL #ifdef AUDIO_OAL
/* /*
* Init call * Init call
@ -67,7 +73,7 @@ ALDeviceList::ALDeviceList()
if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) { if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO)); memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
ALDeviceInfo.bSelected = true; ALDeviceInfo.bSelected = true;
ALDeviceInfo.strDeviceName = std::string(actualDeviceName, strlen(actualDeviceName)); ALDeviceInfo.strDeviceName.assign(actualDeviceName, strlen(actualDeviceName));
alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion); alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion); alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);

View File

@ -4,6 +4,10 @@
#include "common.h" #include "common.h"
#include "sampman.h" #include "sampman.h"
#ifndef _WIN32
#include <float.h>
#endif
extern bool IsFXSupported(); extern bool IsFXSupported();
CChannel::CChannel() CChannel::CChannel()

View File

@ -4,13 +4,15 @@
#include "common.h" #include "common.h"
#include "sampman.h" #include "sampman.h"
typedef long ssize_t;
#include <sndfile.h> #include <sndfile.h>
#include <mpg123.h> #include <mpg123.h>
#ifdef _WIN32
typedef long ssize_t;
#pragma comment( lib, "libsndfile-1.lib" ) #pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123.lib" ) #pragma comment( lib, "libmpg123.lib" )
#else
#include "crossplatform.h"
#endif
class CSndFile : public IDecoder class CSndFile : public IDecoder
{ {
@ -192,7 +194,22 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
m_nPosBeforeReset(0) m_nPosBeforeReset(0)
{ {
strcpy(m_aFilename, filename); // Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
FILE *test = fopen(filename, "r");
if (!test) {
char *r = (char*)alloca(strlen(filename) + 2);
if (casepath(filename, r))
{
strcpy(m_aFilename, r);
}
} else {
fclose(test);
#else
{
#endif
strcpy(m_aFilename, filename);
}
DEV("Stream %s\n", m_aFilename); DEV("Stream %s\n", m_aFilename);

View File

@ -5,16 +5,18 @@
#include "sampman.h" #include "sampman.h"
#include <time.h> #include <time.h>
#include <io.h>
#include "eax.h" #include "eax.h"
#include "eax-util.h" #include "eax-util.h"
#ifdef _WIN32
#include <io.h>
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
#include <AL/alext.h> #include <AL/alext.h>
#include <AL/efx.h> #include <AL/efx.h>
#include <AL/efx-presets.h> #include <AL/efx-presets.h>
#endif
#include "oal/oal_utils.h" #include "oal/oal_utils.h"
#include "oal/aldlist.h" #include "oal/aldlist.h"
@ -31,7 +33,9 @@
//TODO: loop count //TODO: loop count
//TODO: mp3 player //TODO: mp3 player
#ifdef _WIN32
#pragma comment( lib, "OpenAL32.lib" ) #pragma comment( lib, "OpenAL32.lib" )
#endif
cSampleManager SampleManager; cSampleManager SampleManager;
bool _bSampmanInitialised = false; bool _bSampmanInitialised = false;
@ -61,15 +65,15 @@ struct
int defaultProvider; int defaultProvider;
char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; char SampleBankDescFilename[] = "audio/sfx.SDT";
char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; char SampleBankDataFilename[] = "audio/sfx.RAW";
FILE *fpSampleDescHandle; FILE *fpSampleDescHandle;
FILE *fpSampleDataHandle; FILE *fpSampleDataHandle;
bool bSampleBankLoaded [MAX_SAMPLEBANKS]; bool bSampleBankLoaded [MAX_SAMPLEBANKS];
int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
int32 nSampleBankSize [MAX_SAMPLEBANKS]; int32 nSampleBankSize [MAX_SAMPLEBANKS];
int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; uintptr nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
int32 _nSampleDataEndOffset; int32 _nSampleDataEndOffset;
int32 nPedSlotSfx [MAX_PEDSFX]; int32 nPedSlotSfx [MAX_PEDSFX];
@ -573,7 +577,7 @@ cSampleManager::Initialise(void)
return false; return false;
} }
nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]); nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (uintptr)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL); ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL ) if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
@ -582,7 +586,7 @@ cSampleManager::Initialise(void)
return false; return false;
} }
nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX); nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL); ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
} }
@ -985,7 +989,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
if ( !IsSampleBankLoaded(nBank) ) if ( !IsSampleBankLoaded(nBank) )
return false; return false;
int32 addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; uintptr addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
if ( ALBuffers[nSfx].IsEmpty() ) if ( ALBuffers[nSfx].IsEmpty() )
{ {

View File

@ -2869,7 +2869,7 @@ CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
return; return;
} }
} }
uint32 oldestCarWeKeepTime = UINT_MAX; uint32 oldestCarWeKeepTime = UINT32_MAX;
int oldestCarWeKeepIndex = 0; int oldestCarWeKeepIndex = 0;
for (int i = 0; i < MAX_CARS_TO_KEEP; i++) { for (int i = 0; i < MAX_CARS_TO_KEEP; i++) {
if (apCarsToKeep[i] && aCarsToKeepTime[i] < oldestCarWeKeepTime) { if (apCarsToKeep[i] && aCarsToKeepTime[i] < oldestCarWeKeepTime) {

View File

@ -218,7 +218,7 @@ INITSAVEBUF
m_aPhones[i] = ReadSaveBuf<CPhone>(buf); m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
// It's saved as building pool index in save file, convert it to true entity // It's saved as building pool index in save file, convert it to true entity
if (m_aPhones[i].m_pEntity) { if (m_aPhones[i].m_pEntity) {
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)m_aPhones[i].m_pEntity - 1); m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
} }
} }
VALIDATESAVEBUF(size) VALIDATESAVEBUF(size)

View File

@ -988,7 +988,7 @@ INITSAVEBUF
aPickUps[i] = ReadSaveBuf<CPickup>(buf); aPickUps[i] = ReadSaveBuf<CPickup>(buf);
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil) if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1); aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
} }
CollectedPickUpIndex = ReadSaveBuf<uint16>(buf); CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);

View File

@ -590,13 +590,14 @@ int open_script()
{ {
static int scriptToLoad = 1; static int scriptToLoad = 1;
#ifdef _WIN32
if (GetAsyncKeyState('G') & 0x8000) if (GetAsyncKeyState('G') & 0x8000)
scriptToLoad = 0; scriptToLoad = 0;
if (GetAsyncKeyState('R') & 0x8000) if (GetAsyncKeyState('R') & 0x8000)
scriptToLoad = 1; scriptToLoad = 1;
if (GetAsyncKeyState('D') & 0x8000) if (GetAsyncKeyState('D') & 0x8000)
scriptToLoad = 2; scriptToLoad = 2;
#endif
switch (scriptToLoad) { switch (scriptToLoad) {
case 0: scriptfile = "main.scm"; break; case 0: scriptfile = "main.scm"; break;
case 1: scriptfile = "freeroam_miami.scm"; break; case 1: scriptfile = "freeroam_miami.scm"; break;
@ -834,6 +835,8 @@ int8 CRunningScript::ProcessOneCommand()
int8 CRunningScript::ProcessCommands0To99(int32 command) int8 CRunningScript::ProcessCommands0To99(int32 command)
{ {
float *fScriptVar1;
int *nScriptVar1;
switch (command) { switch (command) {
case COMMAND_NOP: case COMMAND_NOP:
return 0; return 0;
@ -1442,7 +1445,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, x2, y2)); UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -1463,46 +1466,58 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2));
if (!ScriptParams[7]) if (!ScriptParams[7])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
return 0; return 0;
} }
case COMMAND_ADD_INT_VAR_TO_INT_VAR: case COMMAND_ADD_INT_VAR_TO_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_INT_LVAR_TO_INT_VAR: case COMMAND_ADD_INT_LVAR_TO_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_ADD_INT_VAR_TO_INT_LVAR: case COMMAND_ADD_INT_VAR_TO_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_INT_LVAR_TO_INT_LVAR: case COMMAND_ADD_INT_LVAR_TO_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR: case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR: case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR: case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR: case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_INT_VAR_FROM_INT_VAR: case COMMAND_SUB_INT_VAR_FROM_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_SUB_INT_LVAR_FROM_INT_LVAR: case COMMAND_SUB_INT_LVAR_FROM_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR: case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR: case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
default: default:
assert(0); assert(0);
@ -1513,66 +1528,88 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
int8 CRunningScript::ProcessCommands100To199(int32 command) int8 CRunningScript::ProcessCommands100To199(int32 command)
{ {
float *fScriptVar1;
int *nScriptVar1;
switch (command) { switch (command) {
case COMMAND_SUB_INT_LVAR_FROM_INT_VAR: case COMMAND_SUB_INT_LVAR_FROM_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_INT_VAR_FROM_INT_LVAR: case COMMAND_SUB_INT_VAR_FROM_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_VAR: case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_LVAR: case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_MULT_INT_VAR_BY_INT_VAR: case COMMAND_MULT_INT_VAR_BY_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_MULT_INT_LVAR_BY_INT_VAR: case COMMAND_MULT_INT_LVAR_BY_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_MULT_INT_VAR_BY_INT_LVAR: case COMMAND_MULT_INT_VAR_BY_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_MULT_INT_LVAR_BY_INT_LVAR: case COMMAND_MULT_INT_LVAR_BY_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_VAR: case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_VAR: case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_LVAR: case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_LVAR: case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_DIV_INT_VAR_BY_INT_VAR: case COMMAND_DIV_INT_VAR_BY_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_DIV_INT_LVAR_BY_INT_VAR: case COMMAND_DIV_INT_LVAR_BY_INT_VAR:
*GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*nScriptVar1 /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_DIV_INT_VAR_BY_INT_LVAR: case COMMAND_DIV_INT_VAR_BY_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_DIV_INT_LVAR_BY_INT_LVAR: case COMMAND_DIV_INT_LVAR_BY_INT_LVAR:
*GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); nScriptVar1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*nScriptVar1 /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_VAR: case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR: case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR: case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_LVAR: case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR: case COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR:
{ {
@ -1589,16 +1626,20 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
return 0; return 0;
} }
case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR: case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR: case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR: case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR: case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR: case COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR:
{ {
@ -1615,16 +1656,20 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
return 0; return 0;
} }
case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR: case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR: case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
*fScriptVar1 -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR: case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
return 0; return 0;
case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR: case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR:
*(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); fScriptVar1 = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
*fScriptVar1 -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
return 0; return 0;
case COMMAND_SET_VAR_INT_TO_VAR_INT: case COMMAND_SET_VAR_INT_TO_VAR_INT:
{ {
@ -1983,7 +2028,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
UpdateCompareFlag(ped->IsWithinArea(x1, y1, x2, y2)); UpdateCompareFlag(ped->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -2010,7 +2055,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2));
if (!ScriptParams[7]) if (!ScriptParams[7])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
return 0; return 0;
@ -2226,7 +2271,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, x2, y2)); UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -2245,7 +2290,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
if (!ScriptParams[7]) if (!ScriptParams[7])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
return 0; return 0;
@ -2980,7 +3025,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
pVehicle->IsWithinArea(x1, y1, x2, y2)); pVehicle->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -3000,7 +3045,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
pVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); pVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
if (!ScriptParams[7]) if (!ScriptParams[7])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
return 0; return 0;
@ -5190,7 +5235,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CVector pos = *(CVector*)&ScriptParams[0]; CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT) if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
CCoronas::RegisterCorona((uint32)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8],
255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f);
return 0; return 0;
} }
@ -5801,7 +5846,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2)); UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -5818,7 +5863,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2)); UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
if (!ScriptParams[5]) if (!ScriptParams[5])
return 0; return 0;
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) if (CTheScripts::DbgFlag)
CTheScripts::DrawDebugSquare(x1, y1, x2, y2); CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
return 0; return 0;
@ -7832,7 +7877,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVector pos = *(CVector*)&ScriptParams[0]; CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT) if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
C3dMarkers::PlaceMarkerSet((uint32)this + m_nIp, 4, pos, *(float*)&ScriptParams[3], C3dMarkers::PlaceMarkerSet((uintptr)this + m_nIp, 4, pos, *(float*)&ScriptParams[3],
SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A,
SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
return 0; return 0;
@ -8039,7 +8084,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = *(float*)&ScriptParams[3]; float radius = *(float*)&ScriptParams[3];
CTheScripts::GetActualScriptSphereIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); CTheScripts::GetActualScriptSphereIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
ScriptParams[0] = CTheScripts::AddScriptSphere((uint32)this + m_nIp, pos, radius); ScriptParams[0] = CTheScripts::AddScriptSphere((uintptr)this + m_nIp, pos, radius);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
return 0; return 0;
} }
@ -10392,7 +10437,7 @@ void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -10476,9 +10521,9 @@ void CRunningScript::LocatePlayerCharCommand(int32 command, uint32* pIp)
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
#ifdef FIX_BUGS #ifdef FIX_BUGS
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
#else #else
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
#endif #endif
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
@ -10556,7 +10601,7 @@ void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -10660,7 +10705,7 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -10746,9 +10791,9 @@ void CRunningScript::LocateCharCharCommand(int32 command, uint32* pIp)
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
#ifdef FIX_BUGS #ifdef FIX_BUGS
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
#else #else
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
#endif #endif
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
@ -10827,7 +10872,7 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -10905,7 +10950,7 @@ void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -10977,7 +11022,7 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -11016,7 +11061,7 @@ void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
result = CBulletInfo::TestForSniperBullet(X - dX, X + dX, Y - dY, Y + dY, b3D ? Z - dZ : -1000.0f, b3D ? Z + dZ : 1000.0f); result = CBulletInfo::TestForSniperBullet(X - dX, X + dX, Y - dY, Y + dY, b3D ? Z - dZ : -1000.0f, b3D ? Z + dZ : 1000.0f);
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
@ -11133,7 +11178,7 @@ void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
@ -11255,7 +11300,7 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantAngledArea((uint32)this + m_nIp, infX, infY, supX, supY, CTheScripts::HighlightImportantAngledArea((uintptr)this + m_nIp, infX, infY, supX, supY,
rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
@ -11376,7 +11421,7 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
@ -11474,7 +11519,7 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp)
} }
UpdateCompareFlag(result); UpdateCompareFlag(result);
if (debug) if (debug)
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) { if (CTheScripts::DbgFlag) {
if (b3D) if (b3D)
CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);

View File

@ -1,3 +1,4 @@
#ifdef _WIN32
#define WITHWINDOWS #define WITHWINDOWS
#include "common.h" #include "common.h"
@ -16,9 +17,8 @@ struct CdReadInfo
char field_C; char field_C;
bool bLocked; bool bLocked;
bool bInUse; bool bInUse;
char _pad0;
int32 nStatus; int32 nStatus;
HANDLE hSemaphore; HANDLE hSemaphore; // used for CdStreamSync
HANDLE hFile; HANDLE hFile;
OVERLAPPED Overlapped; OVERLAPPED Overlapped;
}; };
@ -32,7 +32,7 @@ int32 gNumChannels;
HANDLE gImgFiles[MAX_CDIMAGES]; HANDLE gImgFiles[MAX_CDIMAGES];
HANDLE _gCdStreamThread; HANDLE _gCdStreamThread;
HANDLE gCdStreamSema; HANDLE gCdStreamSema; // released when we have new thing to read(so channel is set)
DWORD _gCdStreamThreadId; DWORD _gCdStreamThreadId;
CdReadInfo *gpReadInfo; CdReadInfo *gpReadInfo;
@ -296,6 +296,7 @@ CdStreamGetLastPosn(void)
return lastPosnRead; return lastPosnRead;
} }
// wait for channel to finish reading
int32 int32
CdStreamSync(int32 channel) CdStreamSync(int32 channel)
{ {
@ -324,6 +325,7 @@ CdStreamSync(int32 channel)
if ( _gbCdStreamOverlapped && pChannel->hFile ) if ( _gbCdStreamOverlapped && pChannel->hFile )
{ {
ASSERT(pChannel->hFile != nil ); ASSERT(pChannel->hFile != nil );
// Beware: This is blocking call (because of last parameter)
if ( GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) ) if ( GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
return STREAM_NONE; return STREAM_NONE;
else else
@ -406,6 +408,7 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
{ {
pChannel->nStatus = STREAM_NONE; pChannel->nStatus = STREAM_NONE;
} }
// Beware: This is blocking call (because of last parameter)
else if ( GetLastError() == ERROR_IO_PENDING else if ( GetLastError() == ERROR_IO_PENDING
&& GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) ) && GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
{ {
@ -508,3 +511,4 @@ CdStreamGetNumImages(void)
{ {
return gNumImages; return gNumImages;
} }
#endif

View File

@ -42,3 +42,7 @@ bool CdStreamAddImage(char const *path);
char *CdStreamGetImageName(int32 cd); char *CdStreamGetImageName(int32 cd);
void CdStreamRemoveImages(void); void CdStreamRemoveImages(void);
int32 CdStreamGetNumImages(void); int32 CdStreamGetNumImages(void);
#ifndef _WIN32
extern bool flushStream[MAX_CDCHANNELS];
#endif

516
src/core/CdStreamPosix.cpp Normal file
View File

@ -0,0 +1,516 @@
#ifndef _WIN32
#include "common.h"
#include "crossplatform.h"
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
// #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp)
bool flushStream[MAX_CDCHANNELS];
struct CdReadInfo
{
uint32 nSectorOffset;
uint32 nSectorsToRead;
void *pBuffer;
bool bLocked;
bool bReading;
int32 nStatus;
#ifdef ONE_THREAD_PER_CHANNEL
int8 nThreadStatus; // 0: created 1:initalized 2:abort now
pthread_t pChannelThread;
sem_t pStartSemaphore;
#endif
sem_t pDoneSemaphore; // used for CdStreamSync
int32 hFile;
};
char gCdImageNames[MAX_CDIMAGES+1][64];
int32 gNumImages;
int32 gNumChannels;
int32 gImgFiles[MAX_CDIMAGES]; // -1: error 0:unused otherwise: fd
char *gImgNames[MAX_CDIMAGES];
#ifndef ONE_THREAD_PER_CHANNEL
pthread_t _gCdStreamThread;
sem_t gCdStreamSema; // released when we have new thing to read(so channel is set)
int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now
Queue gChannelRequestQ;
bool _gbCdStreamOverlapped;
#endif
CdReadInfo *gpReadInfo;
int32 lastPosnRead;
int _gdwCdStreamFlags;
void *CdStreamThread(void* channelId);
void
CdStreamInitThread(void)
{
int status;
#ifndef ONE_THREAD_PER_CHANNEL
gChannelRequestQ.items = (int32 *)calloc(gNumChannels + 1, sizeof(int32));
gChannelRequestQ.head = 0;
gChannelRequestQ.tail = 0;
gChannelRequestQ.size = gNumChannels + 1;
ASSERT(gChannelRequestQ.items != nil );
status = sem_init(&gCdStreamSema, 0, 0);
#endif
if (status == -1) {
CDTRACE("failed to create stream semaphore");
ASSERT(0);
return;
}
if ( gNumChannels > 0 )
{
for ( int32 i = 0; i < gNumChannels; i++ )
{
status = sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0);
if (status == -1)
{
CDTRACE("failed to create sync semaphore");
ASSERT(0);
return;
}
#ifdef ONE_THREAD_PER_CHANNEL
status = sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0);
if (status == -1)
{
CDTRACE("failed to create start semaphore");
ASSERT(0);
return;
}
gpReadInfo[i].nThreadStatus = 0;
int *channelI = (int*)malloc(sizeof(int));
*channelI = i;
status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI);
if (status == -1)
{
CDTRACE("failed to create sync thread");
ASSERT(0);
return;
}
#endif
}
}
#ifndef ONE_THREAD_PER_CHANNEL
debug("Using one streaming thread for all channels\n");
status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil);
gCdStreamThreadStatus = 0;
if (status == -1)
{
CDTRACE("failed to create sync thread");
ASSERT(0);
return;
}
#else
debug("Using seperate streaming threads for each channel\n");
#endif
}
void
CdStreamInit(int32 numChannels)
{
struct statvfs fsInfo;
if((statvfs("models/gta3.img", &fsInfo)) < 0)
{
CDTRACE("can't get filesystem info");
ASSERT(0);
return;
}
_gdwCdStreamFlags = O_RDONLY | O_NOATIME;
// People say it's slower
/*
if ( fsInfo.f_bsize <= CDSTREAM_SECTOR_SIZE )
{
_gdwCdStreamFlags |= O_DIRECT;
debug("Using no buffered loading for streaming\n");
}
*/
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, fsInfo.f_bsize);
ASSERT( pBuffer != nil );
gNumImages = 0;
gNumChannels = numChannels;
gpReadInfo = (CdReadInfo *)calloc(sizeof(CdReadInfo), numChannels);
ASSERT( gpReadInfo != nil );
CDDEBUG("read info %p", gpReadInfo);
CdStreamInitThread();
ASSERT( pBuffer != nil );
RwFreeAlign(pBuffer);
}
uint32
GetGTA3ImgSize(void)
{
ASSERT( gImgFiles[0] > 0 );
struct stat statbuf;
char path[PATH_MAX];
realpath(gImgNames[0], path);
if (stat(path, &statbuf) == -1) {
// Try case-insensitivity
char *r = (char*)alloca(strlen(gImgNames[0]) + 2);
if (casepath(gImgNames[0], r))
{
realpath(r, path);
if (stat(path, &statbuf) != -1)
goto ok;
}
CDTRACE("can't get size of gta3.img");
ASSERT(0);
return 0;
}
ok:
return statbuf.st_size;
}
void
CdStreamShutdown(void)
{
// Destroying semaphores and free(gpReadInfo) will be done at threads
#ifndef ONE_THREAD_PER_CHANNEL
free(gChannelRequestQ.items);
gCdStreamThreadStatus = 2;
sem_post(&gCdStreamSema);
#endif
#ifdef ONE_THREAD_PER_CHANNEL
for ( int32 i = 0; i < gNumChannels; i++ ) {
gpReadInfo[i].nThreadStatus = 2;
sem_post(&gpReadInfo[i].pStartSemaphore);
}
#endif
}
int32
CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
{
ASSERT( channel < gNumChannels );
ASSERT( buffer != nil );
lastPosnRead = size + offset;
ASSERT( _GET_INDEX(offset) < MAX_CDIMAGES );
int32 hImage = gImgFiles[_GET_INDEX(offset)];
ASSERT( hImage > 0 );
CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil );
pChannel->hFile = hImage - 1;
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading )
return STREAM_NONE;
pChannel->nStatus = STREAM_NONE;
pChannel->nSectorOffset = _GET_OFFSET(offset);
pChannel->nSectorsToRead = size;
pChannel->pBuffer = buffer;
pChannel->bLocked = 0;
#ifndef ONE_THREAD_PER_CHANNEL
AddToQueue(&gChannelRequestQ, channel);
if ( sem_post(&gCdStreamSema) != 0 )
printf("Signal Sema Error\n");
#else
if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 )
printf("Signal Sema Error\n");
#endif
return STREAM_SUCCESS;
}
int32
CdStreamGetStatus(int32 channel)
{
ASSERT( channel < gNumChannels );
CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil );
#ifdef ONE_THREAD_PER_CHANNEL
if (pChannel->nThreadStatus == 2)
return STREAM_NONE;
#else
if (gCdStreamThreadStatus == 2)
return STREAM_NONE;
#endif
if ( pChannel->bReading )
return STREAM_READING;
if ( pChannel->nSectorsToRead != 0 )
return STREAM_WAITING;
if ( pChannel->nStatus != STREAM_NONE )
{
int32 status = pChannel->nStatus;
pChannel->nStatus = STREAM_NONE;
return status;
}
return STREAM_NONE;
}
int32
CdStreamGetLastPosn(void)
{
return lastPosnRead;
}
// wait for channel to finish reading
int32
CdStreamSync(int32 channel)
{
ASSERT( channel < gNumChannels );
CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil );
if (flushStream[channel]) {
#ifdef ONE_THREAD_PER_CHANNEL
pChannel->nSectorsToRead = 0;
pthread_kill(gpReadInfo[channel].pChannelThread, SIGINT);
#else
if (pChannel->bReading) {
pChannel->nSectorsToRead = 0;
pthread_kill(_gCdStreamThread, SIGINT);
} else {
pChannel->nSectorsToRead = 0;
}
#endif
pChannel->bReading = false;
flushStream[channel] = false;
return STREAM_NONE;
}
if ( pChannel->nSectorsToRead != 0 )
{
pChannel->bLocked = true;
sem_wait(&pChannel->pDoneSemaphore);
}
pChannel->bReading = false;
return pChannel->nStatus;
}
void
AddToQueue(Queue *queue, int32 item)
{
ASSERT( queue != nil );
ASSERT( queue->items != nil );
queue->items[queue->tail] = item;
queue->tail = (queue->tail + 1) % queue->size;
if ( queue->head == queue->tail )
debug("Queue is full\n");
}
int32
GetFirstInQueue(Queue *queue)
{
ASSERT( queue != nil );
if ( queue->head == queue->tail )
return -1;
ASSERT( queue->items != nil );
return queue->items[queue->head];
}
void
RemoveFirstInQueue(Queue *queue)
{
ASSERT( queue != nil );
if ( queue->head == queue->tail )
{
debug("Queue is empty\n");
return;
}
queue->head = (queue->head + 1) % queue->size;
}
void *CdStreamThread(void *param)
{
debug("Created cdstream thread\n");
#ifndef ONE_THREAD_PER_CHANNEL
while (gCdStreamThreadStatus != 2) {
sem_wait(&gCdStreamSema);
int32 channel = GetFirstInQueue(&gChannelRequestQ);
#else
int channel = *((int*)param);
while (gpReadInfo[channel].nThreadStatus != 2){
sem_wait(&gpReadInfo[channel].pStartSemaphore);
#endif
ASSERT( channel < gNumChannels );
CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil );
#ifdef ONE_THREAD_PER_CHANNEL
if (gpReadInfo[channel].nThreadStatus == 0){
gpReadInfo[channel].nThreadStatus = 1;
#else
if (gCdStreamThreadStatus == 0){
gCdStreamThreadStatus = 1;
#endif
pid_t tid = syscall(SYS_gettid);
int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1);
}
// spurious wakeup or we sent interrupt signal for flushing
if(pChannel->nSectorsToRead == 0)
continue;
pChannel->bReading = true;
if ( pChannel->nStatus == STREAM_NONE )
{
ASSERT(pChannel->hFile >= 0);
ASSERT(pChannel->pBuffer != nil );
lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET);
if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) {
// pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel
pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_NONE : STREAM_ERROR;
} else {
pChannel->nStatus = STREAM_NONE;
}
}
#ifndef ONE_THREAD_PER_CHANNEL
RemoveFirstInQueue(&gChannelRequestQ);
#endif
pChannel->nSectorsToRead = 0;
if ( pChannel->bLocked )
{
sem_post(&pChannel->pDoneSemaphore);
}
pChannel->bReading = false;
}
#ifndef ONE_THREAD_PER_CHANNEL
for ( int32 i = 0; i < gNumChannels; i++ )
{
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
}
sem_destroy(&gCdStreamSema);
#else
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
#endif
free(gpReadInfo);
pthread_exit(nil);
}
bool
CdStreamAddImage(char const *path)
{
ASSERT(path != nil);
ASSERT(gNumImages < MAX_CDIMAGES);
gImgFiles[gNumImages] = open(path, _gdwCdStreamFlags);
// Fix case sensitivity and backslashes.
if (gImgFiles[gNumImages] == -1) {
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
{
gImgFiles[gNumImages] = open(r, _gdwCdStreamFlags);
}
}
if ( gImgFiles[gNumImages] == -1 ) {
assert(false);
return false;
}
gImgNames[gNumImages] = strdup(path);
gImgFiles[gNumImages]++; // because -1: error 0: not used
strcpy(gCdImageNames[gNumImages], path);
gNumImages++;
return true;
}
char *
CdStreamGetImageName(int32 cd)
{
ASSERT(cd < MAX_CDIMAGES);
if ( gImgFiles[cd] > 0)
return gCdImageNames[cd];
return nil;
}
void
CdStreamRemoveImages(void)
{
for ( int32 i = 0; i < gNumChannels; i++ )
CdStreamSync(i);
for ( int32 i = 0; i < gNumImages; i++ )
{
close(gImgFiles[i] - 1);
free(gImgNames[i]);
gImgFiles[i] = 0;
}
gNumImages = 0;
}
int32
CdStreamGetNumImages(void)
{
return gNumImages;
}
#endif

View File

@ -4,7 +4,8 @@
#endif #endif
#include "common.h" #include "common.h"
#include "crossplatform.h" #include "platform.h"
#include "crossplatform.h" // for Windows version
#include "ControllerConfig.h" #include "ControllerConfig.h"
#include "Pad.h" #include "Pad.h"
#include "FileMgr.h" #include "FileMgr.h"
@ -164,13 +165,13 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, rsPADDOWN, KEYBOARD); SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, rsPADDOWN, KEYBOARD);
SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, 'E', OPTIONAL_EXTRA); SetControllerKeyAssociatedWithAction (VEHICLE_LOOKRIGHT, 'E', OPTIONAL_EXTRA);
if ( _dwOperatingSystemVersion != OS_WIN98 ) if ( _dwOperatingSystemVersion == OS_WIN98 )
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
else
{ {
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsLSHIFT, OPTIONAL_EXTRA); SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsLSHIFT, OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsRSHIFT, KEYBOARD); SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsRSHIFT, KEYBOARD);
} }
else
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, rsRCTRL, KEYBOARD); SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, rsRCTRL, KEYBOARD);
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, ' ', OPTIONAL_EXTRA); SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, ' ', OPTIONAL_EXTRA);
@ -217,7 +218,9 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (PED_JUMPING, rsRCTRL, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_JUMPING, rsRCTRL, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_JUMPING, ' ', OPTIONAL_EXTRA); SetControllerKeyAssociatedWithAction (PED_JUMPING, ' ', OPTIONAL_EXTRA);
if ( _dwOperatingSystemVersion != OS_WIN98 ) if ( _dwOperatingSystemVersion == OS_WIN98 )
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
else
{ {
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsLSHIFT, OPTIONAL_EXTRA); SetControllerKeyAssociatedWithAction(PED_SPRINT, rsLSHIFT, OPTIONAL_EXTRA);
#ifndef FIX_BUGS #ifndef FIX_BUGS
@ -226,8 +229,6 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, KEYBOARD); SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, KEYBOARD);
#endif #endif
} }
else
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
SetControllerKeyAssociatedWithAction (PED_CYCLE_TARGET_LEFT, '[', KEYBOARD); SetControllerKeyAssociatedWithAction (PED_CYCLE_TARGET_LEFT, '[', KEYBOARD);

View File

@ -1,6 +1,8 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include <fcntl.h> #include <fcntl.h>
#ifdef _WIN32
#include <direct.h> #include <direct.h>
#endif
#include "common.h" #include "common.h"
#include "FileMgr.h" #include "FileMgr.h"
@ -24,6 +26,31 @@ struct myFILE
#define NUMFILES 20 #define NUMFILES 20
static myFILE myfiles[NUMFILES]; static myFILE myfiles[NUMFILES];
#if !defined(_WIN32)
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include "crossplatform.h"
#define _getcwd getcwd
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
void mychdir(char const *path)
{
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
{
chdir(r);
}
else
{
errno = ENOENT;
}
}
#else
#define mychdir chdir
#endif
/* Force file to open as binary but remember if it was text mode */ /* Force file to open as binary but remember if it was text mode */
static int static int
myfopen(const char *filename, const char *mode) myfopen(const char *filename, const char *mode)
@ -45,7 +72,31 @@ found:
mode++; mode++;
*p++ = 'b'; *p++ = 'b';
*p = '\0'; *p = '\0';
myfiles[fd].file = fopen(filename, realmode);
#if !defined(_WIN32)
char *newPath = strdup(filename);
// Normally casepath() fixes backslashes, but if the mode is sth other than r/rb it will create new file with backslashes on linux, so fix backslashes here
char *nextBs;
while(nextBs = strstr(newPath, "\\")){
*nextBs = '/';
}
#else
const char *newPath = filename;
#endif
myfiles[fd].file = fopen(newPath, realmode);
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
if (!myfiles[fd].file) {
char *r = (char*)alloca(strlen(newPath) + 2);
if (casepath(newPath, r))
{
myfiles[fd].file = fopen(r, realmode);
}
}
free(newPath);
#endif
if(myfiles[fd].file == nil) if(myfiles[fd].file == nil)
return 0; return 0;
return fd; return fd;
@ -191,7 +242,7 @@ CFileMgr::ChangeDir(const char *dir)
if(dir[strlen(dir)-1] != '\\') if(dir[strlen(dir)-1] != '\\')
strcat(ms_dirName, "\\"); strcat(ms_dirName, "\\");
} }
chdir(ms_dirName); mychdir(ms_dirName);
} }
void void
@ -204,14 +255,14 @@ CFileMgr::SetDir(const char *dir)
if(dir[strlen(dir)-1] != '\\') if(dir[strlen(dir)-1] != '\\')
strcat(ms_dirName, "\\"); strcat(ms_dirName, "\\");
} }
chdir(ms_dirName); mychdir(ms_dirName);
} }
void void
CFileMgr::SetDirMyDocuments(void) CFileMgr::SetDirMyDocuments(void)
{ {
SetDir(""); // better start at the root if user directory is relative SetDir(""); // better start at the root if user directory is relative
chdir(_psGetUserFilesFolder()); mychdir(_psGetUserFilesFolder());
} }
int int

View File

@ -128,7 +128,7 @@ CFire::ProcessFire(void)
lightpos.z = m_vecPos.z + 5.0f; lightpos.z = m_vecPos.z + 5.0f;
if (!m_pEntity) { if (!m_pEntity) {
CShadows::StoreStaticShadow((uint32)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos,
7.0f, 0.0f, 0.0f, -7.0f, 7.0f, 0.0f, 0.0f, -7.0f,
255, // this is 0 on PC which results in no shadow 255, // this is 0 on PC which results in no shadow
nRandNumber / 2, nRandNumber / 2, 0, nRandNumber / 2, nRandNumber / 2, 0,

View File

@ -6,6 +6,7 @@
#define WITHWINDOWS #define WITHWINDOWS
#include "common.h" #include "common.h"
#include "crossplatform.h" #include "crossplatform.h"
#include "platform.h"
#include "Frontend.h" #include "Frontend.h"
#include "Font.h" #include "Font.h"
#include "Pad.h" #include "Pad.h"
@ -900,6 +901,7 @@ CMenuManager::Draw()
float smallestSliderBar = lineHeight * 0.1f; float smallestSliderBar = lineHeight * 0.1f;
bool foundTheHoveringItem = false; bool foundTheHoveringItem = false;
wchar unicodeTemp[64]; wchar unicodeTemp[64];
char asciiTemp[32];
#ifdef MENU_MAP #ifdef MENU_MAP
if (m_nCurrScreen == MENUPAGE_MAP) { if (m_nCurrScreen == MENUPAGE_MAP) {
@ -1054,15 +1056,18 @@ CMenuManager::Draw()
#else #else
switch (m_PrefsUseWideScreen) { switch (m_PrefsUseWideScreen) {
case AR_AUTO: case AR_AUTO:
rightText = (wchar*)L"AUTO"; sprintf(asciiTemp, "AUTO");
break; break;
case AR_4_3: case AR_4_3:
rightText = (wchar*)L"4:3"; sprintf(asciiTemp, "4:3");
break; break;
case AR_16_9: case AR_16_9:
rightText = (wchar*)L"16:9"; sprintf(asciiTemp, "16:9");
break; break;
} }
AsciiToUnicode(asciiTemp, unicodeTemp);
rightText = unicodeTemp;
#endif #endif
break; break;
case MENUACTION_RADIO: case MENUACTION_RADIO:
@ -1102,13 +1107,12 @@ CMenuManager::Draw()
break; break;
#ifdef IMPROVED_VIDEOMODE #ifdef IMPROVED_VIDEOMODE
case MENUACTION_SCREENMODE: case MENUACTION_SCREENMODE:
char mode[32];
if (m_nSelectedScreenMode == 0) if (m_nSelectedScreenMode == 0)
sprintf(mode, "FULLSCREEN"); sprintf(asciiTemp, "FULLSCREEN");
else else
sprintf(mode, "WINDOWED"); sprintf(asciiTemp, "WINDOWED");
AsciiToUnicode(mode, unicodeTemp); AsciiToUnicode(asciiTemp, unicodeTemp);
rightText = unicodeTemp; rightText = unicodeTemp;
break; break;
#endif #endif
@ -4794,6 +4798,21 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED"); OutputDebugString("FRONTEND RADIO STATION CHANGED");
break; break;
#ifdef ASPECT_RATIO_SCALE
case MENUACTION_WIDESCREEN:
if (changeValueBy > 0) {
m_PrefsUseWideScreen++;
if (m_PrefsUseWideScreen > 2)
m_PrefsUseWideScreen = 2;
} else {
m_PrefsUseWideScreen--;
if (m_PrefsUseWideScreen < 0)
m_PrefsUseWideScreen = 0;
}
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings();
break;
#endif
case MENUACTION_SCREENRES: case MENUACTION_SCREENRES:
if (m_bGameNotLoaded) { if (m_bGameNotLoaded) {
RwChar** videoMods = _psGetVideoModeList(); RwChar** videoMods = _psGetVideoModeList();
@ -4903,17 +4922,13 @@ CMenuManager::ProcessOnOffMenuOptions()
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings(); SaveSettings();
break; break;
case MENUACTION_WIDESCREEN:
#ifndef ASPECT_RATIO_SCALE #ifndef ASPECT_RATIO_SCALE
case MENUACTION_WIDESCREEN:
m_PrefsUseWideScreen = !m_PrefsUseWideScreen; m_PrefsUseWideScreen = !m_PrefsUseWideScreen;
#else
m_PrefsUseWideScreen++;
if (m_PrefsUseWideScreen > 2)
m_PrefsUseWideScreen = 0;
#endif
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings(); SaveSettings();
break; break;
#endif
case MENUACTION_SETDBGFLAG: case MENUACTION_SETDBGFLAG:
CTheScripts::InvertDebugFlag(); CTheScripts::InvertDebugFlag();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);

View File

@ -664,4 +664,3 @@ VALIDATE_SIZE(CMenuManager, 0x564);
#endif #endif
extern CMenuManager FrontEndMenuManager; extern CMenuManager FrontEndMenuManager;
extern unsigned long _dwOperatingSystemVersion;

View File

@ -2,7 +2,7 @@
#pragma warning( disable : 4005) #pragma warning( disable : 4005)
#pragma warning( pop ) #pragma warning( pop )
#include "common.h" #include "common.h"
#include "crossplatform.h" #include "platform.h"
#include "Game.h" #include "Game.h"
#include "main.h" #include "main.h"

View File

@ -1618,7 +1618,7 @@ CStreaming::GetCdImageOffset(int32 lastPosn)
int dist, mindist; int dist, mindist;
img = -1; img = -1;
mindist = INT_MAX; mindist = INT32_MAX;
offset = ms_imageOffsets[ms_lastImageRead]; offset = ms_imageOffsets[ms_lastImageRead];
if(lastPosn <= offset || lastPosn > offset + ms_imageSize){ if(lastPosn <= offset || lastPosn > offset + ms_imageSize){
// last read position is not in last image // last read position is not in last image
@ -1667,8 +1667,8 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
streamIdFirst = -1; streamIdFirst = -1;
streamIdNext = -1; streamIdNext = -1;
posnFirst = UINT_MAX; posnFirst = UINT32_MAX;
posnNext = UINT_MAX; posnNext = UINT32_MAX;
for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = next){ for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = next){
next = si->m_next; next = si->m_next;

View File

@ -1,5 +1,6 @@
#define WITHWINDOWS #define WITHWINDOWS
#include "common.h" #include "common.h"
#include "crossplatform.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "Record.h" #include "Record.h"
@ -16,15 +17,19 @@ float CTimer::ms_fTimeStepNonClipped;
bool CTimer::m_UserPause; bool CTimer::m_UserPause;
bool CTimer::m_CodePause; bool CTimer::m_CodePause;
uint32 oldPcTimer;
uint32 suspendPcTimer;
uint32 _nCyclesPerMS = 1; uint32 _nCyclesPerMS = 1;
#ifdef _WIN32
LARGE_INTEGER _oldPerfCounter; LARGE_INTEGER _oldPerfCounter;
LARGE_INTEGER perfSuspendCounter; LARGE_INTEGER perfSuspendCounter;
#define RsTimerType uint32
#else
#define RsTimerType double
#endif
RsTimerType oldPcTimer;
RsTimerType suspendPcTimer;
uint32 suspendDepth; uint32 suspendDepth;
@ -45,6 +50,7 @@ void CTimer::Initialise(void)
m_snPreviousTimeInMilliseconds = 0; m_snPreviousTimeInMilliseconds = 0;
m_snTimeInMilliseconds = 1; m_snTimeInMilliseconds = 1;
#ifdef _WIN32
LARGE_INTEGER perfFreq; LARGE_INTEGER perfFreq;
if ( QueryPerformanceFrequency(&perfFreq) ) if ( QueryPerformanceFrequency(&perfFreq) )
{ {
@ -53,6 +59,7 @@ void CTimer::Initialise(void)
QueryPerformanceCounter(&_oldPerfCounter); QueryPerformanceCounter(&_oldPerfCounter);
} }
else else
#endif
{ {
OutputDebugString("Performance counter not available, using millesecond timer\n"); OutputDebugString("Performance counter not available, using millesecond timer\n");
_nCyclesPerMS = 0; _nCyclesPerMS = 0;
@ -77,6 +84,7 @@ void CTimer::Update(void)
{ {
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds; m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 ) if ( (double)_nCyclesPerMS != 0.0 )
{ {
LARGE_INTEGER pc; LARGE_INTEGER pc;
@ -106,10 +114,11 @@ void CTimer::Update(void)
} }
} }
else else
#endif
{ {
uint32 timer = RsTimer(); RsTimerType timer = RsTimer();
uint32 updInMs = timer - oldPcTimer; RsTimerType updInMs = timer - oldPcTimer;
// We need that real frame time to fix transparent menu bug. // We need that real frame time to fix transparent menu bug.
#ifndef FIX_BUGS #ifndef FIX_BUGS
@ -158,9 +167,11 @@ void CTimer::Suspend(void)
if ( ++suspendDepth > 1 ) if ( ++suspendDepth > 1 )
return; return;
#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 ) if ( (double)_nCyclesPerMS != 0.0 )
QueryPerformanceCounter(&perfSuspendCounter); QueryPerformanceCounter(&perfSuspendCounter);
else else
#endif
suspendPcTimer = RsTimer(); suspendPcTimer = RsTimer();
} }
@ -169,6 +180,7 @@ void CTimer::Resume(void)
if ( --suspendDepth != 0 ) if ( --suspendDepth != 0 )
return; return;
#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 ) if ( (double)_nCyclesPerMS != 0.0 )
{ {
LARGE_INTEGER pc; LARGE_INTEGER pc;
@ -177,19 +189,23 @@ void CTimer::Resume(void)
_oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart; _oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart;
} }
else else
#endif
oldPcTimer += RsTimer() - suspendPcTimer; oldPcTimer += RsTimer() - suspendPcTimer;
} }
uint32 CTimer::GetCyclesPerMillisecond(void) uint32 CTimer::GetCyclesPerMillisecond(void)
{ {
#ifdef _WIN32
if (_nCyclesPerMS != 0) if (_nCyclesPerMS != 0)
return _nCyclesPerMS; return _nCyclesPerMS;
else else
#endif
return 1; return 1;
} }
uint32 CTimer::GetCurrentTimeInCycles(void) uint32 CTimer::GetCurrentTimeInCycles(void)
{ {
#ifdef _WIN32
if ( _nCyclesPerMS != 0 ) if ( _nCyclesPerMS != 0 )
{ {
LARGE_INTEGER pc; LARGE_INTEGER pc;
@ -197,6 +213,7 @@ uint32 CTimer::GetCurrentTimeInCycles(void)
return (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless return (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
} }
else else
#endif
return RsTimer() - oldPcTimer; return RsTimer() - oldPcTimer;
} }

View File

@ -752,9 +752,9 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
meant for a different array, but the game doesn't brake meant for a different array, but the game doesn't brake
if save data stored is -1. if save data stored is -1.
*/ */
MapZoneArray[i].child = GetPointerForZoneIndex((int32)MapZoneArray[i].child); MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
MapZoneArray[i].parent = GetPointerForZoneIndex((int32)MapZoneArray[i].parent); MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
MapZoneArray[i].next = GetPointerForZoneIndex((int32)MapZoneArray[i].next); MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
assert(MapZoneArray[i].child == nil); assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil); assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil); assert(MapZoneArray[i].next == nil);

View File

@ -199,15 +199,18 @@ enum Config {
#define USE_TXD_CDIMAGE // generate and load textures from txd.img #define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
//#define USE_TEXTURE_POOL //#define USE_TEXTURE_POOL
//#define AUDIO_OAL #ifdef _WIN32
#define AUDIO_MSS #define AUDIO_MSS
#else
#define AUDIO_OAL
#endif
// Particle // Particle
//#define PC_PARTICLE //#define PC_PARTICLE
//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 //#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// Pad // Pad
#ifndef RW_GL3 #if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT #define XINPUT
#endif #endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m #define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m

View File

@ -1776,6 +1776,8 @@ void GameInit()
} }
} }
// Not used anyway. PS2 main() port
#ifdef _WIN32
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -1847,3 +1849,4 @@ main(int argc, char *argv[])
return 0; return 0;
} }
#endif

View File

@ -24,7 +24,7 @@ StaticPatcher::Apply()
} }
ms_head = nil; ms_head = nil;
} }
#ifdef _WIN32
std::vector<uint32> usedAddresses; std::vector<uint32> usedAddresses;
static DWORD protect[2]; static DWORD protect[2];
@ -76,3 +76,19 @@ InjectHook_internal(uint32 address, uint32 hook, int type)
else else
VirtualProtect((void*)address, 5, protect[0], &protect[1]); VirtualProtect((void*)address, 5, protect[0], &protect[1]);
} }
#else
void
Protect_internal(uint32 address, uint32 size)
{
}
void
Unprotect_internal(void)
{
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
}
#endif

View File

@ -1,7 +1,7 @@
#include <direct.h>
#include <csignal> #include <csignal>
#define WITHWINDOWS #define WITHWINDOWS
#include "common.h" #include "common.h"
#include "crossplatform.h"
#include "patcher.h" #include "patcher.h"
#include "Renderer.h" #include "Renderer.h"
#include "Credits.h" #include "Credits.h"
@ -28,6 +28,11 @@
#include "debugmenu.h" #include "debugmenu.h"
#include "Frontend.h" #include "Frontend.h"
#ifndef _WIN32
#include "assert.h"
#include <stdarg.h>
#endif
#include <list> #include <list>
#ifdef RWLIBS #ifdef RWLIBS
@ -36,7 +41,7 @@ extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list
#ifdef USE_PS2_RAND #ifdef USE_PS2_RAND
unsigned __int64 myrand_seed = 1; unsigned long long myrand_seed = 1;
#else #else
unsigned long int myrand_seed = 1; unsigned long int myrand_seed = 1;
#endif #endif
@ -207,13 +212,22 @@ static const char *carnames[] = {
"bloodra", "bloodrb", "vicechee" "bloodra", "bloodrb", "vicechee"
}; };
static std::list<CTweakVar *> TweakVarsList; static CTweakVar** TweakVarsList;
static int TweakVarsListSize = -1;
static bool bAddTweakVarsNow = false; static bool bAddTweakVarsNow = false;
static const char *pTweakVarsDefaultPath = NULL; static const char *pTweakVarsDefaultPath = NULL;
void CTweakVars::Add(CTweakVar *var) void CTweakVars::Add(CTweakVar *var)
{ {
TweakVarsList.push_back(var); if(TweakVarsListSize == -1) {
TweakVarsList = (CTweakVar**)malloc(64 * sizeof(CTweakVar*));
TweakVarsListSize = 0;
}
if(TweakVarsListSize > 63)
TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var));
TweakVarsList[TweakVarsListSize++] = var;
// TweakVarsList.push_back(var);
if ( bAddTweakVarsNow ) if ( bAddTweakVarsNow )
var->AddDBG(pTweakVarsDefaultPath); var->AddDBG(pTweakVarsDefaultPath);
@ -223,8 +237,8 @@ void CTweakVars::AddDBG(const char *path)
{ {
pTweakVarsDefaultPath = path; pTweakVarsDefaultPath = path;
for(auto i = TweakVarsList.begin(); i != TweakVarsList.end(); ++i) for(int i = 0; i < TweakVarsListSize; ++i)
(*i)->AddDBG(pTweakVarsDefaultPath); TweakVarsList[i]->AddDBG(pTweakVarsDefaultPath);
bAddTweakVarsNow = true; bAddTweakVarsNow = true;
} }
@ -395,6 +409,7 @@ static char re3_buff[re3_buffsize];
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func) void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func)
{ {
#ifdef _WIN32
int nCode; int nCode;
strcpy_s(re3_buff, re3_buffsize, "Assertion failed!" ); strcpy_s(re3_buff, re3_buffsize, "Assertion failed!" );
@ -439,13 +454,22 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
return; return;
abort(); abort();
#else
// TODO
printf("\nRE3 ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
assert(false);
#endif
} }
void re3_debug(const char *format, ...) void re3_debug(const char *format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va); vsprintf_s(re3_buff, re3_buffsize, format, va);
#else
vsprintf(re3_buff, format, va);
#endif
va_end(va); va_end(va);
printf("%s", re3_buff); printf("%s", re3_buff);
@ -457,18 +481,26 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
char buff[re3_buffsize *2]; char buff[re3_buffsize *2];
va_list va; va_list va;
va_start(va, format); va_start(va, format);
#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va); vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va); va_end(va);
sprintf_s(buff, re3_buffsize * 2, "[%s.%s:%d]: %s", filename, func, lineno, re3_buff); sprintf_s(buff, re3_buffsize * 2, "[%s.%s:%d]: %s", filename, func, lineno, re3_buff);
#else
vsprintf(re3_buff, format, va);
va_end(va);
OutputDebugStringA(buff); sprintf(buff, "[%s.%s:%d]: %s", filename, func, lineno, re3_buff);
#endif
OutputDebugString(buff);
} }
void re3_usererror(const char *format, ...) void re3_usererror(const char *format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
#ifdef _WIN32
vsprintf_s(re3_buff, re3_buffsize, format, va); vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va); va_end(va);
@ -477,6 +509,11 @@ void re3_usererror(const char *format, ...)
raise(SIGABRT); raise(SIGABRT);
_exit(3); _exit(3);
#else
vsprintf(re3_buff, format, va);
printf("\nRE3 Error!\n\t%s\n",re3_buff);
assert(false);
#endif
} }
#ifdef VALIDATE_SAVE_SIZE #ifdef VALIDATE_SAVE_SIZE

View File

@ -9,10 +9,11 @@
#include "debugmenu.h" #include "debugmenu.h"
#include <new> #include <new>
#ifdef _WIN32
#define snprintf _snprintf #define snprintf _snprintf
#define strdup _strdup #define strdup _strdup
#endif
// Font stuff // Font stuff

View File

@ -7,6 +7,9 @@
#include <rpskin.h> #include <rpskin.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#ifndef _WIN32
#include "crossplatform.h"
#endif
using namespace rw; using namespace rw;
@ -371,8 +374,24 @@ RwStream *RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, const v
StreamFile fakefile; StreamFile fakefile;
file = rwNewT(StreamFile, 1, 0); file = rwNewT(StreamFile, 1, 0);
memcpy(file, &fakefile, sizeof(StreamFile)); memcpy(file, &fakefile, sizeof(StreamFile));
#ifndef _WIN32
// Be case-insensitive and fix backslashes (from https://github.com/OneSadCookie/fcaseopen/)
FILE* first = fopen((char*)pData, "r");
char *r;
if (!first) {
r = (char*)alloca(strlen((char*)pData) + 2);
// Use default path(and pass error handling to librw) if we can't find any match
if (!casepath((char*)pData, r))
r = (char*)pData;
} else
fclose(first);
if(file->open((char*)r, mode))
return file;
#else
if(file->open((char*)pData, mode)) if(file->open((char*)pData, mode))
return file; return file;
#endif
rwFree(file); rwFree(file);
return nil; return nil;
} }

View File

@ -293,7 +293,7 @@ CVehicleModelInfo::HideDamagedAtomicCB(RpAtomic *atomic, void *data)
RpAtomic* RpAtomic*
CVehicleModelInfo::HideAllComponentsAtomicCB(RpAtomic *atomic, void *data) CVehicleModelInfo::HideAllComponentsAtomicCB(RpAtomic *atomic, void *data)
{ {
if(CVisibilityPlugins::GetAtomicId(atomic) & (int)data) if(CVisibilityPlugins::GetAtomicId(atomic) & (uintptr)data)
RpAtomicSetFlags(atomic, 0); RpAtomicSetFlags(atomic, 0);
else else
RpAtomicSetFlags(atomic, rpATOMICRENDER); RpAtomicSetFlags(atomic, rpATOMICRENDER);
@ -484,7 +484,7 @@ CVehicleModelInfo::SetAtomicFlagCB(RwObject *object, void *data)
{ {
RpAtomic *atomic = (RpAtomic*)object; RpAtomic *atomic = (RpAtomic*)object;
assert(RwObjectGetType(object) == rpATOMIC); assert(RwObjectGetType(object) == rpATOMIC);
CVisibilityPlugins::SetAtomicFlag(atomic, (int)data); CVisibilityPlugins::SetAtomicFlag(atomic, (uintptr)data);
return object; return object;
} }
@ -493,7 +493,7 @@ CVehicleModelInfo::ClearAtomicFlagCB(RwObject *object, void *data)
{ {
RpAtomic *atomic = (RpAtomic*)object; RpAtomic *atomic = (RpAtomic*)object;
assert(RwObjectGetType(object) == rpATOMIC); assert(RwObjectGetType(object) == rpATOMIC);
CVisibilityPlugins::ClearAtomicFlag(atomic, (int)data); CVisibilityPlugins::ClearAtomicFlag(atomic, (uintptr)data);
return object; return object;
} }

View File

@ -2862,7 +2862,7 @@ CPed::SetObjective(eObjective newObj, void *entity)
case OBJECTIVE_WAIT_IN_CAR_THEN_GETOUT: case OBJECTIVE_WAIT_IN_CAR_THEN_GETOUT:
// In this special case, entity parameter isn't CEntity, but int. // In this special case, entity parameter isn't CEntity, but int.
SetObjectiveTimer((int)entity); SetObjectiveTimer((uintptr)entity);
break; break;
case OBJECTIVE_KILL_CHAR_ON_FOOT: case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS: case OBJECTIVE_KILL_CHAR_ANY_MEANS:
@ -3355,7 +3355,7 @@ CPed::MakePhonecall(void)
if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) { if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(), FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
(m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (int)m_threatEntity : (int)((CPed*)m_pEventEntity)->m_threatEntity), false); (m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (uintptr)m_threatEntity : (uintptr)((CPed*)m_pEventEntity)->m_threatEntity), false);
bRunningToPhone = false; bRunningToPhone = false;
} }
#endif #endif
@ -4563,7 +4563,7 @@ CPed::SetPointGunAt(CEntity *to)
SetLookFlag(to, true); SetLookFlag(to, true);
SetAimFlag(to); SetAimFlag(to);
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
SetLookTimer(INT_MAX); SetLookTimer(INT32_MAX);
#endif #endif
} }
@ -4802,8 +4802,8 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) { if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) {
if (veh->pDriver && veh->pDriver->IsPlayer()) { if (veh->pDriver && veh->pDriver->IsPlayer()) {
CWanted *wanted = FindPlayerPed()->m_pWanted; CWanted *wanted = FindPlayerPed()->m_pWanted;
wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (int)this, false); wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (uintptr)this, false);
wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (int)this, false); wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (uintptr)this, false);
} }
} }
} }

View File

@ -1077,7 +1077,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
SetLookFlag(limitedCam, true); SetLookFlag(limitedCam, true);
SetAimFlag(limitedCam); SetAimFlag(limitedCam);
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
SetLookTimer(INT_MAX); // removing this makes head move for real, but I experinced some bugs. SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs.
#endif #endif
} else { } else {
m_fRotationDest = limitedCam; m_fRotationDest = limitedCam;

View File

@ -17,7 +17,7 @@ CConsole::AddLine(char *s, uint8 r, uint8 g, uint8 b)
char tempstr[MAX_STR_LEN+1]; char tempstr[MAX_STR_LEN+1];
while (strlen(s) > MAX_STR_LEN) { while (strlen(s) > MAX_STR_LEN) {
strncpy_s(tempstr, s, MAX_STR_LEN); strncpy(tempstr, s, MAX_STR_LEN);
tempstr[MAX_STR_LEN-1] = '\0'; tempstr[MAX_STR_LEN-1] = '\0';
s += MAX_STR_LEN - 1; s += MAX_STR_LEN - 1;
AddOneLine(tempstr, r, g, b); AddOneLine(tempstr, r, g, b);

View File

@ -65,9 +65,7 @@ struct tParticleSystemData
CParticle *m_pParticles; CParticle *m_pParticles;
}; };
#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(tParticleSystemData, 0x88); VALIDATE_SIZE(tParticleSystemData, 0x88);
#endif
class cParticleSystemMgr class cParticleSystemMgr
{ {
@ -127,8 +125,6 @@ public:
void RangeCheck(tParticleSystemData *pData) { } void RangeCheck(tParticleSystemData *pData) { }
}; };
#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(cParticleSystemMgr, 0x2420); VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
#endif
extern cParticleSystemMgr mod_ParticleSystemManager; extern cParticleSystemMgr mod_ParticleSystemManager;

View File

@ -123,7 +123,7 @@ void
CPlayerSkin::BeginFrontendSkinEdit(void) CPlayerSkin::BeginFrontendSkinEdit(void)
{ {
LoadPlayerDff(); LoadPlayerDff();
RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB); RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
CWorld::Players[0].LoadPlayerSkin(); CWorld::Players[0].LoadPlayerSkin();
gOldFov = CDraw::GetFOV(); gOldFov = CDraw::GetFOV();
CDraw::SetFOV(30.0f); CDraw::SetFOV(30.0f);

View File

@ -645,7 +645,7 @@ CShadows::StoreShadowForPole(CEntity *pPole, float fOffsetX, float fOffsetY, flo
PolePos.x += -CTimeCycle::GetSunPosition().x * (fPoleHeight / 2); PolePos.x += -CTimeCycle::GetSunPosition().x * (fPoleHeight / 2);
PolePos.y += -CTimeCycle::GetSunPosition().y * (fPoleHeight / 2); PolePos.y += -CTimeCycle::GetSunPosition().y * (fPoleHeight / 2);
StoreStaticShadow((uint32)pPole + nID + _TODOCONST(51), SHADOWTYPE_DARK, gpPostShadowTex, &PolePos, StoreStaticShadow((uintptr)pPole + nID + _TODOCONST(51), SHADOWTYPE_DARK, gpPostShadowTex, &PolePos,
-CTimeCycle::GetSunPosition().x * (fPoleHeight / 2), -CTimeCycle::GetSunPosition().x * (fPoleHeight / 2),
-CTimeCycle::GetSunPosition().y * (fPoleHeight / 2), -CTimeCycle::GetSunPosition().y * (fPoleHeight / 2),
CTimeCycle::GetShadowSideX() * fPoleWidth, CTimeCycle::GetShadowSideX() * fPoleWidth,
@ -1516,7 +1516,7 @@ CShadows::UpdatePermanentShadows(void)
// timePassed == aPermanentShadows[i].m_nLifeTime -> 0 // timePassed == aPermanentShadows[i].m_nLifeTime -> 0
float fMult = 1.0f - float(timePassed - (aPermanentShadows[i].m_nLifeTime * 3 / 4)) / (aPermanentShadows[i].m_nLifeTime / 4); float fMult = 1.0f - float(timePassed - (aPermanentShadows[i].m_nLifeTime * 3 / 4)) / (aPermanentShadows[i].m_nLifeTime / 4);
StoreStaticShadow((uint32)&aPermanentShadows[i], StoreStaticShadow((uintptr)&aPermanentShadows[i],
aPermanentShadows[i].m_nType, aPermanentShadows[i].m_nType,
aPermanentShadows[i].m_pTexture, aPermanentShadows[i].m_pTexture,
&aPermanentShadows[i].m_vecPos, &aPermanentShadows[i].m_vecPos,
@ -1533,7 +1533,7 @@ CShadows::UpdatePermanentShadows(void)
} }
else else
{ {
StoreStaticShadow((uint32)&aPermanentShadows[i], StoreStaticShadow((uintptr)&aPermanentShadows[i],
aPermanentShadows[i].m_nType, aPermanentShadows[i].m_nType,
aPermanentShadows[i].m_pTexture, aPermanentShadows[i].m_pTexture,
&aPermanentShadows[i].m_vecPos, &aPermanentShadows[i].m_vecPos,

View File

@ -52,9 +52,7 @@ public:
{ } { }
}; };
#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CStoredShadow, 0x30); VALIDATE_SIZE(CStoredShadow, 0x30);
#endif
class CPolyBunch class CPolyBunch
{ {
@ -69,9 +67,7 @@ public:
{ } { }
}; };
#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CPolyBunch, 0x6C); VALIDATE_SIZE(CPolyBunch, 0x6C);
#endif
class CStaticShadow class CStaticShadow
{ {
@ -100,9 +96,7 @@ public:
void Free(); void Free();
}; };
#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CStaticShadow, 0x40); VALIDATE_SIZE(CStaticShadow, 0x40);
#endif
class CPermanentShadow class CPermanentShadow
{ {

View File

@ -64,7 +64,7 @@ RwMallocAlign(RwUInt32 size, RwUInt32 align)
ASSERT(mem != nil); ASSERT(mem != nil);
void *addr = (void *)((((RwUInt32)mem) + align) & ~(align - 1)); void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1));
ASSERT(addr != nil); ASSERT(addr != nil);

View File

@ -3,6 +3,7 @@
#pragma warning( pop ) #pragma warning( pop )
#include "common.h" #include "common.h"
#include "crossplatform.h" #include "crossplatform.h"
#include "platform.h"
#include "Timer.h" #include "Timer.h"
#ifdef GTA_PC #ifdef GTA_PC

View File

@ -149,7 +149,7 @@ CVisibilityPlugins::SetupVehicleVariables(RpClump *vehicle)
RpMaterial* RpMaterial*
SetAlphaCB(RpMaterial *material, void *data) SetAlphaCB(RpMaterial *material, void *data)
{ {
((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data; ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data;
return material; return material;
} }
@ -875,7 +875,7 @@ void
CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo) CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo)
{ {
CVehicleModelInfo *vmi; CVehicleModelInfo *vmi;
SetFrameHierarchyId(RpClumpGetFrame(clump), (int32)modelInfo); SetFrameHierarchyId(RpClumpGetFrame(clump), (uintptr)modelInfo);
// Unused // Unused
switch (modelInfo->GetModelType()) { switch (modelInfo->GetModelType()) {

View File

@ -1,5 +1,5 @@
#define WITHWINDOWS
#include "common.h" #include "common.h"
#define USEALTERNATIVEWINFUNCS
#include "crossplatform.h" #include "crossplatform.h"
#include "main.h" #include "main.h"

View File

@ -1,5 +1,5 @@
#define WITHWINDOWS
#include "common.h" #include "common.h"
#define USEALTERNATIVEWINFUNCS
#include "crossplatform.h" #include "crossplatform.h"
#include "FileMgr.h" #include "FileMgr.h"

View File

@ -1,7 +1,9 @@
#include "common.h" #include "common.h"
#define USEALTERNATIVEWINFUNCS
#include "crossplatform.h" #include "crossplatform.h"
// Codes compatible with Windows and Linux
#ifndef _WIN32
// For internal use // For internal use
// wMilliseconds is not needed // wMilliseconds is not needed
void tmToSystemTime(const tm *tm, SYSTEMTIME *out) { void tmToSystemTime(const tm *tm, SYSTEMTIME *out) {
@ -19,8 +21,10 @@ void GetLocalTime_CP(SYSTEMTIME *out) {
tm *localTm = localtime(&timestamp); tm *localTm = localtime(&timestamp);
tmToSystemTime(localTm, out); tmToSystemTime(localTm, out);
} }
#endif
#if !defined _WIN32 || defined __MINGW32__ // Compatible with Linux/POSIX and MinGW on Windows
#ifndef _WIN32
HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char newpathname[32]; char newpathname[32];
strncpy(newpathname, pathname, 32); strncpy(newpathname, pathname, 32);
@ -34,7 +38,7 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
strncpy(firstfile->extension, "", sizeof(firstfile->extension)); strncpy(firstfile->extension, "", sizeof(firstfile->extension));
HANDLE d; HANDLE d;
if ((d = opendir(path)) == NULL || !FindNextFile(d, firstfile)) if ((d = (HANDLE)opendir(path)) == NULL || !FindNextFile(d, firstfile))
return NULL; return NULL;
return d; return d;
@ -45,7 +49,7 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) {
static struct stat fileStats; static struct stat fileStats;
static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1]; static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1];
int extensionLen = strlen(finddata->extension); int extensionLen = strlen(finddata->extension);
while ((file = readdir(d)) != NULL) { while ((file = readdir((DIR*)d)) != NULL) {
// We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type. // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type.
if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) && if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) &&
@ -79,3 +83,119 @@ void FileTimeToSystemTime(time_t* writeTime, SYSTEMTIME* out) {
tmToSystemTime(ptm, out); tmToSystemTime(ptm, out);
} }
#endif #endif
// Funcs/features from Windows that we need on other platforms
#ifndef _WIN32
char *strupr(char *s) {
char* tmp = s;
for (;*tmp;++tmp) {
*tmp = toupper((unsigned char) *tmp);
}
return s;
}
char *strlwr(char *s) {
char* tmp = s;
for (;*tmp;++tmp) {
*tmp = tolower((unsigned char) *tmp);
}
return s;
}
char *trim(char *s) {
char *ptr;
if (!s)
return NULL; // handle NULL string
if (!*s)
return s; // handle empty string
for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); --ptr);
ptr[1] = '\0';
return s;
}
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
// r must have strlen(path) + 2 bytes
int casepath(char const *path, char *r)
{
size_t l = strlen(path);
char *p = (char*)alloca(l + 1);
strcpy(p, path);
// my addon: change \'s with /
char *nextBs;
while(nextBs = strstr(p, "\\")){
*nextBs = '/';
}
// my addon: linux doesn't handle filenames with spaces at the end nicely
p = trim(p);
size_t rl = 0;
DIR *d;
if (p[0] == '/')
{
d = opendir("/");
p = p + 1;
}
else
{
d = opendir(".");
r[0] = '.';
r[1] = 0;
rl = 1;
}
int last = 0;
char *c = strsep(&p, "/");
while (c)
{
if (!d)
{
return 0;
}
if (last)
{
closedir(d);
return 0;
}
r[rl] = '/';
rl += 1;
r[rl] = 0;
struct dirent *e = readdir(d);
while (e)
{
if (strcasecmp(c, e->d_name) == 0)
{
strcpy(r + rl, e->d_name);
rl += strlen(e->d_name);
closedir(d);
d = opendir(r);
break;
}
e = readdir(d);
}
if (!e)
{
strcpy(r + rl, c);
rl += strlen(c);
last = 1;
}
c = strsep(&p, "/");
}
if (d) closedir(d);
return 1;
}
#endif

View File

@ -1,10 +1,38 @@
#include <time.h> #include <time.h>
// This is the common include for platform/renderer specific skeletons(glfw, win etc.) and cross platform things (like Windows directories wrapper, platform specific global arrays etc.) // This is the common include for platform/renderer specific skeletons(glfw.cpp, win.cpp etc.) and using cross platform things (like Windows directories wrapper, platform specific global arrays etc.)
// Functions that's different on glfw and win but have same signature, should be located on platform.h.
// This only has <windef.h> as Win header.
#ifdef _WIN32 #ifdef _WIN32
// This only has <windef.h> as Win header.
#include "win.h" #include "win.h"
extern DWORD _dwOperatingSystemVersion;
#else
char *strupr(char *str);
char *strlwr(char *str);
enum {
OS_WIN98,
OS_WIN2000,
OS_WINNT,
OS_WINXP,
};
enum {
LANG_OTHER,
LANG_GERMAN,
LANG_FRENCH,
LANG_ENGLISH,
LANG_ITALIAN,
LANG_SPANISH,
};
enum {
SUBLANG_OTHER,
SUBLANG_ENGLISH_AUS
};
extern long _dwOperatingSystemVersion;
int casepath(char const *path, char *r);
#endif #endif
#ifdef RW_GL3 #ifdef RW_GL3
@ -14,8 +42,8 @@ typedef struct
RwBool fullScreen; RwBool fullScreen;
RwV2d lastMousePos; RwV2d lastMousePos;
double mouseWheel; // glfw doesn't cache it double mouseWheel; // glfw doesn't cache it
int8 joy1id; RwInt8 joy1id;
int8 joy2id; RwInt8 joy2id;
} }
psGlobalType; psGlobalType;
@ -44,17 +72,6 @@ enum eGameState
extern RwUInt32 gGameState; extern RwUInt32 gGameState;
RwBool IsForegroundApp(); RwBool IsForegroundApp();
void InitialiseLanguage();
RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode);
RwChar** _psGetVideoModeList();
RwInt32 _psGetNumVideModes();
void _psSelectScreenVM(RwInt32 videoMode);
void HandleExit();
void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs);
// Mostly wrappers around Windows functions
#ifndef MAX_PATH #ifndef MAX_PATH
#if !defined _WIN32 || defined __MINGW32__ #if !defined _WIN32 || defined __MINGW32__
@ -64,39 +81,39 @@ void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs);
#endif #endif
#endif #endif
// TODO: Remove USEALTERNATIVEWINFUNCS and don't use it anywhere when re3 becomes fully cross-platform, this is for testing
// Codes compatible with Windows and Linux // Codes compatible with Windows and Linux
#if defined USEALTERNATIVEWINFUNCS || !defined _WIN32 || defined __MINGW32__ #ifndef _WIN32
#define DeleteFile unlink #define DeleteFile unlink
// Needed for save games // Needed for save games
struct SYSTEMTIME { struct SYSTEMTIME {
uint16 wYear; RwUInt16 wYear;
uint16 wMonth; RwUInt16 wMonth;
uint16 wDayOfWeek; RwUInt16 wDayOfWeek;
uint16 wDay; RwUInt16 wDay;
uint16 wHour; RwUInt16 wHour;
uint16 wMinute; RwUInt16 wMinute;
uint16 wSecond; RwUInt16 wSecond;
uint16 wMilliseconds; RwUInt16 wMilliseconds;
}; };
void GetLocalTime_CP(SYSTEMTIME* out); void GetLocalTime_CP(SYSTEMTIME* out);
#define GetLocalTime GetLocalTime_CP #define GetLocalTime GetLocalTime_CP
#define OutputDebugString(s) re3_debug("[DBG-2]: " s "\n") #define OutputDebugString(s) re3_debug("[DBG-2]: %s\n",s)
#endif #endif
// Only runs on GNU/POSIX/etc. // Compatible with Linux/POSIX and MinGW on Windows
#if !defined _WIN32 || defined __MINGW32__ #ifndef _WIN32
#include <iostream> #include <iostream>
#include <dirent.h> #include <dirent.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <langinfo.h> #include <langinfo.h>
#include <unistd.h>
typedef DIR* HANDLE; typedef void* HANDLE;
#define INVALID_HANDLE_VALUE NULL #define INVALID_HANDLE_VALUE NULL
#define FindClose closedir #define FindClose(h) closedir((DIR*)h)
#define LOCALE_USER_DEFAULT 0 #define LOCALE_USER_DEFAULT 0
#define DATE_SHORTDATE 0 #define DATE_SHORTDATE 0
@ -107,7 +124,7 @@ struct WIN32_FIND_DATA {
time_t ftLastWriteTime; time_t ftLastWriteTime;
}; };
HANDLE FindFirstFile(char*, WIN32_FIND_DATA*); HANDLE FindFirstFile(const char*, WIN32_FIND_DATA*);
bool FindNextFile(HANDLE, WIN32_FIND_DATA*); bool FindNextFile(HANDLE, WIN32_FIND_DATA*);
void FileTimeToSystemTime(time_t*, SYSTEMTIME*); void FileTimeToSystemTime(time_t*, SYSTEMTIME*);
void GetDateFormat(int, int, SYSTEMTIME*, int, char*, int); void GetDateFormat(int, int, SYSTEMTIME*, int, char*, int);

View File

@ -7,14 +7,11 @@
#pragma warning( disable : 4005) #pragma warning( disable : 4005)
#pragma warning( pop ) #pragma warning( pop )
#pragma comment( lib, "Winmm.lib" ) // Needed for time
#if (defined(_MSC_VER)) #if (defined(_MSC_VER))
#include <tchar.h> #include <tchar.h>
#endif /* (defined(_MSC_VER)) */ #endif /* (defined(_MSC_VER)) */
#include <stdio.h> #include <stdio.h>
#include "rwcore.h" #include "rwcore.h"
#include "resource.h"
#include "skeleton.h" #include "skeleton.h"
#include "platform.h" #include "platform.h"
#include "crossplatform.h" #include "crossplatform.h"
@ -69,14 +66,20 @@ static psGlobalType PsGlobal;
#define JIF(x) if (FAILED(hr=(x))) \ #define JIF(x) if (FAILED(hr=(x))) \
{debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;} {debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;}
unsigned long _dwMemAvailPhys;
// TODO: This is used on selecting video mode, so either think something or remove it completely
DWORD _dwMemTotalVideo = 1024 * (1024 * 1024); // 1024 MB as placeholder
DWORD _dwMemAvailPhys;
DWORD _dwOperatingSystemVersion;
RwUInt32 gGameState; RwUInt32 gGameState;
#ifdef _WIN32
DWORD _dwOperatingSystemVersion;
#include "resource.h"
#else
long _dwOperatingSystemVersion;
#include <sys/sysinfo.h>
#include <stddef.h>
#include <locale.h>
#include <signal.h>
#include <errno.h>
#endif
/* /*
***************************************************************************** *****************************************************************************
*/ */
@ -144,7 +147,7 @@ const char *_psGetUserFilesFolder()
strcpy(szUserFiles, "data"); strcpy(szUserFiles, "data");
return szUserFiles; return szUserFiles;
#else #else
static CHAR szUserFiles[256]; static char szUserFiles[256];
strcpy(szUserFiles, "userfiles"); strcpy(szUserFiles, "userfiles");
_psCreateFolder(szUserFiles); _psCreateFolder(szUserFiles);
return szUserFiles; return szUserFiles;
@ -185,6 +188,8 @@ psCameraShowRaster(RwCamera *camera)
/* /*
***************************************************************************** *****************************************************************************
*/ */
#ifdef _WIN32
#pragma comment( lib, "Winmm.lib" ) // Needed for time
RwUInt32 RwUInt32
psTimer(void) psTimer(void)
{ {
@ -202,6 +207,16 @@ psTimer(void)
return time; return time;
} }
#else
double
psTimer(void)
{
struct timespec start;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
return start.tv_sec * 1000.0 + start.tv_nsec/1000000.0;
}
#endif
/* /*
***************************************************************************** *****************************************************************************
@ -209,12 +224,7 @@ psTimer(void)
void void
psMouseSetPos(RwV2d *pos) psMouseSetPos(RwV2d *pos)
{ {
POINT point; glfwSetCursorPos(PSGLOBAL(window), pos->x, pos->y);
point.x = (RwInt32) pos->x;
point.y = (RwInt32) pos->y;
glfwSetCursorPos(PSGLOBAL(window), point.x, point.y);
PSGLOBAL(lastMousePos.x) = (RwInt32)pos->x; PSGLOBAL(lastMousePos.x) = (RwInt32)pos->x;
@ -285,7 +295,7 @@ psInitialise(void)
gGameState = GS_START_UP; gGameState = GS_START_UP;
TRACE("gGameState = GS_START_UP"); TRACE("gGameState = GS_START_UP");
#ifdef _WIN32
OSVERSIONINFO verInfo; OSVERSIONINFO verInfo;
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
@ -330,14 +340,19 @@ psInitialise(void)
_dwMemAvailPhys = memstats.dwAvailPhys; _dwMemAvailPhys = memstats.dwAvailPhys;
#ifdef FIX_BUGS
debug("Physical memory size %u\n", memstats.dwTotalPhys); debug("Physical memory size %u\n", memstats.dwTotalPhys);
debug("Available physical memory %u\n", memstats.dwAvailPhys); debug("Available physical memory %u\n", memstats.dwAvailPhys);
#else #else
debug("Physical memory size %d\n", memstats.dwTotalPhys); struct sysinfo systemInfo;
debug("Available physical memory %d\n", memstats.dwAvailPhys); sysinfo(&systemInfo);
#endif
_dwMemAvailPhys = systemInfo.freeram;
_dwOperatingSystemVersion = OS_WINXP; // To fool other classes
debug("Physical memory size %u\n", systemInfo.totalram);
debug("Available physical memory %u\n", systemInfo.freeram);
#endif
TheText.Unload(); TheText.Unload();
return TRUE; return TRUE;
@ -413,18 +428,8 @@ RwChar **_psGetVideoModeList()
if ( vm.flags & rwVIDEOMODEEXCLUSIVE ) if ( vm.flags & rwVIDEOMODEEXCLUSIVE )
{ {
if ( vm.width >= 640 _VMList[i] = (RwChar*)RwCalloc(100, sizeof(RwChar));
&& vm.height >= 480 rwsprintf(_VMList[i],"%lu X %lu X %lu", vm.width, vm.height, vm.depth);
&& (vm.width == 640
&& vm.height == 480)
|| !(vm.flags & rwVIDEOMODEEXCLUSIVE)
|| (_dwMemTotalVideo - vm.depth * vm.height * vm.width / 8) > (12 * 1024 * 1024)/*12 MB*/ )
{
_VMList[i] = (RwChar*)RwCalloc(100, sizeof(RwChar));
rwsprintf(_VMList[i],"%lu X %lu X %lu", vm.width, vm.height, vm.depth);
}
else
_VMList[i] = nil;
} }
else else
_VMList[i] = nil; _VMList[i] = nil;
@ -445,6 +450,8 @@ void _psSelectScreenVM(RwInt32 videoMode)
if (!_psSetVideoMode(RwEngineGetCurrentSubSystem(), videoMode)) if (!_psSetVideoMode(RwEngineGetCurrentSubSystem(), videoMode))
{ {
RsGlobal.quit = TRUE; RsGlobal.quit = TRUE;
printf("ERROR: Failed to select new screen resolution\n");
} }
else else
FrontEndMenuManager.LoadAllTextures(); FrontEndMenuManager.LoadAllTextures();
@ -589,7 +596,7 @@ psSelectDevice()
#ifdef DEFAULT_NATIVE_RESOLUTION #ifdef DEFAULT_NATIVE_RESOLUTION
GcurSelVM = 1; GcurSelVM = 1;
#else #else
MessageBox(nil, "Cannot find 640x480 video mode", "GTA3", MB_OK); printf("WARNING: Cannot find 640x480 video mode, selecting device cancelled\n");
return FALSE; return FALSE;
#endif #endif
} }
@ -602,8 +609,9 @@ psSelectDevice()
FrontEndMenuManager.m_nPrefsHeight == 0 || FrontEndMenuManager.m_nPrefsHeight == 0 ||
FrontEndMenuManager.m_nPrefsDepth == 0){ FrontEndMenuManager.m_nPrefsDepth == 0){
// Defaults if nothing specified // Defaults if nothing specified
FrontEndMenuManager.m_nPrefsWidth = GetSystemMetrics(SM_CXSCREEN); const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
FrontEndMenuManager.m_nPrefsHeight = GetSystemMetrics(SM_CYSCREEN); FrontEndMenuManager.m_nPrefsWidth = mode->width;
FrontEndMenuManager.m_nPrefsHeight = mode->height;
FrontEndMenuManager.m_nPrefsDepth = 32; FrontEndMenuManager.m_nPrefsDepth = 32;
FrontEndMenuManager.m_nPrefsWindowed = 0; FrontEndMenuManager.m_nPrefsWindowed = 0;
} }
@ -632,7 +640,7 @@ psSelectDevice()
} }
if(bestFsMode < 0){ if(bestFsMode < 0){
MessageBox(nil, "Cannot find desired video mode", "GTA3", MB_OK); printf("WARNING: Cannot find desired video mode, selecting device cancelled\n");
return FALSE; return FALSE;
} }
GcurSelVM = bestFsMode; GcurSelVM = bestFsMode;
@ -886,6 +894,30 @@ CommandLineToArgv(RwChar *cmdLine, RwInt32 *argCount)
*/ */
void InitialiseLanguage() void InitialiseLanguage()
{ {
#ifndef _WIN32
// Mandatory for Linux(Unix? Posix?) to set lang. to environment lang.
setlocale(LC_ALL, "");
char *systemLang, *keyboardLang;
systemLang = setlocale (LC_ALL, NULL);
keyboardLang = setlocale (LC_CTYPE, NULL);
short primUserLCID, primSystemLCID;
primUserLCID = primSystemLCID = !strncmp(systemLang, "fr_",3) ? LANG_FRENCH :
!strncmp(systemLang, "de_",3) ? LANG_GERMAN :
!strncmp(systemLang, "en_",3) ? LANG_ENGLISH :
!strncmp(systemLang, "it_",3) ? LANG_ITALIAN :
!strncmp(systemLang, "es_",3) ? LANG_SPANISH :
LANG_OTHER;
short primLayout = !strncmp(keyboardLang, "fr_",3) ? LANG_FRENCH : (!strncmp(keyboardLang, "de_",3) ? LANG_GERMAN : LANG_ENGLISH);
short subUserLCID, subSystemLCID;
subUserLCID = subSystemLCID = !strncmp(systemLang, "en_AU",5) ? SUBLANG_ENGLISH_AUS : SUBLANG_OTHER;
short subLayout = !strncmp(keyboardLang, "en_AU",5) ? SUBLANG_ENGLISH_AUS : SUBLANG_OTHER;
#else
WORD primUserLCID = PRIMARYLANGID(GetSystemDefaultLCID()); WORD primUserLCID = PRIMARYLANGID(GetSystemDefaultLCID());
WORD primSystemLCID = PRIMARYLANGID(GetUserDefaultLCID()); WORD primSystemLCID = PRIMARYLANGID(GetUserDefaultLCID());
WORD primLayout = PRIMARYLANGID((DWORD)GetKeyboardLayout(0)); WORD primLayout = PRIMARYLANGID((DWORD)GetKeyboardLayout(0));
@ -893,7 +925,7 @@ void InitialiseLanguage()
WORD subUserLCID = SUBLANGID(GetSystemDefaultLCID()); WORD subUserLCID = SUBLANGID(GetSystemDefaultLCID());
WORD subSystemLCID = SUBLANGID(GetUserDefaultLCID()); WORD subSystemLCID = SUBLANGID(GetUserDefaultLCID());
WORD subLayout = SUBLANGID((DWORD)GetKeyboardLayout(0)); WORD subLayout = SUBLANGID((DWORD)GetKeyboardLayout(0));
#endif
if ( primUserLCID == LANG_GERMAN if ( primUserLCID == LANG_GERMAN
|| primSystemLCID == LANG_GERMAN || primSystemLCID == LANG_GERMAN
|| primLayout == LANG_GERMAN ) || primLayout == LANG_GERMAN )
@ -987,13 +1019,22 @@ void InitialiseLanguage()
TheText.Unload(); TheText.Unload();
TheText.Load(); TheText.Load();
#ifndef _WIN32
// TODO this is needed for strcasecmp to work correctly across all languages, but can these cause other problems??
setlocale(LC_CTYPE, "C");
setlocale(LC_COLLATE, "C");
setlocale(LC_NUMERIC, "C");
#endif
} }
/* /*
***************************************************************************** *****************************************************************************
*/ */
void HandleExit() void HandleExit()
{ {
#ifdef _WIN32
MSG message; MSG message;
while ( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) ) while ( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
{ {
@ -1007,8 +1048,21 @@ void HandleExit()
DispatchMessage(&message); DispatchMessage(&message);
} }
} }
#else
// We now handle terminate message always, why handle on some cases?
return;
#endif
} }
#ifndef _WIN32
void terminateHandler(int sig, siginfo_t *info, void *ucontext) {
RsGlobal.quit = TRUE;
}
void dummyHandler(int sig){
}
#endif
void resizeCB(GLFWwindow* window, int width, int height) { void resizeCB(GLFWwindow* window, int width, int height) {
/* /*
* Handle event to ensure window contents are displayed during re-size * Handle event to ensure window contents are displayed during re-size
@ -1210,17 +1264,36 @@ cursorCB(GLFWwindow* window, double xpos, double ypos) {
/* /*
***************************************************************************** *****************************************************************************
*/ */
#ifdef _WIN32
int PASCAL int PASCAL
WinMain(HINSTANCE instance, WinMain(HINSTANCE instance,
HINSTANCE prevInstance __RWUNUSED__, HINSTANCE prevInstance __RWUNUSED__,
CMDSTR cmdLine, CMDSTR cmdLine,
int cmdShow) int cmdShow)
{ {
RwV2d pos;
RwInt32 argc, i; RwInt32 argc;
RwChar** argv; RwChar** argv;
StaticPatcher::Apply();
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
#else
int
main(int argc, char *argv[])
{
#endif
RwV2d pos;
RwInt32 i;
// StaticPatcher::Apply();
#ifndef _WIN32
struct sigaction act;
act.sa_sigaction = terminateHandler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL);
struct sigaction sa;
sa.sa_handler = dummyHandler;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL); // Needed for CdStreamPosix
#endif
/* /*
* Initialize the platform independent data. * Initialize the platform independent data.
@ -1231,7 +1304,7 @@ WinMain(HINSTANCE instance,
return FALSE; return FALSE;
} }
#ifdef _WIN32
/* /*
* Get proper command line params, cmdLine passed to us does not * Get proper command line params, cmdLine passed to us does not
* work properly under all circumstances... * work properly under all circumstances...
@ -1248,6 +1321,7 @@ WinMain(HINSTANCE instance,
* Parse command line parameters (except program name) one at * Parse command line parameters (except program name) one at
* a time BEFORE RenderWare initialization... * a time BEFORE RenderWare initialization...
*/ */
#endif
for(i=1; i<argc; i++) for(i=1; i<argc; i++)
{ {
RsEventHandler(rsPREINITCOMMANDLINE, argv[i]); RsEventHandler(rsPREINITCOMMANDLINE, argv[i]);
@ -1303,8 +1377,7 @@ WinMain(HINSTANCE instance,
RsEventHandler(rsCAMERASIZE, &r); RsEventHandler(rsCAMERASIZE, &r);
} }
#ifdef _WIN32
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, nil, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, nil, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, nil, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, nil, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, nil, SPIF_SENDCHANGE);
@ -1319,7 +1392,7 @@ WinMain(HINSTANCE instance,
NewStickyKeys.dwFlags = SKF_TWOKEYSOFF; NewStickyKeys.dwFlags = SKF_TWOKEYSOFF;
SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &NewStickyKeys, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &NewStickyKeys, SPIF_SENDCHANGE);
#endif
{ {
CFileMgr::SetDirMyDocuments(); CFileMgr::SetDirMyDocuments();
@ -1335,7 +1408,9 @@ WinMain(HINSTANCE instance,
CFileMgr::SetDir(""); CFileMgr::SetDir("");
} }
#ifdef _WIN32
SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
#ifndef MASTER #ifndef MASTER
if (TurnOnAnimViewer) { if (TurnOnAnimViewer) {
@ -1380,7 +1455,7 @@ WinMain(HINSTANCE instance,
case GS_INIT_ONCE: case GS_INIT_ONCE:
{ {
CoUninitialize(); //CoUninitialize();
LoadingScreen(nil, nil, "loadsc0"); LoadingScreen(nil, nil, "loadsc0");
@ -1549,6 +1624,7 @@ WinMain(HINSTANCE instance,
*/ */
RsEventHandler(rsTERMINATE, nil); RsEventHandler(rsTERMINATE, nil);
#ifdef _WIN32
/* /*
* Free the argv strings... * Free the argv strings...
*/ */
@ -1557,9 +1633,8 @@ WinMain(HINSTANCE instance,
SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, nil, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, nil, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, nil, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, nil, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, nil, SPIF_SENDCHANGE);
SetErrorMode(0); SetErrorMode(0);
#endif
return 0; return 0;
} }

View File

@ -9,8 +9,11 @@ extern "C"
{ {
#endif /* __cplusplus */ #endif /* __cplusplus */
#ifdef _WIN32
extern RwUInt32 psTimer(void); extern RwUInt32 psTimer(void);
#else
extern double psTimer(void);
#endif
extern RwBool psInitialise(void); extern RwBool psInitialise(void);
extern void psTerminate(void); extern void psTerminate(void);
@ -31,6 +34,19 @@ extern RwBool psInstallFileSystem(void);
/* Handle native texture support */ /* Handle native texture support */
extern RwBool psNativeTextureSupport(void); extern RwBool psNativeTextureSupport(void);
extern void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs);
extern void HandleExit();
extern void _psSelectScreenVM(RwInt32 videoMode);
extern void InitialiseLanguage();
extern RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode);
extern RwChar** _psGetVideoModeList();
extern RwInt32 _psGetNumVideModes();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -19,7 +19,11 @@ bool TurnOnAnimViewer = false;
RsGlobalType RsGlobal; RsGlobalType RsGlobal;
#ifdef _WIN32
RwUInt32 RwUInt32
#else
double
#endif
RsTimer(void) RsTimer(void)
{ {
return psTimer(); return psTimer();

View File

@ -257,7 +257,11 @@ extern RwBool
RsInputDeviceAttach(RsInputDeviceType inputDevice, RsInputDeviceAttach(RsInputDeviceType inputDevice,
RsInputEventHandler inputEventHandler); RsInputEventHandler inputEventHandler);
#ifdef _WIN32
extern RwUInt32 extern RwUInt32
#else
extern double
#endif
RsTimer(void); RsTimer(void);
extern void extern void

View File

@ -100,10 +100,10 @@ IVideoWindow *pVW = nil;
IMediaSeeking *pMS = nil; IMediaSeeking *pMS = nil;
DWORD dwDXVersion; DWORD dwDXVersion;
DWORD _dwMemTotalPhys; SIZE_T _dwMemTotalPhys;
DWORD _dwMemAvailPhys; SIZE_T _dwMemAvailPhys;
DWORD _dwMemTotalVirtual; SIZE_T _dwMemTotalVirtual;
DWORD _dwMemAvailVirtual; SIZE_T _dwMemAvailVirtual;
DWORD _dwMemTotalVideo; DWORD _dwMemTotalVideo;
DWORD _dwMemAvailVideo; DWORD _dwMemAvailVideo;
DWORD _dwOperatingSystemVersion; DWORD _dwOperatingSystemVersion;
@ -687,10 +687,10 @@ psInitialise(void)
_GetVideoMemInfo(&_dwMemTotalVideo, &_dwMemAvailVideo); _GetVideoMemInfo(&_dwMemTotalVideo, &_dwMemAvailVideo);
#ifdef FIX_BUGS #ifdef FIX_BUGS
debug("Physical memory size %u\n", _dwMemTotalPhys); debug("Physical memory size %lu\n", _dwMemTotalPhys);
debug("Available physical memory %u\n", _dwMemAvailPhys); debug("Available physical memory %lu\n", _dwMemAvailPhys);
debug("Video memory size %u\n", _dwMemTotalVideo); debug("Video memory size %lu\n", _dwMemTotalVideo);
debug("Available video memory %u\n", _dwMemAvailVideo); debug("Available video memory %lu\n", _dwMemAvailVideo);
#else #else
debug("Physical memory size %d\n", _dwMemTotalPhys); debug("Physical memory size %d\n", _dwMemTotalPhys);
debug("Available physical memory %d\n", _dwMemAvailPhys); debug("Available physical memory %d\n", _dwMemAvailPhys);

View File

@ -22,7 +22,6 @@ enum eWinVersion
OS_WINXP, OS_WINXP,
}; };
extern DWORD _dwOperatingSystemVersion;
#ifdef __DINPUT_INCLUDED__ #ifdef __DINPUT_INCLUDED__
/* platform specfic global data */ /* platform specfic global data */

View File

@ -658,11 +658,11 @@ void CCranes::Load(uint8* buf, uint32 size)
for (int i = 0; i < NUM_CRANES; i++) { for (int i = 0; i < NUM_CRANES; i++) {
CCrane *pCrane = &aCranes[i]; CCrane *pCrane = &aCranes[i];
if (pCrane->m_pCraneEntity != nil) if (pCrane->m_pCraneEntity != nil)
pCrane->m_pCraneEntity = CPools::GetBuildingPool()->GetSlot((uint32)pCrane->m_pCraneEntity - 1); pCrane->m_pCraneEntity = CPools::GetBuildingPool()->GetSlot((uintptr)pCrane->m_pCraneEntity - 1);
if (pCrane->m_pHook != nil) if (pCrane->m_pHook != nil)
pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uint32)pCrane->m_pHook - 1); pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uintptr)pCrane->m_pHook - 1);
if (pCrane->m_pVehiclePickedUp != nil) if (pCrane->m_pVehiclePickedUp != nil)
pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uint32)pCrane->m_pVehiclePickedUp - 1); pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1);
} }
for (int i = 0; i < NUM_CRANES; i++) { for (int i = 0; i < NUM_CRANES; i++) {
aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]); aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]);

View File

@ -997,9 +997,13 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
for ( int32 i = 0; i < 16; i++ ) for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f); CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
CVector dist = point->point - (*source); #ifndef FIX_BUGS
CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(ahead.x, ahead.y, 0.0f); CVector dist = point->point - (*source);
CVector smokePos = *source + offset; CVector offset = dist - Max(0.2f * dist.Magnitude(), 2.0f) * CVector(ahead.x, ahead.y, 0.0f);
CVector smokePos = *source + offset;
#else
CVector smokePos = point->point;
#endif // !FIX_BUGS
smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
@ -1016,9 +1020,13 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
for ( int32 i = 0; i < 16; i++ ) for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f); CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
#ifndef FIX_BUGS
CVector dist = point->point - (*source); CVector dist = point->point - (*source);
CVector offset = dist - Max(0.2f*dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f); CVector offset = dist - Max(0.2f*dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f);
CVector smokePos = *source + offset; CVector smokePos = *source + offset;
#else
CVector smokePos = point->point;
#endif // !FIX_BUGS
CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f)); CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
@ -1230,7 +1238,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if ( cantStandup ) if ( cantStandup )
victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false); victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
victimPed->InflictDamage(nil, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point.pieceB, localDir); victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point.pieceB, localDir);
if ( victimPed->m_nPedType == PEDTYPE_COP ) if ( victimPed->m_nPedType == PEDTYPE_COP )
CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000); CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
@ -1265,9 +1273,13 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
for ( int32 i = 0; i < 16; i++ ) for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f); CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f);
#ifndef FIX_BUGS
CVector dist = point.point - (*fireSource); CVector dist = point.point - (*fireSource);
CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f); CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f);
CVector smokePos = *fireSource + offset; CVector smokePos = *fireSource + offset;
#else
CVector smokePos = point.point;
#endif
CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f)); CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
@ -1280,9 +1292,13 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
for ( int32 i = 0; i < 16; i++ ) for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f); CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f);
#ifndef FIX_BUGS
CVector dist = point.point - (*fireSource); CVector dist = point.point - (*fireSource);
CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f); CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f);
CVector smokePos = *fireSource + offset; CVector smokePos = *fireSource + offset;
#else
CVector smokePos = point.point;
#endif
smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);