1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-12-23 01:30:00 +00:00
This commit is contained in:
Fire-Head 2020-12-07 21:50:18 +03:00
commit 87bca997a4
212 changed files with 36053 additions and 29491 deletions

View file

@ -23,7 +23,7 @@ jobs:
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1
uses: microsoft/setup-msbuild@v1.0.2
- uses: actions/checkout@v2
with:
submodules: 'true'

View file

@ -23,7 +23,7 @@ jobs:
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1
uses: microsoft/setup-msbuild@v1.0.2
- uses: actions/checkout@v2
with:
submodules: 'true'

44
CMakeLists.txt Normal file
View file

@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.8)
project(re3 C CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
if(WIN32)
set(RE3_AUDIOS "NULL" "OAL" "MSS")
else()
set(RE3_AUDIOS "NULL" "OAL")
endif()
set(RE3_AUDIO "OAL" CACHE STRING "Audio")
set_property(CACHE RE3_AUDIO PROPERTY STRINGS ${RE3_AUDIOS})
message(STATUS "RE3_AUDIO = ${RE3_AUDIO} (choices=${RE3_AUDIOS})")
set("RE3_AUDIO_${RE3_AUDIO}" ON)
if(NOT RE3_AUDIO IN_LIST RE3_AUDIOS)
message(FATAL_ERROR "Illegal RE3_AUDIO=${RE3_AUDIO}")
endif()
if(RE3_INSTALL)
include(GNUInstallDirs)
set(RE3_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/re3")
endif()
add_subdirectory("vendor/librw")
add_subdirectory(src)
if(RE3_INSTALL)
include(CMakePackageConfigHelpers)
configure_package_config_file(re3-config.cmake.in re3-config.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/re3-config.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(
EXPORT re3-targets
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
include(CMakeCPack.cmake)
endif()

View file

@ -1,6 +1,6 @@
# re3
[![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg/branch/master?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master)
<a href="https://discord.gg/jYpXxTm"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://discord.gg/aKYAwCx92H"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
| Platform | Debug | Release |
|------------------|-------------|-------------|
| Windows Direct3D9 | [![Download](https://api.bintray.com/packages/gtamodding/re3/Debug_win-x86-librw_d3d9-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Debug_win-x86-librw_d3d9-mss/_latestVersion) | [![Download](https://api.bintray.com/packages/gtamodding/re3/Release_win-x86-librw_d3d9-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Release_win-x86-librw_d3d9-mss/_latestVersion) |
@ -21,14 +21,18 @@ such that we have a working game at all times.
## Preparing the environment for building
- Clone the repo using the argument `--recursive`.
- 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.
- **If you use 64-bit D3D9**: We don't ship 64-bit Dx9 SDK. You need to download it from Microsoft if you don't have it(although it should come pre-installed after some Windows version)
You may want to point GTA_III_RE_DIR environment variable to GTA3 root folder if you want executable to be moved there via post-build script.
- For Linux, proceed: [Building on Linux](https://github.com/GTAmodding/re3/wiki/Building-on-Linux)
- For FreeBSD, proceed: [Building on FreeBSD](https://github.com/GTAmodding/re3/wiki/Building-on-FreeBSD)
- For Windows, assuming you have Visual Studio:
- Clone the repo using the argument `--recursive`.
- Run one of the `premake-vsXXXX.cmd` variants on root folder.
- Open the project via Visual Studio
**If you use 64-bit D3D9**: We don't ship 64-bit Dx9 SDK. You need to download it from Microsoft if you don't have it(although it should come pre-installed after some Windows version)
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: **If you choose OpenAL on Windows** You must read [Running OpenAL build on Windows](https://github.com/GTAmodding/re3/wiki/Running-OpenAL-build-on-Windows).
@ -40,7 +44,15 @@ Please read the [Coding Style](https://github.com/GTAmodding/re3/blob/master/COD
### Unreversed / incomplete classes (at least the ones we know)
The following classes have only unused or practically unused code left:
```
CCullZone - only mobile stuff
CCullZones - only mobile stuff
CMemoryHeap - only on PS2
NameGrid.cpp - only on mobile (a player name grid, either a very early player name code ala GTA1 or a multiplayer leftover)
PedDebug.cpp - only on mobile (debug code)
HandlingMgr.cpp - debug functions from mobile
CVehicle::ProcessBikeWheel - early bike code (only on mobile)
CAutomobile::DebugCode - debug function from mobile
CBoat::DebugCode - debug function from mobile
CBoat::ModifyHandlingValue - debug function from mobile
CBoat::DisplayHandlingData - debug function from mobile
TexturePools - only on PC (slight RW modification that we don't actually need)
```

28
cmake/FindMPG123.cmake Normal file
View file

@ -0,0 +1,28 @@
# - Find mpg123
# Find the native mpg123 includes and library
#
# MPG123_INCLUDE_DIR - where to find mpg123.h
# MPG123_LIBRARIES - List of libraries when using mpg123.
# MPG123_FOUND - True if mpg123 found.
IF(MPG123_INCLUDE_DIR AND MPG123_LIBRARIES)
# Already in cache, be silent
SET(MPG123_FIND_QUIETLY TRUE)
ENDIF(MPG123_INCLUDE_DIR AND MPG123_LIBRARIES)
FIND_PATH(MPG123_INCLUDE_DIR mpg123.h
PATHS "${MPG123_DIR}"
PATH_SUFFIXES include
)
FIND_LIBRARY(MPG123_LIBRARIES NAMES mpg123 mpg123-0
PATHS "${MPG123_DIR}"
PATH_SUFFIXES lib
)
# MARK_AS_ADVANCED(MPG123_LIBRARIES MPG123_INCLUDE_DIR)
# handle the QUIETLY and REQUIRED arguments and set MPG123_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MPG123 DEFAULT_MSG MPG123_LIBRARIES MPG123_INCLUDE_DIR)

67
cmake/FindSndFile.cmake Normal file
View file

@ -0,0 +1,67 @@
# Found on http://hg.kvats.net
#
# - Try to find libsndfile
#
# Once done this will define
#
# SNDFILE_FOUND - system has libsndfile
# SNDFILE_INCLUDE_DIRS - the libsndfile include directory
# SNDFILE_LIBRARIES - Link these to use libsndfile
#
# Copyright (C) 2006 Wengo
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (SNDFILE_LIBRARIES AND SNDFILE_INCLUDE_DIRS)
# in cache already
set(SNDFILE_FOUND TRUE)
else (SNDFILE_LIBRARIES AND SNDFILE_INCLUDE_DIRS)
find_path(SNDFILE_INCLUDE_DIR
NAMES
sndfile.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
find_library(SNDFILE_LIBRARY
NAMES
sndfile
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(SNDFILE_INCLUDE_DIRS
${SNDFILE_INCLUDE_DIR}
)
set(SNDFILE_LIBRARIES
${SNDFILE_LIBRARY}
)
if (SNDFILE_INCLUDE_DIRS AND SNDFILE_LIBRARIES)
set(SNDFILE_FOUND TRUE)
endif (SNDFILE_INCLUDE_DIRS AND SNDFILE_LIBRARIES)
if (SNDFILE_FOUND)
if (NOT SndFile_FIND_QUIETLY)
message(STATUS "Found libsndfile: ${SNDFILE_LIBRARIES}")
endif (NOT SndFile_FIND_QUIETLY)
else (SNDFILE_FOUND)
if (SndFile_FIND_REQUIRED)
message(FATAL_ERROR "Could not find libsndfile")
endif (SndFile_FIND_REQUIRED)
endif (SNDFILE_FOUND)
# show the SNDFILE_INCLUDE_DIRS and SNDFILE_LIBRARIES variables only in the advanced view
mark_as_advanced(SNDFILE_INCLUDE_DIRS SNDFILE_LIBRARIES)
endif (SNDFILE_LIBRARIES AND SNDFILE_INCLUDE_DIRS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -92,7 +92,10 @@ workspace "re3"
filter { "system:bsd" }
platforms {
"bsd-amd64-librw_gl3_glfw-oal"
"bsd-x86-librw_gl3_glfw-oal",
"bsd-amd64-librw_gl3_glfw-oal",
"bsd-arm-librw_gl3_glfw-oal",
"bsd-arm64-librw_gl3_glfw-oal"
}
filter { "system:macosx" }
@ -122,9 +125,11 @@ workspace "re3"
filter { "platforms:*x86*" }
architecture "x86"
floatingpoint "Fast"
filter { "platforms:*amd64*" }
architecture "amd64"
floatingpoint "Fast"
filter { "platforms:*arm*" }
architecture "ARM"
@ -184,6 +189,18 @@ project "librw"
files { path.join(Librw, "src/*.*") }
files { path.join(Librw, "src/*/*.*") }
filter { "platforms:*x86*" }
architecture "x86"
floatingpoint "Fast"
filter { "platforms:*amd64*" }
architecture "amd64"
floatingpoint "Fast"
filter "platforms:win*"
staticruntime "on"
buildoptions { "/Zc:sizedDealloc-" }
filter "platforms:bsd*"
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
@ -194,6 +211,9 @@ project "librw"
includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" }
libdirs { "/usr/local/lib" }
filter "platforms:*gl3_glfw*"
staticruntime "off"
filter "platforms:*RW33*"
flags { "ExcludeFromBuild" }
@ -214,6 +234,7 @@ project "re3"
files { addSrcFiles("src/audio") }
files { addSrcFiles("src/audio/eax") }
files { addSrcFiles("src/audio/oal") }
files { addSrcFiles("src/collision") }
files { addSrcFiles("src/control") }
files { addSrcFiles("src/core") }
files { addSrcFiles("src/entities") }
@ -236,6 +257,7 @@ project "re3"
includedirs { "src/audio" }
includedirs { "src/audio/eax" }
includedirs { "src/audio/oal" }
includedirs { "src/collision" }
includedirs { "src/control" }
includedirs { "src/core" }
includedirs { "src/entities" }
@ -284,9 +306,17 @@ project "re3"
filter "platforms:win*"
files { addSrcFiles("src/skel/win") }
includedirs { "src/skel/win" }
buildoptions { "/Zc:sizedDealloc-" }
linkoptions "/SAFESEH:NO"
characterset ("MBCS")
targetextension ".exe"
if(_OPTIONS["with-librw"]) then
-- external librw is dynamic
staticruntime "on"
end
filter "platforms:win*glfw*"
staticruntime "off"
filter "platforms:win*oal"
includedirs { "vendor/openal-soft/include" }
@ -322,7 +352,6 @@ project "re3"
end
filter "platforms:*RW33*"
staticruntime "on"
includedirs { "sdk/rwsdk/include/d3d8" }
libdirs { "sdk/rwsdk/lib/d3d8/release" }
links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse" }

113
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,113 @@
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
if(${RE3_AUDIO} STREQUAL "OAL")
find_package(OpenAL REQUIRED)
find_package(MPG123 REQUIRED)
find_package(SndFile REQUIRED)
endif()
file(GLOB_RECURSE Sources "*.cpp" "*.h")
MACRO(HEADER_DIRECTORIES return_list)
FILE(GLOB_RECURSE new_list *.cpp)
SET(dir_list "animation"
"audio"
"collision"
"control"
"core"
"entities"
"extras"
"fakerw"
"math"
"modelinfo"
"objects"
"peds"
"render"
"rw"
"save"
"skel"
"text"
"vehicles"
"weapons")
FOREACH(file_path ${new_list})
GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
SET(dir_list ${dir_list} ${dir_path})
ENDFOREACH()
LIST(REMOVE_DUPLICATES dir_list)
SET(${return_list} ${dir_list})
ENDMACRO()
HEADER_DIRECTORIES(header_list)
include_directories(${header_list})
add_executable(re3 ${Sources})
target_link_libraries(re3 librw)
target_link_libraries(re3 Threads::Threads)
if(${RE3_AUDIO} STREQUAL "OAL")
target_link_libraries(re3 ${OPENAL_LIBRARY})
target_link_libraries(re3 ${MPG123_LIBRARIES})
target_link_libraries(re3 ${SNDFILE_LIBRARIES})
endif()
target_include_directories(re3
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
)
target_compile_definitions(re3
PRIVATE
"$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>"
PUBLIC
"RW_${RE3_PLATFORM}"
)
target_compile_definitions(re3 PRIVATE LIBRW=1 AUDIO_OAL=1)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(re3
PRIVATE
"-Wall"
)
if (NOT RE3_PLATFORM_PS2)
target_compile_options(re3
PRIVATE
"-Wextra"
"-Wdouble-promotion"
"-Wpedantic"
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(re3
PUBLIC
/wd4996 /wd4244
)
endif()
set_target_properties(re3
PROPERTIES
C_STANDARD 11
C_EXTENSIONS OFF
C_STANDARD_REQUIRED ON
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
PREFIX ""
)
if(RE3_INSTALL)
target_include_directories(re3
INTERFACE
$<INSTALL_INTERFACE:${RE3_INSTALL_INCLUDEDIR}>
)
install(
TARGETS re3
EXPORT re3-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
endif()

View file

@ -5,7 +5,7 @@
#include "RpAnimBlend.h"
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
CAnimBlendAssociation::CAnimBlendAssociation(void)
{

View file

@ -13,7 +13,7 @@ enum {
ASSOC_MOVEMENT = 0x20, // ???
ASSOC_HAS_TRANSLATION = 0x40,
ASSOC_WALK = 0x80, // for CPed::PlayFootSteps(void)
ASSOC_FLAG_XPRESS = 0x100, // only used by xpress scratch, see CPed::Chat(void)
ASSOC_IDLE = 0x100, // only used by xpress scratch, see CPed::Chat(void)
ASSOC_NOWALK = 0x200, // see CPed::PlayFootSteps(void)
ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
ASSOC_FRONTAL = 0x800, // anims that we fall to front

View file

@ -1,7 +1,7 @@
#include "common.h"
#include "AnimBlendClumpData.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
CAnimBlendClumpData::CAnimBlendClumpData(void)

View file

@ -30,15 +30,14 @@ void
CAnimBlendHierarchy::CalcTotalTime(void)
{
int i, j;
float totalTime = 0.0f;
totalLength = 0.0f;
for(i = 0; i < numSequences; i++){
float seqTime = 0.0f;
for(j = 0; j < sequences[i].numFrames; j++)
seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
totalTime = Max(totalTime, seqTime);
totalLength = Max(totalLength, seqTime);
}
totalLength = totalTime;
}
void
@ -61,6 +60,12 @@ CAnimBlendHierarchy::RemoveAnimSequences(void)
void
CAnimBlendHierarchy::Uncompress(void)
{
#ifdef ANIM_COMPRESSION
int i;
assert(compressed);
for(i = 0; i < numSequences; i++)
sequences[i].Uncompress();
#endif
if(totalLength == 0.0f)
CalcTotalTime();
compressed = 0;
@ -69,6 +74,22 @@ CAnimBlendHierarchy::Uncompress(void)
void
CAnimBlendHierarchy::RemoveUncompressedData(void)
{
// useless
#ifdef ANIM_COMPRESSION
int i;
assert(!compressed);
for(i = 0; i < numSequences; i++)
sequences[i].RemoveUncompressedData();
#endif
compressed = 1;
}
#ifdef USE_CUSTOM_ALLOCATOR
void
CAnimBlendHierarchy::MoveMemory(bool onlyone)
{
int i;
for(i = 0; i < numSequences; i++)
if(sequences[i].MoveMemory() && onlyone)
return;
}
#endif

View file

@ -2,6 +2,10 @@
#include "templates.h"
#ifdef MoveMemory
#undef MoveMemory // windows shit
#endif
class CAnimBlendSequence;
// A collection of sequences
@ -23,6 +27,7 @@ public:
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
void MoveMemory(bool onlyone = false);
};
VALIDATE_SIZE(CAnimBlendHierarchy, 0x28);

View file

@ -1,6 +1,7 @@
#include "common.h"
#include "AnimBlendSequence.h"
#include "MemoryHeap.h"
CAnimBlendSequence::CAnimBlendSequence(void)
{
@ -15,6 +16,7 @@ CAnimBlendSequence::CAnimBlendSequence(void)
CAnimBlendSequence::~CAnimBlendSequence(void)
{
assert(keyFramesCompressed == nil);
if(keyFrames)
RwFree(keyFrames);
}
@ -60,3 +62,138 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
last = frame->rotation;
}
}
void
CAnimBlendSequence::Uncompress(void)
{
int i;
if(numFrames == 0)
return;
PUSH_MEMID(MEMID_ANIMATION);
float rotScale = 1.0f/4096.0f;
float timeScale = 1.0f/60.0f;
float transScale = 1.0f/128.0f;
if(type & KF_TRANS){
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans));
KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed;
KeyFrameTrans *kf = (KeyFrameTrans*)newKfs;
for(i = 0; i < numFrames; i++){
kf->rotation.x = ckf->rot[0]*rotScale;
kf->rotation.y = ckf->rot[1]*rotScale;
kf->rotation.z = ckf->rot[2]*rotScale;
kf->rotation.w = ckf->rot[3]*rotScale;
kf->deltaTime = ckf->deltaTime*timeScale;
kf->translation.x = ckf->trans[0]*transScale;
kf->translation.y = ckf->trans[1]*transScale;
kf->translation.z = ckf->trans[2]*transScale;
kf++;
ckf++;
}
keyFrames = newKfs;
}else{
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame));
KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed;
KeyFrame *kf = (KeyFrame*)newKfs;
for(i = 0; i < numFrames; i++){
kf->rotation.x = ckf->rot[0]*rotScale;
kf->rotation.y = ckf->rot[1]*rotScale;
kf->rotation.z = ckf->rot[2]*rotScale;
kf->rotation.w = ckf->rot[3]*rotScale;
kf->deltaTime = ckf->deltaTime*timeScale;
kf++;
ckf++;
}
keyFrames = newKfs;
}
REGISTER_MEMPTR(&keyFrames);
RwFree(keyFramesCompressed);
keyFramesCompressed = nil;
POP_MEMID();
}
void
CAnimBlendSequence::CompressKeyframes(void)
{
int i;
if(numFrames == 0)
return;
PUSH_MEMID(MEMID_ANIMATION);
float rotScale = 4096.0f;
float timeScale = 60.0f;
float transScale = 128.0f;
if(type & KF_TRANS){
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed));
KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs;
KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames;
for(i = 0; i < numFrames; i++){
ckf->rot[0] = kf->rotation.x*rotScale;
ckf->rot[1] = kf->rotation.y*rotScale;
ckf->rot[2] = kf->rotation.z*rotScale;
ckf->rot[3] = kf->rotation.w*rotScale;
ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
ckf->trans[0] = kf->translation.x*transScale;
ckf->trans[1] = kf->translation.y*transScale;
ckf->trans[2] = kf->translation.z*transScale;
kf++;
ckf++;
}
keyFramesCompressed = newKfs;
}else{
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed));
KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs;
KeyFrame *kf = (KeyFrame*)keyFrames;
for(i = 0; i < numFrames; i++){
ckf->rot[0] = kf->rotation.x*rotScale;
ckf->rot[1] = kf->rotation.y*rotScale;
ckf->rot[2] = kf->rotation.z*rotScale;
ckf->rot[3] = kf->rotation.w*rotScale;
ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
kf++;
ckf++;
}
keyFramesCompressed = newKfs;
}
REGISTER_MEMPTR(&keyFramesCompressed);
POP_MEMID();
}
void
CAnimBlendSequence::RemoveUncompressedData(void)
{
if(numFrames == 0)
return;
CompressKeyframes();
RwFree(keyFrames);
keyFrames = nil;
}
#ifdef USE_CUSTOM_ALLOCATOR
bool
CAnimBlendSequence::MoveMemory(void)
{
if(keyFrames){
void *newaddr = gMainHeap.MoveMemory(keyFrames);
if(newaddr != keyFrames){
keyFrames = newaddr;
return true;
}
}else if(keyFramesCompressed){
void *newaddr = gMainHeap.MoveMemory(keyFramesCompressed);
if(newaddr != keyFramesCompressed){
keyFramesCompressed = newaddr;
return true;
}
}
return false;
}
#endif

View file

@ -2,6 +2,10 @@
#include "Quaternion.h"
#ifdef MoveMemory
#undef MoveMemory // windows shit
#endif
// TODO: put them somewhere else?
struct KeyFrame {
CQuaternion rotation;
@ -12,6 +16,15 @@ struct KeyFrameTrans : KeyFrame {
CVector translation;
};
struct KeyFrameCompressed {
int16 rot[4]; // 4096
int16 deltaTime; // 60
};
struct KeyFrameTransCompressed : KeyFrameCompressed {
int16 trans[3]; // 128
};
// The sequence of key frames of one animated node
class CAnimBlendSequence
@ -41,10 +54,10 @@ public:
&((KeyFrame*)keyFrames)[n];
}
bool HasTranslation(void) { return !!(type & KF_TRANS); }
// TODO? these are unused
// void Uncompress(void);
// void CompressKeyframes(void);
// void RemoveUncompressedData(void);
void Uncompress(void);
void CompressKeyframes(void);
void RemoveUncompressedData(void);
bool MoveMemory(void);
#ifdef PED_SKIN
void SetBoneTag(int tag) { boneTag = tag; }

View file

@ -176,7 +176,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
{ ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_FLAG_XPRESS },
{ ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },

File diff suppressed because it is too large Load diff

View file

@ -167,7 +167,7 @@ cAudioManager::SetEntityStatus(int32 id, uint8 status)
}
void
cAudioManager::PlayOneShot(int32 index, int16 sound, float vol)
cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
{
static const uint8 OneShotPriority[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 4, 4, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View file

@ -332,7 +332,7 @@ public:
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
uint8 GetNum3DProvidersAvailable() const;
int32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission, float velocityChange);
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
@ -351,7 +351,7 @@ public:
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
void PlayLoadedMissionAudio();
void PlayOneShot(int32 index, int16 sound, float vol);
void PlayOneShot(int32 index, uint16 sound, float vol);
void PlaySuspectLastSeen(float x, float y, float z);
void PlayerJustGotInCar() const;
void PlayerJustLeftCar() const;
@ -362,29 +362,29 @@ public:
void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
void ProcessActiveQueues();
bool ProcessAirBrakes(cVehicleParams *params);
bool ProcessAirBrakes(cVehicleParams& params);
void ProcessAirportScriptObject(uint8 sound);
bool ProcessBoatEngine(cVehicleParams *params);
bool ProcessBoatMovingOverWater(cVehicleParams *params);
bool ProcessBoatEngine(cVehicleParams& params);
bool ProcessBoatMovingOverWater(cVehicleParams& params);
void ProcessBridge();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
void ProcessBridgeWarning();
bool ProcessCarBombTick(cVehicleParams *params);
void ProcessCesna(cVehicleParams *params);
bool ProcessCarBombTick(cVehicleParams& params);
void ProcessCesna(cVehicleParams& params);
void ProcessCinemaScriptObject(uint8 sound);
void ProcessCrane();
void ProcessDocksScriptObject(uint8 sound);
bool ProcessEngineDamage(cVehicleParams *params);
bool ProcessEngineDamage(cVehicleParams& params);
void ProcessEntity(int32 sound);
void ProcessExplosions(int32 explosion);
void ProcessFireHydrant();
void ProcessFires(int32 entity);
void ProcessFrontEnd();
void ProcessGarages();
bool ProcessHelicopter(cVehicleParams *params);
bool ProcessHelicopter(cVehicleParams& params);
void ProcessHomeScriptObject(uint8 sound);
void ProcessJumbo(cVehicleParams *);
void ProcessJumbo(cVehicleParams& params);
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
void ProcessJumboFlying();
@ -394,37 +394,37 @@ public:
void ProcessLaunderetteScriptObject(uint8 sound);
void ProcessLoopingScriptObject(uint8 sound);
void ProcessMissionAudio();
void ProcessModelCarEngine(cVehicleParams *params);
void ProcessModelCarEngine(cVehicleParams& params);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessPed(CPhysical *ped);
void ProcessPedHeadphones(cPedParams *params);
void ProcessPedOneShots(cPedParams *params);
void ProcessPedHeadphones(cPedParams &params);
void ProcessPedOneShots(cPedParams &params);
void ProcessPhysical(int32 id);
void ProcessPlane(cVehicleParams *params);
void ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *automobile);
void ProcessPlane(cVehicleParams& params);
void ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile);
void ProcessPoliceCellBeatingScriptObject(uint8 sound);
void ProcessPornCinema(uint8 sound);
void ProcessProjectiles();
void ProcessRainOnVehicle(cVehicleParams *params);
void ProcessRainOnVehicle(cVehicleParams& params);
void ProcessReverb() const;
bool ProcessReverseGear(cVehicleParams *params);
bool ProcessReverseGear(cVehicleParams& params);
void ProcessSawMillScriptObject(uint8 sound);
void ProcessScriptObject(int32 id);
void ProcessShopScriptObject(uint8 sound);
void ProcessSpecial();
bool ProcessTrainNoise(cVehicleParams *params);
bool ProcessTrainNoise(cVehicleParams& params);
void ProcessVehicle(CVehicle *vehicle);
bool ProcessVehicleDoors(cVehicleParams *params);
void ProcessVehicleEngine(cVehicleParams *params);
void ProcessVehicleHorn(cVehicleParams *params);
void ProcessVehicleOneShots(cVehicleParams *params);
bool ProcessVehicleReverseWarning(cVehicleParams *params);
bool ProcessVehicleRoadNoise(cVehicleParams *params);
bool ProcessVehicleSirenOrAlarm(cVehicleParams *params);
bool ProcessVehicleSkidding(cVehicleParams *params);
bool ProcessVehicleDoors(cVehicleParams& params);
void ProcessVehicleEngine(cVehicleParams& params);
void ProcessVehicleHorn(cVehicleParams& params);
void ProcessVehicleOneShots(cVehicleParams& params);
bool ProcessVehicleReverseWarning(cVehicleParams& params);
bool ProcessVehicleRoadNoise(cVehicleParams& params);
bool ProcessVehicleSirenOrAlarm(cVehicleParams& params);
bool ProcessVehicleSkidding(cVehicleParams& params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool ProcessWetRoadNoise(cVehicleParams *params);
bool ProcessWetRoadNoise(cVehicleParams& params);
void ProcessWorkShopScriptObject(uint8 sound);
int32 RandomDisplacement(uint32 seed) const;
@ -462,7 +462,7 @@ public:
bool SetupJumboRumbleSound(uint8 emittingVol);
bool SetupJumboTaxiSound(uint8 vol);
bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
void SetupPedComments(cPedParams *params, uint32 sound);
void SetupPedComments(cPedParams &params, uint16 sound);
void SetupSuspectLastSeenReport();
void Terminate();

View file

@ -161,7 +161,7 @@ cMusicManager::DisplayRadioStationName()
CFont::SetPropOn();
CFont::SetFontStyle(FONT_HEADING);
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
CFont::SetColor(CRGBA(0, 0, 0, 255));
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);

View file

@ -10,13 +10,15 @@
#ifdef _WIN32
#pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123-0.lib" )
#else
#include "crossplatform.h"
#endif
#include <sndfile.h>
#include <mpg123.h>
#endif
#ifndef _WIN32
#include "crossplatform.h"
#endif
#ifndef AUDIO_OPUS
class CSndFile : public IDecoder
{

View file

@ -65,7 +65,7 @@ uint32 _CurMP3Index;
int32 _CurMP3Pos;
bool _bIsMp3Active;
#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
bool _bUseHDDAudio;
char _aHDDPath[MAX_PATH];
#endif
@ -1043,7 +1043,7 @@ cSampleManager::Initialise(void)
if ( !m_bInitialised )
{
#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
FrontEndMenuManager.WaitForUserCD();
if ( FrontEndMenuManager.m_bQuitGameNoCD )
{
@ -1060,7 +1060,7 @@ cSampleManager::Initialise(void)
}
}
#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
// hddaudio
/**
Option for user to play audio files directly from hard disk.
@ -1297,17 +1297,17 @@ cSampleManager::Terminate(void)
bool
cSampleManager::CheckForAnAudioFileOnCD(void)
{
#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
char filepath[MAX_PATH];
#if defined(GTA3_1_1_PATCH)
#if GTA_VERSION >= GTA3_PC_11
if (_bUseHDDAudio)
strcpy(filepath, _aHDDPath);
else
strcpy(filepath, m_szCDRomRootPath);
#else
strcpy(filepath, m_szCDRomRootPath);
#endif // #if defined(GTA3_1_1_PATCH)
#endif // #if GTA_VERSION >= GTA3_PC_11
strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
@ -1324,13 +1324,13 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
#else
return true;
#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
#endif // #if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
}
char
cSampleManager::GetCDAudioDriveLetter(void)
{
#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
if (_bUseHDDAudio)
{
if ( strlen(_aHDDPath) != 0 )

21
src/collision/ColBox.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "common.h"
#include "ColBox.h"
void
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
{
this->min = min;
this->max = max;
this->surface = surf;
this->piece = piece;
}
CColBox&
CColBox::operator=(const CColBox& other)
{
min = other.min;
max = other.max;
surface = other.surface;
piece = other.piece;
return *this;
}

16
src/collision/ColBox.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include "SurfaceTable.h"
struct CColBox
{
CVector min;
CVector max;
uint8 surface;
uint8 piece;
void Set(const CVector &min, const CVector &max, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
CVector GetSize(void) { return max - min; }
CColBox& operator=(const CColBox &other);
};

View file

@ -0,0 +1,9 @@
#include "common.h"
#include "ColLine.h"
void
CColLine::Set(const CVector &p0, const CVector &p1)
{
this->p0 = p0;
this->p1 = p1;
}

14
src/collision/ColLine.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
struct CColLine
{
// NB: this has to be compatible with two CVuVectors
CVector p0;
int pad0;
CVector p1;
int pad1;
CColLine(void) { };
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
void Set(const CVector &p0, const CVector &p1);
};

190
src/collision/ColModel.cpp Normal file
View file

@ -0,0 +1,190 @@
#include "common.h"
#include "ColModel.h"
#include "Game.h"
#include "MemoryHeap.h"
CColModel::CColModel(void)
{
numSpheres = 0;
spheres = nil;
numLines = 0;
lines = nil;
numBoxes = 0;
boxes = nil;
numTriangles = 0;
vertices = nil;
triangles = nil;
trianglePlanes = nil;
level = CGame::currLevel;
ownsCollisionVolumes = true;
}
CColModel::~CColModel(void)
{
RemoveCollisionVolumes();
RemoveTrianglePlanes();
}
void
CColModel::RemoveCollisionVolumes(void)
{
if(ownsCollisionVolumes){
RwFree(spheres);
RwFree(lines);
RwFree(boxes);
RwFree(vertices);
RwFree(triangles);
}
numSpheres = 0;
numLines = 0;
numBoxes = 0;
numTriangles = 0;
spheres = nil;
lines = nil;
boxes = nil;
vertices = nil;
triangles = nil;
}
void
CColModel::CalculateTrianglePlanes(void)
{
PUSH_MEMID(MEMID_COLLISION);
// HACK: allocate space for one more element to stuff the link pointer into
trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1));
REGISTER_MEMPTR(&trianglePlanes);
for(int i = 0; i < numTriangles; i++)
trianglePlanes[i].Set(vertices, triangles[i]);
POP_MEMID();
}
void
CColModel::RemoveTrianglePlanes(void)
{
RwFree(trianglePlanes);
trianglePlanes = nil;
}
void
CColModel::SetLinkPtr(CLink<CColModel*> *lptr)
{
assert(trianglePlanes);
*(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]) = lptr;
}
CLink<CColModel*>*
CColModel::GetLinkPtr(void)
{
assert(trianglePlanes);
return *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]);
}
void
CColModel::GetTrianglePoint(CVector &v, int i) const
{
v = vertices[i].Get();
}
CColModel&
CColModel::operator=(const CColModel &other)
{
int i;
int numVerts;
boundingSphere = other.boundingSphere;
boundingBox = other.boundingBox;
// copy spheres
if(other.numSpheres){
if(numSpheres != other.numSpheres){
numSpheres = other.numSpheres;
if(spheres)
RwFree(spheres);
spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
}
for(i = 0; i < numSpheres; i++)
spheres[i] = other.spheres[i];
}else{
numSpheres = 0;
if(spheres)
RwFree(spheres);
spheres = nil;
}
// copy lines
if(other.numLines){
if(numLines != other.numLines){
numLines = other.numLines;
if(lines)
RwFree(lines);
lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
}
for(i = 0; i < numLines; i++)
lines[i] = other.lines[i];
}else{
numLines = 0;
if(lines)
RwFree(lines);
lines = nil;
}
// copy boxes
if(other.numBoxes){
if(numBoxes != other.numBoxes){
numBoxes = other.numBoxes;
if(boxes)
RwFree(boxes);
boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
}
for(i = 0; i < numBoxes; i++)
boxes[i] = other.boxes[i];
}else{
numBoxes = 0;
if(boxes)
RwFree(boxes);
boxes = nil;
}
// copy mesh
if(other.numTriangles){
// copy vertices
numVerts = 0;
for(i = 0; i < other.numTriangles; i++){
if(other.triangles[i].a > numVerts)
numVerts = other.triangles[i].a;
if(other.triangles[i].b > numVerts)
numVerts = other.triangles[i].b;
if(other.triangles[i].c > numVerts)
numVerts = other.triangles[i].c;
}
numVerts++;
if(vertices)
RwFree(vertices);
if(numVerts){
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
for(i = 0; i < numVerts; i++)
vertices[i] = other.vertices[i];
}
// copy triangles
if(numTriangles != other.numTriangles){
numTriangles = other.numTriangles;
if(triangles)
RwFree(triangles);
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
}
for(i = 0; i < numTriangles; i++)
triangles[i] = other.triangles[i];
}else{
numTriangles = 0;
if(triangles)
RwFree(triangles);
triangles = nil;
if(vertices)
RwFree(vertices);
vertices = nil;
}
return *this;
}

37
src/collision/ColModel.h Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include "templates.h"
#include "ColBox.h"
#include "ColSphere.h"
#include "ColLine.h"
#include "ColPoint.h"
#include "ColTriangle.h"
struct CColModel
{
CColSphere boundingSphere;
CColBox boundingBox;
int16 numSpheres;
int16 numLines;
int16 numBoxes;
int16 numTriangles;
int32 level;
bool ownsCollisionVolumes; // missing on PS2
CColSphere *spheres;
CColLine *lines;
CColBox *boxes;
CompressedVector *vertices;
CColTriangle *triangles;
CColTrianglePlane *trianglePlanes;
CColModel(void);
~CColModel(void);
void RemoveCollisionVolumes(void);
void CalculateTrianglePlanes(void);
void RemoveTrianglePlanes(void);
CLink<CColModel*> *GetLinkPtr(void);
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
CColModel& operator=(const CColModel& other);
};

View file

@ -0,0 +1,16 @@
#include "common.h"
#include "ColPoint.h"
CColPoint&
CColPoint::operator=(const CColPoint &other)
{
point = other.point;
normal = other.normal;
surfaceA = other.surfaceA;
pieceA = other.pieceA;
surfaceB = other.surfaceB;
pieceB = other.pieceB;
// no depth?
return *this;
}

34
src/collision/ColPoint.h Normal file
View file

@ -0,0 +1,34 @@
#pragma once
struct CColPoint
{
CVector point;
int pad1;
// the surface normal on the surface of point
CVector normal;
int pad2;
uint8 surfaceA;
uint8 pieceA;
uint8 surfaceB;
uint8 pieceB;
float depth;
const CVector &GetNormal() { return normal; }
float GetDepth() { return depth; }
void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
this->depth = depth;
this->surfaceA = surfA;
this->pieceA = pieceA;
this->surfaceB = surfB;
this->pieceB = pieceB;
}
void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
this->surfaceA = surfA;
this->pieceA = pieceA;
this->surfaceB = surfB;
this->pieceB = pieceB;
}
CColPoint &operator=(const CColPoint &other);
};

View file

@ -0,0 +1,11 @@
#include "common.h"
#include "ColSphere.h"
void
CColSphere::Set(float radius, const CVector &center, uint8 surf, uint8 piece)
{
this->radius = radius;
this->center = center;
this->surface = surf;
this->piece = piece;
}

13
src/collision/ColSphere.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include "SurfaceTable.h"
struct CColSphere
{
// NB: this has to be compatible with a CVuVector
CVector center;
float radius;
uint8 surface;
uint8 piece;
void Set(float radius, const CVector &center, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
};

View file

@ -0,0 +1,41 @@
#include "common.h"
#include "ColTriangle.h"
void
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
{
this->a = a;
this->b = b;
this->c = c;
this->surface = surf;
}
#ifdef VU_COLLISION
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
CVector norm = CrossProduct(vc-va, vb-va);
norm.Normalise();
float d = DotProduct(norm, va);
normal.x = norm.x*4096.0f;
normal.y = norm.y*4096.0f;
normal.z = norm.z*4096.0f;
dist = d*128.0f;
}
#else
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
normal = CrossProduct(vc-va, vb-va);
normal.Normalise();
dist = DotProduct(normal, va);
CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z));
// find out largest component and its direction
if(an.x > an.y && an.x > an.z)
dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS;
else if(an.y > an.z)
dir = normal.y < 0.0f ? DIR_Y_NEG : DIR_Y_POS;
else
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
}
#endif

View file

@ -0,0 +1,68 @@
#pragma once
#include "CompressedVector.h"
enum Direction {
DIR_X_POS,
DIR_X_NEG,
DIR_Y_POS,
DIR_Y_NEG,
DIR_Z_POS,
DIR_Z_NEG,
};
struct CColTriangle
{
uint16 a;
uint16 b;
uint16 c;
uint8 surface;
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
};
struct CColTrianglePlane
{
#ifdef VU_COLLISION
CompressedVector normal;
int16 dist;
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; }
float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"lh $11, 6(%1)\n"
"pextlw $10, $8\n"
"pextlw $11, $9\n"
"pextlw $2, $11, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$11", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = normal.x;
qword[1] = normal.y;
qword[2] = normal.z;
qword[3] = dist;
}
#endif
#else
CVector normal;
float dist;
uint8 dir;
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n = normal; }
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
#endif
};

View file

@ -23,303 +23,8 @@
#include "Collision.h"
#include "Frontend.h"
// TODO: where do these go?
#ifdef VU_COLLISION
struct VuTriangle
{
// Compressed int16 but unpacked
#ifdef GTA_PS2
uint128 v0;
uint128 v1;
uint128 v2;
uint128 plane;
#else
int32 v0[4];
int32 v1[4];
int32 v2[4];
int32 plane[4];
#endif
};
#ifndef GTA_PS2
static int16 vi01;
static CVuVector vf01;
static CVuVector vf02;
static CVuVector vf03;
CVuVector
DistanceBetweenSphereAndLine(const CVuVector &center, const CVuVector &p0, const CVuVector &line)
{
// center VF12
// p0 VF14
// line VF15
CVuVector ret; // VF16
CVuVector p1 = p0+line;
CVuVector dist0 = center - p0; // VF20
CVuVector dist1 = center - p1; // VF25
float lenSq = line.MagnitudeSqr(); // VF21
float distSq0 = dist0.MagnitudeSqr(); // VF22
float distSq1 = dist1.MagnitudeSqr();
float dot = DotProduct(dist0, line); // VF23
if(dot < 0.0f){
// not above line, closest to p0
ret = p0;
ret.w = distSq0;
return ret;
}
float t = dot/lenSq; // param of nearest point on infinite line
if(t > 1.0f){
// not above line, closest to p1
ret = p1;
ret.w = distSq1;
return ret;
}
// closest to line
ret = p0 + line*t;
ret.w = (ret - center).MagnitudeSqr();
return ret;
}
inline int SignFlags(const CVector &v)
{
int f = 0;
if(v.x < 0.0f) f |= 1;
if(v.y < 0.0f) f |= 2;
if(v.z < 0.0f) f |= 4;
return f;
}
#endif
extern "C" void
LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1,
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
const CVuVector &plane)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf13, 0x0(%1)\n"
"lqc2 vf14, 0x0(%2)\n"
"lqc2 vf15, 0x0(%3)\n"
"lqc2 vf16, 0x0(%4)\n"
"lqc2 vf17, 0x0(%5)\n"
"vcallms Vu0LineToTriangleCollisionStart\n"
".set reorder\n"
:
: "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
);
#else
float dot0 = DotProduct(plane, p0);
float dot1 = DotProduct(plane, p1);
float dist0 = plane.w - dot0;
float dist1 = plane.w - dot1;
// if points are on the same side, no collision
if(dist0 * dist1 > 0.0f){
vi01 = 0;
return;
}
CVuVector diff = p1 - p0;
float t = dist0/(dot1 - dot0);
CVuVector p = p0 + diff*t;
p.w = 0.0f;
vf01 = p;
vf03.x = t;
// Check if point is inside
CVector cross1 = CrossProduct(p-v0, v1-v0);
CVector cross2 = CrossProduct(p-v1, v2-v1);
CVector cross3 = CrossProduct(p-v2, v0-v2);
// Only check relevant directions
int flagmask = 0;
if(Abs(plane.x) > 0.5f) flagmask |= 1;
if(Abs(plane.y) > 0.5f) flagmask |= 2;
if(Abs(plane.z) > 0.5f) flagmask |= 4;
int flags1 = SignFlags(cross1) & flagmask;
int flags2 = SignFlags(cross2) & flagmask;
int flags3 = SignFlags(cross3) & flagmask;
// inside if on the same side of all edges
if(flags1 != flags2 || flags1 != flags3){
vi01 = 0;
return;
}
vi01 = 1;
vf02 = plane;
return;
#endif
}
extern "C" void
LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf13, 0x0(%1)\n"
"lqc2 vf14, 0x0(%2)\n"
"lqc2 vf15, 0x10(%2)\n"
"lqc2 vf16, 0x20(%2)\n"
"lqc2 vf17, 0x30(%2)\n"
"vcallms Vu0LineToTriangleCollisionCompressedStart\n"
".set reorder\n"
:
: "r" (&p0), "r" (&p1), "r" (&tri)
);
#else
CVuVector v0, v1, v2, plane;
v0.x = tri.v0[0]/128.0f;
v0.y = tri.v0[1]/128.0f;
v0.z = tri.v0[2]/128.0f;
v0.w = tri.v0[3]/128.0f;
v1.x = tri.v1[0]/128.0f;
v1.y = tri.v1[1]/128.0f;
v1.z = tri.v1[2]/128.0f;
v1.w = tri.v1[3]/128.0f;
v2.x = tri.v2[0]/128.0f;
v2.y = tri.v2[1]/128.0f;
v2.z = tri.v2[2]/128.0f;
v2.w = tri.v2[3]/128.0f;
plane.x = tri.plane[0]/4096.0f;
plane.y = tri.plane[1]/4096.0f;
plane.z = tri.plane[2]/4096.0f;
plane.w = tri.plane[3]/128.0f;
LineToTriangleCollision(p0, p1, v0, v1, v2, plane);
#endif
}
extern "C" void
SphereToTriangleCollision(const CVuVector &sph,
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
const CVuVector &plane)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf14, 0x0(%1)\n"
"lqc2 vf15, 0x0(%2)\n"
"lqc2 vf16, 0x0(%3)\n"
"lqc2 vf17, 0x0(%4)\n"
"vcallms Vu0SphereToTriangleCollisionStart\n"
".set reorder\n"
:
: "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
);
#else
float planedist = DotProduct(plane, sph) - plane.w; // VF02
if(Abs(planedist) > sph.w){
vi01 = 0;
return;
}
// point on plane
CVuVector p = sph - planedist*plane;
p.w = 0.0f;
vf01 = p;
planedist = Abs(planedist);
// edges
CVuVector v01 = v1 - v0;
CVuVector v12 = v2 - v1;
CVuVector v20 = v0 - v2;
// VU code calculates normal again for some weird reason...
// Check sides of point
CVector cross1 = CrossProduct(p-v0, v01);
CVector cross2 = CrossProduct(p-v1, v12);
CVector cross3 = CrossProduct(p-v2, v20);
// Only check relevant directions
int flagmask = 0;
if(Abs(plane.x) > 0.1f) flagmask |= 1;
if(Abs(plane.y) > 0.1f) flagmask |= 2;
if(Abs(plane.z) > 0.1f) flagmask |= 4;
int nflags = SignFlags(plane) & flagmask;
int flags1 = SignFlags(cross1) & flagmask;
int flags2 = SignFlags(cross2) & flagmask;
int flags3 = SignFlags(cross3) & flagmask;
int testcase = 0;
CVuVector closest(0.0f, 0.0f, 0.0f); // VF04
if(flags1 == nflags){
closest += v2;
testcase++;
}
if(flags2 == nflags){
closest += v0;
testcase++;
}
if(flags3 == nflags){
closest += v1;
testcase++;
}
if(testcase == 3){
// inside triangle - dist to plane already checked
vf02 = plane;
vf02.w = vf03.x = planedist;
vi01 = 1;
}else if(testcase == 1){
// outside two sides - closest to point opposide inside edge
vf01 = closest;
vf02 = sph - closest;
float distSq = vf02.MagnitudeSqr();
vi01 = sph.w*sph.w > distSq;
vf03.x = Sqrt(distSq);
vf02 *= 1.0f/vf03.x;
}else{
// inside two sides - closest to third edge
if(flags1 != nflags)
closest = DistanceBetweenSphereAndLine(sph, v0, v01);
else if(flags2 != nflags)
closest = DistanceBetweenSphereAndLine(sph, v1, v12);
else
closest = DistanceBetweenSphereAndLine(sph, v2, v20);
vi01 = sph.w*sph.w > closest.w;
vf01 = closest;
vf02 = sph - closest;
vf03.x = Sqrt(closest.w);
vf02 *= 1.0f/vf03.x;
}
#endif
}
extern "C" void
SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf14, 0x0(%1)\n"
"lqc2 vf15, 0x10(%1)\n"
"lqc2 vf16, 0x20(%1)\n"
"lqc2 vf17, 0x30(%1)\n"
"vcallms Vu0SphereToTriangleCollisionCompressedStart\n"
".set reorder\n"
:
: "r" (&sph), "r" (&tri)
);
#else
CVuVector v0, v1, v2, plane;
v0.x = tri.v0[0]/128.0f;
v0.y = tri.v0[1]/128.0f;
v0.z = tri.v0[2]/128.0f;
v0.w = tri.v0[3]/128.0f;
v1.x = tri.v1[0]/128.0f;
v1.y = tri.v1[1]/128.0f;
v1.z = tri.v1[2]/128.0f;
v1.w = tri.v1[3]/128.0f;
v2.x = tri.v2[0]/128.0f;
v2.y = tri.v2[1]/128.0f;
v2.z = tri.v2[2]/128.0f;
v2.w = tri.v2[3]/128.0f;
plane.x = tri.plane[0]/4096.0f;
plane.y = tri.plane[1]/4096.0f;
plane.z = tri.plane[2]/4096.0f;
plane.w = tri.plane[3]/128.0f;
SphereToTriangleCollision(sph, v0, v1, v2, plane);
#endif
}
#include "VuCollision.h"
inline int
GetVUresult(void)
@ -362,17 +67,6 @@ GetVUresult(CVuVector &point, CVuVector &normal, float &dist)
#endif
enum Direction
{
DIR_X_POS,
DIR_X_NEG,
DIR_Y_POS,
DIR_Y_NEG,
DIR_Z_POS,
DIR_Z_NEG,
};
eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> CCollision::ms_colModelCache;
@ -2412,11 +2106,12 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
assert(modelA.numLines <= MAXNUMLINES);
// From model A space to model B space
Invert(matrixB, matAB);
matAB = Invert(matrixB, matAB);
matAB *= matrixA;
CColSphere bsphereAB; // bounding sphere of A in B space
bsphereAB.Set(modelA.boundingSphere.radius, matAB * modelA.boundingSphere.center);
bsphereAB.radius = modelA.boundingSphere.radius;
bsphereAB.center = matAB * modelA.boundingSphere.center;
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
return 0;
// B to A space
@ -2449,7 +2144,8 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
int numBoxesB = 0;
int numTrianglesB = 0;
for(i = 0; i < modelB.numSpheres; i++){
s.Set(modelB.spheres[i].radius, matBA * modelB.spheres[i].center);
s.radius = modelB.spheres[i].radius;
s.center = matBA * modelB.spheres[i].center;
if(TestSphereBox(s, modelA.boundingBox))
aSphereIndicesB[numSpheresB++] = i;
}
@ -3037,254 +2733,4 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
/*
* ColModel code
*/
void
CColSphere::Set(float radius, const CVector &center, uint8 surf, uint8 piece)
{
this->radius = radius;
this->center = center;
this->surface = surf;
this->piece = piece;
}
void
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
{
this->min = min;
this->max = max;
this->surface = surf;
this->piece = piece;
}
void
CColLine::Set(const CVector &p0, const CVector &p1)
{
this->p0 = p0;
this->p1 = p1;
}
void
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
{
this->a = a;
this->b = b;
this->c = c;
this->surface = surf;
}
#ifdef VU_COLLISION
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
CVector norm = CrossProduct(vc-va, vb-va);
norm.Normalise();
float d = DotProduct(norm, va);
normal.x = norm.x*4096.0f;
normal.y = norm.y*4096.0f;
normal.z = norm.z*4096.0f;
dist = d*128.0f;
}
#else
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
normal = CrossProduct(vc-va, vb-va);
normal.Normalise();
dist = DotProduct(normal, va);
CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z));
// find out largest component and its direction
if(an.x > an.y && an.x > an.z)
dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS;
else if(an.y > an.z)
dir = normal.y < 0.0f ? DIR_Y_NEG : DIR_Y_POS;
else
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
}
#endif
CColModel::CColModel(void)
{
numSpheres = 0;
spheres = nil;
numLines = 0;
lines = nil;
numBoxes = 0;
boxes = nil;
numTriangles = 0;
vertices = nil;
triangles = nil;
trianglePlanes = nil;
level = CGame::currLevel;
ownsCollisionVolumes = true;
}
CColModel::~CColModel(void)
{
RemoveCollisionVolumes();
RemoveTrianglePlanes();
}
void
CColModel::RemoveCollisionVolumes(void)
{
if(ownsCollisionVolumes){
RwFree(spheres);
RwFree(lines);
RwFree(boxes);
RwFree(vertices);
RwFree(triangles);
}
numSpheres = 0;
numLines = 0;
numBoxes = 0;
numTriangles = 0;
spheres = nil;
lines = nil;
boxes = nil;
vertices = nil;
triangles = nil;
}
void
CColModel::CalculateTrianglePlanes(void)
{
// HACK: allocate space for one more element to stuff the link pointer into
trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1));
for(int i = 0; i < numTriangles; i++)
trianglePlanes[i].Set(vertices, triangles[i]);
}
void
CColModel::RemoveTrianglePlanes(void)
{
RwFree(trianglePlanes);
trianglePlanes = nil;
}
void
CColModel::SetLinkPtr(CLink<CColModel*> *lptr)
{
assert(trianglePlanes);
*(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]) = lptr;
}
CLink<CColModel*>*
CColModel::GetLinkPtr(void)
{
assert(trianglePlanes);
return *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]);
}
void
CColModel::GetTrianglePoint(CVector &v, int i) const
{
v = vertices[i].Get();
}
CColModel&
CColModel::operator=(const CColModel &other)
{
int i;
int numVerts;
boundingSphere = other.boundingSphere;
boundingBox = other.boundingBox;
// copy spheres
if(other.numSpheres){
if(numSpheres != other.numSpheres){
numSpheres = other.numSpheres;
if(spheres)
RwFree(spheres);
spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
}
for(i = 0; i < numSpheres; i++)
spheres[i] = other.spheres[i];
}else{
numSpheres = 0;
if(spheres)
RwFree(spheres);
spheres = nil;
}
// copy lines
if(other.numLines){
if(numLines != other.numLines){
numLines = other.numLines;
if(lines)
RwFree(lines);
lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
}
for(i = 0; i < numLines; i++)
lines[i] = other.lines[i];
}else{
numLines = 0;
if(lines)
RwFree(lines);
lines = nil;
}
// copy boxes
if(other.numBoxes){
if(numBoxes != other.numBoxes){
numBoxes = other.numBoxes;
if(boxes)
RwFree(boxes);
boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
}
for(i = 0; i < numBoxes; i++)
boxes[i] = other.boxes[i];
}else{
numBoxes = 0;
if(boxes)
RwFree(boxes);
boxes = nil;
}
// copy mesh
if(other.numTriangles){
// copy vertices
numVerts = 0;
for(i = 0; i < other.numTriangles; i++){
if(other.triangles[i].a > numVerts)
numVerts = other.triangles[i].a;
if(other.triangles[i].b > numVerts)
numVerts = other.triangles[i].b;
if(other.triangles[i].c > numVerts)
numVerts = other.triangles[i].c;
}
numVerts++;
if(vertices)
RwFree(vertices);
if(numVerts){
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
for(i = 0; i < numVerts; i++)
vertices[i] = other.vertices[i];
}
// copy triangles
if(numTriangles != other.numTriangles){
numTriangles = other.numTriangles;
if(triangles)
RwFree(triangles);
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
}
for(i = 0; i < numTriangles; i++)
triangles[i] = other.triangles[i];
}else{
numTriangles = 0;
if(triangles)
RwFree(triangles);
triangles = nil;
if(vertices)
RwFree(vertices);
vertices = nil;
}
return *this;
}
}

70
src/collision/Collision.h Normal file
View file

@ -0,0 +1,70 @@
#pragma once
#include "ColModel.h"
#include "Game.h" // for eLevelName
#ifdef VU_COLLISION
#include "VuVector.h"
#endif
struct CStoredCollPoly
{
#ifdef VU_COLLISION
CVuVector verts[3];
#else
CVector verts[3];
#endif
bool valid;
};
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE)
#define MAX_COLLISION_POINTS 64
#else
#define MAX_COLLISION_POINTS 32
#endif
class CCollision
{
public:
static eLevelName ms_collisionInMemory;
static CLinkList<CColModel*> ms_colModelCache;
#ifdef NO_ISLAND_LOADING
static bool bAlreadyLoaded;
#endif
static void Init(void);
static void Shutdown(void);
static void Update(void);
static void LoadCollisionWhenINeedIt(bool changeLevel);
static void SortOutCollisionAfterLoad(void);
static void LoadCollisionScreen(eLevelName level);
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
static void CalculateTrianglePlanes(CColModel *model);
// all these return true if there's a collision
static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
static bool TestLineBox(const CColLine &line, const CColBox &box);
static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough);
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly);
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest);
};

View file

@ -0,0 +1,36 @@
#pragma once
struct CompressedVector
{
#ifdef COMPRESSED_COL_VECTORS
int16 x, y, z;
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"pextlw $10, $8\n"
"pextlw $2, $9, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = x;
qword[1] = y;
qword[2] = z;
qword[3] = 0; // junk
}
#endif
#else
float x, y, z;
CVector Get(void) const { return CVector(x, y, z); };
void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; };
#endif
};

View file

@ -1,7 +1,6 @@
#include "common.h"
#include "TempColModels.h"
#include "SurfaceTable.h"
CColModel CTempColModels::ms_colModelPed1;
CColModel CTempColModels::ms_colModelPed2;
@ -41,17 +40,17 @@ CTempColModels::Initialise(void)
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
colmodel.spheres = sphrs;\
colmodel.level = LEVEL_GENERIC;\
colmodel.ownsCollisionVolumes = false;\
colmodel.ownsCollisionVolumes = false;
int i;
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelBBox.level = LEVEL_GENERIC;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelCutObj[i].level = LEVEL_GENERIC;
}
@ -73,8 +72,8 @@ CTempColModels::Initialise(void)
s_aPedSpheres[i].piece = 0;
}
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0);
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
// Ped 2 Spheres
@ -92,8 +91,8 @@ CTempColModels::Initialise(void)
s_aPed2Spheres[i].piece = 0;
}
ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f));
SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
@ -118,8 +117,8 @@ CTempColModels::Initialise(void)
s_aPedGSpheres[2].piece = 0;
s_aPedGSpheres[3].piece = 6;
ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0);
ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f));
SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
@ -142,8 +141,8 @@ CTempColModels::Initialise(void)
s_aDoorSpheres[i].piece = 0;
}
ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0);
ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f));
ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f));
SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
@ -162,8 +161,8 @@ CTempColModels::Initialise(void)
s_aBumperSpheres[i].piece = 0;
}
ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f), SURFACE_DEFAULT, 0);
ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f));
ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f));
SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
@ -182,8 +181,8 @@ CTempColModels::Initialise(void)
s_aPanelSpheres[i].piece = 0;
}
ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0);
ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f));
SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
@ -202,8 +201,8 @@ CTempColModels::Initialise(void)
s_aBonnetSpheres[i].piece = 0;
}
ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0);
ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f));
ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
@ -222,8 +221,8 @@ CTempColModels::Initialise(void)
s_aBootSpheres[i].piece = 0;
}
ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0);
ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f));
ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
@ -244,8 +243,8 @@ CTempColModels::Initialise(void)
s_aWheelSpheres[i].piece = 0;
}
ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0);
ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f));
SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
@ -266,8 +265,8 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres1[i].piece = 0;
}
ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0);
ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f));
ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
@ -288,8 +287,8 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres2[i].piece = 0;
}
ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0);
ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f));
ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f));
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);

View file

@ -0,0 +1,282 @@
#include "common.h"
#ifdef VU_COLLISION
#include "VuVector.h"
#include "VuCollision.h"
#ifndef GTA_PS2
int16 vi01;
CVuVector vf01;
CVuVector vf02;
CVuVector vf03;
CVuVector
DistanceBetweenSphereAndLine(const CVuVector &center, const CVuVector &p0, const CVuVector &line)
{
// center VF12
// p0 VF14
// line VF15
CVuVector ret; // VF16
CVuVector p1 = p0+line;
CVuVector dist0 = center - p0; // VF20
CVuVector dist1 = center - p1; // VF25
float lenSq = line.MagnitudeSqr(); // VF21
float distSq0 = dist0.MagnitudeSqr(); // VF22
float distSq1 = dist1.MagnitudeSqr();
float dot = DotProduct(dist0, line); // VF23
if(dot < 0.0f){
// not above line, closest to p0
ret = p0;
ret.w = distSq0;
return ret;
}
float t = dot/lenSq; // param of nearest point on infinite line
if(t > 1.0f){
// not above line, closest to p1
ret = p1;
ret.w = distSq1;
return ret;
}
// closest to line
ret = p0 + line*t;
ret.w = (ret - center).MagnitudeSqr();
return ret;
}
inline int SignFlags(const CVector &v)
{
int f = 0;
if(v.x < 0.0f) f |= 1;
if(v.y < 0.0f) f |= 2;
if(v.z < 0.0f) f |= 4;
return f;
}
#endif
extern "C" void
LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1,
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
const CVuVector &plane)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf13, 0x0(%1)\n"
"lqc2 vf14, 0x0(%2)\n"
"lqc2 vf15, 0x0(%3)\n"
"lqc2 vf16, 0x0(%4)\n"
"lqc2 vf17, 0x0(%5)\n"
"vcallms Vu0LineToTriangleCollisionStart\n"
".set reorder\n"
:
: "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
);
#else
float dot0 = DotProduct(plane, p0);
float dot1 = DotProduct(plane, p1);
float dist0 = plane.w - dot0;
float dist1 = plane.w - dot1;
// if points are on the same side, no collision
if(dist0 * dist1 > 0.0f){
vi01 = 0;
return;
}
CVuVector diff = p1 - p0;
float t = dist0/(dot1 - dot0);
CVuVector p = p0 + diff*t;
p.w = 0.0f;
vf01 = p;
vf03.x = t;
// Check if point is inside
CVector cross1 = CrossProduct(p-v0, v1-v0);
CVector cross2 = CrossProduct(p-v1, v2-v1);
CVector cross3 = CrossProduct(p-v2, v0-v2);
// Only check relevant directions
int flagmask = 0;
if(Abs(plane.x) > 0.5f) flagmask |= 1;
if(Abs(plane.y) > 0.5f) flagmask |= 2;
if(Abs(plane.z) > 0.5f) flagmask |= 4;
int flags1 = SignFlags(cross1) & flagmask;
int flags2 = SignFlags(cross2) & flagmask;
int flags3 = SignFlags(cross3) & flagmask;
// inside if on the same side of all edges
if(flags1 != flags2 || flags1 != flags3){
vi01 = 0;
return;
}
vi01 = 1;
vf02 = plane;
return;
#endif
}
extern "C" void
LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf13, 0x0(%1)\n"
"lqc2 vf14, 0x0(%2)\n"
"lqc2 vf15, 0x10(%2)\n"
"lqc2 vf16, 0x20(%2)\n"
"lqc2 vf17, 0x30(%2)\n"
"vcallms Vu0LineToTriangleCollisionCompressedStart\n"
".set reorder\n"
:
: "r" (&p0), "r" (&p1), "r" (&tri)
);
#else
CVuVector v0, v1, v2, plane;
v0.x = tri.v0[0]/128.0f;
v0.y = tri.v0[1]/128.0f;
v0.z = tri.v0[2]/128.0f;
v0.w = tri.v0[3]/128.0f;
v1.x = tri.v1[0]/128.0f;
v1.y = tri.v1[1]/128.0f;
v1.z = tri.v1[2]/128.0f;
v1.w = tri.v1[3]/128.0f;
v2.x = tri.v2[0]/128.0f;
v2.y = tri.v2[1]/128.0f;
v2.z = tri.v2[2]/128.0f;
v2.w = tri.v2[3]/128.0f;
plane.x = tri.plane[0]/4096.0f;
plane.y = tri.plane[1]/4096.0f;
plane.z = tri.plane[2]/4096.0f;
plane.w = tri.plane[3]/128.0f;
LineToTriangleCollision(p0, p1, v0, v1, v2, plane);
#endif
}
extern "C" void
SphereToTriangleCollision(const CVuVector &sph,
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
const CVuVector &plane)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf14, 0x0(%1)\n"
"lqc2 vf15, 0x0(%2)\n"
"lqc2 vf16, 0x0(%3)\n"
"lqc2 vf17, 0x0(%4)\n"
"vcallms Vu0SphereToTriangleCollisionStart\n"
".set reorder\n"
:
: "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
);
#else
float planedist = DotProduct(plane, sph) - plane.w; // VF02
if(Abs(planedist) > sph.w){
vi01 = 0;
return;
}
// point on plane
CVuVector p = sph - planedist*plane;
p.w = 0.0f;
vf01 = p;
planedist = Abs(planedist);
// edges
CVuVector v01 = v1 - v0;
CVuVector v12 = v2 - v1;
CVuVector v20 = v0 - v2;
// VU code calculates normal again for some weird reason...
// Check sides of point
CVector cross1 = CrossProduct(p-v0, v01);
CVector cross2 = CrossProduct(p-v1, v12);
CVector cross3 = CrossProduct(p-v2, v20);
// Only check relevant directions
int flagmask = 0;
if(Abs(plane.x) > 0.1f) flagmask |= 1;
if(Abs(plane.y) > 0.1f) flagmask |= 2;
if(Abs(plane.z) > 0.1f) flagmask |= 4;
int nflags = SignFlags(plane) & flagmask;
int flags1 = SignFlags(cross1) & flagmask;
int flags2 = SignFlags(cross2) & flagmask;
int flags3 = SignFlags(cross3) & flagmask;
int testcase = 0;
CVuVector closest(0.0f, 0.0f, 0.0f); // VF04
if(flags1 == nflags){
closest += v2;
testcase++;
}
if(flags2 == nflags){
closest += v0;
testcase++;
}
if(flags3 == nflags){
closest += v1;
testcase++;
}
if(testcase == 3){
// inside triangle - dist to plane already checked
vf02 = plane;
vf02.w = vf03.x = planedist;
vi01 = 1;
}else if(testcase == 1){
// outside two sides - closest to point opposide inside edge
vf01 = closest;
vf02 = sph - closest;
float distSq = vf02.MagnitudeSqr();
vi01 = sph.w*sph.w > distSq;
vf03.x = Sqrt(distSq);
vf02 *= 1.0f/vf03.x;
}else{
// inside two sides - closest to third edge
if(flags1 != nflags)
closest = DistanceBetweenSphereAndLine(sph, v0, v01);
else if(flags2 != nflags)
closest = DistanceBetweenSphereAndLine(sph, v1, v12);
else
closest = DistanceBetweenSphereAndLine(sph, v2, v20);
vi01 = sph.w*sph.w > closest.w;
vf01 = closest;
vf02 = sph - closest;
vf03.x = Sqrt(closest.w);
vf02 *= 1.0f/vf03.x;
}
#endif
}
extern "C" void
SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri)
{
#ifdef GTA_PS2
__asm__ volatile (
".set noreorder\n"
"lqc2 vf12, 0x0(%0)\n"
"lqc2 vf14, 0x0(%1)\n"
"lqc2 vf15, 0x10(%1)\n"
"lqc2 vf16, 0x20(%1)\n"
"lqc2 vf17, 0x30(%1)\n"
"vcallms Vu0SphereToTriangleCollisionCompressedStart\n"
".set reorder\n"
:
: "r" (&sph), "r" (&tri)
);
#else
CVuVector v0, v1, v2, plane;
v0.x = tri.v0[0]/128.0f;
v0.y = tri.v0[1]/128.0f;
v0.z = tri.v0[2]/128.0f;
v0.w = tri.v0[3]/128.0f;
v1.x = tri.v1[0]/128.0f;
v1.y = tri.v1[1]/128.0f;
v1.z = tri.v1[2]/128.0f;
v1.w = tri.v1[3]/128.0f;
v2.x = tri.v2[0]/128.0f;
v2.y = tri.v2[1]/128.0f;
v2.z = tri.v2[2]/128.0f;
v2.w = tri.v2[3]/128.0f;
plane.x = tri.plane[0]/4096.0f;
plane.y = tri.plane[1]/4096.0f;
plane.z = tri.plane[2]/4096.0f;
plane.w = tri.plane[3]/128.0f;
SphereToTriangleCollision(sph, v0, v1, v2, plane);
#endif
}
#endif

View file

@ -0,0 +1,32 @@
#pragma once
struct VuTriangle
{
// Compressed int16 but unpacked
#ifdef GTA_PS2
uint128 v0;
uint128 v1;
uint128 v2;
uint128 plane;
#else
int32 v0[4];
int32 v1[4];
int32 v2[4];
int32 plane[4];
#endif
};
#ifndef GTA_PS2
extern int16 vi01;
extern CVuVector vf01;
extern CVuVector vf02;
extern CVuVector vf03;
#endif
extern "C" {
void LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1, const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, const CVuVector &plane);
void LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri);
void SphereToTriangleCollision(const CVuVector &sph, const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, const CVuVector &plane);
void SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri);
}

View file

@ -2692,7 +2692,7 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
float distance = 30.0f;
CFire* pNearestFire = gFireManager.FindNearestFire(FindPlayerCoors(), &distance);
if (pNearestFire) {
if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 30000){
if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 35000){
CStreaming::RequestModel(MI_FIRETRUCK, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestModel(MI_FIREMAN, STREAMFLAGS_DONT_REMOVE);
if (CStreaming::HasModelLoaded(MI_FIRETRUCK) && CStreaming::HasModelLoaded(MI_FIREMAN)){

View file

@ -19,6 +19,7 @@
#include "Fire.h"
#include "Script.h"
#include "Garages.h"
#include "screendroplets.h"
uint8 CGameLogic::ActivePlayers;
@ -117,6 +118,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
@ -196,6 +200,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
@ -245,6 +252,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);

View file

@ -129,7 +129,7 @@ int32 CGarages::PoliceCarsCollected;
CStoredCar CGarages::aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
CStoredCar CGarages::aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
CStoredCar CGarages::aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
int32 CGarages::AudioEntity = AEHANDLE_NONE;
int32 hGarages = AEHANDLE_NONE;
CGarage CGarages::aGarages[NUM_GARAGES];
bool CGarages::bCamShouldBeOutisde;
@ -156,12 +156,12 @@ void CGarages::Init(void)
aCarsInSafeHouse2[i].Init();
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++)
aCarsInSafeHouse3[i].Init();
AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (AudioEntity >= 0)
DMAudio.SetEntityStatus(AudioEntity, 1);
hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (hGarages >= 0)
DMAudio.SetEntityStatus(hGarages, 1);
AddOne(
CRUSHER_GARAGE_X1, CRUSHER_GARAGE_Y1, CRUSHER_GARAGE_Z1,
CRUSHER_GARAGE_X2, CRUSHER_GARAGE_Y2, CRUSHER_GARAGE_Z2,
CVector(CRUSHER_GARAGE_X1, CRUSHER_GARAGE_Y1, CRUSHER_GARAGE_Z1),
CVector(CRUSHER_GARAGE_X2, CRUSHER_GARAGE_Y2, CRUSHER_GARAGE_Z2),
GARAGE_CRUSHER, 0);
}
@ -169,17 +169,17 @@ void CGarages::Init(void)
void CGarages::Shutdown(void)
{
NumGarages = 0;
if (AudioEntity < 0)
if (hGarages < 0)
return;
DMAudio.DestroyEntity(AudioEntity);
AudioEntity = AEHANDLE_NONE;
DMAudio.DestroyEntity(hGarages);
hGarages = AEHANDLE_NONE;
}
#endif
void CGarages::Update(void)
{
static int GarageToBeTidied = 0;
#ifndef PS2
#ifndef GTA_PS2
if (CReplay::IsPlayingBack())
return;
#endif
@ -202,23 +202,23 @@ void CGarages::Update(void)
aGarages[GarageToBeTidied].TidyUpGarage();
}
int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId)
int16 CGarages::AddOne(CVector p1, CVector p2, eGarageType type, int32 targetId)
{
if (NumGarages >= NUM_GARAGES) {
assert(0);
return NumGarages++;
}
CGarage* pGarage = &aGarages[NumGarages];
pGarage->m_fX1 = Min(X1, X2);
pGarage->m_fX2 = Max(X1, X2);
pGarage->m_fY1 = Min(Y1, Y2);
pGarage->m_fY2 = Max(Y1, Y2);
pGarage->m_fZ1 = Min(Z1, Z2);
pGarage->m_fZ2 = Max(Z1, Z2);
pGarage->m_fX1 = Min(p1.x, p2.x);
pGarage->m_fX2 = Max(p1.x, p2.x);
pGarage->m_fY1 = Min(p1.y, p2.y);
pGarage->m_fY2 = Max(p1.y, p2.y);
pGarage->m_fZ1 = Min(p1.z, p2.z);
pGarage->m_fZ2 = Max(p1.z, p2.z);
pGarage->m_pDoor1 = nil;
pGarage->m_pDoor2 = nil;
pGarage->m_fDoor1Z = Z1;
pGarage->m_fDoor2Z = Z1;
pGarage->m_fDoor1Z = p1.z;
pGarage->m_fDoor2Z = p1.z;
pGarage->m_eGarageType = type;
pGarage->m_bRecreateDoorOnNextRefresh = false;
pGarage->m_bRotatedDoor = false;
@ -368,7 +368,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
CStats::CheckPointReachedSuccessfully();
}
UpdateDoorsHeight();
@ -464,7 +464,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -510,7 +510,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -575,7 +575,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -599,7 +599,8 @@ void CGarage::Update()
}
}
else if (!FindPlayerVehicle() && m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) &&
!IsAnyOtherCarTouchingGarage(m_pTarget) && IsEntityEntirelyOutside(FindPlayerPed(), 2.0f)) {
!IsAnyOtherCarTouchingGarage(m_pTarget) && IsEntityEntirelyOutside(FindPlayerPed(), 2.0f) &&
!IsAnyOtherCarTouchingGarage(m_pTarget)) {
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
m_eGarageState = GS_CLOSING;
@ -609,7 +610,7 @@ void CGarage::Update()
case GS_CLOSING:
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED;
else {
@ -639,7 +640,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -676,7 +677,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_pTarget) {
DestroyVehicleAndDriverAndPassengers(m_pTarget);
m_pTarget = nil;
@ -723,7 +724,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -772,7 +773,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_pTarget) {
MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex());
DestroyVehicleAndDriverAndPassengers(m_pTarget);
@ -812,7 +813,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -833,7 +834,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
if (!IsGarageEmpty())
m_eGarageState = GS_OPENING;
@ -844,7 +845,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -893,7 +894,7 @@ void CGarage::Update()
m_pTarget = nil;
m_eGarageState = GS_AFTERDROPOFF;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_CRUSH_CAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
}
else
@ -913,7 +914,7 @@ void CGarage::Update()
m_fDoorPos = Min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED);
if (m_fDoorPos == HALFPI) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateCrusherAngle();
break;
@ -945,7 +946,7 @@ void CGarage::Update()
case GS_CLOSING:
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED;
else {
@ -974,7 +975,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -994,7 +995,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1014,7 +1015,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1022,7 +1023,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1045,8 +1046,8 @@ void CGarage::Update()
// Close car doors either if player is far, or if he is in vehicle and garage is full,
// or if player is very very far so that we can remove whatever is blocking garage door without him noticing
if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) ||
!FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT) &&
!IsAnyCarBlockingDoor()))
!FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT)) &&
!IsAnyCarBlockingDoor())
m_eGarageState = GS_CLOSING;
else if (FindPlayerVehicle() &&
CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >=
@ -1064,7 +1065,7 @@ void CGarage::Update()
if (!IsPlayerOutsideGarage())
m_eGarageState = GS_OPENING;
else if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
m_eGarageState = GS_FULLYCLOSED;
switch (m_eGarageType) {
case GARAGE_HIDEOUT_ONE: StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouse1, MAX_STORED_CARS_IN_INDUSTRIAL); break;
@ -1111,7 +1112,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1136,7 +1137,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1152,7 +1153,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@ -1260,9 +1261,9 @@ bool CGarage::IsPlayerOutsideGarage()
bool CGarage::IsEntityTouching3D(CEntity * pEntity)
{
float radius = pEntity->GetBoundRadius();
if (pEntity->GetPosition().x - radius < m_fX1 || pEntity->GetPosition().x + radius > m_fX2 ||
pEntity->GetPosition().y - radius < m_fY1 || pEntity->GetPosition().y + radius > m_fY2 ||
pEntity->GetPosition().z - radius < m_fZ1 || pEntity->GetPosition().z + radius > m_fZ2)
if (m_fX1 - radius > pEntity->GetPosition().x || m_fX2 + radius < pEntity->GetPosition().x ||
m_fY1 - radius > pEntity->GetPosition().y || m_fY2 + radius < pEntity->GetPosition().y ||
m_fZ1 - radius > pEntity->GetPosition().z || m_fZ2 + radius < pEntity->GetPosition().z)
return false;
CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
@ -1271,9 +1272,9 @@ bool CGarage::IsEntityTouching3D(CEntity * pEntity)
if (pos.x + radius > m_fX1 && pos.x - radius < m_fX2 &&
pos.y + radius > m_fY1 && pos.y - radius < m_fY2 &&
pos.z + radius > m_fZ1 && pos.z - radius < m_fZ2)
return false;
return true;
}
return true;
return false;
}
bool CGarage::EntityHasASphereWayOutsideGarage(CEntity * pEntity, float fMargin)
@ -1387,7 +1388,9 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
CWorld::Remove(pVehicle);
delete pVehicle;
return; // WHY?
#ifndef FIX_BUGS
return; // makes no sense
#endif
}
}
}
@ -1419,34 +1422,7 @@ void CGarages::PrintMessages()
float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements
#endif
if (MessageNumberInString2 < 0) {
if (MessageNumberInString < 0) {
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
#else
CFont::PrintString(SCREEN_WIDTH / 2 - 2.0f, y_offset - 2.0f, TheText.Get(MessageIDString));
#endif
CFont::SetColor(CRGBA(89, 115, 150, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
else {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
#else
CFont::PrintString(SCREEN_WIDTH / 2 + 2.0f, y_offset - 40.0f + 2.0f, gUString);
#endif
CFont::SetColor(CRGBA(89, 115, 150, 255));
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
#else
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - 40.0f, gUString);
#endif
}
}
else {
if (MessageNumberInString2 >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
@ -1460,6 +1436,31 @@ void CGarages::PrintMessages()
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - 40.0f, gUString);
#endif
}
else if (MessageNumberInString >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
#else
CFont::PrintString(SCREEN_WIDTH / 2 + 2.0f, y_offset - 40.0f + 2.0f, gUString);
#endif
CFont::SetColor(CRGBA(89, 115, 150, 255));
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
#else
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - 40.0f, gUString);
#endif
}
else {
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
#else
CFont::PrintString(SCREEN_WIDTH / 2 - 2.0f, y_offset - 2.0f, TheText.Get(MessageIDString));
#endif
CFont::SetColor(CRGBA(89, 115, 150, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
}
}
@ -1534,41 +1535,54 @@ void CGarage::UpdateCrusherShake(float X, float Y)
m_pDoor2->GetMatrix().GetPosition().y -= Y;
}
// This is dumb but there is no way to avoid goto. What was there originally even?
static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, uint8 nIndex)
{
bool bNeedToFindDoorEntities = false;
if (pDoor) {
if (bIsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex((CDummy*)pDoor)))
return true;
if (nIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)pDoor) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
return true;
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex((CObject*)pDoor)))
return true;
if (nIndex != (CPools::GetObjectPool()->GetIndex((CObject*)pDoor) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
return true;
}
}
return bNeedToFindDoorEntities;
}
void CGarage::RefreshDoorPointers(bool bCreate)
{
bool bNeedToFindDoorEntities = true;
if (!bCreate && !m_bRecreateDoorOnNextRefresh)
bNeedToFindDoorEntities = false;
bool bNeedToFindDoorEntities = bCreate || m_bRecreateDoorOnNextRefresh;
m_bRecreateDoorOnNextRefresh = false;
if (DoINeedToRefreshPointer(m_pDoor1, m_bDoor1IsDummy, m_bDoor1PoolIndex))
bNeedToFindDoorEntities = true;
if (DoINeedToRefreshPointer(m_pDoor2, m_bDoor2IsDummy, m_bDoor2PoolIndex))
bNeedToFindDoorEntities = true;
if (m_pDoor1) {
if (m_bDoor1IsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor1)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor1PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor1) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor1)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor1PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor1) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
}
if (m_pDoor2) {
if (m_bDoor2IsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor2)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor2PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor2) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor2)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor2PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor2) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
}
if (bNeedToFindDoorEntities)
FindDoorsEntities();
}

View file

@ -198,7 +198,6 @@ class CGarages
static CStoredCar aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
static CStoredCar aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
static CStoredCar aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
static int32 AudioEntity;
static bool bCamShouldBeOutisde;
public:
@ -208,7 +207,7 @@ public:
#endif
static void Update(void);
static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId);
static int16 AddOne(CVector pos1, CVector pos2, eGarageType type, int32 targetId);
static void ChangeGarageType(int16, eGarageType, int32);
static void PrintMessages(void);
static void TriggerMessage(const char* text, int16, uint16 time, int16);

87
src/control/NameGrid.cpp Normal file
View file

@ -0,0 +1,87 @@
#include "common.h"
#include "NameGrid.h"
// TODO: reverse mobile code
CPlayerName::CPlayerName()
{
// TODO
}
void
CPlayerName::DisplayName(int)
{
// TODO
}
CRow::CRow()
{
// TODO
}
void
CRow::SetLetter(int, wchar *)
{
// TODO
}
CGrid::CGrid()
{
// TODO
}
void
CGrid::ProcessAnyLeftJustDown()
{
unk_int2--;
}
void
CGrid::ProcessAnyRightJustDown()
{
unk_int2++;
}
void
CGrid::ProcessAnyUpJustDown()
{
unk_int1--;
}
void
CGrid::ProcessAnyDownJustDown()
{
unk_int1++;
}
void
CGrid::AllDoneMakePlayerName()
{
// TODO
}
void
CGrid::ProcessDPadCrossJustDown()
{
// TODO
}
void
CGrid::DisplayGrid()
{
// TODO
}
void
CGrid::ProcessControllerInput()
{
// TODO
}
void
CGrid::Process()
{
ProcessControllerInput();
DisplayGrid();
playerName.DisplayName(2 * playerName.unk_4c);
}

53
src/control/NameGrid.h Normal file
View file

@ -0,0 +1,53 @@
#pragma once
// TODO: reverse mobile code
class CPlayerName
{
friend class CGrid;
float x;
float y;
wchar unk_8[34];
int unk_4c;
public:
CPlayerName();
void DisplayName(int);
};
class CRow
{
friend class CGrid;
int unk_0;
int unk_4;
wchar unk_8[20];
int unk_30;
public:
CRow();
void SetLetter(int, wchar *);
};
class CGrid
{
CRow rows[5];
int unk_int1;
int unk_int2;
int unk_int3;
float unk_float1;
float unk_float2;
CPlayerName playerName;
char unk2[4];
char unk3[4];
public:
CGrid();
void ProcessAnyLeftJustDown();
void ProcessAnyRightJustDown();
void ProcessAnyUpJustDown();
void ProcessAnyDownJustDown();
void AllDoneMakePlayerName();
void ProcessDPadCrossJustDown();
void DisplayGrid();
void ProcessControllerInput();
void Process();
};

View file

@ -542,6 +542,22 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
int done, cont;
int tileStart;
#ifndef MASTER
for (i = 0; i < m_numMapObjects-1; i++)
for (j = i+1; j < m_numMapObjects; j++) {
CTreadable *obj1 = m_mapObjects[i];
CTreadable *obj2 = m_mapObjects[j];
if (obj1->GetModelIndex() == obj2->GetModelIndex() &&
obj1->GetPosition().x == obj2->GetPosition().x && obj1->GetPosition().y == obj2->GetPosition().y && obj1->GetPosition().z == obj2->GetPosition().z &&
obj1->GetRight().x == obj2->GetRight().x && obj1->GetForward().x == obj2->GetForward().x && obj1->GetUp().x == obj2->GetUp().x &&
obj1->GetRight().y == obj2->GetRight().y && obj1->GetForward().y == obj2->GetForward().y && obj1->GetUp().y == obj2->GetUp().y &&
obj1->GetRight().z == obj2->GetRight().z && obj1->GetForward().z == obj2->GetForward().z && obj1->GetUp().z == obj2->GetUp().z) {
printf("THIS IS VERY BAD INDEED. FIX IMMEDIATELY!!!\n");
printf("Double road objects at the following coors: %f %f %f\n", obj1->GetPosition().x, obj1->GetPosition().y, obj1->GetPosition().z);
}
}
#endif // !MASTER
oldNumPathNodes = m_numPathNodes;
oldNumLinks = m_numConnections;
@ -1633,10 +1649,18 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start)
DoPathSearch(type, start, -1, target, pNodeList, &DummyResult, 32, nil, &dist, 999999.88f, -1);
else
DoPathSearch(type, start, -1, target, nil, &DummyResult2, 0, nil, &dist, 50.0f, -1);
#ifdef FIX_BUGS
// dist has GenerationDistMultiplier as a factor, so our reference dist should have it too
if(type == PATH_CAR)
return dist < 160.0f*TheCamera.GenerationDistMultiplier;
else
return dist < 100.0f*TheCamera.GenerationDistMultiplier;
#else
if(type == PATH_CAR)
return dist < 160.0f;
else
return dist < 100.0f;
#endif
}
void

View file

@ -387,7 +387,7 @@ INITSAVEBUF
// Convert entity pointer to building pool index while saving
if (phone->m_pEntity) {
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1);
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
}
}
VALIDATESAVEBUF(*size)

View file

@ -353,11 +353,11 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
m_pObject->GetMatrix().UpdateRW();
m_pObject->UpdateRwFrame();
if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z)
if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false) && waterLevel >= m_pObject->GetPosition().z)
m_eType = PICKUP_FLOATINGPACKAGE_FLOATING;
break;
case PICKUP_FLOATINGPACKAGE_FLOATING:
if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0))
if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
m_pObject->GetMatrix().GetPosition().z = waterLevel;
m_pObject->GetMatrix().UpdateRW();
@ -1013,7 +1013,7 @@ INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil)
buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1);
buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
}
WriteSaveBuf(buf, CollectedPickUpIndex);
@ -1436,3 +1436,85 @@ CPacManPickups::ResetPowerPillsCarriedByPlayer()
FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
}
}
void
CPed::CreateDeadPedMoney(void)
{
if (!CGame::nastyGame)
return;
int mi = GetModelIndex();
if ((mi >= MI_COP && mi <= MI_FIREMAN) || CharCreatedBy == MISSION_CHAR || bInVehicle)
return;
int money = CGeneral::GetRandomNumber() % 60;
if (money < 10)
return;
if (money == 43)
money = 700;
int pickupCount = money / 40 + 1;
int moneyPerPickup = money / pickupCount;
for(int i = 0; i < pickupCount; i++) {
// (CGeneral::GetRandomNumber() % 256) * PI / 128 gives a float up to something TWOPI-ish.
float pickupX = 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().x;
float pickupY = 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().y;
bool found = false;
float groundZ = CWorld::FindGroundZFor3DCoord(pickupX, pickupY, GetPosition().z, &found) + 0.5f;
if (found) {
CPickups::GenerateNewOne(CVector(pickupX, pickupY, groundZ), MI_MONEY, PICKUP_MONEY, moneyPerPickup + (CGeneral::GetRandomNumber() & 7));
}
}
}
void
CPed::CreateDeadPedWeaponPickups(void)
{
bool found = false;
float angleToPed;
CVector pickupPos;
if (bInVehicle)
return;
for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
eWeaponType weapon = GetWeapon(i).m_eWeaponType;
int weaponAmmo = GetWeapon(i).m_nAmmoTotal;
if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || weaponAmmo == 0)
continue;
angleToPed = i * 1.75f;
pickupPos = GetPosition();
pickupPos.x += 1.5f * Sin(angleToPed);
pickupPos.y += 1.5f * Cos(angleToPed);
pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
CVector pedPos = GetPosition();
pedPos.z += 0.3f;
CVector pedToPickup = pickupPos - pedPos;
float distance = pedToPickup.Magnitude();
// outer edge of pickup
distance = (distance + 0.3f) / distance;
CVector pickupPos2 = pedPos;
pickupPos2 += distance * pedToPickup;
// pickup must be on ground and line to its edge must be clear
if (!found || CWorld::GetIsLineOfSightClear(pickupPos2, pedPos, true, false, false, false, false, false, false)) {
// otherwise try another position (but disregard second check apparently)
angleToPed += 3.14f;
pickupPos = GetPosition();
pickupPos.x += 1.5f * Sin(angleToPed);
pickupPos.y += 1.5f * Cos(angleToPed);
pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
}
if (found)
CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon]));
}
ClearWeapons();
}

View file

@ -1,5 +1,5 @@
#include "common.h"
#ifdef GTA_REPLAY
#include "AnimBlendAssociation.h"
#include "Boat.h"
#include "SpecialFX.h"
@ -1585,3 +1585,4 @@ void CReplay::Display()
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
#endif

View file

@ -63,6 +63,12 @@ struct CStoredDetailedAnimationState
void PlayReplayFromHD(void);
#ifdef GTA_REPLAY
#define REPLAY_STUB
#else
#define REPLAY_STUB {}
#endif
class CReplay
{
enum {
@ -273,20 +279,24 @@ private:
#endif
public:
static void Init(void);
static void DisableReplays(void);
static void EnableReplays(void);
static void Update(void);
static void FinishPlayback(void);
static void EmptyReplayBuffer(void);
static void Display(void);
static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene);
static void StreamAllNecessaryCarsAndPeds(void);
static bool ShouldStandardCameraBeProcessed(void);
static void Init(void) REPLAY_STUB;
static void DisableReplays(void) REPLAY_STUB;
static void EnableReplays(void) REPLAY_STUB;
static void Update(void) REPLAY_STUB;
static void FinishPlayback(void) REPLAY_STUB;
static void EmptyReplayBuffer(void) REPLAY_STUB;
static void Display(void) REPLAY_STUB;
static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) REPLAY_STUB;
static void StreamAllNecessaryCarsAndPeds(void) REPLAY_STUB;
#ifndef GTA_REPLAY
static bool ShouldStandardCameraBeProcessed(void) { return true; }
static bool IsPlayingBack() { return false; }
static bool IsPlayingBackFromFile() { return false; }
#else
static bool ShouldStandardCameraBeProcessed(void);
static bool IsPlayingBack() { return Mode == MODE_PLAYBACK; }
static bool IsPlayingBackFromFile() { return bPlayingBackFromFile; }
private:
static void RecordThisFrame(void);
static void StorePedUpdate(CPed *ped, int id);
@ -314,4 +324,5 @@ private:
/* Absolute nonsense, but how could this function end up being outside of class? */
friend void PlayReplayFromHD(void);
#endif
};

View file

@ -81,7 +81,7 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
}
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
float fMinDist = 16000000.0f;
float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
@ -128,7 +128,7 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
}
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
float fMinDist = 16000000.0f;
float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level

View file

@ -1,7 +1,7 @@
#include "common.h"
#include "SceneEdit.h"
#ifdef GTA_SCENE_EDIT
#include "Automobile.h"
#include "Camera.h"
#include "CarCtrl.h"
@ -1096,3 +1096,4 @@ bool CSceneEdit::SelectWeapon(void)
}
return false;
}
#endif

View file

@ -1,5 +1,5 @@
#pragma once
#ifdef GTA_SCENE_EDIT
class CPed;
class CVehicle;
@ -93,3 +93,4 @@ public:
static void SelectVehicle(void);
static bool SelectWeapon(void);
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,29 @@ class CPlayerInfo;
class CRunningScript;
extern int32 ScriptParams[32];
void FlushLog();
#define script_assert(_Expression) FlushLog(); assert(_Expression);
#define PICKUP_PLACEMENT_OFFSET 0.5f
#define PED_FIND_Z_OFFSET 5.0f
#define SPHERE_MARKER_R 0
#define SPHERE_MARKER_G 128
#define SPHERE_MARKER_B 255
#define SPHERE_MARKER_A 128
#define SPHERE_MARKER_PULSE_PERIOD 2048
#define SPHERE_MARKER_PULSE_FRACTION 0.1f
#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
#define METERS_IN_FOOT 0.3048f
#define FEET_IN_METER 3.28084f
#else
#define METERS_IN_FOOT 0.3f
#define FEET_IN_METER 3.33f
#endif
#define KEY_LENGTH_IN_SCRIPT 8
struct intro_script_rectangle
@ -376,6 +399,11 @@ private:
#ifdef FIX_BUGS
friend void RetryMission(int, int);
#endif
#ifdef MISSION_SWITCHER
public:
static void SwitchToMission(int32 mission);
#endif
};
@ -514,6 +542,8 @@ private:
return false;
}
}
friend class CTheScripts;
};
#ifdef MISSION_REPLAY

1555
src/control/Script2.cpp Normal file

File diff suppressed because it is too large Load diff

2082
src/control/Script3.cpp Normal file

File diff suppressed because it is too large Load diff

2027
src/control/Script4.cpp Normal file

File diff suppressed because it is too large Load diff

2011
src/control/Script5.cpp Normal file

File diff suppressed because it is too large Load diff

1343
src/control/Script6.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -1156,7 +1156,7 @@ enum {
COMMAND_IS_CHAR_LYING_DOWN,
COMMAND_CAN_CHAR_SEE_DEAD_CHAR,
COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER,
#ifndef GTA3_1_1_PATCH
#if GTA_VERSION < GTA3_PC_11
COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER,
#endif
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT

View file

@ -49,7 +49,7 @@ CAnimViewer::Render(void) {
if (pTarget) {
#ifdef FIX_BUGS
#ifdef PED_SKIN
if(pTarget->IsPed())
if(pTarget->IsPed() && IsClumpSkinned(pTarget->GetClump()))
((CPed*)pTarget)->UpdateRpHAnim();
#endif
#endif
@ -100,6 +100,9 @@ CAnimViewer::Initialise(void) {
CRadar::Initialise();
CRadar::LoadTextures();
CVehicleModelInfo::LoadVehicleColours();
#ifdef FIX_BUGS
CVehicleModelInfo::LoadEnvironmentMaps();
#endif
CAnimManager::LoadAnimFiles();
CWorld::PlayerInFocus = 0;
CWeapon::InitialiseWeapons();
@ -294,7 +297,12 @@ CAnimViewer::Update(void)
if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) {
((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
#ifdef FIX_BUGS
// so we don't end up in the water
pTarget->GetMatrix().GetPosition().z = 10.0f;
#else
pTarget->GetMatrix().GetPosition().z = 0.0f;
#endif
if (modelInfo->GetModelType() == MITYPE_PED) {
((CPed*)pTarget)->bKindaStayInSamePlace = true;

View file

@ -263,9 +263,11 @@ CCam::Process(void)
case MODE_FIGHT_CAM_RUNABOUT:
Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
#ifdef GTA_SCENE_EDIT
case MODE_EDITOR:
Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
#endif
default:
Source = CVector(0.0f, 0.0f, 0.0f);
Front = CVector(0.0f, 1.0f, 0.0f);
@ -2570,7 +2572,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
ResetStatics = false;
}
#ifndef GTA3_1_1_PATCH
#if GTA_VERSION < GTA3_PC_11
((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD);
Source = HeadPos;
Source.z += 0.1f;
@ -2605,7 +2607,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f);
else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
#ifdef GTA3_1_1_PATCH
#if GTA_VERSION >= GTA3_PC_11
HeadPos.x = 0.0f;
HeadPos.y = 0.0f;
HeadPos.z = 0.0f;
@ -3919,6 +3921,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
}
#endif
#ifdef GTA_SCENE_EDIT
void
CCam::Process_Editor(const CVector&, float, float, float)
{
@ -3997,6 +4000,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z);
}
}
#endif
void
CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
@ -4010,6 +4014,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f;
else
Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f;
#ifdef IMPROVED_CAMERA
if(CPad::GetPad(0)->GetLeftMouse()){
Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f);
Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f);
}
#endif
if(Distance < 1.5f)
Distance = 1.5f;

View file

@ -74,7 +74,7 @@ bool bDidWeProcessAnyCinemaCam;
CCamera::CCamera(void)
{
#if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS)
#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
m_fMouseAccelHorzntl = 0.0025f;
m_fMouseAccelVertical = 0.003f;
#endif
@ -88,15 +88,15 @@ CCamera::CCamera(float)
void
CCamera::Init(void)
{
#if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS)
#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
float fMouseAccelHorzntl = m_fMouseAccelHorzntl;
float fMouseAccelVertical = m_fMouseAccelVertical;
#endif
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart ) {
if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart )
#endif
{
#ifdef FIX_BUGS
static const CCamera DummyCamera = CCamera(0.f);
*this = DummyCamera;
@ -104,15 +104,13 @@ CCamera::Init(void)
memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh?
#endif
#if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS)
#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
m_fMouseAccelHorzntl = fMouseAccelHorzntl;
m_fMouseAccelVertical = fMouseAccelVertical;
#endif
m_pRwCamera = nil;
#ifdef PS2_MENU
}
#endif
m_1rstPersonRunCloseToAWall = false;
m_fPositionAlongSpline = 0.0f;
@ -123,7 +121,7 @@ CCamera::Init(void)
Cams[0].Mode = CCam::MODE_FOLLOWPED;
Cams[1].Mode = CCam::MODE_FOLLOWPED;
unknown = 0;
m_bJustJumpedOutOf1stPersonBecauseOfTarget = false;
m_bUnknown = false;
ClearPlayerWeaponMode();
m_bInATunnelAndABigVehicle = false;
m_iModeObbeCamIsInForCar = OBBE_INVALID;
@ -237,7 +235,7 @@ CCamera::Init(void)
m_uiTransitionState = 0;
m_uiTimeTransitionStart = 0;
m_bLookingAtPlayer = true;
#if !defined(GTA3_1_1_PATCH) && !defined(FIX_BUGS)
#if GTA_VERSION < GTA3_PC_11 && !defined(FIX_BUGS)
m_fMouseAccelHorzntl = 0.0025f;
m_fMouseAccelVertical = 0.003f;
#endif
@ -715,14 +713,18 @@ CCamera::Process(void)
DistanceToWater = CWaterLevel::CalcDistanceToWater(GetPosition().x, GetPosition().y);
// LOD dist
if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier())
LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f);
else
if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){
LODDistMultiplier = 70.0f/CDraw::GetFOV();
#ifndef FIX_BUGS
// makes no sense and gone in VC
LODDistMultiplier *= CDraw::GetAspectRatio()/(4.0f/3.0f);
#endif
}else
LODDistMultiplier = 1.0f;
// missing on PS2
#if GTA_VERSION > GTA3_PS2_160
GenerationDistMultiplier = LODDistMultiplier;
LODDistMultiplier *= CRenderer::ms_lodDistScale;
//
#endif
// Keep track of speed
if(m_bJustInitalised || m_bJust_Switched){
@ -1574,8 +1576,10 @@ CCamera::CamControl(void)
switchByJumpCut = true;
}
}
#ifdef GTA_SCENE_EDIT
if(CSceneEdit::m_bEditOn)
ReqMode = CCam::MODE_EDITOR;
#endif
if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){
if(switchByJumpCut){
@ -3398,10 +3402,10 @@ CCamera::Fade(float timeout, int16 direction)
m_fTimeToFadeMusic = timeout;
m_uiFadeTimeStartedMusic = CTimer::GetTimeInMilliseconds();
// Not on PS2
if(!m_bJustJumpedOutOf1stPersonBecauseOfTarget && m_iMusicFadingDirection == FADE_OUT){
if(!m_bUnknown && m_iMusicFadingDirection == FADE_OUT){
unknown++;
if(unknown >= 2){
m_bJustJumpedOutOf1stPersonBecauseOfTarget = true;
m_bUnknown = true;
unknown = 0;
}else
m_bMoveCamToAvoidGeom = true;

View file

@ -213,7 +213,9 @@ public:
void PrintMode(void);
void Process_Debug(const CVector&, float, float, float);
#ifdef GTA_SCENE_EDIT
void Process_Editor(const CVector&, float, float, float);
#endif
void Process_ModelView(const CVector &CameraTarget, float, float, float);
void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float);
@ -348,7 +350,7 @@ public:
bool m_bcutsceneFinished;
bool m_bCullZoneChecksOn;
bool m_bFirstPersonBeingUsed;
bool m_bJustJumpedOutOf1stPersonBecauseOfTarget;
bool m_bUnknown;
bool m_bIdleOn;
bool m_bInATunnelAndABigVehicle;
bool m_bInitialNodeFound;

View file

@ -5,6 +5,7 @@
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@ -242,8 +243,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
else
return STREAM_SUCCESS;
}
#ifdef BIG_IMG
LARGE_INTEGER liDistanceToMove;
liDistanceToMove.QuadPart = _GET_OFFSET(offset);
liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE;
SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN);
#else
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
#endif
DWORD NumberOfBytesRead;

View file

@ -16,7 +16,7 @@
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@ -429,7 +429,7 @@ void *CdStreamThread(void *param)
ASSERT(pChannel->hFile >= 0);
ASSERT(pChannel->pBuffer != nil );
lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET);
lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)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
// STREAM_WAITING is a little hack to make CStreaming not process this data

View file

@ -1,254 +0,0 @@
#pragma once
#include "templates.h"
#include "Game.h" // for eLevelName
#ifdef VU_COLLISION
#include "VuVector.h"
#endif
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE)
#define MAX_COLLISION_POINTS 64
#else
#define MAX_COLLISION_POINTS 32
#endif
struct CompressedVector
{
#ifdef COMPRESSED_COL_VECTORS
int16 x, y, z;
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"pextlw $10, $8\n"
"pextlw $2, $9, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = x;
qword[1] = y;
qword[2] = z;
qword[3] = 0; // junk
}
#endif
#else
float x, y, z;
CVector Get(void) const { return CVector(x, y, z); };
void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; };
#endif
};
struct CColSphere
{
// NB: this has to be compatible with a CVuVector
CVector center;
float radius;
uint8 surface;
uint8 piece;
void Set(float radius, const CVector &center, uint8 surf, uint8 piece);
void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
};
struct CColBox
{
CVector min;
CVector max;
uint8 surface;
uint8 piece;
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
CVector GetSize(void) { return max - min; }
};
struct CColLine
{
// NB: this has to be compatible with two CVuVectors
CVector p0;
int pad0;
CVector p1;
int pad1;
CColLine(void) { };
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
void Set(const CVector &p0, const CVector &p1);
};
struct CColTriangle
{
uint16 a;
uint16 b;
uint16 c;
uint8 surface;
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
};
struct CColTrianglePlane
{
#ifdef VU_COLLISION
CompressedVector normal;
int16 dist;
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; }
float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"lh $11, 6(%1)\n"
"pextlw $10, $8\n"
"pextlw $11, $9\n"
"pextlw $2, $11, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$11", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = normal.x;
qword[1] = normal.y;
qword[2] = normal.z;
qword[3] = dist;
}
#endif
#else
CVector normal;
float dist;
uint8 dir;
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n = normal; }
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
#endif
};
struct CColPoint
{
CVector point;
int pad1;
// the surface normal on the surface of point
CVector normal;
int pad2;
uint8 surfaceA;
uint8 pieceA;
uint8 surfaceB;
uint8 pieceB;
float depth;
void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
this->depth = depth;
this->surfaceA = surfA;
this->pieceA = pieceA;
this->surfaceB = surfB;
this->pieceB = pieceB;
}
void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
this->surfaceA = surfA;
this->pieceA = pieceA;
this->surfaceB = surfB;
this->pieceB = pieceB;
}
};
struct CStoredCollPoly
{
#ifdef VU_COLLISION
CVuVector verts[3];
#else
CVector verts[3];
#endif
bool valid;
};
struct CColModel
{
CColSphere boundingSphere;
CColBox boundingBox;
int16 numSpheres;
int16 numLines;
int16 numBoxes;
int16 numTriangles;
int32 level;
bool ownsCollisionVolumes; // missing on PS2
CColSphere *spheres;
CColLine *lines;
CColBox *boxes;
CompressedVector *vertices;
CColTriangle *triangles;
CColTrianglePlane *trianglePlanes;
CColModel(void);
~CColModel(void);
void RemoveCollisionVolumes(void);
void CalculateTrianglePlanes(void);
void RemoveTrianglePlanes(void);
CLink<CColModel*> *GetLinkPtr(void);
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
CColModel& operator=(const CColModel& other);
};
class CCollision
{
public:
static eLevelName ms_collisionInMemory;
static CLinkList<CColModel*> ms_colModelCache;
#ifdef NO_ISLAND_LOADING
static bool bAlreadyLoaded;
#endif
static void Init(void);
static void Shutdown(void);
static void Update(void);
static void LoadCollisionWhenINeedIt(bool changeLevel);
static void SortOutCollisionAfterLoad(void);
static void LoadCollisionScreen(eLevelName level);
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
static void CalculateTrianglePlanes(CColModel *model);
// all these return true if there's a collision
static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
static bool TestLineBox(const CColLine &line, const CColBox &box);
static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough);
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly);
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest);
};

View file

@ -2316,8 +2316,252 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
return num;
}
#ifdef BIND_VEHICLE_FIREWEAPON
#define VFB(b) b,
#else
#define VFB(b)
#endif
#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \
{{ \
O, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
L1, /* VEHICLE_CHANGE_RADIO_STATION */ \
L3, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
R1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
O, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
SELECT, /* VEHICLE_CHANGE_RADIO_STATION */ \
L1, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
R1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
X, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
T, /* PED_SNIPER_ZOOM_IN */ \
Q, /* PED_SNIPER_ZOOM_OUT */ \
L1, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
O, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
L3, /* VEHICLE_CHANGE_RADIO_STATION */ \
R1, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
T, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
R1, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(R1) /* VEHICLE_FIREWEAPON */ \
nil, /* VEHICLE_ACCELERATE */ \
nil, /* VEHICLE_BRAKE */ \
O, /* VEHICLE_CHANGE_RADIO_STATION */ \
L3, /* VEHICLE_HORN */ \
Q, /* TOGGLE_SUBMISSIONS */ \
L1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
L1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}}
const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
#ifdef BUTTON_ICONS
const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
#endif
#if 0 // set 1 for ps2 fonts
#define PS2_TRIANGLE "\""
#define PS2_CIRCLE "|"
#define PS2_CROSS "/"
#define PS2_SQUARE "^"
#elif defined(BUTTON_ICONS)
#define PS2_TRIANGLE "~T~"
#define PS2_CIRCLE "~O~"
#define PS2_CROSS "~X~"
#define PS2_SQUARE "~Q~"
#else
#define PS2_TRIANGLE "TRIANGLE"
#define PS2_CIRCLE "CIRCLE"
#define PS2_CROSS "CROSS"
#define PS2_SQUARE "SQUARE"
#endif
const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
#ifdef BUTTON_ICONS
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
#endif
#undef PS2_TRIANGLE
#undef PS2_CIRCLE
#undef PS2_CROSS
#undef PS2_SQUARE
#undef CONTROLLER_BUTTONS
#undef VFB
void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight)
{
#ifdef DETECT_PAD_INPUT_SWITCH
if (CPad::GetPad(0)->IsAffectedByController) {
wchar wstr[16];
// TODO: INI and/or menu setting for Xbox/PS switch
#ifdef BUTTON_ICONS
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
#else
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons;
#endif
assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these
AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr);
CMessages::WideStringCopy(text, wstr, leight);
return;
}
#endif
int32 nums = GetNumOfSettingsForAction((e_ControllerAction)action);
int32 sets = 0;

View file

@ -11,7 +11,6 @@
#include "HandlingMgr.h"
#include "CarCtrl.h"
#include "PedType.h"
#include "PedStats.h"
#include "AnimManager.h"
#include "Game.h"
#include "RwHelper.h"
@ -25,6 +24,7 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
#include "MemoryHeap.h"
char CFileLoader::ms_line[256];
@ -59,7 +59,13 @@ CFileLoader::LoadLevel(const char *filename)
savedTxd = RwTexDictionaryCreate();
RwTexDictionarySetCurrent(savedTxd);
}
#if GTA_VERSION <= GTA3_PS2_160
CFileMgr::ChangeDir("\\DATA\\");
fd = CFileMgr::OpenFile(filename, "r");
CFileMgr::ChangeDir("\\");
#else
fd = CFileMgr::OpenFile(filename, "r");
#endif
assert(fd > 0);
for(line = LoadLine(fd); line; line = LoadLine(fd)){
@ -72,11 +78,13 @@ CFileLoader::LoadLevel(const char *filename)
if(strncmp(line, "IMAGEPATH", 9) == 0){
RwImageSetPath(line + 10);
}else if(strncmp(line, "TEXDICTION", 10) == 0){
PUSH_MEMID(MEMID_TEXTURES);
strcpy(txdname, line+11);
LoadingScreenLoadingFile(txdname);
RwTexDictionary *txd = LoadTexDictionary(txdname);
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
POP_MEMID();
}else if(strncmp(line, "COLFILE", 7) == 0){
int level;
sscanf(line+8, "%d", &level);
@ -95,12 +103,16 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
PUSH_MEMID(MEMID_DEF_MODELS);
CModelInfo::ConstructMloClumps();
POP_MEMID();
CObjectData::Initialise("DATA\\OBJECT.DAT");
objectsLoaded = true;
}
PUSH_MEMID(MEMID_WORLD);
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
POP_MEMID();
}else if(strncmp(line, "MAPZONE", 7) == 0){
LoadingScreenLoadingFile(line + 8);
LoadMapZones(line + 8);
@ -189,6 +201,8 @@ CFileLoader::LoadCollisionFile(const char *filename)
CBaseModelInfo *mi;
ColHeader header;
PUSH_MEMID(MEMID_COLLISION);
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
@ -212,6 +226,8 @@ CFileLoader::LoadCollisionFile(const char *filename)
}
CFileMgr::CloseFile(fd);
POP_MEMID();
}
void
@ -233,6 +249,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 44;
if(model.numSpheres > 0){
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
REGISTER_MEMPTR(&model.spheres);
for(i = 0; i < model.numSpheres; i++){
model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]);
buf += 20;
@ -244,6 +261,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numLines > 0){
model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
REGISTER_MEMPTR(&model.lines);
for(i = 0; i < model.numLines; i++){
model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
buf += 24;
@ -255,6 +273,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numBoxes > 0){
model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox));
REGISTER_MEMPTR(&model.boxes);
for(i = 0; i < model.numBoxes; i++){
model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]);
buf += 28;
@ -266,6 +285,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(numVertices > 0){
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
REGISTER_MEMPTR(&model.vertices);
for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
if(Abs(*(float*)buf) >= 256.0f ||
@ -281,6 +301,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numTriangles > 0){
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
REGISTER_MEMPTR(&model.triangles);
for(i = 0; i < model.numTriangles; i++){
model.triangles[i].Set(model.vertices, *(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12], buf[13]);
buf += 16;
@ -332,6 +353,16 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
return atomic;
}
#ifdef LIBRW
void
InitClump(RpClump *clump)
{
RpClumpForAllAtomics(clump, ConvertPlatformAtomic, nil);
}
#else
#define InitClump(clump)
#endif
void
CFileLoader::LoadModelFile(const char *filename)
{
@ -343,6 +374,7 @@ CFileLoader::LoadModelFile(const char *filename)
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
clump = RpClumpStreamRead(stream);
if(clump){
InitClump(clump);
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
}
@ -368,6 +400,7 @@ CFileLoader::LoadClumpFile(const char *filename)
GetNameAndLOD(nodename, name, &n);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
InitClump(clump);
assert(mi->IsClump());
mi->SetClump(clump);
}else
@ -393,6 +426,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) {
// Read LOD ped
clump = RpClumpStreamRead(stream);
InitClump(clump);
if(clump){
((CPedModelInfo*)mi)->SetLowDetailClump(clump);
RpClumpDestroy(clump);
@ -423,6 +457,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpGtaStreamRead2(stream);
if(clump){
InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@ -443,6 +478,7 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
InitClump(clump);
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
@ -806,6 +842,8 @@ CFileLoader::LoadAtomicFile2Return(const char *filename)
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
clump = RpClumpStreamRead(stream);
if(clump)
InitClump(clump);
RwStreamClose(stream, nil);
return clump;
}

File diff suppressed because it is too large Load diff

View file

@ -18,7 +18,6 @@
#define MENU_X_MARGIN 40.0f
#define MENUACTION_POS_Y 60.0f
#define MENUACTION_WIDTH 38.0f
#define MENUACTION_SCALE_MULT 0.9f
#define MENURADIO_ICON_SCALE 60.0f
@ -156,9 +155,6 @@ enum eSaveSlot
SAVESLOT_7,
SAVESLOT_8,
SAVESLOT_LABEL = 36,
#ifdef CUSTOM_FRONTEND_OPTIONS
SAVESLOT_CFO
#endif
};
#ifdef MENU_MAP
@ -239,18 +235,31 @@ enum eMenuScreen
MENUPAGE_MOUSE_CONTROLS = 56,
MENUPAGE_MISSION_RETRY = 57,
#ifdef MENU_MAP
MENUPAGE_MAP,
MENUPAGE_MAP = 58,
#endif
MENUPAGE_UNK, // 58 in game. Map page is added above, because last screen in CMenuScreens should always be empty to make CFO work
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUPAGES = 65 // for some room to add more screen
#ifdef GRAPHICS_MENU_OPTIONS
MENUPAGE_GRAPHICS_SETTINGS,
#else
MENUPAGES
MENUPAGE_ADVANCED_DISPLAY_SETTINGS,
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
MENUPAGE_DETECT_JOYSTICK,
#endif
#endif
MENUPAGE_UNK, // originally 58. Custom screens are inserted above, because last screen in CMenuScreens should always be empty to make CFO work
MENUPAGES
};
enum eMenuAction
{
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_CFO_SELECT = -2,
MENUACTION_CFO_DYNAMIC = -1,
#endif
MENUACTION_NOTHING,
MENUACTION_LABEL,
MENUACTION_CHANGEMENU,
@ -370,12 +379,6 @@ enum eMenuAction
// MENUACTION_MIPMAPS,
// MENUACTION_TEXTURE_FILTERING,
//#endif
//#ifdef NO_ISLAND_LOADING
// MENUACTION_ISLANDLOADING,
//#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_TRIGGERFUNC
#endif
};
enum eCheckHover
@ -458,6 +461,7 @@ struct BottomBarOption
int32 screenId;
};
#ifndef CUSTOM_FRONTEND_OPTIONS
struct CMenuScreen
{
char m_ScreenName[8];
@ -470,9 +474,91 @@ struct CMenuScreen
int32 m_Action; // eMenuAction
char m_EntryName[8];
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option
int32 m_TargetMenu; // eMenuScreen
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreen aScreens[MENUPAGES];
#else
#include "frontendoption.h"
struct CCustomScreenLayout {
eMenuSprites sprite;
int columnWidth;
int headerHeight;
int lineHeight;
int8 font;
int8 alignment;
bool showLeftRightHelper;
float fontScaleX;
float fontScaleY;
};
struct CCFO
{
int8 *value;
const char *save;
};
struct CCFOSelect : CCFO
{
char** rightTexts;
int8 numRightTexts;
bool onlyApplyOnEnter;
int8 displayedValue; // only if onlyApplyOnEnter enabled for now
int8 lastSavedValue; // only if onlyApplyOnEnter enabled
ChangeFunc changeFunc;
CCFOSelect() {};
CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){
this->value = value;
if (value)
this->lastSavedValue = this->displayedValue = *value;
this->save = save;
this->rightTexts = (char**)rightTexts;
this->numRightTexts = numRightTexts;
this->onlyApplyOnEnter = onlyApplyOnEnter;
this->changeFunc = changeFunc;
}
};
struct CCFODynamic : CCFO
{
DrawFunc drawFunc;
ButtonPressFunc buttonPressFunc;
CCFODynamic() {};
CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
this->value = value;
this->save = save;
this->drawFunc = drawFunc;
this->buttonPressFunc = buttonPressFunc;
}
};
struct CMenuScreenCustom
{
char m_ScreenName[8];
int32 m_PreviousPage[2]; // eMenuScreen
CCustomScreenLayout *layout;
ReturnPrevPageFunc returnPrevPageFunc;
struct CMenuEntry
{
int32 m_Action; // eMenuAction - below zero is CFO
char m_EntryName[8];
struct {
union {
CCFO *m_CFO; // for initializing
CCFOSelect *m_CFOSelect;
CCFODynamic *m_CFODynamic;
};
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
};
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreenCustom aScreens[MENUPAGES];
#endif
class CMenuManager
{
@ -628,7 +714,6 @@ public:
ISLAND_LOADING_HIGH
};
static int8 m_DisplayIslandLoading;
static int8 m_PrefsIslandLoading;
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
@ -696,6 +781,7 @@ public:
void PageUpList(bool);
void PageDownList(bool);
int8 GetPreviousPageOption();
void ProcessList(bool &goBack, bool &optionSelected);
};
#ifndef IMPROVED_VIDEOMODE
@ -703,6 +789,5 @@ VALIDATE_SIZE(CMenuManager, 0x564);
#endif
extern CMenuManager FrontEndMenuManager;
extern CMenuScreen aScreens[MENUPAGES];
#endif
#endif

View file

@ -22,7 +22,7 @@
#include "Game.h"
#include "World.h"
#include "PlayerInfo.h"
#include "FrontendControls.h"
#include "FrontEndControls.h"
#include "MemoryCard.h"
#define CRect_SZ(x, y, w, h) CRect(x, y, x+w, y+h)
@ -203,20 +203,6 @@ static const char* FrontendFilenames[][2] =
{"fe_radio9", "" },
};
#ifdef CUTSCENE_BORDERS_SWITCH
bool CMenuManager::m_PrefsCutsceneBorders = true;
#endif
#ifdef MULTISAMPLING
int8 CMenuManager::m_nPrefsMSAALevel = 0;
int8 CMenuManager::m_nDisplayMSAALevel = 0;
#endif
#ifdef NO_ISLAND_LOADING
int8 CMenuManager::m_DisplayIslandLoading = ISLAND_LOADING_LOW;
int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW;
#endif
int32 CMenuManager::m_PrefsSfxVolume = 102;
int32 CMenuManager::m_PrefsMusicVolume = 102;
int32 CMenuManager::m_PrefsBrightness = 256;
@ -3044,4 +3030,4 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *string, CRGBA &color)
*dst = '\0';
}
#endif
#endif

View file

@ -160,31 +160,9 @@ public:
static int32 m_PrefsLanguage;
static CONTRCONFIG m_PrefsControllerConfig;
static bool m_PrefsUseVibration;
#ifdef NO_ISLAND_LOADING
enum
{
ISLAND_LOADING_LOW = 0,
ISLAND_LOADING_MEDIUM,
ISLAND_LOADING_HIGH
};
static int8 m_DisplayIslandLoading;
static int8 m_PrefsIslandLoading;
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
#define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
#else
#define ISLAND_LOADING_IS(p)
#define ISLAND_LOADING_ISNT(p)
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
static bool m_PrefsCutsceneBorders;
#endif
#ifdef MULTISAMPLING
static int8 m_nPrefsMSAALevel;
static int8 m_nDisplayMSAALevel;
#endif
#ifdef GTA_PC
bool m_bQuitGameNoCD;

View file

@ -86,10 +86,14 @@
#include "ZoneCull.h"
#include "Zones.h"
#include "debugmenu.h"
#include "frontendoption.h"
#include "postfx.h"
#include "custompipes.h"
#include "screendroplets.h"
#include "crossplatform.h"
#include "MemoryHeap.h"
#ifdef USE_TEXTURE_POOL
#include "TexturePools.h"
#endif
eLevelName CGame::currLevel;
bool CGame::bDemoMode = true;
@ -129,7 +133,7 @@ void MessageScreen(char *msg)
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f // unused
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 450.0f
@ -172,19 +176,33 @@ CGame::InitialiseRenderWare(void)
#ifdef USE_TEXTURE_POOL
_TexturePoolsInitialise();
#endif
CTxdStore::Initialise();
CVisibilityPlugins::Initialise();
#if GTA_VERSION > GTA3_PS2_160
CTxdStore::Initialise(); // in GameInit on ps2
CVisibilityPlugins::Initialise(); // in plugin attach on ps2
#endif
//InitialiseScene(Scene); // PS2 only, only clears Scene.camera
#ifdef GTA_PS2
RpSkySelectTrueTSClipper(TRUE);
RpSkySelectTrueTLClipper(TRUE);
// PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights
// directly without going through RpWorld and all that
SetupPS2ManagerDefaultLightingCallback();
PreAllocateRwObjects();
#endif
/* Create camera */
Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE);
Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE);
ASSERT(Scene.camera != nil);
if (!Scene.camera)
{
return (false);
}
RwCameraSetFarClipPlane(Scene.camera, 2000.0f);
RwCameraSetFarClipPlane(Scene.camera, 2000.0f); // 250.0f on PS2 but who cares
RwCameraSetNearClipPlane(Scene.camera, 0.9f);
CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
@ -207,8 +225,12 @@ CGame::InitialiseRenderWare(void)
/* Add the camera to the world */
RpWorldAddCamera(Scene.world, Scene.camera);
LightsCreate(Scene.world);
CreateDebugFont();
#if GTA_VERSION > GTA3_PS2_160
CreateDebugFont(); // in GameInit on PS2
#else
RwImageSetPath("textures");
#endif
#ifdef LIBRW
#ifdef PS2_MATFX
@ -224,14 +246,22 @@ CGame::InitialiseRenderWare(void)
ReplaceAtomicPipeCallback();
#endif // PS2_ALPHA_TEST
#endif // LIBRW
#if GTA_VERSION > GTA3_PS2_160
// in GameInit on PS2
PUSH_MEMID(MEMID_TEXTURES);
CFont::Initialise();
CHud::Initialise();
POP_MEMID();
#endif
// TODO: define
CPlayerSkin::Initialise();
return (true);
}
// missing altogether on PS2
void CGame::ShutdownRenderWare(void)
{
CMBlur::MotionBlurClose();
@ -241,7 +271,8 @@ void CGame::ShutdownRenderWare(void)
for ( int32 i = 0; i < NUMPLAYERS; i++ )
CWorld::Players[i].DeletePlayerSkin();
// TODO: define
CPlayerSkin::Shutdown();
DestroyDebugFont();
@ -264,16 +295,19 @@ void CGame::ShutdownRenderWare(void)
#endif
}
// missing altogether on PS2
bool CGame::InitialiseOnceAfterRW(void)
{
#if GTA_VERSION > GTA3_PS2_160
TheText.Load();
DMAudio.Initialise();
DMAudio.Initialise(); // before TheGame() on PS2
CTimer::Initialise();
CTempColModels::Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
#endif
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1;
@ -314,19 +348,10 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetMusicFadeVol(127);
CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
#ifdef CUSTOM_FRONTEND_OPTIONS
// Apparently this func. can be run multiple times at the start.
if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) {
// needs stored language and TheText to be loaded, and last TheText reload is at the start of here
CustomFrontendOptionsPopulate();
}
#endif
#ifdef LOAD_INI_SETTINGS
LoadINISettings(); // needs frontend options to be loaded
#endif
return true;
}
// missing altogether on PS2
void
CGame::FinalShutdown(void)
{
@ -337,21 +362,40 @@ CGame::FinalShutdown(void)
bool CGame::Initialise(const char* datFile)
{
#ifdef GTA_PS2
// TODO: upload VU0 collision code here
#endif
#if GTA_VERSION > GTA3_PS2_160
ResetLoadingScreenBar();
strcpy(aDatFile, datFile);
CPools::Initialise();
CPools::Initialise(); // done in CWorld on PS2
#endif
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#endif
currLevel = LEVEL_INDUSTRIAL;
PUSH_MEMID(MEMID_TEXTURES);
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot);
CTxdStore::AddRef(gameTxdSlot);
LoadingScreen("Loading the Game", "Loading particles", nil);
int particleTxdSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD");
CTxdStore::AddRef(particleTxdSlot);
CTxdStore::SetCurrentTxd(gameTxdSlot);
LoadingScreen("Loading the Game", "Setup game variables", nil);
POP_MEMID();
#ifdef GTA_PS2
CDma::SyncChannel(0, true);
#endif
CGameLogic::InitAtStartOfGame();
CReferences::Init();
TheCamera.Init();
@ -362,32 +406,72 @@ bool CGame::Initialise(const char* datFile)
CWeather::Init();
CCullZones::Init();
CCollision::Init();
#ifdef PS2_MENU
#ifdef PS2_MENU // TODO: is this the right define?
TheText.Load();
#endif
CTheZones::Init();
CUserDisplay::Init();
CMessages::Init();
#if GTA_VERSION > GTA3_PS2_160
CMessages::ClearAllMessagesDisplayedByGame();
#endif
CRecordDataForGame::Init();
CRestart::Initialise();
PUSH_MEMID(MEMID_WORLD);
CWorld::Initialise();
POP_MEMID();
#if GTA_VERSION <= GTA3_PS2_160
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CTempColModels::Initialise();
#endif
PUSH_MEMID(MEMID_TEXTURES);
CParticle::Initialise();
#ifdef PS2
POP_MEMID();
#if GTA_VERSION <= GTA3_PS2_160
gStartX = -180.0f;
gStartY = 180.0f;
gStartZ = 14.0f;
#endif
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::Initialise();
CCutsceneMgr::Initialise();
POP_MEMID();
PUSH_MEMID(MEMID_CARS);
CCarCtrl::Init();
POP_MEMID();
#if GTA_VERSION > GTA3_PS2_160
InitModelIndices();
#endif
PUSH_MEMID(MEMID_DEF_MODELS);
CModelInfo::Initialise();
#if GTA_VERSION <= GTA3_PS2_160
CPedStats::Initialise(); // InitialiseOnceAfterRW
#else
// probably moved before LoadLevel for multiplayer maps?
CPickups::Init();
CTheCarGenerators::Init();
#endif
#ifndef GTA_PS2 // or GTA_VERSION?
CdStreamAddImage("MODELS\\GTA3.IMG");
#endif
#if GTA_VERSION > GTA3_PS2_160
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
#else
CFileLoader::LoadLevel("GTA3.DAT");
#endif
#ifdef EXTENDED_PIPELINES
// for generic fallback
CustomPipes::SetTxdFindCallback();
@ -396,17 +480,30 @@ bool CGame::Initialise(const char* datFile)
CVehicleModelInfo::LoadVehicleColours();
CVehicleModelInfo::LoadEnvironmentMaps();
CTheZones::PostZoneCreation();
POP_MEMID();
#if GTA_VERSION <= GTA3_PS2_160
TestModelIndices();
#endif
LoadingScreen("Loading the Game", "Setup paths", GetRandomSplashScreen());
ThePaths.PreparePathData();
#if GTA_VERSION > GTA3_PS2_160
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CWorld::Players[0].LoadPlayerSkin();
TestModelIndices();
#endif
LoadingScreen("Loading the Game", "Setup water", nil);
CWaterLevel::Initialise("DATA\\WATER.DAT");
#if GTA_VERSION <= GTA3_PS2_160
CTimeCycle::Initialise(); // InitialiseOnceAfterRW
#else
TheConsole.Init();
#endif
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
CStreaming::Init();
CStreaming::LoadInitialVehicles();
@ -414,22 +511,37 @@ bool CGame::Initialise(const char* datFile)
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::LoadAnimFiles();
POP_MEMID();
CPed::Initialise();
CRouteNode::Initialise();
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
LoadingScreen("Loading the Game", "Find big buildings", nil);
CRenderer::Init();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CRadar::Initialise();
CRadar::LoadTextures();
CWeapon::InitialiseWeapons();
LoadingScreen("Loading the Game", "Setup traffic lights", nil);
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CPopulation::Initialise();
#if GTA_VERSION <= GTA3_PS2_160
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
// CWorld::Players[0].LoadPlayerSkin(); // TODO: use a define for this
#endif
CWorld::PlayerInFocus = 0;
CCoronas::Init();
CShadows::Init();
@ -438,44 +550,74 @@ bool CGame::Initialise(const char* datFile)
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
#ifdef GTA_SCENE_EDIT
CSceneEdit::Initialise();
#endif
LoadingScreen("Loading the Game", "Load scripts", nil);
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
POP_MEMID();
LoadingScreen("Loading the Game", "Setup game variables", nil);
#if GTA_VERSION <= GTA3_PS2_160
CTimer::Initialise();
#endif
CClock::Initialise(1000);
#if GTA_VERSION <= GTA3_PS2_160
CTheCarGenerators::Init();
#endif
CHeli::InitHelis();
CCranes::InitCranes();
CMovingThings::Init();
CDarkel::Init();
CStats::Init();
#if GTA_VERSION <= GTA3_PS2_160
CPickups::Init();
#endif
CPacManPickups::Init();
#if GTA_VERSION <= GTA3_PS2_160
CGarages::Init();
#endif
CRubbish::Init();
CClouds::Init();
#if GTA_VERSION <= GTA3_PS2_160
CRemote::Init();
#endif
CSpecialFX::Init();
CWaterCannons::Init();
CBridge::Init();
#if GTA_VERSION > GTA3_PS2_160
CGarages::Init();
#endif
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
CWorld::RepositionCertainDynamicObjects();
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
#if GTA_VERSION <= GTA3_PS2_160
CCullZones::ResolveVisibilities();
#endif
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
#if GTA_VERSION > GTA3_PS2_160
CCullZones::ResolveVisibilities();
#endif
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
CRecordDataForChase::Init();
CReplay::Init();
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
#endif
{
#endif
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
#ifdef PS2_MENU
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
}
#endif
LoadingScreen("Loading the Game", "Load scene", nil);
CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = currLevel;
@ -490,7 +632,7 @@ bool CGame::ShutDown(void)
CPlane::Shutdown();
CTrain::Shutdown();
CSpecialFX::Shutdown();
#ifndef PS2
#if GTA_VERSION > GTA3_PS2_160
CGarages::Shutdown();
#endif
CMovingThings::Shutdown();
@ -531,7 +673,9 @@ bool CGame::ShutDown(void)
CSkidmarks::Shutdown();
CWeaponEffects::Shutdown();
CParticle::Shutdown();
#if GTA_VERSION > GTA3_PS2_160
CPools::ShutDown();
#endif
CTxdStore::RemoveTxdSlot(gameTxdSlot);
CdStreamRemoveImages();
return true;
@ -542,13 +686,11 @@ void CGame::ReInitGameObjectVariables(void)
CGameLogic::InitAtStartOfGame();
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
#endif
{
#endif
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
#ifdef PS2_MENU
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
}
#endif
CDebug::DebugInitTextBuffer();
CWeather::Init();
CUserDisplay::Init();
@ -557,7 +699,7 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::bDoingCarCollisions = false;
CHud::ReInitialise();
CRadar::Initialise();
#ifdef PS2
#if GTA_VERSION <= GTA3_PS2_160
gStartX = -180.0f;
gStartY = 180.0f;
gStartZ = 14.0f;
@ -570,6 +712,9 @@ void CGame::ReInitGameObjectVariables(void)
CStreaming::LoadAllRequestedModels(false);
CPed::Initialise();
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
CWeapon::InitialiseWeapons();
CPopulation::Initialise();
@ -577,15 +722,19 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::Players[i].Clear();
CWorld::PlayerInFocus = 0;
#ifdef PS2
#if GTA_VERSION <= GTA3_PS2_160
CWeaponEffects::Init();
CSkidmarks::Init();
#endif
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
POP_MEMID();
CTimer::Initialise();
CClock::Initialise(1000);
CTheCarGenerators::Init();
@ -596,7 +745,7 @@ void CGame::ReInitGameObjectVariables(void)
CPickups::Init();
CPacManPickups::Init();
CGarages::Init();
#ifdef PS2
#if GTA_VERSION <= GTA3_PS2_160
CClouds::Init();
CRemote::Init();
#endif
@ -666,7 +815,7 @@ void CGame::ShutDownForRestart(void)
CRadar::RemoveRadarSections();
FrontEndMenuManager.UnloadTextures();
CParticleObject::RemoveAllParticleObjects();
#ifndef PS2
#if GTA_VERSION >= GTA3_PS2_160
CPedType::Shutdown();
CSpecialFX::Shutdown();
#endif
@ -745,10 +894,10 @@ void CGame::InitialiseWhenRestarting(void)
//CFont::SetFontStyle(?);
CFont::SetBackgroundOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f // unused
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_SCALE_X(480.0f)); // 480.0f
CFont::SetCentreSize(SCREEN_SCALE_X(480.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 255, 255));
CFont::SetBackGroundOnlyTextOff();
@ -811,7 +960,7 @@ void CGame::InitialiseWhenRestarting(void)
void CGame::Process(void)
{
CPad::UpdatePads();
#ifdef GTA_PS2
#ifdef USE_CUSTOM_ALLOCATOR
ProcessTidyUpMemory();
#endif
TheCamera.SetMotionBlurAlpha(0);
@ -821,8 +970,12 @@ void CGame::Process(void)
DebugMenuProcess();
#endif
CCutsceneMgr::Update();
PUSH_MEMID(MEMID_FRONTEND);
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
POP_MEMID();
CStreaming::Update();
if (!CTimer::GetIsPaused())
{
@ -835,7 +988,11 @@ void CGame::Process(void)
CPad::DoCheats();
CClock::Update();
CWeather::Update();
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Process();
POP_MEMID();
CCollision::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
@ -844,7 +1001,9 @@ void CGame::Process(void)
CSkidmarks::Update();
CAntennas::Update();
CGlass::Update();
#ifdef GTA_SCENE_EDIT
CSceneEdit::Update();
#endif
CEventList::Update();
CParticle::Update();
gFireManager.Update();
@ -859,7 +1018,11 @@ void CGame::Process(void)
CWaterCannons::Update();
CUserDisplay::Process();
CReplay::Update();
PUSH_MEMID(MEMID_WORLD);
CWorld::Process();
POP_MEMID();
gAccidentManager.Update();
CPacManPickups::Update();
CPickups::Update();
@ -880,33 +1043,370 @@ void CGame::Process(void)
gPhoneInfo.Update();
if (!CReplay::IsPlayingBack())
{
PUSH_MEMID(MEMID_CARS);
CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
POP_MEMID();
}
}
#ifdef PS2
#ifdef GTA_PS2
CMemCheck::DoTest();
#endif
}
void CGame::DrasticTidyUpMemory(bool)
#ifdef USE_CUSTOM_ALLOCATOR
int32 gNumMemMoved;
bool
MoveMem(void **ptr)
{
#ifdef PS2
// meow
if(*ptr){
gNumMemMoved++;
void *newPtr = gMainHeap.MoveMemory(*ptr);
if(*ptr != newPtr){
*ptr = newPtr;
return true;
}
}
return false;
}
// Some convenience structs
struct SkyDataPrefix
{
uint32 pktSize1;
uint32 data; // pointer to data as read from TXD
uint32 pktSize2;
uint32 unused;
};
struct DMAGIFUpload
{
uint32 tag1_qwc, tag1_addr; // dmaref
uint32 nop1, vif_direct1;
uint32 giftag[4];
uint32 gs_bitbltbuf[4];
uint32 tag2_qwc, tag2_addr; // dmaref
uint32 nop2, vif_direct2;
};
// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot
RwTexture *
MoveTextureMemoryCB(RwTexture *texture, void *pData)
{
#ifdef GTA_PS2
bool *pRet = (bool*)pData;
RwRaster *raster = RwTextureGetRaster(texture);
_SkyRasterExt *rasterExt = RASTEREXTFROMRASTER(raster);
if(raster->originalPixels == nil || // the raw data
raster->cpPixels == raster->originalPixels || // old format, can't handle it
rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0)
return texture;
// this is the allocated pointer we will move
SkyDataPrefix *prefix = (SkyDataPrefix*)raster->originalPixels;
DMAGIFUpload *uploads = (DMAGIFUpload*)(prefix+1);
// We have 4qw for each upload,
// i.e. for each buffer width of mip levels,
// and the palette if there is one.
// NB: this code does NOT support mipmaps!
// so we assume two uploads (pixels and palette)
//
// each upload looks like this:
// (DMAcnt; NOP; VIF DIRECT(2))
// giftag (1, A+D)
// GS_BITBLTBUF
// (DMAref->pixel data; NOP; VIF DIRECT(5))
// the DMArefs are what we have to adjust
uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff;
dataDiff = prefix->data - (uintptr)raster->originalPixels;
upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels;
if(raster->palette)
upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels;
pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels;
if(raster->palette)
paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels;
uint8 *newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels);
if(newptr != raster->originalPixels){
// adjust everything
prefix->data = (uintptr)newptr + dataDiff;
uploads[0].tag2_addr = (uintptr)newptr + upload1Diff;
if(raster->palette)
uploads[1].tag2_addr = (uintptr)newptr + upload2Diff;
raster->originalPixels = newptr;
raster->cpPixels = newptr + pixelDiff;
if(raster->palette)
raster->palette = newptr + paletteDiff;
if(pRet){
*pRet = true;
return nil;
}
}
#else
// nothing to do here really, everything should be in videomemory
#endif
return texture;
}
bool
MoveAtomicMemory(RpAtomic *atomic, bool onlyOne)
{
RpGeometry *geo = RpAtomicGetGeometry(atomic);
#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
if(MoveMem((void**)&geo->triangles) && onlyOne)
return true;
if(MoveMem((void**)&geo->matList.materials) && onlyOne)
return true;
if(MoveMem((void**)&geo->preLitLum) && onlyOne)
return true;
if(MoveMem((void**)&geo->texCoords[0]) && onlyOne)
return true;
if(MoveMem((void**)&geo->texCoords[1]) && onlyOne)
return true;
// verts and normals of morph target are allocated together
int vertDiff;
if(geo->morphTarget->normals)
vertDiff = geo->morphTarget->normals - geo->morphTarget->verts;
if(MoveMem((void**)&geo->morphTarget->verts)){
if(geo->morphTarget->normals)
geo->morphTarget->normals = geo->morphTarget->verts + vertDiff;
if(onlyOne)
return true;
}
RpMeshHeader *oldmesh = geo->mesh;
if(MoveMem((void**)&geo->mesh)){
// index pointers are allocated together with meshes,
// have to relocate those too
RpMesh *mesh = (RpMesh*)(geo->mesh+1);
uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh;
for(int i = 0; i < geo->mesh->numMeshes; i++)
mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc);
if(onlyOne)
return true;
}
#else
// we could do something in librw here
#endif
return false;
}
bool
MoveColModelMemory(CColModel &colModel, bool onlyOne)
{
#if GTA_VERSION >= GTA3_PS2_160
// hm...should probably only do this if ownsCollisionVolumes
// but it doesn't exist on PS2...
if(!colModel.ownsCollisionVolumes)
return false;
#endif
if(MoveMem((void**)&colModel.spheres) && onlyOne)
return true;
if(MoveMem((void**)&colModel.lines) && onlyOne)
return true;
if(MoveMem((void**)&colModel.boxes) && onlyOne)
return true;
if(MoveMem((void**)&colModel.vertices) && onlyOne)
return true;
if(MoveMem((void**)&colModel.triangles) && onlyOne)
return true;
if(MoveMem((void**)&colModel.trianglePlanes) && onlyOne)
return true;
return false;
}
RpAtomic*
MoveAtomicMemoryCB(RpAtomic *atomic, void *pData)
{
bool *pRet = (bool*)pData;
if(pRet == nil)
MoveAtomicMemory(atomic, false);
else if(MoveAtomicMemory(atomic, true)){
*pRet = true;
return nil;
}
return atomic;
}
bool
TidyUpModelInfo(CBaseModelInfo *modelInfo, bool onlyone)
{
if(modelInfo->GetColModel() && modelInfo->DoesOwnColModel())
if(MoveColModelMemory(*modelInfo->GetColModel(), onlyone))
return true;
RwObject *rwobj = modelInfo->GetRwObject();
if(RwObjectGetType(rwobj) == rpATOMIC)
if(MoveAtomicMemory((RpAtomic*)rwobj, onlyone))
return true;
if(RwObjectGetType(rwobj) == rpCLUMP){
bool ret = false;
if(onlyone)
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret);
else
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil);
if(ret)
return true;
}
if(modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel)
if(MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone))
return true;
return false;
}
#endif
void CGame::DrasticTidyUpMemory(bool flushDraw)
{
#ifdef USE_CUSTOM_ALLOCATOR
bool removedCol = false;
TidyUpMemory(true, flushDraw);
if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
TidyUpMemory(true, flushDraw);
}
if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC);
TidyUpMemory(true, flushDraw);
removedCol = true;
}
if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
TidyUpMemory(true, flushDraw);
}
if(removedCol){
// different on PS2
CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory);
}
if(!playingIntro)
CStreaming::RequestBigBuildings(currLevel);
CStreaming::LoadAllRequestedModels(true);
#endif
}
void CGame::TidyUpMemory(bool, bool)
void CGame::TidyUpMemory(bool moveTextures, bool flushDraw)
{
#ifdef PS2
// meow
#ifdef USE_CUSTOM_ALLOCATOR
printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock());
if(moveTextures){
if(flushDraw){
#ifdef GTA_PS2
for(int i = 0; i < sweMaxFlips+1; i++){
#else
for(int i = 0; i < 5; i++){ // probably more than needed
#endif
RwCameraBeginUpdate(Scene.camera);
RwCameraEndUpdate(Scene.camera);
RwCameraShowRaster(Scene.camera, nil, 0);
}
}
int fontSlot = CTxdStore::FindTxdSlot("fonts");
for(int i = 0; i < TXDSTORESIZE; i++){
if(i == fontSlot ||
CTxdStore::GetSlot(i) == nil)
continue;
RwTexDictionary *txd = CTxdStore::GetSlot(i)->texDict;
if(txd)
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil);
}
}
// animations
for(int i = 0; i < NUMANIMATIONS; i++){
CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(i);
if(anim == nil)
continue; // cannot happen
anim->MoveMemory();
}
// model info
for(int i = 0; i < MODELINFOSIZE; i++){
CBaseModelInfo *mi = CModelInfo::GetModelInfo(i);
if(mi == nil)
continue;
TidyUpModelInfo(mi, false);
}
printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock());
#endif
}
void CGame::ProcessTidyUpMemory(void)
{
#ifdef PS2
// meow
#ifdef USE_CUSTOM_ALLOCATOR
static int32 modelIndex = 0;
static int32 animIndex = 0;
static int32 txdIndex = 0;
bool txdReturn = false;
RwTexDictionary *txd = nil;
gNumMemMoved = 0;
// model infos
for(int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++){
CBaseModelInfo *mi;
do{
mi = CModelInfo::GetModelInfo(modelIndex);
modelIndex++;
if(modelIndex >= MODELINFOSIZE)
modelIndex = 0;
}while(mi == nil);
if(TidyUpModelInfo(mi, true))
return;
}
// tex dicts
for(int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++){
if(gNumMemMoved > 80)
break;
do{
#ifdef FIX_BUGS
txd = nil;
#endif
if(CTxdStore::GetSlot(txdIndex))
txd = CTxdStore::GetSlot(txdIndex)->texDict;
txdIndex++;
if(txdIndex >= TXDSTORESIZE)
txdIndex = 0;
}while(txd == nil);
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn);
if(txdReturn)
return;
}
// animations
CAnimBlendHierarchy *anim;
do{
anim = CAnimManager::GetAnimation(animIndex);
animIndex++;
if(animIndex >= NUMANIMATIONS)
animIndex = 0;
}while(anim == nil); // always != nil
anim->MoveMemory(true);
#endif
}

View file

@ -2,8 +2,10 @@
#include "Frontend.h"
#ifdef PC_MENU
// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp.
// Please don't touch this file, except for bug fixing or ports.
// Check MenuScreensCustom.cpp
#ifndef CUSTOM_FRONTEND_OPTIONS
CMenuScreen aScreens[MENUPAGES] = {
// MENUPAGE_NONE = 0
{ "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
@ -390,6 +392,9 @@ CMenuScreen aScreens[MENUPAGES] = {
{ "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
#ifdef MENU_MAP
MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP,
#endif
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
@ -436,10 +441,10 @@ CMenuScreen aScreens[MENUPAGES] = {
#ifdef MENU_MAP
// MENUPAGE_MAP
{ "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
{ "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 2,
MENUACTION_UNK110, "", SAVESLOT_NONE, MENUPAGE_NONE, // to prevent cross/enter to go back
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
},
#endif
// MENUPAGE_UNK
@ -449,4 +454,5 @@ CMenuScreen aScreens[MENUPAGES] = {
};
#endif
#endif
#endif

View file

@ -0,0 +1,878 @@
#include "common.h"
#include "platform.h"
#include "crossplatform.h"
#include "Renderer.h"
#include "Frontend.h"
#include "Font.h"
#include "Camera.h"
#include "main.h"
#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
#include "RwHelper.h"
#include "Text.h"
#include "Streaming.h"
#include "FileLoader.h"
#include "Collision.h"
#include "ModelInfo.h"
#include "Pad.h"
// Menu screens array is at the bottom of the file.
#ifdef PC_MENU
#ifdef CUSTOM_FRONTEND_OPTIONS
#ifdef IMPROVED_VIDEOMODE
#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) },
#else
#define VIDEOMODE_SELECTOR
#endif
#ifdef MULTISAMPLING
#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
#else
#define MULTISAMPLING_SELECTOR
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) },
#else
#define CUTSCENE_BORDERS_TOGGLE
#endif
#ifdef FREE_CAM
#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) },
#else
#define FREE_CAM_TOGGLE
#endif
#ifdef PS2_ALPHA_TEST
#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) },
#else
#define DUALPASS_SELECTOR
#endif
#ifdef NO_ISLAND_LOADING
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
#else
#define ISLAND_LOADING_SELECTOR
#endif
#ifdef EXTENDED_COLOURFILTER
#define POSTFX_SELECTORS \
MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \
MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) },
#else
#define POSTFX_SELECTORS
#endif
#ifdef EXTENDED_PIPELINES
#define PIPELINES_SELECTOR \
MENUACTION_CFO_SELECT, "FED_VPL", { new CCFOSelect((int8*)&CustomPipes::VehiclePipeSwitch, "VehiclePipeline", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), false, nil) }, \
MENUACTION_CFO_SELECT, "FED_PRM", { new CCFOSelect((int8*)&CustomPipes::RimlightEnable, "NeoRimLight", off_on, 2, false, nil) }, \
MENUACTION_CFO_SELECT, "FED_WLM", { new CCFOSelect((int8*)&CustomPipes::LightmapEnable, "NeoLightMaps", off_on, 2, false, nil) }, \
MENUACTION_CFO_SELECT, "FED_RGL", { new CCFOSelect((int8*)&CustomPipes::GlossEnable, "NeoRoadGloss", off_on, 2, false, nil) },
#else
#define PIPELINES_SELECTOR
#endif
#ifdef INVERT_LOOK_FOR_PAD
#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "InvertPad", off_on, 2, false, nil) },
#else
#define INVERT_PAD_SELECTOR
#endif
const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" };
const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" };
void RestoreDefGraphics(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef PS2_ALPHA_TEST
gPS2alphaTest = false;
#endif
#ifdef MULTISAMPLING
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
#endif
#ifdef NO_ISLAND_LOADING
if (!FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
CCollision::bAlreadyLoaded = false;
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
CStreaming::LoadAllRequestedModels(true);
} else
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
CMenuManager::m_PrefsFrameLimiter = true;
CMenuManager::m_PrefsVsyncDisp = true;
CMenuManager::m_PrefsVsync = true;
CMenuManager::m_PrefsUseWideScreen = false;
FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
#if GTA_VERSION >= GTA3_PC_11
if (_dwOperatingSystemVersion == OS_WIN98) {
CMBlur::BlurOn = false;
CMBlur::MotionBlurClose();
} else {
CMBlur::BlurOn = true;
CMBlur::MotionBlurOpen(Scene.camera);
}
#else
CMBlur::BlurOn = true;
#endif
FrontEndMenuManager.SaveSettings();
#endif
}
void RestoreDefDisplay(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef CUTSCENE_BORDERS_SWITCH
CMenuManager::m_PrefsCutsceneBorders = true;
#endif
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
CMenuManager::m_PrefsBrightness = 256;
CMenuManager::m_PrefsLOD = 1.2f;
CRenderer::ms_lodDistScale = 1.2f;
CMenuManager::m_PrefsShowSubtitles = true;
FrontEndMenuManager.SaveSettings();
#endif
}
#ifdef NO_ISLAND_LOADING
const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" };
void IslandLoadingAfterChange(int8 before, int8 after) {
if (!FrontEndMenuManager.m_bGameNotLoaded) {
if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) {
FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug:
if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH)
CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC);
if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
if (CGame::currLevel != LEVEL_INDUSTRIAL)
CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL);
if (CGame::currLevel != LEVEL_COMMERCIAL)
CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL);
if (CGame::currLevel != LEVEL_SUBURBAN)
CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN);
CCollision::bAlreadyLoaded = true;
FrontEndMenuManager.m_PrefsIslandLoading = after;
CStreaming::RequestBigBuildings(CGame::currLevel);
} else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
FrontEndMenuManager.m_PrefsIslandLoading = after;
CStreaming::RequestIslands(CGame::currLevel);
} else
FrontEndMenuManager.m_PrefsIslandLoading = after;
} else { // low
CCollision::bAlreadyLoaded = false;
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
}
CStreaming::LoadAllRequestedModels(true);
}
FrontEndMenuManager.SetHelperText(0);
}
#endif
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangRusSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangJapSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
#endif
#ifndef MULTISAMPLING
void GraphicsGoBack() {
}
#else
void GraphicsGoBack() {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
void MultiSamplingButtonPress(int8 action) {
if (action == FEOPTION_ACTION_SELECT) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
} else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) {
if (FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1);
int i = 0;
int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels();
while (maxAA != 1) {
i++;
maxAA >>= 1;
}
if (FrontEndMenuManager.m_nDisplayMSAALevel < 0)
FrontEndMenuManager.m_nDisplayMSAALevel = i;
else if (FrontEndMenuManager.m_nDisplayMSAALevel > i)
FrontEndMenuManager.m_nDisplayMSAALevel = 0;
}
} else if (action == FEOPTION_ACTION_FOCUSLOSS) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
FrontEndMenuManager.SetHelperText(3);
}
}
}
wchar* MultiSamplingDraw(bool *disabled, bool userHovering) {
static wchar unicodeTemp[64];
if (userHovering) {
if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) {
if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply
FrontEndMenuManager.ResetHelperText();
} else {
FrontEndMenuManager.SetHelperText(1);
}
} else {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
}
if (!FrontEndMenuManager.m_bGameNotLoaded)
*disabled = true;
switch (FrontEndMenuManager.m_nDisplayMSAALevel) {
case 0:
return TheText.Get("FEM_OFF");
default:
sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel));
AsciiToUnicode(gString, unicodeTemp);
return unicodeTemp;
}
}
#endif
#ifdef IMPROVED_VIDEOMODE
const char* screenModes[] = { "FED_FLS", "FED_WND" };
void ScreenModeAfterChange(int8 before, int8 after)
{
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
FrontEndMenuManager.SetHelperText(0);
}
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
wchar selectedJoystickUnicode[128];
wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
int numButtons;
int found = -1;
const char *joyname;
if (userHovering) {
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if ((joyname = glfwGetJoystickName(i))) {
const uint8* buttons = glfwGetJoystickButtons(i, &numButtons);
for (int j = 0; j < numButtons; j++) {
if (buttons[j]) {
found = i;
break;
}
}
if (found != -1)
break;
}
}
if (found != -1 && PSGLOBAL(joy1id) != found) {
if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found)
PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
else
PSGLOBAL(joy2id) = -1;
strcpy(gSelectedJoystickName, joyname);
PSGLOBAL(joy1id) = found;
}
}
if (PSGLOBAL(joy1id) == -1)
AsciiToUnicode("Not found", selectedJoystickUnicode);
else
AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
return selectedJoystickUnicode;
}
#endif
CMenuScreenCustom aScreens[MENUPAGES] = {
// MENUPAGE_NONE = 0
{ "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil, },
// MENUPAGE_STATS = 1
{ "FET_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_NEW_GAME = 2
{ "FET_SGA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FES_SNG", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_BRIEFS = 3
{ "FET_BRE", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CONTROLLER_SETTINGS = 4
{ "FET_CON", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_SOUND_SETTINGS = 5
{ "FET_AUD", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_MUSICVOLUME, "FEA_MUS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_SFXVOLUME, "FEA_SFX", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_AUDIOHW, "FEA_3DH", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_SPEAKERCONF, "FEA_SPK", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_RADIO, "FEA_RSS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#ifndef GRAPHICS_MENU_OPTIONS
// MENUPAGE_DISPLAY_SETTINGS = 6
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
#ifndef EXTENDED_COLOURFILTER
MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
#endif
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
VIDEOMODE_SELECTOR
MULTISAMPLING_SELECTOR
MENUACTION_CHANGEMENU, "FET_ADV", { nil, SAVESLOT_NONE, MENUPAGE_ADVANCED_DISPLAY_SETTINGS },
MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#else
// MENUPAGE_DISPLAY_SETTINGS = 6
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#endif
// MENUPAGE_LANGUAGE_SETTINGS = 7
{ "FET_LAN", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_LANG_ENG, "FEL_ENG", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
MENUACTION_LANG_FRE, "FEL_FRE", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
MENUACTION_LANG_GER, "FEL_GER", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
MENUACTION_LANG_ITA, "FEL_ITA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
MENUACTION_LANG_SPA, "FEL_SPA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
#ifdef MORE_LANGUAGES
MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) },
MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) },
MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) },
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CHOOSE_LOAD_SLOT = 8
{ "FET_LG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
MENUACTION_CHECKSAVE, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM },
MENUACTION_CHECKSAVE, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM },
},
// MENUPAGE_CHOOSE_DELETE_SLOT = 9
{ "FET_DG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
MENUACTION_CHANGEMENU, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM },
},
// MENUPAGE_NEW_GAME_RELOAD = 10
{ "FET_NG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FESZ_QR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
MENUACTION_NEWGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
},
// MENUPAGE_LOAD_SLOT_CONFIRM = 11
{ "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
},
// MENUPAGE_DELETE_SLOT_CONFIRM = 12
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_DELETING },
},
// MENUPAGE_NO_MEMORY_CARD = 13
{ "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
// hud adjustment page in mobile
},
// MENUPAGE_LOADING_IN_PROGRESS = 14
{ "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FED_LDW", { nil, SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM },
},
// MENUPAGE_DELETING_IN_PROGRESS = 15
{ "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FEDL_WR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_PS2_LOAD_FAILED = 16
{ "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FES_LOE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_DELETE_FAILED = 17
{ "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FES_DEE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
},
// MENUPAGE_DEBUG_MENU = 18
{ "FED_DBG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_RELOADIDE, "FED_RID", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_RELOADIPL, "FED_RIP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SETDBGFLAG, "FED_DFL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_PEDROADGROUPS, "FED_SPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CARROADGROUPS, "FED_SCR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_COLLISIONPOLYS, "FED_SCP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_PARSEHEAP, "FED_PAH", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SHOWCULL, "FED_SCZ", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_DEBUGSTREAM, "FED_DSR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_MEMORY_CARD_DEBUG = 19
{ "FEM_MCM", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_REGMEMCARD1, "FEM_RMC", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CREATEROOTDIR, "FEM_CRD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CREATELOADICONS, "FEM_CLI", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_FILLWITHGUFF, "FEM_FFF", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SAVEGAME, "FEM_STG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_MEMORY_CARD_TEST = 20
{ "FEM_MC2", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_MAIN = 21
{ "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_PS2_SAVE_FAILED = 22
{ "MCDNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_PS2_SAVE_FAILED_2 = 23
{ "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// Unused in PC but anyway
// MENUPAGE_SAVE = 24
#ifdef PS2_SAVE_DIALOG
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_CHANGEMENU, "FESZ_SA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#else
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FES_SCG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#endif
// MENUPAGE_NO_MEMORY_CARD_2 = 25
{ "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CHOOSE_SAVE_SLOT = 26
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
MENUACTION_CHANGEMENU, "FEM_SL8", { nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
},
// MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS },
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
},
// MENUPAGE_MULTIPLAYER_MAP = 28
{ "FET_MAP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_CONNECTION = 29
{ "FET_CON", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_FIND_GAME = 30
{ "FET_FG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_MODE = 31
{ "FET_GT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_CREATE = 32
{ "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_MULTIPLAYER_START = 33
{ "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_SKIN_SELECT_OLD = 34
{ "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_CONTROLLER_PC = 35
{ "FET_CTL", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_CTRLMETHOD, "FET_CME", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
MENUACTION_KEYBOARDCTRLS,"FET_RDK", { nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS },
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK },
#endif
MENUACTION_CHANGEMENU, "FET_AMS", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_PLB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_CWL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_CWR", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_LKT", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_PJP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_PSP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_TLF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_TRG", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_GETKEY, "FEC_CCM", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
},
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_LUP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
MENUACTION_GETKEY, "FEC_LDN", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
MENUACTION_SHOWHEADBOB, "FEC_GSL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
},
// MENUPAGE_CONTROLLER_DEBUG = 40
{ "FEC_DBG", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_TGD", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
MENUACTION_GETKEY, "FEC_TDO", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
MENUACTION_GETKEY, "FEC_TSS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_OPTIONS = 41
{ "FET_OPT", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FET_CTL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
MENUACTION_LOADRADIO, "FET_AUD", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
MENUACTION_CHANGEMENU, "FET_DIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
#ifdef GRAPHICS_MENU_OPTIONS
MENUACTION_CHANGEMENU, "FET_GRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
#endif
MENUACTION_CHANGEMENU, "FET_LAN", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
MENUACTION_PLAYERSETUP, "FET_PSU", { nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_EXIT = 42
{ "FET_QG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_LABEL, "FEQ_SRE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_DONTCANCEL, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CANCELGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_SAVING_IN_PROGRESS = 43
{ "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FES_WAR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_SAVE_SUCCESSFUL = 44
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FES_SSC", { nil, SAVESLOT_LABEL, MENUPAGE_NONE },
MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
},
// MENUPAGE_DELETING = 45
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
MENUACTION_LABEL, "FED_DLW", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_DELETE_SUCCESS = 46
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
MENUACTION_LABEL, "DEL_FNM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
},
// MENUPAGE_SAVE_FAILED = 47
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
},
// MENUPAGE_LOAD_FAILED = 48
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_LOAD_FAILED_2 = 49
{ "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FEC_LUN", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
},
// MENUPAGE_FILTER_GAME = 50
{ "FIL_FLT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
},
// MENUPAGE_START_MENU = 51
{ "FEM_MM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
},
// MENUPAGE_PAUSE_MENU = 52
{ "FET_PAU", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_RESUME, "FEM_RES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
#ifdef MENU_MAP
MENUACTION_CHANGEMENU, "FEG_MAP", { nil, SAVESLOT_NONE, MENUPAGE_MAP },
#endif
MENUACTION_CHANGEMENU, "FEP_STA", { nil, SAVESLOT_NONE, MENUPAGE_STATS },
MENUACTION_CHANGEMENU, "FEP_BRI", { nil, SAVESLOT_NONE, MENUPAGE_BRIEFS },
MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
},
// MENUPAGE_CHOOSE_MODE = 53
{ "FEN_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FET_SP", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
MENUACTION_INITMP, "FET_MP", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_SKIN_SELECT = 54
{ "FET_PSU", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
},
// MENUPAGE_KEYBOARD_CONTROLS = 55
{ "FET_STI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
},
// MENUPAGE_MOUSE_CONTROLS = 56
{ "FET_MTI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_MOUSESENS, "FEC_MSH", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
MENUACTION_INVVERT, "FEC_IVV", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
INVERT_PAD_SELECTOR
MENUACTION_MOUSESTEER, "FET_MST", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
// MENUPAGE_MISSION_RETRY = 57
#ifdef MISSION_REPLAY
{ "M_FAIL", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FESZ_RM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
MENUACTION_REJECT_RETRY, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#else
{ "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
// mission failed, wanna restart page in mobile
},
#endif
#ifdef MENU_MAP
// MENUPAGE_MAP
{ "FEG_MAP", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
MENUACTION_UNK110, "", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, // to prevent cross/enter to go back
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#endif
#ifdef GRAPHICS_MENU_OPTIONS
// MENUPAGE_GRAPHICS_SETTINGS
{ "FET_GRA", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), GraphicsGoBack,
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
VIDEOMODE_SELECTOR
MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MULTISAMPLING_SELECTOR
#ifdef EXTENDED_COLOURFILTER
POSTFX_SELECTORS
#else
MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
#endif
#ifdef EXTENDED_PIPELINES
PIPELINES_SELECTOR
#endif
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#else
// MENUPAGE_ADVANCED_DISPLAY_SETTINGS
{ "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil,
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
#ifdef EXTENDED_COLOURFILTER
POSTFX_SELECTORS
#endif
#ifdef EXTENDED_PIPELINES
PIPELINES_SELECTOR
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// MENUPAGE_DETECT_JOYSTICK
{ "FEC_JOD", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC,
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil,
MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) },
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
},
#endif
// MENUPAGE_UNK
{ "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
},
};
#endif
#endif

View file

@ -59,6 +59,9 @@ bool CPad::bDisplayNoControllerMessage;
bool CPad::bObsoleteControllerMessage;
bool CPad::bOldDisplayNoControllerMessage;
bool CPad::m_bMapPadOneToPadTwo;
#ifdef INVERT_LOOK_FOR_PAD
bool CPad::bInvertLook4Pad;
#endif
#ifdef GTA_PS2
unsigned char act_direct[6];
unsigned char act_align[6];
@ -934,7 +937,7 @@ void CPad::AddToPCCheatString(char c)
if ( !_CHEATCMP("GNIROOOOOB") )
SlowTimeCheat();
#ifndef GTA3_1_1_PATCH
#if GTA_VERSION < GTA3_PC_11
// "TURTOISE"
if ( !_CHEATCMP("ESIOTRUT") )
ArmourCheat();
@ -1281,7 +1284,7 @@ void CPad::Update(int16 pad)
{
if ( ShakeDur )
{
ShakeDur = Max(ShakeDur - CTimer::GetTimeStepInMilliseconds(), 0);
ShakeDur = Max(ShakeDur - (int32)CTimer::GetTimeStepInMilliseconds(), 0);
if ( ShakeDur == 0 )
{
@ -2534,10 +2537,20 @@ int16 CPad::SniperModeLookLeftRight(void)
int16 CPad::SniperModeLookUpDown(void)
{
int16 axis = NewState.LeftStickY;
int16 dpad;
#ifdef FIX_BUGS
axis = -axis;
#endif
int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
#ifndef INVERT_LOOK_FOR_PAD
dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
#else
if (CPad::bInvertLook4Pad) {
axis = -axis;
dpad = (NewState.DPadDown - NewState.DPadUp) / 2;
} else {
dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
}
#endif
if ( Abs(axis) > Abs(dpad) )
return axis;
@ -2567,6 +2580,10 @@ int16 CPad::LookAroundUpDown(void)
#ifdef FIX_BUGS
axis = -axis;
#endif
#ifdef INVERT_LOOK_FOR_PAD
if (CPad::bInvertLook4Pad)
axis = -axis;
#endif
if ( Abs(axis) > 85 && !GetLookBehindForPed() )
return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) )
@ -2593,7 +2610,7 @@ void CPad::PrintErrorMessage(void)
CFont::SetScale(0.85f, 1.0f);
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
@ -2610,7 +2627,7 @@ void CPad::PrintErrorMessage(void)
CFont::SetScale(0.85f, 1.0f);
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));

View file

@ -170,6 +170,9 @@ public:
static bool bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
static bool m_bMapPadOneToPadTwo;
#ifdef INVERT_LOOK_FOR_PAD
static bool bInvertLook4Pad;
#endif
static CKeyboardState OldKeyState;
static CKeyboardState NewKeyState;

View file

@ -12,6 +12,7 @@
#include "Streaming.h"
#include "Wanted.h"
#include "World.h"
#include "MemoryHeap.h"
CCPtrNodePool *CPools::ms_pPtrNodePool;
CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
@ -23,18 +24,36 @@ CObjectPool *CPools::ms_pObjectPool;
CDummyPool *CPools::ms_pDummyPool;
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
#ifdef GTA_PS2 // or USE_CUSTOM_ALLOCATOR
#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg)
#else
#define CHECKMEM(msg)
#endif
void
CPools::Initialise(void)
{
PUSH_MEMID(MEMID_POOLS);
CHECKMEM("before pools");
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
CHECKMEM("after CPtrNodePool");
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
CHECKMEM("after CEntryInfoNodePool");
ms_pPedPool = new CPedPool(NUMPEDS);
CHECKMEM("after CPedPool");
ms_pVehiclePool = new CVehiclePool(NUMVEHICLES);
CHECKMEM("after CVehiclePool");
ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS);
CHECKMEM("after CBuildingPool");
ms_pTreadablePool = new CTreadablePool(NUMTREADABLES);
CHECKMEM("after CTreadablePool");
ms_pObjectPool = new CObjectPool(NUMOBJECTS);
CHECKMEM("after CObjectPool");
ms_pDummyPool = new CDummyPool(NUMDUMMIES);
CHECKMEM("after CDummyPool");
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
CHECKMEM("after pools");
POP_MEMID();
}
void

View file

@ -33,6 +33,9 @@
#endif
#include "main.h"
#include "Frontend.h"
#include "Font.h"
#include "MemoryMgr.h"
#include "MemoryHeap.h"
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@ -289,6 +292,11 @@ CStreaming::Shutdown(void)
}
}
#ifndef MASTER
uint64 timeProcessingTXD;
uint64 timeProcessingDFF;
#endif
void
CStreaming::Update(void)
{
@ -296,6 +304,11 @@ CStreaming::Update(void)
CStreamingInfo *si, *prev;
bool requestedSubway = false;
#ifndef MASTER
timeProcessingTXD = 0;
timeProcessingDFF = 0;
#endif
UpdateMemoryUsed();
if(ms_channelError != -1){
@ -331,6 +344,14 @@ CStreaming::Update(void)
LoadRequestedModels();
#ifndef MASTER
if (CPad::GetPad(1)->GetLeftShoulder1JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
PrintStreamingBufferState();
// TODO: PrintRequestList
//if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
// PrintRequestList();
#endif
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
@ -390,6 +411,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
assert(sizeof(direntry) == 32);
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
dot = strchr(direntry.name, '.');
assert(dot);
if(dot) *dot = '\0';
if(direntry.size > (uint32)ms_streamingBufferSize)
ms_streamingBufferSize = direntry.size;
@ -436,6 +458,35 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
CFileMgr::CloseFile(fd);
}
#ifdef USE_CUSTOM_ALLOCATOR
RpAtomic*
RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data)
{
#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
// not quite sure what's going on here:
// gta3's RW 3.1 allocates separate memory for geometry data of RpGeometry.
// Is that a R* change? rpDefaultGeometryInstance also depends on it
RpGeometry *geo = RpAtomicGetGeometry(atomic);
if(geo->triangles)
REGISTER_MEMPTR(&geo->triangles);
if(geo->matList.materials)
REGISTER_MEMPTR(&geo->matList.materials);
if(geo->preLitLum)
REGISTER_MEMPTR(&geo->preLitLum);
if(geo->texCoords[0])
REGISTER_MEMPTR(&geo->texCoords[0]);
if(geo->texCoords[1])
REGISTER_MEMPTR(&geo->texCoords[1]);
#else
// normally RpGeometry is allocated in one block (excluding morph targets)
// so we don't really have allocated pointers in the struct.
// NB: in librw we actually do it in two allocations (geometry itself and data)
// so we could conceivably come up with something here
#endif
return atomic;
}
#endif
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
{
@ -469,10 +520,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Set Txd to use
CTxdStore::AddRef(mi->GetTxdSlot());
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
#ifdef USE_CUSTOM_ALLOCATOR
RegisterAtomicMemPtrsCB(((CSimpleModelInfo*)mi)->m_atomics[0], nil);
#endif
} else if (mi->GetModelType() == MITYPE_VEHICLE) {
// load vehicles in two parts
CModelInfo::GetModelInfo(streamId)->AddRef();
@ -481,7 +536,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else{
success = CFileLoader::LoadClumpFile(stream, streamId);
#ifdef USE_CUSTOM_ALLOCATOR
if(success)
RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
#endif
}
POP_MEMID();
UpdateMemoryUsed();
// Txd no longer needed unless we only read part of the file
@ -505,12 +565,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
PUSH_MEMID(MEMID_STREAM_TEXUTRES);
if(ms_bLoadingBigModel || cdsize > 200){
success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
if(success)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else
success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream);
POP_MEMID();
UpdateMemoryUsed();
if(!success){
@ -560,7 +622,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Mark objects as loaded
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
#endif
}
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@ -600,31 +664,42 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
if(streamId < STREAM_OFFSET_TXD){
// Model
mi = CModelInfo::GetModelInfo(streamId);
PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
success = CFileLoader::FinishLoadClumpFile(stream, streamId);
if(success)
if(success){
#ifdef USE_CUSTOM_ALLOCATOR
RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
#endif
success = AddToLoadedVehiclesList(streamId);
}
POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
}else{
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
PUSH_MEMID(MEMID_STREAM_TEXUTRES);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
POP_MEMID();
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
}
RwStreamClose(stream, &mem);
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; // only done if success on PS2
#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
#endif
if(!success){
RemoveModel(streamId);
ReRequestModel(streamId);
UpdateMemoryUsed();
UpdateMemoryUsed(); // directly after pop on PS2
return false;
}
UpdateMemoryUsed();
UpdateMemoryUsed(); // directly after pop on PS2
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
@ -741,7 +816,9 @@ CStreaming::RequestBigBuildings(eLevelName level)
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding
#ifdef NO_ISLAND_LOADING
&& ((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) || (b->m_level == level))
&& (((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODindustEntity) && (b != pIslandLODcomIndEntity) &&
(b != pIslandLODcomSubEntity) && (b != pIslandLODsubIndEntity) && (b != pIslandLODsubComEntity)
) || (b->m_level == level))
#else
&& b->m_level == level
#endif
@ -855,7 +932,11 @@ CStreaming::RemoveModel(int32 id)
CModelInfo::GetModelInfo(id)->DeleteRwObject();
else
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
#ifdef USE_CUSTOM_ALLOCATOR
UpdateMemoryUsed();
#else
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
#endif
}
if(ms_aInfoForModel[id].m_next){
@ -877,6 +958,9 @@ CStreaming::RemoveModel(int32 id)
RpClumpGtaCancelStream();
else
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
#ifdef USE_CUSTOM_ALLOCATOR
UpdateMemoryUsed();
#endif
}
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
@ -2041,19 +2125,25 @@ CStreaming::FlushRequestList(void)
void
CStreaming::ImGonnaUseStreamingMemory(void)
{
// empty
PUSH_MEMID(MEMID_STREAM);
}
void
CStreaming::IHaveUsedStreamingMemory(void)
{
POP_MEMID();
UpdateMemoryUsed();
}
void
CStreaming::UpdateMemoryUsed(void)
{
// empty
#ifdef USE_CUSTOM_ALLOCATOR
ms_memoryUsed =
gMainHeap.GetMemoryUsed(MEMID_STREAM) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES);
#endif
}
#define STREAM_DIST 80.0f
@ -2633,3 +2723,71 @@ CStreaming::UpdateForAnimViewer(void)
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
}
}
void
CStreaming::PrintStreamingBufferState()
{
char str[128];
wchar wstr[128];
uint32 offset, size;
CTimer::Stop();
int i = 0;
while (i < NUMSTREAMINFO) {
while (true) {
int j = 0;
DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255);
CPad::UpdatePads();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight);
CRGBA unusedColor(255, 255, 255, 255);
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
CFont::SetWrapx(DEFAULT_SCREEN_WIDTH);
CFont::SetScale(0.5f, 0.75f);
CFont::SetCentreOff();
CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(200, 200, 200, 200));
CFont::SetBackGroundOnlyTextOff();
int modelIndex = i;
if (modelIndex < NUMSTREAMINFO) {
int y = 24;
for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) {
CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex];
CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex);
if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size))
continue;
if (modelIndex >= STREAM_OFFSET_TXD)
sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD),
CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags);
else
sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size,
streamingInfo->m_flags);
AsciiToUnicode(str, wstr);
CFont::PrintString(24.0f, y, wstr);
y += 12;
j++;
}
}
if (CPad::GetPad(1)->GetCrossJustDown())
i = modelIndex;
if (!CPad::GetPad(1)->GetTriangleJustDown())
break;
i = 0;
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
CTimer::Update();
}

View file

@ -188,4 +188,6 @@ public:
static void MemoryCardLoad(uint8 *buffer, uint32 length);
static void UpdateForAnimViewer(void);
static void PrintStreamingBufferState();
};

View file

@ -53,6 +53,9 @@ bool CWorld::bIncludeCarTyres;
void
CWorld::Initialise()
{
#if GTA_VERSION <= GTA3_PS2_160
CPools::Initialise();
#endif
pIgnoreEntity = nil;
bDoingCarCollisions = false;
bSecondShift = false;
@ -919,24 +922,24 @@ CEntity *
CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
bool ignoreSomeObjects)
{
static CColModel sphereCol;
static CColModel OurColModel;
sphereCol.boundingSphere.center.x = 0.0f;
sphereCol.boundingSphere.center.y = 0.0f;
sphereCol.boundingSphere.center.z = 0.0f;
sphereCol.boundingSphere.radius = radius;
sphereCol.boundingBox.min.x = -radius;
sphereCol.boundingBox.min.y = -radius;
sphereCol.boundingBox.min.z = -radius;
sphereCol.boundingBox.max.x = radius;
sphereCol.boundingBox.max.y = radius;
sphereCol.boundingBox.max.z = radius;
sphereCol.numSpheres = 1;
sphereCol.spheres = &sphereCol.boundingSphere;
sphereCol.numLines = 0;
sphereCol.numBoxes = 0;
sphereCol.numTriangles = 0;
sphereCol.ownsCollisionVolumes = false;
OurColModel.boundingSphere.center.x = 0.0f;
OurColModel.boundingSphere.center.y = 0.0f;
OurColModel.boundingSphere.center.z = 0.0f;
OurColModel.boundingSphere.radius = radius;
OurColModel.boundingBox.min.x = -radius;
OurColModel.boundingBox.min.y = -radius;
OurColModel.boundingBox.min.z = -radius;
OurColModel.boundingBox.max.x = radius;
OurColModel.boundingBox.max.y = radius;
OurColModel.boundingBox.max.z = radius;
OurColModel.numSpheres = 1;
OurColModel.spheres = &OurColModel.boundingSphere;
OurColModel.numLines = 0;
OurColModel.numBoxes = 0;
OurColModel.numTriangles = 0;
OurColModel.ownsCollisionVolumes = false;
CMatrix sphereMat;
sphereMat.SetTranslate(spherePos);
@ -959,7 +962,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
int collidedSpheres =
CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol,
CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol,
gaTempSphereColPoints, nil, nil);
if(collidedSpheres != 0 ||
@ -1735,10 +1738,12 @@ CWorld::ShutDown(void)
CWorld::Remove(pEntity);
delete pEntity;
}
#ifndef FIX_BUGS
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
#endif
}
for(int32 i = 0; i < 4; i++) {
for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) {
@ -1750,6 +1755,12 @@ CWorld::ShutDown(void)
}
for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
#ifdef FIX_BUGS
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
#endif
if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) {
sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
@ -1780,6 +1791,9 @@ CWorld::ShutDown(void)
}
}
ms_listMovingEntityPtrs.Flush();
#if GTA_VERSION <= GTA3_PS2_160
CPools::Shutdown();
#endif
}
void

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,7 @@ public:
float maxz;
int32 m_indexStart;
int16 m_groupIndexCount[3];
int16 m_groupIndexCount[3]; // only useful during resolution stage
int16 m_numBuildings;
int16 m_numTreadablesPlus10m;
int16 m_numTreadables;
@ -26,30 +26,35 @@ public:
static void DoStuffEnteringZone_OneTreadable(uint16 i);
static bool TestLine(CVector a1, CVector a2);
static bool TestLine(CVector vec1, CVector vec2);
static bool DoThoroughLineTest(CVector vec1, CVector vec2, CEntity *testEntity);
float CalcDistToCullZoneSquared(float x, float y);
float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
bool PointFallsWithinZone(CVector pos, float radius);
bool TestEntityVisibilityFromCullZone(CEntity *entity, float extraDist, CEntity *LODentity);
void FindTestPoints();
void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
switch (groupid) {
case 0:
default:
// buildings
start = m_indexStart;
size = m_groupIndexCount[0];
break;
case 1:
// treadables + 10m
start = m_groupIndexCount[0] + m_indexStart;
size = m_groupIndexCount[1];
break;
case 2:
// treadables
start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
size = m_groupIndexCount[2];
break;
default:
start = m_indexStart;
size = m_groupIndexCount[0];
break;
}
}
void FindTestPoints() {}; // todo
bool TestEntityVisibilityFromCullZone(CEntity*, float, CEntity*) { return false; }; // todo
};
enum eZoneAttribs
@ -121,5 +126,12 @@ public:
static void DoVisibilityTestCullZone(int zoneId, bool doIt);
static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
static void CompressIndicesArray() {};// todo
static void CompressIndicesArray();
static bool PickRandomSetForGroup(int32 zone, int32 group, uint16 *set);
static void ReplaceSetForAllGroups(uint16 *set, uint16 setid);
static void TidyUpAndMergeLists(uint16 *extraIndices, int32 numExtraIndices);
// debug
static bool LoadTempFile(void);
static void SaveTempFile(void);
};

View file

@ -1,27 +1,27 @@
#pragma once
enum Config {
NUMPLAYERS = 1,
NUMPLAYERS = 1, // 4 on PS2
NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
MODELINFOSIZE = 5500,
MODELINFOSIZE = 5500, // 3150 on PS2
// TXDSTORESIZE = 850,
TXDSTORESIZE = 1024, // for Xbox map
EXTRADIRSIZE = 128,
CUTSCENEDIRSIZE = 512,
SIMPLEMODELSIZE = 5000,
SIMPLEMODELSIZE = 5000, // 2910 on PS2
MLOMODELSIZE = 1,
MLOINSTANCESIZE = 1,
TIMEMODELSIZE = 30,
CLUMPMODELSIZE = 5,
PEDMODELSIZE = 90,
VEHICLEMODELSIZE = 120,
VEHICLEMODELSIZE = 120, // 70 on PS2
XTRACOMPSMODELSIZE = 2,
TWODFXSIZE = 2000,
TWODFXSIZE = 2000, // 1210 on PS2
MAXVEHICLESLOADED = 50, // 70 on mobile
@ -135,10 +135,6 @@ enum Config {
NUM_EXPLOSIONS = 48,
};
// We'll use this once we're ready to become independent of the game
// Use it to mark bugs in the code that will prevent the game from working then
//#define STANDALONE
// We don't expect to compile for PS2 or Xbox
// but it might be interesting for documentation purposes
#define GTA_PC
@ -156,30 +152,68 @@ enum Config {
// any debug stuff that is only left in mobile, is not in MASTER
//#define MASTER
// once and for all:
// pc: FINAL & MASTER
// mobile: FINAL
// MASTER builds must be FINAL
#ifdef MASTER
#define FINAL
#endif
// Version defines
#define GTA3_PS2_140 300
#define GTA3_PS2_160 301
#define GTA3_PC_10 310
#define GTA3_PC_11 311
#define GTA3_PC_STEAM 312
// TODO? maybe something for xbox or android?
#define GTA_VERSION GTA3_PC_11
// quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages
#define NO_CDCHECK
// those infamous texts
#define DRAW_GAME_VERSION_TEXT
#define DRAW_MENU_VERSION_TEXT
// Memory allocation and compression
// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
# define ANIM_COMPRESSION
#elif defined GTA_PC
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
# define GTA_REPLAY
# define GTA_SCENE_EDIT
#elif defined GTA_XBOX
#endif
#ifdef VU_COLLISION
#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code
#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code
#endif
#ifdef MASTER
// only in master builds
#undef DRAW_GAME_VERSION_TEXT
#else
// not in master builds
#define VALIDATE_SAVE_SIZE
#define NO_MOVIES // disable intro videos
#define DEBUGMENU
#endif
#ifdef FINAL
@ -187,18 +221,19 @@ enum Config {
# define USE_MY_DOCUMENTS // use my documents directory for user files
#else
// not in any game
# define NASTY_GAME // nasty game for all languages
# define NO_MOVIES // disable intro videos
# define NO_CDCHECK
# define CHATTYSPLASH // print what the game is loading
# define DEBUGMENU
# define TIMEBARS // print debug timers
#endif
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
#define FIX_BUGS // fixes bugs that we've came across during reversing
#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define LOAD_INI_SETTINGS
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
// Just debug menu entries
#ifdef DEBUGMENU
#define MISSION_SWITCHER // from debug menu
#endif
// Rendering/display
//#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering
@ -209,17 +244,20 @@ enum Config {
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define PS2_ALPHA_TEST // emulate ps2 alpha test
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
//#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
//#define USE_TEXTURE_POOL
#define CUTSCENE_BORDERS_SWITCH
#ifdef LIBRW
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
#define MULTISAMPLING // adds MSAA option
//#define SCREEN_DROPLETS // neo water droplets
#endif
#ifdef LIBRW
// these are not supported with librw yet
# undef MULTISAMPLING
#ifndef EXTENDED_COLOURFILTER
#undef SCREEN_DROPLETS // we need the backbuffer for this effect
#endif
#ifndef EXTENDED_PIPELINES
#undef SCREEN_DROPLETS // we need neo.txd
#endif
// Particle
@ -239,12 +277,14 @@ enum Config {
#define ALT_DODO_CHEAT
#define REGISTER_START_BUTTON
//#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls
#define BUTTON_ICONS // use textures to show controller buttons
// Hud, frontend and radar
#define PS2_HUD
#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
// #define BETA_SLIDING_TEXT
#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC
// #define XBOX_SUBTITLES // the infamous outlines
#define PC_MENU
#ifndef PC_MENU
@ -258,7 +298,14 @@ enum Config {
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
//# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
# define CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full
# ifdef CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full
# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
# define CUTSCENE_BORDERS_SWITCH
# define MULTISAMPLING // adds MSAA option
# define INVERT_LOOK_FOR_PAD // add bInvertLook4Pad from VC
# endif
#endif
// Script
@ -270,7 +317,7 @@ enum Config {
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT
@ -307,6 +354,8 @@ enum Config {
#endif
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
// IMG
#define BIG_IMG // allows to read larger img files
//#define SQUEEZE_PERFORMANCE
#ifdef SQUEEZE_PERFORMANCE
@ -315,3 +364,7 @@ enum Config {
#define PC_PARTICLE
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
#endif
#ifdef LIBRW
// these are not supported with librw yet
#endif

View file

@ -63,7 +63,11 @@
#include "SceneEdit.h"
#include "debugmenu.h"
#include "Clock.h"
#include "postfx.h"
#include "custompipes.h"
#include "screendroplets.h"
#include "frontendoption.h"
#include "MemoryHeap.h"
GlobalScene Scene;
@ -88,7 +92,11 @@ RwRGBA gColourTop;
bool gameAlreadyInitialised;
float NumberOfChunksLoaded;
#ifdef GTA_PS2
#define TOTALNUMCHUNKS 48.0f
#else
#define TOTALNUMCHUNKS 73.0f
#endif
bool g_SlowMode = false;
char version_name[64];
@ -102,6 +110,18 @@ void TheGame(void);
void DebugMenuPopulate(void);
#endif
#ifndef FINAL
bool gbPrintMemoryUsage;
#endif
#ifdef PS2_MENU
#define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad
#define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad
#else
#define WANT_TO_LOAD FrontEndMenuManager.m_bWantToLoad
#define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad
#endif
void
ValidateVersion()
{
@ -404,9 +424,19 @@ Initialise3D(void *param)
DebugMenuInit();
DebugMenuPopulate();
#endif // !DEBUGMENU
#ifdef CUSTOM_FRONTEND_OPTIONS
// Apparently this func. can be run multiple times at the start.
if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) {
// needs stored language and TheText to be loaded, and last TheText reload is at the start of here
CustomFrontendOptionsPopulate();
}
#endif
bool ret = CGame::InitialiseRenderWare();
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeInit(); // need Scene.world for this
#endif
#ifdef SCREEN_DROPLETS
ScreenDroplets::InitDraw();
#endif
return ret;
}
@ -417,6 +447,9 @@ Initialise3D(void *param)
static void
Terminate3D(void)
{
#ifdef SCREEN_DROPLETS
ScreenDroplets::Shutdown();
#endif
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeShutdown();
#endif
@ -634,18 +667,18 @@ LoadingIslandScreen(const char *levelName)
CFont::SetColor(CRGBA(243, 237, 71, 255));
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
#else
CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
#endif
TextCopy(wstr, name);
TheText.UpperCase(wstr);
CFont::SetColor(CRGBA(243, 237, 71, 255));
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
#ifdef FIX_BUGS
CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr);
#else
CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
CFont::PrintString(SCREEN_WIDTH-20, SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr);
#endif
CFont::DrawFonts();
DoRWStuffEndOfFrame();
@ -768,6 +801,170 @@ tZonePrint ZonePrint[] =
};
#ifndef MASTER
void
PrintMemoryUsage(void)
{
// little hack
if(CPools::GetPtrNodePool() == nil)
return;
// Style taken from LCS, modified for III
// CFont::SetFontStyle(FONT_PAGER);
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
CFont::SetWrapx(640.0f);
// CFont::SetScale(0.5f, 0.75f);
CFont::SetScale(0.4f, 0.75f);
CFont::SetCentreOff();
CFont::SetCentreSize(640.0f);
CFont::SetJustifyOff();
CFont::SetPropOn();
CFont::SetColor(CRGBA(200, 200, 200, 200));
CFont::SetBackGroundOnlyTextOff();
CFont::SetDropShadowPosition(0);
float y;
#ifdef USE_CUSTOM_ALLOCATOR
y = 24.0f;
sprintf(gString, "Total: %d blocks, %d bytes", gMainHeap.m_totalBlocksUsed, gMainHeap.m_totalMemUsed);
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Game: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME), gMainHeap.GetMemoryUsed(MEMID_GAME));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "World: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_WORLD), gMainHeap.GetMemoryUsed(MEMID_WORLD));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Render: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDER), gMainHeap.GetMemoryUsed(MEMID_RENDER));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Render List: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDERLIST), gMainHeap.GetMemoryUsed(MEMID_RENDERLIST));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Default Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_DEF_MODELS), gMainHeap.GetMemoryUsed(MEMID_DEF_MODELS));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_TEXTURES), gMainHeap.GetMemoryUsed(MEMID_TEXTURES));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Streaming: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM), gMainHeap.GetMemoryUsed(MEMID_STREAM));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Streamed Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_MODELS), gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Streamed Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_TEXUTRES), gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_ANIMATION));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Pools: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_POOLS), gMainHeap.GetMemoryUsed(MEMID_POOLS));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_COLLISION), gMainHeap.GetMemoryUsed(MEMID_COLLISION));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Game Process: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME_PROCESS), gMainHeap.GetMemoryUsed(MEMID_GAME_PROCESS));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Script: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_SCRIPT), gMainHeap.GetMemoryUsed(MEMID_SCRIPT));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Cars: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_CARS), gMainHeap.GetMemoryUsed(MEMID_CARS));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Frontend: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_FRONTEND), gMainHeap.GetMemoryUsed(MEMID_FRONTEND));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
#endif
y = 132.0f;
AsciiToUnicode("Pools usage:", gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "PtrNode: %d/%d", CPools::GetPtrNodePool()->GetNoOfUsedSpaces(), CPools::GetPtrNodePool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "EntryInfoNode: %d/%d", CPools::GetEntryInfoNodePool()->GetNoOfUsedSpaces(), CPools::GetEntryInfoNodePool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Ped: %d/%d", CPools::GetPedPool()->GetNoOfUsedSpaces(), CPools::GetPedPool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Vehicle: %d/%d", CPools::GetVehiclePool()->GetNoOfUsedSpaces(), CPools::GetVehiclePool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Building: %d/%d", CPools::GetBuildingPool()->GetNoOfUsedSpaces(), CPools::GetBuildingPool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Treadable: %d/%d", CPools::GetTreadablePool()->GetNoOfUsedSpaces(), CPools::GetTreadablePool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Object: %d/%d", CPools::GetObjectPool()->GetNoOfUsedSpaces(), CPools::GetObjectPool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "Dummy: %d/%d", CPools::GetDummyPool()->GetNoOfUsedSpaces(), CPools::GetDummyPool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
sprintf(gString, "AudioScriptObjects: %d/%d", CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces(), CPools::GetAudioScriptObjectPool()->GetSize());
AsciiToUnicode(gString, gUString);
CFont::PrintString(400.0f, y, gUString);
y += 12.0f;
}
void
DisplayGameDebugText()
{
@ -779,11 +976,15 @@ DisplayGameDebugText()
TWEAKBOOL(bDisplayPosn);
TWEAKBOOL(bDisplayRate);
}
#endif
if(gbPrintMemoryUsage)
PrintMemoryUsage();
#endif
char str[200];
wchar ustr[200];
#ifdef DRAW_GAME_VERSION_TEXT
wchar ver[200];
AsciiToUnicode(version_name, ver);
@ -803,6 +1004,7 @@ DisplayGameDebugText()
#else
CFont::PrintString(10.0f, 10.0f, ver);
#endif
#endif // #ifdef DRAW_GAME_VERSION_TEXT
FrameSamples++;
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
@ -989,9 +1191,11 @@ Render2dStuff(void)
MusicManager.DisplayRadioStationName();
TheConsole.Display();
#ifdef GTA_SCENE_EDIT
if(CSceneEdit::m_bEditOn)
CSceneEdit::Draw();
else
#endif
CHud::Draw();
CUserDisplay::OnscnTimer.ProcessForDisplay();
CMessages::Display();
@ -1010,13 +1214,9 @@ RenderMenus(void)
{
if (FrontEndMenuManager.m_bMenuActive)
{
#ifdef PS2
gMainHeap.PushMemId(_TODOCONST(17));
#endif
PUSH_MEMID(MEMID_FRONTEND);
FrontEndMenuManager.DrawFrontEnd();
#ifdef PS2
gMainHeap.PopMemId();
#endif
POP_MEMID();
}
}
@ -1055,24 +1255,29 @@ Idle(void *arg)
CPad::UpdatePads();
FrontEndMenuManager.Process();
} else {
PUSH_MEMID(MEMID_GAME_PROCESS);
CPointLights::InitPerFrame();
tbStartTimer(0, "CGame::Process");
CGame::Process();
tbEndTimer("CGame::Process");
POP_MEMID();
tbStartTimer(0, "DMAudio.Service");
DMAudio.Service();
tbEndTimer("DMAudio.Service");
}
if (RsGlobal.quit)
return;
#else
PUSH_MEMID(MEMID_GAME_PROCESS);
CPointLights::InitPerFrame();
tbStartTimer(0, "CGame::Process");
CGame::Process();
tbEndTimer("CGame::Process");
POP_MEMID();
tbStartTimer(0, "DMAudio.Service");
DMAudio.Service();
@ -1080,21 +1285,12 @@ Idle(void *arg)
#endif
if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
#ifdef PS2_MENU
TheMemoryCard.m_bWantToLoad = false;
WANT_TO_LOAD = false;
FrontEndMenuManager.m_bWantToRestart = true;
#else
FrontEndMenuManager.m_bWantToRestart = true;
FrontEndMenuManager.m_bWantToLoad = false;
#endif
return;
}
#ifdef PS2_MENU
if ( FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad )
#else
if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
#endif
if(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
{
return;
}
@ -1104,18 +1300,22 @@ Idle(void *arg)
if(arg == nil)
return;
PUSH_MEMID(MEMID_RENDER);
if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
TheCamera.GetScreenFadeStatus() != FADE_2)
{
#if defined(GTA_PC) && defined(FIX_BUGS)
#if defined(GTA_PC) && !defined(RW_GL3) && defined(FIX_BUGS)
// This is from SA, but it's nice for windowed mode
if (!FrontEndMenuManager.m_bRenderGameInMenu) {
// This is from SA, but it's nice for windowed mode
RwV2d pos;
pos.x = SCREEN_WIDTH / 2.0f;
pos.y = SCREEN_HEIGHT / 2.0f;
RsMouseSetPos(&pos);
}
#endif
PUSH_MEMID(MEMID_RENDERLIST);
tbStartTimer(0, "CnstrRenderList");
CRenderer::ConstructRenderList();
tbEndTimer("CnstrRenderList");
@ -1123,6 +1323,7 @@ Idle(void *arg)
tbStartTimer(0, "PreRender");
CRenderer::PreRender();
tbEndTimer("PreRender");
POP_MEMID();
#ifdef FIX_BUGS
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); // TODO: temp? this fixes OpenGL render but there should be a better place for this
@ -1133,12 +1334,12 @@ Idle(void *arg)
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
return;
goto popret;
}else{
if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
255))
return;
goto popret;
}
DefinedState();
@ -1159,10 +1360,17 @@ Idle(void *arg)
RenderDebugShit();
RenderEffects();
tbStartTimer(0, "RenderMotionBlur");
if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) &&
TheCamera.m_ScreenReductionPercentage > 0.0f)
TheCamera.SetMotionBlurAlpha(150);
#ifdef SCREEN_DROPLETS
CPostFX::GetBackBuffer(Scene.camera);
ScreenDroplets::Process();
ScreenDroplets::Render();
#endif
tbStartTimer(0, "RenderMotionBlur");
TheCamera.RenderMotionBlur();
tbEndTimer("RenderMotionBlur");
@ -1178,7 +1386,7 @@ Idle(void *arg)
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
if(!RsCameraBeginUpdate(Scene.camera))
return;
goto popret;
}
#ifdef PS2_SAVE_DIALOG
@ -1191,7 +1399,7 @@ Idle(void *arg)
#ifdef PS2_MENU
if ( TheMemoryCard.m_bWantToLoad )
return;
goto popret;
#endif
tbStartTimer(0, "DoFade");
@ -1210,8 +1418,13 @@ Idle(void *arg)
DoRWStuffEndOfFrame();
POP_MEMID(); // MEMID_RENDER
if(g_SlowMode)
ProcessSlowMode();
return;
popret: POP_MEMID(); // MEMID_RENDER
}
void
@ -1377,14 +1590,13 @@ TheModelViewer(void)
}
#endif
#ifdef PS2
#ifdef GTA_PS2
void TheGame(void)
{
printf("Into TheGame!!!\n");
#ifdef GTA_PS2
gMainHeap.PushMemId(_TODOCONST(1));
#endif
PUSH_MEMID(MEMID_GAME); // NB: not popped
CTimer::Initialise();
@ -1422,77 +1634,49 @@ void TheGame(void)
while (true)
{
#ifdef PS2
if (TheMemoryCard.m_bWantToLoad)
#else
if (FrontEndMenuManager.m_bWantToLoad)
#endif
if (WANT_TO_LOAD)
{
Const char *splash1 = GetLevelSplashScreen(CGame::currLevel);
LoadSplash(splash1);
}
#ifdef PS2
TheMemoryCard.m_bWantToLoad = false;
#else
FrontEndMenuManager.m_bWantToLoad = false;
#endif
WANT_TO_LOAD = false;
CTimer::Update();
#ifdef PS2
while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad))
#else
while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad))
#endif
while (!(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD))
{
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
#ifdef GTA_PS2
gMainHeap.PushMemId(_TODOCONST(12));
#endif
CPointLights::NumLights = 0;
PUSH_MEMID(MEMID_GAME_PROCESS)
CPointLights::InitPerFrame();
CGame::Process();
#ifdef GTA_PS2
gMainHeap.PopMemId();
#endif
POP_MEMID();
DMAudio.Service();
if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing())
{
#ifdef PS2
TheMemoryCard.m_bWantToLoad = false;
#else
FrontEndMenuManager.m_bWantToLoad = false;
#endif
WANT_TO_LOAD = false;
FrontEndMenuManager.m_bWantToRestart = true;
break;
}
#ifdef PS2
if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
#else
if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
#endif
if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
break;
SetLightsWithTimeOfDayColour(Scene.world);
#ifdef GTA_PS2
gMainHeap.PushMemId(_TODOCONST(15));
#endif
PUSH_MEMID(MEMID_RENDER);
if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 )
{
#ifdef GTA_PS2
gMainHeap.PushMemId(_TODOCONST(11));
#endif
PUSH_MEMID(MEMID_RENDERLIST);
CRenderer::ConstructRenderList();
CRenderer::PreRender();
#ifdef GTA_PS2
gMainHeap.PopMemId();
#endif
POP_MEMID();
if (CWeather::LightningFlash && !CCullZones::CamNoRain())
DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255);
@ -1528,15 +1712,9 @@ void TheGame(void)
RenderMenus();
#ifdef PS2
if (TheMemoryCard.m_bWantToLoad)
#else
if (FrontEndMenuManager.m_bWantToLoad)
#endif
if (WANT_TO_LOAD)
{
#ifdef GTA_PS2
gMainHeap.PopMemId();
#endif
POP_MEMID(); // MEMID_RENDER
break;
}
@ -1553,9 +1731,7 @@ void TheGame(void)
CTimer::Update();
#ifdef GTA_PS2
gMainHeap.PopMemId();
#endif
POP_MEMID(): // MEMID_RENDER
if (g_SlowMode)
ProcessSlowMode();
@ -1567,24 +1743,12 @@ void TheGame(void)
CGame::ShutDownForRestart();
CTimer::Stop();
#ifdef PS2
if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
#else
if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
#endif
if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
{
#ifdef PS2
if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
#else
if (b_FoundRecentSavedGameWantToLoad)
#endif
if (FOUND_GAME_TO_LOAD)
{
FrontEndMenuManager.m_bWantToRestart = true;
#ifdef PS2
TheMemoryCard.m_bWantToLoad = true;
#else
FrontEndMenuManager.m_bWantToLoad = true;
#endif
WANT_TO_LOAD = true;
}
CGame::InitialiseWhenRestarting();
@ -1607,7 +1771,7 @@ void SystemInit()
mwInit();
#endif
#ifdef GTA_PS2
#ifdef USE_CUSTOM_ALLOCATOR
InitMemoryMgr();
#endif
@ -1637,7 +1801,7 @@ void SystemInit()
#ifdef GTA_PS2
CFileMgr::InitCd();
Char modulepath[256];
char modulepath[256];
strcpy(modulepath, "cdrom0:\\");
strcat(modulepath, "SYSTEM\\");
@ -1724,7 +1888,7 @@ void SystemInit()
//
#endif
#ifdef PS2
#ifdef GTA_PS2
TheMemoryCard.Init();
#endif
}
@ -1753,7 +1917,7 @@ void GameInit()
#endif
CdStreamInit(MAX_CDCHANNELS);
#ifdef PS2
#ifdef GTA_PS2
Initialise3D(); //no params
#else
//TODO
@ -1860,21 +2024,18 @@ void GameInit()
CreateDebugFont();
#ifdef GTA_PS2
AddIntcHandler(_TODOCONST(2), VBlankCounter, 0);
AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0);
#endif
CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
CSprite2d::SetRecipNearClip();
CTxdStore::Initialise();
#ifdef GTA_PS2
gMainHeap.PushMemId(_TODOCONST(9));
#endif
PUSH_MEMID(MEMID_TEXTURES);
CFont::Initialise();
CHud::Initialise();
#ifdef GTA_PS2
gMainHeap.PopMemId();
#endif
POP_MEMID();
ValidateVersion();
@ -1902,11 +2063,10 @@ main(int argc, char *argv[])
SystemInit();
#ifdef PS2
#ifdef GTA_PS2
int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE);
if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT
&& r != CMemoryCard::ERR_OPENNOENTRY && r != CMemoryCard::ERR_NONE )
if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT )
{
GameInit();
@ -1916,6 +2076,8 @@ main(int argc, char *argv[])
CFont::Initialise();
FrontEndMenuManager.DrawMemoryCardStartUpMenus();
}else if(r == CMemoryCard::ERR_OPENNOENTRY || r == CMemoryCard::ERR_NONE){
// eh?
}
#endif
@ -1926,12 +2088,18 @@ main(int argc, char *argv[])
InitMPEGPlayer();
#ifdef GTA_PAL
PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false);
if (CGame::frenchGame || CGame::germanGame)
PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true);
else
PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true);
#else
PlayMPEG("cdrom0:\\MOVIES\\DMANTSC.PSS;1", false);
PlayMPEG("cdrom0:\\MOVIES\\INTRNTSC.PSS;1", true);
#endif
ShutdownMPEGPlayer();

View file

@ -20,6 +20,10 @@ extern bool gbShowTimebars;
#define gbShowTimebars false
#endif
#ifndef FINAL
extern bool gbPrintMemoryUsage;
#endif
class CSprite2d;
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);

View file

@ -1,7 +1,6 @@
#include <csignal>
#define WITHWINDOWS
#include "common.h"
#include "platform.h"
#include "crossplatform.h"
#include "Renderer.h"
#include "Credits.h"
@ -16,7 +15,6 @@
#include "Boat.h"
#include "Heli.h"
#include "Automobile.h"
#include "Ped.h"
#include "Console.h"
#include "Debug.h"
#include "Hud.h"
@ -26,12 +24,12 @@
#include "Radar.h"
#include "debugmenu.h"
#include "Frontend.h"
#include "Text.h"
#include "WaterLevel.h"
#include "main.h"
#include "MBlur.h"
#include "Script.h"
#include "postfx.h"
#include "custompipes.h"
#include "MemoryHeap.h"
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#include "FileMgr.h"
@ -76,388 +74,61 @@ mysrand(unsigned int seed)
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
#include "Font.h"
void ReloadFrontendOptions(void)
{
CustomFrontendOptionsPopulate();
}
void RestoreDefGraphics(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef PS2_ALPHA_TEST
gPS2alphaTest = false;
#endif
#ifdef MULTISAMPLING
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
CMenuManager::m_PrefsFrameLimiter = true;
CMenuManager::m_PrefsVsyncDisp = true;
CMenuManager::m_PrefsVsync = true;
CMenuManager::m_PrefsUseWideScreen = false;
FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
#ifdef GTA3_1_1_PATCH
if (_dwOperatingSystemVersion == OS_WIN98) {
CMBlur::BlurOn = false;
CMBlur::MotionBlurClose();
} else {
CMBlur::BlurOn = true;
CMBlur::MotionBlurOpen(Scene.camera);
}
#else
CMBlur::BlurOn = true;
#endif
FrontEndMenuManager.SaveSettings();
#endif
}
void RestoreDefDisplay(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef CUTSCENE_BORDERS_SWITCH
CMenuManager::m_PrefsCutsceneBorders = true;
#endif
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
CMenuManager::m_PrefsBrightness = 256;
CMenuManager::m_PrefsLOD = 1.2f;
CRenderer::ms_lodDistScale = 1.2f;
CMenuManager::m_PrefsShowSubtitles = true;
FrontEndMenuManager.SaveSettings();
#endif
}
#ifdef MULTISAMPLING
void MultiSamplingGoBack() {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
void MultiSamplingButtonPress(int8 action) {
if (action == FEOPTION_ACTION_SELECT) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
} else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) {
if (FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1);
int i = 0;
int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels();
while (maxAA != 1) {
i++;
maxAA >>= 1;
}
if (FrontEndMenuManager.m_nDisplayMSAALevel < 0)
FrontEndMenuManager.m_nDisplayMSAALevel = i;
else if (FrontEndMenuManager.m_nDisplayMSAALevel > i)
FrontEndMenuManager.m_nDisplayMSAALevel = 0;
}
} else if (action == FEOPTION_ACTION_FOCUSLOSS) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
FrontEndMenuManager.SetHelperText(3);
}
}
}
wchar* MultiSamplingDraw(bool *disabled, bool userHovering) {
static wchar unicodeTemp[64];
if (userHovering) {
if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) {
if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply
FrontEndMenuManager.ResetHelperText();
} else {
FrontEndMenuManager.SetHelperText(1);
}
} else {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
}
if (!FrontEndMenuManager.m_bGameNotLoaded)
*disabled = true;
switch (FrontEndMenuManager.m_nDisplayMSAALevel) {
case 0:
return TheText.Get("FEM_OFF");
default:
sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel));
AsciiToUnicode(gString, unicodeTemp);
return unicodeTemp;
}
}
const char* multisamplingKey = "MultiSampling";
#endif
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangRusSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangJapSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
#endif
#ifdef IMPROVED_VIDEOMODE
void ScreenModeChange(int8 displayedValue)
{
if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) {
FrontEndMenuManager.m_nPrefsWindowed = displayedValue;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
}
#endif
#ifdef FREE_CAM
void FreeCamChange(int8 displayedValue)
{
TheCamera.bFreeCam = !!displayedValue;
FrontEndMenuManager.SaveSettings();
}
const char* freeCamKey = "FreeCam";
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
void BorderModeChange(int8 displayedValue)
{
CMenuManager::m_PrefsCutsceneBorders = !!displayedValue;
FrontEndMenuManager.SaveSettings();
}
const char* cutsceneBordersKey = "CutsceneBorders";
#endif
#ifdef PS2_ALPHA_TEST
void PS2AlphaTestChange(int8 displayedValue)
{
gPS2alphaTest = !!displayedValue;
FrontEndMenuManager.SaveSettings();
}
const char* ps2alphaKey = "PS2AlphaTest";
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
wchar selectedJoystickUnicode[128];
wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
int numButtons;
int found = -1;
const char *joyname;
if (userHovering) {
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if ((joyname = glfwGetJoystickName(i))) {
const uint8* buttons = glfwGetJoystickButtons(i, &numButtons);
for (int j = 0; j < numButtons; j++) {
if (buttons[j]) {
found = i;
break;
}
}
if (found != -1)
break;
}
}
if (found != -1 && PSGLOBAL(joy1id) != found) {
if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found)
PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
else
PSGLOBAL(joy2id) = -1;
strcpy(gSelectedJoystickName, joyname);
PSGLOBAL(joy1id) = found;
}
}
if (PSGLOBAL(joy1id) == -1)
AsciiToUnicode("Not found", selectedJoystickUnicode);
else
AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
return selectedJoystickUnicode;
}
#endif
// Important: Make sure to read the warnings/informations in frontendoption.h!!
// If you will hardcode any text, please use AllocUnicode! wchar_t size differs between platforms
void
CustomFrontendOptionsPopulate(void)
{
RemoveCustomFrontendOptions(); // if exist
// -- Graphics/display seperation preperation starts - don't add options in here!
#ifdef GRAPHICS_MENU_OPTIONS
int graphicsMenu = FrontendScreenAdd("FET_GRA", MENUSPRITE_MAINMENU, MENUPAGE_OPTIONS, 50, 0, 20,
FONT_HEADING, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, true);
int newDisplayMenu = FrontendScreenAdd("FET_DIS", MENUSPRITE_MAINMENU, MENUPAGE_OPTIONS, 50, 0, 20,
FONT_HEADING, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, true);
FrontendOptionSetCursor(MENUPAGE_OPTIONS, 2, true);
FrontendOptionAddRedirect(TheText.Get("FET_DIS"), newDisplayMenu, 0);
FrontendOptionSetCursor(MENUPAGE_OPTIONS, 3);
FrontendOptionAddRedirect(TheText.Get("FET_GRA"), graphicsMenu, 0);
#define SWITCH_TO_GRAPHICS_MENU FrontendOptionSetCursor(graphicsMenu, -1);
#define SWITCH_TO_DISPLAY_MENU FrontendOptionSetCursor(newDisplayMenu, -1);
#define CLONE_OPTION(a, b, c, d) FrontendOptionAddBuiltinAction(a, b, c, d);
#define ADD_BACK FrontendOptionAddBackButton(TheText.Get("FEDS_TB"));
#define ADD_RESTORE_DEFAULTS(a) FrontendOptionAddDynamic(TheText.Get("FET_DEF"), nil, nil, a, nil);
#else
int advancedDisplayMenu = FrontendScreenAdd("FET_ADV", MENUSPRITE_MAINMENU, MENUPAGE_DISPLAY_SETTINGS, 50, 0, 20,
FONT_HEADING, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, true);
bool movedToAdvMenu = false;
#define SWITCH_TO_GRAPHICS_MENU \
if (GetNumberOfMenuOptions(MENUPAGE_DISPLAY_SETTINGS) >= 12) { \
FrontendOptionSetCursor(advancedDisplayMenu, -1); \
movedToAdvMenu = true; \
} else { \
FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3); \
}
#define SWITCH_TO_DISPLAY_MENU SWITCH_TO_GRAPHICS_MENU
#define CLONE_OPTION(a, b, c, d)
#define ADD_BACK
#define ADD_RESTORE_DEFAULTS(a)
#endif
// -- Graphics/display seperation preperation end
const wchar* off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") };
#ifdef MORE_LANGUAGES
FrontendOptionSetCursor(MENUPAGE_LANGUAGE_SETTINGS, -2);
FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, nil, LangPolSelect, nil);
FrontendOptionAddDynamic(TheText.Get("FEL_RUS"), nil, nil, LangRusSelect, nil);
FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, nil, LangJapSelect, nil);
#endif
#ifdef MENU_MAP
FrontendOptionSetCursor(MENUPAGE_PAUSE_MENU, 2);
FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP);
#endif
// -- Start of graphics menu - add options in display order!
SWITCH_TO_GRAPHICS_MENU
CLONE_OPTION(TheText.Get("FED_RES"), MENUACTION_SCREENRES, nil, nil);
CLONE_OPTION(TheText.Get("FED_WIS"), MENUACTION_WIDESCREEN, nil, nil)
#ifdef IMPROVED_VIDEOMODE
const wchar* screenModes[] = { TheText.Get("FED_FLS"), TheText.Get("FED_WND") };
// Storing isn't enabled because it's handled in Frontend
FrontendOptionAddSelect(TheText.Get("FEM_SCF"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil);
#endif
CLONE_OPTION(TheText.Get("FEM_VSC"), MENUACTION_FRAMESYNC, nil, nil);
CLONE_OPTION(TheText.Get("FEM_FRM"), MENUACTION_FRAMELIMIT, nil, nil);
#ifdef MULTISAMPLING
SWITCH_TO_GRAPHICS_MENU
FrontendOptionAddDynamic(TheText.Get("FED_AAS"), MultiSamplingDraw, (int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, MultiSamplingButtonPress, MultiSamplingGoBack, multisamplingKey);
#endif
CLONE_OPTION(TheText.Get("FED_TRA"), MENUACTION_TRAILS, nil, nil);
#ifdef PS2_ALPHA_TEST
SWITCH_TO_GRAPHICS_MENU
FrontendOptionAddSelect(TheText.Get("FEM_2PR"), off_on, 2, (int8*)&gPS2alphaTest, false, PS2AlphaTestChange, nil, ps2alphaKey);
#endif
ADD_RESTORE_DEFAULTS(RestoreDefGraphics)
ADD_BACK
// ---- End of Graphics Menu ----
// -- Start of Display menu - add options in display order!
SWITCH_TO_DISPLAY_MENU
CLONE_OPTION(TheText.Get("FED_BRI"), MENUACTION_BRIGHTNESS, nil, nil);
CLONE_OPTION(TheText.Get("FEM_LOD"), MENUACTION_DRAWDIST, nil, nil);
#ifdef CUTSCENE_BORDERS_SWITCH
SWITCH_TO_DISPLAY_MENU
FrontendOptionAddSelect(TheText.Get("FEM_CSB"), off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil, cutsceneBordersKey);
#endif
#ifdef FREE_CAM
SWITCH_TO_DISPLAY_MENU
FrontendOptionAddSelect(TheText.Get("FEC_FRC"), off_on, 2, (int8*)&TheCamera.bFreeCam, false, FreeCamChange, nil, freeCamKey);
#endif
CLONE_OPTION(TheText.Get("FED_SUB"), MENUACTION_SUBTITLES, nil, nil);
// Add link to advanced graphics menu if it's filled.
#ifndef GRAPHICS_MENU_OPTIONS
if (movedToAdvMenu) {
FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3);
FrontendOptionAddRedirect(TheText.Get("FET_ADV"), advancedDisplayMenu, 0);
FrontendOptionSetCursor(advancedDisplayMenu, -1);
FrontendOptionAddBackButton(TheText.Get("FEDS_TB"));
}
#endif
ADD_RESTORE_DEFAULTS(RestoreDefDisplay)
ADD_BACK
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
int detectJoystickMenu = FrontendScreenAdd("FEC_JOD", MENUSPRITE_MAINMENU, MENUPAGE_CONTROLLER_PC, 40, 60, 20,
FONT_BANK, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, false);
FrontendOptionSetCursor(detectJoystickMenu, 0);
FrontendOptionAddBuiltinAction(TheText.Get("FEC_JPR"), MENUACTION_LABEL, nil, nil);
FrontendOptionAddDynamic(TheText.Get("FEC_JDE"), DetectJoystickDraw, nil, nil, nil);
FrontendOptionAddBackButton(TheText.Get("FEDS_TB"));
FrontendOptionSetCursor(MENUPAGE_CONTROLLER_PC, 2);
FrontendOptionAddRedirect(TheText.Get("FEC_JOD"), detectJoystickMenu, 1);
#endif
// Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h
}
#endif
#ifdef LOAD_INI_SETTINGS
#include "ini_parser.hpp"
linb::ini cfg;
int CheckAndReadIniInt(const char *cat, const char *key, int original)
{
std::string strval = cfg.get(cat, key, "");
const char *value = strval.c_str();
if (value && value[0] != '\0')
return atoi(value);
return original;
}
float CheckAndReadIniFloat(const char *cat, const char *key, float original)
{
std::string strval = cfg.get(cat, key, "");
const char *value = strval.c_str();
if (value && value[0] != '\0')
return atof(value);
return original;
}
void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed)
{
char temp[10];
if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
changed = true;
sprintf(temp, "%u", val);
cfg.set(cat, key, temp);
}
}
void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed)
{
char temp[10];
if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
changed = true;
sprintf(temp, "%f", val);
cfg.set(cat, key, temp);
}
}
void LoadINISettings()
{
linb::ini cfg;
cfg.load_file("re3.ini");
char defaultStr[4];
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// Written by assuming the codes below will run after _InputInitialiseJoys().
@ -491,28 +162,38 @@ void LoadINISettings()
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < numCustomFrontendOptions; i++) {
FrontendOption& option = customFrontendOptions[i];
if (option.save) {
// CFO only supports saving uint8 right now
sprintf(defaultStr, "%u", *option.value);
option.lastSavedValue = option.displayedValue = *option.value = atoi(cfg.get("FrontendOptions", option.save, defaultStr).c_str());
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
if (option.m_Action == MENUACTION_NOTHING)
break;
// CFO check
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// CFO only supports saving uint8 right now
*option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value);
if (option.m_Action == MENUACTION_CFO_SELECT) {
option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
}
}
}
}
#endif
#ifdef NO_ISLAND_LOADING
sprintf(defaultStr, "%u", CMenuManager::m_PrefsIslandLoading);
CMenuManager::m_PrefsIslandLoading = atoi(cfg.get("FrontendOptions", "NoIslandLoading", defaultStr).c_str());
CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading;
#ifdef EXTENDED_COLOURFILTER
CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
#endif
#ifdef EXTENDED_PIPELINES
CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess);
CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity);
CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult);
CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
#endif
}
void SaveINISettings()
{
linb::ini cfg;
cfg.load_file("re3.ini");
bool changed = false;
char temp[4];
@ -523,23 +204,29 @@ void SaveINISettings()
}
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < numCustomFrontendOptions; i++) {
FrontendOption &option = customFrontendOptions[i];
if (option.save) {
if (atoi(cfg.get("FrontendOptions", option.save, "xxx").c_str()) != *option.value) { // if .ini doesn't have that key compare with xxx, so we can add it
changed = true;
sprintf(temp, "%u", *option.value);
cfg.set("FrontendOptions", option.save, temp);
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
if (option.m_Action == MENUACTION_NOTHING)
break;
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// Beware: CFO only supports saving uint8 right now
CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed);
}
}
}
#endif
#ifdef NO_ISLAND_LOADING
if (atoi(cfg.get("FrontendOptions", "NoIslandLoading", "xxx").c_str()) != CMenuManager::m_PrefsIslandLoading) {
changed = true;
sprintf(temp, "%u", CMenuManager::m_PrefsIslandLoading);
cfg.set("FrontendOptions", "NoIslandLoading", temp);
}
#ifdef EXTENDED_COLOURFILTER
CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed);
#endif
#ifdef EXTENDED_PIPELINES
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed);
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed);
CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed);
CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed);
CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed);
#endif
if (changed)
@ -688,6 +375,19 @@ ResetCamStatics(void)
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
}
#ifdef MISSION_SWITCHER
int8 nextMissionToSwitch = 0;
static void
SwitchToMission(void)
{
CTheScripts::SwitchToMission(nextMissionToSwitch);
}
#endif
#ifdef USE_CUSTOM_ALLOCATOR
static void ParseHeap(void) { gMainHeap.ParseHeap(); }
#endif
static const char *carnames[] = {
"landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony",
"mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer",
@ -870,8 +570,19 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil);
DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil);
#ifndef FINAL
DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil);
#ifdef USE_CUSTOM_ALLOCATOR
DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap);
#endif
#endif
DebugMenuAddVarBool8("Debug", "Show cullzone debug stuff", &gbShowCullZoneDebugStuff, nil);
DebugMenuAddVarBool8("Debug", "Disable zone cull", &gbDisableZoneCull, nil);
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
#ifdef GTA_SCENE_EDIT
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
#endif
#ifdef MENU_MAP
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif
@ -888,9 +599,6 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil);
#ifdef CUSTOM_FRONTEND_OPTIONS
DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions);
#endif
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
@ -899,6 +607,29 @@ DebugMenuPopulate(void)
#ifdef TIMEBARS
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
#endif
#ifdef MISSION_SWITCHER
DebugMenuEntry *missionEntry;
static const char* missions[] = {
"Intro Movie", "Hospital Info Scene", "Police Station Info Scene",
"RC Diablo Destruction", "RC Mafia Massacre", "RC Rumpo Rampage", "RC Casino Calamity",
"Patriot Playground", "A Ride In The Park", "Gripped!", "Multistorey Mayhem",
"Paramedic", "Firefighter", "Vigilante", "Taxi Driver",
"The Crook", "The Thieves", "The Wife", "Her Lover",
"Give Me Liberty and Luigi's Girls", "Don't Spank My Bitch Up", "Drive Misty For Me", "Pump-Action Pimp", "The Fuzz Ball",
"Mike Lips Last Lunch", "Farewell 'Chunky' Lee Chong", "Van Heist", "Cipriani's Chauffeur", "Dead Skunk In The Trunk", "The Getaway",
"Taking Out The Laundry", "The Pick-Up", "Salvatore's Called A Meeting", "Triads And Tribulations", "Blow Fish", "Chaperone", "Cutting The Grass",
"Bomb Da Base: Act I", "Bomb Da Base: Act II", "Last Requests", "Turismo", "I Scream, You Scream", "Trial By Fire", "Big'N'Veiny", "Sayonara Salvatore",
"Under Surveillance", "Paparazzi Purge", "Payday For Ray", "Two-Faced Tanner", "Kanbu Bust-Out", "Grand Theft Auto", "Deal Steal", "Shima", "Smack Down",
"Silence The Sneak", "Arms Shortage", "Evidence Dash", "Gone Fishing", "Plaster Blaster", "Marked Man",
"Liberator", "Waka-Gashira Wipeout!", "A Drop In The Ocean", "Bling-Bling Scramble", "Uzi Rider", "Gangcar Round-Up", "Kingdom Come",
"Grand Theft Aero", "Escort Service", "Decoy", "Love's Disappearance", "Bait", "Espresso-2-Go!", "S.A.M.",
"Uzi Money", "Toyminator", "Rigged To Blow", "Bullion Run", "Rumble", "The Exchange"
};
missionEntry = DebugMenuAddVar("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, 79, missions);
DebugMenuEntrySetWrap(missionEntry, true);
DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission);
#endif
extern bool PrintDebugCode;
extern int16 DebugCamMode;

View file

@ -46,8 +46,8 @@ class CPool
public:
CPool(int size){
// TODO: use new here
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
m_entries = (U*)new uint8[sizeof(U)*size];
m_flags = (Flags*)new uint8[sizeof(Flags)*size];
m_size = size;
m_allocPtr = 0;
for(int i = 0; i < size; i++){
@ -61,8 +61,8 @@ public:
}
void Flush() {
if (m_size > 0) {
free(m_entries);
free(m_flags);
delete[] (uint8*)m_entries;
delete[] (uint8*)m_flags;
m_entries = nil;
m_flags = nil;
m_size = 0;
@ -124,12 +124,18 @@ public:
(T*)&m_entries[handle >> 8] : nil;
}
int GetIndex(T *entry){
int i = GetJustIndex(entry);
int i = GetJustIndex_NoFreeAssert(entry);
return m_flags[i].u + (i<<8);
}
int GetJustIndex(T *entry){
// TODO: the cast is unsafe
return (int)((U*)entry - m_entries);
int index = GetJustIndex_NoFreeAssert(entry);
assert(!IsFreeSlot(index));
return index;
}
int GetJustIndex_NoFreeAssert(T* entry){
int index = ((U*)entry - m_entries);
assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
return index;
}
int GetNoOfUsedSpaces(void) const{
int i;
@ -141,8 +147,8 @@ public:
}
bool IsFreeSlot(int i) { return !!m_flags[i].free; }
void ClearStorage(uint8 *&flags, U *&entries){
free(flags);
free(entries);
delete[] (uint8*)flags;
delete[] (uint8*)entries;
flags = nil;
entries = nil;
}
@ -156,8 +162,8 @@ public:
debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
}
void Store(uint8 *&flags, U *&entries){
flags = (uint8*)malloc(sizeof(uint8)*m_size);
entries = (U*)malloc(sizeof(U)*m_size);
flags = (uint8*)new uint8[sizeof(uint8)*m_size];
entries = (U*)new uint8[sizeof(U)*m_size];
memcpy(flags, m_flags, sizeof(uint8)*m_size);
memcpy(entries, m_entries, sizeof(U)*m_size);
debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */

View file

@ -28,6 +28,7 @@
#include "Bones.h"
#include "Debug.h"
#include "Renderer.h"
#include "MemoryHeap.h"
int gBuildings;
@ -274,7 +275,11 @@ CEntity::CreateRwObject(void)
CBaseModelInfo *mi;
mi = CModelInfo::GetModelInfo(m_modelIndex);
PUSH_MEMID(MEMID_WORLD);
m_rwObject = mi->CreateInstance();
POP_MEMID();
if(m_rwObject){
if(IsBuilding())
gBuildings++;

View file

@ -572,7 +572,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(IsGlass(B->GetModelIndex()))
CGlass::WindowRespondsToSoftCollision(B, impulseA);
if(!A->bInfiniteMass)
A->ApplyMoveForce(colpoint.normal*(1.0f + A->m_fElasticity)*impulseA);
A->ApplyMoveForce(colpoint.GetNormal() * (1.0f + A->m_fElasticity) * impulseA);
return true;
}
}else if(!B->bInfiniteMass)
@ -624,7 +624,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}else{
if(IsGlass(B->GetModelIndex()))
CGlass::WindowRespondsToSoftCollision(B, impulseA);
CVector f = colpoint.normal * impulseA;
CVector f = colpoint.GetNormal() * impulseA;
if(A->IsVehicle() && colpoint.normal.z < 0.7f)
f.z *= 0.3f;
if(!A->bInfiniteMass){
@ -824,7 +824,7 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
normalSpeed = DotProduct(speed, colpoint.normal);
if(normalSpeed < 0.0f){
float minspeed = 1.3f*GRAVITY * CTimer::GetTimeStep();
#ifdef GTA3_1_1_PATCH
#if GTA_VERSION >= GTA3_PC_11
if ((IsObject() || IsVehicle() && (GetUp().z < -0.3f || ((CVehicle*)this)->IsBike() && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED))) &&
#else
if((IsObject() || IsVehicle() && GetUp().z < -0.3f) &&
@ -1146,43 +1146,43 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
mostColliding = 0;
for(j = 1; j < numCollisions; j++)
if(colpoints[j].depth > colpoints[mostColliding].depth)
if (colpoints[j].GetDepth() > colpoints[mostColliding].GetDepth())
mostColliding = j;
if(CWorld::bSecondShift)
for(j = 0; j < numCollisions; j++)
shift += colpoints[j].normal * colpoints[j].depth * 1.5f/numCollisions;
shift += colpoints[j].GetNormal() * colpoints[j].GetDepth() * 1.5f / numCollisions;
else
for(j = 0; j < numCollisions; j++)
shift += colpoints[j].normal * colpoints[j].depth * 1.2f/numCollisions;
shift += colpoints[j].GetNormal() * colpoints[j].GetDepth() * 1.2f / numCollisions;
if(A->IsVehicle() && B->IsVehicle()){
CVector dir = A->GetPosition() - B->GetPosition();
dir.Normalise();
if(dir.z < 0.0f && dir.z < A->GetForward().z && dir.z < A->GetRight().z)
dir.z = Min(0.0f, Min(A->GetForward().z, A->GetRight().z));
shift += dir * colpoints[mostColliding].depth * 0.5f;
shift += dir * colpoints[mostColliding].GetDepth() * 0.5f;
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
CVector dir = colpoints[mostColliding].normal;
CVector dir = colpoints[mostColliding].GetNormal();
float f = Min(Abs(dir.z), 0.9f);
dir.z = 0.0f;
dir.Normalise();
shift += dir * colpoints[mostColliding].depth / (1.0f - f);
shift += dir * colpoints[mostColliding].GetDepth() / (1.0f - f);
boat = B;
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
CVector dir = colpoints[mostColliding].normal * -1.0f;
CVector dir = colpoints[mostColliding].GetNormal() * -1.0f;
float f = Min(Abs(dir.z), 0.9f);
dir.z = 0.0f;
dir.Normalise();
B->GetMatrix().Translate(dir * colpoints[mostColliding].depth / (1.0f - f));
B->GetMatrix().Translate(dir * colpoints[mostColliding].GetDepth() / (1.0f - f));
// BUG? how can that ever happen? A is a Ped
if(B->IsVehicle())
B->ProcessEntityCollision(A, colpoints);
}else{
if(CWorld::bSecondShift)
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.4f;
shift += colpoints[mostColliding].GetNormal() * colpoints[mostColliding].GetDepth() * 0.4f;
else
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.2f;
shift += colpoints[mostColliding].GetNormal() * colpoints[mostColliding].GetDepth() * 0.2f;
}
doShift = true;

Some files were not shown because too many files have changed in this diff Show more