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

This commit is contained in:
GaryOderNichts 2021-08-19 19:09:56 +02:00
commit 9465d49c32
122 changed files with 6942 additions and 4667 deletions

View File

@ -1,13 +0,0 @@
As long as it's not linux/cross-platform skeleton/compatibility layer, all of the code on the repo that's not behind a preprocessor condition(like FIX_BUGS) are **completely** reversed code from original binaries.
We **don't** accept custom codes, as long as it's not wrapped via preprocessor conditions, or it's linux/cross-platform skeleton/compatibility layer.
We accept only these kinds of PRs;
- A new feature that exists in at least one of the GTAs (if it wasn't in III/VC then it doesn't have to be decompilation)
- Game, UI or UX bug fixes (if it's a fix to R* code, it should be behind FIX_BUGS)
- Platform-specific and/or unused code that's not been reversed yet
- Makes reversed code more understandable/accurate, as in "which code would produce this assembly".
- A new cross-platform skeleton/compatibility layer, or improvements to them
- Translation fixes, for languages R* supported/outsourced
- Code that increase maintainability

View File

@ -1,25 +1,50 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${WUT_ROOT}/include",
"../librw"
],
"defines": [
"__WIIU__",
"__WUT__",
"LIBRW",
"AUDIO_OAL",
"BIGENDIAN",
"__FILENAME__=\"a\""
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu18",
"cppStandard": "gnu++14",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
"configurations": [
{
"name": "Mac",
"includePath": ["${default}"],
"defines": [],
"macFrameworkPath": [
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/opt/local/bin/clang",
"compilerArgs": ["-g"],
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"browse": {
"path": [
"/opt/local/include",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include"
]
}
},
{
"name": "Linux",
"includePath": ["${default}"],
"defines": ["XDG_ROOT"],
"compilerPath": "/usr/bin/gcc",
"compilerArgs": ["-ggdb"],
"cStandard": "gnu11",
"cppStandard": "gnu++14"
},
{
"name": "devkitPro aarch64 (Nintendo Switch)",
"compilerPath": "${env:DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++",
"includePath": [
"${default}",
"${env:DEVKITPRO}/portlibs/switch/include",
"${env:DEVKITPRO}/libnx/include"
],
"intelliSenseMode": "gcc-arm64",
"cStandard": "gnu11",
"cppStandard": "gnu++11",
"defines": [
"__SWITCH__",
"LIBRW",
"RW_GL3",
"AUDIO_OAL"
]
}
],
"version": 4
}

101
.vscode/settings.json vendored
View File

@ -1,69 +1,36 @@
{
"files.associations": {
"*.utheme": "ini",
"chrono": "cpp",
"random": "cpp",
"limits": "cpp",
"valarray": "cpp",
"*.tcc": "cpp",
"fstream": "cpp",
"memory_resource": "cpp",
"*.idl": "cpp",
"array": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"utility": "cpp",
"typeinfo": "cpp",
"cmath": "cpp",
"string": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"atomic": "cpp",
"bit": "cpp",
"bitset": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"variant": "cpp"
}
"C_Cpp.default.cStandard": "gnu11",
"C_Cpp.default.cppStandard": "gnu++14",
"C_Cpp.default.includePath": [
"src",
"src/animation",
"src/audio",
"src/audio/eax",
"src/audio/oal",
"src/buildings",
"src/collision",
"src/control",
"src/core",
"src/entities",
"src/extras",
"src/fakerw",
"src/math",
"src/modelinfo",
"src/objects",
"src/peds",
"src/renderer",
"src/rw",
"src/save",
"src/save/glfw",
"src/skel",
"src/text",
"src/vehicles",
"src/weapons",
"vendor/librw"
],
"C_Cpp.vcFormat.indent.gotoLabels": "leftmostColumn",
"C_Cpp.vcFormat.space.pointerReferenceAlignment": "right",
"cSpell.enabled": false,
"files.trimFinalNewlines": false,
"files.trimTrailingWhitespace": false
}

View File

@ -1,15 +1,27 @@
cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.14)
set(EXECUTABLE reVC)
set(PROJECT REVC)
project(${EXECUTABLE} C CXX)
set(${PROJECT}_AUTHOR "${PROJECT} Team")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1 "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
message(STATUS "Building ${CMAKE_PROJECT_NAME} GIT SHA1: ${GIT_SHA1}")
if(NINTENDO_SWITCH)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/nx")
include(NXFunctions)
endif()
if(NOT COMMAND reVC_platform_target)
function(reVC_platform_target)
endfunction()
endif()
if(WIN32)
set(${PROJECT}_AUDIOS "OAL" "MSS")
else()
@ -66,6 +78,8 @@ if(${PROJECT}_INSTALL)
set(os "-apple")
elseif(UNIX)
set(os "-linux")
elseif(NINTENDO_SWITCH)
set(os "-switch")
else()
set(compiler "-UNK")
message(WARNING "Unknown os. Created cpack package will be wrong. (override using cpack -P)")

View File

@ -1,5 +1,5 @@
# reVC-wiiu
<img src="https://github.com/GaryOderNichts/re3-wiiu/blob/miami-wiiu/logo.png?raw=true" alt="reVC logo" width="200">
<img src="https://github.com/GaryOderNichts/re3-wiiu/blob/miami-wiiu/res/images/logo_1024.png?raw=true" alt="reVC logo" width="200">
This is a port of GTA Vice City to the Nintendo Wii U.

27
autoconf/LICENSE.txt Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2016 Blizzard Entertainment and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of Premake nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

305
autoconf/api.lua Normal file
View File

@ -0,0 +1,305 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
-- Enhanced by re3
---
local p = premake
local autoconf = p.modules.autoconf
autoconf.cache = {}
autoconf.parameters = ""
---
-- register autoconfigure api.
---
p.api.register {
name = "autoconfigure",
scope = "config",
kind = "table"
}
---
-- Check for a particular include file.
--
-- @cfg : Current config.
-- @variable : The variable to store the result, such as 'HAVE_STDINT_H'.
-- @filename : The header file to check for.
---
function check_include(cfg, variable, filename)
local res = autoconf.cache_compile(cfg, variable, function ()
p.outln('#include <' .. filename .. '>')
p.outln('int main(void) { return 0; }')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- Check for size of a particular type.
--
-- @cfg : Current config.
-- @variable : The variable to use, such as 'SIZEOF_SIZE_T', this method will also add "'HAVE_' .. variable".
-- @type : The type to check.
-- @headers : An optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_type_size(cfg, variable, type, headers, defines)
check_include(cfg, 'HAVE_SYS_TYPES_H', 'sys/types.h')
check_include(cfg, 'HAVE_STDINT_H', 'stdint.h')
check_include(cfg, 'HAVE_STDDEF_H', 'stddef.h')
local res = autoconf.cache_compile(cfg, variable .. cfg.platform,
function ()
if cfg.autoconf['HAVE_SYS_TYPES_H'] then
p.outln('#include <sys/types.h>')
end
if cfg.autoconf['HAVE_STDINT_H'] then
p.outln('#include <stdint.h>')
end
if cfg.autoconf['HAVE_STDDEF_H'] then
p.outln('#include <stddef.h>')
end
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln("")
p.outln("#define SIZE (sizeof(" .. type .. "))")
p.outln("char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',")
p.outln(" ('0' + ((SIZE / 10000)%10)),")
p.outln(" ('0' + ((SIZE / 1000)%10)),")
p.outln(" ('0' + ((SIZE / 100)%10)),")
p.outln(" ('0' + ((SIZE / 10)%10)),")
p.outln(" ('0' + (SIZE %10)),")
p.outln(" ']', '\\0'};")
p.outln("")
p.outln("int main(int argc, char *argv[]) {")
p.outln(" int require = 0;")
p.outln(" require += info_size[argc];")
p.outln(" (void)argv;")
p.outln(" return require;")
p.outln("}")
end,
function (e)
-- if the compile step succeeded, we should have a binary with 'INFO:size[*****]'
-- somewhere in there.
local content = io.readfile(e.binary)
if content then
local size = string.find(content, 'INFO:size')
if size then
e.size = tonumber(string.sub(content, size+10, size+14))
end
end
end
)
if res.size then
autoconf.set_value(cfg, 'HAVE_' .. variable, 1)
autoconf.set_value(cfg, variable, res.size)
end
end
---
-- Check if the given struct or class has the specified member variable
--
-- @cfg : current config.
-- @variable : variable to store the result.
-- @type : the name of the struct or class you are interested in
-- @member : the member which existence you want to check
-- @headers : an optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_struct_has_member(cfg, variable, type, member, headers, defines)
local res = autoconf.cache_compile(cfg, variable, function ()
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln('int main(void) {')
p.outln(' (void)sizeof(((' .. type .. '*)0)->' .. member ..');')
p.outln(' return 0;')
p.outln('}')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- Check if a symbol exists as a function, variable, or macro
--
-- @cfg : current config.
-- @variable : variable to store the result.
-- @symbol : The symbol to check for.
-- @headers : an optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_symbol_exists(cfg, variable, symbol, headers, defines)
local h = headers
local res = autoconf.cache_compile(cfg, variable, function ()
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln('int main(int argc, char** argv) {')
p.outln(' (void)argv;')
p.outln('#ifndef ' .. symbol)
p.outln(' return ((int*)(&' .. symbol .. '))[argc];')
p.outln('#else')
p.outln(' (void)argc;')
p.outln(' return 0;')
p.outln('#endif')
p.outln('}')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- try compiling a piece of c/c++
---
function autoconf.try_compile(cfg, cpp)
local ts = autoconf.toolset(cfg)
if ts then
return ts.try_compile(cfg, cpp, autoconf.parameters)
else
p.warnOnce('autoconf', 'no toolset found, autoconf always failing.')
end
end
function autoconf.cache_compile(cfg, entry, func, post)
if not autoconf.cache[entry] then
local cpp = p.capture(func)
local res = autoconf.try_compile(cfg, cpp)
if res then
local e = { binary = res, value = true }
if post then
post(e)
end
autoconf.cache[entry] = e
else
autoconf.cache[entry] = { }
end
end
return autoconf.cache[entry]
end
---
-- get the current configured toolset, or the default.
---
function autoconf.toolset(cfg)
local ts = p.config.toolset(cfg)
if not ts then
local tools = {
-- Actually we always return nil on msc. see msc.lua
['vs2010'] = p.tools.msc,
['vs2012'] = p.tools.msc,
['vs2013'] = p.tools.msc,
['vs2015'] = p.tools.msc,
['vs2017'] = p.tools.msc,
['vs2019'] = p.tools.msc,
['gmake'] = premake.tools.gcc,
['gmake2'] = premake.tools.gcc,
['codelite'] = premake.tools.gcc,
['xcode4'] = premake.tools.clang,
}
ts = tools[_ACTION]
end
return ts
end
---
-- store the value of the variable in the configuration
---
function autoconf.set_value(cfg, variable, value)
cfg.autoconf[variable] = value
end
---
-- write the cfg.autoconf table to the file
---
function autoconf.writefile(cfg, filename)
if cfg.autoconf then
local file = io.open(filename, "w+")
for variable, value in pairs(cfg.autoconf) do
file:write('#define ' .. variable .. ' ' .. tostring(value) .. (_eol or '\n'))
end
file:close()
end
end
---
-- Utility method to add a table of headers.
---
function autoconf.include_headers(headers)
if headers ~= nil then
if type(headers) == "table" then
for _, v in ipairs(headers) do
p.outln('#include <' .. v .. '>')
end
else
p.outln('#include <' .. headers .. '>')
end
end
end
function autoconf.include_defines(defines)
if defines ~= nil then
if type(defines) == "table" then
for _, v in ipairs(defines) do
p.outln('#define ' .. v)
end
else
p.outln('#define ' .. defines)
end
end
end
---
-- attach ourselfs to the running action.
---
p.override(p.action, 'call', function (base, name)
local a = p.action.get(name)
-- store the old callback.
local onBaseProject = a.onProject or a.onproject
-- override it with our own.
a.onProject = function(prj)
-- go through each configuration, and call the setup configuration methods.
for cfg in p.project.eachconfig(prj) do
cfg.autoconf = {}
if cfg.autoconfigure then
verbosef('Running auto config steps for "%s/%s".', prj.name, cfg.name)
for file, func in pairs(cfg.autoconfigure) do
func(cfg)
if not (file ~= "dontWrite") then
os.mkdir(cfg.objdir)
local filename = path.join(cfg.objdir, file)
autoconf.writefile(cfg, filename)
end
end
end
end
-- then call the old onProject.
if onBaseProject then
onBaseProject(prj)
end
end
-- now call the original action.call methods
base(name)
end)

18
autoconf/autoconf.lua Normal file
View File

@ -0,0 +1,18 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
if not premake.modules.autoconf then
p.modules.autoconf = {}
p.modules.autoconf._VERSION = p._VERSION
verbosef('Loading autoconf module...')
include('api.lua')
include('msc.lua')
include('clang.lua')
include('gcc.lua')
end
return p.modules.autoconf

27
autoconf/clang.lua Normal file
View File

@ -0,0 +1,27 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local clang = p.tools.clang
function clang.try_compile(cfg, text, parameters)
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
if parameters == nil then
parameters = ""
end
local outFile = path.join(cfg.objdir, "temp.out")
-- compile that text file.
if os.execute('clang "' .. cppFile .. '" ' .. parameters .. ' -o "' .. outFile ..'" &> /dev/null') then
return outFile
else
return nil
end
end

27
autoconf/gcc.lua Normal file
View File

@ -0,0 +1,27 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local gcc = p.tools.gcc
function gcc.try_compile(cfg, text, parameters)
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
if parameters == nil then
parameters = ""
end
local outFile = path.join(cfg.objdir, "temp.out")
-- compile that text file.
if os.execute('gcc "' .. cppFile .. '" ' .. parameters .. ' -o "' .. outFile ..'" &> /dev/null') then
return outFile
else
return nil
end
end

62
autoconf/msc.lua Normal file
View File

@ -0,0 +1,62 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local msc = p.tools.msc
-- "parameters" is unused, matter of fact this file is unused - re3
function msc.try_compile(cfg, text, parameters)
return nil
--[[
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
-- write out a batch file.
local batch = p.capture(function ()
p.outln('@echo off')
p.outln('SET mypath=%~dp0')
p.outln('pushd %mypath%')
local map = {
vs2010 = 'VS100COMNTOOLS',
vs2012 = 'VS110COMNTOOLS',
vs2013 = 'VS120COMNTOOLS',
vs2015 = 'VS140COMNTOOLS',
vs2017 = 'VS141COMNTOOLS',
vs2019 = 'VS142COMNTOOLS',
}
local a = map[_ACTION]
if a then
a = path.translate(os.getenv(a), '/')
a = path.join(a, '../../VC/vcvarsall.bat')
if cfg.platform == 'x86' then
p.outln('call "' .. a .. '" > NUL')
else
p.outln('call "' .. a .. '" amd64 > NUL')
end
p.outln('cl.exe /nologo temp.cpp > NUL')
else
error('Unsupported Visual Studio version: ' .. _ACTION)
end
end)
local batchFile = path.join(cfg.objdir, "compile.bat")
if not io.writefile(batchFile, batch) then
return nil
end
if os.execute(batchFile) then
return path.join(cfg.objdir, "temp.exe")
else
return nil
end
--]]
end

View File

@ -28,7 +28,7 @@ find_package_handle_standard_args(MilesSDK DEFAULT_MSG MilesSDK_LIBRARIES MilesS
if(NOT TARGET MilesSDK::MilesSDK)
add_library(MilesSDK::MilesSDK UNKNOWN IMPORTED)
set_target_properties(MilesSDK::MilesSDK PROPERTIES
IMPORTED_LOCATION "${MilesSDK_LIBRARIES}
IMPORTED_LOCATION "${MilesSDK_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MilesSDK_INCLUDE_DIR}"
)
endif()

View File

@ -18,7 +18,7 @@ find_path(mpg123_INCLUDE_DIR mpg123.h
PATH_SUFFIXES include
)
find_library(mpg123_LIBRARIES NAMES mpg123 mpg123-0
find_library(mpg123_LIBRARIES NAMES mpg123 mpg123-0 libmpg123-0
HINTS ${PKG_MPG123_LIBRARIES}
PATHS "${mpg123_DIR}"
PATH_SUFFIXES lib

View File

@ -0,0 +1,38 @@
if(NOT COMMAND nx_generate_nacp)
message(FATAL_ERROR "The `nx_generate_nacp` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
if(NOT COMMAND nx_create_nro)
message(FATAL_ERROR "The `nx_create_nro` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
function(reVC_platform_target TARGET)
cmake_parse_arguments(RPT "INSTALL" "" "" ${ARGN})
get_target_property(TARGET_TYPE "${TARGET}" TYPE)
if(TARGET_TYPE STREQUAL "EXECUTABLE")
nx_generate_nacp(${TARGET}.nacp
NAME "${TARGET}"
AUTHOR "${${PROJECT}_AUTHOR}"
VERSION "1.0.0-${GIT_SHA1}"
)
nx_create_nro(${TARGET}
NACP ${TARGET}.nacp
ICON "${PROJECT_SOURCE_DIR}/res/images/logo_256.jpg"
)
if(${PROJECT}_INSTALL AND RPT_INSTALL)
get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME)
if(NOT TARGET_OUTPUT_NAME)
set(TARGET_OUTPUT_NAME "${TARGET}")
endif()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_OUTPUT_NAME}.nro"
DESTINATION "."
)
endif()
endif()
endfunction()

View File

@ -1723,6 +1723,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH>
@ -4711,6 +4718,11 @@
<PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH>
@ -8248,6 +8260,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH>
@ -11236,6 +11255,11 @@
<PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH>
@ -13780,6 +13804,12 @@
<PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -42,6 +42,8 @@ newoption {
description = "Don't print full paths into binary"
}
require("autoconf")
if(_OPTIONS["with-librw"]) then
Librw = "vendor/librw"
else
@ -365,6 +367,19 @@ project "reVC"
filter "platforms:win*glfw*"
staticruntime "off"
filter "platforms:*glfw*"
premake.modules.autoconf.parameters = "-lglfw -lX11"
autoconfigure {
-- iterates all configs and runs on them
["dontWrite"] = function (cfg)
check_symbol_exists(cfg, "haveX11", "glfwGetX11Display", { "X11/Xlib.h", "X11/XKBlib.h", "GLFW/glfw3.h", "GLFW/glfw3native.h" }, "GLFW_EXPOSE_NATIVE_X11")
if cfg.autoconf["haveX11"] then
table.insert(cfg.links, "X11")
table.insert(cfg.defines, "GET_KEYBOARD_INPUT_FROM_X11")
end
end
}
filter "platforms:win*oal"
includedirs { "vendor/openal-soft/include" }
includedirs { "vendor/libsndfile/include" }
@ -381,10 +396,10 @@ project "reVC"
libdirs { "vendor/openal-soft/libs/Win64" }
filter "platforms:linux*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:bsd*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:macosx*oal"
links { "openal", "mpg123", "sndfile", "pthread" }

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

BIN
res/images/logo_256.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -54,9 +54,13 @@ target_compile_definitions(${EXECUTABLE} PRIVATE USE_OUR_VERSIONING)
if(${PROJECT}_AUDIO STREQUAL "OAL")
find_package(OpenAL REQUIRED)
target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
if(TARGET OpenAL::OpenAL)
target_link_libraries(${EXECUTABLE} PRIVATE OpenAL::OpenAL)
else()
target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
endif()
target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL)
elseif(${PROJECT}_AUDIO STREQUAL "MSS")
find_package(MilesSDK REQUIRED)
@ -120,13 +124,35 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
)
endif()
if(NINTENDO_SWITCH)
set(${PROJECT}_C_CXX_EXTENSIONS ON)
else()
set(${PROJECT}_C_CXX_EXTENSIONS OFF)
endif()
if(LIBRW_PLATFORM_GL3 AND LIBRW_GL3_GFXLIB STREQUAL "GLFW")
include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES glfw)
set(CMAKE_REQUIRED_DEFINITIONS -DGLFW_EXPOSE_NATIVE_X11)
check_symbol_exists(glfwGetX11Display "GLFW/glfw3.h;GLFW/glfw3native.h" GLFW_HAS_X11)
unset(CMAKE_REQUIRED_DEFINITIONS)
unset(CMAKE_REQUIRED_LIBRARIES)
if (GLFW_HAS_X11)
find_package(X11 REQUIRED)
target_link_libraries(${EXECUTABLE} PRIVATE X11::X11)
target_compile_definitions(${EXECUTABLE} PRIVATE GET_KEYBOARD_INPUT_FROM_X11)
endif (GLFW_HAS_X11)
endif()
set_target_properties(${EXECUTABLE}
PROPERTIES
C_STANDARD 11
C_EXTENSIONS OFF
C_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
C_STANDARD_REQUIRED ON
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
CXX_STANDARD_REQUIRED ON
)
@ -140,3 +166,5 @@ if(${PROJECT}_INSTALL)
install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL)
endif()
endif()
reVC_platform_target(${EXECUTABLE} INSTALL)

View File

@ -10,20 +10,39 @@
const int CollisionSoundIntensity = 60;
cAudioCollisionManager::cAudioCollisionManager()
void
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
float velocity)
{
m_sQueue.m_pEntity1 = nil;
m_sQueue.m_pEntity2 = nil;
m_sQueue.m_bSurface1 = SURFACE_DEFAULT;
m_sQueue.m_bSurface2 = SURFACE_DEFAULT;
m_sQueue.m_fIntensity2 = 0.0f;
m_sQueue.m_fIntensity1 = 0.0f;
m_sQueue.m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
float distSquared;
CVector v1;
CVector v2;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
(velocity < 0.0016f && collisionPower < 0.01f))
return;
m_bCollisionsInQueue = 0;
if(entity1->IsBuilding()) {
v1 = v2 = entity2->GetPosition();
} else if(entity2->IsBuilding()) {
v1 = v2 = entity1->GetPosition();
} else {
v1 = entity1->GetPosition();
v2 = entity2->GetPosition();
}
CVector pos = (v1 + v2) * 0.5f;
distSquared = GetDistanceSquared(pos);
if(distSquared < SQR(CollisionSoundIntensity)) {
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
m_sCollisionManager.AddCollisionToRequestedQueue();
}
}
void
@ -55,135 +74,71 @@ cAudioCollisionManager::AddCollisionToRequestedQueue()
m_bIndicesTable[i] = collisionsIndex;
}
float
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const
{
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
}
float
cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
{
float result;
switch(a) {
case SURFACE_DEFAULT:
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_CONCRETE_BEACH: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
case SURFACE_GRASS:
case SURFACE_GRAVEL:
case SURFACE_MUD_DRY:
case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
case SURFACE_GLASS:
case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
case SURFACE_SCAFFOLD_POLE:
case SURFACE_METAL_GATE:
case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
case SURFACE_SAND:
case SURFACE_WATER:
case SURFACE_RUBBER:
case SURFACE_WHEELBASE:
case SURFACE_SAND_BEACH: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
case SURFACE_NEWS_VENDOR: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
default: result = 0.f; break;
}
return result;
}
float
cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const
{
float e;
e = a;
if(a <= b) return 0.0f;
if(c <= a) e = c;
return (e - b) / d;
}
uint32
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
{
uint8 surface1 = audioCollision.m_bSurface1;
uint8 surface2 = audioCollision.m_bSurface2;
int32 vol;
float ratio;
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
surface2 == SURFACE_HEDGE) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
} else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || surface2 == SURFACE_MUD_DRY ||
surface1 == SURFACE_SAND || surface2 == SURFACE_SAND || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
return 0;
} else {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
vol = 40.f * ratio;
}
if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
return vol;
}
void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
cAudioManager::ServiceCollisions()
{
bool8 distCalculated = FALSE;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
CalculateDistance(distCalculated, m_sQueueSample.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = emittingVol;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
int i, j;
bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
for(i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
for(j = 0; j < NUMAUDIOCOLLISIONS; j++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
) {
abRepeatedCollision1[index] = TRUE;
abRepeatedCollision2[j] = TRUE;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
break;
}
}
}
for(i = 0; i < NUMAUDIOCOLLISIONS; i++) {
if(!abRepeatedCollision2[i]) {
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
}
}
for(i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if(!abRepeatedCollision1[index]) {
for(j = 0; j < NUMAUDIOCOLLISIONS; j++) {
if(!abRepeatedCollision2[j]) {
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
break;
}
}
SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
}
}
for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_sCollisionManager.m_bCollisionsInQueue = 0;
}
static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_COL_TARMAC_1,
SFX_COL_GRASS_1,
@ -223,9 +178,8 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
{
int16 s1;
int16 s2;
uint16 s1;
uint16 s2;
int32 emittingVol;
float ratio;
@ -251,7 +205,7 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
m_sQueueSample.m_nVolume =
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
switch(m_sQueueSample.m_nSampleIndex) {
case SFX_COL_TARMAC_1:
@ -311,13 +265,13 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 11;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nEmittingVolume = emittingVol;
SET_EMITTING_VOLUME(emittingVol);
RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_SoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
SET_SOUND_REVERB(TRUE);
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
}
@ -325,100 +279,129 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
}
void
cAudioManager::ServiceCollisions()
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
int i, j;
bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
) {
abRepeatedCollision1[index] = TRUE;
abRepeatedCollision2[j] = TRUE;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
break;
bool8 distCalculated = FALSE;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
CalculateDistance(distCalculated, m_sQueueSample.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nLoopCount = 0;
SET_EMITTING_VOLUME(emittingVol);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_SoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
SET_SOUND_REVERB(TRUE);
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
}
}
for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
if (!abRepeatedCollision2[i]) {
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
}
}
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if (!abRepeatedCollision1[index]) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
if (!abRepeatedCollision2[j]) {
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
break;
}
}
SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
}
}
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_sCollisionManager.m_bCollisionsInQueue = 0;
}
void
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
float velocity)
uint32
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
{
float distSquared;
CVector v1;
CVector v2;
uint8 surface1 = audioCollision.m_bSurface1;
uint8 surface2 = audioCollision.m_bSurface2;
int32 vol;
float ratio;
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
(velocity < 0.0016f && collisionPower < 0.01f))
return;
if(entity1->IsBuilding()) {
v1 = v2 = entity2->GetPosition();
} else if(entity2->IsBuilding()) {
v1 = v2 = entity1->GetPosition();
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
surface2 == SURFACE_HEDGE) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
} else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || surface2 == SURFACE_MUD_DRY ||
surface1 == SURFACE_SAND || surface2 == SURFACE_SAND || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
return 0;
} else {
v1 = entity1->GetPosition();
v2 = entity2->GetPosition();
}
CVector pos = (v1 + v2) * 0.5f;
distSquared = GetDistanceSquared(pos);
if(distSquared < SQR(CollisionSoundIntensity)) {
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
m_sCollisionManager.AddCollisionToRequestedQueue();
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
vol = 40.f * ratio;
}
if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
return vol;
}
float
cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
{
switch(a) {
case SURFACE_DEFAULT:
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_CONCRETE_BEACH: return GetCollisionRatio(b, 10.f, 60.f, 50.f);
case SURFACE_GRASS:
case SURFACE_GRAVEL:
case SURFACE_MUD_DRY:
case SURFACE_CARDBOARDBOX: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
case SURFACE_CAR: return GetCollisionRatio(b, 6.f, 50.f, 44.f);
case SURFACE_GLASS:
case SURFACE_METAL_CHAIN_FENCE: return GetCollisionRatio(b, 0.1f, 10.f, 9.9f);
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_THICK_METAL_PLATE: return GetCollisionRatio(b, 30.f, 130.f, 100.f);
case SURFACE_GARAGE_DOOR: return GetCollisionRatio(b, 20.f, 100.f, 80.f);
case SURFACE_CAR_PANEL: return GetCollisionRatio(b, 0.f, 4.f, 4.f);
case SURFACE_SCAFFOLD_POLE:
case SURFACE_METAL_GATE:
case SURFACE_LAMP_POST: return GetCollisionRatio(b, 1.f, 10.f, 9.f);
case SURFACE_FIRE_HYDRANT: return GetCollisionRatio(b, 1.f, 15.f, 14.f);
case SURFACE_GIRDER: return GetCollisionRatio(b, 8.f, 50.f, 42.f);
case SURFACE_PED: return GetCollisionRatio(b, 0.f, 20.f, 20.f);
case SURFACE_SAND:
case SURFACE_WATER:
case SURFACE_RUBBER:
case SURFACE_WHEELBASE:
case SURFACE_SAND_BEACH: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
case SURFACE_WOOD_CRATES: return GetCollisionRatio(b, 1.f, 4.f, 3.f);
case SURFACE_WOOD_BENCH: return GetCollisionRatio(b, 0.1f, 5.f, 4.9f);
case SURFACE_WOOD_SOLID: return GetCollisionRatio(b, 0.1f, 40.f, 39.9f);
case SURFACE_PLASTIC: return GetCollisionRatio(b, 0.1f, 4.f, 3.9f);
case SURFACE_HEDGE: return GetCollisionRatio(b, 0.f, 0.5f, 0.5f);
case SURFACE_CONTAINER: return GetCollisionRatio(b, 4.f, 40.f, 36.f);
case SURFACE_NEWS_VENDOR: return GetCollisionRatio(b, 0.f, 5.f, 5.f);
default: break;
}
return 0.f;
}
float
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c)
{
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
}
float
cAudioManager::GetCollisionRatio(float a, float b, float c, float d)
{
float e;
e = a;
if(a <= b) return 0.0f;
if(c <= a) e = c;
return (e - b) / d;
}

View File

@ -17,7 +17,18 @@ public:
float m_fDistance;
int32 m_nBaseVolume;
// no methods
cAudioCollision() { Reset(); }
void Reset()
{
m_pEntity1 = nil;
m_pEntity2 = nil;
m_bSurface1 = 0;
m_bSurface2 = 0;
m_fIntensity1 = m_fIntensity2 = 0.0f;
m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_fDistance = 0.0f;
}
};
VALIDATE_SIZE(cAudioCollision, 40);
@ -31,7 +42,15 @@ public:
uint8 m_bCollisionsInQueue;
cAudioCollision m_sQueue;
cAudioCollisionManager();
cAudioCollisionManager()
{
m_sQueue.Reset();
for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_bCollisionsInQueue = 0;
}
void AddCollisionToRequestedQueue();
};

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,10 @@ cAudioManager::cAudioManager()
ClearRequestedQueue();
ClearActiveSamples();
GenerateIntegerRandomNumberTable();
field_4 = 0;
m_bDoubleVolume = FALSE;
#ifdef AUDIO_REFLECTIONS
m_bDynamicAcousticModelingStatus = TRUE;
#endif
for (int i = 0; i < NUM_AUDIOENTITIES; i++) {
m_asAudioEntities[i].m_bIsUsed = FALSE;
@ -58,11 +60,16 @@ cAudioManager::Initialise()
PreInitialiseGameSpecificSetup();
m_bIsInitialised = SampleManager.Initialise();
if (m_bIsInitialised) {
#ifdef EXTERNAL_3D_SOUND
m_nActiveSamples = SampleManager.GetMaximumSupportedChannels();
if (m_nActiveSamples <= 1) {
Terminate();
} else {
--m_nActiveSamples;
#else
{
m_nActiveSamples = NUM_CHANNELS_GENERIC;
#endif
PostInitialiseGameSpecificSetup();
InitialisePoliceRadioZones();
InitialisePoliceRadio();
@ -111,7 +118,9 @@ cAudioManager::Service()
if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause;
m_nUserPause = CTimer::GetIsUserPaused();
#ifdef AUDIO_REFLECTIONS
UpdateReflections();
#endif
ServiceSoundEffects();
MusicManager.Service();
}
@ -160,6 +169,14 @@ cAudioManager::DestroyEntity(int32 id)
}
}
bool8
cAudioManager::GetEntityStatus(int32 id)
{
if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed)
return m_asAudioEntities[id].m_bStatus;
return FALSE;
}
void
cAudioManager::SetEntityStatus(int32 id, bool8 status)
{
@ -167,6 +184,14 @@ cAudioManager::SetEntityStatus(int32 id, bool8 status)
m_asAudioEntities[id].m_bStatus = status;
}
void *
cAudioManager::GetEntityPointer(int32 id)
{
if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed)
return m_asAudioEntities[id].m_pEntity;
return NULL;
}
void
cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
{
@ -218,39 +243,39 @@ cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
}
void
cAudioManager::SetMP3BoostVolume(uint8 volume) const
{
SampleManager.SetMP3BoostVolume(volume);
}
void
cAudioManager::SetEffectsMasterVolume(uint8 volume) const
cAudioManager::SetEffectsMasterVolume(uint8 volume)
{
SampleManager.SetEffectsMasterVolume(volume);
}
void
cAudioManager::SetMusicMasterVolume(uint8 volume) const
cAudioManager::SetMusicMasterVolume(uint8 volume)
{
SampleManager.SetMusicMasterVolume(volume);
}
void
cAudioManager::SetEffectsFadeVol(uint8 volume) const
cAudioManager::SetMP3BoostVolume(uint8 volume)
{
SampleManager.SetMP3BoostVolume(volume);
}
void
cAudioManager::SetEffectsFadeVol(uint8 volume)
{
SampleManager.SetEffectsFadeVolume(volume);
}
void
cAudioManager::SetMonoMode(bool8 mono)
cAudioManager::SetMusicFadeVol(uint8 volume)
{
SampleManager.SetMonoMode(mono);
SampleManager.SetMusicFadeVolume(volume);
}
void
cAudioManager::SetMusicFadeVol(uint8 volume) const
cAudioManager::SetOutputMode(bool8 surround)
{
SampleManager.SetMusicFadeVolume(volume);
// on ps2 this calls another method of cAudioManager to set DTS mode on or off
}
void
@ -317,17 +342,24 @@ cAudioManager::DestroyAllGameCreatedEntities()
}
}
#ifdef GTA_PC
uint8
cAudioManager::GetNum3DProvidersAvailable() const
cAudioManager::GetNum3DProvidersAvailable()
{
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised)
return SampleManager.GetNum3DProvidersAvailable();
#endif
return 0;
}
char *
cAudioManager::Get3DProviderName(uint8 id) const
cAudioManager::Get3DProviderName(uint8 id)
{
#ifndef EXTERNAL_3D_SOUND
return nil;
#else
if (!m_bIsInitialised)
return nil;
#ifdef AUDIO_OAL
@ -338,22 +370,27 @@ cAudioManager::Get3DProviderName(uint8 id) const
return nil;
#endif
return SampleManager.Get3DProviderName(id);
#endif
}
int8
cAudioManager::GetCurrent3DProviderIndex() const
cAudioManager::GetCurrent3DProviderIndex()
{
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised)
return SampleManager.GetCurrent3DProviderIndex();
#endif
return -1;
}
int8
cAudioManager::AutoDetect3DProviders() const
cAudioManager::AutoDetect3DProviders()
{
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised)
return SampleManager.AutoDetect3DProviders();
#endif
return -1;
}
@ -361,6 +398,9 @@ cAudioManager::AutoDetect3DProviders() const
int8
cAudioManager::SetCurrent3DProvider(uint8 which)
{
#ifndef EXTERNAL_3D_SOUND
return -1;
#else
if (!m_bIsInitialised)
return -1;
for (uint8 i = 0; i < m_nActiveSamples + 1; ++i)
@ -379,16 +419,19 @@ cAudioManager::SetCurrent3DProvider(uint8 which)
--m_nActiveSamples;
}
return current;
#endif
}
void
cAudioManager::SetSpeakerConfig(int32 conf) const
cAudioManager::SetSpeakerConfig(int32 conf)
{
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetSpeakerConfig(conf);
#endif
}
bool8
cAudioManager::IsMP3RadioChannelAvailable() const
cAudioManager::IsMP3RadioChannelAvailable()
{
if (m_bIsInitialised)
return SampleManager.IsMP3RadioChannelAvailable();
@ -397,7 +440,7 @@ cAudioManager::IsMP3RadioChannelAvailable() const
}
void
cAudioManager::ReleaseDigitalHandle() const
cAudioManager::ReleaseDigitalHandle()
{
if (m_bIsInitialised) {
SampleManager.ReleaseDigitalHandle();
@ -405,38 +448,43 @@ cAudioManager::ReleaseDigitalHandle() const
}
void
cAudioManager::ReacquireDigitalHandle() const
cAudioManager::ReacquireDigitalHandle()
{
if (m_bIsInitialised) {
SampleManager.ReacquireDigitalHandle();
}
}
#ifdef AUDIO_REFLECTIONS
void
cAudioManager::SetDynamicAcousticModelingStatus(bool8 status)
{
m_bDynamicAcousticModelingStatus = status;
}
#endif
bool8
cAudioManager::CheckForAnAudioFileOnCD() const
cAudioManager::CheckForAnAudioFileOnCD()
{
return SampleManager.CheckForAnAudioFileOnCD();
}
char
cAudioManager::GetCDAudioDriveLetter() const
cAudioManager::GetCDAudioDriveLetter()
{
if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter();
if (m_bIsInitialised)
return SampleManager.GetCDAudioDriveLetter();
return '\0';
}
bool8
cAudioManager::IsAudioInitialised() const
cAudioManager::IsAudioInitialised()
{
return m_bIsInitialised;
}
#endif // GTA_PC
void
cAudioManager::ServiceSoundEffects()
{
@ -461,7 +509,9 @@ cAudioManager::ServiceSoundEffects()
ClearActiveSamples();
}
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
#ifdef AUDIO_REVERB
if(m_bReverb) ProcessReverb();
#endif
ProcessSpecial();
ClearRequestedQueue();
InterrogateAudioEntities();
@ -470,7 +520,7 @@ cAudioManager::ServiceSoundEffects()
ServiceCollisions();
AddReleasingSounds();
ProcessMissionAudio();
#ifdef GTA_PC
#ifdef EXTERNAL_3D_SOUND
AdjustSamplesVolume();
#endif
ProcessActiveQueues();
@ -487,7 +537,7 @@ cAudioManager::ServiceSoundEffects()
}
uint8
cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const
cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance)
{
float newSoundIntensity;
float newEmittingVolume;
@ -501,29 +551,42 @@ cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float d
newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity))
/ (soundIntensity - newSoundIntensity));
return Min(127u, newEmittingVolume);
return Min(127, newEmittingVolume);
}
void
cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const
cAudioManager::TranslateEntity(Const CVector *in, CVector *out)
{
*out = MultiplyInverse(TheCamera.GetMatrix(), *in);
}
Const static uint8 PanTable[64] = { 0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53,
54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
int32
cAudioManager::ComputeFrontRearMix(float dist, CVector *vec)
{
int32 index = vec->y / (dist / 64.f);
index = Min(63, ABS(index));
if (vec->y > 0.f)
return Max(0, 63 - (int8)PanTable[index]);
return Min(127, PanTable[index] + 63);
}
int32
cAudioManager::ComputePan(float dist, CVector *vec)
{
const uint8 PanTable[64] = { 0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53,
54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
int32 index = Min(63, Abs(int32(vec->x / (dist / 64.f))));
int32 index = vec->x / (dist / 64.f);
index = Min(63, ABS(index));
if (vec->x > 0.f)
return Max(20, 63 - PanTable[index]);
return Max(20, 63 - (int8)PanTable[index]);
return Min(107, PanTable[index] + 63);
}
uint32
cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const
cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier)
{
uint32 newFreq = oldFreq;
if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) {
@ -540,7 +603,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
}
int32
cAudioManager::RandomDisplacement(uint32 seed) const
cAudioManager::RandomDisplacement(uint32 seed)
{
int32 value;
@ -573,9 +636,11 @@ cAudioManager::InterrogateAudioEntities()
void
cAudioManager::AddSampleToRequestedQueue()
{
int32 calculatedVolume;
uint32 calculatedVolume;
uint8 sampleIndex;
#ifdef AUDIO_REFLECTIONS
bool8 bReflections;
#endif
if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (MAX_VOLUME - m_sQueueSample.m_nVolume);
@ -589,11 +654,12 @@ cAudioManager::AddSampleToRequestedQueue()
}
m_sQueueSample.m_nCalculatedVolume = calculatedVolume;
m_sQueueSample.m_bLoopEnded = FALSE;
#ifdef AUDIO_REFLECTIONS
if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) {
m_sQueueSample.m_bRequireReflection = FALSE;
m_sQueueSample.m_nLoopsRemaining = 0;
}
if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) {
if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount > 0) {
bReflections = m_sQueueSample.m_bRequireReflection;
} else {
bReflections = FALSE;
@ -602,23 +668,28 @@ cAudioManager::AddSampleToRequestedQueue()
m_sQueueSample.m_bRequireReflection = FALSE;
if ( m_bReverb && m_sQueueSample.m_bIs2D )
m_sQueueSample.field_4C = 30;
m_sQueueSample.m_nFrontRearOffset = 30;
#ifdef AUDIO_REVERB
if (!m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bReverbFlag = FALSE;
#endif
#endif
m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample;
AddDetailsToRequestedOrderList(sampleIndex);
#ifdef AUDIO_REFLECTIONS
if (bReflections)
AddReflectionsToRequestedQueue();
#endif
}
}
void
cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
{
uint32 i = 0;
if (sample != 0) {
if (sample > 0) {
for (; i < sample; i++) {
if (m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]].m_nCalculatedVolume >
m_asSamples[m_nActiveSampleQueue][sample].m_nCalculatedVolume)
@ -631,6 +702,7 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample;
}
#ifdef AUDIO_REFLECTIONS
void
cAudioManager::AddReflectionsToRequestedQueue()
{
@ -652,33 +724,33 @@ cAudioManager::AddReflectionsToRequestedQueue()
} else {
emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16;
}
m_sQueueSample.m_fSoundIntensity /= 2.f;
m_sQueueSample.m_SoundIntensity /= 2.f;
int halfOldFreq = oldFreq >> 1;
uint32 halfOldFreq = oldFreq >> 1;
for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) {
if ( CTimer::GetIsSlowMotionActive() )
m_afReflectionsDistances[i] = GetRandomNumberInRange(i % 4, 0, 2) * 100.f / 8.f;
m_afReflectionsDistances[i] = (m_anRandomTable[i % 4] % 3) * 100.f / 8.f;
reflectionDistance = m_afReflectionsDistances[i];
if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_fSoundIntensity) {
if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_SoundIntensity) {
m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f);
if (m_sQueueSample.m_nLoopsRemaining > 3) {
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
m_sQueueSample.m_nEmittingVolume = emittingVolume;
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
SET_EMITTING_VOLUME(emittingVolume);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume > emittingVolume / 16) {
m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256;
if (m_sQueueSample.m_nLoopCount) {
if (m_sQueueSample.m_nLoopCount > 0) {
if ( CTimer::GetIsSlowMotionActive() ) {
m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances));
} else {
noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
if (noise <= 0)
m_sQueueSample.m_nFrequency += noise;
else
if (noise > 0)
m_sQueueSample.m_nFrequency -= noise;
else
m_sQueueSample.m_nFrequency += noise;
}
}
m_sQueueSample.m_nReleasingVolumeModificator += 20;
@ -695,43 +767,87 @@ cAudioManager::AddReflectionsToRequestedQueue()
void
cAudioManager::UpdateReflections()
{
CVector camPos = TheCamera.GetPosition();
CVector camPos;
CColPoint colpoint;
CEntity *ent;
#if GTA_VERSION < GTAVC_PC_10
if (m_FrameCounter % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[0] = camPos;
m_avecReflectionsPos[0].y += 50.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[0] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[0] = 50.0f;
} else if ((m_FrameCounter + 1) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[1] = camPos;
m_avecReflectionsPos[1].y -= 50.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[1] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[1] = 50.0f;
} else if ((m_FrameCounter + 2) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[2] = camPos;
m_avecReflectionsPos[2].x -= 50.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[2] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[2] = 50.0f;
} else if ((m_FrameCounter + 3) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[3] = camPos;
m_avecReflectionsPos[3].x += 50.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[3] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[3] = 50.0f;
} else if ((m_FrameCounter + 4) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[4] = camPos;
m_avecReflectionsPos[4].z += 50.0f;
if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil))
m_afReflectionsDistances[4] = colpoint.point.z - camPos.z;
else
m_afReflectionsDistances[4] = 50.0f;
}
#else
if (m_FrameCounter % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[0] = camPos;
m_avecReflectionsPos[0].y += 100.f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[0] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[0] = 100.0f;
} else if ((m_FrameCounter + 1) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[1] = camPos;
m_avecReflectionsPos[1].y -= 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[1] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[1] = 100.0f;
} else if ((m_FrameCounter + 2) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[2] = camPos;
m_avecReflectionsPos[2].x -= 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[2] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[2] = 100.0f;
} else if ((m_FrameCounter + 3) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[3] = camPos;
m_avecReflectionsPos[3].x += 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[3] = Distance(camPos, colpoint.point);
else
m_afReflectionsDistances[3] = 100.0f;
} else if ((m_FrameCounter + 4) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.y += 1.0f;
m_avecReflectionsPos[4] = camPos;
m_avecReflectionsPos[4].z += 100.0f;
@ -739,8 +855,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[4] = colpoint.point.z - camPos.z;
else
m_afReflectionsDistances[4] = 100.0f;
} else if ((m_FrameCounter + 5) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.y -= 1.0f;
m_avecReflectionsPos[5] = camPos;
m_avecReflectionsPos[5].z += 100.0f;
@ -748,8 +864,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[5] = colpoint.point.z - camPos.z;
else
m_afReflectionsDistances[5] = 100.0f;
} else if ((m_FrameCounter + 6) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.x -= 1.0f;
m_avecReflectionsPos[6] = camPos;
m_avecReflectionsPos[6].z += 100.0f;
@ -757,8 +873,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[6] = colpoint.point.z - camPos.z;
else
m_afReflectionsDistances[6] = 100.0f;
} else if ((m_FrameCounter + 7) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.x += 1.0f;
m_avecReflectionsPos[7] = camPos;
m_avecReflectionsPos[7].z += 100.0f;
@ -767,7 +883,9 @@ cAudioManager::UpdateReflections()
else
m_afReflectionsDistances[7] = 100.0f;
}
#endif
}
#endif // AUDIO_REFLECTIONS
void
cAudioManager::AddReleasingSounds()
@ -794,8 +912,11 @@ cAudioManager::AddReleasingSounds()
break;
}
}
if (!toProcess[i]) {
if (sample.m_nCounter <= 255 || !sample.m_nLoopsRemaining) {
if(!toProcess[i]) {
#ifdef AUDIO_REFLECTIONS
if(sample.m_nCounter <= 255 || sample.m_nLoopsRemaining == 0) // check if not reflection
#endif
{
if (sample.m_nReleasingVolumeDivider == 0)
continue;
if (sample.m_nLoopCount == 0) {
@ -829,40 +950,42 @@ cAudioManager::AddReleasingSounds()
void
cAudioManager::ProcessActiveQueues()
{
CVector position;
uint32 freqDivided;
uint32 loopCount;
uint8 emittingVol;
uint8 vol;
uint8 offset;
float x;
bool8 flag;
float position2;
float position1;
uint32 samplesPerFrame;
uint32 samplesToPlay;
#ifdef EXTERNAL_3D_SOUND
float x;
float usedX;
float usedY;
float usedZ;
#endif
uint8 vol;
uint8 emittingVol;
CVector position;
bool8 missionState;
for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
}
for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
tSound &sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (sample.m_nSampleIndex != NO_SAMPLE) {
for (int32 j = 0; j < m_nActiveSamples; j++) {
if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex &&
sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex && sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
if (sample.m_nLoopCount) {
if (m_FrameCounter & 1) {
if (!(j & 1)) {
flag = FALSE;
} else {
flag = TRUE;
}
} else if (j & 1) {
flag = FALSE;
} else {
flag = TRUE;
}
if (m_FrameCounter & 1)
flag = !!(j & 1);
else
flag = !(j & 1);
if (flag && !SampleManager.GetChannelUsedFlag(j)) {
sample.m_bLoopEnded = TRUE;
@ -871,7 +994,7 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue;
}
if (!sample.m_nReleasingVolumeDivider)
if (sample.m_nReleasingVolumeDivider == 0)
sample.m_nReleasingVolumeDivider = 1;
}
sample.m_bIsProcessed = TRUE;
@ -879,36 +1002,39 @@ cAudioManager::ProcessActiveQueues()
sample.m_nVolumeChange = -1;
if (!sample.m_bReleasingSoundFlag) {
if (sample.m_bIs2D) {
if (field_4) {
emittingVol = 2 * Min(63, sample.m_nEmittingVolume);
} else {
emittingVol = sample.m_nEmittingVolume;
}
#ifdef EXTERNAL_3D_SOUND
emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nEmittingVolume) : sample.m_nEmittingVolume;
#else
emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nVolume) : sample.m_nVolume;
#endif
SampleManager.SetChannelFrequency(j, sample.m_nFrequency);
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(j, emittingVol);
#else
SampleManager.SetChannelPan(j, sample.m_nOffset);
SampleManager.SetChannelVolume(j, emittingVol);
#endif
} else {
position2 = sample.m_fDistance;
position1 = m_asActiveSamples[j].m_fDistance;
m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
sample.m_nFrequency = ComputeDopplerEffectedFrequency(
sample.m_nFrequency,
m_asActiveSamples[j].m_fDistance,
sample.m_fDistance,
sample.m_fSpeedMultiplier);
sample.m_nFrequency = ComputeDopplerEffectedFrequency(sample.m_nFrequency, position1, position2, sample.m_fSpeedMultiplier);
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
m_asActiveSamples[j].m_nFrequency = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency);
uint32 freq = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
m_asActiveSamples[j].m_nFrequency = freq;
SampleManager.SetChannelFrequency(j, freq);
}
#ifdef EXTERNAL_3D_SOUND
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
if (field_4) {
emittingVol = 2 * Min(63, vol);
} else {
emittingVol = vol;
}
#else
if (sample.m_nVolume != m_asActiveSamples[j].m_nVolume) {
vol = Clamp2((int8)sample.m_nVolume, (int8)m_asActiveSamples[j].m_nVolume, 10);
#endif
emittingVol = m_bDoubleVolume ? 2 * Min(63, vol) : vol;
missionState = FALSE;
for (int32 k = 0; k < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); k++) {
for (int32 k = 0; k < MISSION_AUDIO_SLOTS; k++) {
if (m_sMissionAudio.m_bIsMobile[k]) {
missionState = TRUE;
break;
@ -921,14 +1047,26 @@ cAudioManager::ProcessActiveQueues()
emittingVol = (emittingVol * field_5538) / 127;
}
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(j, emittingVol);
m_asActiveSamples[j].m_nEmittingVolume = vol;
#else
SampleManager.SetChannelVolume(j, emittingVol);
m_asActiveSamples[j].m_nVolume = vol;
#endif
}
TranslateEntity(&sample.m_vecPos, &position);
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannel3DPosition(j, position.x, position.y, position.z);
SampleManager.SetChannel3DDistances(j, sample.m_fSoundIntensity, 0.25f * sample.m_fSoundIntensity);
SampleManager.SetChannel3DDistances(j, sample.m_SoundIntensity, 0.25f * sample.m_SoundIntensity);
#else
sample.m_nOffset = ComputePan(sample.m_fDistance, &position);
SampleManager.SetChannelPan(j, sample.m_nOffset);
#endif
}
#if !defined(GTA_PS2) || defined(AUDIO_REVERB)
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
#endif
break; //continue for i
}
sample.m_bIsProcessed = FALSE;
@ -946,35 +1084,46 @@ cAudioManager::ProcessActiveQueues()
}
}
for (uint8 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (!sample.m_bIsProcessed && !sample.m_bLoopEnded &&
m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
if (sample.m_nCounter > 255 && sample.m_nLoopCount && sample.m_nLoopsRemaining) {
tSound &sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (!sample.m_bIsProcessed && !sample.m_bLoopEnded && m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
#ifdef AUDIO_REFLECTIONS
if (sample.m_nCounter > 255 && sample.m_nLoopCount > 0 && sample.m_nLoopsRemaining > 0) { // check if reflection
sample.m_nLoopsRemaining--;
sample.m_nReleasingVolumeDivider = 1;
} else {
} else
#endif
{
for (uint8 j = 0; j < m_nActiveSamples; j++) {
uint8 k = (j + field_6) % m_nActiveSamples;
if (!m_asActiveSamples[k].m_bIsProcessed) {
if (sample.m_nLoopCount != 0) {
freqDivided = sample.m_nFrequency / m_nTimeSpent;
loopCount = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
if (freqDivided == 0)
if (sample.m_nLoopCount > 0) {
samplesPerFrame = sample.m_nFrequency / m_nTimeSpent;
samplesToPlay = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
if (samplesPerFrame == 0)
continue;
sample.m_nReleasingVolumeDivider = loopCount / freqDivided + 1;
sample.m_nReleasingVolumeDivider = samplesToPlay / samplesPerFrame + 1;
}
memcpy(&m_asActiveSamples[k], &sample, sizeof(tSound));
if (!m_asActiveSamples[k].m_bIs2D)
if (!m_asActiveSamples[k].m_bIs2D) {
TranslateEntity(&m_asActiveSamples[k].m_vecPos, &position);
if (field_4) {
emittingVol = 2 * Min(63, m_asActiveSamples[k].m_nEmittingVolume);
} else {
emittingVol = m_asActiveSamples[k].m_nEmittingVolume;
#ifndef EXTERNAL_3D_SOUND
m_asActiveSamples[j].m_nOffset = ComputePan(m_asActiveSamples[j].m_fDistance, &position);
#endif
}
#ifdef EXTERNAL_3D_SOUND
emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].m_nEmittingVolume) : m_asActiveSamples[j].m_nEmittingVolume;
#else
emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].m_nVolume) : m_asActiveSamples[j].m_nVolume;
#endif
#ifdef GTA_PS2
{
SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex);
#else
if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) {
#endif
SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency);
bool8 isMobile = FALSE;
for (int32 l = 0; l < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); l++) {
for (int32 l = 0; l < MISSION_AUDIO_SLOTS; l++) {
if (m_sMissionAudio.m_bIsMobile[l]) {
isMobile = TRUE;
break;
@ -987,24 +1136,40 @@ cAudioManager::ProcessActiveQueues()
} else {
vol = (emittingVol * field_5538 / 127);
}
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(k, vol);
#else
SampleManager.SetChannelVolume(j, emittingVol);
SampleManager.SetChannelPan(j, m_asActiveSamples[j].m_nOffset);
#endif
#ifndef GTA_PS2
SampleManager.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd);
SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount);
#endif
#if !defined(GTA_PS2) || defined(AUDIO_REVERB)
SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverbFlag);
#endif
#ifdef EXTERNAL_3D_SOUND
if (m_asActiveSamples[k].m_bIs2D) {
offset = m_asActiveSamples[k].m_nOffset;
if (offset == 63) {
uint8 offset = m_asActiveSamples[k].m_nOffset;
if (offset == 63)
x = 0.0f;
} else if (offset >= 63) {
else if (offset >= 63)
x = (offset - 63) * 1000.0f / 63;
} else {
else
x = -(63 - offset) * 1000.0f / 63; //same like line below
}
position = CVector(x, 0.0f, 0.0f);
m_asActiveSamples[k].m_fSoundIntensity = 100000.0f;
usedX = x;
usedY = 0.0f;
usedZ = 0.0f;
m_asActiveSamples[k].m_SoundIntensity = 100000.0f;
} else {
usedX = position.x;
usedY = position.y;
usedZ = position.z;
}
SampleManager.SetChannel3DPosition(k, position.x, position.y, position.z);
SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_fSoundIntensity, 0.25f * m_asActiveSamples[k].m_fSoundIntensity);
SampleManager.SetChannel3DPosition(k, usedX, usedY, usedZ);
SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_SoundIntensity, 0.25f * m_asActiveSamples[k].m_SoundIntensity);
#endif
SampleManager.StartChannel(k);
}
m_asActiveSamples[k].m_bIsProcessed = TRUE;
@ -1040,7 +1205,9 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nReleasingVolumeModificator = 5;
m_asActiveSamples[i].m_nFrequency = 0;
m_asActiveSamples[i].m_nVolume = 0;
#ifdef EXTERNAL_3D_SOUND
m_asActiveSamples[i].m_nEmittingVolume = 0;
#endif
m_asActiveSamples[i].m_fDistance = 0.0f;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bLoopEnded = FALSE;
@ -1050,19 +1217,30 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nLoopEnd = -1;
#endif
m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f;
m_asActiveSamples[i].m_fSoundIntensity = 200.0f;
m_asActiveSamples[i].m_SoundIntensity = 200.0f;
m_asActiveSamples[i].m_nOffset = 63;
m_asActiveSamples[i].m_bReleasingSoundFlag = FALSE;
m_asActiveSamples[i].m_nCalculatedVolume = 0;
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
m_asActiveSamples[i].m_nVolumeChange = -1;
m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f);
#ifdef AUDIO_REVERB
m_asActiveSamples[i].m_bReverbFlag = FALSE;
#endif // AUDIO_REVERB
#ifdef AUDIO_REFLECTIONS
m_asActiveSamples[i].m_nLoopsRemaining = 0;
m_asActiveSamples[i].m_bRequireReflection = FALSE;
#endif // AUDIO_REFLECTIONS
}
}
void
cAudioManager::LoadBankIfNecessary(uint8 bank)
{
if(!SampleManager.IsSampleBankLoaded(bank))
SampleManager.LoadSampleBank(bank);
}
void
cAudioManager::GenerateIntegerRandomNumberTable()
{
@ -1071,7 +1249,7 @@ cAudioManager::GenerateIntegerRandomNumberTable()
}
}
#ifdef GTA_PC
#ifdef EXTERNAL_3D_SOUND
void
cAudioManager::AdjustSamplesVolume()
{
@ -1079,7 +1257,7 @@ cAudioManager::AdjustSamplesVolume()
tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (!pSample->m_bIs2D)
pSample->m_nEmittingVolume = ComputeEmittingVolume(pSample->m_nEmittingVolume, pSample->m_fSoundIntensity, pSample->m_fDistance);
pSample->m_nEmittingVolume = ComputeEmittingVolume(pSample->m_nEmittingVolume, pSample->m_SoundIntensity, pSample->m_fDistance);
}
}

View File

@ -10,33 +10,39 @@ class tSound
{
public:
int32 m_nEntityIndex;
int32 m_nCounter;
int32 m_nSampleIndex;
uint32 m_nCounter;
uint32 m_nSampleIndex;
uint8 m_nBankIndex;
bool8 m_bIs2D;
int32 m_nReleasingVolumeModificator;
uint32 m_nReleasingVolumeModificator;
uint32 m_nFrequency;
uint8 m_nVolume;
float m_fDistance;
int32 m_nLoopCount;
uint32 m_nLoopCount;
#ifndef GTA_PS2
int32 m_nLoopStart;
uint32 m_nLoopStart;
int32 m_nLoopEnd;
#endif
#ifdef EXTERNAL_3D_SOUND
uint8 m_nEmittingVolume;
#endif
float m_fSpeedMultiplier;
float m_fSoundIntensity;
float m_SoundIntensity;
bool8 m_bReleasingSoundFlag;
CVector m_vecPos;
#if !defined(GTA_PS2) || defined(AUDIO_REVERB) // GTA_PS2 because this field exists on mobile but not on PS2
bool8 m_bReverbFlag;
#endif
#ifdef AUDIO_REFLECTIONS
uint8 m_nLoopsRemaining;
bool8 m_bRequireReflection; // Used for oneshots
#endif
uint8 m_nOffset;
uint8 field_4C;
int32 m_nReleasingVolumeDivider;
uint8 m_nFrontRearOffset;
uint32 m_nReleasingVolumeDivider;
bool8 m_bIsProcessed;
bool8 m_bLoopEnded;
int32 m_nCalculatedVolume;
uint32 m_nCalculatedVolume;
int8 m_nVolumeChange;
};
@ -51,7 +57,7 @@ public:
eAudioType m_nType;
void *m_pEntity;
bool8 m_bIsUsed;
uint8 m_bStatus;
bool8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents;
@ -66,8 +72,11 @@ public:
int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
uint8 m_bVolume;
uint8 m_nVolume;
int8 m_nProcess;
#if defined(EXTERNAL_3D_SOUND) && defined(FIX_BUGS)
uint8 m_nEmittingVolume;
#endif
};
VALIDATE_SIZE(tPedComment, 28);
@ -113,7 +122,7 @@ class cMissionAudio
public:
CVector m_vecPos[MISSION_AUDIO_SLOTS];
bool8 m_bPredefinedProperties[MISSION_AUDIO_SLOTS];
int32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
uint32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS];
uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
bool8 m_bIsPlaying[MISSION_AUDIO_SLOTS];
@ -163,7 +172,7 @@ public:
float m_fDistance;
CVehicle *m_pVehicle;
cTransmission *m_pTransmission;
int32 m_nIndex;
uint32 m_nIndex;
float m_fVelocityChange;
cVehicleParams()
@ -180,6 +189,24 @@ public:
VALIDATE_SIZE(cVehicleParams, 0x1C);
#if GTA_VERSION < GTAVC_PC_10
enum {
/*
REFLECTION_YMAX = 0, top
REFLECTION_YMIN = 1, bottom
REFLECTION_XMIN = 2, left
REFLECTION_XMAX = 3, right
REFLECTION_ZMAX = 4,
*/
REFLECTION_TOP = 0,
REFLECTION_BOTTOM,
REFLECTION_LEFT,
REFLECTION_RIGHT,
REFLECTION_UP,
MAX_REFLECTIONS,
};
#else
enum {
REFLECTION_NORTH = 0,
REFLECTION_SOUTH,
@ -191,15 +218,19 @@ enum {
REFLECTION_CEIL_EAST,
MAX_REFLECTIONS,
};
#endif
enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
class cAudioManager
{
public:
bool8 m_bIsInitialised;
uint8 m_bReverb; // unused
bool8 m_bReverb; // unused
bool8 m_bFifthFrameFlag;
uint8 m_nActiveSamples;
uint8 field_4; // unused
bool8 m_bDoubleVolume; // unused
bool8 m_bDynamicAcousticModelingStatus;
int8 field_6;
float m_fSpeedOfSound;
@ -214,8 +245,10 @@ public:
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal;
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS];
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS];
#ifdef AUDIO_REFLECTIONS
CVector m_avecReflectionsPos[MAX_REFLECTIONS];
float m_afReflectionsDistances[MAX_REFLECTIONS];
#endif
cAudioScriptObjectManager m_sAudioScriptObjectManager;
// miami
@ -243,307 +276,318 @@ public:
uint8 field_5538; // something related to phone dialogues
int32 m_anRandomTable[5];
uint8 m_nTimeSpent;
uint8 m_nUserPause;
uint8 m_nPreviousUserPause;
bool8 m_nUserPause;
bool8 m_nPreviousUserPause;
uint32 m_FrameCounter;
cAudioManager();
~cAudioManager();
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; }
bool8 IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; }
bool8 ShouldDuckMissionAudio(uint8 slot) const;
// "Should" be in alphabetic order, except "getXTalkSfx"
void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void AddReflectionsToRequestedQueue();
void AddReleasingSounds();
void AddSampleToRequestedQueue();
void AgeCrimes(); // inlined in vc
void CalculateDistance(bool8 &condition, float dist);
bool8 CheckForAnAudioFileOnCD() const;
void ClearActiveSamples();
void ClearMissionAudio(uint8 slot); // inlined in vc
void ClearRequestedQueue(); // inlined in vc
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const;
int32 ComputePan(float, CVector *);
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
int32 CreateEntity(eAudioType type, void *entity);
void DestroyAllGameCreatedEntities();
void DestroyEntity(int32 id); // inlined in vc
void DoPoliceRadioCrackle();
// functions returning talk sfx,
// order from GetPedCommentSfx
uint32 GetPlayerTalkSfx(CPed *ped, int16 sound);
uint32 GetCopTalkSfx(CPed *ped, int16 sound);
uint32 GetSwatTalkSfx(CPed *ped, int16 sound);
uint32 GetFBITalkSfx(CPed *ped, int16 sound);
uint32 GetArmyTalkSfx(CPed *ped, int16 sound);
uint32 GetMedicTalkSfx(CPed *ped, int16 sound);
uint32 GetFiremanTalkSfx(CPed *ped, int16 sound);
uint32 GetDefaultTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHFOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHMYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHMOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYRITalkSfx(CPed *ped, int16 sound);
uint32 GetHFORITalkSfx(CPed *ped, int16 sound);
uint32 GetHMYRITalkSfx(CPed *ped, int16 sound);
uint32 GetHMORITalkSfx(CPed *ped, int16 sound);
uint32 GetHFYBETalkSfx(CPed *ped, int16 sound);
uint32 GetHFOBETalkSfx(CPed *ped, int16 sound);
uint32 GetHMYBETalkSfx(CPed *ped, int16 sound);
uint32 GetHMOBETalkSfx(CPed *ped, int16 sound);
uint32 GetHFYBUTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYMDTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYCGTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYPRTalkSfx(CPed *ped, int16 sound);
uint32 GetHFOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetHMOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetHMYAPTalkSfx(CPed *ped, int16 sound);
uint32 GetHMOCATalkSfx(CPed *ped, int16 sound);
uint32 GetBMODKTalkSfx(CPed *ped, int16 sound);
uint32 GetBMYCRTalkSfx(CPed *ped, int16 sound);
uint32 GetBFYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetBFOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetBMYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetBMOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetBFYRITalkSfx(CPed *ped, int16 sound);
uint32 GetBFORITalkSfx(CPed *ped, int16 sound);
uint32 GetBMYRITalkSfx(CPed *ped, int16 sound);
uint32 GetBFYBETalkSfx(CPed *ped, int16 sound);
uint32 GetBMYBETalkSfx(CPed *ped, int16 sound);
uint32 GetBFOBETalkSfx(CPed *ped, int16 sound);
uint32 GetBMOBETalkSfx(CPed *ped, int16 sound);
uint32 GetBMYBUTalkSfx(CPed *ped, int16 sound);
uint32 GetBFYPRTalkSfx(CPed *ped, int16 sound);
uint32 GetBFOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetBMOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetBMYPITalkSfx(CPed *ped, int16 sound);
uint32 GetBMYBBTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYCRTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetWFOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetWMOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYRITalkSfx(CPed *ped, int16 sound);
uint32 GetWFORITalkSfx(CPed *ped, int16 sound);
uint32 GetWMYRITalkSfx(CPed *ped, int16 sound);
uint32 GetWMORITalkSfx(CPed *ped, int16 sound);
uint32 GetWFYBETalkSfx(CPed *ped, int16 sound);
uint32 GetWMYBETalkSfx(CPed *ped, int16 sound);
uint32 GetWFOBETalkSfx(CPed *ped, int16 sound);
uint32 GetWMOBETalkSfx(CPed *ped, int16 sound);
uint32 GetWMYCWTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYGOTalkSfx(CPed *ped, int16 sound);
uint32 GetWFOGOTalkSfx(CPed *ped, int16 sound);
uint32 GetWMOGOTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYLGTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYLGTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYBUTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYBUTalkSfx(CPed *ped, int16 sound);
uint32 GetWMOBUTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYPRTalkSfx(CPed *ped, int16 sound);
uint32 GetWFOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetWMOTRTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYPITalkSfx(CPed *ped, int16 sound);
uint32 GetWMOCATalkSfx(CPed *ped, int16 sound);
uint32 GetWFYJGTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYJGTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYSKTalkSfx(CPed *ped, int16 sound);
uint32 GetWMYSKTalkSfx(CPed *ped, int16 sound);
uint32 GetWFYSHTalkSfx(CPed *ped, int16 sound);
uint32 GetWFOSHTalkSfx(CPed *ped, int16 sound);
uint32 GetJFOTOTalkSfx(CPed *ped, int16 sound);
uint32 GetJMOTOTalkSfx(CPed *ped, int16 sound);
uint32 GetCBTalkSfx(CPed *ped, int16 sound);
uint32 GetHNTalkSfx(CPed *ped, int16 sound);
uint32 GetSGTalkSfx(CPed *ped, int16 sound);
uint32 GetCLTalkSfx(CPed *ped, int16 sound);
uint32 GetGDTalkSfx(CPed *ped, int16 sound);
uint32 GetBKTalkSfx(CPed *ped, int16 sound);
uint32 GetPGTalkSfx(CPed *ped, int16 sound);
uint32 GetVICETalkSfx(CPed *ped, int16 sound, int16 model);
uint32 GetWFYG1TalkSfx(CPed *ped, int16 sound);
uint32 GetWFYG2TalkSfx(CPed *ped, int16 sound);
uint32 GetGenericMaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
// end of functions returning talk sfx
void GenerateIntegerRandomNumberTable();
char *Get3DProviderName(uint8 id) const;
char GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const;
int8 AutoDetect3DProviders() const;
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const;
float GetCollisionRatio(float a, float b, float c, float d) const; // inlined in vc
float GetDistanceSquared(const CVector &v) const; // inlined in vc
int32 GetJumboTaxiFreq() const; // inlined in vc
uint8 GetMissionAudioLoadingStatus(uint8 slot) const;
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
uint8 GetNum3DProvidersAvailable() const;
uint32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission,
float velocityChange);
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange);
bool8 HasAirBrakes(int32 model) const;
void Initialise();
void InitialisePoliceRadio();
void InitialisePoliceRadioZones();
void InterrogateAudioEntities(); // inlined
bool8 IsAudioInitialised() const;
bool8 IsMissionAudioSampleFinished(uint8 slot);
bool8 IsMP3RadioChannelAvailable() const;
bool8 MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
void PlayLoadedMissionAudio(uint8 slot);
void PlayOneShot(int32 index, uint16 sound, float vol);
void PlaySuspectLastSeen(float x, float y, float z);
void PlayerJustGotInCar() const;
void PlayerJustLeftCar() const;
void PostInitialiseGameSpecificSetup();
void PostTerminateGameSpecificShutdown();
void PreInitialiseGameSpecificSetup() const;
void PreloadMissionAudio(uint8 slot, Const char *name);
void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
void ProcessActiveQueues();
bool8 ProcessAirBrakes(cVehicleParams& params);
bool8 ProcessBoatEngine(cVehicleParams& params);
bool8 ProcessBoatMovingOverWater(cVehicleParams& params);
#ifdef GTA_BRIDGE
void ProcessBridge();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
void ProcessBridgeWarning();
#endif
bool8 ProcessCarBombTick(cVehicleParams& params);
void ProcessCarHeli(cVehicleParams& params);
void ProcessCesna(cVehicleParams& params);
//void ProcessCrane();
bool8 ProcessEngineDamage(cVehicleParams& params);
void ProcessEntity(int32 sound);
void ProcessExplosions(int32 explosion);
void ProcessFireHydrant();
void ProcessFires(int32 entity);
void ProcessFrontEnd();
void ProcessGarages();
void ProcessJumbo(cVehicleParams& params);
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
void ProcessJumboFlying();
void ProcessJumboLanding(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane);
void ProcessJumboTaxi();
void ProcessLoopingScriptObject(uint8 sound);
void ProcessMissionAudio();
void ProcessMissionAudioSlot(uint8 slot);
void ProcessModelHeliVehicle(cVehicleParams& params);
void ProcessModelVehicle(cVehicleParams& params);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessPed(CPhysical *ped);
void ProcessPedOneShots(cPedParams &params);
void ProcessPhysical(int32 id);
void ProcessPlane(cVehicleParams& params);
void ProcessPlayerMood();
void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh);
void ProcessProjectiles();
void ProcessRainOnVehicle(cVehicleParams& params);
void ProcessReverb() const;
bool8 ProcessReverseGear(cVehicleParams& params);
void ProcessScriptObject(int32 id);
void ProcessSpecial();
#ifdef GTA_TRAIN
bool8 ProcessTrainNoise(cVehicleParams *params);
#endif
void ProcessVehicle(CVehicle *vehicle);
bool8 ProcessVehicleDoors(cVehicleParams &params);
void ProcessVehicleEngine(cVehicleParams &params);
void ProcessVehicleFlatTyre(cVehicleParams &params);
bool8 ProcessVehicleHorn(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool8 ProcessWetRoadNoise(cVehicleParams& params);
void ProcessEscalators();
void ProcessExtraSounds();
int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const;
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
void ReportCrime(eCrimeType crime, const CVector &pos);
void ResetAudioLogicTimers(uint32 timer);
void ResetPoliceRadio();
void ResetTimers(uint32 time);
void Service();
void ServiceCollisions();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(bool8 status);
void SetEffectsFadeVol(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetMP3BoostVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool8 status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
void SetMonoMode(bool8 mono);
void SetMusicFadeVol(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
void SetUpOneShotCollisionSound(const cAudioCollision &col);
bool8 SetupCrimeReport();
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
void SetupPedComments(cPedParams &params, uint16 sound);
void SetupSuspectLastSeenReport();
void Terminate();
void TranslateEntity(Const CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CVehicle *veh, int vehType);
void UpdateReflections();
bool8 UsesReverseWarning(int32 model) const;
bool8 UsesSiren(cVehicleParams &params) const;
bool8 UsesSirenSwitching(cVehicleParams &params) const;
CVehicle *FindVehicleOfPlayer();
void SetPedTalkingStatus(CPed *ped, bool8 status);
void SetPlayersMood(uint8 mood, uint32 time);
float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
void Service();
int32 CreateEntity(eAudioType type, void *entity);
void DestroyEntity(int32 id); // inlined in vc
bool8 GetEntityStatus(int32 id);
void SetEntityStatus(int32 id, bool8 status);
void *GetEntityPointer(int32 id);
void PlayOneShot(int32 index, uint16 sound, float vol);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
void SetMP3BoostVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
void SetMusicFadeVol(uint8 volume);
void SetOutputMode(bool8 surround);
void ResetTimers(uint32 time);
void DestroyAllGameCreatedEntities();
#ifdef GTA_PC
// only used in pc
uint8 GetNum3DProvidersAvailable();
char *Get3DProviderName(uint8 id);
int8 GetCurrent3DProviderIndex();
int8 AutoDetect3DProviders();
int8 SetCurrent3DProvider(uint8 which);
void SetSpeakerConfig(int32 conf);
bool8 IsMP3RadioChannelAvailable();
void ReleaseDigitalHandle();
void ReacquireDigitalHandle();
#ifdef AUDIO_REFLECTIONS
void SetDynamicAcousticModelingStatus(bool8 status);
#endif
bool8 CheckForAnAudioFileOnCD();
char GetCDAudioDriveLetter();
bool8 IsAudioInitialised();
#endif
void ServiceSoundEffects();
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance);
void TranslateEntity(Const CVector *v1, CVector *v2);
int32 ComputeFrontRearMix(float, CVector *);
int32 ComputePan(float, CVector *);
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier);
int32 RandomDisplacement(uint32 seed);
void InterrogateAudioEntities(); // inlined
void AddSampleToRequestedQueue();
void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
#ifdef AUDIO_REFLECTIONS
void AddReflectionsToRequestedQueue();
void UpdateReflections();
#endif
void AddReleasingSounds();
void ProcessActiveQueues();
void ClearRequestedQueue(); // inlined in vc
void ClearActiveSamples();
void GenerateIntegerRandomNumberTable();
void LoadBankIfNecessary(uint8 bank);
#ifdef EXTERNAL_3D_SOUND // actually must have been && AUDIO_MSS as well
void AdjustSamplesVolume(); // inlined
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined
#endif
// audio logic
void PreInitialiseGameSpecificSetup();
void PostInitialiseGameSpecificSetup();
void PreTerminateGameSpecificShutdown();
void PostTerminateGameSpecificShutdown();
void ResetAudioLogicTimers(uint32 timer);
void ProcessReverb();
float GetDistanceSquared(const CVector &v); // inlined in vc
void CalculateDistance(bool8 &condition, float dist);
CVehicle *FindVehicleOfPlayer();
void ProcessSpecial();
void ProcessEntity(int32 sound);
void ProcessPhysical(int32 id);
// vehicles
void ProcessVehicle(CVehicle *vehicle);
void ProcessCarHeli(cVehicleParams &params);
void ProcessRainOnVehicle(cVehicleParams &params);
bool8 ProcessReverseGear(cVehicleParams &params);
void ProcessModelHeliVehicle(cVehicleParams &params);
void ProcessModelVehicle(cVehicleParams &params);
void ProcessVehicleFlatTyre(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessWetRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleEngine(cVehicleParams &params);
void UpdateGasPedalAudio(CVehicle *veh, int vehType);
void PlayerJustGotInCar();
void PlayerJustLeftCar();
void AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void ProcessCesna(cVehicleParams &params);
void ProcessPlayersVehicleEngine(cVehicleParams &params, CVehicle *veh);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, float velocityChange);
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange);
bool8 ProcessVehicleHorn(cVehicleParams &params);
bool8 UsesSiren(cVehicleParams &params);
bool8 UsesSirenSwitching(cVehicleParams &params);
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
bool8 UsesReverseWarning(uint32 model);
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleDoors(cVehicleParams &params);
bool8 ProcessAirBrakes(cVehicleParams &params);
bool8 HasAirBrakes(uint32 model);
bool8 ProcessEngineDamage(cVehicleParams &params);
bool8 ProcessCarBombTick(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
#ifdef GTA_TRAIN
bool8 ProcessTrainNoise(cVehicleParams &params);
#endif
bool8 ProcessBoatEngine(cVehicleParams &params);
bool8 ProcessBoatMovingOverWater(cVehicleParams &params);
void ProcessPlane(cVehicleParams &params);
void ProcessJumbo(cVehicleParams &params);
void ProcessJumboTaxi();
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane);
void ProcessJumboFlying();
void ProcessJumboLanding(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
int32 GetJumboTaxiFreq(); // inlined in vc
// peds
void ProcessPed(CPhysical *ped);
void ProcessPedOneShots(cPedParams &params);
void SetPedTalkingStatus(CPed *ped, bool8 status);
void SetPlayersMood(uint8 mood, uint32 time);
void ProcessPlayerMood();
// ped comments
void SetupPedComments(cPedParams &params, uint16 sound);
uint32 GetPedCommentSfx(CPed *ped, uint16 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset);
uint32 GetPlayerTalkSfx(CPed *ped, uint16 sound);
uint32 GetGenericMaleTalkSfx(CPed *ped, uint16 sound); // inlined in vc
uint32 GetGenericFemaleTalkSfx(CPed *ped, uint16 sound); // inlined in vc
uint32 GetDefaultTalkSfx(CPed *ped, uint16 sound);
uint32 GetCopTalkSfx(CPed *ped, uint16 sound);
uint32 GetSwatTalkSfx(CPed *ped, uint16 sound);
uint32 GetFBITalkSfx(CPed *ped, uint16 sound);
uint32 GetArmyTalkSfx(CPed *ped, uint16 sound);
uint32 GetMedicTalkSfx(CPed *ped, uint16 sound);
uint32 GetFiremanTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYG1TalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYG2TalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetHMYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetHMOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetHFORITalkSfx(CPed *ped, uint16 sound);
uint32 GetHMYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetHMORITalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetHFOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetHMYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetHMOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYBUTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYMDTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYCGTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFYPRTalkSfx(CPed *ped, uint16 sound);
uint32 GetHFOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetHMOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetHMOCATalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYCRTalkSfx(CPed *ped, uint16 sound);
uint32 GetBFYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetBFOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetBMOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetBFYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetBFORITalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetBFYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetBFOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetBMOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYBUTalkSfx(CPed *ped, uint16 sound);
uint32 GetBFYPRTalkSfx(CPed *ped, uint16 sound);
uint32 GetBFOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetBMOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYPITalkSfx(CPed *ped, uint16 sound);
uint32 GetBMYBBTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYCRTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYSKTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYSKTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOSTTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetWFORITalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYRITalkSfx(CPed *ped, uint16 sound);
uint32 GetWMORITalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYBETalkSfx(CPed *ped, uint16 sound);
uint32 GetWFOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOBETalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYCWTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYGOTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFOGOTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOGOTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYLGTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYLGTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYBUTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYBUTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOBUTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYPRTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOTRTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYPITalkSfx(CPed *ped, uint16 sound);
uint32 GetWMOCATalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYSHTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFOSHTalkSfx(CPed *ped, uint16 sound);
uint32 GetJFOTOTalkSfx(CPed *ped, uint16 sound);
uint32 GetJMOTOTalkSfx(CPed *ped, uint16 sound);
uint32 GetHNTalkSfx(CPed *ped, uint16 sound);
uint32 GetBKTalkSfx(CPed *ped, uint16 sound);
uint32 GetCBTalkSfx(CPed *ped, uint16 sound);
uint32 GetSGTalkSfx(CPed *ped, uint16 sound);
uint32 GetCLTalkSfx(CPed *ped, uint16 sound);
uint32 GetGDTalkSfx(CPed *ped, uint16 sound);
uint32 GetPGTalkSfx(CPed *ped, uint16 sound);
uint32 GetViceWhiteTalkSfx(CPed *ped, uint16 sound);
uint32 GetViceBlackTalkSfx(CPed *ped, uint16 sound);
uint32 GetBMODKTalkSfx(CPed *ped, uint16 sound);
uint32 GetHMYAPTalkSfx(CPed *ped, uint16 sound);
uint32 GetWFYJGTalkSfx(CPed *ped, uint16 sound);
uint32 GetWMYJGTalkSfx(CPed *ped, uint16 sound);
uint32 GetSpecialCharacterTalkSfx(CPed *ped, int32 model, uint16 sound);
void DebugPlayPedComment(int32 sound);
// particles
void ProcessExplosions(int32 explosion);
void ProcessFires(int32 entity);
void ProcessWaterCannon(int32);
// script objects
void ProcessScriptObject(int32 id);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessLoopingScriptObject(uint8 sound);
// misc
void ProcessWeather(int32 id);
void ProcessFrontEnd();
//void ProcessCrane();
void ProcessProjectiles();
void ProcessEscalators();
void ProcessExtraSounds();
void ProcessGarages();
void ProcessFireHydrant();
#ifdef GTA_BRIDGE
void ProcessBridge();
void ProcessBridgeWarning();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
#endif
// mission audio
const char *GetMissionAudioLoadedLabel(uint8 slot);
bool8 MissionScriptAudioUsesPoliceChannel(uint32 soundMission);
void PreloadMissionAudio(uint8 slot, Const char *name);
uint8 GetMissionAudioLoadingStatus(uint8 slot);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void PlayLoadedMissionAudio(uint8 slot);
bool8 ShouldDuckMissionAudio(uint8 slot);
bool8 IsMissionAudioSamplePlaying(uint8 slot);
bool8 IsMissionAudioSampleFinished(uint8 slot);
void ClearMissionAudio(uint8 slot); // inlined in vc
void ProcessMissionAudioSlot(uint8 slot);
void ProcessMissionAudio();
// police radio
void InitialisePoliceRadioZones();
void InitialisePoliceRadio();
void ResetPoliceRadio();
void SetMissionScriptPoliceAudio(uint32 sfx); // inlined and optimized
int8 GetMissionScriptPoliceAudioPlayingStatus();
void DoPoliceRadioCrackle();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
bool8 SetupCrimeReport();
void SetupSuspectLastSeenReport();
void ReportCrime(eCrimeType crime, const CVector &pos);
void PlaySuspectLastSeen(float x, float y, float z);
void AgeCrimes(); // inlined in vc
// collision stuff
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
void ServiceCollisions();
void SetUpOneShotCollisionSound(const cAudioCollision &col);
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
float GetCollisionOneShotRatio(uint32 a, float b);
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c); // not used
float GetCollisionRatio(float a, float b, float c, float d); // inlined in vc
float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
};
/*
@ -562,6 +606,21 @@ public:
#define RESET_LOOP_OFFSETS
#define SET_LOOP_OFFSETS(sample)
#endif
#ifdef EXTERNAL_3D_SOUND
#define SET_EMITTING_VOLUME(vol) m_sQueueSample.m_nEmittingVolume = vol
#else
#define SET_EMITTING_VOLUME(vol)
#endif
#ifdef AUDIO_REFLECTIONS
#define SET_SOUND_REFLECTION(b) m_sQueueSample.m_bRequireReflection = b
#else
#define SET_SOUND_REFLECTION(b)
#endif
#ifdef AUDIO_REVERB
#define SET_SOUND_REVERB(b) m_sQueueSample.m_bReverbFlag = b
#else
#define SET_SOUND_REVERB(b)
#endif
#if defined(AUDIO_MSS) && !defined(PS2_AUDIO_CHANNELS)
static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error");

View File

@ -38,6 +38,12 @@ cDMAudio::DestroyEntity(int32 audioEntity)
AudioManager.DestroyEntity(audioEntity);
}
bool8
cDMAudio::GetEntityStatus(int32 audioEntity)
{
return AudioManager.GetEntityStatus(audioEntity);
}
void
cDMAudio::SetEntityStatus(int32 audioEntity, bool8 status)
{
@ -57,9 +63,9 @@ cDMAudio::DestroyAllGameCreatedEntities(void)
}
void
cDMAudio::SetMonoMode(bool8 mono)
cDMAudio::SetOutputMode(bool8 surround)
{
AudioManager.SetMonoMode(mono);
AudioManager.SetOutputMode(surround);
}
void
@ -163,7 +169,9 @@ cDMAudio::ReacquireDigitalHandle(void)
void
cDMAudio::SetDynamicAcousticModelingStatus(bool8 status)
{
#ifdef AUDIO_REFLECTIONS
AudioManager.SetDynamicAcousticModelingStatus(status);
#endif
}
bool8
@ -184,6 +192,12 @@ cDMAudio::IsAudioInitialised(void)
return AudioManager.IsAudioInitialised();
}
void
cDMAudio::ResetPoliceRadio()
{
AudioManager.ResetPoliceRadio();
}
void
cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos)
{
@ -309,6 +323,12 @@ cDMAudio::PlayLoadedMissionAudio(uint8 slot)
AudioManager.PlayLoadedMissionAudio(slot);
}
bool8
cDMAudio::IsMissionAudioSamplePlaying(uint8 slot)
{
return AudioManager.IsMissionAudioSamplePlaying(slot);
}
bool8
cDMAudio::IsMissionAudioSampleFinished(uint8 slot)
{
@ -321,6 +341,12 @@ cDMAudio::ClearMissionAudio(uint8 slot)
AudioManager.ClearMissionAudio(slot);
}
const char *
cDMAudio::GetMissionAudioLoadedLabel(uint8 slot)
{
return AudioManager.GetMissionAudioLoadedLabel(slot);
}
uint8
cDMAudio::GetRadioInCar(void)
{

View File

@ -25,11 +25,12 @@ public:
int32 CreateEntity(eAudioType type, void *UID);
void DestroyEntity(int32 audioEntity);
bool8 GetEntityStatus(int32 audioEntity);
void SetEntityStatus(int32 audioEntity, bool8 status);
void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume);
void DestroyAllGameCreatedEntities(void);
void SetMonoMode(bool8 mono);
void SetOutputMode(bool8 surround);
void SetMP3BoostVolume(uint8 volume);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
@ -58,6 +59,7 @@ public:
char GetCDAudioDriveLetter(void);
bool8 IsAudioInitialised(void);
void ResetPoliceRadio();
void ReportCrime(eCrimeType crime, CVector const &pos);
int32 CreateLoopingScriptObject(cAudioScriptObject *scriptObject);
@ -85,8 +87,10 @@ public:
uint8 GetMissionAudioLoadingStatus(uint8 slot);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void PlayLoadedMissionAudio(uint8 slot);
bool8 IsMissionAudioSamplePlaying(uint8 slot);
bool8 IsMissionAudioSampleFinished(uint8 slot);
void ClearMissionAudio(uint8 slot);
const char *GetMissionAudioLoadedLabel(uint8 slot);
uint8 GetRadioInCar(void);
void SetRadioInCar(uint32 radio);

View File

@ -132,23 +132,23 @@ cMusicManager::SetStartingTrackPositions(bool8 isNewGameTimer)
if (IsInitialised()) {
time_t timevalue = time(0);
if (timevalue == -1) {
pos = AudioManager.GetRandomNumber(0);
pos = AudioManager.m_anRandomTable[0];
} else {
tm* pTm = localtime(&timevalue);
if (pTm->tm_sec == 0)
pTm->tm_sec = AudioManager.GetRandomNumber(0);
pTm->tm_sec = AudioManager.m_anRandomTable[0];
if (pTm->tm_min == 0)
pTm->tm_min = AudioManager.GetRandomNumber(1);
pTm->tm_min = AudioManager.m_anRandomTable[1];
if (pTm->tm_hour == 0)
pTm->tm_hour = AudioManager.GetRandomNumber(2);
pTm->tm_hour = AudioManager.m_anRandomTable[2];
if (pTm->tm_mday == 0)
pTm->tm_mday = AudioManager.GetRandomNumber(3);
pTm->tm_mday = AudioManager.m_anRandomTable[3];
if (pTm->tm_mon == 0)
pTm->tm_mon = AudioManager.GetRandomNumber(4);
pTm->tm_mon = AudioManager.m_anRandomTable[4];
if (pTm->tm_year == 0)
pTm->tm_year = AudioManager.GetRandomNumber(3);
pTm->tm_year = AudioManager.m_anRandomTable[3];
if (pTm->tm_wday == 0)
pTm->tm_wday = AudioManager.GetRandomNumber(2);
pTm->tm_wday = AudioManager.m_anRandomTable[2];
pos = pTm->tm_yday
* pTm->tm_wday
* pTm->tm_year
@ -165,7 +165,7 @@ cMusicManager::SetStartingTrackPositions(bool8 isNewGameTimer)
if (i < STREAMED_SOUND_CITY_AMBIENT && isNewGameTimer)
m_aTracks[i].m_nPosition = NewGameRadioTimers[i];
else if (i < STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED)
m_aTracks[i].m_nPosition = (pos * AudioManager.GetRandomNumber(i % 5)) % m_aTracks[i].m_nLength;
m_aTracks[i].m_nPosition = (pos * AudioManager.m_anRandomTable[i % 5]) % m_aTracks[i].m_nLength;
else
m_aTracks[i].m_nPosition = 0;
@ -263,7 +263,7 @@ cMusicManager::GetRadioInCar(void)
CVehicle* veh = AudioManager.FindVehicleOfPlayer();
if (veh != nil) {
if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) {
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0))
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && !AudioManager.m_nUserPause))
return STREAMED_SOUND_RADIO_POLICE;
return m_nRadioInCar;
}
@ -271,7 +271,7 @@ cMusicManager::GetRadioInCar(void)
}
}
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0))
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && !AudioManager.m_nUserPause))
return RADIO_OFF;
return m_nRadioInCar;
}
@ -461,7 +461,7 @@ cMusicManager::ServiceFrontEndMode()
} else {
if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER)
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0);
else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0)
else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && !AudioManager.m_nUserPause)
ChangeMusicMode(MUSICMODE_GAME);
}
} else {
@ -561,7 +561,7 @@ cMusicManager::ServiceGameMode()
}
}
#ifdef RADIO_SCROLL_TO_PREV_STATION
else if(CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
else if(!CPad::GetPad(0)->ArePlayerControlsDisabled() && (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown())) {
if(!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE);
int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON
@ -1171,7 +1171,7 @@ cMusicManager::GetCarTuning()
if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE;
if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI;
if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable())
veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK;
veh->m_nRadioStation = AudioManager.m_anRandomTable[2] % USERTRACK;
return veh->m_nRadioStation;
}

View File

@ -23,9 +23,9 @@ struct tPoliceRadioZone {
tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = 2;
uint8 gSpecialSuspectLastSeenReport;
uint32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = PLAY_STATUS_FINISHED;
bool8 gSpecialSuspectLastSeenReport;
uint32 gMinTimeToNextReport[NUM_CRIME_TYPES];
void
@ -64,8 +64,9 @@ cAudioManager::InitialisePoliceRadio()
m_sPoliceRadioQueue.policeChannelCounterSeconds = 0;
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
#if !defined(GTA_PS2) || defined(AUDIO_REVERB)
SampleManager.SetChannelReverbFlag(CHANNEL_POLICE_RADIO, FALSE);
#endif
gSpecialSuspectLastSeenReport = FALSE;
for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
gMinTimeToNextReport[i] = m_FrameCounter;
@ -80,17 +81,17 @@ cAudioManager::ResetPoliceRadio()
}
void
cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
cAudioManager::SetMissionScriptPoliceAudio(uint32 sfx)
{
if (!m_bIsInitialised) return;
if (g_nMissionAudioPlayingStatus != 1) {
g_nMissionAudioPlayingStatus = 0;
if (g_nMissionAudioPlayingStatus != PLAY_STATUS_PLAYING) {
g_nMissionAudioPlayingStatus = PLAY_STATUS_STOPPED;
g_nMissionAudioSfx = sfx;
}
}
int8
cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const
cAudioManager::GetMissionScriptPoliceAudioPlayingStatus()
{
return g_nMissionAudioPlayingStatus;
}
@ -107,13 +108,13 @@ cAudioManager::DoPoliceRadioCrackle()
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_nVolume = m_anRandomTable[2] % 20 + 15;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume;
SET_EMITTING_VOLUME(m_sQueueSample.m_nVolume);
SET_LOOP_OFFSETS(SFX_POLICE_RADIO_CRACKLE)
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = FALSE;
SET_SOUND_REVERB(FALSE);
m_sQueueSample.m_nOffset = 63;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bRequireReflection = FALSE;
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
@ -125,7 +126,7 @@ cAudioManager::ServicePoliceRadio()
if(!m_bIsInitialised) return;
if(m_nUserPause == 0) {
if(!m_nUserPause) {
bool8 crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
@ -162,20 +163,20 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
static int cWait = 0;
static bool8 bChannelOpen = FALSE;
static uint8 bMissionAudioPhysicalPlayingStatus = 0;
static uint8 bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_STOPPED;
static int32 PoliceChannelFreq = 22050;
if (!m_bIsInitialised) return;
if (m_nUserPause != 0) {
if (m_nUserPause) {
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 &&
if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING &&
SampleManager.IsStreamPlaying(1)) {
SampleManager.PauseStream(TRUE, 1);
}
} else {
if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE &&
bMissionAudioPhysicalPlayingStatus == 1) {
bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING) {
SampleManager.PauseStream(FALSE, 1);
}
if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = FALSE;
@ -188,17 +189,17 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
return;
}
if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) {
if (g_nMissionAudioPlayingStatus) {
if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus &&
if (g_nMissionAudioPlayingStatus != PLAY_STATUS_STOPPED) {
if (g_nMissionAudioPlayingStatus == PLAY_STATUS_PLAYING && bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_STOPPED &&
SampleManager.IsStreamPlaying(1)) {
bMissionAudioPhysicalPlayingStatus = 1;
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_PLAYING;
}
if (bMissionAudioPhysicalPlayingStatus == 1) {
if (bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING) {
if (SampleManager.IsStreamPlaying(1)) {
DoPoliceRadioCrackle();
} else {
bMissionAudioPhysicalPlayingStatus = 2;
g_nMissionAudioPlayingStatus = 2;
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_FINISHED;
g_nMissionAudioPlayingStatus = PLAY_STATUS_FINISHED;
g_nMissionAudioSfx = NO_SAMPLE;
cWait = 30;
}
@ -208,13 +209,13 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE, 1);
SampleManager.StartPreloadedStreamedFile(1);
g_nMissionAudioPlayingStatus = 1;
bMissionAudioPhysicalPlayingStatus = 0;
g_nMissionAudioPlayingStatus = PLAY_STATUS_PLAYING;
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_STOPPED;
return;
}
}
if (bChannelOpen) DoPoliceRadioCrackle();
if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != 1) &&
if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != PLAY_STATUS_PLAYING) &&
!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO) && m_sPoliceRadioQueue.policeChannelTimer) {
if (m_sPoliceRadioQueue.policeChannelTimer) {
sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
@ -225,7 +226,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
}
if (wantedLevel == 0) {
if (gSpecialSuspectLastSeenReport) {
gSpecialSuspectLastSeenReport = 0;
gSpecialSuspectLastSeenReport = FALSE;
} else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1) {
bChannelOpen = FALSE;
processed = TRUE;
@ -246,8 +247,10 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq);
SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, 100);
SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63);
#ifndef GTA_PS2
SampleManager.SetChannelLoopCount(CHANNEL_POLICE_RADIO, 1);
SampleManager.SetChannelLoopPoints(CHANNEL_POLICE_RADIO, 0, -1);
#endif
SampleManager.StartChannel(CHANNEL_POLICE_RADIO);
}
if (processed) ResetPoliceRadio();

View File

@ -116,9 +116,15 @@ enum
#define MAXPROVIDERS 64
#ifdef EXTERNAL_3D_SOUND
#define MAXCHANNELS (NUM_CHANNELS_GENERIC+1)
#define MAXCHANNELS_SURROUND (MAXCHANNELS-4)
#define MAX2DCHANNELS 1
#else
#define MAXCHANNELS 0
#define MAXCHANNELS_SURROUND 0
#define MAX2DCHANNELS NUM_CHANNELS
#endif
#define MAX_STREAMS 3
@ -163,6 +169,7 @@ public:
cSampleManager(void);
~cSampleManager(void);
#ifdef EXTERNAL_3D_SOUND
void SetSpeakerConfig(int32 nConfig);
uint32 GetMaximumSupportedChannels(void);
@ -176,6 +183,7 @@ public:
int8 SetCurrent3DProvider(uint8 which);
int8 AutoDetect3DProviders();
#endif
bool8 IsMP3RadioChannelAvailable(void);
@ -216,9 +224,11 @@ public:
void SetChannelReverbFlag (uint32 nChannel, bool8 nReverbFlag);
bool8 InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
#ifdef EXTERNAL_3D_SOUND
void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
#endif
void SetChannelVolume (uint32 nChannel, uint32 nVolume);
void SetChannelPan (uint32 nChannel, uint32 nPan);
void SetChannelFrequency (uint32 nChannel, uint32 nFreq);

View File

@ -69,7 +69,7 @@ bool8 _bIsMp3Active;
bool8 _bSampmanInitialised = FALSE;
#ifdef EXTERNAL_3D_SOUND
//
// Miscellaneous globals / defines
@ -89,8 +89,10 @@ S32 usingEAX=0;
S32 usingEAX3=0;
HPROVIDER opened_provider=0;
H3DSAMPLE opened_samples[MAXCHANNELS] = {0};
#endif
HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
HDIGDRIVER DIG;
#ifdef EXTERNAL_3D_SOUND
S32 speaker_type=0;
U32 _maxSamples;
@ -259,6 +261,7 @@ set_new_provider(S32 index)
return FALSE;
}
#endif
U32 RadioHandlers[9];
@ -324,6 +327,7 @@ cSampleManager::~cSampleManager(void)
}
#ifdef EXTERNAL_3D_SOUND
void
cSampleManager::SetSpeakerConfig(int32 which)
{
@ -459,6 +463,7 @@ cSampleManager::AutoDetect3DProviders()
return ds3ds;
return -1;
}
#endif
static bool8
_ResolveLink(char const *path, char *out)
@ -873,9 +878,11 @@ cSampleManager::ReleaseDigitalHandle(void)
{
if ( DIG )
{
#ifdef EXTERNAL_3D_SOUND
prevprovider = curprovider;
release_existing();
curprovider = -1;
#endif
AIL_digital_handle_release(DIG);
}
}
@ -886,8 +893,10 @@ cSampleManager::ReacquireDigitalHandle(void)
if ( DIG )
{
AIL_digital_handle_reacquire(DIG);
#ifdef EXTERNAL_3D_SOUND
if ( prevprovider != -1 )
set_new_provider(prevprovider);
#endif
}
}
@ -917,6 +926,7 @@ cSampleManager::Initialise(void)
m_nMonoMode = 0;
}
#ifdef EXTERNAL_3D_SOUND
// miles
TRACE("MILES");
{
@ -937,6 +947,7 @@ cSampleManager::Initialise(void)
for ( int32 i = 0; i < MAXCHANNELS; i++ )
opened_samples[i] = NULL;
}
#endif
// banks
TRACE("banks");
@ -1025,11 +1036,20 @@ cSampleManager::Initialise(void)
if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
{
FILE *f;
#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[0]);
strcat(filepath, PS2StreamedNameTable[0]);
f = fopen(filepath, "rb");
FILE *f = fopen(filepath, "rb");
if ( !f )
#endif
{
strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[0]);
f = fopen(filepath, "rb");
}
if ( f )
{
fclose(f);
@ -1050,7 +1070,9 @@ cSampleManager::Initialise(void)
return FALSE;
}
#ifdef EXTERNAL_3D_SOUND
add_providers();
#endif
m_szCDRomRootPath[0] = '\0';
@ -1270,6 +1292,7 @@ cSampleManager::Initialise(void)
{
_bSampmanInitialised = TRUE;
#ifdef EXTERNAL_3D_SOUND
U32 n = 0;
while ( n < m_nNumberOfProviders )
@ -1287,6 +1310,7 @@ cSampleManager::Initialise(void)
Terminate();
return FALSE;
}
#endif
}
// mp3
@ -1322,7 +1346,7 @@ cSampleManager::Initialise(void)
int32 randval;
if ( bUseRandomTable )
randval = AudioManager.GetRandomNumber(1);
randval = AudioManager.m_anRandomTable[1];
else
randval = localtm->tm_sec * localtm->tm_min;
@ -1333,7 +1357,7 @@ cSampleManager::Initialise(void)
randmp3 = randmp3->pNext;
if ( bUseRandomTable )
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
_CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
else
{
if ( localtm->tm_sec > 0 )
@ -1342,7 +1366,7 @@ cSampleManager::Initialise(void)
_CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
}
else
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
_CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
}
}
else
@ -1378,7 +1402,9 @@ cSampleManager::Terminate(void)
}
}
#ifdef EXTERNAL_3D_SOUND
release_existing();
#endif
_DeleteMP3Entries();
@ -1410,6 +1436,7 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
{
#if !defined(NO_CDCHECK) // TODO: check steam, probably GTAVC_STEAM_PATCH needs to be added
char filepath[MAX_PATH];
FILE *f;
strcpy(filepath, m_MiscomPath);
strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]);
@ -1453,6 +1480,7 @@ cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuff
{
for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
{
#ifdef EXTERNAL_3D_SOUND
if ( i < MAXCHANNELS )
{
if ( opened_samples[i] && GetChannelUsedFlag(i) )
@ -1465,6 +1493,7 @@ cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuff
}
}
else
#endif
{
if ( opened_2dsamples[i - MAXCHANNELS] )
{
@ -1668,27 +1697,30 @@ cSampleManager::GetSampleLength(uint32 nSample)
bool8
cSampleManager::UpdateReverb(void)
{
#ifdef EXTERNAL_3D_SOUND
if ( !usingEAX )
return FALSE;
if ( AudioManager.GetFrameCounter() & 15 )
if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
float fRatio = 0.0f;
#ifdef AUDIO_REFLECTIONS
#define MIN_DIST 0.5f
#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0)
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_NORTH], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_SOUTH], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_WEST], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_EAST], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_NORTH] + AudioManager.m_afReflectionsDistances[REFLECTION_SOUTH]) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_WEST] + AudioManager.m_afReflectionsDistances[REFLECTION_EAST]) / 2.f, 4.0f, 1/3.f);
#undef CALCULATE_RATIO
#undef MIN_DIST
#endif
fRatio = Clamp(fRatio, 0.0f, 0.6f);
@ -1716,11 +1748,14 @@ cSampleManager::UpdateReverb(void)
_fPrevEaxRatioDestination = fRatio;
return TRUE;
#endif
return FALSE;
}
void
cSampleManager::SetChannelReverbFlag(uint32 nChannel, bool8 nReverbFlag)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1745,11 +1780,13 @@ cSampleManager::SetChannelReverbFlag(uint32 nChannel, bool8 nReverbFlag)
AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f);
}
}
#endif
}
bool8
cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1760,6 +1797,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
break;
}
}
#endif
int32 addr;
@ -1780,8 +1818,10 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
addr = nPedSlotSfxAddr[slot];
}
#ifdef EXTERNAL_3D_SOUND
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
{
AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize);
@ -1789,6 +1829,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
}
else
return FALSE;
#ifdef EXTERNAL_3D_SOUND
}
else
{
@ -1809,8 +1850,10 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
return TRUE;
}
#endif
}
#ifdef EXTERNAL_3D_SOUND
void
cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
{
@ -1845,6 +1888,7 @@ cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
if ( opened_samples[nChannel] )
AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin);
}
#endif
void
cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
@ -1852,10 +1896,12 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
uint32 vol = nVolume;
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
#ifdef EXTERNAL_3D_SOUND
switch ( nChannel )
{
case CHANNEL_POLICE_RADIO:
{
#endif
nChannelVolume[nChannel] = vol;
// increase the volume for JB.MP3 and S4_BDBD.MP3
@ -1871,33 +1917,40 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
}
#ifdef EXTERNAL_3D_SOUND
break;
}
}
#endif
}
void
cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
{
#ifdef EXTERNAL_3D_SOUND
switch ( nChannel )
{
case CHANNEL_POLICE_RADIO:
{
#ifndef FIX_BUGS
#endif
#if !defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG
#else
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
#endif
AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan);
#ifdef EXTERNAL_3D_SOUND
break;
}
}
#endif
}
void
cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1911,19 +1964,23 @@ cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq);
#ifdef EXTERNAL_3D_SOUND
}
else
{
if ( opened_samples[nChannel] )
AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq);
}
#endif
}
void
cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1937,19 +1994,23 @@ cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 n
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd);
#ifdef EXTERNAL_3D_SOUND
}
else
{
if ( opened_samples[nChannel] )
AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd);
}
#endif
}
void
cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1963,19 +2024,23 @@ cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount);
#ifdef EXTERNAL_3D_SOUND
}
else
{
if ( opened_samples[nChannel] )
AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount);
}
#endif
}
bool8
cSampleManager::GetChannelUsedFlag(uint32 nChannel)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -1989,10 +2054,12 @@ cSampleManager::GetChannelUsedFlag(uint32 nChannel)
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING;
else
return FALSE;
#ifdef EXTERNAL_3D_SOUND
}
else
{
@ -2001,12 +2068,14 @@ cSampleManager::GetChannelUsedFlag(uint32 nChannel)
else
return FALSE;
}
#endif
}
void
cSampleManager::StartChannel(uint32 nChannel)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -2020,19 +2089,23 @@ cSampleManager::StartChannel(uint32 nChannel)
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
#ifdef EXTERNAL_3D_SOUND
}
else
{
if ( opened_samples[nChannel] )
AIL_start_3D_sample(opened_samples[nChannel]);
}
#endif
}
void
cSampleManager::StopChannel(uint32 nChannel)
{
#ifdef EXTERNAL_3D_SOUND
bool8 b2d = FALSE;
switch ( nChannel )
@ -2046,8 +2119,10 @@ cSampleManager::StopChannel(uint32 nChannel)
if ( b2d )
{
#endif
if ( opened_2dsamples[nChannel - MAXCHANNELS] )
AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
#ifdef EXTERNAL_3D_SOUND
}
else
{
@ -2057,6 +2132,7 @@ cSampleManager::StopChannel(uint32 nChannel)
AIL_end_3D_sample(opened_samples[nChannel]);
}
}
#endif
}
void
@ -2122,7 +2198,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
bool8
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
int i = 0;
uint32 i = 0;
uint32 position = nPos;
char filename[MAX_PATH];
@ -2204,7 +2280,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
if ( !_pMP3List )
{
nFile = 0;
_bIsMp3Active = 0;
_bIsMp3Active = FALSE;
#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_MiscomPath);
strcat(filename, PS2StreamedNameTable[nFile]);
@ -2253,7 +2329,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
}
}
_bIsMp3Active = 0;
_bIsMp3Active = FALSE;
}
while ( ++i < nNumMP3s );
position = 0;

View File

@ -19,6 +19,7 @@ cSampleManager::~cSampleManager(void)
}
#ifdef EXTERNAL_3D_SOUND
void cSampleManager::SetSpeakerConfig(int32 nConfig)
{
@ -59,6 +60,7 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
{
return 0;
}
#endif
bool8
cSampleManager::IsMP3RadioChannelAvailable(void)
@ -228,6 +230,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
return FALSE;
}
#ifdef EXTERNAL_3D_SOUND
void
cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
{
@ -248,6 +251,7 @@ cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
#endif
void
cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)

View File

@ -944,8 +944,7 @@ cSampleManager::Initialise(void)
aStream[0]->Close();
nStreamLength[i] = tatalms;
}
else
} else
USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
}
#ifdef AUDIO_CACHE
@ -1041,7 +1040,7 @@ cSampleManager::Initialise(void)
int32 randval;
if ( bUseRandomTable )
randval = AudioManager.GetRandomNumber(1);
randval = AudioManager.m_anRandomTable[1];
else
randval = localtm->tm_sec * localtm->tm_min;
@ -1052,7 +1051,7 @@ cSampleManager::Initialise(void)
randmp3 = randmp3->pNext;
if ( bUseRandomTable )
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
_CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
else
{
if ( localtm->tm_sec > 0 )
@ -1061,7 +1060,7 @@ cSampleManager::Initialise(void)
_CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
}
else
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
_CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
}
}
else
@ -1404,24 +1403,26 @@ bool8 cSampleManager::UpdateReverb(void)
if ( !usingEAX && !_usingEFX )
return FALSE;
if ( AudioManager.GetFrameCounter() & 15 )
if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
float fRatio = 0.0f;
#ifdef AUDIO_REFLECTIONS
#define MIN_DIST 0.5f
#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0)
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_NORTH], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_SOUTH], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_WEST], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_EAST], 10.0f, 1/2.f);
fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_NORTH] + AudioManager.m_afReflectionsDistances[REFLECTION_SOUTH]) / 2.f, 4.0f, 1/3.f);
fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_WEST] + AudioManager.m_afReflectionsDistances[REFLECTION_EAST]) / 2.f, 4.0f, 1/3.f);
#undef CALCULATE_RATIO
#undef MIN_DIST
#endif
fRatio = Clamp(fRatio, 0.0f, 0.6f);
@ -1697,7 +1698,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
bool8
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
int i = 0;
uint32 i = 0;
uint32 position = nPos;
char filename[MAX_PATH];
@ -1776,7 +1777,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
if ( !_pMP3List )
{
nFile = 0;
_bIsMp3Active = 0;
_bIsMp3Active = FALSE;
CStream *stream = aStream[nStream];
#ifdef PS2_AUDIO_PATHS
@ -1819,7 +1820,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
}
}
_bIsMp3Active = 0;
_bIsMp3Active = FALSE;
}
while ( ++i < nNumMP3s );
position = 0;

View File

@ -101,7 +101,7 @@ GetCollisionInSectorList(CPtrList &list)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
level = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel()->level;
level = CModelInfo::GetColModel(e->GetModelIndex())->level;
if(level != LEVEL_GENERIC)
return (eLevelName)level;
}

View File

@ -584,8 +584,18 @@ void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle)
{
if (pVehicle->pDriver){
pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
if (pVehicle->GetModelIndex() == MI_AMBULAN)
switch (pVehicle->GetModelIndex()) {
case MI_FIRETRUCK:
case MI_FBICAR:
case MI_ENFORCER:
case MI_BARRACKS:
case MI_RHINO:
case MI_POLICE:
break;
case MI_AMBULAN:
pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
break;
}
}
int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){
@ -601,8 +611,18 @@ void CCarAI::TellOccupantsToFleeCar(CVehicle* pVehicle)
{
if (pVehicle->pDriver && !pVehicle->pDriver->IsPlayer()) {
pVehicle->pDriver->SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
if (pVehicle->GetModelIndex() != MI_FIRETRUCK && pVehicle->GetModelIndex() == MI_AMBULAN)
switch (pVehicle->GetModelIndex()) {
case MI_FIRETRUCK:
case MI_FBIRANCH:
case MI_ENFORCER:
case MI_BARRACKS:
case MI_RHINO:
case MI_POLICE:
break;
case MI_AMBULAN:
pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
break;
}
}
int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {

View File

@ -94,7 +94,7 @@ int32 CCarCtrl::NumRandomCars;
int32 CCarCtrl::NumParkedCars;
int32 CCarCtrl::NumPermanentCars;
int8 CCarCtrl::CountDownToCarsAtStart;
int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
int32 CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS;
uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 CCarCtrl::LastTimeAmbulanceCreated;
@ -400,7 +400,7 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->m_bSirenOrAlarm = true;
pVehicle->AutoPilot.m_nNextPathNodeInfo = connectionId;
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = CGeneral::GetRandomNumber() % lanesOnCurrentRoad;
CBox* boundingBox = &CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel()->boundingBox;
CBox* boundingBox = &CModelInfo::GetColModel(pVehicle->GetModelIndex())->boundingBox;
float carLength = 1.0f + (boundingBox->max.y - boundingBox->min.y) / 2;
float distanceBetweenNodes = (pCurNode->GetPosition() - pNextNode->GetPosition()).Magnitude2D();
/* If car is so long that it doesn't fit between two car nodes, place it directly in the middle. */
@ -964,6 +964,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
}
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
float threshold = OFFSCREEN_DESPAWN_RANGE;
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (pVehicle->GetIsOnScreen() ||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
@ -975,11 +976,15 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
pVehicle->bIsLawEnforcer ||
pVehicle->bIsCarParkVehicle ||
CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime
){
)
#endif
{
threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier;
}
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (TheCamera.GetForward().z < -0.9f)
threshold = 70.0f;
#endif
if (pVehicle->bExtendedRange)
threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER;
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
@ -1554,7 +1559,7 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
continue;
if (Abs(pTestVehicle->GetPosition().z - pVehicle->GetPosition().z) >= VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING)
continue;
if (pTestVehicle != pVehicle)
if (pTestVehicle != pVehicle && (!pVehicle->bPartOfConvoy || !pTestVehicle->bPartOfConvoy))
WeaveForOtherCar(pTestVehicle, pVehicle, pAngleToWeaveLeft, pAngleToWeaveRight);
}
}
@ -1562,8 +1567,6 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
{
CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
if (pVehicle->bPartOfConvoy && pOtherCar->bPartOfConvoy)
return;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle())
return;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar)

View File

@ -19,17 +19,27 @@ void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVe
float actualFactor = CalcSpeedScaleFactor(pPos1, pPos2, pDir1->x, pDir1->y, pDir2->x, pDir2->y);
CVector2D dir1 = *pDir1 * actualFactor;
CVector2D dir2 = *pDir2 * actualFactor;
float t1 = Abs(DotProduct2D(*pPos1 - *pPos2, *pDir1));
float t2 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir2));
float t1 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir1));
float t2 = Abs(DotProduct2D(*pPos1 - *pPos2, *pDir2));
float curveCoef;
if (t1 > t2) {
if (between < (t1 - t2) / (t1 + t2))
float coef = (t1 - t2) / (t1 + t2);
#ifdef FIX_BUGS
if (between <= coef)
#else
if (between < coef)
#endif
curveCoef = 0.0f;
else
curveCoef = 0.5f - 0.5f * Cos(3.1415f * (t1 + t2) / (2 * t2) * (between - (t1 - t2) / (t1 + t2)));
curveCoef = 0.5f - 0.5f * Cos(3.1415f * (between - coef) * (t1 + t2) / (2 * t2));
}
else {
if (2 * t1 / (t1 + t2) < between)
float coef = 2 * t1 / (t1 + t2);
#ifdef FIX_BUGS
if (coef <= between)
#else
if (coef < between)
#endif
curveCoef = 1.0f;
else
curveCoef = 0.5f - 0.5f * Cos(3.1415f * between * (t1 + t2) / (2 * t1));

View File

@ -102,6 +102,15 @@ CGameLogic::Update()
CVector vecRestartPos;
float fRestartFloat;
#ifdef MISSION_REPLAY
// what a place to check!
if (gbTryingPorn4Again) {
CRunningScript* pScript = CTheScripts::pActiveScripts;
if (pScript && !CGeneral::faststricmp(pScript->m_abScriptName, "porno4"))
gbTryingPorn4Again = false;
}
#endif
if (CCutsceneMgr::IsCutsceneProcessing()) return;
UpdateShortCut();

View File

@ -1986,7 +1986,7 @@ void CGarages::GivePlayerDetonator()
float CGarages::FindDoorHeightForMI(int32 mi)
{
return CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.max.z - CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.min.z - 0.1f;
return CModelInfo::GetColModel(mi)->boundingBox.max.z - CModelInfo::GetColModel(mi)->boundingBox.min.z - 0.1f;
}
void CGarage::TidyUpGarage()

View File

@ -23,6 +23,7 @@
#ifdef FIX_BUGS
#include "Replay.h"
#endif
#include "SaveBuf.h"
#include "Script.h"
#include "Shadows.h"
#include "SpecialFX.h"

View File

@ -1,6 +1,7 @@
#include "common.h"
#include "Restart.h"
#include "SaveBuf.h"
#include "Zones.h"
#include "PathFind.h"
#include "SaveBuf.h"

View File

@ -60,7 +60,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle();
if (!pEntityToAttack)
pEntityToAttack = (CEntity*)FindPlayerPed();
CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel();
CColModel* pPoliceColModel = CModelInfo::GetColModel(MI_POLICE);
float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
for (int32 i = 0; i < 2; i++) {
const int32 roadBlockIndex = i + 2 * roadBlockType;
@ -217,7 +217,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
vehicleId = MI_ENFORCER;
if (!CStreaming::HasModelLoaded(vehicleId))
vehicleId = MI_POLICE;
CColModel* pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel();
CColModel *pVehicleColModel = CModelInfo::GetColModel(vehicleId);
float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
int16 numRoadblockVehicles = Min(6, (int16)(distBetween / fModelRadius));
for (int16 i = 0; i < numRoadblockVehicles; i++) {
@ -231,7 +231,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + 3.1416f);
tmp.SetTranslateOnly(offset * forward + pos);
tmp.GetPosition().z += 0.6f;
float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f;
float fModelRadius = CModelInfo::GetColModel(vehicleId)->boundingSphere.radius - 0.25f;
int16 colliding = 0;
CWorld::FindObjectsKindaColliding(tmp.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
if (!colliding) {

File diff suppressed because it is too large Load Diff

View File

@ -372,6 +372,13 @@ public:
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
int CollectParameterForDebug(char* buf, bool& var);
void GetStoredParameterForDebug(char* buf);
void LogOnStartProcessing();
void LogBeforeProcessingCommand(int32 command);
void LogAfterProcessingCommand(int32 command);
static char commandInfo[];
static uint32 storedIp;
#endif
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
@ -575,13 +582,26 @@ public:
static void SetObjectiveForAllPedsInCollective(int, eObjective);
#endif
};
#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
static bool MissionSupportsMissionReplay(int index)
{
return index >= 3 && index <= 35 || index >= 51 && index <= 65 || index >= 67 && index <= 74 || index >= 83 && index <= 87;
}
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
extern int scriptToLoad;
static int ScriptToLoad;
static int OpenScript();
#endif
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
static void LogAfterScriptInitializing();
static void LogBeforeScriptProcessing();
static void LogAfterScriptProcessing();
#endif
};
#ifdef MISSION_REPLAY
static_assert(false, "Mission replay is not supported");
extern int AllowMissionReplay;
extern uint32 WaitForMissionActivate;
extern uint32 WaitForSave;
@ -592,10 +612,28 @@ extern bool gbTryingPorn4Again;
extern int IsInAmmunation;
extern int MissionSkipLevel;
uint32 AddExtraDeathDelay();
void RetryMission(int, int);
#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
extern bool UsingMobileScript;
extern bool AlreadySavedGame;
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
extern int scriptToLoad;
uint32 AddExtraDeathDelay();
void RetryMission(int, int unk = 0);
enum {
MISSION_RETRY_TYPE_SUGGEST_TO_PLAYER = 0,
MISSION_RETRY_TYPE_1,
MISSION_RETRY_TYPE_BEGIN_RESTARTING
};
enum {
MISSION_RETRY_STAGE_NORMAL = 0,
MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE,
MISSION_RETRY_STAGE_START_PROCESSING,
MISSION_RETRY_STAGE_WAIT_FOR_DELAY,
MISSION_RETRY_STAGE_WAIT_FOR_MENU,
MISSION_RETRY_STAGE_WAIT_FOR_USER,
MISSION_RETRY_STAGE_START_RESTARTING,
MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART,
};
#endif

View File

@ -149,7 +149,12 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
case COMMAND_ADD_EXPLOSION:
CollectParameters(&m_nIp, 4);
CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
#ifdef SIMPLER_MISSIONS
if (!CGeneral::faststricmp(m_abScriptName, "hait2"))
CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true, 11.25f);
else
#endif
CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
return 0;
case COMMAND_IS_CAR_UPRIGHT:

View File

@ -12,6 +12,7 @@
#include "Pools.h"
#include "Population.h"
#include "RpAnimBlend.h"
#include "SaveBuf.h"
#include "Shadows.h"
#include "SpecialFX.h"
#include "World.h"
@ -1379,10 +1380,12 @@ void CRunningScript::DoDeatharrestCheck()
if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest())
return;
#ifdef MISSION_REPLAY
if (AllowMissionReplay != 0)
if (AllowMissionReplay != MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART && AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
return;
if (AllowMissionReplay == MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART)
AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
if (CanAllowMissionReplay())
AllowMissionReplay = 1;
AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE;
#endif
script_assert(m_nStackPointer > 0);
while (m_nStackPointer > 1)

View File

@ -125,10 +125,6 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
{
CollectParameters(&m_nIp, 1);
#ifdef MISSION_REPLAY
AllowMissionReplay = 0;
SaveGameForPause(3);
#endif
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
pPlayerInfo->MakePlayerSafe(true);
@ -372,21 +368,33 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
return 0;
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{
#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
uint32 oldIp = m_nIp;
#endif
CollectParameters(&m_nIp, 1);
if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
return 0;
#ifdef MISSION_REPLAY
missionRetryScriptIndex = ScriptParams[0];
if (missionRetryScriptIndex == 19)
CStats::LastMissionPassedName[0] = '\0';
#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
if (!UsingMobileScript && CTheScripts::MissionSupportsMissionReplay(missionRetryScriptIndex)){
if (!AlreadySavedGame) {
m_nIp = oldIp - 2;
SaveGameForPause(SAVE_TYPE_QUICKSAVE_FOR_SCRIPT);
AlreadySavedGame = true;
return 0;
}
else {
AlreadySavedGame = false;
}
}
#endif
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
#ifdef USE_DEBUG_SCRIPT_LOADER
CFileMgr::ChangeDir("\\data\\");
int handle = CFileMgr::OpenFile(scriptfile, "rb");
CFileMgr::ChangeDir("\\");
int handle = CTheScripts::OpenScript();
#else
CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
@ -1075,6 +1083,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
case COMMAND_FAIL_CURRENT_MISSION:
CTheScripts::FailCurrentMission = 2;
#ifdef MISSION_REPLAY
MissionSkipLevel = 0;
#endif
return 0;
case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE:
{

View File

@ -576,6 +576,9 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
return 0;
case COMMAND_DO_SAVE_GAME:
CollectParameters(&m_nIp, 1);
#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
UsingMobileScript = true;
#endif
#ifdef MISSION_REPLAY
SaveGameForPause(ScriptParams[0]);
#endif

View File

@ -293,7 +293,11 @@ enum {
COMMAND_IS_PLAYER_IN_ZONE,
COMMAND_IS_PLAYER_PRESSING_HORN,
COMMAND_HAS_CHAR_SPOTTED_PLAYER,
#ifdef SUPPORT_GINPUT_SCRIPT
COMMAND_HAS_PAD_IN_HANDS,
#else
COMMAND_ORDER_CHAR_TO_BACKDOOR,
#endif
COMMAND_ADD_CHAR_TO_GANG,
COMMAND_IS_CHAR_OBJECTIVE_PASSED,
COMMAND_SET_CHAR_DRIVE_AGGRESSION,

1765
src/control/ScriptDebug.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -277,7 +277,7 @@ CTrafficLights::DisplayActualLight(CEntity *ent)
12.0f, 1.0f, 40.0f, false, 0.0f);
if (id >= 0) {
if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
if (DotProduct(TheCamera.GetForward(), ent->GetForward()) > 0.0f)
CCoronas::RegisterCorona((uintptr)ent + id,
r * CTimeCycle::GetSpriteBrightness() * 0.7f,
g * CTimeCycle::GetSpriteBrightness() * 0.7f,

View File

@ -226,7 +226,7 @@ CCam::Process(void)
break;
case MODE_CAM_ON_A_STRING:
#ifdef FREE_CAM
if(CCamera::bFreeCam)
if(CCamera::bFreeCam && !CVehicle::bCheat5)
Process_FollowCar_SA(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
else
#endif

View File

@ -2708,6 +2708,14 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
#undef PS2_CROSS
#undef PS2_SQUARE
const char *NintendoSwitchButtons_noIcons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS("Y", "A", "B", "X", "L", "ZL", "LS", "R", "ZR", "RS", "BACK", "right stick up", "right stick down", "right stick left", "right stick right");
#ifdef BUTTON_ICONS
const char *NintendoSwitchButtons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK", "~H~", "~L~", "~(~", "~)~");
#endif
#undef UP
#undef DOWN
#undef LEFT
@ -2733,6 +2741,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons;
break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = CFont::ButtonsSlot != -1 ? NintendoSwitchButtons : NintendoSwitchButtons_noIcons;
break;
default:
#endif
Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
@ -2748,6 +2759,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = PlayStationButtons_noIcons;
break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = NintendoSwitchButtons_noIcons;
break;
default:
Buttons = XboxButtons_noIcons;
break;

View File

@ -208,6 +208,7 @@ wchar* CMenuManager::m_pDialogText = nil;
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \
CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
// value must be between 0.0-1.0
#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \
do { \
float y = origY MINUS_SCROLL_OFFSET; \
@ -346,7 +347,7 @@ CMenuManager::ThingsToDoBeforeLeavingPage()
option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue)
option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
option.m_CFOSelect->displayedValue = *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
if (aScreens[m_nCurrScreen].returnPrevPageFunc) {
aScreens[m_nCurrScreen].returnPrevPageFunc();
@ -543,8 +544,16 @@ CMenuManager::CMenuManager()
#endif
#ifdef GAMEPAD_MENU
#ifdef __SWITCH__
m_PrefsControllerType = CONTROLLER_NINTENDO_SWITCH;
#else
m_PrefsControllerType = CONTROLLER_XBOXONE;
#endif
#endif
#ifdef MISSION_REPLAY
m_bAttemptingMissionRetry = false;
#endif
}
void
@ -570,13 +579,27 @@ CMenuManager::Initialise(void)
m_nCurrOption = 0;
m_nOptionHighlightTransitionBlend = 0;
CentreMousePointer();
#ifdef GTA_HANDHELD
m_bShowMouse = false;
#else
m_bShowMouse = true;
#endif
m_fMapSize = MENU_Y(162.0f); // Y because of HOR+
m_fMapCenterX = MENU_X_LEFT_ALIGNED(320.0f);
m_fMapCenterY = MENU_Y(225.0f);
CPad::StopPadsShaking();
#ifdef MISSION_REPLAY
if (!m_OnlySaveMenu) {
if (m_nCurrScreen == MENUPAGE_MISSION_RETRY && m_bAttemptingMissionRetry)
m_bAttemptingMissionRetry = false;
else
m_nCurrScreen = MENUPAGE_NONE;
}
#else
if (!m_OnlySaveMenu)
m_nCurrScreen = MENUPAGE_NONE;
#endif
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
DMAudio.Service();
@ -700,27 +723,33 @@ CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
#ifdef FIX_BUGS
m_PrefsBrightness += value * (384 / MENUSLIDER_LOGICAL_BARS);
#else
m_PrefsBrightness += value * 24.19f;
#endif
m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 384);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
m_PrefsLOD += ((1.8f - 0.925f) / 16.0f);
m_PrefsLOD += ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
else
m_PrefsLOD -= ((1.8f - 0.925f) / 16.0f);
m_PrefsLOD -= ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = Clamp(m_PrefsLOD, 0.925f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
// I wonder the idea behind clamping those max to 65
case MENUACTION_MUSICVOLUME:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_PrefsMusicVolume += value * (128 / 32);
m_PrefsMusicVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 65);
DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
}
break;
case MENUACTION_SFXVOLUME:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_PrefsSfxVolume += value * (128 / 32);
m_PrefsSfxVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 65);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
}
@ -728,19 +757,33 @@ CMenuManager::CheckSliderMovement(int value)
case MENUACTION_MP3VOLUMEBOOST:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
if (DMAudio.IsMP3RadioChannelAvailable()) {
m_PrefsMP3BoostVolume += value * (128 / 32);
m_PrefsMP3BoostVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
m_PrefsMP3BoostVolume = Clamp(m_PrefsMP3BoostVolume, 0, 65);
DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
}
}
break;
case MENUACTION_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ???
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
#endif
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
case MENUACTION_CFO_SLIDER:
{
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
float oldValue = *(float*)option.m_CFOSlider->value;
*(float*)option.m_CFOSlider->value += value * ((option.m_CFOSlider->max - option.m_CFOSlider->min) / MENUSLIDER_LOGICAL_BARS);
*(float*)option.m_CFOSlider->value = Clamp(*(float*)option.m_CFOSlider->value, option.m_CFOSlider->min, option.m_CFOSlider->max);
if (*(float*)option.m_CFOSlider->value != oldValue && option.m_CFOSlider->changeFunc)
option.m_CFOSlider->changeFunc(oldValue, *(float*)option.m_CFOSlider->value);
break;
}
#endif
default:
return;
}
@ -852,10 +895,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
int lastActiveBarX = 0;
float curBarX = 0.0f;
for (int i = 0; i < 16; i++) {
curBarX = i * rectSize/16.0f + x;
for (int i = 0; i < MENUSLIDER_BARS; i++) {
curBarX = i * rectSize/MENUSLIDER_BARS + x;
if (i / 16.0f + 1 / 32.0f < progress) {
if (i / (float)MENUSLIDER_BARS + 1 / (MENUSLIDER_BARS * 2.f) < progress) {
color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255));
lastActiveBarX = curBarX;
} else
@ -863,7 +906,7 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
maxBarHeight = Max(mostLeftBarSize, mostRightBarSize);
float curBarFreeSpace = ((16 - i) * mostLeftBarSize + i * mostRightBarSize) / 16.0f;
float curBarFreeSpace = ((MENUSLIDER_BARS - i) * mostLeftBarSize + i * mostRightBarSize) / (float)MENUSLIDER_BARS;
float left = curBarX;
float top = y + maxBarHeight - curBarFreeSpace;
float right = spacing + curBarX;
@ -1328,8 +1371,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
// To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions)
if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
if (*(int8*)option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
@ -1379,7 +1422,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
int saveSlot = aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot;
if (rightText || action == MENUACTION_DRAWDIST || action == MENUACTION_BRIGHTNESS || action == MENUACTION_MUSICVOLUME ||
action == MENUACTION_SFXVOLUME || action == MENUACTION_MP3VOLUMEBOOST || action == MENUACTION_MOUSESENS ||
saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) {
saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8
#ifdef CUSTOM_FRONTEND_OPTIONS
|| action == MENUACTION_CFO_SLIDER
#endif
) {
rightXMin = 600;
leftXMax = 40;
}
@ -1506,30 +1553,41 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
}
#ifdef CUSTOM_FRONTEND_OPTIONS
#define SLIDER_Y(pos) (aScreens[m_nCurrScreen].m_aEntries[i].m_Y - 5.f)
#else
#define SLIDER_Y(pos) pos
#endif
// Sliders
int lastActiveBarX;
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
case MENUACTION_BRIGHTNESS:
ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true);
ProcessSlider(m_PrefsBrightness / 384.0f, SLIDER_Y(70.0f), HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true);
break;
case MENUACTION_DRAWDIST:
ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true);
ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, SLIDER_Y(99.0f), HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true);
break;
case MENUACTION_MUSICVOLUME:
if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, SCREEN_WIDTH, true);
ProcessSlider(m_PrefsMusicVolume / 64.0f, SLIDER_Y(70.0f), HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, SCREEN_WIDTH, true);
break;
case MENUACTION_SFXVOLUME:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true);
ProcessSlider(m_PrefsSfxVolume / 64.0f, SLIDER_Y(99.0f), HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true);
break;
case MENUACTION_MOUSESENS:
ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, SCREEN_WIDTH, false);
ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, SLIDER_Y(170.0f), HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, SCREEN_WIDTH, false);
break;
case MENUACTION_MP3VOLUMEBOOST:
if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER && DMAudio.IsMP3RadioChannelAvailable())
ProcessSlider(m_PrefsMP3BoostVolume / 64.f, 128.0f, HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true);
ProcessSlider(m_PrefsMP3BoostVolume / 64.f, SLIDER_Y(128.0f), HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true);
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
case MENUACTION_CFO_SLIDER:
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
ProcessSlider((*(float*)option.m_CFOSlider->value - option.m_CFOSlider->min) / (option.m_CFOSlider->max - option.m_CFOSlider->min), SLIDER_Y(0), HOVEROPTION_INCREASE_CFO_SLIDER, HOVEROPTION_DECREASE_CFO_SLIDER, SCREEN_WIDTH, true);
break;
#endif
}
// Not just unused, but also collides with the bug fix in Font.cpp. Yikes.
@ -3126,9 +3184,6 @@ CMenuManager::LoadSettings()
if (LoadINISettings()) {
LoadINIControllerSettings();
}
// if no reVC.ini, create it, or update it with new values
SaveINISettings();
SaveINIControllerSettings();
#endif
#ifdef FIX_BUGS
@ -4278,7 +4333,11 @@ CMenuManager::UserInput(void)
int action = aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action;
if (action != MENUACTION_BRIGHTNESS && action != MENUACTION_DRAWDIST && action != MENUACTION_MUSICVOLUME
&& action != MENUACTION_SFXVOLUME && action != MENUACTION_MOUSESENS && action != MENUACTION_MP3VOLUMEBOOST)
&& action != MENUACTION_SFXVOLUME && action != MENUACTION_MOUSESENS && action != MENUACTION_MP3VOLUMEBOOST
#ifdef CUSTOM_FRONTEND_OPTIONS
&& action != MENUACTION_CFO_SLIDER
#endif
)
m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
break;
@ -4358,6 +4417,9 @@ CMenuManager::UserInput(void)
case HOVEROPTION_INCREASE_MUSICVOLUME:
case HOVEROPTION_INCREASE_SFXVOLUME:
case HOVEROPTION_INCREASE_MOUSESENS:
#ifdef CUSTOM_FRONTEND_OPTIONS
case HOVEROPTION_INCREASE_CFO_SLIDER:
#endif
CheckSliderMovement(1);
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
@ -4366,6 +4428,9 @@ CMenuManager::UserInput(void)
case HOVEROPTION_DECREASE_MUSICVOLUME:
case HOVEROPTION_DECREASE_SFXVOLUME:
case HOVEROPTION_DECREASE_MOUSESENS:
#ifdef CUSTOM_FRONTEND_OPTIONS
case HOVEROPTION_DECREASE_CFO_SLIDER:
#endif
CheckSliderMovement(-1);
break;
}
@ -4397,7 +4462,11 @@ CMenuManager::UserInput(void)
|| CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp()
|| CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
if (option == MENUACTION_BRIGHTNESS)
if (option == MENUACTION_BRIGHTNESS
#ifdef CUSTOM_FRONTEND_OPTIONS
|| option == MENUACTION_CFO_SLIDER
#endif
)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
@ -4408,7 +4477,11 @@ CMenuManager::UserInput(void)
if (CPad::GetPad(0)->GetBackJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) {
if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU && m_nCurrScreen != MENUPAGE_CHOOSE_SAVE_SLOT
&& m_nCurrScreen != MENUPAGE_SAVE_CHEAT_WARNING && m_nCurrScreen != MENUPAGE_SAVING_IN_PROGRESS
&& m_nCurrScreen != MENUPAGE_DELETING_IN_PROGRESS && m_nCurrScreen != MENUPAGE_OUTRO)
&& m_nCurrScreen != MENUPAGE_DELETING_IN_PROGRESS && m_nCurrScreen != MENUPAGE_OUTRO
#ifdef MISSION_REPLAY
&& m_nCurrScreen != MENUPAGE_MISSION_RETRY
#endif
)
{
m_bShowMouse = false;
goBack = true;
@ -4428,7 +4501,11 @@ CMenuManager::UserInput(void)
if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
curAction == MENUACTION_MP3VOLUMEBOOST)
curAction == MENUACTION_MP3VOLUMEBOOST
#ifdef CUSTOM_FRONTEND_OPTIONS
|| curAction == MENUACTION_CFO_SLIDER
#endif
)
changeValueBy = -1;
lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
@ -4439,7 +4516,11 @@ CMenuManager::UserInput(void)
if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
curAction == MENUACTION_MP3VOLUMEBOOST)
curAction == MENUACTION_MP3VOLUMEBOOST
#ifdef CUSTOM_FRONTEND_OPTIONS
|| curAction == MENUACTION_CFO_SLIDER
#endif
)
changeValueBy = 1;
lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
}
@ -4498,10 +4579,10 @@ CMenuManager::UserInput(void)
if (oldEntry.m_CFOSelect->displayedValue != oldEntry.m_CFOSelect->lastSavedValue)
SetHelperText(3); // Restored original value
oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *oldEntry.m_CFO->value;
oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *(int8*)oldEntry.m_CFO->value;
}
} else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) {
if (oldEntry.m_CFOSelect->displayedValue != *oldEntry.m_CFO->value)
if (oldEntry.m_CFOSelect->displayedValue != *(int8*)oldEntry.m_CFO->value)
SetHelperText(1); // Enter to apply
else if (m_nHelperTextMsgId == 1)
ResetHelperText(); // Applied
@ -4574,7 +4655,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
#ifdef USE_DEBUG_SCRIPT_LOADER
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
if (CPad::GetPad(0)->GetChar('R')) {
scriptToLoad = 1;
CTheScripts::ScriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
@ -4726,6 +4807,18 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
}
break;
#ifdef MISSION_REPLAY
case MENUACTION_REJECT_RETRY:
doingMissionRetry = false;
AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
RequestFrontEndShutDown();
break;
case MENUACTION_UNK114:
doingMissionRetry = false;
RequestFrontEndShutDown();
RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
return;
#endif
case MENUACTION_SAVEGAME:
{
int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
@ -4924,9 +5017,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
}
int8 oldValue = *option.m_CFO->value;
int8 oldValue = *(int8*)option.m_CFO->value;
*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
*(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
@ -5091,9 +5184,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1;
}
if (!option.m_CFOSelect->onlyApplyOnEnter) {
int8 oldValue = *option.m_CFO->value;
int8 oldValue = *(int8*)option.m_CFO->value;
*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
*(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
@ -5376,9 +5469,22 @@ CMenuManager::ProcessFileActions()
{
switch (m_nCurrScreen) {
case MENUPAGE_LOADING_IN_PROGRESS:
#ifdef MISSION_REPLAY
if (MissionSkipLevel) {
if (gGameState != GS_PLAYING_GAME)
DoSettingsBeforeStartingAGame();
RequestFrontEndShutDown();
break;
}
if (doingMissionRetry) {
RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
m_nCurrSaveSlot = SLOT_COUNT;
doingMissionRetry = false;
}
#endif
if (CheckSlotDataValid(m_nCurrSaveSlot)) {
#ifdef USE_DEBUG_SCRIPT_LOADER
scriptToLoad = 0;
CTheScripts::ScriptToLoad = 0;
#endif
#ifdef XBOX_MESSAGE_SCREEN
@ -5906,6 +6012,7 @@ const char* controllerTypesPaths[] = {
"MODELS/FRONTEND_DS4.TXD",
"MODELS/FRONTEND_X360.TXD",
"MODELS/FRONTEND_XONE.TXD",
"MODELS/FRONTEND_NSW.TXD",
};
void
@ -6016,6 +6123,18 @@ CMenuManager::PrintController(void)
TEXT_L2R2_Y += 5.0f;
TEXT_SELECT_X += 3.0f;
break;
case CONTROLLER_NINTENDO_SWITCH:
TEXT_L1_Y += 5.0f;
TEXT_L1_Y_VEH = TEXT_L1_Y;
TEXT_R1_Y += 5.0f;
TEXT_TRIANGLE_Y += 3.0f;
TEXT_CIRCLE_Y += 3.0f;
TEXT_CROSS_Y += 3.0f;
TEXT_LSTICK_Y -= 23.0f;
TEXT_DPAD_Y += 25.0;
TEXT_RSTICK_Y += 1.0f;
TEXT_R3_Y += 1.0f;
break;
};
if (m_DisplayControllerOnFoot) {
@ -6312,6 +6431,7 @@ CMenuManager::PrintController(void)
{
case CONTROLLER_XBOXONE:
case CONTROLLER_XBOX360:
case CONTROLLER_NINTENDO_SWITCH:
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
switch (m_PrefsLanguage)
{
@ -6392,6 +6512,7 @@ CMenuManager::PrintController(void)
{
case CONTROLLER_XBOXONE:
case CONTROLLER_XBOX360:
case CONTROLLER_NINTENDO_SWITCH:
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
switch (m_PrefsLanguage)
{
@ -6475,6 +6596,7 @@ CMenuManager::PrintController(void)
{
case CONTROLLER_XBOXONE:
case CONTROLLER_XBOX360:
case CONTROLLER_NINTENDO_SWITCH:
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
switch (m_PrefsLanguage)
{
@ -6559,6 +6681,7 @@ CMenuManager::PrintController(void)
{
case CONTROLLER_XBOXONE:
case CONTROLLER_XBOX360:
case CONTROLLER_NINTENDO_SWITCH:
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT"));
break;
@ -6601,6 +6724,9 @@ CMenuManager::LoadController(int8 type)
case CONTROLLER_DUALSHOCK4:
CFont::LoadButtons("MODELS/PS3BTNS.TXD");
break;
case CONTROLLER_NINTENDO_SWITCH:
CFont::LoadButtons("MODELS/NSWBTNS.TXD");
break;
default:
CFont::LoadButtons("MODELS/X360BTNS.TXD");
break;

View File

@ -15,6 +15,9 @@
#define MENUACTION_SCALE_MULT 0.9f
#define MENUSLIDER_BARS 16
#define MENUSLIDER_LOGICAL_BARS MENUSLIDER_BARS
#define MENULABEL_X_MARGIN 80.0f
#define MENULABEL_POS_X 100.0f
#define MENULABEL_POS_Y 97.0f
@ -26,9 +29,17 @@
#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f)
#define MENURADIO_ICON_FIRST_X 238.f
#ifdef EXTERNAL_3D_SOUND
#define MENURADIO_ICON_Y 288.0f
#else
#define MENURADIO_ICON_Y 248.0f
#endif
#define MENURADIO_ICON_SIZE 60.0f
#ifdef EXTERNAL_3D_SOUND
#define MENURADIO_SELECTOR_START_Y 285.f // other options should leave room on the screen
#else
#define MENURADIO_SELECTOR_START_Y 245.0f
#endif
#define MENURADIO_SELECTOR_HEIGHT 65.f
#define MENUSLIDER_X 500.0f
@ -218,8 +229,11 @@ enum eMenuScreen
#ifdef DETECT_JOYSTICK_MENU
MENUPAGE_DETECT_JOYSTICK,
#endif
#endif
#ifdef MISSION_REPLAY
MENUPAGE_MISSION_RETRY,
#endif
MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages
MENUPAGES
};
@ -227,6 +241,7 @@ enum eMenuScreen
enum eMenuAction
{
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_CFO_SLIDER = -3,
MENUACTION_CFO_SELECT = -2,
MENUACTION_CFO_DYNAMIC = -1,
#endif
@ -288,6 +303,10 @@ enum eMenuAction
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
#endif
#ifdef MISSION_REPLAY
MENUACTION_REJECT_RETRY,
MENUACTION_UNK114
#endif
};
enum eCheckHover
@ -328,6 +347,10 @@ enum eCheckHover
HOVEROPTION_DECREASE_MOUSESENS,
HOVEROPTION_INCREASE_MP3BOOST,
HOVEROPTION_DECREASE_MP3BOOST,
#ifdef CUSTOM_FRONTEND_OPTIONS
HOVEROPTION_INCREASE_CFO_SLIDER,
HOVEROPTION_DECREASE_CFO_SLIDER,
#endif
HOVEROPTION_NOT_HOVERING,
};
@ -400,7 +423,7 @@ struct CCustomScreenLayout {
struct CCFO
{
int8 *value;
void *value;
const char *saveCat;
const char *save;
};
@ -431,6 +454,24 @@ struct CCFOSelect : CCFO
}
};
// Value is float in here
struct CCFOSlider : CCFO
{
ChangeFuncFloat changeFunc;
float min;
float max;
CCFOSlider() {};
CCFOSlider(float* value, const char* saveCat, const char* save, float min, float max, ChangeFuncFloat changeFunc = nil){
this->value = value;
this->saveCat = saveCat;
this->save = save;
this->changeFunc = changeFunc;
this->min = min;
this->max = max;
}
};
struct CCFODynamic : CCFO
{
DrawFunc drawFunc;
@ -462,6 +503,7 @@ struct CMenuScreenCustom
CCFO *m_CFO; // for initializing
CCFOSelect *m_CFOSelect;
CCFODynamic *m_CFODynamic;
CCFOSlider *m_CFOSlider;
};
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
@ -680,6 +722,10 @@ public:
int8 m_nDisplayMSAALevel;
#endif
#ifdef MISSION_REPLAY
bool m_bAttemptingMissionRetry;
#endif
#ifdef GAMEPAD_MENU
enum
{
@ -688,6 +734,7 @@ public:
CONTROLLER_DUALSHOCK4,
CONTROLLER_XBOX360,
CONTROLLER_XBOXONE,
CONTROLLER_NINTENDO_SWITCH,
};
int8 m_PrefsControllerType;

View File

@ -792,12 +792,12 @@ TriggerAudio_StereoMono(CMenuMultiChoiceTriggered *widget)
{
if (widget->GetMenuSelection() == 1)
{
DMAudio.SetMonoMode(true);
DMAudio.SetMonoMode(TRUE);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MONO, 0);
}
else
{
DMAudio.SetMonoMode(false);
DMAudio.SetMonoMode(FALSE);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_STEREO, 0);
}
}

View File

@ -333,6 +333,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.Initialise();
#ifndef GTA_PS2
#ifdef EXTERNAL_3D_SOUND
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
@ -344,6 +345,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
DMAudio.SetSpeakerConfig(FrontEndMenuManager.m_PrefsSpeakers);
#endif
DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA);
DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume);
DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
@ -373,7 +375,11 @@ bool CGame::Initialise(const char* datFile)
CPools::Initialise();
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#ifdef PED_CAR_DENSITY_SLIDERS
// Load density values from gta3.ini only if our reVC.ini have them 0.6f
if (CIniFile::PedNumberMultiplier == 0.6f && CIniFile::CarNumberMultiplier == 0.6f)
#endif
CIniFile::LoadIniFile();
#endif
#ifdef USE_TEXTURE_POOL
_TexturePoolsUnknown(false);
@ -899,7 +905,13 @@ void CGame::Process(void)
CEventList::Update();
CParticle::Update();
gFireManager.Update();
// Otherwise even on 30 fps most probably you won't see any peds around Ocean View Hospital
#if defined FIX_BUGS && !defined SQUEEZE_PERFORMANCE
if (processTime > 2) {
#else
if (processTime >= 2) {
#endif
CPopulation::Update(false);
} else {
uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();

View File

@ -23,7 +23,7 @@ void CIniFile::LoadIniFile()
CarNumberMultiplier = Min(3.0f, Max(0.5f, CarNumberMultiplier));
CFileMgr::CloseFile(f);
}
CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier;
CPopulation::MaxNumberOfPedsInUseInterior = 40.0f * PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = 12.0f * CarNumberMultiplier;
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * PedNumberMultiplier;
CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CarNumberMultiplier;
}

View File

@ -1,5 +1,9 @@
#pragma once
#define DEFAULT_MAX_NUMBER_OF_PEDS 25.0f
#define DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR 40.0f
#define DEFAULT_MAX_NUMBER_OF_CARS 12.0f
class CIniFile
{
public:

View File

@ -30,11 +30,17 @@ CMenuScreen aScreens[] = {
MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 40, 76, MENUALIGN_LEFT,
MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 367, MENUALIGN_CENTER,
#else
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 327, MENUALIGN_CENTER,
#endif
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
@ -329,6 +335,16 @@ CMenuScreen aScreens[] = {
},
#endif
#ifdef MISSION_REPLAY
// MENUPAGE_MISSION_RETRY = 57 on mobile
{ "M_FAIL", MENUPAGE_DISABLED, 0,
MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, 320, 200, MENUALIGN_CENTER,
MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, 320, 225, MENUALIGN_CENTER,
},
#endif
// MENUPAGE_OUTRO - Originally 34
{ "", 0, 0, },
};

View File

@ -27,6 +27,9 @@
#include "Pad.h"
#include "ControllerConfig.h"
#include "DMAudio.h"
#include "IniFile.h"
#include "CarCtrl.h"
#include "Population.h"
// Menu screens array is at the bottom of the file.
@ -34,7 +37,7 @@
#ifdef CUSTOM_FRONTEND_OPTIONS
#ifdef IMPROVED_VIDEOMODE
#if defined(IMPROVED_VIDEOMODE) && !defined(GTA_HANDHELD)
#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT,
#else
#define VIDEOMODE_SELECTOR
@ -64,6 +67,15 @@
#define DUALPASS_SELECTOR
#endif
#ifdef PED_CAR_DENSITY_SLIDERS
// 0.2f - 3.4f makes it possible to have 1.0f somewhere inbetween
#define DENSITY_SLIDERS \
MENUACTION_CFO_SLIDER, "FEM_PED", { new CCFOSlider(&CIniFile::PedNumberMultiplier, "Display", "PedDensity", 0.2f, 3.4f, PedDensityChange) }, 0, 0, MENUALIGN_LEFT, \
MENUACTION_CFO_SLIDER, "FEM_CAR", { new CCFOSlider(&CIniFile::CarNumberMultiplier, "Display", "CarDensity", 0.2f, 3.4f, CarDensityChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define DENSITY_SLIDERS
#endif
#ifdef NO_ISLAND_LOADING
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT,
#else
@ -136,6 +148,9 @@ void RestoreDefDisplay(int8 action) {
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#endif
#ifdef PED_CAR_DENSITY_SLIDERS
CIniFile::LoadIniFile();
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
FrontEndMenuManager.m_PrefsBrightness = 256;
FrontEndMenuManager.m_PrefsLOD = 1.2f;
@ -182,6 +197,17 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
}
#endif
#ifdef PED_CAR_DENSITY_SLIDERS
void PedDensityChange(float before, float after) {
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * after;
CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * after;
}
void CarDensityChange(float before, float after) {
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * after;
}
#endif
#ifndef MULTISAMPLING
void GraphicsGoBack() {
}
@ -354,7 +380,7 @@ void DetectJoystickGoBack() {
#endif
#ifdef GAMEPAD_MENU
const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE" };
const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE", "FEC_NSW" };
void ControllerTypeAfterChange(int8 before, int8 after)
{
FrontEndMenuManager.LoadController(after);
@ -385,11 +411,17 @@ CMenuScreenCustom aScreens[] = {
MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT,
MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER,
#else
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 327, MENUALIGN_CENTER,
#endif
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
@ -398,6 +430,7 @@ CMenuScreenCustom aScreens[] = {
{ "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
@ -426,6 +459,7 @@ CMenuScreenCustom aScreens[] = {
{ "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
@ -604,7 +638,11 @@ CMenuScreenCustom aScreens[] = {
// MENUPAGE_OPTIONS = 27
{ "FET_OPT", MENUPAGE_NONE, nil, nil,
#ifdef GTA_HANDHELD
MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 320, 132, MENUALIGN_CENTER,
#else
MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER,
#endif
MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef GRAPHICS_MENU_OPTIONS
@ -660,7 +698,11 @@ CMenuScreenCustom aScreens[] = {
{ "", 0, nil, nil, },
#ifdef GAMEPAD_MENU
#ifdef GTA_HANDHELD
{ "FET_AGS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), nil,
#else
{ "FET_AGS", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({40, 78, 25, true, true}), nil,
#endif
MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 40, 76, MENUALIGN_LEFT,
MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 0, 0, MENUALIGN_LEFT,
INVERT_PAD_SELECTOR
@ -726,7 +768,9 @@ CMenuScreenCustom aScreens[] = {
// MENUPAGE_GRAPHICS_SETTINGS
{ "FET_GFX", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack,
#ifndef GTA_HANDHELD
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR
#ifdef LEGACY_MENU_OPTIONS
@ -756,6 +800,17 @@ CMenuScreenCustom aScreens[] = {
},
#endif
#ifdef MISSION_REPLAY
// MENUPAGE_MISSION_RETRY = 57 on mobile
{ "M_FAIL", MENUPAGE_DISABLED, nil, nil,
MENUACTION_LABEL, "FESZ_RM", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS }, 320, 200, MENUALIGN_CENTER,
MENUACTION_REJECT_RETRY, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 320, 225, MENUALIGN_CENTER,
},
#endif
// MENUPAGE_OUTRO = 34
{ "", 0, nil, nil, },
};

View File

@ -10,6 +10,7 @@
#endif
#include "Population.h"
#include "ProjectileInfo.h"
#include "SaveBuf.h"
#include "Streaming.h"
#include "Wanted.h"
#include "World.h"
@ -269,7 +270,7 @@ INITSAVEBUF
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumBoats;
if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumBoats;
++nNumBikes;
#else
if (!pVehicle->pDriver && !bHasPassenger) {
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
@ -277,7 +278,7 @@ INITSAVEBUF
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumBoats;
if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumBoats;
++nNumBikes;
#endif
}
}

View File

@ -16,6 +16,7 @@
#include "Script.h"
#include "TxdStore.h"
#include "World.h"
#include "SaveBuf.h"
#include "Streaming.h"
#include "SpecialFX.h"
#include "Font.h"
@ -65,6 +66,9 @@ CSprite2d CRadar::RadioVCPRSprite;
CSprite2d CRadar::RadioEspantosoSprite;
CSprite2d CRadar::RadioEmotionSprite;
CSprite2d CRadar::RadioWaveSprite;
#ifdef MAP_ENHANCEMENTS
CSprite2d CRadar::WaypointSprite;
#endif
CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
nil,
@ -106,7 +110,10 @@ CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
&RadioVCPRSprite,
&RadioEspantosoSprite,
&RadioEmotionSprite,
&RadioWaveSprite
&RadioWaveSprite,
#ifdef MAP_ENHANCEMENTS
&WaypointSprite,
#endif
};
// Why this doesn't coincide with world coordinates i don't know
@ -478,7 +485,7 @@ void CRadar::Draw3dMarkers()
CEntity *entity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
pos.z += 1.2f * CModelInfo::GetColModel(entity->GetModelIndex())->boundingBox.max.z + 2.5f;
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
@ -502,7 +509,7 @@ void CRadar::Draw3dMarkers()
CEntity *entity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
pos.z += CModelInfo::GetColModel(entity->GetModelIndex())->boundingBox.max.z + 1.0f + 1.0f;
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
@ -818,6 +825,9 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
#ifdef MAP_ENHANCEMENTS
if(sprite == RADAR_SPRITE_WAYPOINT) alpha = 255;
#endif
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
if (FrontEndMenuManager.m_bMenuMapActive) {
@ -935,6 +945,9 @@ const char* gRadarTexNames[] = {
void
CRadar::Initialise()
{
#ifdef MAP_ENHANCEMENTS
TargetMarkerId = -1;
#endif
for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_BlipIndex = 1;
SetRadarMarkerState(i, false);
@ -1002,9 +1015,11 @@ INITSAVEBUF
WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
#ifdef MAP_ENHANCEMENTS
bool bWaypointDeleted = false;
if (TargetMarkerId != -1) {
ClearBlip(TargetMarkerId);
TargetMarkerId = -1;
bWaypointDeleted = true;
}
#endif
@ -1029,6 +1044,11 @@ INITSAVEBUF
SkipSaveBuf(buf, sizeof(sRadarTraceSave));
}
#ifdef MAP_ENHANCEMENTS
if(bWaypointDeleted)
ToggleTargetMarker(TargetMarkerPos.x, TargetMarkerPos.y);
#endif
VALIDATESAVEBUF(*size);
}
@ -1076,6 +1096,43 @@ CRadar::LoadTextures()
RadioEspantosoSprite.SetTexture("REspantoso");
RadioEmotionSprite.SetTexture("REmotion");
RadioWaveSprite.SetTexture("RWave");
#ifdef MAP_ENHANCEMENTS
WaypointSprite.SetTexture("radar_waypoint");
if(!WaypointSprite.m_pTexture) {
// create the texture if it's missing in TXD
#define WAYPOINT_R (255)
#define WAYPOINT_G (72)
#define WAYPOINT_B (77)
RwRaster *raster = RwRasterCreate(16, 16, 0, rwRASTERTYPETEXTURE | rwRASTERFORMAT8888);
RwUInt32 *pixels = (RwUInt32 *)RwRasterLock(raster, 0, rwRASTERLOCKWRITE);
for(int x = 0; x < 16; x++)
for(int y = 0; y < 16; y++)
{
int x2 = x < 8 ? x : 7 - (x & 7);
int y2 = y < 8 ? y : 7 - (y & 7);
if ((y2 >= 4 && x2 >= 4) // square in the center is transparent
|| (x2 < 2 && y2 == 0) // two pixels on each side of first/last line are transparent
|| (x2 < 1 && y2 == 1)) // one pixel on each side of second to first/last line is transparent
pixels[x + y * 16] = 0;
else if((x2 == 2 && y2 >= 2)|| (y2 == 2 && x2 >= 2) )// colored square inside
#ifdef RW_GL3
pixels[x + y * 16] = WAYPOINT_R | (WAYPOINT_G << 8) | (WAYPOINT_B << 16) | (255 << 24);
#else
pixels[x + y * 16] = WAYPOINT_B | (WAYPOINT_G << 8) | (WAYPOINT_R << 16) | (255 << 24);
#endif
else
pixels[x + y * 16] = 0xFF000000; // black
}
RwRasterUnlock(raster);
WaypointSprite.m_pTexture = RwTextureCreate(raster);
RwTextureSetFilterMode(WaypointSprite.m_pTexture, rwFILTERLINEAR);
#undef WAYPOINT_R
#undef WAYPOINT_G
#undef WAYPOINT_B
}
#endif
CTxdStore::PopCurrentTxd();
}
@ -1270,6 +1327,9 @@ void CRadar::Shutdown()
RadioEspantosoSprite.Delete();
RadioEmotionSprite.Delete();
RadioWaveSprite.Delete();
#ifdef MAP_ENHANCEMENTS
WaypointSprite.Delete();
#endif
RemoveRadarSections();
}
@ -1431,12 +1491,12 @@ CRadar::ToggleTargetMarker(float x, float y)
{
if (TargetMarkerId == -1) {
int nextBlip;
for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
for (nextBlip = NUMRADARBLIPS-1; nextBlip >= 0; nextBlip--) {
if (!ms_RadarTrace[nextBlip].m_bInUse)
break;
}
if (nextBlip == NUMRADARBLIPS)
if (nextBlip == 0)
return;
ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD;
@ -1444,14 +1504,14 @@ CRadar::ToggleTargetMarker(float x, float y)
ms_RadarTrace[nextBlip].m_bDim = 0;
ms_RadarTrace[nextBlip].m_bInUse = 1;
ms_RadarTrace[nextBlip].m_Radius = 1.0f;
CVector pos(x, y, CWorld::FindGroundZForCoord(x,y));
CVector pos(x, y, 0.0f/*CWorld::FindGroundZForCoord(x,y)*/);
TargetMarkerPos = pos;
ms_RadarTrace[nextBlip].m_vec2DPos = pos;
ms_RadarTrace[nextBlip].m_vecPos = pos;
ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
ms_RadarTrace[nextBlip].m_wScale = 5;
ms_RadarTrace[nextBlip].m_eBlipDisplay = BLIP_DISPLAY_BLIP_ONLY;
ms_RadarTrace[nextBlip].m_eRadarSprite = RADAR_SPRITE_NONE;
ms_RadarTrace[nextBlip].m_eRadarSprite = RADAR_SPRITE_WAYPOINT;
TargetMarkerId = CRadar::GetNewUniqueBlipIndex(nextBlip);
} else {
ClearBlip(TargetMarkerId);
@ -1739,6 +1799,11 @@ CRadar::DrawLegend(int32 x, int32 y, int32 sprite)
case RADAR_SPRITE_RADIO_WAVE:
text = TheText.Get("LG_34");
break;
#ifdef MAP_ENHANCEMENTS
case RADAR_SPRITE_WAYPOINT:
text = TheText.Get("LG_38");
break;
#endif
default:
break;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "Sprite2d.h"
#include "Draw.h"
#define CARBLIP_MARKER_COLOR_R 252
#define CARBLIP_MARKER_COLOR_G 138
@ -92,6 +93,9 @@ enum eRadarSprite
RADAR_SPRITE_RADIO_ESPANTOSO,
RADAR_SPRITE_RADIO_EMOTION,
RADAR_SPRITE_RADIO_WAVE,
#ifdef MAP_ENHANCEMENTS
RADAR_SPRITE_WAYPOINT,
#endif
RADAR_SPRITE_COUNT
};
@ -232,6 +236,7 @@ public:
static int16 MapLegendCounter;
#ifdef MAP_ENHANCEMENTS
static CSprite2d WaypointSprite;
static int TargetMarkerId;
static CVector TargetMarkerPos;
#endif

View File

@ -365,7 +365,7 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
colmodel = nil;
} else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough, ignoreShootThrough))
@ -465,7 +465,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
if(e->m_scanCode != GetCurrentScanCode() && e->bUsesCollision) {
e->m_scanCode = GetCurrentScanCode();
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough, false, poly))
entity = e;
@ -666,7 +666,7 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
if(e != pIgnoreEntity && !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough, false))
return false;
@ -971,7 +971,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
float distance = diff.Magnitude();
if(e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
CColModel *eCol = CModelInfo::GetColModel(e->GetModelIndex());
int collidedSpheres =
CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol,
gaTempSphereColPoints, nil, nil);

View File

@ -11,6 +11,11 @@
#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc
#endif
#ifdef __SWITCH__
#include <switch.h>
#endif
#include <stdint.h>
#include <string.h>
#include <math.h>
@ -325,7 +330,7 @@ extern wchar *AllocUnicode(const char*src);
#define Clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
#define Clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius))
#define Clamp2(v, center, radius) ((v) > (center) ? Min(v, center + radius) : Max(v, center - radius))
inline float sq(float x) { return x*x; }
#define SQR(x) ((x) * (x))
@ -411,7 +416,10 @@ __inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function
#define _TODOCONST(x) (x)
#ifdef CHECK_STRUCT_SIZES
#define VALIDATE_SIZE(struc, size) static_assert(sizeof(struc) == size, "Invalid structure size of " #struc)
template<int s, int t> struct check_size {
static_assert(s == t, "Invalid structure size");
};
#define VALIDATE_SIZE(struc, size) check_size<sizeof(struc), size> struc ## Check
#else
#define VALIDATE_SIZE(struc, size)
#endif

View File

@ -135,7 +135,6 @@ enum Config {
NUM_SOUNDS_SAMPLES_BANKS = 2,
NUM_AUDIOENTITIES = 250,
NUM_AUDIO_REFLECTIONS = 8,
NUM_SCRIPT_MAX_ENTITIES = 40,
NUM_GARAGE_STORED_CARS = 4,
@ -165,6 +164,11 @@ enum Config {
#define GTA_VERSION GTAVC_PC_11
// Enable configuration for handheld console ports
#if defined(__SWITCH__) || defined(PSP2)
#define GTA_HANDHELD
#endif
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
@ -176,12 +180,19 @@ enum Config {
# define VU_COLLISION
# define PS2_MENU
#elif defined GTA_PC
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define EXTERNAL_3D_SOUND
# define AUDIO_REVERB
# ifndef GTA_HANDHELD
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# endif
# define GTA_REPLAY
# define GTA_SCENE_EDIT
# define PC_MENU
# define PC_WATER
#elif defined GTA_XBOX
#elif defined GTA_MOBILE
# define MISSION_REPLAY
# define SIMPLER_MISSIONS
#endif
// This is enabled for all released games.
@ -217,6 +228,7 @@ enum Config {
#define DONT_FIX_REPLAY_BUGS
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
#define AUDIO_REFLECTIONS
#else
// This enables things from the PS2 version on PC
#define GTA_PS2_STUFF
@ -274,6 +286,9 @@ enum Config {
#define NO_MOVIES // add option to disable intro videos
#define EXTENDED_OFFSCREEN_DESPAWN_RANGE // Use onscreen despawn range for offscreen peds and vehicles to avoid them despawning in the distance when you look
// away
#if defined(__LP64__) || defined(_WIN64)
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build
#endif
@ -327,7 +342,7 @@ enum Config {
#if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT
#endif
#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined __SWITCH__ && !defined __WIIU__)
#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined GTA_HANDHELD)
#define DETECT_JOYSTICK_MENU // Then we'll expect user to enter Controller->Detect joysticks if his joystick isn't detected at the start.
#endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
@ -349,7 +364,7 @@ enum Config {
//# define PS2_MENU_USEALLPAGEICONS
#else
# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# ifdef XINPUT
# if defined(XINPUT) || defined(GTA_HANDHELD)
# define GAMEPAD_MENU // Add gamepad menu
# endif
//# define TRIANGLE_BACK_BUTTON
@ -367,6 +382,7 @@ enum Config {
# define MULTISAMPLING // adds MSAA option
#endif
# define INVERT_LOOK_FOR_PAD // enable the hidden option
# define PED_CAR_DENSITY_SLIDERS
# endif
#endif
@ -376,14 +392,16 @@ enum Config {
#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
#define SUPPORT_JAPANESE_SCRIPT
//#define SUPPORT_XBOX_SCRIPT
//#define SUPPORT_MOBILE_SCRIPT
#define SUPPORT_MOBILE_SCRIPT
#define SUPPORT_GINPUT_SCRIPT
#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT)
static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive");
#endif
#ifdef PC_MENU
//#define MISSION_REPLAY // mobile feature
#define MISSION_REPLAY // mobile feature
//#define SIMPLER_MISSIONS // apply simplifications from mobile
#define USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
//#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
@ -400,6 +418,10 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif
#ifndef MISSION_REPLAY
#undef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
#endif
// Replay
//#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool!
//#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!)
@ -420,6 +442,10 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define FREE_CAM // Rotating cam
// Audio
#define EXTERNAL_3D_SOUND // use external engine to simulate 3d audio spatialization. OpenAL would not work without it (because it works in a 3d space
// originally and making it work in 2d only requires more resource). Will not work on PS2
#define AUDIO_REFLECTIONS // Enable audio reflections. This is enabled in all vanilla versions
#define AUDIO_REVERB // Enable audio reverb. It was disabled in PS2 and mobile versions
#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 43 (PC has 28 originally)
@ -453,6 +479,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING
#undef PS2_AUDIO_CHANNELS
#undef EXTENDED_OFFSCREEN_DESPAWN_RANGE
#endif
#ifdef __WIIU__
@ -469,4 +496,19 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef USE_CUTSCENE_SHADOW_FOR_PED
#endif
#ifdef GTA_HANDHELD
#define IGNORE_MOUSE_KEYBOARD // ignore mouse & keyboard input
#endif
#ifdef __SWITCH__
#define USE_UNNAMED_SEM // named semaphores are unsupported on the switch
#endif
#endif // VANILLA_DEFINES
#if defined(AUDIO_OAL) && !defined(EXTERNAL_3D_SOUND)
#error AUDIO_OAL cannot work without EXTERNAL_3D_SOUND
#endif
#if defined(GTA_PS2) && defined(EXTERNAL_3D_SOUND)
#error EXTERNAL_3D_SOUND cannot work on PS2
#endif

View File

@ -44,10 +44,11 @@
#include "Camera.h"
#include "MBlur.h"
#include "ControllerConfig.h"
#include "CarCtrl.h"
#include "Population.h"
#include "IniFile.h"
#if 1
#include "crossplatform.h"
#endif
#ifndef _WIN32
#include "assert.h"
@ -132,7 +133,7 @@ void LangJapSelect(int8 action)
void
CustomFrontendOptionsPopulate(void)
{
// Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h
// Most of custom options are done statically in MenuScreensCustom.cpp, we add them here only if they're dependent to extra files
int fd;
// These work only if we have neo folder, so they're dynamically added
@ -510,8 +511,10 @@ bool LoadINISettings()
ReadIniIfExists("Audio", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume);
ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume);
ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers);
ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
#endif
ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA);
ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness);
ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD);
@ -570,22 +573,30 @@ bool LoadINISettings()
// CFO check
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// CFO only supports saving uint8 right now
// Migrate from old .ini to new .ini
if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value))
// Old values can only be int8, new ones can contain float if it is slider
if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, (int8*)option.m_CFO->value))
cfg["FrontendOptions"].remove(option.m_CFO->save);
else if (option.m_Action == MENUACTION_CFO_SLIDER)
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, (float*)option.m_CFO->value);
else
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value);
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, (int8*)option.m_CFO->value);
if (option.m_Action == MENUACTION_CFO_SELECT) {
option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *(int8*)option.m_CFO->value;
}
}
}
}
#endif
// Fetched in above block, but needs evaluation
#ifdef PED_CAR_DENSITY_SLIDERS
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * CIniFile::PedNumberMultiplier;
CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * CIniFile::PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CIniFile::CarNumberMultiplier;
#endif
return true;
}
@ -609,8 +620,10 @@ void SaveINISettings()
StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume);
StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume);
StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers);
StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
#endif
StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA);
StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness);
StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD);
@ -666,8 +679,10 @@ void SaveINISettings()
break;
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// Beware: CFO only supports saving uint8 right now
StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value);
if (option.m_Action == MENUACTION_CFO_SLIDER)
StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *(float*)option.m_CFO->value);
else
StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *(int8*)option.m_CFO->value);
}
}
}
@ -1278,7 +1293,9 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
OutputDebugString(buff);
}
#endif
#ifndef MASTER
void re3_usererror(const char *format, ...)
{
va_list va;

View File

@ -226,14 +226,13 @@ CPhysical::RemoveAndAdd(void)
CRect
CPhysical::GetBoundRect(void)
{
CVUVECTOR center;
CVector center;
float radius;
GetBoundCentre(center);
center = GetBoundCentre();
radius = GetBoundRadius();
return CRect(center.x-radius, center.y-radius, center.x+radius, center.y+radius);
}
// --MIAMI: Proof-read once
void
CPhysical::AddToMovingList(void)
{
@ -241,7 +240,6 @@ CPhysical::AddToMovingList(void)
m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this);
}
// --MIAMI: Proof-read once
void
CPhysical::RemoveFromMovingList(void)
{
@ -261,7 +259,6 @@ CPhysical::SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, C
m_vecDamageNormal = dir;
}
// --MIAMI: Proof-read once
void
CPhysical::AddCollisionRecord(CEntity *ent)
{
@ -285,7 +282,6 @@ CPhysical::AddCollisionRecord(CEntity *ent)
}
}
// --MIAMI: Proof-read once
void
CPhysical::AddCollisionRecord_Treadable(CEntity *ent)
{
@ -293,7 +289,6 @@ CPhysical::AddCollisionRecord_Treadable(CEntity *ent)
}
}
// --MIAMI: Proof-read once
bool
CPhysical::GetHasCollidedWith(CEntity *ent)
{
@ -305,7 +300,6 @@ CPhysical::GetHasCollidedWith(CEntity *ent)
return false;
}
// --MIAMI: Proof-read once
void
CPhysical::RemoveRefsToEntity(CEntity *ent)
{
@ -321,7 +315,6 @@ CPhysical::RemoveRefsToEntity(CEntity *ent)
}
}
// --MIAMI: Proof-read once
void
CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phys, CVector localPos)
{
@ -338,7 +331,6 @@ CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phy
CWorld::Add(phys);
}
// --MIAMI: Proof-read once
int32
CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
{
@ -357,7 +349,6 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
return numSpheres;
}
// --MIAMI: Proof-read once
void
CPhysical::ProcessControl(void)
{
@ -425,7 +416,6 @@ CPhysical::GetSpeed(const CVector &r)
return m_vecMoveSpeed + m_vecMoveFriction + CrossProduct(m_vecTurnFriction + m_vecTurnSpeed, r);
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyMoveSpeed(void)
{
@ -435,7 +425,6 @@ CPhysical::ApplyMoveSpeed(void)
GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep());
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyTurnSpeed(void)
{
@ -451,14 +440,12 @@ CPhysical::ApplyTurnSpeed(void)
}
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyMoveForce(float jx, float jy, float jz)
{
m_vecMoveSpeed += CVector(jx, jy, jz)*(1.0f/m_fMass);
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz)
{
@ -473,7 +460,6 @@ CPhysical::ApplyFrictionMoveForce(float jx, float jy, float jz)
m_vecMoveFriction += CVector(jx, jy, jz)*(1.0f/m_fMass);
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float py, float pz)
{
@ -482,7 +468,6 @@ CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float
m_vecTurnFriction += turnimpulse*(1.0f/m_fTurnMass);
}
// --MIAMI: Proof-read once
bool
CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias)
{
@ -496,7 +481,6 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &
return true;
}
// --MIAMI: Proof-read once
bool
CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir)
{
@ -514,7 +498,6 @@ CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVecto
return true;
}
// --MIAMI: Proof-read once
// What exactly is speed?
bool
CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed)
@ -579,7 +562,6 @@ CPhysical::ApplyFriction(void)
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
}
// --MIAMI: Proof-read once
void
CPhysical::ApplyAirResistance(void)
{
@ -698,7 +680,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){
CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true);
Bobj->bHasBeenDamaged = true;
}else if(model == MI_PARKINGMETER || model == MI_PARKINGMETER2){
}else if((model == MI_PARKINGMETER || model == MI_PARKINGMETER2) && !Bobj->bHasBeenDamaged){
CPickups::CreateSomeMoney(GetPosition(), CGeneral::GetRandomNumber()%100);
Bobj->bHasBeenDamaged = true;
}else if(B->IsObject() && !IsExplosiveThingModel(model))
@ -716,14 +698,17 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}
return true;
}
}else if(!B->bInfiniteMass)
}else if(!B->bInfiniteMass){
B->SetIsStatic(false);
CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2;
CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60);
}
}
}
if(B->GetIsStatic())
return false;
if(!B->bInfiniteMass && !B->m_phy_flagA08)
if(!B->bInfiniteMass && !B->bIsStaticWaitingForCollision)
B->AddToMovingList();
}
@ -733,11 +718,11 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
// negative if A is moving towards B
speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal);
// positive if B is moving towards A
float speedB = DotProduct(B->m_vecMoveSpeed, colpoint.normal);
speedB = DotProduct(B->m_vecMoveSpeed, colpoint.normal);
bool affectB = false;
float mA = A->m_fMass;;
float mB = B->m_fMass;;
float mA = A->m_fMass;
float mB = B->m_fMass;
float speedSum;
if(((CPed*)A)->GetPedState() == PED_FOLLOW_PATH){
affectB = true;
@ -1009,7 +994,7 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
Abs(m_vecMoveSpeed.z) < minspeed*2.0f)
impulse = -0.8f * normalSpeed * mass;
else if(IsVehicle() && ((CVehicle*)this)->IsBoat() &&
colpoint.surfaceB == SURFACE_WOOD_SOLID && colpoint.normal.z < 0.5f)
(colpoint.surfaceB == SURFACE_WOOD_SOLID || colpoint.normal.z < 0.5f))
impulse = -(2.0f * m_fElasticity + 1.0f) * normalSpeed * mass;
else
impulse = -(m_fElasticity + 1.0f) * normalSpeed * mass;
@ -1037,7 +1022,6 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
return false;
}
// --MIAMI: Proof-read once
bool
CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
{
@ -1187,7 +1171,6 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
return false;
}
// --MIAMI: Proof-read once
bool
CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
{
@ -1253,7 +1236,6 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
return false;
}
// --MIAMI: Proof-read once
bool
CPhysical::ProcessShiftSectorList(CPtrList *lists)
{
@ -1287,11 +1269,12 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
skipShift = false;
if(B->IsBuilding() ||
B->IsObject() && B->bInfiniteMass)
B->IsObject() && B->bInfiniteMass ||
A->IsPed() && B->IsObject() && B->GetIsStatic() && !Bobj->bHasBeenDamaged)
canshift = true;
else
canshift = A->IsPed() &&
B->IsObject() && B->GetIsStatic() && !Bobj->bHasBeenDamaged;
canshift = false;
if(B == A ||
B->m_scanCode == CWorld::GetCurrentScanCode() ||
!B->bUsesCollision ||
@ -1320,7 +1303,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
Aobj->m_pCollidingEntity = nil;
}else if(Aobj->m_pCollidingEntity != B){
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(A->GetModelIndex())->boundingBox.GetSize();
size = A->GetMatrix() * size;
if(size.z < B->GetPosition().z ||
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
@ -1338,7 +1321,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
Bobj->m_pCollidingEntity = nil;
}else if(Bobj->m_pCollidingEntity != A){
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(B->GetModelIndex())->boundingBox.GetSize();
size = B->GetMatrix() * size;
if(size.z < A->GetPosition().z ||
(Invert(A->GetMatrix(), inv) * size).z < 0.0f)
@ -1350,9 +1333,10 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
else if(A->IsPed() && IsBodyPart(B->GetModelIndex()))
skipShift = true;
else if(A->IsPed() && ((CPed*)A)->m_pCollidingEntity == B ||
B->IsPed() && ((CPed*)B)->m_pCollidingEntity == A ||
A->GetModelIndex() == MI_RCBANDIT && B->IsVehicle() ||
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle()))
B->IsPed() && ((CPed*)B)->m_pCollidingEntity == A)
skipShift = true;
else if(A->GetModelIndex() == MI_RCBANDIT && B->IsVehicle() ||
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle()))
skipShift = true;
if(skipShift)
@ -1416,7 +1400,6 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
return true;
}
// --MIAMI: Proof-read once
bool
CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
{
@ -1583,7 +1566,6 @@ collision:
return true;
}
// --MIAMI: Proof-read once
bool
CPhysical::ProcessCollisionSectorList(CPtrList *lists)
{
@ -1621,18 +1603,17 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
bool isTouching = true;
if(!B->bUsesCollision ||
B->m_scanCode == CWorld::GetCurrentScanCode() ||
B == A ||
!(isTouching = B->GetIsTouching(center, radius))){
if(!isTouching){
if(A->IsObject() && Aobj->m_pCollidingEntity == B)
Aobj->m_pCollidingEntity = nil;
else if(B->IsObject() && Bobj->m_pCollidingEntity == A)
Bobj->m_pCollidingEntity = nil;
else if(A->IsPed() && Aped->m_pCollidingEntity == B)
Aped->m_pCollidingEntity = nil;
else if(B->IsPed() && Bped->m_pCollidingEntity == A)
Bped->m_pCollidingEntity = nil;
}
B == A)
continue;
if(!B->GetIsTouching(center, radius)){
if(A->IsObject() && Aobj->m_pCollidingEntity == B)
Aobj->m_pCollidingEntity = nil;
else if(B->IsObject() && Bobj->m_pCollidingEntity == A)
Bobj->m_pCollidingEntity = nil;
else if(A->IsPed() && Aped->m_pCollidingEntity == B)
Aped->m_pCollidingEntity = nil;
else if(B->IsPed() && Bped->m_pCollidingEntity == A)
Bped->m_pCollidingEntity = nil;
continue;
}
@ -1664,7 +1645,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
skipCollision = true;
else if(Aobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(A->GetModelIndex())->boundingBox.GetSize();
size = A->GetMatrix() * size;
if(size.z < B->GetPosition().z ||
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
@ -1683,7 +1664,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
skipCollision = true;
else if(Bobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(B->GetModelIndex())->boundingBox.GetSize();
size = B->GetMatrix() * size;
if(size.z < A->GetPosition().z ||
(Invert(A->GetMatrix(), inv) * size).z < 0.0f){
@ -1833,7 +1814,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(!CWorld::bNoMoreCollisionTorque &&
A->GetStatus() == STATUS_PLAYER && A->IsVehicle() &&
Abs(A->m_vecMoveSpeed.x) > 0.2f &&
Abs(A->m_vecMoveSpeed.y) > 0.2f){
Abs(A->m_vecMoveSpeed.y) > 0.2f && !A->bIsInWater){
A->m_vecMoveFriction.x += moveSpeed.x * -0.3f / numCollisions;
A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions;
A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions;
@ -1986,7 +1967,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
Bobj->ObjectDamage(maxImpulseB);
else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(B->GetModelIndex())->boundingBox.GetSize();
size = B->GetMatrix() * size;
if(size.z < A->GetPosition().z ||
(Invert(A->GetMatrix(), inv) * size).z < 0.0f)
@ -2001,7 +1982,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){
#endif
CMatrix inv;
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
CVector size = CModelInfo::GetColModel(A->GetModelIndex())->boundingBox.GetSize();
size = A->GetMatrix() * size;
if(size.z < B->GetPosition().z ||
(Invert(B->GetMatrix(), inv) * size).z < 0.0f)
@ -2054,7 +2035,6 @@ CPhysical::CheckCollision_SimpleCar(void)
float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f;
// --MIAMI: Proof-read once
void
CPhysical::ProcessShift(void)
{
@ -2110,7 +2090,7 @@ CPhysical::ProcessShift(void)
}
// x is the number of units (m) we would like to step
#define NUMSTEPS(x) ceil(Sqrt(distSq) * (1.0f/(x)))
#define NUMSTEPS(x) Ceil(Sqrt(distSq) * (1.0f/(x)))
float HIGHSPEED_ELASTICITY_MULT_PED = 2.0f;
float HIGHSPEED_ELASTICITY_MULT_COPCAR = 2.0f;
@ -2186,10 +2166,11 @@ CPhysical::ProcessCollision(void)
m_bIsVehicleBeingShifted = false;
bJustCheckCollision = true;
bool savedUsesCollision = bUsesCollision;
bUsesCollision = false;
if(!CheckCollision()){
bJustCheckCollision = false;
bUsesCollision = true;
bUsesCollision = savedUsesCollision;
if(IsVehicle())
((CVehicle*)this)->bVehicleColProcessed = true;
@ -2204,7 +2185,7 @@ CPhysical::ProcessCollision(void)
return;
}
bJustCheckCollision = false;
bUsesCollision = true;
bUsesCollision = savedUsesCollision;
GetMatrix() = savedMatrix;
m_vecMoveSpeed = savedMoveSpeed;
if(IsVehicle() && ((CVehicle*)this)->bIsLawEnforcer)

View File

@ -15,8 +15,6 @@ class CTreadable;
class CPhysical : public CEntity
{
public:
// The not properly indented fields haven't been checked properly yet
int32 m_audioEntityId;
float m_phys_unused1;
uint32 m_nLastTimeCollided;

View File

@ -35,6 +35,8 @@ typedef void (*ReturnPrevPageFunc)();
typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value.
// only called on enter if onlyApplyOnEnter set, otherwise called on every value change
typedef void (*ChangeFuncFloat)(float before, float after); // called after updating the value.
// for dynamic options
typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text.
// you can also set *disabled if you want to gray it out.

View File

@ -741,7 +741,7 @@ uint32 im2D_UV2_Vao;
void
openim2d_uv2(void)
{
u_xform = rw::gl3::registerUniform("u_xform"); // this doesn't add a new one, so it's safe
u_xform = rw::gl3::registerUniform("u_xform", rw::gl3::UNIFORM_VEC4); // this doesn't add a new one, so it's safe
glGenBuffers(1, &im2D_UV2_Ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
@ -803,7 +803,7 @@ RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, Rw
setAttribPointers(im2d_UV2_attribDesc, 4);
#endif
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
setUniform(u_xform, xform);
flushCache();
glDrawElements(primTypeMap[primType], numIndices,

View File

@ -16,7 +16,6 @@ using namespace rw;
RwUInt8 RwObjectGetType(const RwObject *obj) { return obj->type; }
RwFrame* rwObjectGetParent(const RwObject *obj) { return (RwFrame*)obj->parent; }
void *RwMalloc(size_t size) { return engine->memfuncs.rwmalloc(size, 0); }
void *RwCalloc(size_t numObj, size_t sizeObj) {
void *mem = RwMalloc(numObj*sizeObj);
@ -236,8 +235,8 @@ RwRaster *RwRasterGetCurrentContext(void) { return Raster::getCurrentContext(
RwBool RwRasterClear(RwInt32 pixelValue);
RwBool RwRasterClearRect(RwRect * rpRect, RwInt32 pixelValue);
RwRaster *RwRasterShowRaster(RwRaster * raster, void *dev, RwUInt32 flags);
RwUInt8 *RwRasterLock(RwRaster * raster, RwUInt8 level, RwInt32 lockMode);
RwRaster *RwRasterUnlock(RwRaster * raster);
RwUInt8 *RwRasterLock(RwRaster * raster, RwUInt8 level, RwInt32 lockMode) { return raster->lock(level, lockMode); }
RwRaster *RwRasterUnlock(RwRaster * raster) { raster->unlock(0); return raster; }
RwUInt8 *RwRasterLockPalette(RwRaster * raster, RwInt32 lockMode);
RwRaster *RwRasterUnlockPalette(RwRaster * raster);
RwInt32 RwRasterRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);

View File

@ -104,6 +104,14 @@ enum RwRasterFormat
rwRASTERFORMATMASK = 0xff00
};
enum RwRasterLockMode
{
rwRASTERLOCKWRITE = rw::Raster::LOCKWRITE,
rwRASTERLOCKREAD = rw::Raster::LOCKREAD,
rwRASTERLOCKNOFETCH = rw::Raster::LOCKNOFETCH,
rwRASTERLOCKRAW = rw::Raster::LOCKRAW,
};
enum RwRasterFlipMode
{
rwRASTERFLIPDONTWAIT = 0,

View File

@ -0,0 +1,41 @@
#include "common.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
/*
void
CMloModelInfo::ConstructClump()
{
m_clump = RpClumpCreate();
RwFrame *mainFrame = RwFrameCreate();
RwFrameSetIdentity(mainFrame);
RpClumpSetFrame(m_clump, mainFrame);
for (int i = firstInstance; i < lastInstance; i++) {
int modelId = CModelInfo::GetMloInstanceStore().store[i].m_modelIndex;
RwMatrix *attMat = CModelInfo::GetMloInstanceStore().store[i].GetMatrix().m_attachment;
CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(modelId);
if (minfo->m_atomics[0] != nil) {
RpAtomic *newAtomic = RpAtomicClone(minfo->m_atomics[0]);
RwFrame *newFrame = RwFrameCreate();
if (newAtomic != nil && newFrame != nil) {
*RwFrameGetMatrix(newFrame) = *attMat;
RpAtomicSetFrame(newAtomic, newFrame);
RwFrameAddChild(mainFrame, newFrame);
RpClumpAddAtomic(m_clump, newAtomic);
} else {
debug("Failed to allocate memory while creating template MLO.\n");
}
}
}
if (RpClumpGetNumAtomics(m_clump) != 0) {
CVisibilityPlugins::SetClumpModelInfo(m_clump, this);
} else {
RpClumpDestroy(m_clump);
m_clump = nil;
}
}
*/

View File

@ -0,0 +1,14 @@
#pragma once
#include "ClumpModelInfo.h"
class CMloModelInfo : public CClumpModelInfo
{
public:
float drawDist;
int firstInstance;
int lastInstance;
public:
CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
void ConstructClump();
};

View File

@ -2,6 +2,7 @@
#include "2dEffect.h"
#include "SimpleModelInfo.h"
#include "MloModelInfo.h"
#include "TimeModelInfo.h"
#include "WeaponModelInfo.h"
#include "ClumpModelInfo.h"

View File

@ -287,7 +287,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bHeadStuckInCollision = false;
bDeadPedInFrontOfCar = false;
m_gangFlags = 0xFF;
m_gangFlags = ~0;
bStayInCarOnJack = false;
@ -511,8 +511,20 @@ CPed::BuildPedLists(void)
continue;
deadsRegistered++;
}
#ifdef FIX_BUGS
// If the gap ped list is full, sort it and truncate it
// before pushing more unsorted peds
if( gnNumTempPedList == ARRAY_SIZE(gapTempPedList) - 1 )
{
gapTempPedList[gnNumTempPedList] = nil;
SortPeds(gapTempPedList, 0, gnNumTempPedList - 1);
gnNumTempPedList = ARRAY_SIZE(m_nearPeds);
}
#endif
gapTempPedList[gnNumTempPedList] = ped;
gnNumTempPedList++;
// NOTE: We cannot absolutely fill the gap list, as the list is null-terminated before being passed to SortPeds
assert(gnNumTempPedList < ARRAY_SIZE(gapTempPedList));
}
}
@ -1221,8 +1233,12 @@ CPed::ClearAimFlag(void)
m_lookTimer = 0;
}
if (IsPlayer())
if (IsPlayer()) {
((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
#ifdef FREE_CAM
((CPlayerPed*)this)->m_bFreeAimActive = false;
#endif
}
}
void
@ -2192,7 +2208,7 @@ CPed::ProcessControl(void)
Say(SOUND_PED_DAMAGE);
}
CColModel* collidingCol = CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel();
CColModel *collidingCol = CModelInfo::GetColModel(collidingVeh->m_modelIndex);
CVector colMinVec = collidingCol->boundingBox.min;
CVector colMaxVec = collidingCol->boundingBox.max;
@ -2884,8 +2900,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
CColPoint intersectionPoint;
CColLine ourLine;
CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex())->GetColModel();
CColModel *ourCol = CModelInfo::GetColModel(GetModelIndex());
CColModel *hisCol = CModelInfo::GetColModel(collidingEnt->GetModelIndex());
if (!bUsesCollision && !bJustCheckCollision)
return 0;
@ -3402,7 +3418,7 @@ void
CPed::SetDirectionToWalkAroundObject(CEntity *obj)
{
float distLimitForTimer = 8.0f;
CColModel *objCol = CModelInfo::GetModelInfo(obj->GetModelIndex())->GetColModel();
CColModel *objCol = CModelInfo::GetColModel(obj->GetModelIndex());
CVector objColMin = objCol->boundingBox.min;
CVector objColMax = objCol->boundingBox.max;
CVector objColCenter = (objColMin + objColMax) / 2.0f;
@ -4951,7 +4967,7 @@ CPed::PreRender(void)
if (CWeather::Rain > 0.3f && TheCamera.SoundDistUp > 15.0f) {
if ((TheCamera.GetPosition() - GetPosition()).Magnitude() < 25.0f) {
bool doSplashUp = true;
CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
CColModel *ourCol = CModelInfo::GetColModel(GetModelIndex());
CVector speed = FindPlayerSpeed();
if (Abs(speed.x) <= 0.05f && Abs(speed.y) <= 0.05f) {
@ -7291,6 +7307,9 @@ CPed::SetAnswerMobile(void)
{
if (m_nPedState != PED_ANSWER_MOBILE && !DyingOrDead()) {
SetPedState(PED_ANSWER_MOBILE);
#ifdef FIX_BUGS
ClearLookFlag();
#endif
RemoveWeaponAnims(GetWeapon()->m_eWeaponType, -4.0f);
CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_IN, 4.0f);
assoc->SetFinishCallback(StartTalkingOnMobileCB, this);
@ -7298,6 +7317,9 @@ CPed::SetAnswerMobile(void)
if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
m_storedWeapon = GetWeapon()->m_eWeaponType;
#ifdef FIX_BUGS
SetCurrentWeapon(0);
#endif
RemoveWeaponModel(-1);
}
}
@ -9165,7 +9187,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
CVector forward(0.09f * ped->GetForward() + ped->GetPosition());
forward.z += CModelInfo::GetModelInfo(ped->GetModelIndex())->GetColModel()->spheres[2].center.z + 0.35f;
forward.z += CModelInfo::GetColModel(ped->GetModelIndex())->spheres[2].center.z + 0.35f;
CEntity *obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false);
if (!obstacle) {

View File

@ -345,11 +345,17 @@ CPed::SetAttack(CEntity *victim)
if (m_pLookTarget) {
SetAimFlag(m_pLookTarget);
} else if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
SetAimFlag(m_fRotationCur);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
} else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
SetAimFlag(m_fRotationCur);
#ifdef FREE_CAM
} else if (this != FindPlayerPed() || !((CPlayerPed*)this)->m_bFreeAimActive) {
#else
} else {
#endif
if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
SetAimFlag(m_fRotationCur);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
} else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
SetAimFlag(m_fRotationCur);
}
}
}
#ifdef FIX_BUGS
@ -821,6 +827,9 @@ CPed::Attack(void)
if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
#ifdef FREE_CAM
if (!IsPlayer() || !((CPlayerPed*)this)->m_bFreeAimActive)
#endif
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
}
@ -1017,6 +1026,15 @@ CPed::Attack(void)
weaponAnimAssoc->SetCurrentTime(animLoopEnd);
weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
SetPointGunAt(m_pPointGunAt);
#ifdef FREE_CAM
} else if (IsPlayer() && ((CPlayerPed*)this)->m_bFreeAimActive && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
SetLookFlag(limitedCam, true, true);
SetAimFlag(limitedCam);
SetLookTimer(INT32_MAX);
SetPointGunAt(nil);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
#endif
} else {
ClearAimFlag();

View File

@ -29,7 +29,7 @@ class CPedIK
{
public:
enum {
GUN_POINTED_SUCCESSFULLY = 1, // set but unused
GUN_POINTED_SUCCESSFULLY = 1,
LOOKAROUND_HEAD_ONLY = 2,
AIMS_WITH_ARM = 4,
};

View File

@ -98,6 +98,9 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nAttackDirToCheck = 0;
m_nLastBusFareCollected = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
#ifdef FREE_CAM
m_bFreeAimActive = false;
#endif
}
void
@ -574,8 +577,12 @@ CPlayerPed::DoWeaponSmoothSpray(void)
return -1.0f;
case WEAPONTYPE_CHAINSAW:
if (GetMeleeStartAnim(weaponInfo) && RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(weaponInfo)))
if (GetMeleeStartAnim(weaponInfo) && RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(weaponInfo))) {
#ifdef FREE_CAM
if (TheCamera.Cams[0].Using3rdPersonMouseCam()) return -1.0f;
#endif
return PI / 128.0f;
}
else if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false)))
return PI / 176.f;
else
@ -1221,11 +1228,21 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
}
if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
#ifdef FIX_BUGS
// fix tommy being locked into looking at the same spot if you duck just after starting to shoot
if(!m_pPointGunAt)
ClearPointGunAt();
#endif
bCrouchWhenShooting = true;
SetDuck(60000, true);
} else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT ||
padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) {
#ifdef FIX_BUGS
// same fix as above except for standing up
if(!m_pPointGunAt)
ClearPointGunAt();
#endif
ClearDuck(true);
bCrouchWhenShooting = false;
}
@ -1328,17 +1345,22 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
if ((padUsed->GetTarget() && CAN_AIM_WITH_ARM) || padUsed->GetWeapon()) {
float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
m_cachedCamSource = TheCamera.Cams[TheCamera.ActiveCam].Source;
m_cachedCamFront = TheCamera.Cams[TheCamera.ActiveCam].Front;
m_cachedCamUp = TheCamera.Cams[TheCamera.ActiveCam].Up;
// On this one we can rotate arm.
if (CAN_AIM_WITH_ARM) {
if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
SetPointGunAt(nil);
bIsPointingGunAt = false; // to not stop after attack
}
pointedGun = 2;
SetLookFlag(limitedCam, true);
m_bFreeAimActive = true;
SetLookFlag(limitedCam, true, true);
SetAimFlag(limitedCam);
SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs.
SetLookTimer(INT32_MAX);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN) {
// This is a seperate ped state just for pointing gun. Used for target button
SetPointGunAt(nil);
}
} else {
m_fRotationDest = limitedCam;
changedHeadingRate = 2;
@ -1366,9 +1388,19 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
changedHeadingRate = 0;
RestoreHeadingRate();
}
if (pointedGun == 1 && m_nPedState != PED_ATTACK) {
pointedGun = 0;
ClearPointGunAt();
if (pointedGun == 1) {
if (m_nPedState == PED_ATTACK) {
if (!padUsed->GetWeapon() && (m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
SetAimFlag(limitedCam);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
m_bFreeAimActive = true;
}
} else {
pointedGun = 0;
ClearPointGunAt();
}
}
#endif
@ -1465,6 +1497,13 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
}
#ifdef FREE_CAM
if (TheCamera.Cams[0].Using3rdPersonMouseCam() && smoothSprayRate > 0.0f) {
padMoveInGameUnit = 0.0f;
smoothSprayWithoutMove = false;
}
#endif
if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);

View File

@ -44,6 +44,12 @@ public:
float m_fGunSpinAngle;
unsigned int m_nPadDownPressedInMilliseconds;
unsigned int m_nLastBusFareCollected;
#ifdef FREE_CAM
bool m_bFreeAimActive;
CVector m_cachedCamSource;
CVector m_cachedCamFront;
CVector m_cachedCamUp;
#endif
static bool bDontAllowWeaponChange;
#ifndef MASTER

View File

@ -40,8 +40,8 @@ bool CPopulation::ms_bGivePedsWeapons;
int32 CPopulation::m_AllRandomPedsThisType = -1;
float CPopulation::PedDensityMultiplier = 1.0f;
uint32 CPopulation::ms_nTotalMissionPeds;
int32 CPopulation::MaxNumberOfPedsInUse = 25;
int32 CPopulation::MaxNumberOfPedsInUseInterior = 40;
int32 CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS;
int32 CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR;
uint32 CPopulation::ms_nNumCivMale;
uint32 CPopulation::ms_nNumCivFemale;
uint32 CPopulation::ms_nNumCop;
@ -1095,6 +1095,7 @@ CPopulation::ManagePopulation(void)
}
float dist = (ped->GetPosition() - playerPos).Magnitude2D();
bool pedIsFarAway = false;
if (ped->IsGangMember())
@ -1105,8 +1106,9 @@ CPopulation::ManagePopulation(void)
if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist ||
(!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)) {
pedIsFarAway = true;
} else if (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist) {
}
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
else if (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist) {
if (CTimer::GetTimeInMilliseconds() > ped->m_nExtendedRangeTimer && !ped->GetIsOnScreen()) {
if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER
&& TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT
@ -1118,7 +1120,9 @@ CPopulation::ManagePopulation(void)
}
}
} else {
}
#endif
else {
ped->m_nExtendedRangeTimer = ped->m_nPedType == PEDTYPE_COP ? CTimer::GetTimeInMilliseconds() + 10000 : CTimer::GetTimeInMilliseconds() + 4000;
}
@ -1542,7 +1546,7 @@ CPopulation::PlaceGangMembersInCircle(ePedType pedType, int pedAmount, CVector c
int gangModel = ChooseGangOccupation(pedType - PEDTYPE_GANG1);
if (((CPedModelInfo*)CModelInfo::GetModelInfo(gangModel))->GetRwObject()) {
CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil };
CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetModelInfo(gangModel)->GetColModel()->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetColModel(gangModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
bool foundObstacle = false;
for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
CEntity* obstacle = obstacles[m];
@ -1626,7 +1630,7 @@ CPopulation::PlaceCouple(ePedType manType, int32 manModel, ePedType womanType, i
return;
if (!TheCamera.IsSphereVisible(coors, 1.5f) || MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) {
if (CPedPlacement::IsPositionClearForPed(coors, CModelInfo::GetModelInfo(manModel)->GetColModel()->boundingSphere.radius, -1, nil)) {
if (CPedPlacement::IsPositionClearForPed(coors, CModelInfo::GetColModel(manModel)->boundingSphere.radius, -1, nil)) {
bool manFoundGround;
float manGroundZ = CWorld::FindGroundZFor3DCoord(coors.x, coors.y, coors.z, &manFoundGround) + 1.0f;
if (manFoundGround) {
@ -1660,7 +1664,7 @@ CPopulation::PlaceCouple(ePedType manType, int32 manModel, ePedType womanType, i
CEntity* obstacles[3];
memcpy(obstacles, gCoupleObstacles, sizeof(gCoupleObstacles));
CPedPlacement::IsPositionClearForPed(womanPos, CModelInfo::GetModelInfo(womanModel)->GetColModel()->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
CPedPlacement::IsPositionClearForPed(womanPos, CModelInfo::GetColModel(womanModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
for (int i = 0; i < ARRAY_SIZE(obstacles); i++) {
CEntity *obstacle = obstacles[i];
if (obstacle) {
@ -1736,7 +1740,7 @@ CPopulation::PlaceMallPedsAsStationaryGroup(CVector const& coors, int32 group)
if (pedModelInfo->GetRwObject()) {
CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil };
CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetModelInfo(pedModel)->GetColModel()->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetColModel(pedModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
bool foundObstacle = false;
for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
CEntity* obstacle = obstacles[m];

View File

@ -928,7 +928,7 @@ CEscalator::AddThisOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, b
m_pos2 = pos2;
m_pos3 = pos3;
float escalatorStepHeight = CModelInfo::GetModelInfo(MI_ESCALATORSTEP)->GetColModel()->boundingBox.max.z;
float escalatorStepHeight = CModelInfo::GetColModel(MI_ESCALATORSTEP)->boundingBox.max.z;
m_pos0.z -= escalatorStepHeight;
m_pos1.z -= escalatorStepHeight;
m_pos2.z -= escalatorStepHeight;

View File

@ -49,7 +49,7 @@ UnicodeMakeUpperCase(wchar *dst, const wchar *src) //idk what to do with it, see
}
CFontDetails CFont::Details;
int16 CFont::NewLine;
bool16 CFont::NewLine;
CSprite2d CFont::Sprite[MAX_FONTS];
CFontRenderState CFont::RenderState;

View File

@ -129,7 +129,7 @@ class CFont
#else
static int16 Size[MAX_FONTS][210];
#endif
static int16 NewLine;
static bool16 NewLine;
public:
static CSprite2d Sprite[MAX_FONTS];
static CFontDetails Details;

View File

@ -36,6 +36,12 @@
#define SCALE_AND_CENTER_X_FIX(a) (a)
#endif
#ifdef FIX_BUGS
#define FRAMECOUNTER CTimer::GetLogicalFrameCounter()
#else
#define FRAMECOUNTER CTimer::GetFrameCounter()
#endif
// Game has colors inlined in code.
// For easier modification we collect them here:
CRGBA MONEY_COLOR(0, 207, 133, 255);
@ -559,12 +565,12 @@ void CHud::Draw()
CFont::SetDropShadowPosition(2);
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
if (m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8
if (m_ItemToFlash == ITEM_HEALTH && FRAMECOUNTER & 8
|| m_ItemToFlash != ITEM_HEALTH
|| playerPed->m_fHealth < 10
&& CTimer::GetFrameCounter() & 8) {
&& FRAMECOUNTER & 8) {
if (playerPed->m_fHealth >= 10
|| playerPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
|| playerPed->m_fHealth < 10 && FRAMECOUNTER & 8) {
AsciiToUnicode("{", sPrintIcon);
#ifdef FIX_BUGS
@ -578,7 +584,7 @@ void CHud::Draw()
if (FrontEndMenuManager.m_PrefsShowHud) {
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(65.0f), sPrint);
if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) {
if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || FRAMECOUNTER & 4) {
// CFont::SetColor(HEALTH_COLOR);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 54.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
}
@ -589,7 +595,7 @@ void CHud::Draw()
/*
DrawArmour
*/
if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_ARMOUR) {
if (m_ItemToFlash == ITEM_ARMOUR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_ARMOUR) {
CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
if (playerPed->m_fArmour > 1.0f) {
AsciiToUnicode("<", sPrintIcon);
@ -605,7 +611,7 @@ void CHud::Draw()
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint);
if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 4) {
if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || FRAMECOUNTER & 4) {
// CFont::SetColor(ARMOUR_COLOR);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
}
@ -639,13 +645,13 @@ void CHud::Draw()
if (FrontEndMenuManager.m_PrefsShowHud) {
if (playerPed->m_pWanted->GetWantedLevel() > i
&& (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange
+ 2000 || CTimer::GetFrameCounter() & 4)) {
+ 2000 || FRAMECOUNTER & 4)) {
WANTED_COLOR.a = alpha;
CFont::SetColor(WANTED_COLOR);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
} else if (playerPed->m_pWanted->m_nMinWantedLevel > i && CTimer::GetFrameCounter() & 4) {
} else if (playerPed->m_pWanted->m_nMinWantedLevel > i && FRAMECOUNTER & 4) {
WANTED_COLOR_FLASH.a = alpha;
CFont::SetColor(WANTED_COLOR_FLASH);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
@ -961,7 +967,7 @@ void CHud::Draw()
TimerFlashTimer = 0;
}
if (CTimer::GetFrameCounter() & 4 || TimerFlashTimer == 0) {
if (FRAMECOUNTER & 4 || TimerFlashTimer == 0) {
AsciiToUnicode(CUserDisplay::OnscnTimer.m_sClocks[0].m_aClockBuffer, sTimer);
CFont::SetPropOn();
CFont::SetBackgroundOff();
@ -999,7 +1005,7 @@ void CHud::Draw()
CounterFlashTimer[i] = 0;
}
if (CTimer::GetFrameCounter() & 4 || CounterFlashTimer[i] == 0) {
if (FRAMECOUNTER & 4 || CounterFlashTimer[i] == 0) {
if (CUserDisplay::OnscnTimer.m_sCounters[i].m_nType == COUNTER_DISPLAY_NUMBER) {
AsciiToUnicode(CUserDisplay::OnscnTimer.m_sCounters[i].m_aCounterBuffer, sTimer);
CFont::SetPropOn();
@ -1054,7 +1060,7 @@ void CHud::Draw()
DrawRadar
*/
if (FrontEndMenuManager.m_PrefsRadarMode != 2 &&
!m_HideRadar && (m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_RADAR)) {
!m_HideRadar && (m_ItemToFlash == ITEM_RADAR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_RADAR)) {
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
CRadar::DrawMap();

View File

@ -29,6 +29,8 @@
bool gbShowPedRoadGroups;
bool gbShowCarRoadGroups;
bool gbShowCollisionPolys;
bool gbShowCollisionPolysReflections;
bool gbShowCollisionPolysNoShadows;
bool gbShowCollisionLines;
bool gbBigWhiteDebugLightSwitchedOn;
@ -126,11 +128,16 @@ CRenderer::PreRender(void)
void
CRenderer::RenderOneRoad(CEntity *e)
{
#ifndef FINAL
if(gbDontRenderBuildings)
return;
if(gbShowCollisionPolys)
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex());
else{
#endif
#ifndef MASTER
if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows)
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex());
else
#endif
{
PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName());
e->Render();
@ -148,12 +155,15 @@ CRenderer::RenderOneNonRoad(CEntity *e)
bool resetLights;
#ifndef MASTER
if(gbShowCollisionPolys){
if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows){
if(!e->IsVehicle()){
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex());
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex());
return;
}
}else if(e->IsBuilding()){
}else
#endif
#ifndef FINAL
if(e->IsBuilding()){
if(e->bIsBIGBuilding){
if(gbDontRenderBigBuildings)
return;
@ -164,7 +174,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
}else
#endif
if(e->IsPed()){
#ifndef MASTER
#ifndef FINAL
if(gbDontRenderPeds)
return;
#endif
@ -172,7 +182,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
if(ped->m_nPedState == PED_DRIVING)
return;
}
#ifndef MASTER
#ifndef FINAL
else if(e->IsObject() || e->IsDummy()){
if(gbDontRenderObjects)
return;
@ -665,8 +675,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
ti->m_alpha = 255;
}else{
// Hide if possible
if(CANTIMECULL)
if(CANTIMECULL){
ent->DeleteRwObject();
return VIS_INVISIBLE;
}
// can't cull, so we'll try to draw this one, but don't request
// it since what we really want is the other one.
request = false;

View File

@ -5,6 +5,10 @@
#include "Camera.h"
#include "Sprite.h"
#ifdef ASPECT_RATIO_SCALE
#include "Frontend.h"
#endif
float CSprite::m_f2DNearScreenZ;
float CSprite::m_f2DFarScreenZ;
float CSprite::m_fRecipNearClipPlane;

View File

@ -1,5 +1,6 @@
#define WITHD3D
#include "common.h"
#include <rpskin.h>
#include "Timecycle.h"
#include "skeleton.h"

View File

@ -51,7 +51,7 @@ CVisibilityPlugins::Initialise(void)
m_alphaBoatAtomicList.tail.item.sort = 100000000.0f;
#ifdef ASPECT_RATIO_SCALE
// default 150 if not enough for bigger FOVs
// default 150 is not enough for bigger FOVs
m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3);
#else
m_alphaEntityList.Init(NUMALPHAENTITYLIST);
@ -604,8 +604,7 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
return atomic;
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq))
RENDERCALLBACK(atomic);
}else{
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
@ -662,12 +661,14 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
RpAtomic*
CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
{
RpClump *clump;
float dist;
int32 alpha;
RwV3d cam2atm;
RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){
alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
clump = RpAtomicGetClump(atomic);
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
if(dist < ms_pedLod1Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
RENDERCALLBACK(atomic);
else
@ -755,12 +756,23 @@ CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE;
}
bool
CVisibilityPlugins::MloVisibilityCB(RpClump *clump)
{
RwFrame *frame = RpClumpGetFrame(clump);
CMloModelInfo *modelInfo = (CMloModelInfo*)GetFrameHierarchyId(frame);
if (SQR(modelInfo->drawDist) < GetDistanceSquaredFromCamera(frame))
return false;
return CVisibilityPlugins::FrustumSphereCB(clump);
}
bool
CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump)
{
if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist)
return FrustumSphereCB(clump);
return false;
RwFrame *frame = RpClumpGetFrame(clump);
if (ms_vehicleLod1Dist < GetDistanceSquaredFromCamera(frame))
return false;
return FrustumSphereCB(clump);
}
bool
@ -854,6 +866,12 @@ CVisibilityPlugins::ClearAtomicFlag(RpAtomic *atomic, int f)
ATOMICEXT(atomic)->flags &= ~f;
}
void
CVisibilityPlugins::SetAtomicId(RpAtomic *atomic, int id)
{
ATOMICEXT(atomic)->flags = id;
}
int
CVisibilityPlugins::GetAtomicId(RpAtomic *atomic)
{
@ -939,7 +957,9 @@ CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo
// Unused
switch (modelInfo->GetModelType()) {
// ignore MLO
case MITYPE_MLO:
CLUMPEXT(clump)->visibilityCB = MloVisibilityCB;
break;
case MITYPE_VEHICLE:
vmi = (CVehicleModelInfo*)modelInfo;
if(vmi->m_vehicleType == VEHICLE_TYPE_TRAIN ||
@ -953,6 +973,12 @@ CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo
}
}
CClumpModelInfo*
CVisibilityPlugins::GetClumpModelInfo(RpClump *clump)
{
return (CClumpModelInfo*)GetFrameHierarchyId(RpClumpGetFrame(clump));
}
void
CVisibilityPlugins::SetClumpAlpha(RpClump *clump, int alpha)
{
@ -964,3 +990,9 @@ CVisibilityPlugins::GetClumpAlpha(RpClump *clump)
{
return CLUMPEXT(clump)->alpha;
}
bool
CVisibilityPlugins::IsClumpVisible(RpClump *clump)
{
return CLUMPEXT(clump)->visibilityCB(clump);
}

View File

@ -84,6 +84,7 @@ public:
// All actually unused
static bool DefaultVisibilityCB(RpClump *clump);
static bool FrustumSphereCB(RpClump *clump);
static bool MloVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB_BigVehicle(RpClump *clump);
@ -104,6 +105,7 @@ public:
static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic);
static void SetAtomicFlag(RpAtomic*, int);
static void ClearAtomicFlag(RpAtomic*, int);
static void SetAtomicId(RpAtomic *atomic, int);
static int GetAtomicId(RpAtomic *atomic);
static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender);
@ -133,8 +135,10 @@ public:
int alpha;
};
static void SetClumpModelInfo(RpClump*, CClumpModelInfo*);
static CClumpModelInfo *GetClumpModelInfo(RpClump*);
static void SetClumpAlpha(RpClump*, int);
static int GetClumpAlpha(RpClump*);
static bool IsClumpVisible(RpClump*);
static void *ClumpConstructor(void *object, int32 offset, int32 len);
static void *ClumpDestructor(void *object, int32 offset, int32 len);

View File

@ -478,7 +478,7 @@ DoGameSpecificStuffAfterSucessLoad()
CGame::TidyUpMemory(true, false);
StillToFadeOut = true;
JustLoadedDontFadeInYet = true;
TheCamera.Fade(0.0f, 0);
TheCamera.Fade(0.0f, FADE_OUT);
CTheScripts::Process();
}
@ -693,6 +693,7 @@ enum
SAVE_TYPE_64_BIT = 2,
SAVE_TYPE_MSVC = 4,
SAVE_TYPE_GCC = 8,
SAVE_TYPE_STEAM = 16,
};
uint8
@ -707,6 +708,14 @@ GetSaveType(char *savename)
uint8 *buf = work_buff;
CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts
buf += 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3;
int8 steam_byte;
ReadDataFromBufferPointer(buf, steam_byte);
if (steam_byte == -3)
save_type |= SAVE_TYPE_STEAM;
LoadSaveDataBlockNoCheck(buf, file, size); // ped pool
LoadSaveDataBlockNoCheck(buf, file, size); // garages
@ -757,6 +766,29 @@ GetSaveType(char *savename)
return save_type;
}
static void
FixSimpleVarsAndScripts(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
uint8 *buf_start = buf;
uint8 *buf2_start = buf2;
uint32 read = *size;
uint32 written = *size - (sizeof(int8) + 3);
uint32 pre_steam = 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3;
uint32 post_steam = *size - (sizeof(int8) + 3) - pre_steam;
CopyBuf(buf, buf2, pre_steam);
SkipBuf(buf, sizeof(int8) + 3);
CopyBuf(buf, buf2, post_steam);
*size = 0;
assert(buf - buf_start == read);
assert(buf2 - buf2_start == written);
*size = written;
}
static void
FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
@ -1018,7 +1050,7 @@ FixScriptPaths(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
bool
FixSave(int32 slot, uint8 save_type)
{
if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC)
if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC && !(save_type & SAVE_TYPE_STEAM))
return true;
bool success = false;
@ -1044,17 +1076,29 @@ FixSave(int32 slot, uint8 save_type)
totalSize = 0;
CFileMgr::Read(file_in, (const char *)&size, sizeof(size));
size = align4bytes(size);
buf = work_buff;
CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts
WriteSavaDataBlockNoFunc(buf, file_out, size);
if (save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT) {
memset(work_buff2, 0, sizeof(work_buff2));
buf2 = work_buff2;
FixSimpleVarsAndScripts(save_type, buf, buf2, &size);
if (!PcSaveHelper.PcClassSaveRoutine(file_out, work_buff2, size))
goto fail;
totalSize += size;
} else
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // garages
FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case
if (!(save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT))
FixSaveDataBlock(FixGarages, file_out, size);
else
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // game logic
WriteSavaDataBlockNoFunc(buf, file_out, size);
@ -1176,13 +1220,20 @@ void DisplaySaveResult(int unk, char* name)
bool SaveGameForPause(int type)
{
if (AllowMissionReplay != 0 || type != 3 && WaitForSave > CTimer::GetTimeInMilliseconds())
if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL && AllowMissionReplay != MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART) {
debug("SaveGameForPause failed during AllowMissionReplay %d", AllowMissionReplay);
return false;
}
if (type != SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY && WaitForSave > CTimer::GetTimeInMilliseconds()) {
debug("SaveGameForPause failed WaitForSave");
return false;
}
WaitForSave = 0;
if (gGameState != GS_PLAYING_GAME || CTheScripts::IsPlayerOnAMission() || CStats::LastMissionPassedName[0] == '\0') {
if (gGameState != GS_PLAYING_GAME || (CTheScripts::bAlreadyRunningAMissionScript && type != SAVE_TYPE_QUICKSAVE_FOR_SCRIPT_ON_A_MISSION)) {
DisplaySaveResult(3, CStats::LastMissionPassedName);
return false;
}
debug("SaveGameForPause ******************************** %s doSave %d", CStats::LastMissionPassedName, !CTheScripts::bAlreadyRunningAMissionScript);
IsQuickSave = type;
MissionStartTime = 0;
int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT);

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